Valentin Lab
10 years ago
10 changed files with 292 additions and 0 deletions
-
28precise/docker-builder/README
-
1precise/docker-builder/config
-
29precise/docker-builder/hooks/install
-
3precise/docker-builder/hooks/start
-
3precise/docker-builder/hooks/stop
-
11precise/docker-builder/metadata.yaml
-
1precise/docker-builder/revision
-
38precise/docker-builder/src/usr/lib/docker-updater/wrap-application
-
68precise/docker-builder/src/usr/local/bin/docker-build
-
110precise/docker-builder/src/usr/local/bin/docker-update
@ -0,0 +1,28 @@ |
|||||
|
|
||||
|
|
||||
|
Unfinished because untested. But, the script docker-updater is |
||||
|
tested and used. |
||||
|
|
||||
|
|
||||
|
This LXC requires a kernel >3.8 at least. (to be able to run docker in |
||||
|
LXC) It requires also "aufs" capabilities (apparmor.d permission, but |
||||
|
also available in kernel) |
||||
|
|
||||
|
XXXvlab: we could run docker in LXC via a socket towards an host's |
||||
|
install of docker and remove this constraint. |
||||
|
|
||||
|
|
||||
|
It is meant to build image of applications based on a single git-sub |
||||
|
code. |
||||
|
|
||||
|
It provides an IMAGE that does not requires 'git' tool, and won't |
||||
|
contain any git history. |
||||
|
|
||||
|
Then, it'll be able to update this image by small "docker commits" |
||||
|
quite efficiently. |
||||
|
|
||||
|
|
||||
|
Currently the image produced can only be run on docker host that |
||||
|
support running aufs in the containers (this implies, that the docker |
||||
|
fs driver IS NOT aufs, that the host kernel support aufs, and that |
||||
|
permissions are set so that container can mount an aufs filesystem). |
@ -0,0 +1 @@ |
|||||
|
lxc.aa_profile = unconfined |
@ -0,0 +1,29 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
set -eux # -x for verbose logging to juju debug-log |
||||
|
|
||||
|
## |
||||
|
## add files |
||||
|
## |
||||
|
|
||||
|
cp src/usr/local/sbin/* src/usr/local/sbin/ |
||||
|
|
||||
|
## Could consider not using docker inside the LXC for compatibility |
||||
|
## reason in this case you need to setup a --lts connection. You can |
||||
|
## use "DOCKER_MAIN_OPTS" to add this to every usage of docker one |
||||
|
## 0k-docker is installed. |
||||
|
|
||||
|
## install |
||||
|
## - 0k-docker for docker-build-charm |
||||
|
ln -sf /opt/apps/0k-docker/bin/docker-build-charm /usr/local/sbin |
||||
|
|
||||
|
## - 0k-charm for charms |
||||
|
ln -sf /opt/apps/0k-charms/precise /srv/charm-store |
||||
|
|
||||
|
apt-get install python-pip ## for 'pip install shyaml' |
||||
|
pip install shyaml ## for docker-build-charm |
||||
|
|
||||
|
apt-get install kal-shlib-pretty ## for docker-build-charm |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,3 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
juju-log "Nothing to Start for base." |
@ -0,0 +1,3 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
juju-log "Nothing to stop for base." |
@ -0,0 +1,11 @@ |
|||||
|
name: docker-builder |
||||
|
summary: "Docker Builder" |
||||
|
maintainer: "Valentin Lab <valentin.lab@kalysto.org>" |
||||
|
inherit: docker |
||||
|
description: | |
||||
|
Docker Builder |
||||
|
data-resources: |
||||
|
- /var/lib/docker |
||||
|
- /srv/docker-updates |
||||
|
config-resources: |
||||
|
- /etc/docker |
@ -0,0 +1 @@ |
|||||
|
0 |
@ -0,0 +1,38 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
orig=$0.diverted |
||||
|
|
||||
|
if [ -z "$APP_LOCATION" ]; then |
||||
|
echo "Error: APP_LOCATION was not defined." |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
app=/srv/app |
||||
|
root=$app/root |
||||
|
changes=$app/changes/0000 |
||||
|
mnt=$app/mnt |
||||
|
|
||||
|
## All these should be in the root image |
||||
|
#mkdir -p $root $mnt |
||||
|
#mkdir -p "$(dirname "$APP_LOCATION")" |
||||
|
|
||||
|
if [ -d "$changes" ]; then |
||||
|
clean_all() { |
||||
|
cd / |
||||
|
mountpoint "$mnt" 2>/dev/null && umount "$mnt" |
||||
|
} |
||||
|
|
||||
|
|
||||
|
trap "clean_all" EXIT |
||||
|
mount -t aufs -o br=$changes:$root -o udba=none none "$mnt" |
||||
|
if [ "$?" != 0 ]; then |
||||
|
echo "Error: aufs mount failed." |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
ln -sf "$mnt" "$APP_LOCATION" |
||||
|
else |
||||
|
ln -sf "$root" "$APP_LOCATION" |
||||
|
fi |
||||
|
|
||||
|
"$orig" "$@" |
@ -0,0 +1,68 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
## Called by git-hooks or by hand, it should produce a master git-sub repository |
||||
|
|
||||
|
## it should: |
||||
|
## - checkout the correct BRANCH of GIT_REPOS in DOCKER_UPDATE_PATH |
||||
|
## - launch a build of IMAGE with special option to copy the git repos checkouted |
||||
|
## - push the image to UPDATED_IMAGE_NAME |
||||
|
|
||||
|
|
||||
|
#!- |
||||
|
. /etc/shlib |
||||
|
#!- |
||||
|
|
||||
|
|
||||
|
DOCKER_UPDATE_PATH=${DOCKER_UPDATE_PATH:-/srv/docker-builder} |
||||
|
|
||||
|
|
||||
|
include common |
||||
|
include pretty |
||||
|
|
||||
|
usage="$exname COMPONENT CHARM MASTER_IMAGE_NAME BRANCH" |
||||
|
|
||||
|
if [ "$#" == 0 ]; then |
||||
|
print_usage |
||||
|
exit 0 |
||||
|
fi |
||||
|
|
||||
|
COMPONENT_NAME="$1" |
||||
|
CHARM="$2" |
||||
|
MASTER_IMAGE_NAME="$3" |
||||
|
BRANCH="$4" |
||||
|
|
||||
|
if [ -z "$COMPONENT_NAME" ]; then |
||||
|
print_error "You need to specify a component name as first argument." |
||||
|
fi |
||||
|
|
||||
|
if [ -z "$CHARM" ]; then |
||||
|
print_error "You need to specify a charm name as second argument." |
||||
|
fi |
||||
|
|
||||
|
if [ -z "$MASTER_IMAGE_NAME" ]; then |
||||
|
print_error "You need to specify a master image ame as first argument. (ie: docker.0k.io/odoo:master)" |
||||
|
fi |
||||
|
|
||||
|
if [ -z "$BRANCH" ]; then |
||||
|
print_error "You need to specify a branch as fourth argument. (ie: 8.0/0k/dev/master)" |
||||
|
fi |
||||
|
|
||||
|
|
||||
|
. /etc/charm/global.conf |
||||
|
|
||||
|
## git-sub co should be so much better ! |
||||
|
set -ex |
||||
|
|
||||
|
mkdir -p "$DOCKER_UPDATE_PATH" |
||||
|
cd "$DOCKER_UPDATE_PATH" |
||||
|
rm -rf "$COMPONENT_NAME" |
||||
|
time git sub clone $GIT_0K_CLONE_OPTIONS $GIT_0K_SUB_CLONE_OPTIONS -b "$BRANCH" \ |
||||
|
"$GIT_0K_BASE"/0k/"$COMPONENT_NAME" |
||||
|
docker rmi "$CHARM" || true |
||||
|
export DOCKER_RUN_OPTS="-v $DOCKER_UPDATE_PATH/$COMPONENT_NAME:$DOCKER_UPDATE_PATH/$COMPONENT_NAME" |
||||
|
time ODOO_CP_FROM_DIR="$DOCKER_UPDATE_PATH/$COMPONENT_NAME" EXTRA_CHARM_VARS="ODOO_CP_FROM_DIR" docker-build-charm "$CHARM" |
||||
|
|
||||
|
docker tag "$CHARM" "$MASTER_IMAGE_NAME" |
||||
|
|
||||
|
docker push "$MASTER_IMAGE_NAME" |
||||
|
|
@ -0,0 +1,110 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
|
||||
|
#!- |
||||
|
. /etc/shlib |
||||
|
#!- |
||||
|
|
||||
|
|
||||
|
DOCKER_UPDATE_PATH=${DOCKER_UPDATE_PATH:-/srv/docker-builder} |
||||
|
|
||||
|
|
||||
|
include common |
||||
|
include pretty |
||||
|
|
||||
|
usage="$exname COMPONENT MASTER_IMAGE_NAME BRANCH UPDATED_IMAGE_NAME" |
||||
|
|
||||
|
|
||||
|
COMPONENT_NAME="$1" |
||||
|
MASTER_IMAGE_NAME="$2" |
||||
|
BRANCH="$3" |
||||
|
UPDATED_IMAGE_NAME="$4" |
||||
|
|
||||
|
## Note: we will need in the DOCKER_UPDATE_HOST: |
||||
|
## - git-sub |
||||
|
|
||||
|
## should we check for aufs ? |
||||
|
|
||||
|
mkdir -p "$DOCKER_UPDATE_PATH" |
||||
|
cd "$DOCKER_UPDATE_PATH" |
||||
|
if ! [ -d "$COMPONENT_NAME" ]; then |
||||
|
echo "ERROR: repository $DOCKER_UPDATE_PATH/$COMPONENT_NAME is not existent." |
||||
|
echo "You should build it on this host prior to run this hook." |
||||
|
echo "As a remainder: this host is supposed to keep the reference git that" |
||||
|
echo "was used to built the master image." |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
if [ -e "$COMPONENT_NAME.locked" ]; then |
||||
|
echo "Master is being updated." |
||||
|
echo "Or '$COMPONENT_NAME.locked' file was left dangling over." |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
|
||||
|
clean_all() { |
||||
|
cd / |
||||
|
mountpoint "$tmpdir_root" 2>/dev/null && umount "$tmpdir_root" |
||||
|
[ -d "$tmpdir_root" ] && rmdir "$tmpdir_root" |
||||
|
[ -d "$tmpdir_changes" ] && rm -rf "$tmpdir_changes" |
||||
|
} |
||||
|
|
||||
|
tmpdir_changes=$(mktemp -d /tmp/$COMPONENT_NAME.changes.XXXXXX) |
||||
|
tmpdir_root=$(mktemp -d /tmp/$COMPONENT_NAME.root.XXXXXX) |
||||
|
|
||||
|
trap "clean_all" EXIT |
||||
|
mount -t aufs -o br=$tmpdir_changes:$DOCKER_UPDATE_PATH/$COMPONENT_NAME -o udba=none none "$tmpdir_root" |
||||
|
cd "$tmpdir_root" |
||||
|
|
||||
|
## XXXvlab: We probably would need to: |
||||
|
## - fetch only the module concerned |
||||
|
## - fetch only the ref concerned |
||||
|
git fetch origin "$BRANCH" |
||||
|
git checkout "$BRANCH" |
||||
|
git sub update |
||||
|
|
||||
|
cd / && |
||||
|
umount "$tmpdir_root" && |
||||
|
rmdir "$tmpdir_root" |
||||
|
if [ "$?" != 0 ]; then |
||||
|
echo "Uh oh... could not umount aufs $tmpdir_root or delete it." |
||||
|
exit 1 |
||||
|
fi |
||||
|
cd "$tmpdir_changes" |
||||
|
|
||||
|
echo "Cleaning the change layer." |
||||
|
find . -name .git -type d -exec rm -rf {} \; -prune |
||||
|
|
||||
|
|
||||
|
|
||||
|
## XXXvlab: if we produced it we shouldn't have to pull it |
||||
|
# |
||||
|
#echo "Pulling $MASTER_IMAGE_NAME" |
||||
|
#docker pull "$MASTER_IMAGE_NAME" || exit 1 |
||||
|
container_id=$( |
||||
|
docker run -d \ |
||||
|
-v $tmpdir_changes:/mnt/changes \ |
||||
|
--entrypoint '/bin/bash' \ |
||||
|
"$MASTER_IMAGE_NAME" \ |
||||
|
-c " |
||||
|
mkdir -p /srv/app/{root,changes} |
||||
|
cp -a /mnt/changes /srv/app/changes/0000 |
||||
|
ls /srv/app/changes/0000 |
||||
|
") |
||||
|
if [ "$?" != 0 ]; then |
||||
|
echo "Failed to call docker run..." |
||||
|
exit 1 |
||||
|
fi |
||||
|
if [ "$(docker wait "$container_id")" != "0" ]; then |
||||
|
echo "Copy of changes to docker images failed !" |
||||
|
echo "Log of container:" |
||||
|
docker logs "$container_id" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
docker commit --author "$exname" \ |
||||
|
--message "Automatic Updater" \ |
||||
|
"$container_id" \ |
||||
|
"$UPDATED_IMAGE_NAME" |
||||
|
|
||||
|
docker push "$UPDATED_IMAGE_NAME" |
Write
Preview
Loading…
Cancel
Save
Reference in new issue