Docker Symlink Wrapper: Difference between revisions

From Wiki-DB
Jump to navigationJump to search
Added limitations
No edit summary
Line 57: Line 57:
Here an example for a JSON file which can be used to add new symlinks:
Here an example for a JSON file which can be used to add new symlinks:
  <nowiki>{
  <nowiki>{
"symlinks":[
    "symlinks":[
"arm-linux-gnueabihf-as",
        "arm-linux-gnueabihf-as",
"arm-linux-gnueabihf-ld",
        "arm-linux-gnueabihf-ld",
"arm-linux-gnueabihf-gcc",
        "arm-linux-gnueabihf-gcc",
"arm-linux-gnueabihf-g++",
        "arm-linux-gnueabihf-g++",
"arm-linux-gnueabihf-ar",
        "arm-linux-gnueabihf-ar",
"arm-linux-gnueabihf-nm",
        "arm-linux-gnueabihf-nm",
"arm-linux-gnueabihf-strip",
        "arm-linux-gnueabihf-strip",
"arm-linux-gnueabihf-objcopy",
        "arm-linux-gnueabihf-objcopy",
"arm-linux-gnueabihf-objdump"
        "arm-linux-gnueabihf-objdump",
],
        "make-cross",
"registry":"",
        "cmake-cross"
"image":"dhelectronics/linaro-cross-build",
    ],
"tag":"buster-arm32v7-8",
    "registry":"",
"installpath":"/usr/local/bin"
    "image":"dhelectronics/linaro-cross-build",
    "tag":"buster-arm32v7-8",
    "installpath":"/usr/local/bin"
}</nowiki>
}</nowiki>
When adding the configuration of the symlink to the configfile of the wrapper script, the JSON object is prepended by the 'name' (the other param of the install command) and added to the main object of the configuration.
When adding the configuration of the symlink to the configfile of the wrapper script, the JSON object is prepended by the 'name' (the other param of the install command) and added to the main object of the configuration.
Line 83: Line 85:
* When you use a script which calls a symlinked program in a huge number of times, the performance is reduced. This is because at each call of the symlinked program, a new container is created and after the execution of the program has finished, the container is destroyed (creation and destruction of containers are a ressource-heavy operation).
* When you use a script which calls a symlinked program in a huge number of times, the performance is reduced. This is because at each call of the symlinked program, a new container is created and after the execution of the program has finished, the container is destroyed (creation and destruction of containers are a ressource-heavy operation).
* The <tt>list-versions</tt>-command won't work with an image which only exists localy. This is because the command uses the API of the corresponding docker registry to get all available versions.
* The <tt>list-versions</tt>-command won't work with an image which only exists localy. This is because the command uses the API of the corresponding docker registry to get all available versions.
* If you make symlinks of software which is also installed on the host system, it depends on the <tt>PATH</tt>-varaiable which of them is used (when calling the command without the absolute path). It may happen that you use accidently the wrong version of the software without noticing.

Revision as of 10:14, 8 October 2020

Overview

docker-symlink-wrapper.py is a wrapper script which creates symlinks for applications. If the symlink is called the script starts the corresoponding application in a container and passes all parameters to it. The script can manage multiple symlinks which can point to different container images. It is also possible to set the tag of the docker image which is used (= version of the application).

docker-symlink-wrapper.py requires the python modules requests and docker. The versions supplied by the Debian package repository is, at least in stretch, too old (especially the docker module), so install the recent version via pip:

pip3 install requests docker

The wrapper script uses a configuration file for storing the known symlinks and their configration. This file is located at /var/lib/docker-symlink-wrapper/symlinks.json. This concludes that you need to superuser privileges if you want to call a command of the script which changes the configuration.

For authentification at docker registries the saved credentials of the Docker CLI are used (usually at ~/.docker/config.json). So use docker login <registry-address> to login into the registry before using the script.

Available Commands

