Skip to content
Snippets Groups Projects
Commit b0d361f0 authored by gyulaid's avatar gyulaid
Browse files

repo image build + bump version

parent 5cef2729
Branches
Tags
No related merge requests found
[metadata]
name = alice-ci
version = 0.0.13
version = 0.0.14
author = Daniel Gyulai
description = Alice CI framework
long_description = file: README.md
......
......@@ -34,6 +34,7 @@ def parse_jobs(args):
exit(1)
except RunnerError as e:
print(f"RunnerError-> {e}")
exit(1)
def main():
......
import logging
import subprocess
import docker
from os.path import join, isdir
from os import getcwd, mkdir
import os
import requests
import platform
import time
from ..exceptions import RunnerError
from ..config import ConfigHolder
pipconf = """[global]
index-url = URL
trusted-host = BASE
......@@ -30,25 +35,60 @@ class RepoConfig:
class PypiRepoRunner:
def __init__(self, config) -> None:
logging.info("[PythonRunner] Initializing")
logging.info("[PyPiRepo] Initializing")
self.config = RepoConfig(config)
self.client = docker.from_env()
self.user = "alice"
self.passwd = "alice"
self.htpasswd = 'alice:{SHA}UisnajVr3zkBPfq+os1D4UHsyeg='
def __is_running(self, name):
def get_image(self):
# TODO: remove when resolved:
# Official Docker image support for ARM?
# https://github.com/pypiserver/pypiserver/issues/364
pypiserver = "https://github.com/pypiserver/pypiserver.git"
if platform.machine() == "aarch64":
tag = "alice.localhost/pypiserver:arm"
try:
self.client.containers.get(name)
return True
except docker.errors.NotFound:
return False
self.client.images.get(tag)
return tag
except docker.errors.ImageNotFound:
print("[PyPiRepo] Building PyPiServer ARM image, this could take a while")
workdir = join(getcwd(), ".alice", "pypirepo", "source")
if not os.path.isdir(workdir):
os.mkdir(workdir)
git_command = ["git", "clone", pypiserver, "--branch=v1.3.2"]
output = []
with subprocess.Popen(git_command, cwd=workdir, stdout=subprocess.PIPE) as p:
for line in p.stdout:
output.append(line.decode('utf8').strip())
p.wait()
if p.returncode != 0:
print("\n".join(output))
raise(RunnerError("[PyPiRepo] Could not fetch pypiserver source"))
source_path = os.path.join(workdir, "pypiserver")
self.client.images.build(path=source_path, tag=tag)
return tag
else:
return "pypiserver/pypiserver:latest"
def run(self, job_spec):
job_config = self.config.copy(job_spec)
running = self.__is_running(job_config.container_name)
print(f"[PyPiRepo] {job_config.container_name} running: {running}")
docker_host_ip = None
for network in self.client.networks.list():
if network.name == "bridge":
try:
docker_host_ip = network.attrs["IPAM"]["Config"][0]["Gateway"]
except KeyError:
docker_host_ip = network.attrs["IPAM"]["Config"][0]["Subnet"].replace(".0/16", ".1")
if docker_host_ip is None:
raise RunnerError("Unable to determine Docker host IP")
if job_config.enabled:
try:
c = self.client.containers.get(job_config.container_name)
print(f"[PyPiRepo] {job_config.container_name} already running")
except docker.errors.NotFound:
persistency_dir = join(getcwd(), ".alice", "pypirepo")
if not isdir(persistency_dir):
mkdir(persistency_dir)
......@@ -61,21 +101,9 @@ class PypiRepoRunner:
with open(htpasswd_file, 'w') as f:
f.write(self.htpasswd)
docker_host_ip = None
for network in self.client.networks.list():
if network.name == "bridge":
try:
docker_host_ip = network.attrs["IPAM"]["Config"][0]["Gateway"]
except KeyError:
docker_host_ip = network.attrs["IPAM"]["Config"][0]["Subnet"].replace(".0/16", ".1")
if docker_host_ip is None:
raise RunnerError("Unable to determine Docker host IP")
if job_config.enabled:
if not running:
c = self.client.containers.run(
name=job_config.container_name,
image="pypiserver/pypiserver:latest",
image=self.get_image(),
detach=True,
labels={"app": "alice"},
command=["--overwrite", "-P", ".htpasswd", "packages"],
......@@ -94,12 +122,32 @@ class PypiRepoRunner:
"Name": "unless-stopped"
}
)
print(f"[PyPiRepo] Started {job_config.container_name}")
c.reload()
print(f"[PyPiRepo] {job_config.container_name} : {c.status}")
logging.info(f"[PyPiRepo] {job_config.container_name} : {c.status}")
if c.status != "running":
raise RunnerError(f"[PyPiRepo] Repo container unstable: {c.status}")
uri = f"http://localhost:{job_config.port}"
unreachable = True
attempts = 0
while unreachable and attempts < 5:
attempts += 1
try:
requests.get(uri)
unreachable = False
except Exception as e:
logging.info(f"[PyPiRepo] {attempts} - Repo at {uri} is unavailable: {e}")
time.sleep(2)
if unreachable:
raise RunnerError(f"[PyPiRepo] Repo unreachable")
cfgh = ConfigHolder.getInstance()
cfgh.soft_set("PYPI_USER", self.user)
cfgh.soft_set("PYPI_PASS", self.passwd)
cfgh.soft_set("PYPI_REPO", f"http://localhost:{job_config.port}")
cfgh.soft_set("PYPI_REPO", uri)
cfgh.soft_set("DOCKER_PYPI_USER", self.user)
cfgh.soft_set("DOCKER_PYPI_PASS", self.passwd)
cfgh.soft_set("DOCKER_PYPI_REPO", f"http://{docker_host_ip}:{job_config.port}")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment