Browse Source

new: [docker-builder] added new charm.

postgres
Valentin Lab 10 years ago
parent
commit
caef5ac5aa
  1. 28
      precise/docker-builder/README
  2. 1
      precise/docker-builder/config
  3. 29
      precise/docker-builder/hooks/install
  4. 3
      precise/docker-builder/hooks/start
  5. 3
      precise/docker-builder/hooks/stop
  6. 11
      precise/docker-builder/metadata.yaml
  7. 1
      precise/docker-builder/revision
  8. 38
      precise/docker-builder/src/usr/lib/docker-updater/wrap-application
  9. 68
      precise/docker-builder/src/usr/local/bin/docker-build
  10. 110
      precise/docker-builder/src/usr/local/bin/docker-update

28
precise/docker-builder/README

@ -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).

1
precise/docker-builder/config

@ -0,0 +1 @@
lxc.aa_profile = unconfined

29
precise/docker-builder/hooks/install

@ -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

3
precise/docker-builder/hooks/start

@ -0,0 +1,3 @@
#!/bin/bash
juju-log "Nothing to Start for base."

3
precise/docker-builder/hooks/stop

@ -0,0 +1,3 @@
#!/bin/bash
juju-log "Nothing to stop for base."

11
precise/docker-builder/metadata.yaml

@ -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

1
precise/docker-builder/revision

@ -0,0 +1 @@
0

38
precise/docker-builder/src/usr/lib/docker-updater/wrap-application

@ -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" "$@"

68
precise/docker-builder/src/usr/local/bin/docker-build

@ -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"

110
precise/docker-builder/src/usr/local/bin/docker-update

@ -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"
Loading…
Cancel
Save