docker-symlink-wrapper.py install <name> <json file> | - Installs new symlinks to a container and adds them to the configuration file of the script. 'name' is an unique keyword for the entry in the configuration file (so that the entry can be recognized later), while 'json file' is a file in the JSON format which has the configuration of the container (Definition of the fields of the JSON file is below). Instead of using a JSON file as a parameter you can substitue that with an '-', then the script reads the JSON from STDIN.
docker-symlink-wrapper.py uninstall <name> Removes the symlinks from a container and from the configuration file of the script. 'name' is an unique keyword of the entry in the configuration file.
docker-symlink-wrapper.py list Lists all known symlinks, its keyword and the corresponding container.
docker-symlink-wrapper.py list-versions <name> Lists all available versions of a container (= tag) for this 'name'. This command does connect to the corresponding container registry and reads the available tags. This command does NOT work with images which are only local! For using this command with registies which require the addition of certificates (like corporate internal registries) you have to add the certificate (or its root certificate) to the system certificates (usually at /etc/ssl/certs/ca-certificates.crt).
docker-symlink-wrapper.py set-version <name> <tag> Sets the used version of the container for the 'name' to the 'tag',
<symlinkname> [...] When the script is called trough one of the symlinks, it looks at the configuration to determine the correct container to start. After that it starts that container and calls inside the container the applictaion which has the same name as the symlink and passes all parameter to it. If something is piped into STDIN of the symlink, the docker-symlink-wrapper script passes this to the STDIN of the program inside the container. The return value of the the container and captured and returned.

JSON-format for adding new symlinks

When adding new symlinks, JSON must be supplied which contains all neccessary information. It must consists of one object with the following fields:

  • symlinks: List of strings which are the application names that should be calles inside the container.
  • registry: A string that is the address of the container registry. If this field is empty, Docker's own registry Docker Hub is used as a default. This field is needed, because the is no way to definitly distinguish if the first segment of the image name is the address of the registry or that it is the first part of the container repository name.
  • image: A string that contains the name of the docker image which is used for the applications. The image name usually contains the address of the registry. If the registry is omitted, the image is either local or uses Docker Hub as a registry.
  • tag: A string that is used as default tag of the container image.
  • installpath: A string that defines the path in the system where the symlinks are installed.

Here an example for a JSON file which can be used to add new symlinks:

{
    "symlinks":[
        "arm-linux-gnueabihf-as",
        "arm-linux-gnueabihf-ld",
        "arm-linux-gnueabihf-gcc",
        "arm-linux-gnueabihf-g++",
        "arm-linux-gnueabihf-ar",
        "arm-linux-gnueabihf-nm",
        "arm-linux-gnueabihf-strip",
        "arm-linux-gnueabihf-objcopy",
        "arm-linux-gnueabihf-objdump",
        "make-cross",
        "cmake-cross"
    ],
    "registry":"",
    "image":"dhelectronics/linaro-cross-build",
    "tag":"buster-arm32v7-8",
    "installpath":"/usr/local/bin"
}

When adding the configuration of the symlink to the configfile of the wrapper script, the JSON object is prepended by the 'name' (the other param of the install command) and added to the main object of the configuration.

Limitations

There are some limitations of the script:

  • Only containers which do not need any special adjustments (like additional capabilities) can be started.
  • The container image is only pulled from the registry if the image isn't already in the image storage of the local docker instance. This can result that you work with an older version of a container, even if there is a new version available. (Docker version 20.03 (not released yet as of 10/2020) will introduce a pull-policy flag at docker run, maybe the Python library will get this too, then this can be fixed in future versions of the wrapper)
  • If a symlink is called, only the current working directory is mounted into the container. If the program needs to access files outside of the current working directory, you have to properly adjust the current working directory before calling the symlink.
  • When you use a script which calls a symlinked program in a huge number of times, the performance is reduced. This is because at each call of the symlinked program, a new container is created and after the execution of the program has finished, the container is destroyed (creation and destruction of containers are a ressource-heavy operation).
  • The list-versions-command won't work with an image which only exists localy. This is because the command uses the API of the corresponding docker registry to get all available versions.
  • If you make symlinks of software which is also installed on the host system, it depends on the PATH-varaiable which of them is used (when calling the command without the absolute path). It may happen that you use accidently the wrong version of the software without noticing.