~andrewjbeach/juju-ci-tools/make-local-patcher

588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
1
#!/usr/bin/env python
588.1.2 by Abel Deuring
Use command line parameters instead of the env variables JENKINS_KVM and WORKSPACE.
2
from argparse import ArgumentParser
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
3
import logging
4
import os
5
import shutil
6
import subprocess
619.1.1 by Abel Deuring
build_vagrant_boxes.py: Build only one Vagrant image per run.
7
import sys
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
8
858.1.5 by Curtis Hovey
Use the jujuci functions to get packages for vagrant tests.
9
from jujuci import (
10
    add_credential_args,
11
    get_artifacts,
12
    get_credentials,
13
    PUBLISH_REVISION
14
)
621.1.1 by Abel Deuring
new helper function to find successful build for a given build_revision; build_vagrant_boxes.py uses this function.
15
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
16
"""Build Juju-Vagrant boxes for Juju packages build by publish-revision.
17
18
Required environment variables:
19
20
    WORKSPACE - path to Jenkins' workspace directory
21
    JENKINS_KVM - path to the local copy of
22
        lp:~ubuntu-on-ec2/vmbuilder/jenkins_kvm (main build scripts)
23
"""
24
619.1.1 by Abel Deuring
build_vagrant_boxes.py: Build only one Vagrant image per run.
25
SERIES_TO_NUMBERS = {
26
    'trusty': '14.04',
27
    'precise': '12.04',
28
}
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
29
JENKINS_KVM = 'JENKINS_KVM'
30
WORKSPACE = 'WORKSPACE'
31
706.1.1 by Aaron Bentley
Switch to flake8 and fix lint.
32
858.1.5 by Curtis Hovey
Use the jujuci functions to get packages for vagrant tests.
33
def get_package_globs(series, arch):
34
    series_number = SERIES_TO_NUMBERS[series]
619.1.1 by Abel Deuring
build_vagrant_boxes.py: Build only one Vagrant image per run.
35
    return {
1287 by Curtis Hovey
Revert juju-core2 support.
36
        'core': 'juju-core_*%s*_%s.deb' % (series_number, arch),
858.1.5 by Curtis Hovey
Use the jujuci functions to get packages for vagrant tests.
37
        'local': 'juju-local_*%s*_all.deb' % series_number,
619.1.1 by Abel Deuring
build_vagrant_boxes.py: Build only one Vagrant image per run.
38
    }
39
40
858.1.5 by Curtis Hovey
Use the jujuci functions to get packages for vagrant tests.
41
def get_debian_packages(credentials, workspace, series, arch, revision_build):
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
42
    result = {}
858.1.5 by Curtis Hovey
Use the jujuci functions to get packages for vagrant tests.
43
    package_globs = get_package_globs(series, arch)
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
44
    try:
858.1.5 by Curtis Hovey
Use the jujuci functions to get packages for vagrant tests.
45
        for package, glob in package_globs.items():
46
            artifacts = get_artifacts(
47
                credentials, PUBLISH_REVISION, revision_build, glob,
48
                workspace, dry_run=False, verbose=False)
49
            file_path = os.path.join(workspace, artifacts[0].file_name)
50
            result[package] = file_path
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
51
    except Exception:
619.1.1 by Abel Deuring
build_vagrant_boxes.py: Build only one Vagrant image per run.
52
        for file_path in result.values():
53
            if os.path.exists(file_path):
54
                os.unlink(file_path)
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
55
        raise
56
    return result
57
58
59
def remove_leftover_virtualbox(series, arch):
60
    """The build script sometimes does not remove a VirtualBox instance.
61
62
    If such an instance is not deleted, the next build for the same
63
    series/architecture will fail.
64
    """
65
    left_over_name = 'ubuntu-cloudimg-%s-juju-vagrant-%s' % (series, arch)
66
    instances = subprocess.check_output(['vboxmanage', 'list', 'vms'])
67
    for line in instances.split('\n'):
630 by Abel Deuring
prevent a failure in build_vagrant_boxes.py for an empty output of 'vboxmanage lst vms'
68
        if line != '':
69
            name, uid = line.split(' ')
70
            name = name.strip('"')
71
            if name == left_over_name:
72
                subprocess.check_call([
73
                    'vboxmanage', 'unregistervm', name, '--delete'])
74
                break
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
75
76
620.1.1 by Abel Deuring
build_vagrant_boxes.py: Use juju-core/juju-local packages built by CI only optionally.
77
def build_vagrant_box(series, arch, jenkins_kvm, workspace, package_info=None):
631.1.1 by Abel Deuring
build_vagrant_boxes.py: Copy the existing environment when calling the main build script; prevent some errors when the main build script fails early.
78
    env = os.environ.copy()
79
    env['BUILD_FOR'] = '%s:%s' % (series, arch)
620.1.1 by Abel Deuring
build_vagrant_boxes.py: Use juju-core/juju-local packages built by CI only optionally.
80
    if package_info is not None:
81
        env['JUJU_CORE_PKG'] = package_info['core']
82
        env['JUJU_LOCAL_PKG'] = package_info['local']
588.1.2 by Abel Deuring
Use command line parameters instead of the env variables JENKINS_KVM and WORKSPACE.
83
    builder_path = os.path.join(jenkins_kvm, 'build-juju-local.sh')
631.1.1 by Abel Deuring
build_vagrant_boxes.py: Copy the existing environment when calling the main build script; prevent some errors when the main build script fails early.
84
    build_dir = '%s-%s' % (series, arch)
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
85
    logging.info('Building Vagrant box for %s %s' % (series, arch))
