Skip to content
This repository has been archived by the owner on Jun 10, 2019. It is now read-only.

Use the rel_path utility function #341

Merged
merged 8 commits into from
Sep 20, 2016
Merged
8 changes: 3 additions & 5 deletions bootstrapvz/base/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@ def validate_manifest(data, validator, error):
:param function validator: The function that validates the manifest given the data and a path
:param function error: The function tha raises an error when the validation fails
"""
import os.path
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml'))
validator(data, schema_path)
from bootstrapvz.common.tools import rel_path
validator(data, rel_path(__file__, 'manifest-schema.yml'))

from bootstrapvz.common.releases import get_release
from bootstrapvz.common.releases import squeeze
from bootstrapvz.common.releases import get_release, squeeze
release = get_release(data['system']['release'])

if release < squeeze:
Expand Down
6 changes: 2 additions & 4 deletions bootstrapvz/base/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
invocations should have etc..
"""
from bootstrapvz.common.exceptions import ManifestError
from bootstrapvz.common.tools import load_data
from bootstrapvz.common.tools import load_data, rel_path
import logging
log = logging.getLogger(__name__)

Expand All @@ -28,9 +28,7 @@ def __init__(self, path=None, data=None):
raise ManifestError('`path\' or `data\' must be provided')
self.path = path

import os.path
self.metaschema = load_data(os.path.normpath(os.path.join(os.path.dirname(__file__),
'metaschema.json')))
self.metaschema = load_data(rel_path(__file__, 'metaschema.json'))

self.load_data(data)
self.load_modules()
Expand Down
8 changes: 4 additions & 4 deletions bootstrapvz/base/tasklist.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,22 +128,22 @@ def get_all_tasks(loaded_modules):
import pkgutil
import os.path
import bootstrapvz
bootstrapvz_root = os.path.dirname(bootstrapvz.__file__)
module_paths = set([(os.path.join(bootstrapvz_root, 'common/tasks'), 'bootstrapvz.common.tasks.')])
from bootstrapvz.common.tools import rel_path
module_paths = set([(rel_path(bootstrapvz.__file__, 'common/tasks'), 'bootstrapvz.common.tasks.')])

for module in loaded_modules:
module_path = os.path.dirname(module.__file__)
module_prefix = module.__name__ + '.'
module_paths.add((module_path, module_prefix))

providers = os.path.join(os.path.dirname(bootstrapvz.__file__), 'providers')
providers = rel_path(bootstrapvz.__file__, 'providers')
for module_loader, module_name, ispkg in pkgutil.iter_modules([providers, 'bootstrapvz.providers']):
module_path = os.path.join(module_loader.path, module_name)
# The prefix param seems to do nothing, so we prefix the module name ourselves
module_prefix = 'bootstrapvz.providers.{}.'.format(module_name)
module_paths.add((module_path, module_prefix))

plugins = os.path.join(os.path.dirname(bootstrapvz.__file__), 'plugins')
plugins = rel_path(bootstrapvz.__file__, 'plugins')
for module_loader, module_name, ispkg in pkgutil.iter_modules([plugins, 'bootstrapvz.plugins']):
module_path = os.path.join(module_loader.path, module_name)
module_prefix = 'bootstrapvz.plugins.{}.'.format(module_name)
Expand Down
4 changes: 2 additions & 2 deletions bootstrapvz/common/tasks/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import os.path
from bootstrapvz.common.tools import rel_path

assets = os.path.normpath(os.path.join(os.path.dirname(__file__), '../assets'))
assets = rel_path(__file__, '../assets')
4 changes: 2 additions & 2 deletions bootstrapvz/common/tasks/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ class ConfigureNetworkIF(Task):

@classmethod
def run(cls, info):
network_config_path = os.path.join(os.path.dirname(__file__), 'network-configuration.yml')
from ..tools import config_get
from ..tools import config_get, rel_path
network_config_path = rel_path(__file__, 'network-configuration.yml')
if_config = config_get(network_config_path, [info.manifest.release.codename])

