Compare commits

...

3 commits

Author SHA1 Message Date
Benjamin Renard
6d7c03fb3d Fix publishing snapshot
When calling APTLY publish API, we have to pass the distribution name
and not the repository name. Distribution names are now collected from
changes files and a call to the APTLY publish API will be made for all
updated distribution.

Also add a PREFIX parameter to permit to specify the APTLY prefix (and
storage if it need to be specified).
2022-11-30 20:23:41 +01:00
Benjamin Renard
59214019ba Allow to set parameter using environment variables PLUGIN_* or APTLY_* 2022-11-30 20:15:37 +01:00
Benjamin Renard
4529061bc4 Rename entrypoint.py to aptly-publish 2022-11-30 20:13:57 +01:00
2 changed files with 67 additions and 50 deletions

View file

@ -1,6 +1,6 @@
FROM alpine FROM alpine
ADD entrypoint.py /bin/ ADD aptly-publish /bin/
RUN chmod +x /bin/entrypoint.py RUN chmod +x /bin/aptly-publish
RUN apk -Uuv add python3 py3-requests py3-urllib3 py3-pip RUN apk -Uuv add python3 py3-requests py3-urllib3 py3-pip
RUN pip install debian-parser RUN pip install debian-parser
ENTRYPOINT /bin/entrypoint.py ENTRYPOINT /bin/aptly-publish

View file

