Generisanje konfiguracija za nginx, istorija jednog pull zahteva

Pozdrav, drugovi. Predivno na mojim borbenim serverima nginx radi od 2006. godine i tokom godina njegove administracije nakupio sam puno konfiguracija i šablona. Puno sam hvalio nginx i nekako je ispalo da sam čak i pokrenuo nginx hub na hubu, pohvali se m/
Prijatelji su me zamolili da im postavim razvojnu farmu i umjesto da im vučem svoje specifične šablone, sjetio sam se zanimljivog projekta nginxconfig.io, koji razbacuje konfiguracije po policama i priprema sve za šifriranje itd. Pomislio sam, zašto ne? Međutim, razbjesnila me činjenica da mi nginxconfig nudi da preuzmem zip arhivu u pretraživač, a da mi ne dozvoljava da je otpremim direktno na server koristeći wget/fetch/curl. Kakve gluposti, zasto mi to treba u browseru, treba mi na serveru sa konzole. Ljut, otišao sam na github da vidim suštinu projekta, što je dovelo do njegovog račvanja i, kao rezultat, zahtjeva za povlačenjem. O čemu ne bih pisao da nije zanimljivo 😉

Generisanje konfiguracija za nginx, istorija jednog pull zahteva

Naravno, prije kopanja po izvorima, pogledao sam gdje Chrome povlači generiranu zip arhivu sa konfiguracijama, a tamo me je čekala adresa koja počinje sa “blob:”, ups. Već je postalo jasno da usluga usput ništa ne generiše, zapravo, sve to radi js. Zaista, zip arhivu generiše sam klijent, pretraživač i javascript. One. ljepota je taj projekat nginxconfig.io može se jednostavno sačuvati kao html stranica, postaviti na neke narod.ru i to će raditi) Ovo je vrlo smiješno i zanimljivo rješenje, međutim, užasno je nezgodno za postavljanje servera, u stvari, upravo za ono što je ovaj projekat stvoren. Preuzmite generiranu arhivu pomoću pretraživača, a zatim je prenesite na server koristeći nc... u 2019? Postavio sam sebi zadatak da pronađem način da preuzmem rezultirajuću konfiguraciju direktno na server.
Nakon forkiranja projekta, počeo sam razmišljati o tome koje su mi opcije bile. Zadatak je bio komplikovan činjenicom da nisam želeo da odstupim od uslova da projekat ostane čist front-end, bez ikakvog back-enda. Naravno, najjednostavnije rješenje bi bilo podići nodejs i prisiliti ga da generiše arhivu sa konfiguracijama koristeći direktne veze.
Zapravo, nije bilo mnogo opcija. Tačnije, samo jedno mi je palo na pamet. Moramo podesiti konfiguracije i dobiti link koji možemo kopirati na konzolu servera da dobijemo zip arhivu.
Nekoliko tekstualnih datoteka u rezultujućoj zip arhivi težilo je prilično malo, doslovno nekoliko kilobajta. Očigledno rješenje je bilo da se base64 string iz generirane zip arhive baci u bafer, dok je na serveru sa komandom u konzoli

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

mogli bismo kreirati ovu istu zip datoteku.

nginxconfig.io je napisan u AngularJS-u, ne mogu ni zamisliti koliko bi kilometara koda bilo potrebno da autor nije izabrao reaktivni js framework. Ali savršeno mogu zamisliti koliko bi se sve to jednostavnije i ljepše moglo implementirati u VueJS, iako je to sasvim druga tema.
U resursima projekta vidimo metodu za generiranje zip arhive:

$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',
	});
};

sve je prilično jednostavno, koristeći biblioteku jszip Zip se kreira gdje se nalaze konfiguracijski fajlovi. Nakon kreiranja zip arhive, js je šalje u pretraživač koristeći biblioteku FileSaver.js:

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

gdje je sadržaj rezultirajući blob objekt zip arhive.

Ok, sve što sam trebao da uradim je da dodam još jedno dugme pored njega i kada bih kliknuo na njega, ne bih sačuvao rezultujuću zip arhivu u pretraživač, već bih preuzeo base64 kod iz nje. Nakon što sam malo petljao, dobio sam 2 metode, umjesto samo jednog downloadZip-a:

$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',
	});
};

Kao što ste možda primijetili, premjestio sam generiranje same zip arhive na privatnu genezip metodu i tako dalje. Ovo je AngularJS, a sam autor se drži povratnih poziva i nije ga implementirao kroz obećanja. downloadZip je i dalje sačuvao kao izlaz, dok je downloadBase64 učinio nešto malo drugačije. Kreiramo FileReader objekat koji nam je došao u html5 i već je prilično pristupačno za upotrebu. Koji u jednom trenutku može napraviti base64 string od blob-a, tačnije pravi string DataURL, ali to za nas nije toliko važno, jer DataURL sadrži upravo ono što nam treba. Bingo, čekala me mala zamka kada sam pokušao sve ovo staviti u bafer. Autor je u projektu koristio biblioteku clipboardjs, koji vam omogućava da radite sa međuspremnikom bez flash objekata, na osnovu odabranog teksta. U početku sam odlučio da svoj base64 stavim u element sa display:none;, ali u ovom slučaju nisam mogao da ga stavim u međuspremnik jer ne dolazi do razdvajanja. Stoga, umjesto display:none; Ja sam uradio

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

što mi je omogućilo da i sakrijem element od pogleda i zapravo ga ostavim na stranici. Voila, zadatak je završen, kada sam kliknuo na svoje dugme, ova linija je stavljena u bafer:

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

koju sam jednostavno zalijepio u konzolu na serveru i odmah dobio zip arhivu sa svim konfiguracijama.
I, naravno, poslao sam pull request autoru, jer... projekat je aktivan i živahan, volio bih da vidim ažuriranja od autora i da imam svoje dugme) Za zainteresovane evo ga moja viljuška projekta i sebe pull zahtjev, gdje možete vidjeti šta sam ispravio/dodao.
Sretan razvoj svima)

Generisanje konfiguracija za nginx, istorija jednog pull zahteva

izvor: www.habr.com

Dodajte komentar