interfaces_path = os.path.join(info.root, 'etc/network/interfaces')
Expand Down
5 changes: 5 additions & 0 deletions bootstrapvz/common/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,8 @@ def copy_tree(from_path, to_path):
for path in files:
copy(os.path.join(abs_prefix, path),
os.path.join(to_path, prefix, path))


def rel_path(base, path):
import os.path
return os.path.normpath(os.path.join(os.path.dirname(base), path))
12 changes: 3 additions & 9 deletions bootstrapvz/plugins/admin_user/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@


def validate_manifest(data, validator, error):
import os.path
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml'))
validator(data, schema_path)
pubkey = data['plugins']['admin_user'].get('pubkey', None)
if pubkey is not None and not os.path.exists(pubkey):
msg = 'Could not find public key at %s' % pubkey
error(msg, ['plugins', 'admin_user', 'pubkey'])
from bootstrapvz.common.tools import rel_path
validator(data, rel_path(__file__, 'manifest-schema.yml'))


def resolve_tasks(taskset, manifest):
Expand All @@ -24,6 +17,7 @@ def resolve_tasks(taskset, manifest):
taskset.add(tasks.AdminUserPassword)

if 'pubkey' in manifest.plugins['admin_user']:
taskset.add(tasks.CheckPublicKeyFile)
taskset.add(tasks.AdminUserPublicKey)
elif manifest.provider['name'] == 'ec2':
logging.getLogger(__name__).info("The SSH key will be obtained from EC2")
Expand Down
6 changes: 3 additions & 3 deletions bootstrapvz/plugins/admin_user/manifest-schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ properties:
properties:
username: {type: string}
password: {type: string}
pubkey: {$ref: '#/definitions/absolute_path'}
pubkey: {$ref: '#/definitions/path'}
required: [username]
additionalProperties: false
definitions:
absolute_path:
pattern: ^/[^\0]+$
path:
pattern: ^[^\0]+$
type: string
38 changes: 33 additions & 5 deletions bootstrapvz/plugins/admin_user/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,27 @@
log = logging.getLogger(__name__)


class CheckPublicKeyFile(Task):
description = 'Check that the public key is a valid file'
phase = phases.validation

@classmethod
def run(cls, info):
from bootstrapvz.common.tools import log_call, rel_path

pubkey = info.manifest.plugins['admin_user'].get('pubkey', None)
if pubkey is not None:
abs_pubkey = rel_path(info.manifest.path, pubkey)
if not os.path.isfile(abs_pubkey):
msg = 'Could not find public key at %s' % pubkey
info.manifest.validation_error(msg, ['plugins', 'admin_user', 'pubkey'])

ret, _, stderr = log_call('ssh-keygen -l -f ' + abs_pubkey)
if ret != 0:
msg = 'Invalid public key file at %s' % pubkey
info.manifest.validation_error(msg, ['plugins', 'admin_user', 'pubkey'])


class AddSudoPackage(Task):
description = 'Adding `sudo\' to the image packages'
phase = phases.preparation
Expand Down Expand Up @@ -74,14 +95,21 @@ def run(cls, info):

# Get the stuff we need (username & public key)
username = info.manifest.plugins['admin_user']['username']
with open(info.manifest.plugins['admin_user']['pubkey']) as pubkey_handle:

from bootstrapvz.common.tools import rel_path
pubkey_path = rel_path(info.manifest.path,
info.manifest.plugins['admin_user']['pubkey'])

with open(pubkey_path) as pubkey_handle:
pubkey = pubkey_handle.read()

# paths
ssh_dir_rel = os.path.join('home', username, '.ssh')
auth_keys_rel = os.path.join(ssh_dir_rel, 'authorized_keys')
ssh_dir_abs = os.path.join(info.root, ssh_dir_rel)
auth_keys_abs = os.path.join(info.root, auth_keys_rel)
from os.path import join
ssh_dir_rel = join('home', username, '.ssh')
auth_keys_rel = join(ssh_dir_rel, 'authorized_keys')
ssh_dir_abs = join(info.root, ssh_dir_rel)
auth_keys_abs = join(info.root, auth_keys_rel)

