Create clr-sdk Docker Container.

Docker container for running Clear Linux developer tooling.

Allows a user to run mixer tool in a cross-platform way.

Built atop the clearlinux:latest image, and includes the
os-clr-on-clr bundle for devloper tools. A python script
sets up up a non-root user (with UID & GID mapped to the
mix directory mounted at runtime), with sudo privileges
only for mixer, swupd, and mock.

Note: The README mentions privileges needed to run mixer
build-image. This is sufficient for now, and narrowing
the --privileged to the specific CAP subset (SYS_ADMIN,
MKNOD, etc?) is left for a future task.

Signed-off-by: Kevin C. Wells <kevin.c.wells@intel.com>
This commit is contained in:
Kevin C. Wells
2017-11-13 05:50:57 -08:00
parent 3d190ff089
commit 7ea6f7d329
5 changed files with 178 additions and 0 deletions
+1
View File
@@ -13,6 +13,7 @@ Containers
- ciao-scheduler
- ciao-deploy
- ciao-webui
- clr-sdk
- machine-learning
- Keystone
- MariaDB
+16
View File
@@ -0,0 +1,16 @@
FROM clearlinux:latest
MAINTAINER kevin.c.wells@intel.com
ARG swupd_args
COPY setup.py /usr/bin/setup.py
COPY clruser /usr/share/defaults/sudo/sudoers.d/
# Update and add bundles
RUN swupd update $swupd_args && \
swupd bundle-add os-clr-on-clr $swupd_args && \
chmod 755 /usr/bin/setup.py && \
chmod 440 /usr/share/defaults/sudo/sudoers.d/clruser
ENTRYPOINT ["/usr/bin/setup.py"]
+79
View File
@@ -0,0 +1,79 @@
# Clear SDK Container
[![](https://images.microbadger.com/badges/image/clearlinux/clr-sdk.svg)](http://microbadger.com/images/clearlinux/clr-sdk "Get your own image badge on microbadger.com")
[![](https://images.microbadger.com/badges/version/clearlinux/clr-sdk.svg)](http://microbadger.com/images/clearlinux/clr-sdk "Get your own version badge on microbadger.com")
This repo provides a Clear Linux* SDK container for running the Clear Linux devloper tools. This container will allow you to use the [mixer tool](https://clearlinux.org/features/mixer) on your Linux host.
# Build
## Building Locally
```
docker build -t clearlinux/clr-sdk .
```
> #### Note:
> If you are behind a firewall, you may need to pass the `--network host` and/or `--build-arg http://<proxy>:<port>` flags to docker build to configure your proxy.
#### Optional Build ARGs
* `--build-arg swupd_args` specifies [SWUPD](https://clearlinux.org/documentation/swupdate_how_to_run_the_updater.html) flags passed to the update during build.
## Pulling from Dockerhub
```
docker pull clearlinux/clr-sdk
```
# Run
* **Create a mix directory**
The directory you create will be used for the output created while using the container.
```
mkdir -p /home/myuser/mix
```
*It is important that you are the owner of this directory.* The owner of the
directory is what determines the user id used inside the container. If you
are not the owner of the directory, you may not have access to the files the
container creates.
* **Running the docker container**
Assuming you created the mix directory as described above, the command to
run the docker container would be:
```
docker run --rm -it -v /home/myuser/mix:/home/clr/mix clearlinux/clr-sdk --mixdir=/home/clr/mix
```
### A note on the arguments:
#### docker run arguments
* `--rm` cleans up and removes the container once you exit it. The files
generated in the mounted directory will persist on the host.
* `-it` attaches an interactive terminal.
* `-v /path/on/host:/path/in/container` bind mounts a directory on the host
to a path inside the container. Only the files generated in this path
inside the container will be accessible on the host or persist after
the container has exited. The container path will be automatically
generated within the container if it doesn't already exist, and will
replace whatever may already be there, so _use caution_.
* If you plan to run `sudo mixer build-image` inside the container, you
must additionally pass `--privileged -v /dev:/dev` to docker run. This is
because `mixer build-image` needs to mount a loopback device for generating
the image filesystem. The `-v /dev:/dev` bind mount is due to an [outstanding
issue](https://github.com/moby/moby/issues/27886) where loopback devices
created within the container are not visible within the container. **This
can have serious side effects**, so only run the container in this way for
this specific command.
* If you are behind a firewall, you may need to pass the `--network host`
flag to docker run, and then set your `http_proxy` and `https_proxy`
environment variables within the container to configure your proxy.
#### Container arguments
* `-d`|`--mixdir` tells the startup script what directory you mounted using
the `-v` option above. The owner UID and GID of this directory will be
used for user inside the container. This is also the active directory when
the container runs. Omitting this argument will result in a default user
id and active directory, _even if you mounted a directory with -v_. This
can be useful, but is likely not what you want, and may cause the container
user to not have permission to access the mounted mix directory.
* `--id` manually sets the UID and GID for the user inside the container.
Should be in the form UID:GID. Takes precedence over id inferred by
mixdir argument. This may cause the container user to not have permission
to access the mounted mix directory.
At this point, you should be able to run the commands described in the
[mixer guide](https://clearlinux.org/documentation/clear-linux/guides/maintenance/mixer.html).
+2
View File
@@ -0,0 +1,2 @@
clr ALL=NOPASSWD:SETENV: /usr/bin/mixer, /usr/bin/swupd
+80
View File
@@ -0,0 +1,80 @@
#!/usr/bin/python3
import argparse
import subprocess
import os
import sys
import pathlib
parser = argparse.ArgumentParser()
parser.add_argument('-d','--mixdir',
help='The directory where you intend to make your mix. '
'This will be the active directory once the container '
'is running. In the abscence of the "id" argument, '
'the owner uid and gid of the mixdir will be used for '
'the user in the container.')
parser.add_argument("--id",
help='UID and GID to use for the user inside the '
'container. It should be in the form UID:GID.')
args = parser.parse_args()
mixdir = args.mixdir if args.mixdir else "/home/clr/mix"
# Get UID and GID for user
uid,gid = (None, None)
if args.id:
try:
uid,gid = args.id.split(":")
uid = int(uid)
gid = int(gid)
except ValueError:
sys.stderr.write("Invalid id: Must be of form UID:GID\n")
sys.exit(1)
elif args.mixdir:
# Use owner of mixdir
try:
stat = os.stat(args.mixdir)
uid,gid = (stat.st_uid, stat.st_gid)
except FileNotFoundError:
# This implies the --mixdir flag was passed, but to a
# directory that doesn't exist. It will get created below.
pass
if not uid or not gid:
# Use default
uid,gid = (1000, 1000)
elif uid == 0 or gid == 0:
sys.stderr.write("UID and GID must both be non-zero.\n")
sys.exit(1)
user = "clr"
# Create the group and user
try:
cmd = "groupadd -o -g {} {}".format(gid,user)
subprocess.run(cmd.split(),stdout=subprocess.PIPE,stderr=subprocess.STDOUT,check=True)
# Note: adding user to mock group for access to running mock
cmd = "useradd -Nmo -g {} -G mock -u {} {}".format(gid,uid,user)
subprocess.run(cmd.split(),stdout=subprocess.PIPE,stderr=subprocess.STDOUT,check=True)
os.chown("/home/{}".format(user),uid,gid)
except subprocess.SubprocessError:
sys.stderr.write("Error creating user.\n")
sys.exit(1)
# Create the mix directory if it doesn't exist.
# Note: we catch FileExistsError rather than using exist_ok=True so
# that we only chown the directory if we're the one that created it.
try:
pathlib.Path(mixdir).mkdir(parents=True)
os.chown(mixdir,uid,gid)
except FileExistsError:
pass
# Move to mixdir and start bash as new user
os.chdir(mixdir)
cmd = "sudo -H -u {} bash -i".format(user).split()
os.execvp(cmd[0], cmd)