Initial commit

This commit is contained in:
Mikhail Gordeev 2022-06-11 01:19:22 +03:00
commit a3883938bc
22 changed files with 620 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
Dockerfile

260
build.py Executable file
View File

@ -0,0 +1,260 @@
#!/usr/bin/python3
import argparse
import os
import re
import subprocess
from graphlib import TopologicalSorter
from pathlib import Path
from jinja2 import Template
IMAGES_DIR = Path("images")
class DockerBuilder:
def make_from_re(self):
registry = r"(?P<registry>[\w.:]+)"
organization = r"(?P<organization>\w+)"
name = r"(?P<name>\w+)"
tag = r"(?P<tag>[\w.]+)"
return f"^FROM (:?{registry}/)?(:?{organization}/)?{name}(:?:{tag})?$"
def __init__(self, registry, organization, latest, dry_run):
self.from_re = re.compile(self.make_from_re())
self.images_dir = IMAGES_DIR
self.registry = registry
self.organization = organization
self.latest = latest
self.dry_run = dry_run
def forall_images(consume_result):
def forall_images_decorator(f):
def wrapped(self, *args, **kwargs):
for image in self.images_dir.iterdir():
local_kwargs = {
"image": image,
"dockerfile": image / "Dockerfile",
"dockerfile_template": image / "Dockerfile.template",
}
new_kwargs = kwargs | local_kwargs
yield f(self, *args, **new_kwargs)
def consumer(*args, **kwargs):
for _ in wrapped(*args, **kwargs):
pass
if consume_result:
return consumer
else:
return wrapped
return forall_images_decorator
@forall_images(consume_result=True)
def remove_dockerfiles(self, **kwargs):
if kwargs["dockerfile"].exists():
kwargs["dockerfile"].unlink()
@forall_images(consume_result=True)
def render_dockerfiles(self, branch, **kwargs):
if kwargs["dockerfile_template"].exists():
if self.registry:
registry = self.registry.rstrip("/") + "/"
alt_image = "alt/alt"
else:
registry = ""
alt_image = "alt"
rendered = Template(kwargs["dockerfile_template"].read_text()).render(
alt_image=alt_image,
branch=branch,
organization=self.organization,
registry=registry,
)
kwargs["dockerfile"].write_text(rendered + "\n")
@forall_images(consume_result=False)
def get_requires(self, **kwargs):
requires = set()
for line in kwargs["dockerfile"].read_text().splitlines():
if match := re.match(self.from_re, line):
from_image = match.groupdict()
if from_image["organization"] == self.organization:
requires.add(from_image["name"])
return (kwargs["image"].name, requires)
def get_build_order(self):
requires = {}
for image, image_requires in self.get_requires():
requires[image] = image_requires
ts = TopologicalSorter(requires)
return ts.static_order()
def render_full_tag(self, image, tag):
if self.registry:
registry = self.registry.rstrip("/") + "/"
else:
registry = ""
if tag:
tag = f":{tag}"
return f"{registry}{self.organization}/{image}{tag}"
def run(self, cmd, *args, **kwargs):
if self.dry_run:
pre_cmd = ["echo"]
else:
pre_cmd = []
subprocess.run(pre_cmd + cmd, *args, **kwargs)
def build(self, image, arches, tag):
new_env = os.environ | {"DOCKER_BUILDKIT": "1"}
platforms = ",".join([f"linux/{a}" for a in arches])
full_name = self.render_full_tag(image, tag)
if tag == self.latest:
lates_name = self.render_full_tag(image, "latest")
names = f"{full_name},{lates_name}"
else:
names = full_name
cmd = [
"buildctl",
"build",
"--frontend=dockerfile.v0",
"--local",
"context=.",
"--local",
"dockerfile=.",
"--opt",
f"platform={platforms}",
"--output",
f'type=image,"name={names}",push=true',
]
self.run(
cmd,
cwd=self.images_dir / image,
env=new_env,
)
def parse_args():
stages = ["build", "remove_dockerfiles", "render_dockerfiles", "push"]
arches = ["amd64", "386", "arm64", "arm", "ppc64le"]
branches = ["p9", "p10", "sisyphus"]
images = os.listdir(IMAGES_DIR)
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"-r",
"--registry",
default="registry.altlinux.org",
)
parser.add_argument(
"-o",
"--organization",
default="alt",
)
parser.add_argument(
"-l",
"--latest",
default="p10",
)
parser.add_argument(
"--dry-run",
action="store_true",
help="print instead of running docker commands",
)
parser.add_argument(
"-i",
"--images",
nargs="+",
default=images,
choices=images,
help="list of branches",
)
parser.add_argument(
"--skip-images",
nargs="+",
default=[],
choices=images,
help="list of skipping images",
)
parser.add_argument(
"-a",
"--arches",
nargs="+",
default=arches,
choices=arches,
help="list of arches",
)
parser.add_argument(
"--skip-arches",
nargs="+",
default=[],
choices=arches,
help="list of skipping arches",
)
parser.add_argument(
"-b",
"--branches",
nargs="+",
default=branches,
choices=branches,
help="list of branches",
)
parser.add_argument(
"--skip-branches",
nargs="+",
default=[],
choices=branches,
help="list of skipping branches",
)
parser.add_argument(
"--stages",
nargs="+",
default=stages,
choices=stages,
help="list of stages",
)
parser.add_argument(
"--skip-stages",
nargs="+",
default=[],
choices=stages,
help="list of skipping stages",
)
args = parser.parse_args()
args.stages = set(args.stages) - set(args.skip_stages)
args.branches = set(args.branches) - set(args.skip_branches)
args.images = set(args.images) - set(args.skip_images)
return args
def main():
args = parse_args()
for branch in args.branches:
db = DockerBuilder(args.registry, args.organization, args.latest, args.dry_run)
if "remove_dockerfiles" in args.stages:
db.remove_dockerfiles()
if "render_dockerfiles" in args.stages:
db.render_dockerfiles(branch)
if "build" in args.stages:
for image in db.get_build_order():
if image not in args.images:
continue
if "build" in args.stages:
db.build(image, args.arches, branch)
if __name__ == "__main__":
main()
# vim: colorcolumn=89

