Gjenerimi i konfigurimeve për nginx, historia e një kërkese tërheqjeje

Përshëndetje, shokë. E bukur në serverët e mi luftarakë nginx funksionon që nga viti 2006 dhe gjatë viteve të administrimit të tij kam grumbulluar shumë konfigurime dhe shabllone. E lavdërova shumë nginx-in dhe disi doli që edhe unë nisa një hub nginx në hub, tregohu m/
Miqtë më kërkuan të krijoja një fermë zhvillimi për ta dhe në vend që t'i zvarritja shabllonet e mia specifike, m'u kujtua një projekt interesant nginxconfig.io, i cili shpërndan konfigurimet në rafte dhe përgatit gjithçka për të lejuar enkriptimin, etj. Mendova, pse jo? Megjithatë, u tërbova nga fakti që nginxconfig më ofron të shkarkoj arkivin zip në shfletues, pa më lejuar ta ngarkoj direkt në server duke përdorur wget/fetch/curl. Çfarë marrëzi, pse më duhet në shfletues, më duhet në server nga tastiera. I zemëruar, shkova në github për të parë guximin e projektit, i cili çoi në pirunin e tij dhe, si rezultat, një kërkesë për tërheqje. Për të cilën nuk do të shkruaja nëse nuk do të ishte interesante 😉

Gjenerimi i konfigurimeve për nginx, historia e një kërkese tërheqjeje

Sigurisht, përpara se të gërmoj në burimet, shikova se ku Chrome tërheq arkivin zip të gjeneruar me konfigurime, dhe atje më priste një adresë që fillon me "blob:", oops. Tashmë është bërë e qartë se shërbimi nuk gjeneron asgjë gjatë rrugës, në fakt, gjithçka bëhet nga js. Në të vërtetë, arkivi zip gjenerohet nga klienti, shfletuesi dhe vetë javascript. ato. e bukura është se projekti nginxconfig.io mund të ruhet thjesht si një faqe html, e ngarkuar në disa narod.ru dhe do të funksionojë) Kjo është një zgjidhje shumë qesharake dhe interesante, megjithatë, është jashtëzakonisht e papërshtatshme për vendosjen e serverëve, në fakt, pikërisht për atë që u krijua ky projekt. Shkarkoni arkivin e krijuar me një shfletues dhe më pas transferojeni në server duke përdorur nc... në 2019? I vendosa vetes detyrën për të gjetur një mënyrë për të shkarkuar konfigurimin që rezulton drejtpërdrejt në server.
Pasi përfundova projektin, fillova të mendoj se cilat ishin opsionet e mia. Detyra ishte e ndërlikuar nga fakti se nuk doja të devijoja nga kushti që projekti të mbetej një front-end i pastër, pa asnjë prapavijë. Sigurisht, zgjidhja më e thjeshtë do të ishte tërheqja e nodejs dhe detyrimi i saj për të gjeneruar një arkiv me konfigurime duke përdorur lidhje direkte.
Në fakt, nuk kishte shumë opsione. Më saktë, vetëm një më erdhi në mendje. Duhet të konfigurojmë konfigurimet dhe të marrim një lidhje që mund ta kopjojmë në tastierën e serverit për të marrë një arkiv zip.
Disa skedarë teksti në arkivin zip që rezulton peshonin mjaft, fjalë për fjalë disa kilobajt. Zgjidhja e dukshme ishte të merrej vargu base64 nga arkivi zip i gjeneruar dhe ta hidhte atë në tampon, ndërsa në server me komandën në tastierë

echo 'base64string' | base64 --decode > config.zip

ne mund të krijojmë të njëjtin skedar zip.

nginxconfig.io ishte shkruar në AngularJS, as nuk mund ta imagjinoj se çfarë kilometrash kodi do të ishin kërkuar nëse autori nuk do të kishte zgjedhur një kornizë reaktive js. Por unë mund ta imagjinoj në mënyrë të përkryer se sa më e thjeshtë dhe më e bukur mund të zbatohej e gjithë kjo në VueJS, megjithëse kjo është një temë krejtësisht e ndryshme.
Në burimet e projektit ne shohim një metodë për gjenerimin e një arkivi zip:

$scope.downloadZip = function() {
	var zip = new JSZip();

	var sourceCodes = $window.document.querySelectorAll('main .file .code.source');

	for (var i = 0; i < sourceCodes.length; i++) {
		var sourceCode = sourceCodes[i];

		var name	= sourceCode.dataset.filename;
		var content	= sourceCode.children[0].children[0].innerText;

		if (!$scope.isSymlink() && name.match(/^sites-available//)) {
			name = name.replace(/^sites-available//, 'sites-enabled/');
		}

		zip.file(name, content);

		if (name.match(/^sites-available//)) {
			zip.file(name.replace(/^sites-available//, 'sites-enabled/'), '../' + name, {
				unixPermissions: parseInt('120755', 8),
			});
		}
	}

	zip.generateAsync({
		type: 'blob',
		platform: 'UNIX',
	}).then(function(content) {
		saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
	});

	gtag('event', $scope.getDomains().join(','), {
		event_category: 'download_zip',
	});
};

gjithçka është mjaft e thjeshtë, duke përdorur bibliotekën jszip Krijohet një zip ku vendosen skedarët e konfigurimit. Pas krijimit të arkivit zip, js e fut atë në shfletues duke përdorur bibliotekën FileSaver.js:

saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');

ku përmbajtja është objekti blob që rezulton i arkivit zip.

Ok, gjithçka që duhej të bëja ishte të shtoja një buton tjetër pranë tij dhe kur klikoja mbi të, nuk do ta ruaja arkivin zip që rezulton në shfletues, por do të merrja kodin bazë64 prej tij. Pasi u përpoqa pak, mora 2 metoda, në vend të vetëm një shkarkimi Zip:

$scope.downloadZip = function() {
	generateZip(function (content) {
		saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
	});

	gtag('event', $scope.getDomains().join(','), {
		event_category: 'download_zip',
	});
};
$scope.downloadBase64 = function() {
	generateZip(function (content) {
		var reader = new FileReader();
		reader.readAsDataURL(content);
		reader.onloadend = function() {
			var base64 = reader.result.replace(/^data:.+;base64,/, '');
			// в переменной base64 как раз нужный мне zip архив в виде base64 строки
		}
	});

	gtag('event', $scope.getDomains().join(','), {
		event_category: 'download_base64',
	});
};

Siç mund ta keni vënë re, unë e zhvendosa gjenerimin e vetë arkivit zip në metodën private generateZip, e kështu me radhë. Ky është AngularJS, dhe vetë autori i përmbahet thirrjeve dhe nuk e zbatoi atë përmes premtimeve. downloadZip ende bëri saveAs si një dalje, ndërsa downloadBase64 bëri diçka pak më ndryshe. Ne krijojmë një objekt FileReader që na erdhi në html5 dhe tashmë është mjaft të arritshme per perdorim. E cila, në një kohë, mund të bëjë një varg base64 nga një blob, ose më mirë, krijon një varg DataURL, por kjo nuk është aq e rëndësishme për ne, sepse DataURL përmban pikërisht atë që na nevojitet. Bingo, një pengesë e vogël më priste kur u përpoqa t'i vendosja të gjitha këto në tampon. Autori përdori bibliotekën në projekt clipboardjs, i cili ju lejon të punoni me clipboard pa objekte flash, bazuar në tekstin e zgjedhur. Fillimisht, vendosa të vendos bazën time 64 në një element me display:none;, por në këtë rast nuk munda ta vendosa në clipboard sepse nuk ndodh ndarje. Prandaj, në vend të shfaqjes: asnjë; unë e bëra

position: absolute;
z-index: -1;
opacity: 0;

gjë që më lejoi të fsheh elementin nga pamja dhe në fakt ta lija atë në faqe. Voila, detyra u krye, kur klikova në butonin tim, një rresht si ky u vendos në buffer:

echo 'base64string' | base64 --decode > config.zip

të cilin thjesht e ngjita në tastierën në server dhe menjëherë mora një arkiv zip me të gjitha konfigurimet.
Dhe, natyrisht, i dërgova një kërkesë për tërheqje autorit, sepse ... projekti është aktiv dhe i gjallë, do të doja të shihja përditësime nga autori dhe të kisha butonin tim) Për të interesuarit, ja ku është piruni im projekti dhe unë tërheq kërkesë, ku mund të shihni se çfarë korrigjova/shtova.
Gëzuar zhvillim të gjithëve)

Gjenerimi i konfigurimeve për nginx, historia e një kërkese tërheqjeje

Burimi: www.habr.com

Shto një koment