# Create the ssh dir if nobody has created it yet
if not os.path.exists(ssh_dir_abs):
os.mkdir(ssh_dir_abs, 0700)
Expand Down
5 changes: 2 additions & 3 deletions bootstrapvz/plugins/ansible/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@


def validate_manifest(data, validator, error):
import os.path
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml'))
validator(data, schema_path)
from bootstrapvz.common.tools import rel_path
validator(data, rel_path(__file__, 'manifest-schema.yml'))


def resolve_tasks(taskset, manifest):
Expand Down
5 changes: 2 additions & 3 deletions bootstrapvz/plugins/apt_proxy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
def validate_manifest(data, validator, error):
import os.path
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml'))
validator(data, schema_path)
from bootstrapvz.common.tools import rel_path
validator(data, rel_path(__file__, 'manifest-schema.yml'))


def resolve_tasks(taskset, manifest):
Expand Down
5 changes: 2 additions & 3 deletions bootstrapvz/plugins/chef/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@


def validate_manifest(data, validator, error):
import os.path
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml'))
validator(data, schema_path)
from bootstrapvz.common.tools import rel_path
validator(data, rel_path(__file__, 'manifest-schema.yml'))


def resolve_tasks(taskset, manifest):
Expand Down
5 changes: 2 additions & 3 deletions bootstrapvz/plugins/cloud_init/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@


def validate_manifest(data, validator, error):
import os.path
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml'))
validator(data, schema_path)
from bootstrapvz.common.tools import rel_path
validator(data, rel_path(__file__, 'manifest-schema.yml'))


def resolve_tasks(taskset, manifest):
Expand Down
5 changes: 2 additions & 3 deletions bootstrapvz/plugins/commands/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@


def validate_manifest(data, validator, error):
import os.path
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml'))
validator(data, schema_path)
from bootstrapvz.common.tools import rel_path
validator(data, rel_path(__file__, 'manifest-schema.yml'))


def resolve_tasks(taskset, manifest):
Expand Down
8 changes: 3 additions & 5 deletions bootstrapvz/plugins/debconf/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
def validate_manifest(data, validator, error):
from bootstrapvz.common.tools import log_check_call
import os.path
schema_path = os.path.join(os.path.dirname(__file__),
'schema.yaml')
validator(data, schema_path)
from bootstrapvz.common.tools import log_check_call, rel_path
validator(data, rel_path(__file__, 'manifest-schema.yml'))

log_check_call(['debconf-set-selections', '--checkonly'],
stdin=data['plugins']['debconf'])

Expand Down
6 changes: 3 additions & 3 deletions bootstrapvz/plugins/docker_daemon/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import os.path
from bootstrapvz.common.tools import rel_path
import tasks
from bootstrapvz.common.tasks import apt
from bootstrapvz.common.releases import wheezy


def validate_manifest(data, validator, error):
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml'))
validator(data, schema_path)
validator(data, rel_path(__file__, 'manifest-schema.yml'))

from bootstrapvz.common.releases import get_release
if get_release(data['system']['release']) == wheezy:
# prefs is a generator of apt preferences across files in the manifest
Expand Down
5 changes: 2 additions & 3 deletions bootstrapvz/plugins/docker_daemon/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
from bootstrapvz.common import phases
from bootstrapvz.common.tasks import grub
from bootstrapvz.common.tasks import initd
from bootstrapvz.common.tools import log_check_call
from bootstrapvz.common.tools import sed_i
from bootstrapvz.common.tools import log_check_call, sed_i, rel_path
import os
import os.path
import shutil
import subprocess
import time

ASSETS_DIR = os.path.normpath(os.path.join(os.path.dirname(__file__), 'assets'))
ASSETS_DIR = rel_path(__file__, 'assets')


class AddDockerDeps(Task):
Expand Down
5 changes: 2 additions & 3 deletions bootstrapvz/plugins/ec2_launch/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
def validate_manifest(data, validator, error):
import os.path
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml'))
validator(data, schema_path)
from bootstrapvz.common.tools import rel_path
validator(data, rel_path(__file__, 'manifest-schema.yml'))


