2014-05-07 17:03:16 -07:00
|
|
|
from bootstrapvz.base import Task
|
|
|
|
from bootstrapvz.common import phases
|
2014-06-22 05:54:44 +00:00
|
|
|
from bootstrapvz.common.tasks import boot
|
2014-05-07 17:03:16 -07:00
|
|
|
from bootstrapvz.common.tasks import initd
|
2014-11-19 16:14:41 -08:00
|
|
|
from bootstrapvz.common.tools import log_check_call
|
2014-11-21 12:26:56 -08:00
|
|
|
from bootstrapvz.common.tools import sed_i
|
2014-06-22 05:54:44 +00:00
|
|
|
from bootstrapvz.providers.gce.tasks import boot as gceboot
|
2014-05-07 17:03:16 -07:00
|
|
|
import os
|
|
|
|
import os.path
|
|
|
|
import shutil
|
2014-11-19 16:25:27 -08:00
|
|
|
import subprocess
|
|
|
|
import time
|
2014-05-07 17:03:16 -07:00
|
|
|
|
|
|
|
ASSETS_DIR = os.path.normpath(os.path.join(os.path.dirname(__file__), 'assets'))
|
|
|
|
|
|
|
|
|
|
|
|
class AddDockerDeps(Task):
|
|
|
|
description = 'Add packages for docker deps'
|
|
|
|
phase = phases.package_installation
|
|
|
|
DOCKER_DEPS = ['aufs-tools', 'btrfs-tools', 'git', 'iptables',
|
2014-11-19 16:25:27 -08:00
|
|
|
'procps', 'xz-utils', 'ca-certificates']
|
2014-05-07 17:03:16 -07:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def run(cls, info):
|
|
|
|
for pkg in cls.DOCKER_DEPS:
|
|
|
|
info.packages.add(pkg)
|
|
|
|
|
|
|
|
|
|
|
|
class AddDockerBinary(Task):
|
|
|
|
description = 'Add docker binary'
|
|
|
|
phase = phases.system_modification
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def run(cls, info):
|
2014-09-13 15:08:52 -03:00
|
|
|
docker_version = info.manifest.plugins['docker_daemon'].get('version', False)
|
|
|
|
docker_url = 'https://get.docker.io/builds/Linux/x86_64/docker-'
|
|
|
|
if docker_version:
|
|
|
|
docker_url += docker_version
|
|
|
|
else:
|
|
|
|
docker_url += 'latest'
|
2014-05-07 17:03:16 -07:00
|
|
|
bin_docker = os.path.join(info.root, 'usr/bin/docker')
|
2014-09-13 15:08:52 -03:00
|
|
|
log_check_call(['wget', '-O', bin_docker, docker_url])
|
2014-05-07 17:03:16 -07:00
|
|
|
os.chmod(bin_docker, 0755)
|
|
|
|
|
|
|
|
|
|
|
|
class AddDockerInit(Task):
|
|
|
|
description = 'Add docker init script'
|
|
|
|
phase = phases.system_modification
|
|
|
|
successors = [initd.InstallInitScripts]
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def run(cls, info):
|
|
|
|
init_src = os.path.join(ASSETS_DIR, 'init.d/docker')
|
|
|
|
info.initd['install']['docker'] = init_src
|
|
|
|
default_src = os.path.join(ASSETS_DIR, 'default/docker')
|
|
|
|
default_dest = os.path.join(info.root, 'etc/default/docker')
|
|
|
|
shutil.copy(default_src, default_dest)
|
2014-11-21 12:26:56 -08:00
|
|
|
docker_opts = info.manifest.plugins['docker_daemon'].get('docker_opts')
|
|
|
|
if docker_opts:
|
|
|
|
sed_i(default_dest, r'^#*DOCKER_OPTS=.*$', 'DOCKER_OPTS="%s"' % docker_opts)
|
2014-06-22 05:54:44 +00:00
|
|
|
|
|
|
|
|
|
|
|
class EnableMemoryCgroup(Task):
|
|
|
|
description = 'Change grub configuration to enable the memory cgroup'
|
|
|
|
phase = phases.system_modification
|
2014-07-09 21:20:26 +02:00
|
|
|
successors = [boot.InstallGrub_1_99, boot.InstallGrub_2]
|
2014-06-22 05:54:44 +00:00
|
|
|
predecessors = [boot.ConfigureGrub, gceboot.ConfigureGrub]
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def run(cls, info):
|
|
|
|
grub_config = os.path.join(info.root, 'etc/default/grub')
|
|
|
|
sed_i(grub_config, r'^(GRUB_CMDLINE_LINUX*=".*)"\s*$', r'\1 cgroup_enable=memory"')
|
2014-10-31 05:32:15 -07:00
|
|
|
|
2014-11-19 11:49:17 -08:00
|
|
|
|
2014-10-31 05:32:15 -07:00
|
|
|
class PullDockerImages(Task):
|
|
|
|
description = 'Pull docker images'
|
|
|
|
phase = phases.system_modification
|
|
|
|
predecessors = [AddDockerBinary]
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def run(cls, info):
|
2014-11-21 10:51:03 -08:00
|
|
|
from bootstrapvz.common.exceptions import TaskError
|
2014-11-23 21:48:09 -08:00
|
|
|
from subprocess import CalledProcessError
|
2014-11-21 10:51:03 -08:00
|
|
|
images = info.manifest.plugins['docker_daemon'].get('pull_images', [])
|
|
|
|
retries = info.manifest.plugins['docker_daemon'].get('pull_images_retries', 10)
|
|
|
|
|
|
|
|
bin_docker = os.path.join(info.root, 'usr/bin/docker')
|
|
|
|
graph_dir = os.path.join(info.root, 'var/lib/docker')
|
|
|
|
socket = 'unix://' + os.path.join(info.workspace, 'docker.sock')
|
|
|
|
pidfile = os.path.join(info.workspace, 'docker.pid')
|
|
|
|
|
|
|
|
try:
|
2014-11-21 11:22:11 -08:00
|
|
|
# start docker daemon temporarly.
|
2014-11-21 10:51:03 -08:00
|
|
|
daemon = subprocess.Popen([bin_docker, '-d', '--graph', graph_dir, '-H', socket, '-p', pidfile])
|
2014-11-21 11:22:11 -08:00
|
|
|
# wait for docker daemon to start.
|
2014-11-21 10:51:03 -08:00
|
|
|
for _ in range(retries):
|
2014-11-23 21:48:09 -08:00
|
|
|
try:
|
|
|
|
log_check_call([bin_docker, '-H', socket, 'version'])
|
2014-11-21 10:51:03 -08:00
|
|
|
break
|
2014-11-23 21:48:09 -08:00
|
|
|
except CalledProcessError:
|
|
|
|
time.sleep(1)
|
2014-11-21 10:51:03 -08:00
|
|
|
for img in images:
|
2014-11-21 11:22:11 -08:00
|
|
|
# docker load if tarball.
|
2014-11-21 10:51:03 -08:00
|
|
|
if img.endswith('.tar.gz') or img.endswith('.tgz'):
|
|
|
|
cmd = [bin_docker, '-H', socket, 'load', '-i', img]
|
2014-11-23 21:48:09 -08:00
|
|
|
try:
|
|
|
|
log_check_call(cmd)
|
|
|
|
except CalledProcessError as e:
|
|
|
|
msg = 'error {e} loading docker image {img}.'.format(img=img, e=e)
|
2014-11-21 10:51:03 -08:00
|
|
|
raise TaskError(msg)
|
2014-11-21 11:22:11 -08:00
|
|
|
# docker pull if image name.
|
|
|
|
else:
|
2014-11-21 10:51:03 -08:00
|
|
|
cmd = [bin_docker, '-H', socket, 'pull', img]
|
2014-11-23 21:48:09 -08:00
|
|
|
try:
|
|
|
|
log_check_call(cmd)
|
|
|
|
except CalledProcessError as e:
|
|
|
|
msg = 'error {e} pulling docker image {img}.'.format(img=img, e=e)
|
2014-11-21 10:51:03 -08:00
|
|
|
raise TaskError(msg)
|
|
|
|
finally:
|
2014-11-21 11:22:11 -08:00
|
|
|
# shutdown docker daemon.
|
2014-11-21 10:51:03 -08:00
|
|
|
daemon.terminate()
|
2014-11-23 21:48:09 -08:00
|
|
|
os.remove(os.path.join(info.workspace, 'docker.sock'))
|