แแ แกแขแแขแแแจแ แแแแแ แแแแฃแแแแ แ แฉแแแ แแแแแชแแแแแแ NJS-แก, JavaScript-แแก แแแ แฏแแแแแก Nginx-แแกแแแแก, แ แแแแแแช แจแแแฃแจแแแแแฃแแแ Nginx Inc-แแก แแแแ แแ แแฆแฌแแ แก แแแก แซแแ แแแแ แจแแกแแซแแแแแแแแแก แ แแแแฃแ แ แแแแแแแแแก แแแแแงแแแแแแ. NJS แแ แแก JavaScript-แแก แฅแแแฏแแฃแคแ, แ แแแแแแช แกแแจแฃแแแแแแก แแแซแแแแ แแแแคแแ แแแแแ Nginx-แแก แคแฃแแฅแชแแแแแ แแแ. แแแแฎแแแแ
แฒแแแ แฎแแแก แฌแแโฆ
แฉแแแก แแแแ แกแแแฃแจแแแแ แแ แแแแแแแแ แแแแแ แแแแแฆแ แแแขแแแแ แแ แแแแแ แญแ แแแ CI/CD แแแแกแแแแแแแแ แแแแแ -แแแแแแแแ, แแแแแแ แแ แกแฎแแ แกแแแแแแแแแแ, แ แแแแแแแช แแแแแแแแ แแแแแแแก แ แแแกแแแแ. แกแฃแ แแแแแ, แ แแแแแแแช แแแ แ แแแแแแงแแแแแแแ CI-แจแ, แแแแแแแแ แแแแแแแแ แแแ แคแแ แแแจแ. แแกแแแ แแแแแ แแฃแแแ แแฃแจแแแแแแแ แแ แแฆแแแแ, แ แแแแกแแช แฉแแแแ gitlab IP แจแแแชแแแแ แแ CI แแแแ แแ แแแแแแฅแชแ. แแ แแแแแแ แแก แแงแ, แ แแ แแ แ-แแ แ แแแแแ แกแฃแ แแแก, แ แแแแแแช แแแแแฌแแแแแแแ CI-แจแ, แแแแฉแแแ git, แ แแแแแแแช แแแแงแแแแ Python แแแแฃแแแแ ssh-แแก แกแแจแฃแแแแแแ. ssh-แกแแแแก แแญแแ แแแแแ แแแ แแแ แแแกแแฆแแแ แแ... แแก แแงแ แกแฃแ แแแแ แชแแแแแแ_แแแกแแแแซแแแแแแ แแ แแแ. แแ แแแแแกแแแแ แ CI แแแ แแแฎแแ แฎแแ แแแกแแฆแแแแก แแแแแแแฌแแแแแก แจแแชแแแแแ แ แแแแฃแ IP-แกแ แแ แชแแแแแแ_แแแกแแแแซแแแแจแ แแแแแแแแฃแแก แจแแ แแก แจแแฃแกแแแแแแแแก แแแแ. แแฎแแแ แกแฃแ แแแ แกแฌแ แแคแแ แจแแแแ แแแ แแ แกแแแฃแแ Dockfiles-แแแ แแ แแแแแแขแ แแแ แแแแขแ StrictHostKeyChecking no
. แแแแ แแ แชแฃแแ แแแแ แแแ แฉแ แแ แแแฉแแแ แกแฃแ แแแแ, แแแแแแขแแแ แแแแแแ แแแ แแ PyPI แกแแชแแแจแ. แแแแแขแแแแแ แแแแฃแกแ, แแแ แแ PyPI-แแ แแแแแกแแแแก แจแแแแแ, แแงแ แฃแคแ แ แแแ แขแแแ แแแแกแแแแแ แแ แแแแฎแแแแแแแก แแแ แแแแฃแ แ แแฆแฌแแ แ.txt
แแ แฉแแแแแ แแแแแแแแฃแแแ, แแแขแแแแแ!
แฉแแแ แงแแแแแคแแ แก แแแฌแแ แแแแแ แฆแ แฃแแแแแจแ แแ แแฃแแแ แแแขแแแจแ แแ แกแแแแแแแ แแแแแแแแ แแแแแแฆแ แแแขแแ แ แกแแ แแแกแ, แ แแแแแแช แแงแ แแแฅแแแแฅแแแแแก แแ แแฅแแแ แแแแขแแแแแ แ แแแ แ แกแแชแแแแแแ. แแแ แแ, แ แแแแแ แฉแแแ แแแงแแแแแ S3-แก, แแ แแแ แแขแแขแ แแแก แแแแแแญแ. แแ, แแฃ แจแแกแแซแแแแแแแ, แแแแแแขแแคแแแแชแแแ gitlab-แจแ (แกแแญแแ แแแแแก แจแแแแฎแแแแแจแ แจแแแแซแแแแ แแแแแ แแแแแแขแแ).
แกแฌแ แแคแแ แซแแแแแ แ แแแแแแแแ แจแแแแแ แแแแแแฆแ: s3pypi, pypicloud แแ แแแ แแแแขแ แขแฃแ แแแแแกแแแแก html แคแแแแแแแก โแฎแแแแโ แจแแฅแแแแ. แแแแ แแแ แแแแขแ แแแแแกแแแแแ แแแฅแ แ.
s3pypi: แแก แแ แแก แแแแแ S3 แฐแแกแขแแแแแก แแแแแงแแแแแแกแแแแก. แฉแแแ แแแขแแแ แแแแ แคแแแแแแก, แแแแแแแ แแ แแแ html-แก แแ แแขแแแ แแแแ แแแแแ แแแแแฃแแจแ. แแแแแแแแแ แกแแฎแแแก แแแแแงแแแแแแกแแแแก.
pypicloud: แกแแแแขแแ แแกแ แแ แแแฅแขแ แฉแแแแ, แแแแ แแ แแแแฃแแแแขแแชแแแก แฌแแแแแฎแแแก แจแแแแแ แแแแแแแชแ แฃแแแฃแแ แแแแ แฉแ. แแแฃแฎแแแแแแ แแแ แแ แแแแฃแแแแขแแชแแแกแ แแ แแฅแแแแ แกแแญแแ แแแแแแแก แจแแกแแแแแแกแแ แแแคแแ แแแแแแก แจแแกแแซแแแแแแแแกแ, แกแแแแแแแแแแจแ แแฆแแแฉแแแ แแแแแแขแ แแ แ แแฃแแ แแแแคแแแฃแ แแชแแ. แแฅแแแแ แแแแชแแแแแแก แจแแกแแกแ แฃแแแแแแ แแแแแก แแแ แแฅแขแแ แแแ, แแแแ แแแแแแแ แจแแคแแกแแแแ, 3-5 แแฆแ แแแกแญแแ แแแแแแ. แกแแ แแแกแก แแกแแแ แกแญแแ แแแแ แแแแแชแแแแ แแแแ. แกแฎแแ แ แแ แแแ แแคแแ แ แแแแแแแแ, แแแแขแแแแ.
แฃแคแ แ แกแแฆแ แแแกแแฃแแ แซแแแแแ แแแแแแฆแ แแแแฃแแ Nginx-แแกแแแแก, ngx_aws_auth. แแแกแ แขแแกแขแแ แแแแก แจแแแแแ แแงแ แแ แแฃแแแ แจแ แแแฉแแแแแแ XML, แ แแแแแแช แแฉแแแแแแแ S3 แแแแแฃแแแก แจแแแแแแกแก. แฉแฎแ แแแแก แแ แแก แแแแ แฉแแแแแ แแ แแ แฌแแแก แฌแแ แแงแ. แกแแชแแแ แแแขแแแแแฃแแ แฉแแแแ.
แฌแงแแ แแกแแแ แแแกแแแแ แแ แฌแแแแแฎแแแ
แแ แแแแแแแแแก แกแแคแฃแซแแแแแ, แแ แแ แกแแแแแก แจแแแแแ แฉแแแก แแ แแฃแแแ แจแ แแแแฎแ แแแแแ XML, แ แแแแ แช ngx_aws_auth แแแแฃแแแก แแแแแงแแแแแแกแแก, แแแแ แแ แงแแแแแคแแ แ แฃแแแ แแแฌแแ แแแ แแงแ JS-แจแ.
แซแแแแแ แแแแแฌแแแ แแแแแฅแกแแก แฎแกแแแ แ. แฏแแ แแ แแ, แแแ แแ แแแแฃแแแแขแแชแแ แแ แแ แแแแแ แแแแแแแแ, แแแแ แแช, แฉแแแ แแแฆแแแ Nginx-แแก แงแแแแ แกแแแแแแก แคแแแแแแแแ แแฃแจแแแแแกแแแแก (แแแ แแแแแแ), แแแกแแแ, แแแแช แแชแแก แ แแแแ แแแฌแแ แแก แแแแคแแแฃแ แแชแแแแ Nginx-แแกแแแแก, แจแแซแแแแก แแแแ แแแแแก แ แ แแ แแก แ แ. แแแแแแแแแแแ แฉแแแแแแกแแช แแแแฃแกแแ แแแแแแแแ แแ แแแกแแแ แจแแแแ แแแแ (แแฃ แแฃแแแแแ แฌแแ แแ), แ แแ แแฆแแ แแคแแ แ แแแฅแแแ แแแฅแกแฃแกแแ.
TL;DR 2 แแฆแแก แจแแแแแ, PyPi-แก แกแแขแแกแขแ แแแ แกแแ แฃแแแ แแแแแแงแแแแแแแ CI-แจแ.
แ แแแแ แแฃแจแแแแก แแแ?
แแแแฃแแ แฉแแขแแแ แแฃแแแ Nginx-แจแ ngx_http_js_module
, แฉแแ แแฃแแแ แแแแแ แแก แแคแแชแแแแฃแ แกแฃแ แแแจแ. แฉแแแ แแแแแ แขแแ แแแก แฉแแแแก แกแแ แแแขแก แแแ แแฅแขแแแแก แแแแแงแแแแแแ js_import
Nginx แแแแคแแแฃแ แแชแแแแแ. แคแฃแแฅแชแแแก แแฌแแแแแ แแแ แแฅแขแแแ js_content
. แแแ แแฅแขแแแ แแแแแแงแแแแแ แชแแแแแแแแก แแแกแแงแแแแแแแ js_set
, แ แแแแแแช แแ แแฃแแแแขแแ แแฆแแแก แแฎแแแแ แกแแ แแแขแจแ แแฆแฌแแ แแ แคแฃแแฅแชแแแก. แแแแ แแ แฉแแแ แจแแแแแซแแแ แจแแแแกแ แฃแแแ แฅแแแแแแแแฎแแแแ NJS-แจแ แแฎแแแแ Nginx-แแก แแแแแงแแแแแแ แแ แแ แ XMLHttpRequest-แแก แแแแแงแแแแแแ. แแแแกแแแแแก แจแแกแแแแแแกแ แแแแแแ แแแแ แฃแแแ แแแแแแขแแก Nginx-แแก แแแแคแแแฃแ แแชแแแก. แแ แกแแ แแแขแแ แฃแแแ แแฆแฌแแ แแก แฅแแแแแแฎแแแแ แแ แแแแแแ แแแแแกแแแแก. Nginx แแแแคแแแฃแ แแชแแแแแ แคแฃแแฅแชแแแแ แฌแแแแแแกแแแแก, แคแฃแแฅแชแแแก แกแแฎแแแ แฃแแแ แแงแแก แแฅแกแแแ แขแแ แแแฃแแ แแแแแ แกแแ แแแขแจแ export default
.
nginx.conf
load_module modules/ngx_http_js_module.so;
http {
js_import imported_name from script.js;
server {
listen 8080;
...
location = /sub-query {
internal;
proxy_pass http://upstream;
}
location / {
js_content imported_name.request;
}
}
script.js
function request(r) {
function call_back(resp) {
// handler's code
r.return(resp.status, resp.responseBody);
}
r.subrequest('/sub-query', { method: r.method }, call_back);
}
export default {request}
แแ แแฃแแแ แจแ แแแแฎแแแแแกแแก http://localhost:8080/
แจแแแแแแแ แ location /
แ แแแแแจแแช แแแ แแฅแขแแแ js_content
แแซแแฎแแแก แคแฃแแฅแชแแแก request
แแฆแฌแแ แแแแ แฉแแแแก แกแแ แแแขแจแ script.js
. แแแแแก แแฎแ แแ, แคแฃแแฅแชแแแจแ request
แแแแแแแ แฅแแแแแแแแฎแแ location = /sub-query
, แแ แแฃแแแแขแแแแ แแแฆแแแฃแแ แแแแแแแ (แแแแแแแแ แ แแแแแแแแจแ GET). (r)
แแ แคแฃแแฅแชแแแก แแแแแซแแฎแแแแกแแก แแ แแแแ แแแแแแ. แฅแแแแแแฎแแแแแก แแแกแฃแฎแ แแแแฃแจแแแแแแ แคแฃแแฅแชแแแจแ call_back
.
แแชแแแแแ S3-แก
แแแ แแแ S3 แกแแชแแแแกแแแแก แแแแฎแแแแแก แแแกแแแแแแแแแ, แฉแแแ แแแญแแ แแแแ:
ACCESS_KEY
SECRET_KEY
S3_BUCKET
แแแแแงแแแแแฃแแ http แแแแแแแแแ, แแแแแแแแ แ แแแ แแฆแ/แแ แ, S3_NAME แแ URI, แฌแแ แแแแฅแแแแแ แแแ แแแแฃแแ แขแแแแก แกแขแ แแฅแแแ, แ แแแแแแช แฎแแแแแฌแแ แแแแ (HMAC_SHA1) SECRET_KEY-แแก แแแแแงแแแแแแ. แจแแแแแแ แแ แแก แฎแแแ แแกแแแแกแ AWS $ACCESS_KEY:$HASH
, แจแแแซแแแแ แแแแแงแแแแแฃแ แแฅแแแก แแแขแแ แแแแชแแแก แกแแแแฃแ แจแ. แแแแแ แแแ แแฆแ/แแ แ, แ แแแแแแช แแแแแงแแแแแฃแแ แแงแ แฌแแแ แแขแแแแ แกแขแ แแฅแแแแก แแแแแ แแ แแแแกแแแแก, แฃแแแ แแแแแแขแแก แกแแแแฃแ แก X-amz-date
. แแแแจแ แแกแ แแแแแแงแฃแ แแแ:
nginx.conf
load_module modules/ngx_http_js_module.so;
http {
js_import s3 from s3.js;
js_set $s3_datetime s3.date_now;
js_set $s3_auth s3.s3_sign;
server {
listen 8080;
...
location ~* /s3-query/(?<s3_path>.*) {
internal;
proxy_set_header X-amz-date $s3_datetime;
proxy_set_header Authorization $s3_auth;
proxy_pass $s3_endpoint/$s3_path;
}
location ~ "^/(?<prefix>[w-]*)[/]?(?<postfix>[w-.]*)$" {
js_content s3.request;
}
}
s3.js
(AWS Sign v2 แแแขแแ แแแแชแแแก แแแแแแแแ, แจแแแชแแแแ แแแซแแแแแแฃแแ แกแขแแขแฃแกแแ)
var crypt = require('crypto');
var s3_bucket = process.env.S3_BUCKET;
var s3_access_key = process.env.S3_ACCESS_KEY;
var s3_secret_key = process.env.S3_SECRET_KEY;
var _datetime = new Date().toISOString().replace(/[:-]|.d{3}/g, '');
function date_now() {
return _datetime
}
function s3_sign(r) {
var s2s = r.method + 'nnnn';
s2s += `x-amz-date:${date_now()}n`;
s2s += '/' + s3_bucket;
s2s += r.uri.endsWith('/') ? '/' : r.variables.s3_path;
return `AWS ${s3_access_key}:${crypt.createHmac('sha1', s3_secret_key).update(s2s).digest('base64')}`;
}
function request(r) {
var v = r.variables;
function call_back(resp) {
r.return(resp.status, resp.responseBody);
}
var _subrequest_uri = r.uri;
if (r.uri === '/') {
// root
_subrequest_uri = '/?delimiter=/';
} else if (v.prefix !== '' && v.postfix === '') {
// directory
var slash = v.prefix.endsWith('/') ? '' : '/';
_subrequest_uri = '/?prefix=' + v.prefix + slash;
}
r.subrequest(`/s3-query${_subrequest_uri}`, { method: r.method }, call_back);
}
export default {request, s3_sign, date_now}
แชแแขแ แแฎแกแแ แแแแก แจแแกแแฎแแ _subrequest_uri
: แแก แแ แแก แชแแแแแ, แ แแแแแแช, แกแแฌแงแแกแ แฃแ แแแแ แแแแแแแแแแ แ, แฅแแแแก แแแแฎแแแแแก S3-แแ. แแฃ แแฅแแแ แแญแแ แแแแแ "root"-แแก แจแแแแแ แกแแก แแแฆแแแ, แแแจแแ แฃแแแ แจแแฅแแแแ uri แแแแฎแแแแ, แ แแแแแแช แแแฃแแแแแแก แแแแแแแขแแ แแ. delimiter
, แ แแแแแแช แแแแแ แฃแแแแก แงแแแแ CommonPrefixes xml แแแแแแแขแแแแก แกแแแก, แ แแแแแแช แจแแแกแแแแแแแ แแแ แแฅแขแแ แแแแแก (PyPI-แก แจแแแแฎแแแแแจแ, แงแแแแ แแแแแขแแก แกแแแก). แแฃ แแฅแแแ แแญแแ แแแแแ แจแแแแแแกแแแแก แกแแแก แแแฆแแแ แแแแแ แแขแฃแ แแแ แแฅแขแแ แแแจแ (แแแแแขแแก แงแแแแ แแแ แกแแแก แกแแ), แแแจแแ uri แแแแฎแแแแ แฃแแแ แจแแแชแแแแแก แแ แแคแแฅแกแแก แแแแก แแแ แแฅแขแแ แแแก (แแแแแขแแก) แกแแฎแแแฌแแแแแแ, แ แแแแแแช แแฃแชแแแแแแแ แแแแแ แแแแ แฎแแแแแแ /. แฌแแแแแฆแแแแ แจแแแแฎแแแแแจแ, แจแแฏแแฎแแแ แจแแกแแซแแแแแแแ, แแแแแแแแแ, แแแ แแฅแขแแ แแแจแ แจแแแแแแกแแก แแแแฎแแแแแกแแก. แแ แแก แแแ แแฅแขแแ แแแแ aiohttp-แแแแฎแแแแ แแ aiohttp-แแแแฎแแแแแแ แแ แแฃ แแแแฎแแแแ แแแแกแแแฆแแ แแแก /?prefix=aiohttp-request
, แแแจแแ แแแกแฃแฎแ แจแแแชแแแก แแ แแแ แแแ แแฅแขแแ แแแก แจแแแแแ แกแก. แแฃ แแแแแจแ แแ แแก แฎแแแแแกแแ, /?prefix=aiohttp-request/
, แแแจแแ แแแกแฃแฎแ แจแแแชแแแก แแฎแแแแ แกแแญแแ แ แแแ แแฅแขแแ แแแก. แแ แแฃ แแแแแแฎแแแ แคแแแแก, แแแจแแ แแแฆแแแฃแแ แฃแ แ แแ แฃแแแ แแแแกแฎแแแแแแแแแแก แแ แแแแแแแแกแแแ.
แจแแแแแฎแแ แแ แแแแแขแแแ แแแ Nginx. แแ แแฃแแแ แจแ แฉแแแ แแฌแแ แ แฉแแแแ Nginx-แแก แแแกแแแแ แแก, แแแแฎแแแแแก แจแแแแแ แแฅแแแแ XML, แแแแแแแแแ:
แแแ แแฅแขแแ แแแแแก แกแแ
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>myback-space</Name>
<Prefix></Prefix>
<Marker></Marker>
<MaxKeys>10000</MaxKeys>
<Delimiter>/</Delimiter>
<IsTruncated>false</IsTruncated>
<CommonPrefixes>
<Prefix>new/</Prefix>
</CommonPrefixes>
<CommonPrefixes>
<Prefix>old/</Prefix>
</CommonPrefixes>
</ListBucketResult>
แแแ แแฅแขแแ แแแแแก แกแแแแแ แแแแญแแ แแแแแ แแฎแแแแ แแแแแแแขแแแ CommonPrefixes
.
แแ แแฃแแแ แจแ แฉแแแแก แแแกแแแแ แแแ แกแแญแแ แ แแแ แแฅแขแแ แแแก แแแแแขแแแแ, แฉแแแ แแกแแแ แแแแแฆแแแ แแแก แจแแแแแแกแก XML แกแแฎแแ:
แคแแแแแแแก แกแแ แแแ แแฅแขแแ แแแจแ
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name> myback-space</Name>
<Prefix>old/</Prefix>
<Marker></Marker>
<MaxKeys>10000</MaxKeys>
<Delimiter></Delimiter>
<IsTruncated>false</IsTruncated>
<Contents>
<Key>old/giphy.mp4</Key>
<LastModified>2020-08-21T20:27:46.000Z</LastModified>
<ETag>"00000000000000000000000000000000-1"</ETag>
<Size>1350084</Size>
<Owner>
<ID>02d6176db174dc93cb1b899f7c6078f08654445fe8cf1b6ce98d8855f66bdbf4</ID>
<DisplayName></DisplayName>
</Owner>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>old/hsd-k8s.jpg</Key>
<LastModified>2020-08-31T16:40:01.000Z</LastModified>
<ETag>"b2d76df4aeb4493c5456366748218093"</ETag>
<Size>93183</Size>
<Owner>
<ID>02d6176db174dc93cb1b899f7c6078f08654445fe8cf1b6ce98d8855f66bdbf4</ID>
<DisplayName></DisplayName>
</Owner>
<StorageClass>STANDARD</StorageClass>
</Contents>
</ListBucketResult>
แคแแแแแแแก แกแแแแแ แฉแแแ แแแแฆแแแ แแฎแแแแ แแแแแแแขแแแก Key
.
แ แฉแแแ แแฎแแแแ แแแฆแแแฃแแ XML-แแก แแแแแแแแแแแ แแ HTML แกแแฎแแ แแแแแแแแ, แแแก แจแแแแแ, แ แแช แฏแแ Content-Type แกแแแแฃแ แ แขแแฅแกแขแแ/html-แแ แจแแแชแแแแ.
function request(r) {
var v = r.variables;
function call_back(resp) {
var body = resp.responseBody;
if (r.method !== 'PUT' && resp.status < 400 && v.postfix === '') {
r.headersOut['Content-Type'] = "text/html; charset=utf-8";
body = toHTML(body);
}
r.return(resp.status, body);
}
var _subrequest_uri = r.uri;
...
}
function toHTML(xml_str) {
var keysMap = {
'CommonPrefixes': 'Prefix',
'Contents': 'Key',
};
var pattern = `<k>(?<v>.*?)</k>`;
var out = [];
for(var group_key in keysMap) {
var reS;
var reGroup = new RegExp(pattern.replace(/k/g, group_key), 'g');
while(reS = reGroup.exec(xml_str)) {
var data = new RegExp(pattern.replace(/k/g, keysMap[group_key]), 'g');
var reValue = data.exec(reS);
var a_text = '';
if (group_key === 'CommonPrefixes') {
a_text = reValue.groups.v.replace(///g, '');
} else {
a_text = reValue.groups.v.split('/').slice(-1);
}
out.push(`<a href="/ka/${reValue.groups.v}">${a_text}</a>`);
}
}
return '<html><body>n' + out.join('</br>n') + 'n</html></body>'
}
PyPI-แก แแชแแแแแแ
แฉแแแ แแแแแฌแแแแ, แ แแ แแ แแคแแ แ แแจแแแแ แแ แกแแ แแ แแแแแขแแแแ, แ แแแแแแแช แชแแแแแแแ, แ แแ แแฃแจแแแแก.
# ะกะพะทะดะฐะตะผ ะดะปั ัะตััะพะฒ ะฝะพะฒะพะต ะพะบััะถะตะฝะธะต
python3 -m venv venv
. ./venv/bin/activate
# ะกะบะฐัะธะฒะฐะตะผ ัะฐะฑะพัะธะต ะฟะฐะบะตัั.
pip download aiohttp
# ะะฐะณััะถะฐะตะผ ะฒ ะฟัะธะฒะฐัะฝัั ัะตะฟั
for wheel in *.whl; do curl -T $wheel http://localhost:8080/${wheel%%-*}/$wheel; done
rm -f *.whl
# ะฃััะฐะฝะฐะฒะปะธะฒะฐะตะผ ะธะท ะฟัะธะฒะฐัะฝะพะน ัะตะฟั
pip install aiohttp -i http://localhost:8080
แฉแแแ แแแแแแ แแแ แฉแแแแ แแแแแ.
# ะกะพะทะดะฐะตะผ ะดะปั ัะตััะพะฒ ะฝะพะฒะพะต ะพะบััะถะตะฝะธะต
python3 -m venv venv
. ./venv/bin/activate
pip install setuptools wheel
python setup.py bdist_wheel
for wheel in dist/*.whl; do curl -T $wheel http://localhost:8080/${wheel%%-*}/$wheel; done
pip install our_pkg --extra-index-url http://localhost:8080
CI-แจแ แแแแแขแแก แจแแฅแแแ แแ แฉแแขแแแ แแแ แแกแ แแแแแแงแฃแ แแแ:
pip install setuptools wheel
python setup.py bdist_wheel
curl -sSfT dist/*.whl -u "gitlab-ci-token:${CI_JOB_TOKEN}" "https://pypi.our-domain.com/${CI_PROJECT_NAME}"
แแแแแแขแแคแแแแชแแ
Gitlab-แจแ แจแแกแแซแแแแแแแ JWT-แแก แแแแแงแแแแแ แแแ แ แกแแ แแแกแแแแก แแแแแแขแแคแแแแชแแแก/แแแขแแ แแแแชแแแกแแแแก. Nginx-แจแ auth_request แแแ แแฅแขแแแแก แแแแแงแแแแแแ, แฉแแแ แแแแแแแงแแแแ แแแแแแขแแคแแแแชแแแก แแแแแชแแแแแก แฅแแแแแแฎแแแแแแ, แ แแแแแแช แจแแแชแแแก แคแฃแแฅแชแแแก แแแแแซแแฎแแแแก แกแแ แแแขแจแ. แกแแ แแแขแ แแแแแ แแ แ แฅแแแแแแฎแแแแแก แแแฃแแแแแแก Gitlab url-แก แแ แแฃ แแแแแแขแแคแแแแชแแแก แแแแแชแแแแแ แกแฌแแ แแ แแงแ แแแแแแแแฃแแ, แแแจแแ Gitlab แแแแแ แฃแแแแก แแแแก 200 แแ แแแแแแแ แแฃแแ แแฅแแแแ แแแแแขแแก แแขแแแ แแแ/แฉแแแแขแแแ แแแ. แ แแขแแ แแ แแแแแแงแแแแ แแ แแ แฅแแแแแแฎแแแแ แแ แแแฃแงแแแแแแแแ แแแแแแแแแ แแแแแชแแแแแ Gitlab-แจแ? แแแแก แแแแ, แ แแ แแแจแแ แฉแแแ แแแแแแฌแแแก Nginx-แแก แแแแคแแแฃแ แแชแแแก แคแแแแแก แ แแแแฅแขแแ แแแ แงแแแแ แฏแแ แแ, แ แแชแ แ แแแแ แชแแแแแแแแก แจแแแแขแแแ แแแขแแ แแแแชแแแจแ แแ แแก แกแแแแแแ แแแแฆแแแแ แแแแชแแแแ. แแกแแแ, แแฃ Kubernetes แแงแแแแแก แแฎแแแแ แฌแแกแแแแแฎแแ root แคแแแแฃแ แ แกแแกแขแแแแก แแแแแขแแแแก, แแแจแแ แแก แแแแแ แฃแคแ แ แแแข แกแแ แแฃแแแก แแแขแแแก nginx.conf-แแก แฉแแแแชแแแแแแกแแก configmap-แแ. แแ แแแกแแแฃแขแฃแ แแ แจแแฃแซแแแแแแ แฎแแแแ Nginx-แแก แแแแคแแแฃแ แแชแแ configmap-แแก แกแแจแฃแแแแแแ, แแแแแแ แแฃแแแ, แแแแแขแแแแก แแแแแงแแแแแแกแแก, แ แแแแแแช แแ แซแแแแแก แขแแแแแแก (pvc) แแ แแฎแแแแ แฌแแแแแฎแแแแ root แคแแแแฃแ แ แกแแกแขแแแแก แแแแแแจแแ แแแแก (แแก แแกแแแ แฎแแแแ).
NJS แจแฃแแแแแฃแ แแก แแแแแงแแแแแแ, แฉแแแ แแแฆแแแ แจแแกแแซแแแแแแแแก แจแแแชแแแแแ แแแแแแแแฃแแ แแแ แแแแขแ แแแ nginx แแแแคแแแฃแ แแชแแแจแ แแแ แแแแก แชแแแแแแแแก แแแแแงแแแแแแ แแ แแแแแแแแแ แแแ แแแแฃแแ แจแแแแฌแแแแ แกแแ แแแขแจแ (แแแแแแแแแ, แแ แแกแฌแแ แแ แแแแแแแแฃแแ URL).
nginx.conf
location = /auth-provider {
internal;
proxy_pass $auth_url;
}
location = /auth {
internal;
proxy_set_header Content-Length "";
proxy_pass_request_body off;
js_content auth.auth;
}
location ~ "^/(?<prefix>[w-]*)[/]?(?<postfix>[w-.]*)$" {
auth_request /auth;
js_content s3.request;
}
s3.js
var env = process.env;
var env_bool = new RegExp(/[Tt]rue|[Yy]es|[Oo]n|[TtYy]|1/);
var auth_disabled = env_bool.test(env.DISABLE_AUTH);
var gitlab_url = env.AUTH_URL;
function url() {
return `${gitlab_url}/jwt/auth?service=container_registry`
}
function auth(r) {
if (auth_disabled) {
r.return(202, '{"auth": "disabled"}');
return null
}
r.subrequest('/auth-provider',
{method: 'GET', body: ''},
function(res) {
r.return(res.status, "");
});
}
export default {auth, url}
แแแแ แแแแแแแแแ แฉแแแแแ แแแแฎแแ: -แ แแขแแ แแ แแแแแแงแแแแ แแแ แแแแฃแแแแ? แแฅ แฃแแแ แงแแแแแคแแ แ แแแแแแแ! แแแแแแแแแ, var AWS = แแแแแฎแแแก ('aws-sdk') แแ แแ แแ แแก แกแแญแแ แ โแแแแแกแแแแแแกโ แแแฌแแ แ S3 แแแแแแขแแคแแแแชแแแ!
แแแแแ แแแแแแแแแ แแแแฃแกแแแแ
แฉแแแแแแก แแแ แ JS แแแแฃแแแแแก แแแแแ แขแแก แจแแฃแซแแแแแแแ แแแฎแแ แฃแกแแแแแแแ, แแแแ แแ แแแกแแแแแแแแ แคแฃแแฅแชแแ. แแแแแ แแแงแแแแแ แแแแแแแแจแ แแฆแฌแแ แแแ แแแแฎแแแแ('แแ แแแขแ') แแ แแก
แจแแแฃแแจแแ แแกแแแ แฃแแแ แแงแแก แแแแแ แแฃแแ Nginx-แแก แแแแแแแแ แ แแ แแแฅแขแแกแแแแก gzip off;
แแแแก แแแแ, แ แแ NJS-แจแ แแ แแ แแก gzip แแแแฃแแ แแ แแแกแ แแแแแแจแแ แแแ แจแแฃแซแแแแแแแ, แจแแกแแแแแแกแแ, แจแแแฃแแจแฃแ แแแแแชแแแแแแแ แแฃแจแแแแ แแ แแ แกแแแแแก. แแแ แแแแแ, แแก แแ แกแแฅแแแก แแแแฃแกแ แแแแแแแแแ แแ แแ แแก. แแแแ แ แขแแฅแกแขแ แแ แแ แแก แแ แแแแแชแแแฃแแ แคแแแแแแ แฃแแแ แจแแแฃแแจแฃแแแ แแ แแแแแขแแแแแ แจแแแฃแแจแแ แแแ แแแแแ แแ แแแแฎแแแ แแแ. แแกแแแ, แแก แแ แแ แแก แแกแแแ แแแขแแแ แแฃแแ แแ แแ แแขแแแฃแแ แกแแ แแแกแ, แ แแ แแแแแฌแแแ แจแแฌแฃแฎแแแ แจแแแแแ แกแแก แ แแแแแแแแ แแแแแฌแแแแ แกแฌแ แแคแแ แแแฌแแแแแแ.
แกแแ แแแขแแก แแแแแ แแแแก แแแแ แแ แ แกแญแแ แแแแ แแ แจแแกแแซแแแแแแแ แแฎแแแแ error.log-แจแ โแแแญแแแแกโ แกแแจแฃแแแแแแ. แแแงแแแแแฃแแ แแฃแ แแแแแก แแแแแก แแแคแแ แแแชแแแก, แแแคแ แแฎแแแแแแก แแ แจแแชแแแแแก แแแฎแแแแแ, แจแแกแแซแแแแแแแ แแแแแแงแแแแ 3 แแแแแแ, แจแแกแแแแแแกแแ, r.log, r.warn, r.error. แแชแแแแแ แแแแแแ แแ แกแแ แแแขแแก แแแแแ แแแแก Chrome (v8) แแ njs แแแแกแแแแก แฎแแแกแแฌแงแแจแ, แแแแ แแ แแฅ แงแแแแแคแ แแก แจแแแแฌแแแแ แแ แจแแแซแแแแ. แแแแแก แแแแแ แแแแกแแก, แแแฃ แคแฃแแฅแชแแฃแ แ แขแแกแขแแ แแแแกแแก, แแกแขแแ แแ แแกแ แแแแแแงแฃแ แแแ:
docker-compose restart nginx
curl localhost:8080/
docker-compose logs --tail 10 nginx
แแ แจแแแซแแแแ แแงแแก แแกแแแแ แแกแแแ แแแแแแแแแแ แแแ.
แแแแแแแก แฅแแแแแแแแฎแแแแแกแ แแ แชแแแแแแแแก แแแแแงแแแแแแ แแแแแก แแแฌแแ แ แฉแแฎแแแ แแฃแ แแฃแ แแแฃแ แจแ แแฅแชแแแ. แฎแแแแแฎแแ แแฌแงแแ แฉแฅแแ แแแแก แกแฎแแแแแกแฎแแ IDE แคแแแฏแ แแแแก แแแ แจแแแ, แ แแแ แแแแ แแแแ แจแแแ แแแแแก แแแฅแแแแแแแแแก แแแแแแแแแแ แแแ. แแก แแ แแ แแก แ แแฃแแ, แแแแ แแ แแแแฏแแ แซแแแแแ แแแแแฆแแแแแแแแแแแ.
ES6-แแก แกแ แฃแแ แแฎแแ แแแญแแ แ แแ แแ แกแแแแแก.
แจแแแซแแแแ แกแฎแแ แฎแแ แแแแแแแช แแงแแก, แแแแ แแ แกแฎแแ แแ แแคแแ แ แจแแแฎแแแแ แแ. แแแแแแแ แแ แแแคแแ แแแชแแ, แแฃ แแแฅแแ NJS-แแก แแแแแงแแแแแแก แฃแแ แงแแคแแแ แแแแแชแแแแแแ.
แแแกแแแแ
NJS แแ แแก แแกแฃแแฃแฅแ แฆแแ แแแแแก แแแ แฏแแแแแ, แ แแแแแแช แกแแจแฃแแแแแแก แแแซแแแแ แแแแแฎแแ แชแแแแแ แกแฎแแแแแกแฎแแ JavaScript แกแแ แแแขแแแ Nginx-แจแ. แแแกแ แแแแแแแแ แแแแก แแ แแก แแแแ แงแฃแ แแแฆแแแ แแแแแแ แจแแกแ แฃแแแแแก. แ แ แแฅแแ แฃแแแ, แฏแแ แแแแแ แแแแ แ แแแแแ, แแแแ แแ แแ แแแฅแขแก แแชแแ แ แแฃแแแ แแแฃแจแแแแแก แแ แแฅแขแแฃแ แแ แแแแขแแแแ แแฎแแ แคแฃแแฅแชแแแแก แแ แแกแฌแแ แแแแ แจแแชแแแแแแก. แแแแแแแแแแ, แ แแ แแแแกแแ NJS แแแแชแแแ แกแแจแฃแแแแแแก แแแแแแแจแแ แแ แแแ แ แแแแฃแแแแ, แ แแช Nginx-แแก แคแฃแแฅแชแแแแแ แแแแก แแแแฅแแแก แจแแฃแแฆแฃแแแแ แแแฎแแแก. แแแแ แแ แแ แกแแแแแก NGINX Plus แแ, แกแแแแ แแฃแแแ, แแ แแฅแแแแ แคแฃแแฅแชแแแแ!
แฌแงแแ แ: www.habr.com