173 lines
4.5 KiB
Python
173 lines
4.5 KiB
Python
import glob
|
|
import pwd
|
|
import os
|
|
|
|
from subprocess import call, check_call
|
|
|
|
from charmhelpers.core.templating import render
|
|
from charmhelpers.core.hookenv import (
|
|
log,
|
|
config,
|
|
ERROR,
|
|
)
|
|
from charmhelpers.core.host import (
|
|
add_group,
|
|
add_user_to_group,
|
|
mkdir,
|
|
mount,
|
|
)
|
|
from charmhelpers.contrib.storage.linux.utils import (
|
|
is_block_device,
|
|
)
|
|
from charmhelpers.contrib.storage.linux.loopback import (
|
|
ensure_loopback_device
|
|
)
|
|
from charmhelpers.contrib.storage.linux.lvm import (
|
|
create_lvm_volume_group,
|
|
create_lvm_physical_volume
|
|
)
|
|
|
|
BASE_PACKAGES = ['btrfs-tools', 'lvm2']
|
|
LXD_PACKAGES = ['lxd', 'lxd-client']
|
|
LXD_SOURCE_PACKAGES = [
|
|
'lxc',
|
|
'lxc-dev',
|
|
'mercurial',
|
|
'git',
|
|
'pkg-config',
|
|
'protobuf-compiler',
|
|
'golang-goprotobuf-dev',
|
|
'build-essential',
|
|
'golang',
|
|
'xz-utils',
|
|
'tar',
|
|
'acl',
|
|
]
|
|
|
|
LXD_GIT = 'github.com/lxc/lxd'
|
|
DEFAULT_LOOPBACK_SIZE = '10G'
|
|
|
|
|
|
def install_lxd():
|
|
'''Install LXD'''
|
|
|
|
|
|
def install_lxd_source(user='ubuntu'):
|
|
'''Install LXD from source repositories; installs toolchain first'''
|
|
log('Installing LXD from source')
|
|
|
|
home = pwd.getpwnam(user).pw_dir
|
|
GOPATH = os.path.join(home, 'go')
|
|
LXD_SRC = os.path.join(GOPATH, 'src', 'github.com/lxc/lxd')
|
|
|
|
if not os.path.exists(GOPATH):
|
|
mkdir(GOPATH)
|
|
|
|
env = os.environ.copy()
|
|
env['GOPATH'] = GOPATH
|
|
env['HTTP_PROXY'] = 'http://squid.internal:3128'
|
|
env['HTTPS_PROXY'] = 'https://squid.internal:3128'
|
|
cmd = 'go get -v %s' % LXD_GIT
|
|
log('Installing LXD: %s' % (cmd))
|
|
check_call(cmd, env=env, shell=True)
|
|
|
|
if not os.path.exists(LXD_SRC):
|
|
log('Failed to go get %s' % LXD_GIT, level=ERROR)
|
|
raise
|
|
|
|
cwd = os.getcwd()
|
|
try:
|
|
os.chdir(LXD_SRC)
|
|
cmd = 'go get -v -d ./...'
|
|
log('Downloading LXD deps: %s' % (cmd))
|
|
call(cmd, env=env, shell=True)
|
|
|
|
# build deps
|
|
cmd = 'make'
|
|
log('Building LXD deps: %s' % (cmd))
|
|
call(cmd, env=env, shell=True)
|
|
except Exception:
|
|
log("failed to install lxd")
|
|
raise
|
|
finally:
|
|
os.chdir(cwd)
|
|
|
|
|
|
def configure_lxd_source(user='ubuntu'):
|
|
'''Add required configuration and files when deploying LXD from source'''
|
|
log('Configuring LXD Source')
|
|
home = pwd.getpwnam(user).pw_dir
|
|
GOPATH = os.path.join(home, 'go')
|
|
|
|
templates_dir = 'templates'
|
|
render('lxd_upstart', '/etc/init/lxd.conf', {},
|
|
perms=0o644, templates_dir=templates_dir)
|
|
render('lxd_service', '/lib/systemd/system/lxd.service', {},
|
|
perms=0o644, templates_dir=templates_dir)
|
|
add_group('lxd', system_group=True)
|
|
add_user_to_group(user, 'lxd')
|
|
|
|
files = glob.glob('%s/bin/*' % GOPATH)
|
|
for i in files:
|
|
cmd = ['cp', i, '/usr/bin']
|
|
check_call(cmd)
|
|
|
|
|
|
def configure_lxd_block():
|
|
'''Configure a block device for use by LXD for containers'''
|
|
log('Configuring LXD container storage')
|
|
if filesystem_mounted('/var/lib/lxd'):
|
|
log('/varlib/lxd already configured, skipping')
|
|
return
|
|
|
|
lxd_block_device = config('block-device')
|
|
if not lxd_block_device:
|
|
log('block device is not provided - skipping')
|
|
return
|
|
|
|
dev = None
|
|
if lxd_block_device.startswith('/dev/'):
|
|
dev = lxd_block_device
|
|
elif lxd_block_device.startswith('/'):
|
|
log('Configuring loopback device for use with LXD')
|
|
_bd = lxd_block_device.split('|')
|
|
if len(_bd) == 2:
|
|
dev, size = _bd
|
|
else:
|
|
dev = lxd_block_device
|
|
size = DEFAULT_LOOPBACK_SIZE
|
|
dev = ensure_loopback_device(dev, size)
|
|
|
|
if not dev or not is_block_device(dev):
|
|
log('Invalid block device provided: %s' % lxd_block_device)
|
|
return
|
|
|
|
if not os.path.exists('/var/lib/lxd'):
|
|
mkdir('/var/lib/lxd')
|
|
|
|
if config('fs-type') == 'btrfs':
|
|
cmd = ['mkfs.btrfs', '-f', dev]
|
|
check_call(cmd)
|
|
mount(dev,
|
|
'/var/lib/lxd',
|
|
options='user_subvol_rm_allowed',
|
|
persist=True,
|
|
filesystem='btrfs')
|
|
elif config('fs-type') == 'lvm':
|
|
create_lvm_physical_volume(dev)
|
|
create_lvm_volume_group('lxd_vg', dev)
|
|
|
|
|
|
def determine_packages():
|
|
packages = [] + BASE_PACKAGES
|
|
packages = list(set(packages))
|
|
if config('use-source'):
|
|
packages.extend(LXD_SOURCE_PACKAGES)
|
|
else:
|
|
packages.extend(LXD_PACKAGES)
|
|
return packages
|
|
|
|
|
|
def filesystem_mounted(fs):
|
|
return call(['grep', '-wqs', fs, '/proc/mounts']) == 0
|