View File

@ -0,0 +1,13 @@
FROM {{ registry }}{{ alt_image }}:{{ branch }}
MAINTAINER alt-cloud
RUN apt-get update && \
apt-get install -y apache2; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
EXPOSE 80
CMD ["/usr/sbin/httpd2", "-D", "NO_DETACH", "-k", "start"]

13
images/apache2/README.md Normal file
View File

@ -0,0 +1,13 @@
dockerfiles-alt-apache2
========================
ALT dockerfile for apache2.
Copy Dockerfile somewhere and build the image:
`$ docker build --rm -t <username>/apache2 .`
And launch the apache2 container:
`docker run -p 80:80 <username>/apache2`
It could be test via:
`curl localhost:80`

View File

@ -0,0 +1,11 @@
FROM {{ registry }}{{ alt_image }}:{{ branch }}
MAINTAINER alt-cloud
RUN apt-get update && \
apt-get install -y glibc-gconv-modules glibc-locales tzdata; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
CMD ["bash"]

4
images/base/README.md Normal file
View File

@ -0,0 +1,4 @@
ALT dockerfile for base image.
The base image is contains locales and other basic, but not strongly
required packages.

View File

@ -0,0 +1,61 @@
FROM {{ registry }}{{ organization }}/base:{{ branch }}
MAINTAINER alt-cloud
# install editor
RUN apt-get update && \
apt-get install -y vim-console; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
# install debugging tools
RUN apt-get update && \
apt-get install -y strace gdb; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
# install document viewers
RUN apt-get update && \
apt-get install -y man; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
# install version control system
RUN apt-get update && \
apt-get install -y git-core perl-Git; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
# install network utils
RUN apt-get update && \
apt-get install -y curl iproute2; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
# install file utils
RUN apt-get update && \
apt-get install -y lsof silver-searcher; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
# install shell and completions
RUN apt-get update && \
apt-get install -y zsh zsh-completions; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
# install compilation utils
RUN apt-get update && \
apt-get install -y make gcc gcc-c++; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
CMD ["zsh"]

15
images/devel/README.md Normal file
View File

@ -0,0 +1,15 @@
dockerfiles-alt-devel
======================
ALT dockerfile for developers.
DO NOT USE THIS IN PRODUCTION!
This image is only for devel or testing purposes. It contains packages that
usually need for debugging or testing something.
Copy Dockerfile somewhere and build the image:
`$ docker build --rm -t <username>/devel .`
And launch the devel container:
`docker run -it <username>/devel`

View File

@ -0,0 +1,13 @@
FROM {{ registry }}{{ alt_image }}:{{ branch }}
MAINTAINER alt-cloud
RUN apt-get update && \
apt-get install -y etcd; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
VOLUME /data
ENTRYPOINT ["/usr/sbin/etcd", "--data-dir", "/data"]

13
images/etcd/README.md Normal file
View File

@ -0,0 +1,13 @@
dockerfiles-alt-etcd
=========================
ALT dockerfile for etcd.
Copy Dockerfile somewhere and build the image:
`$ docker build --rm -t <username>/etcd.`
And launch the etcd container:
`docker run -d -v <etcd data dir>:/data <username>/etcd`
If etcdclt watnted it could be run via:
`docker run --entrypoint etcdctl <username>/etcd`

View File

@ -0,0 +1,31 @@
FROM {{ registry }}{{ alt_image }}:{{ branch }}
MAINTAINER alt-cloud
RUN apt-get update && \
apt-get install -y gitea openssh-server; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
RUN apt-get update && \
apt-get install -y gosu; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
ENV USER gitea
ENV HOME /var/lib/gitea
ENV GITEA_WORK_DIR /var/lib/gitea
WORKDIR /var/lib/gitea
COPY app.ini /etc/gitea/app.ini
COPY entrypoint.sh /entrypoint.sh
EXPOSE 3000
EXPOSE 2222
VOLUME ["/var/lib/gitea"]
ENTRYPOINT ["/entrypoint.sh"]

22
images/gitea/README.md Normal file
View File