@ -16,28 +16,38 @@ from urllib3.util import Retry
from debian_parser import PackagesParser from debian_parser import PackagesParser
def from_env(name, default=None):
""" Retrieve a parameter from environment """
for var in (f'PLUGIN_{name}', f'APTLY_{name}'):
if var in os.environ:
return os.environ[var]
return default
# Handle parameters from environment # Handle parameters from environment
API_URL = os.environ.get('PLUGIN_API_URL', None) API_URL = from_env('API_URL', None)
if not API_URL: if not API_URL:
print('API URL not provided') print('API URL not provided')
sys.exit(1) sys.exit(1)
API_USERNAME = os.environ.get('PLUGIN_API_USERNAME', None) API_USERNAME = from_env('API_USERNAME', None)
if not API_USERNAME: if not API_USERNAME:
print('API username not provided') print('API username not provided')
sys.exit(1) sys.exit(1)
API_PASSWORD = os.environ.get('PLUGIN_API_PASSWORD', None) API_PASSWORD = from_env('API_PASSWORD', None)
if not API_PASSWORD: if not API_PASSWORD:
print('API password not provided') print('API password not provided')
sys.exit(1) sys.exit(1)
MAX_RETRY = os.environ.get('PLUGIN_MAX_RETRIES', None) MAX_RETRY = from_env('MAX_RETRIES', None)
REPO_NAME = os.environ.get('PLUGIN_REPO_NAME', 'stable') REPO_NAME = from_env('REPO_NAME', 'stable')
REPO_COMPONENT = os.environ.get('PLUGIN_REPO_COMPONENT', 'main') PREFIX = from_env('PREFIX', '.')
DIST = os.environ.get('PLUGIN_PATH', 'dist') REPO_COMPONENT = from_env('REPO_COMPONENT', 'main')
SOURCE_NAME = os.environ.get('PLUGIN_SOURCE_PACKAGE_NAME', None) INPUT_PATH = from_env('PATH', 'dist')
SOURCE_NAME = from_env('SOURCE_PACKAGE_NAME', None)
DISTRIBUTIONS = []
# List changes files # List changes files
changes_files_regex = ( changes_files_regex = (
@ -48,21 +58,21 @@ changes_files_regex = (
) )
changes_files = [] changes_files = []
try: try:
for filename in os.listdir(DIST): for filename in os.listdir(INPUT_PATH):
filepath = os.path.join(DIST, filename) filepath = os.path.join(INPUT_PATH, filename)
if not os.path.isfile(filepath): if not os.path.isfile(filepath):
continue continue
if changes_files_regex.match(filename): if changes_files_regex.match(filename):
changes_files.append(filepath) changes_files.append(filepath)
except FileNotFoundError: except FileNotFoundError:
print(f'Specified directory path "{DIST}" not found') print(f'Specified directory path "{INPUT_PATH}" not found')
sys.exit(1) sys.exit(1)
except NotADirectoryError: except NotADirectoryError:
print(f'Specified path "{DIST}" is not a directory') print(f'Specified path "{INPUT_PATH}" is not a directory')
sys.exit(1) sys.exit(1)
if not changes_files: if not changes_files:
print(f'No changes file found in {DIST}') print(f'No changes file found in {INPUT_PATH}')
sys.exit(1) sys.exit(1)
@ -88,13 +98,14 @@ def list_files_in_changes_file(filepath):
files = [] files = []
for infos in parser.parse(): for infos in parser.parse():
for info in infos: for info in infos:
if info['tag'].lower() != 'files': if info['tag'].lower() == 'files':
continue
for line in info['value'].split(' '): for line in info['value'].split(' '):
if not line: if not line:
continue continue
files.append(os.path.join(dirpath, line.split()[-1])) files.append(os.path.join(dirpath, line.split()[-1]))
if info['tag'].lower() == 'distribution':
if info['value'] not in DISTRIBUTIONS:
DISTRIBUTIONS.append(info['value'])
return files return files
@ -137,7 +148,9 @@ def include_file(package_name, changes_file):
result.status_code == 200 and result.status_code == 200 and
data.get('Report', {}).get('Added') data.get('Report', {}).get('Added')
): ):
print(f'Unknown error occurred including {changes_file}') print(
f'Unknown error occurred including {changes_file}'
'See APTLY API logs for details.')
return False return False
return True return True
@ -150,9 +163,8 @@ for changes_file in changes_files:
for filepath in filepaths: for filepath in filepaths:
if not upload_file(package_name, filepath): if not upload_file(package_name, filepath):
print( print(
f' - {filepath}: fail to upload file, pass this changes ' f' - {filepath}: fail to upload file. See APTLY API logs '
'file' 'for details.')
)
sys.exit(1) sys.exit(1)
else: else:
print(f' - {filepath}') print(f' - {filepath}')
@ -182,30 +194,35 @@ error = (
not data.get('CreatedAt') not data.get('CreatedAt')
) )
if error: if error:
print(f'Fail to create snapshot "{snap_name}" of repository "{REPO_NAME}"') print(
f'Fail to create snapshot "{snap_name}" of repository "{REPO_NAME}".'
'See APTLY API logs for details.')
sys.exit(1) sys.exit(1)
# Update published snapshot of repository # Update published snapshot of repository for each distributions
print( for distribution in DISTRIBUTIONS:
f'Update published snapshot of repository "{REPO_NAME}" to "{snap_name}"') print(
url = f'{API_URL}/publish/:./{REPO_NAME}' f'Update published snapshot of distribution "{distribution}" to '
payload = { f'"{snap_name}" (prefix: {PREFIX})')
url = f'{API_URL}/publish/:{PREFIX}/{distribution}'
payload = {
'Snapshots': [ 'Snapshots': [
{ {
'Component': REPO_COMPONENT, 'Component': REPO_COMPONENT,
'Name': snap_name 'Name': snap_name
} }
] ]
} }
result = session.put(url, json=payload) result = session.put(url, json=payload)
if ( if (
result.status_code < 200 or result.status_code < 200 or
result.status_code > 299 result.status_code > 299
): ):
print( print(
f'Fail to update published snapshot of repository "{REPO_NAME}" to ' f'Fail to update published snapshot of distribution "{distribution}" '
f'"{snap_name}"') f'to "{snap_name}" (prefix: {PREFIX}). See APTLY API logs for '
'details.')
sys.exit(1) sys.exit(1)
print("Done.") print("Done.")