def resolve_tasks(taskset, manifest):
Expand Down
5 changes: 2 additions & 3 deletions bootstrapvz/plugins/ec2_publish/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
def validate_manifest(data, validator, error):
import os.path
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml'))
validator(data, schema_path)
from bootstrapvz.common.tools import rel_path
validator(data, rel_path(__file__, 'manifest-schema.yml'))


def resolve_tasks(taskset, manifest):
Expand Down
2 changes: 1 addition & 1 deletion bootstrapvz/plugins/file_copy/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The ``file_copy`` plugin takes a (non-empty) ``files`` list, and optionally a ``
Files (items in the ``files`` list) must be objects with the following properties:

- ``src`` and ``dst`` (required) are the source and destination paths.
``src`` is relative to the current directory, whereas ``dst`` is a path in the VM.
``src`` is relative to the manifest, whereas ``dst`` is a path in the VM.
- ``permissions`` (optional) is a permission string in a format appropriate for ``chmod(1)``.
- ``owner`` and ``group`` (optional) are respectively a user and group specification,
in a format appropriate for ``chown(1)`` and ``chgrp(1)``.
Expand Down
12 changes: 3 additions & 9 deletions bootstrapvz/plugins/file_copy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,14 @@


def validate_manifest(data, validator, error):
import os.path
from bootstrapvz.common.tools import rel_path

schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml'))
validator(data, schema_path)

for i, file_entry in enumerate(data['plugins']['file_copy']['files']):
srcfile = file_entry['src']
if not os.path.exists(srcfile):
msg = 'The source file %s does not exist.' % srcfile
error(msg, ['plugins', 'file_copy', 'files', i])
validator(data, rel_path(__file__, 'manifest-schema.yml'))


def resolve_tasks(taskset, manifest):
if ('mkdirs' in manifest.plugins['file_copy']):
taskset.add(tasks.MkdirCommand)
if ('files' in manifest.plugins['file_copy']):
taskset.add(tasks.ValidateFiles)
taskset.add(tasks.FileCopyCommand)
30 changes: 26 additions & 4 deletions bootstrapvz/plugins/file_copy/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,42 @@ def run(cls, info):
modify_path(info, dir_entry['dir'], dir_entry)


class ValidateFiles(Task):
description = 'Check that the required files exist'
phase = phases.validation

@classmethod
def run(cls, info):
from bootstrapvz.common.tools import rel_path

for i, file_entry in enumerate(info.manifest.plugins['file_copy']['files']):
if not os.path.exists(rel_path(info.manifest.path, file_entry['src'])):
msg = 'The source file %s does not exist.' % file_entry['src']
info.manifest.validation_error(msg, ['plugins', 'file_copy', 'files', i])


class FileCopyCommand(Task):
description = 'Copying user specified files into the image'
phase = phases.user_modification
predecessors = [MkdirCommand]

@classmethod
def run(cls, info):
from bootstrapvz.common.tools import rel_path

for file_entry in info.manifest.plugins['file_copy']['files']:
# note that we don't use os.path.join because it can't
# handle absolute paths, which 'dst' most likely is.
final_destination = os.path.normpath("%s/%s" % (info.root, file_entry['dst']))
if os.path.isfile(file_entry['src']):
shutil.copy(file_entry['src'], final_destination)
src_path = rel_path(info.manifest.path, file_entry['src'])
if os.path.isfile(src_path):
shutil.copy(src_path, final_destination)
else:
shutil.copytree(src_path, final_destination)

if os.path.isfile(src_path) and os.path.isdir(final_destination):
dst = os.path.join(final_destination, os.path.basename(src_path))
else:
shutil.copytree(file_entry['src'], final_destination)
dst = final_destination

modify_path(info, file_entry['dst'], file_entry)
modify_path(info, dst, file_entry)
5 changes: 2 additions & 3 deletions bootstrapvz/plugins/google_cloud_repo/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import tasks
import os.path
from bootstrapvz.common.tools import rel_path


def validate_manifest(data, validator, error):
schema_path = os.path.normpath(os.path.join(os.path.dirname(__file__), 'manifest-schema.yml'))
validator(data, schema_path)
validator(data, rel_path(__file__, 'manifest-schema.yml'))


def resolve_tasks(taskset, manifest):
Expand Down