@ -0,0 +1,22 @@
dockerfiles-alt-gitea
======================
ALT dockerfile for gitea.
Copy Dockerfile somewhere and build the image:
`$ docker build --rm -t <username>/gitea .`
And launch the gitea container:
`docker run -d -p 80:3000 -p 2222:22 -v <gitea_path>:/var/lib/gitea <username>/gitea`
## Configuration
After mounting gitea_path would contain all variable gitea data. Gitea
parameters could be customized via files in gitea_path.
Main configuration paths (relative to gitea_path):
* config -> custom/conf/app.ini;
* https certificates -> custom/https/;
* mail certificates -> custom/mailer/;
* openssh server configuration and keys -> openssh/;
* sqlite3 database -> data/gitea.db.

15
images/gitea/app.ini Normal file
View File

@ -0,0 +1,15 @@
APP_NAME = Gitea working in ALT container
RUN_MODE = prod
[repository]
ROOT = repos
[database]
DB_TYPE = sqlite3
PATH = data/gitea.db
LOG_SQL = false
[log]
MODE = console
BUFFER_LEN = 10000
LEVEL = Info

34
images/gitea/entrypoint.sh Executable file
View File

@ -0,0 +1,34 @@
#!/bin/sh -eu
# Use bash to debug startup errors
if [ "${1-}" = bash ]; then
exec bash
fi
if [ ! -f custom/conf/app.ini ]; then
mkdir -p custom/conf
cp /etc/gitea/app.ini -t custom/conf
fi
start_sshd() {
# Store openssh config and keys in openssh directory to use them if
# container recreats
if [ -d openssh ]; then
cp -a openssh/* /etc/openssh/
else
cp -a /etc/openssh -T openssh
fi
# Ensure keys created and saved to openssh directory
/usr/bin/ssh-keygen -A
cp -a /etc/openssh/* -t openssh
/usr/sbin/sshd
}
start_sshd
chmod 0700 .
chown gitea:gitea . -R
exec gosu gitea /usr/bin/gitea web

View File

@ -0,0 +1,18 @@
FROM {{ registry }}{{ alt_image }}:{{ branch }}
MAINTAINER alt-cloud
RUN apt-get update && \
apt-get install -y nginx apache2-html tzdata; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
RUN cd /etc/nginx/sites-enabled.d && ln -s ../sites-available.d/default.conf .
RUN sed -Ei 's/^([[:space:]]*listen[[:space:]]+)localhost(:80)/\10.0.0.0\2/' \
/etc/nginx/sites-available.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

13
images/nginx/README.md Normal file
View File

@ -0,0 +1,13 @@
dockerfiles-alt-nginx
======================
ALT dockerfile for nginx.
Copy Dockerfile somewhere and build the image:
`$ docker build --rm -t <username>/nginx .`
And launch the nginx container:
`docker run -it -p 80:80 <username>/nginx`
It could be test via:
`curl localhost:80`

View File

@ -0,0 +1,15 @@
FROM {{ registry }}{{ organization }}/base:{{ branch }}
MAINTAINER alt-cloud
RUN apt-get update && \
apt-get install -y python3-module-pip \
python3-module-setuptools \
python3-dev \
gcc \
; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
CMD ["python3"]

13
images/python/README.md Normal file
View File

@ -0,0 +1,13 @@
dockerfiles-alt-python
=======================
ALT dockerfile for python.
Image contains python(3) and tools to get upstream python modules. Main purpose
of the image is to run python apps using upstream modules.
Copy Dockerfile somewhere and build the image:
`$ docker build --rm -t <username>/python .`
And launch the python container:
`docker run -it <username>/python`

View File

@ -0,0 +1,11 @@
FROM {{ registry }}{{ alt_image }}:{{ branch }}
MAINTAINER alt-cloud
RUN apt-get update && \
apt-get install -y irb; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
CMD ["irb"]

10
images/ruby/README.md Normal file
View File

@ -0,0 +1,10 @@
dockerfiles-alt-ruby
=====================
ALT dockerfile for ruby.
Copy Dockerfile somewhere and build the image:
`$ docker build --rm -t <username>/ruby .`
And launch the ruby container:
`docker run -it <username>/ruby`

View File

@ -0,0 +1,24 @@
FROM {{ registry }}{{ organization }}/base:{{ branch }}
MAINTAINER alt-cloud
RUN apt-get update && \
apt-get install -y systemd; \
rm -f /var/cache/apt/archives/*.rpm \
/var/cache/apt/*.bin \
/var/lib/apt/lists/*.*
RUN ( \
cd /lib/systemd/system/sysinit.target.wants/; \
for i in *; do \
[ $i == systemd-tmpfiles-setup.service ] || rm -f $i; \
done \
); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;
CMD ["/sbin/init"]

10
images/systemd/README.md Normal file
View File

@ -0,0 +1,10 @@
dockerfiles-alt-systemd
========================
ALT dockerfile for systemd.
Copy Dockerfile somewhere and build the image:
`$ docker build --rm -t <username>/systemd .`
And launch the systemd container:
`docker run -it <username>/systemd`