Like the title suggests, I wrote a script in Python that uses the python3-lxc
library to automate the creation of Linux LXC containers. I realised that containers can be great when I'm writing (and even installing other) apps and setting up FreeBSD-ish* jail environments to organise my workspaces for whatever project that I'm up to.
Setting up LXC containers can be a pain in the you-know-what, so I decided to automate the task with Python and came up with this:
# Generic Python3 development environment
# - Automated LXC container setup script
# By Aleksey <[email protected]>
# - GitHub: https://github.com/Alekseyyy
import lxc
import sys
import argparse
parser = argparse.ArgumentParser(description="Use LXC to setup a Python3 development environment")
parser.add_argument("--name", action="store", type=str, default="python3-dev", help="the name of the container")
parser.add_argument("--user", action="store", type=str, default="dev", help="the user's ssh username")
args = parser.parse_args()
container = lxc.Container(args.name)
# Check to see if container already exists
if container.defined:
print("Container of the name %s already exists. Exiting..." % name)
sys.exit(1)
# Create and start the container
if not container.create("download", lxc.LXC_CREATE_QUIET, {"dist":"ubuntu",
"release":"bionic",
"arch":"amd64"}):
print("Failed to create the Python3 development container. Exiting... ")
sys.exit(1)
print("Created the Python3 development container!")
if not container.start():
print("Failed to start the Python3 development container")
sys.exit(1)
print("Started the Python3 development container!")
# Setup the container
print("Setting up the container...")
container.get_ips(timeout=30) #wait a bit :P
setup_commands = [
["apt", "update"],
["apt", "dist-upgrade"],
["apt", "install", "python3"],
["apt", "install", "python3-pip"],
["apt", "install", "ssh"],
["useradd", args.user],
["mkdir", "/home/%s" % args.user]
]
for k in setup_commands:
container.attach_wait(lxc.attach_run_command, k)
print("\nFinished setting up! (don't forget to set a password for %s" % args.user)
print("Container state: %s" % container.state)
print("Container PID: %s\n" % container.init_pid)
The script works like:
- Importing the necessary libraries
- Parsing arguments to be used in creating the image
- Creating and starting up the container
- "Attaching" to the container to set up any prerequisites
- Finally printing out the process ID and state of the container
Because I'm lazy, this sets up a privileged container that requires the sudo
command to run (which is insecure for production systems if I'm not mistaken, but should be fine for users who just want a container to work in).
- Can you recommend a better way to deploy LXC containers?
- Can you recommend ways coding practices to improve my script?
- I noticed that I can't automatically set a password for the lower-privileged user that I created and that some images can't download (possibly because of some GPG keyserver error). I should ask this in StackOverflow, but do you have any advice to solve this?
- Do you have any other advice regarding LXC-based containers, containers in general or Python programming?
Also, you can check out my other Python-automated LXC scripts if you're interested here: https://github.com/Alekseyyy/InfoSec/tree/master/lxc
*I'm sure that there are technical differences between FreeBSD jails and LXC containers, plz go easy on me :P
lxc-create
command to create the container? It looks like you just wrote a Python wrapper around an already existing command line tool. Note that for some distros, thelxc-create
commands also allows you to specify a list of packages you want added onto the base image. \$\endgroup\$