Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ repos:
- id: trailing-whitespace

- repo: https://github.com/psf/black
rev: 22.1.0
rev: 22.3.0
hooks:
- id: black
args: ['--skip-string-normalization']
Expand Down
6 changes: 6 additions & 0 deletions lain_cli/cluster_values/values-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

# 镜像仓库
registry: docker.io/timfeirg
# 默认使用 http 访问 registry ,可以配置为使用 https
# registry_endpoint_use_https: yes

# 有一些 PaaS 提供内网镜像加速, 集群内外用的镜像 tag 不一样
# internalRegistry: registry.in.example.com
Expand All @@ -25,6 +27,10 @@ secrets_env:
dockerhub_username: DOCKERHUB_USERNAME
dockerhub_password: DOCKERHUB_PASSWORD

# 或者提供获取访问 registry api 需要的 access token 的获取命令。如 AWS ECR ,可以这样配置:
# registry_token_fetch_cmd: "aws ecr get-authorization-token --output text --query 'authorizationData[].authorizationToken'"
# registry_token_type: "Basic"

extra_docs: |
在这里书写额外的欢迎信息

Expand Down
59 changes: 41 additions & 18 deletions lain_cli/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
import requests
from tenacity import retry, stop_after_attempt, wait_fixed

from lain_cli.utils import RegistryUtils, RequestClientMixin, tell_cluster_config
from lain_cli.utils import (
RegistryUtils,
RequestClientMixin,
subprocess_run,
tell_cluster_config,
)


class Registry(RequestClientMixin, RegistryUtils):
Expand All @@ -25,27 +30,45 @@ def __init__(self, registry=None, **kwargs):
api_host = 'index.docker.io'
self.endpoint = f'http://{api_host}'
else:
self.endpoint = f'http://{registry}'
https = kwargs.get('registry_endpoint_use_https', False)
protocol = 'https' if https else 'http'
self.endpoint = f'{protocol}://{registry}'

self.dockerhub_password = kwargs.get('dockerhub_password')
self.dockerhub_username = kwargs.get('dockerhub_username')

self.token_fetch_cmd = kwargs.get('registry_token_fetch_cmd')
self.token_type = kwargs.get('registry_token_type', 'Bearer')

def prepare_token(self, scope):
if not all([self.dockerhub_password, self.dockerhub_username]):
return
res = requests.post(
'https://auth.docker.io/token',
data={
'grant_type': 'password',
'service': 'registry.docker.io',
'scope': scope,
'client_id': 'dockerengine',
'username': self.dockerhub_username,
'password': self.dockerhub_password,
},
)
access_token = res.json()['access_token']
self.headers['Authorization'] = f'Bearer {access_token}'
if self.token_fetch_cmd:
res = subprocess_run(
self.token_fetch_cmd,
shell=True,
check=True,
capture_output=True,
)
token = res.stdout.decode().strip()

elif all([self.dockerhub_password, self.dockerhub_username]):
res = requests.post(
'https://auth.docker.io/token',
data={
'grant_type': 'password',
'service': 'registry.docker.io',
'scope': scope,
'client_id': 'dockerengine',
'username': self.dockerhub_username,
'password': self.dockerhub_password,
},
)
token = res.json()['access_token']

else:
token = None

if token:
self.headers['Authorization'] = f'{self.token_type} {token}'

def request(self, *args, **kwargs):
res = super().request(*args, **kwargs)
Expand Down Expand Up @@ -79,7 +102,7 @@ def list_tags(self, repo_name, n=None, timeout=90):
repo = f'{self.namespace}/{repo_name}' if self.namespace else repo_name
path = f'/v2/{repo}/tags/list'
self.prepare_token(scope=f'repository:{repo}:pull,push')
responson = self.get(path, params={'n': 99999}, timeout=timeout).json()
responson = self.get(path, params={'n': 1000}, timeout=timeout).json()
if 'tags' not in responson:
return []
tags = self.sort_and_filter(responson.get('tags') or [], n=n)
Expand Down