3
from helpers import command, Config, run
7
install_extra_repository,
4
12
from subprocess import CalledProcessError
10
18
# config_file is changed via juju like:
11
19
# juju set buildbot-master config-file=`uuencode master.cfg`
21
CONFIG_PICKLE = "config.pkl"
26
SUPPORTED_TRANSPORTS = ['bzr']
28
restart_required = False
13
30
log = command('juju-log')
14
31
bzr = command('bzr')
32
apt_get_install = command('apt-get', 'install', '-y', '--force-yes')
16
34
# Log the fact that we're about to begin the install step.
17
35
log('--> config-changed')
20
buildbot_dir = config['installdir']
21
config_file = config['config-file']
22
config_transport = config['config-transport']
23
config_url = config['config-url']
40
# If all of the required keys are not present in the configuration then exit
42
if not all(config.get(k) for k in REQUIRED_KEYS):
43
log('All required items not configured: {}'.format(REQUIRED_KEYS))
47
prev_config = load_pickle(CONFIG_PICKLE)
48
diff = DictDiffer(config, prev_config)
51
log("No configuration changes, exiting.")
25
54
log('Updating buildbot configuration.')
55
log('Configuration changes seen:')
58
buildbot_pkg = config.get('buildbot-pkg')
59
buildbot_dir = config.get('installdir')
60
config_file = config.get('config-file')
61
config_transport = config.get('config-transport')
62
config_url = config.get('config-url')
63
extra_repo = config.get('extra-repository')
64
extra_pkgs = config.get('extra-packages')
66
# Add a new repository if it was just added.
67
if extra_repo and 'extra-repository' in diff.added_or_changed:
68
install_extra_repository(extra_repo)
69
restart_required = True
71
if extra_pkgs and 'extra_packages' not in diff.unchanged:
72
apt_get_install(extra_pkgs)
73
restart_required = True
75
if 'buildbot-pkg' not in diff.unchanged:
76
apt_get_install(buildbot_pkg)
77
restart_required = True
79
# Ensure the install directory exists.
80
if not os.path.exists(buildbot_dir):
81
os.makedirs(buildbot_dir)
83
# If asked to fetch the config file then it must be a transport we support.
84
if config_url and config_transport not in SUPPORTED_TRANSPORTS:
85
log("{} is an unsupported transport".format(config_transport))
26
88
# Write the buildbot config to disk (fetching it if necessary).
89
if config_file and 'config-file' not in diff.unchanged:
90
if not os.path.exists(buildbot_dir):
91
os.makedirs(buildbot_dir)
28
92
with open(os.path.join(buildbot_dir, 'master.cfg', 'w')) as f:
29
93
f.write(base64.decode(config_file))
30
log('Config decoded and written.')
31
elif config_transport == 'bzr' and config_url:
94
log('config_file decoded and written.')
95
restart_required = True
96
elif (config_transport == 'bzr' and config_url and
97
'config-transport' not in diff.unchanged and
98
'config-url' not in diff.unchanged):
32
99
# If the branch is private then more setup needs to be done. The
33
100
# gpg-agent needs to send the key over and the bzr launchpad-login
35
lp_id = config['config-user']
102
lp_id = config.get('config-user')
37
104
bzr('launchpad-login', lp_id)
39
private_key = config['config-private-key']
106
private_key = config.get('config-private-key')
41
108
# Set up the .ssh directory.
42
109
ssh_dir = os.expanduser('~/.ssh')
44
111
os.chmod(ssh_dir, 0700)
45
112
with open(os.path.join(ssh_dir, 'lp_key', w)) as f:
46
113
f.write(base64.decode(private_key))
48
114
bzr('branch', '--use-existing-dir', config_url, buildbot_dir)
49
115
run('chown', '-R', 'ubuntu:ubuntu', buildbot_dir)
116
log('configuration fetched from {}'.format(config_url))
117
restart_required = True
51
# XXX Is it an error to get to this point?
119
# Configuration file specifiers are unchanged or unrecognized.
54
122
# Restart buildbot if it is running.
55
pidfile = os.path.join(buildbot_dir, 'twistd.pid')
56
if os.path.exists(pidfile):
57
buildbot_pid = open(pidfile).read().strip()
59
# Is buildbot running?
60
run('kill', '-0', buildbot_pid)
61
except CalledProcessError:
62
# Buildbot isn't running, so no need to reconfigure it.
124
pidfile = os.path.join(buildbot_dir, 'twistd.pid')
125
if os.path.exists(pidfile):
126
buildbot_pid = open(pidfile).read().strip()
128
# Is buildbot running?
129
run('kill', '-0', buildbot_pid)
130
except CalledProcessError:
131
# Buildbot isn't running, so no need to reconfigure it.
134
# Buildbot is running, reconfigure it.
135
log('Reconfiguring buildbot')
136
run('buildbot', 'reconfig', buildbot_dir)
137
log('Buildbot reconfigured')
65
# Buildbot is running, reconfigure it.
66
log('Reconfiguring buildbot')
67
run('buildbot', 'reconfig', buildbot_dir)
68
log('Buildbot reconfigured')
139
# Buildbot isn't running so start afresh but only if properly
141
if os.path.exists(os.path.join(buildbot_dir, 'master.cfg')):
142
run('buildbot', 'start', buildbot_dir)
144
log("Configuration changed but didn't require restarting.")
146
save_pickle(config, CONFIG_PICKLE)
70
148
log('<-- config-changed')