Skip to content

Instantly share code, notes, and snippets.

@cloudnull
Last active October 5, 2015 23:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cloudnull/34ff32c4f2dd9edc9902 to your computer and use it in GitHub Desktop.
Save cloudnull/34ff32c4f2dd9edc9902 to your computer and use it in GitHub Desktop.
create a cached image of an lxc container. this was adapted from https://gist.github.com/odyssey4me/859208c8d22fee4fb8ba
BASE_CONTAINER_NAME="base-image"
IMAGE_PATH="/var/lib/lxc/${BASE_CONTAINER_NAME}/rootfs"
DISTRO="ubuntu"
RELEASE="trusty"
ARCH="amd64"
LXC_CACHE_LOCATION="/var/cache/lxc"
LXC_REPO_PATH="/var/www/repo"
LXC_IMAGE_DATE=$(date +%Y%m%d_%H:%M)
LXC_IMAGE_INDEX="lxc-images/${DISTRO}/${RELEASE}/${BASE_CONTAINER_NAME}/${ARCH}/${LXC_IMAGE_DATE}"
LXC_CONTAINER_IMAGE_TARGET="${LXC_REPO_PATH}/${LXC_IMAGE_INDEX}"
## Pre download cache cleanup
if [ -d "${LXC_CACHE_LOCATION}/download/${DISTRO}/${RELEASE}" ];then
rm -rf "${LXC_CACHE_LOCATION}/download/${DISTRO}/${RELEASE}"
fi
## create lxc container from "download" template
lxc-create --bdev=dir \
--name=${BASE_CONTAINER_NAME} \
--template=download \
-- \
--dist ${DISTRO} \
--release ${RELEASE} \
--arch amd64
## Update the base image
chroot ${IMAGE_PATH} <<EOC
echo 'nameserver 8.8.8.8' | tee /etc/resolv.conf
apt-get update
apt-key update
apt-get upgrade -y
apt-get install -y \
openssh-server \
python2.7 \
apt-transport-https \
python-lxml \
bridge-utils \
bsdmainutils \
build-essential \
cgmanager \
cgmanager-utils \
cgroup-lite \
comerr-dev \
curl \
debconf-utils \
debhelper \
dh-apparmor \
gettext \
gir1.2-glib-2.0 \
git \
groff-base \
intltool-debian \
iptables \
iso-codes \
krb5-multidev \
libcgmanager-dev \
libdbus-1-dev \
libdbus-glib-1-2 \
libdevmapper-event1.02.1 \
libexpat1-dev \
libffi-dev \
libpq-dev \
libpq5 \
libpython-dev \
libxml2-dev \
libxslt1-dev \
libxslt1.1 \
lvm2 \
python-apt \
python-apt-common \
python-dev \
python-pycurl \
python-software-properties \
python3-apt \
python3-dbus \
python3-gi \
python3-minimal \
python3-pycurl \
python3-software-properties \
software-properties-common \
sqlite3 \
ssh \
sshpass \
time
apt-get clean
rm -f /usr/bin/python
ln -s /usr/bin/python2.7 /usr/bin/python
cat > /etc/ssh/sshd_config <<EOF
# Port/Protocol
Port 22
Protocol 2
# HostKeys
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes
# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
ServerKeyBits 1024
# Logging
SyslogFacility AUTH
LogLevel INFO
# Authentication
LoginGraceTime 120
PermitRootLogin yes
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM yes
UseDNS no
X11Forwarding no
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
EOF
EOC
## Create or clean up the LXC container image target and rootfs
if [ ! -d "${LXC_CONTAINER_IMAGE_TARGET}" ];then
mkdir -p ${LXC_CONTAINER_IMAGE_TARGET}
fi
## Move the LXC container image to the cache location
pushd ${LXC_CONTAINER_IMAGE_TARGET}
tar -Opc -C ${IMAGE_PATH} . | pxz -1 -T8 -D12 -c - > rootfs.tar.xz
popd
## Create meta data for the lxc image
mkdir -p "${IMAGE_PATH}/meta"
pushd "${IMAGE_PATH}/meta"
cat > config-user <<EOF
lxc.include = LXC_TEMPLATE_CONFIG/ubuntu.common.conf
lxc.include = LXC_TEMPLATE_CONFIG/ubuntu.userns.conf
EOF
cat > config <<EOF
lxc.include = LXC_TEMPLATE_CONFIG/ubuntu.common.conf
EOF
cat > create-message <<EOF
Created an Ubuntu container (release=${RELEASE}, arch=${ARCH}, variant=${BASE_CONTAINER_NAME})
For security reason, container images ship without user accounts
and without a root password.
Use lxc-attach or chroot directly into the rootfs to set a root password
or create user accounts.
EOF
cat > excludes-user <<EOF
./dev/agpgart
./dev/audio
./dev/audio1
./dev/audio2
./dev/audio3
./dev/audioctl
./dev/console
./dev/dsp
./dev/dsp1
./dev/dsp2
./dev/dsp3
./dev/full
./dev/kmem
./dev/loop0
./dev/loop1
./dev/loop2
./dev/loop3
./dev/loop4
./dev/loop5
./dev/loop6
./dev/loop7
./dev/mem
./dev/midi0
./dev/midi00
./dev/midi01
./dev/midi02
./dev/midi03
./dev/midi1
./dev/midi2
./dev/midi3
./dev/mixer
./dev/mixer1
./dev/mixer2
./dev/mixer3
./dev/mpu401data
./dev/mpu401stat
./dev/null
./dev/port
./dev/ptmx
./dev/ram0
./dev/ram1
./dev/ram10
./dev/ram11
./dev/ram12
./dev/ram13
./dev/ram14
./dev/ram15
./dev/ram16
./dev/ram2
./dev/ram3
./dev/ram4
./dev/ram5
./dev/ram6
./dev/ram7
./dev/ram8
./dev/ram9
./dev/random
./dev/rmidi0
./dev/rmidi1
./dev/rmidi2
./dev/rmidi3
./dev/sequencer
./dev/smpte0
./dev/smpte1
./dev/smpte2
./dev/smpte3
./dev/sndstat
./dev/tty
./dev/tty0
./dev/tty1
./dev/tty2
./dev/tty3
./dev/tty4
./dev/tty5
./dev/tty6
./dev/tty7
./dev/tty8
./dev/tty9
./dev/urandom
./dev/zero
EOF
cat > expiry <<EOF
0
EOF
cat > templates <<EOF
/etc/hostname
/etc/hosts
EOF
popd
pushd "${LXC_CONTAINER_IMAGE_TARGET}"
tar -Opc -C "${IMAGE_PATH}/meta" . | pxz -1 -T8 -D12 -c - > meta.tar.xz
popd
## Remove the old container
lxc-destroy --force --name=${BASE_CONTAINER_NAME}
## Create image index
mkdir -p "${LXC_REPO_PATH}/meta/1.0"
echo "${DISTRO};${RELEASE};${ARCH};${BASE_CONTAINER_NAME};${LXC_IMAGE_DATE};/${LXC_IMAGE_INDEX}/" | tee -a ${LXC_REPO_PATH}/meta/1.0/index-system
@cloudnull
Copy link
Author

to create a container once the base image has been created use the following:

lxc-create --bdev=dir --name=template2 --template=download -- --dist=ubuntu --release=trusty --arch=amd64 --server=10.255.255.100:8181 --no-validate --variant=base-image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment