moved config format from INI to YAML

This commit is contained in:
Gilles Grandou 2023-12-04 22:39:30 +01:00
parent 97cf440ce5
commit 8ccd734c02
6 changed files with 185 additions and 171 deletions

View File

@ -28,9 +28,9 @@ ln -sf $venvdir/bin/runon $bindir/
echo "install base config in $configdir..." echo "install base config in $configdir..."
mkdir -p $configdir mkdir -p $configdir
if [ -n "$devmode" ]; then if [ -n "$devmode" ]; then
ln -s $srcdir/runon.default.conf $configdir/ ln -s $srcdir/runon.default.yaml $configdir/
else else
cp -p $srcdir/runon.default.conf $configdir/ cp -p $srcdir/runon.default.yaml $configdir/
fi fi
echo "done." echo "done."

View File

@ -1,121 +0,0 @@
[DEFAULT]
environment =
HOME
USER
DISPLAY
TERM
debian_chroot=${osname}
binds =
/etc/timezone:ro
/etc/localtime:ro
/etc/passwd:ro
/etc/group:ro
/etc/shadow:ro
/tmp/.X11-unix:ro
/home/${user}
[centos7]
dockerfile =
FROM centos:7
RUN yum install sudo -y
RUN echo "Defaults lecture = never" >> /etc/sudoers
RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
RUN yum group install -y "Development Tools"
pkginstall = RUN yum install {} -y
packages = xterm vim-X11 git python3 bash-completion
[rocky8]
dockerfile =
FROM rockylinux:8
RUN yum install sudo -y
RUN echo "Defaults lecture = never" >> /etc/sudoers
RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
pkginstall = RUN yum install {} -y
packages = xterm vim-X11 git python3 bash-completion
[rocky9]
dockerfile =
FROM rockylinux:9
RUN dnf install sudo -y
RUN echo "Defaults lecture = never" >> /etc/sudoers
RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
pkginstall = RUN dnf install {} -y
packages = xterm vim-X11 git python3 bash-completion
[debian9]
dockerfile =
FROM debian:9
ARG DEBIAN_FRONTEND=noninteractive
RUN echo "deb http://archive.debian.org/debian stretch main" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y upgrade
RUN apt install -y --allow-downgrades libnettle6=3.3-1+b2 # default libnettle6 conflicts with libgtk-3.0
RUN apt-get -y install sudo
RUN echo "Defaults lecture = never" >> /etc/sudoers
RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
pkginstall = RUN apt-get -y install {}
packages = xterm x11-apps vim-gtk3 git build-essential python3 bash-completion
[debian10]
dockerfile =
FROM debian:10
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get -y install apt-utils
RUN apt-get -y upgrade
RUN apt-get -y install sudo
RUN echo "Defaults lecture = never" >> /etc/sudoers
RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
pkginstall = RUN apt-get -y install {}
packages = xterm x11-apps vim-gtk3 git build-essential python3 bash-completion
[debian11]
dockerfile =
FROM debian:11
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get -y install apt-utils
RUN apt-get -y install sudo
RUN echo "Defaults lecture = never" >> /etc/sudoers
RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
pkginstall = RUN apt-get -y install {}
packages = xterm x11-apps vim-gtk3 git build-essential python3 bash-completion
[debian12]
dockerfile =
FROM debian:12
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get -y install apt-utils
RUN apt-get -y install sudo
RUN echo "Defaults lecture = never" >> /etc/sudoers
RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
pkginstall = RUN apt-get -y install {}
packages = xterm x11-apps vim-gtk3 git build-essential python3 bash-completion
[ubuntu20.04]
dockerfile =
FROM ubuntu:20.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get -y install apt-utils
RUN apt-get -y install sudo
RUN echo "Defaults lecture = never" >> /etc/sudoers
RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
pkginstall = RUN apt-get -y install {}
packages = xterm x11-apps vim-gtk3 git build-essential python3 bash-completion
[ubuntu22.04]
dockerfile =
FROM ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get -y install apt-utils
RUN apt-get -y install sudo
RUN echo "Defaults lecture = never" >> /etc/sudoers
RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
pkginstall = RUN apt-get -y install {}
packages = xterm x11-apps vim-gtk3 git build-essential python3 bash-completion

116
runon.default.yaml Normal file
View File

