runon/README.md

9.1 KiB

RUNON - Run your commands in any systems

(c) 2021 Gilles Grandou gilles@grandou.net licensed under GPL-2.0.

home: https://git.grandou.net/gilles/runon

Runon is a frontend to podman allowing to run seamlessly any application in any linux based operating system, including graphical applications, while keeping the host user environment.

the v1 legacy runon branch was based on docker. Current versions are now relying on podman.

Quick HOWTO

$ grep ^PRETTY_NAME /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"

$ runon centos7 grep ^PRETTY_NAME /etc/os-release
PRETTY_NAME="CentOS Linux 7 (Core)"

$ runon ubuntu20.04 grep ^PRETTY_NAME /etc/os-release
PRETTY_NAME="Ubuntu 20.04.6 LTS"

$ runon debian9 grep ^PRETTY_NAME /etc/os-release
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"

$ runon rocky9 xterm
[xterm launched!]

Install

Installation has been tested on:

  • Debian 11 (bullseye)
  • Debian 12 (bookworm)
  • RockyLinux 9.3 (Blue Onyx)

However it should work straightforward on any equivalent system.

Podman Install

If not already installed, just run as root the suitable command for your system:

apt install podman
dnf install podman

To check that podman is correctly installed, just try:

$ podman run -it hello-world
Resolved "hello-world" as an alias (/etc/containers/registries.conf.d/shortnames.conf)
Trying to pull docker.io/library/hello-world:latest...
Getting image source signatures
Copying blob 719385e32844 done  
Copying config 9c7a54a9a4 done  
Writing manifest to image destination
Storing signatures

Hello from Docker!
This message shows that your installation appears to be working correctly.
[...]

If your encounter an error like this one:

Error: writing blob: adding layer with blob "sha256:3331450fb84fde695e565405a554d5cf213a33826da197b29aabde08be012f8b": Error processing tar file(exit status 1): potentially insufficient UIDs or GIDs available in user namespace (requested 0:42 for /etc/gshadow): Check /etc/subuid and /etc/subgid: lchown /etc/gshadow: invalid argument

it's likely that your user account has been create a while ago on a legacy distribution release and has no support for subuid and subgid. You can fix it easily with these commands:

sudo usermod --add-subgids 10000-75535 $USER
sudo usermod --add-subuids 10000-75535 $USER
podman system migrate
podman pull

If you're running on a Debian system, there is a good explanation of the above problem in /usr/share/doc/podman/README.Debian.

Python Dependencies

There is no specific dependency, you just need to insure to have:

  • a Python release 3.6 or better
  • the python venv module
  • the python pip module

manual install

cd <tools>
git clone  https://git.grandou.net/gilles/runon

local install, in your ~/.local/bin

cd <runon>
./install

If you plan to work runon development, you can pass --dev to install links to your current git clone:

./install --dev

each user can have its own configuration in ~/.config/runon/runon.conf.

You can keep your configuration in several places, the 1st one which is find is used:

  • runon.yaml in the current directory
  • .runon.yaml in the current directory
  • ~/.config/runon/runon.yaml
  • ~/.config/runon/runon.default.yaml, the configuration file installed by default

uninstall

To uninstall, just run:

./uninstall

you can create soft links to runos to simplify calls:

runos -l centos7

now calling centos7 ... is equivalent to call runos centos7 ...:

centos7 xterm

Usage

With the default configuration, a seamless environment is set up, allowing to transparently run commands in various environments, while keeping:

  • user environment (uid, gid, home directory, ...)
  • password less sudo support
  • X support to run graphical applications

Basic usage

runon [options] <osname> <command>

runon -h

available options

  • -v verbose output, display information on the current startup step

  • -u forces the container image to be updated, useful if the distribution has been updated and you want to use it. Otherwise, if a container has been already built, it will be used directly without doing any network access.

  • -c <configfile> uses a custom config file, useful to try new distribution without breaking your running config.

  • -l create an executable link with the osname name. you can after run the command with osname [...] instead of runos osname [...]

Listing available distributions:

Just run:

$ runon list
Available distributions:
  centos7
  debian10
  debian11
  debian12
  debian9
  rocky8
  rocky9
  ubuntu20.04
  ubuntu22.04

This lists all osname present in your current configuration file.

Editing configuration:

you can easily open the current configuration file with:

$ runon edit

If you open the runon.default.yaml file, take care to save your changes in a new runon.yaml file to avoid the default one, which could be overwritten next time you install or update runon.

Interactive shell

Just run:

runon <osname>

while start an insteractive shell in the container system:

$ runon ubuntu22.04
(ubuntu22.04) gilles@host:~$ cat /etc/os-release 
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
(ubuntu22.04) gilles@host:~$ xclock 
^C
(ubuntu22.04) gilles@host:~$ exit
exit

To help differentiate the environment on are running on, you can add this snippet to your .bashrc:

# container
if [ -n "$container" ]; then
    PS1="($container) $PS1"
fi

This now displays your runon name on your bash prompt.

Configuration

Configuration is done in runon.yaml file, which describes supported distribution in YAML format.

Example config

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
    - "{home}"
  environment:
    - USER
    - DISPLAY
    - TERM
    - container={osname}

centos7:
  <<: *rh_base
  image: docker.io/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: docker.io/rockylinux:8

rocky9:
  <<: *rh_base
  image: docker.io/rockylinux:9

Each entry which contains an image: field defines a distribution which can be used by runon. In the above example the other entries are used as templates for real entries.

Config entries

  • image the base image used to build the container.

  • dockerfile the base content of dockerfile which will be used to generate the running environment. There is usually no need to diverge from the ones given in example.

  • pkginstall the dockerfile command used to install a package, likely to be standard for all deb and rpm based distributions. In the command {} is replaced by the package name.

  • packages the list of packages to install. Feel free to add the ones you need for your commands (likely news system libs, new tools, ...)

  • binds the list of files and directories from the host system to expose in the container system. you might want to add /opt or other shared directories. See below for a description of binds entries

  • environment the list of environment variables you want to pass or set in the container system. See below for a description

Lines starting with # or are comments.

Some substitution happens upon reading the configuration:

  • {osname} the executed distribution.
  • {user} the current username
  • {uid} the current UID
  • {home} the user's home directory

Binds

Each binds line can have one of the following formats:

<hostpath>
<hostpath>:<mode>
<hostpath>:<containerpath>
<hostpath>:<containerpath>:<mode>

with:

  • <hostpath> is the filename or the dirname of the path you want to expose
  • <containerpath> is the pathname inside the container, by default it's the same path.
  • <mode> can be rw, read-write (by default), or ro, read-only.

Environment

Each environment line define a Environment Variable which is set in the container upon execution.

Each line can have one of the following formats:

<envvar>
<envvar>=<value>

If no value is given, the host value is passed into the container.