moved config format from INI to YAML
This commit is contained in:
parent
97cf440ce5
commit
8ccd734c02
4
install
4
install
@ -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."
|
||||||
|
@ -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
116
runon.default.yaml
Normal 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
|
||||||
|
|
110
runon/runon.py
110
runon/runon.py
@ -4,59 +4,70 @@ 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',
|
||||||
|
os.path.join(xdg.BaseDirectory.xdg_config_home, 'runon', 'runon.yaml'),
|
||||||
|
os.path.join(xdg.BaseDirectory.xdg_config_home, 'runon', 'runon.default.yaml')
|
||||||
|
]
|
||||||
|
if user_conf:
|
||||||
|
conf_list = [ user_conf ]
|
||||||
|
for conf in conf_list:
|
||||||
|
if os.path.exists(conf):
|
||||||
|
return conf
|
||||||
|
return None
|
||||||
|
|
||||||
def read_ini(user_confname, osname=''):
|
|
||||||
ini_list = [
|
|
||||||
'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 = {
|
|
||||||
'osname': osname,
|
|
||||||
'user': getpass.getuser()
|
|
||||||
}
|
|
||||||
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):
|
def read_yaml(conf_file):
|
||||||
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:
|
try:
|
||||||
for f in fields:
|
with open(conf_file, 'r') as file:
|
||||||
conf[f] = ini.get(osname, f)
|
conf = yaml.safe_load(file)
|
||||||
except configparser.NoOptionError as e:
|
return conf
|
||||||
print('ERROR: {}'.format(e))
|
except yaml.YAMLError as e:
|
||||||
|
print(f'ERROR: bad configuration file:')
|
||||||
|
print(e)
|
||||||
sys.exit(1)
|
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
|
||||||
|
|
||||||
|
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):
|
||||||
link = os.path.join(os.path.dirname(binpath), osname)
|
link = os.path.join(os.path.dirname(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)
|
||||||
|
3
setup.py
3
setup.py
@ -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": [
|
||||||
|
Loading…
Reference in New Issue
Block a user