@ -0,0 +1,116 @@
debian_base: &debian_base
dockerfile:
- ARG DEBIAN_FRONTEND=noninteractive
- RUN apt-get update
- RUN apt-get -y install apt-utils
- RUN apt-get -y upgrade
- RUN apt-get -y install sudo
- RUN echo "Defaults lecture = never" >> /etc/sudoers
- RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
pkginstall:
"RUN apt-get -y install {}"
packages:
- xterm
- x11-apps
- vim-gtk3
- git
- build-essential
- python3
- bash-completion
binds:
- /etc/timezone:ro
- /etc/localtime:ro
- /etc/passwd:ro
- /etc/group:ro
- /etc/shadow:ro
- /tmp/.X11-unix:ro
- /home/{user}
environment:
- HOME
- USER
- DISPLAY
- TERM
- debian_chroot={osname}
debian9:
<<: *debian_base
image: debian:9
dockerfile:
- ARG DEBIAN_FRONTEND=noninteractive
- RUN echo "deb http://archive.debian.org/debian stretch main" > /etc/apt/sources.list
- RUN apt-get update
- RUN apt-get -y upgrade
- RUN apt install -y --allow-downgrades libnettle6=3.3-1+b2 # default libnettle6 conflicts with libgtk-3.0
- RUN apt-get -y install sudo
- RUN echo "Defaults lecture = never" >> /etc/sudoers
- RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
debian10:
<<: *debian_base
image: debian:10
debian11:
<<: *debian_base
image: debian:11
debian12:
<<: *debian_base
image: debian:12
ubuntu20.04:
<<: *debian_base
image: ubuntu:20.04
ubuntu22.04:
<<: *debian_base
image: ubuntu:22.04
rh_base: &rh_base
dockerfile:
- RUN dnf install -y sudo
- RUN echo "Defaults lecture = never" >> /etc/sudoers
- RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
- RUN dnf group install -y "Development Tools"
pkginstall:
"RUN dnf install -y {}"
packages:
- xterm
- vim-X11
- git
- python3
- bash-completion
binds:
- /etc/timezone:ro
- /etc/localtime:ro
- /etc/passwd:ro
- /etc/group:ro
- /etc/shadow:ro
- /tmp/.X11-unix:ro
- /home/{user}
environment:
- HOME
- USER
- DISPLAY
- TERM
- debian_chroot={osname}
centos7:
<<: *rh_base
image: centos:7
dockerfile:
- RUN yum install -y sudo
- RUN echo "Defaults lecture = never" >> /etc/sudoers
- RUN echo "ALL ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
- RUN yum group install -y "Development Tools"
pkginstall:
"RUN yum install -y {}"
rocky8:
<<: *rh_base
image: rockylinux:8
rocky9:
<<: *rh_base
image: rockylinux:9

View File

