Tạo cấu hình cho nginx, lịch sử của một yêu cầu kéo

Xin chào các đồng chí. Đẹp trên máy chủ chiến đấu của tôi nginx đã chạy từ năm 2006 và qua nhiều năm quản lý, tôi đã tích lũy được rất nhiều cấu hình và mẫu. Tôi đã khen ngợi nginx rất nhiều và bằng cách nào đó, hóa ra tôi thậm chí còn bắt đầu một trung tâm nginx trên trung tâm đó, khoe m/
Bạn bè yêu cầu tôi thiết lập một trang trại phát triển cho họ và thay vì kéo theo các mẫu cụ thể của tôi, tôi nhớ đến một dự án thú vị nginxconfig.io, phân tán các cấu hình trên giá và chuẩn bị mọi thứ cho phép mã hóa, v.v. Tôi nghĩ, tại sao không? Tuy nhiên, tôi rất tức giận vì nginxconfig đề nghị tôi tải kho lưu trữ zip xuống trình duyệt mà không cho phép tôi tải trực tiếp lên máy chủ bằng cách sử dụng wget/fetch/curl. Vô lý quá, tại sao tôi lại cần nó trong trình duyệt, tôi cần nó trên máy chủ từ bảng điều khiển. Tức giận, tôi đã truy cập github để xem nội dung cốt lõi của dự án, dẫn đến sự phân nhánh của nó và kết quả là một yêu cầu kéo. Điều mà tôi sẽ không viết nếu nó không thú vị 😉

Tạo cấu hình cho nginx, lịch sử của một yêu cầu kéo

Tất nhiên, trước khi tìm hiểu các nguồn, tôi đã xem xét nơi Chrome kéo kho lưu trữ zip được tạo bằng các cấu hình và có một địa chỉ bắt đầu bằng “blob:” đang đợi tôi, rất tiếc. Rõ ràng là dịch vụ này không tạo ra bất cứ thứ gì trong quá trình thực hiện, trên thực tế, tất cả đều được thực hiện bởi js. Thật vậy, kho lưu trữ zip được tạo bởi chính ứng dụng khách, trình duyệt và javascript. Những thứ kia. vẻ đẹp là dự án nginxconfig.io có thể được lưu đơn giản dưới dạng trang html, tải lên một số narod.ru và nó sẽ hoạt động) Đây là một giải pháp rất hài hước và thú vị, tuy nhiên, nó cực kỳ bất tiện cho việc thiết lập máy chủ, trên thực tế, chính xác cho những gì dự án này được tạo ra. Tải xuống kho lưu trữ đã tạo bằng trình duyệt, sau đó chuyển nó sang máy chủ bằng nc... vào năm 2019? Tôi tự đặt cho mình nhiệm vụ tìm cách tải trực tiếp cấu hình kết quả xuống máy chủ.
Sau khi phân nhánh dự án, tôi bắt đầu suy nghĩ về những lựa chọn của mình. Nhiệm vụ này rất phức tạp bởi thực tế là tôi không muốn đi chệch khỏi điều kiện là dự án phải vẫn là một giao diện người dùng thuần túy, không có bất kỳ phần phụ trợ nào. Tất nhiên, giải pháp đơn giản nhất là kéo nodejs lên và buộc nó tạo một kho lưu trữ có cấu hình bằng các liên kết trực tiếp.
Thực ra không có nhiều lựa chọn. Chính xác hơn, chỉ có một người nghĩ đến. Chúng tôi cần thiết lập cấu hình và nhận liên kết mà chúng tôi có thể sao chép vào bảng điều khiển máy chủ để có được kho lưu trữ zip.
Một số tệp văn bản trong kho lưu trữ zip thu được nặng khá nhiều, theo nghĩa đen là vài kilobyte. Giải pháp rõ ràng là lấy chuỗi base64 từ kho lưu trữ zip được tạo và ném nó vào bộ đệm, trong khi trên máy chủ có lệnh trong bảng điều khiển

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

chúng ta có thể tạo cùng một tệp zip này.

nginxconfig.io được viết bằng AngularJS, tôi thậm chí không thể tưởng tượng được sẽ cần bao nhiêu km mã nếu tác giả không chọn khung js phản ứng. Nhưng tôi hoàn toàn có thể tưởng tượng tất cả những điều này có thể được triển khai đơn giản và đẹp đẽ hơn như thế nào trong VueJS, mặc dù đây là một chủ đề hoàn toàn khác.
Trong tài nguyên dự án, chúng tôi thấy một phương pháp tạo kho lưu trữ 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',
	});
};

mọi thứ khá đơn giản, sử dụng thư viện jszip Một zip được tạo ở nơi đặt các tệp cấu hình. Sau khi tạo kho lưu trữ zip, js sẽ cung cấp nó cho trình duyệt bằng thư viện FileSaver.js:

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

trong đó nội dung là đối tượng blob kết quả của kho lưu trữ zip.

Được rồi, tất cả những gì tôi phải làm là thêm một nút khác bên cạnh nó và khi tôi nhấp vào nó, tôi sẽ không lưu kho lưu trữ zip kết quả vào trình duyệt mà lấy mã base64 từ nó. Sau khi loay hoay một chút, tôi nhận được 2 phương pháp, thay vì chỉ một downloadZip:

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

Như bạn có thể nhận thấy, tôi đã chuyển chính việc tạo kho lưu trữ zip sang phương thức generateZip riêng tư, v.v. Đây là AngularJS và bản thân tác giả bám vào các lệnh gọi lại và không triển khai nó thông qua các lời hứa. downloadZip vẫn thực hiện saveAs làm đầu ra, trong khi downloadBase64 thực hiện điều gì đó hơi khác một chút. Chúng tôi tạo một đối tượng FileReader xuất hiện trong html5 và đã khá có sẵn để sử dụng. Tại một thời điểm, nó có thể tạo chuỗi base64 từ một blob, hay nói đúng hơn là nó tạo chuỗi DataURL, nhưng điều này không quá quan trọng đối với chúng tôi, bởi vì DataURL chứa chính xác những gì chúng ta cần. Bingo, một chút trở ngại đang chờ đợi tôi khi tôi cố gắng đưa tất cả những thứ này vào bộ đệm. Tác giả đã sử dụng thư viện trong dự án clipboardj, cho phép bạn làm việc với bảng nhớ tạm mà không cần đối tượng flash, dựa trên văn bản đã chọn. Ban đầu, tôi quyết định đặt base64 của mình vào một phần tử có display:none;, nhưng trong trường hợp này tôi không thể đặt nó vào bảng tạm vì không có sự tách biệt xảy ra. Do đó, thay vì display:none; tôi đã làm

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

điều này cho phép tôi vừa ẩn phần tử khỏi chế độ xem vừa thực sự để nó trên trang. Thì đấy, nhiệm vụ đã hoàn thành, khi tôi nhấp vào nút của mình, một dòng như thế này đã được đặt vào bộ đệm:

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

mà tôi vừa dán vào bảng điều khiển trên máy chủ và ngay lập tức nhận được một kho lưu trữ zip với tất cả các cấu hình.
Và tất nhiên là tôi đã gửi pull request tới tác giả, bởi vì... dự án đang hoạt động và sống động, tôi muốn xem thông tin cập nhật từ tác giả và có nút riêng) Đối với những người quan tâm, đây là cái nĩa của tôi dự án và bản thân anh ấy yêu cầu kéo, nơi bạn có thể thấy những gì tôi đã sửa/thêm vào.
Chúc mọi người phát triển)

Tạo cấu hình cho nginx, lịch sử của một yêu cầu kéo

Nguồn: www.habr.com

Thêm một lời nhận xét