86
    try:
87
        subprocess.check_call(builder_path, env=env)
88
        boxname = '%s-server-cloudimg-%s-juju-vagrant-disk1.box' % (
89
            series, arch)
90
        os.rename(
588.1.2 by Abel Deuring
Use command line parameters instead of the env variables JENKINS_KVM and WORKSPACE.
91
            os.path.join(jenkins_kvm, build_dir, boxname),
92
            os.path.join(workspace, boxname))
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
93
    finally:
94
        remove_leftover_virtualbox(series, arch)
631.1.1 by Abel Deuring
build_vagrant_boxes.py: Copy the existing environment when calling the main build script; prevent some errors when the main build script fails early.
95
        full_build_dir_path = os.path.join(jenkins_kvm, build_dir)
96
        if os.path.exists(full_build_dir_path):
97
            shutil.rmtree(full_build_dir_path)
98
        builder_image = os.path.join(
99
            jenkins_kvm, '%s-builder-%s.img' % (series, arch))
100
        if os.path.exists(builder_image):
101
            os.unlink(builder_image)
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
102
103
619.1.1 by Abel Deuring
build_vagrant_boxes.py: Build only one Vagrant image per run.
104
def clean_workspace(workspace):
105
    """Remove any files and directories found in the workspace."""
106
    for item in os.listdir(workspace):
107
        path = os.path.join(workspace, item)
108
        if os.path.isdir(path):
109
            shutil.rmtree(path)
110
        else:
111
            os.unlink(path)
112
113
114
def main():
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
115
    logging.basicConfig(
116
        level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s',
117
        datefmt='%Y-%m-%d %H:%M:%S')
588.1.2 by Abel Deuring
Use command line parameters instead of the env variables JENKINS_KVM and WORKSPACE.
118
    parser = ArgumentParser('Build Juju-Vagrant boxes')
119
    parser.add_argument(
120
        '--jenkins-kvm', help='Directory with the main build script',
121
        required=True)
122
    parser.add_argument(
123
        '--workspace', help='Workspace directory', required=True)
619.1.1 by Abel Deuring
build_vagrant_boxes.py: Build only one Vagrant image per run.
124
    parser.add_argument(
125
        '--series', help='Build the image for this series', required=True)
126
    parser.add_argument(
127
        '--arch', help='Build the image for this architecture', required=True)
620.1.1 by Abel Deuring
build_vagrant_boxes.py: Use juju-core/juju-local packages built by CI only optionally.
128
    parser.add_argument(
621.1.1 by Abel Deuring
new helper function to find successful build for a given build_revision; build_vagrant_boxes.py uses this function.
129
        '--use-ci-juju-packages',
130
        help=(
131
            'Build the image with juju packages built by CI. The value of '
132
            'this option is a revision_build number. The debian packages '
133
            'are retrieved from a run of the publish-revision for this '
134
            'revision_build.'))
858.1.5 by Curtis Hovey
Use the jujuci functions to get packages for vagrant tests.
135
    add_credential_args(parser)
588.1.2 by Abel Deuring
Use command line parameters instead of the env variables JENKINS_KVM and WORKSPACE.
136
    args = parser.parse_args()
619.1.1 by Abel Deuring
build_vagrant_boxes.py: Build only one Vagrant image per run.
137
    clean_workspace(args.workspace)
621.1.1 by Abel Deuring
new helper function to find successful build for a given build_revision; build_vagrant_boxes.py uses this function.
138
    if args.use_ci_juju_packages is not None:
858.1.5 by Curtis Hovey
Use the jujuci functions to get packages for vagrant tests.
139
        credentials = get_credentials(args)
620.1.1 by Abel Deuring
build_vagrant_boxes.py: Use juju-core/juju-local packages built by CI only optionally.
140
        package_info = get_debian_packages(
858.1.5 by Curtis Hovey
Use the jujuci functions to get packages for vagrant tests.
141
            credentials, args.workspace, args.series, args.arch,
621.1.1 by Abel Deuring
new helper function to find successful build for a given build_revision; build_vagrant_boxes.py uses this function.
142
            args.use_ci_juju_packages)
620.1.1 by Abel Deuring
build_vagrant_boxes.py: Use juju-core/juju-local packages built by CI only optionally.
143
        if 'core' not in package_info:
144
            logging.error('Could not find juju-core package')
145
            sys.exit(1)
146
        if 'local' not in package_info:
147
            logging.error('Could not find juju-local package')
148
            sys.exit(1)
149
    else:
706.1.1 by Aaron Bentley
Switch to flake8 and fix lint.
150
        package_info = None
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
151
    try:
619.1.1 by Abel Deuring
build_vagrant_boxes.py: Build only one Vagrant image per run.
152
        build_vagrant_box(
620.1.1 by Abel Deuring
build_vagrant_boxes.py: Use juju-core/juju-local packages built by CI only optionally.
153
            args.series, args.arch, args.jenkins_kvm, args.workspace,
154
            package_info)
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
155
    finally:
620.1.1 by Abel Deuring
build_vagrant_boxes.py: Use juju-core/juju-local packages built by CI only optionally.
156
        if package_info is not None:
157
            for filename in package_info.values():
158
                os.unlink(filename)
588.1.1 by Abel Deuring
New script build_vagrant_boxes.py
159
160
161
if __name__ == '__main__':
619.1.1 by Abel Deuring
build_vagrant_boxes.py: Build only one Vagrant image per run.
162
    main()