@ -4,58 +4,69 @@ import docker
import dockerpty import dockerpty
import io import io
import getpass import getpass
import pathlib
import platform import platform
import os import os
import re import re
import xdg.BaseDirectory import xdg.BaseDirectory
import configparser import yaml
import subprocess import subprocess
from pprint import pprint from pprint import pprint
def natural_sortkey(string): def find_config_file(user_conf):
tokenize = re.compile(r'(\d+)|(\D+)').findall conf_list = [
return tuple(int(num) if num else alpha for num, alpha in tokenize(string)) 'runon.yaml',
'.runon.yaml',
def read_ini(user_confname, osname=''): os.path.join(xdg.BaseDirectory.xdg_config_home, 'runon', 'runon.yaml'),
ini_list = [ os.path.join(xdg.BaseDirectory.xdg_config_home, 'runon', 'runon.default.yaml')
'runon.conf',
'.runon.conf',
os.path.join(xdg.BaseDirectory.xdg_config_home, 'runon', 'runon.conf'),
os.path.join(xdg.BaseDirectory.xdg_config_home, 'runon', 'runon.default.conf'),
] ]
defaults = { if user_conf:
'osname': osname, conf_list = [ user_conf ]
'user': getpass.getuser() for conf in conf_list:
} if os.path.exists(conf):
if user_confname:
ini_list.insert(0, user_confname)
ini = configparser.ConfigParser(defaults=defaults, interpolation=configparser.ExtendedInterpolation())
ini.read(ini_list)
return ini
def list_osnames(user_confname):
ini = read_ini(user_confname)
return ini.sections()
def load_config(user_confname, osname):
ini = read_ini(user_confname, osname)
if not ini.has_section(osname):
print('ERROR: cannot find configuration for distribution "{}"'.format(osname))
sys.exit(1)
conf = {}
fields = [ 'dockerfile', 'pkginstall', 'packages', 'environment', 'binds', 'user', 'osname' ]
try:
for f in fields:
conf[f] = ini.get(osname, f)
except configparser.NoOptionError as e:
print('ERROR: {}'.format(e))
sys.exit(1)
for f in [ 'dockerfile', 'environment', 'binds' ]:
conf[f] = [ i for i in conf[f].split('\n') if i ]
for f in [ 'packages' ]:
conf[f] = conf[f].split()
return conf return conf
return None
def read_yaml(conf_file):
try:
with open(conf_file, 'r') as file:
conf = yaml.safe_load(file)
return conf
except yaml.YAMLError as e:
print(f'ERROR: bad configuration file:')
print(e)
sys.exit(1)
return conf
def list_osnames(conf_file):
conf = read_yaml(conf_file)
osnames = []
for key in conf:
if (type(conf[key]) is dict) and conf[key].get('image'):
osnames.append(key)
return osnames
def load_config(conf_file, osname):
user_vars = {
'osname': osname,
'user': getpass.getuser(),
'uid': os.getuid(),
'home': pathlib.Path.home(),
}
conf = read_yaml(conf_file)
osconf = conf.get(osname)
if not osconf:
print(f"ERROR: cannot find configuration for distribution {osname}")
sys.exit(1)
osconf['osname'] = osname
for k in [ 'dockerfile', 'packages', 'environment', 'binds' ]:
if osconf.get(k):
osconf[k] = [ s.format(**user_vars) for s in osconf[k]]
return osconf
def make_osname_link(binpath, osname): def make_osname_link(binpath, osname):
@ -72,9 +83,12 @@ def make_image_name(osname):
def build_image(client, conf, update, verbose): def build_image(client, conf, update, verbose):
image = conf.get('image')
packages = conf['packages'] packages = conf['packages']
dockerfile = conf['dockerfile'] dockerfile = conf['dockerfile']
pkginstall = conf['pkginstall'] pkginstall = conf['pkginstall']
if image:
dockerfile.insert(0, 'FROM {}'.format(image))
for p in packages: for p in packages:
dockerfile.append(pkginstall.format(p)) dockerfile.append(pkginstall.format(p))
tag = make_image_name(conf['osname']) tag = make_image_name(conf['osname'])
@ -193,21 +207,25 @@ def main():
if osname: if osname:
args.osname = osname args.osname = osname
conf_file = find_config_file(args.config)
if not conf_file:
print('ERROR: config file not found')
sys.exit(1)
if args.osname == 'list': if args.osname == 'list':
osnames = list_osnames(args.config) osnames = list_osnames(conf_file)
print('Available distributions:') print('Available distributions:')
for o in sorted(osnames, key=natural_sortkey): for o in sorted(osnames):
print(' {}'.format(o)) print(' {}'.format(o))
print() print()
if args.link:
for o in osnames:
make_osname_link(sys.argv[0], args.osname)
return 0 return 0
client = docker.from_env()
conf = load_config(args.config, args.osname)
if args.link: if args.link:
make_osname_link(sys.argv[0], args.osname) make_osname_link(sys.argv[0], args.osname)
conf = load_config(conf_file, args.osname)
client = docker.from_env()
image = build_image(client, conf, args.update, args.verbose) image = build_image(client, conf, args.update, args.verbose)
container = create_container(client, image, conf, args.command, args.verbose) container = create_container(client, image, conf, args.command, args.verbose)
ret = run_container(client, container) ret = run_container(client, container)

View File

@ -11,8 +11,9 @@ setup(
install_requires = [ install_requires = [
"docker", "docker",
"dockerpty", "dockerpty",
"pathlib",
"pyxdg", "pyxdg",
"pyyaml",
], ],
entry_points={ entry_points={
"console_scripts": [ "console_scripts": [

View File

@ -18,7 +18,7 @@ fi
if [ -e $configdir ]; then if [ -e $configdir ]; then
echo "remove configs" echo "remove configs"
rm -vf $configdir/runon.default.conf rm -vf $configdir/runon.default.yaml
rmdir -v $configdir || true rmdir -v $configdir || true
fi fi