5
Deployment automation for juju.
16
from deployer.config import ConfigStack
17
from deployer.env import select_runtime
18
from deployer.action import diff, importer
19
from deployer.utils import ErrorExit, setup_logging
23
parser = argparse.ArgumentParser()
26
help=('File containing deployment(s) json config. This '
27
'option can be repeated, with later files overriding '
28
'values in earlier ones.'),
29
dest='configs', action='append')
31
'-d', '--debug', help='Enable debugging to stdout',
33
action="store_true", default=False)
36
help='Disallow deployment of locally-modified charms',
37
dest="no_local_mods", default=True, action='store_false')
39
'-u', '--update-charms',
40
help='Update existing charm branches',
41
dest="update_charms", default=False, action="store_true")
43
'-l', '--ls', help='List available deployments',
44
dest="list_deploys", action="store_true", default=False)
46
'-D', '--destroy-services',
47
help='Destroy all services (do not terminate machines)',
48
dest="destroy_services", action="store_true",
51
'-T', '--terminate-machines',
52
help=('Terminate all machines but the bootstrap node. '
53
'Destroy any services that exist on each'),
54
dest="terminate_machines", action="store_true",
58
help='Timeout (sec) for entire deployment (45min default)',
59
dest='timeout', action='store', type=int, default=2700)
61
"-f", '--find-service', action="store", type=str,
62
help='Find hostname from first unit of a specific service.',
65
"-b", '--branch-only', action="store_true",
66
help='Update vcs branches and exit.',
69
'-s', '--deploy-delay', action='store', type=float,
70
help=("Time in seconds to sleep between 'deploy' commands, "
71
"to allow machine provider to process requests. On "
72
"terminate machines this also signals waiting for "
74
dest="deploy_delay", default=0)
76
'-e', '--environment', action='store', dest='juju_env',
77
help='Deploy to a specific Juju environment.',
78
default=os.getenv('JUJU_ENV'))
80
'-o', '--override', action='append', type=str,
81
help=('Override *all* config options of the same name '
82
'across all services. Input as key=value.'),
83
dest='overrides', default=None)
85
'-v', '--verbose', action='store_true', default=False,
86
dest="verbose", help='Verbose output')
88
'-W', '--watch', help='Watch environment changes on console',
89
dest="watch", action="store_true", default=False)
91
'-r', "--retry", default=0, type=int, dest="retry_count",
92
help=("Resolve CLI and unit errors via number of retries (default: 0)."
93
" Either standalone or in a deployment"))
95
"--diff", action="store_true", default=False,
96
help=("Generate a delta between a configured deployment and a running"
99
'-w', '--relation-wait', action='store', dest='rel_wait',
100
default=60, type=int,
101
help=('Number of seconds to wait before checking for '
102
'relation errors after all relations have been added '
103
'and subordinates started. (default: 60)'))
104
parser.add_argument("--description", help=argparse.SUPPRESS,
106
parser.add_argument("deployment", nargs="?")
115
logging.getLogger('deployer.cli').info(
116
"Deployment stopped. run time: %0.2f", time.time() - stime)
121
parser = setup_parser()
122
options = parser.parse_args()
124
if options.description:
125
print "Tool for declarative management of complex deployments."
128
# Debug implies watching and verbose
130
options.watch = options.verbose = True
131
setup_logging(options.verbose, options.debug)
133
log = logging.getLogger("deployer.cli")
134
start_time = time.time()
136
env = select_runtime(options.juju_env, options)
137
log.debug('Using runtime %s', env.__class__.__name__)
139
config = ConfigStack(options.configs or [])
141
# Destroy services and exit
142
if options.destroy_services or options.terminate_machines:
143
log.info("Resetting environment...")
145
env.reset(terminate_machines=options.terminate_machines,
146
terminate_delay=options.deploy_delay,
148
log.info("Environment reset in %0.2f", time.time() - start_time)
151
# Display service info and exit
152
if options.find_service:
153
address = env.get_service_address(options.find_service)
155
log.error("Service not found %r", options.find_service)
158
log.warning("Service: %s has no address for first unit",
159
options.find_service)
161
log.info("Service: %s address: %s", options.find_service, address)
165
# Just resolve/retry hooks in the environment
166
if not options.deployment and options.retry_count:
167
log.info("Retrying hooks for error resolution")
170
options.retry_count, watch=options.watch, timeout=options.timeout)
172
# Arg check on config files and deployment name.
173
if not options.configs:
174
log.error("Config files must be specified")
179
# Just list the available deployments
180
if options.list_deploys:
181
print "\n".join(sorted(config.keys()))
184
# Do something to a deployment
185
if not options.deployment:
187
"Deployment name must be specified. available: %s", tuple(
188
sorted(config.keys())))
191
deployment = config.get(options.deployment)
194
diff.Diff(env, deployment, options).run()
198
log.info("Starting deployment of %s", options.deployment)
199
importer.Importer(env, deployment, options).run()
202
log.info("Deployment complete in %0.2f seconds" % (
203
time.time() - start_time))
206
if __name__ == '__main__':