Generacio de agordoj por nginx, historio de unu tira peto

Saluton, kamaradoj. Bela sur miaj batalserviloj nginx funkcias ekde 2006 kaj dum la jaroj de ĝia administrado mi amasigis multajn agordojn kaj ŝablonojn. Mi multe laŭdis nginx kaj iel montriĝis, ke ankaŭ mi eĉ komencis nginx-nabon sur la nabo, montru m/
Amikoj petis min starigi evoluan bienon por ili, kaj anstataŭ treni ilin miajn specifajn ŝablonojn, mi rememoris interesan projekton. nginxconfig.io, kiu disĵetas agordojn sur la bretoj kaj preparas ĉion por lasas ĉifri, ktp. Mi pensis, kial ne? Tamen mi furioziĝis pro tio, ke nginxconfig proponas al mi elŝuti la zip-arkivon en la retumilon, sen permesi al mi alŝuti ĝin rekte al la servilo per wget/fetch/curl. Kia sensencaĵo, kial mi bezonas ĝin en la retumilo, mi bezonas ĝin en la servilo de la konzolo. Kolera, mi iris al github por vidi la kuraĝon de la projekto, kio kondukis al ĝia forko kaj, kiel rezulto, tira peto. Pri kio mi ne skribus, se ĝi ne estus interesa 😉

Generacio de agordoj por nginx, historio de unu tira peto

Kompreneble, antaŭ ol fosi en la fontojn, mi rigardis kie Chrome tiras la generitan zip-arkivon kun agordoj, kaj tie atendis min adreso komencanta per "blob:", ho. Jam evidentiĝis, ke la servo generas nenion survoje, fakte, ĉio estas farita de js. Efektive, la zip-arkivo estas generita de la kliento, retumilo kaj javaskripto mem. Tiuj. la beleco estas ke la projekto nginxconfig.io povas esti simple konservita kiel html-paĝo, alŝutita al iuj narod.ru kaj ĝi funkcios) Ĉi tio estas tre amuza kaj interesa solvo, tamen ĝi estas terure maloportuna por agordi servilojn, fakte, ĝuste por tio, kion ĉi tiu projekto estis kreita. Elŝutu la generitan arkivon per retumilo, kaj poste transdoni ĝin al la servilo per nc... en 2019? Mi fiksis al mi la taskon trovi manieron elŝuti la rezultan agordon rekte al la servilo.
Forkinte la projekton, mi ekpensis pri kiuj estas miaj elektoj. La tasko estis komplikita pro tio, ke mi ne volis deflankiĝi de la kondiĉo, ke la projekto restu pura antaŭfino, sen ia malantaŭa fino. Kompreneble, la plej simpla solvo estus eltiri nodej-ojn kaj devigi ĝin generi arkivon kun agordoj uzante rektajn ligilojn.
Fakte, ne estis multaj ebloj. Pli precize, nur unu venis en la menson. Ni devas agordi la agordojn kaj ricevi ligilon, kiun ni povas kopii al la servila konzolo por ricevi zip-arkivon.
Pluraj tekstdosieroj en la rezulta zip-arkivo pezis sufiĉe, laŭvorte kelkajn kilobajtojn. La evidenta solvo estis akiri la base64-ŝnuron el la generita zip-arkivo kaj ĵeti ĝin en la bufron, dum en la servilo kun la komando en la konzolo.

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

ni povus krei ĉi tiun saman zip-dosieron.

nginxconfig.io estis skribita en AngularJS, mi eĉ ne povas imagi kiajn kilometrojn da kodo estus bezonataj se la aŭtoro ne elektus reaktivan js-kadron. Sed mi povas perfekte imagi, kiom pli simpla kaj bela ĉio ĉi povus esti efektivigita en VueJS, kvankam ĉi tio estas tute alia temo.
En la projektaj rimedoj ni vidas metodon por generi zip-arkivon:

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

ĉio estas sufiĉe simpla, uzante la bibliotekon jszip Zip estas kreita kie la agordaj dosieroj estas metitaj. Post kreado de la zip-arkivo, js nutras ĝin al la retumilo uzante la bibliotekon FileSaver.js:

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

kie enhavo estas la rezulta blobbjekto de la zip-arkivo.

Bone, mi devis nur aldoni alian butonon apud ĝi kaj kiam mi klakis sur ĝi, mi ne konservus la rezultan zip-arkivon al la retumilo, sed ricevus la base64-kodon de ĝi. Post muzikado iomete, mi ricevis 2 metodojn, anstataŭ nur unu elŝutiZip:

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

Kiel vi eble rimarkis, mi movis la generacion de la zip-arkivo mem al la privata metodo generiZip, ktp. Ĉi tio estas AngularJS, kaj la aŭtoro mem restas al revoki kaj ne efektivigis ĝin per promesoj. downloadZip ankoraŭ konservis kiel eligo, dum downloadBase64 faris ion iomete malsaman. Ni kreas FileReader-objekton, kiu venis al ni en HTML5 kaj jam estas sufiĉe alirebla por uzo. Kiu, samtempe, povas fari baz64-ĉenon el blob, aŭ pli ĝuste, ĝi faras DataURL-ĉenon, sed ĉi tio ne tiom gravas por ni, ĉar DataURL enhavas ĝuste tion, kion ni bezonas. Bingo, iomete atendis min kiam mi provis meti ĉion ĉi en la bufron. La aŭtoro uzis la bibliotekon en la projekto tondujojs, kiu ebligas al vi labori kun la tondujo sen fulmaj objektoj, surbaze de la elektita teksto. Komence, mi decidis meti mian base64 en elementon kun display:none;, sed ĉi-kaze mi ne povis meti ĝin en la tondujo ĉar ne okazas disiĝo. Tial, anstataŭ montri:neniu; Mi faris

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

kio permesis al mi kaj kaŝi la elementon de vido kaj fakte lasi ĝin sur la paĝo. Voila, la tasko estis finita, kiam mi klakis sur mia butono, linio tia estis metita en la bufron:

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

kiun mi simple gluis en la konzolon sur la servilo kaj tuj ricevis zip-arkivon kun ĉiuj agordoj.
Kaj, kompreneble, mi sendis tirpeton al la aŭtoro, ĉar... la projekto estas aktiva kaj vigla, mi ŝatus vidi ĝisdatigojn de la aŭtoro kaj havi mian propran butonon) Por interesatoj, jen ĝi estas mia forko projekto kaj sin mem tiri peton, kie vi povas vidi kion mi korektis/aldonis.
Feliĉa evoluo ĉiuj)

Generacio de agordoj por nginx, historio de unu tira peto

fonto: www.habr.com

Aldoni komenton