359
359
ie. --foo_bar is converted to --foo-bar. Non-option arguments
360
360
are left untouched.
367
prog_name = os.path.basename(sys.argv[0])
368
if prog_name in ("__main__.py", "-c"):
369
prog = "{0} -m mojo".format(sys.executable)
372
except (AttributeError, TypeError, IndexError):
376
def __init__(self, *args, **kwargs):
377
if "prog" not in kwargs or kwargs["prog"] is None:
378
kwargs["prog"] = self.get_prog()
379
super(MojoArgumentParser, self).__init__(*args, **kwargs)
362
381
def add_argument(self, *args, **kwargs):
363
382
# Replace _ with - to create a consistent cli, no matter
364
383
# what the callsite chose. We don't need to worry about
390
prog_name = os.path.basename(sys.argv[0])
391
if prog_name in ("__main__.py", "-c"):
392
prog = "{0} -m mojo".format(sys.executable)
395
except (AttributeError, TypeError, IndexError):
400
406
def create_arg_parser():
401
407
# main program parser
402
ap = MojoArgumentParser(prog=get_prog())
408
ap = MojoArgumentParser()
403
409
ap.add_argument("--blunt", action="store_true",
404
410
help="Handle fewer exceptions")
405
411
ap.add_argument("--break_everything", action="store_true",
408
414
help="Log level. Checks $MOJO_LOGLEVEL, defaults to INFO")
409
415
ap.add_argument("--logfile", "-L", default=os.environ.get('MOJO_LOGFILE'),
410
416
help="File to log to in addition to stdout. Overrides environment "
411
"variable MOJO_LOGFILE. Defaults to MOJO_WORKSPACE/log/mojo.log")
417
"variable MOJO_LOGFILE. Defaults to MOJO_WORKSPACE/log/mojo.log")
412
418
ap.add_argument("-r", "--mojo_root", default=os.environ.get('MOJO_ROOT'),
413
419
help="Root directory that mojo works out of Overrides the MOJO_ROOT environment variable. "
414
"Defaults to /srv/mojo for projects using 'lxc' containers and to "
415
" ~/.local/share/mojo for 'lxd' and 'containerless' projects.")
416
ap.add_argument('--version', action='version',
417
version=mojo.__version__)
420
"Defaults to /srv/mojo for projects using 'lxc' containers and to "
421
" ~/.local/share/mojo for 'lxd' and 'containerless' projects.")
422
ap.add_argument('--version', action='version', version=mojo.__version__)
419
424
# subcommand parser
420
425
sp = ap.add_subparsers(title="subcommands", dest="subparser_name")
424
429
project_kwargs = {'help': "Project name. Overrides the MOJO_PROJECT environment variable."}
425
430
series_args = ("-s", "--series")
426
431
series_kwargs = {'default': os.environ.get('MOJO_SERIES'),
427
'help': "Distro series. Overrides the MOJO_SERIES environment variable."}
432
'help': "Distro series. Overrides the MOJO_SERIES environment variable."}
428
433
stage_args = ("--stage", )
429
434
stage_kwargs = {'default': os.environ.get('MOJO_STAGE', 'devel'),
430
435
'help': "Deployment stage. Overrides MOJO_STAGE environment variable (default: devel)"}
444
449
phaseopts.add_argument(*series_args, **series_kwargs)
445
450
phaseopts.add_argument("--spec-url", default=None,
446
451
help='Location of the Mojo spec. Overrides the '
447
'MOJO_SPEC environment variable. If MOJO_SPEC '
448
'is unset, defaults to ".".')
452
'MOJO_SPEC environment variable. If MOJO_SPEC '
453
'is unset, defaults to ".".')
450
455
# project-new subcommand - creates a new mojo project
451
456
prjnewcmd = sp.add_parser("project-new",
452
description="Create a new Mojo project and container")
457
description="Create a new Mojo project and container")
453
458
prjnewcmd.add_argument(*series_args, required=False, **series_kwargs)
454
459
prjnewcmd.add_argument("name", nargs='?', default=os.environ.get('MOJO_PROJECT'),
455
help="Base name of the project ([a-zA-Z0-9._]*)")
460
help="Base name of the project ([a-zA-Z0-9._]*)")
456
461
prjnewcmd.add_argument('-c', "--container", default=os.environ.get('MOJO_CONTAINER', 'lxc'),
457
choices=['lxc', 'lxd', 'containerless'],
458
help="Container. Options 'lxc', 'lxd' or 'containerless'. "
462
choices=['lxc', 'lxd', 'containerless'],
463
help="Container. Options 'lxc', 'lxd' or 'containerless'. "
460
465
prjnewcmd.set_defaults(func=call_project_new)
462
467
# project-destroy subcommand - deletes a mojo project
463
468
prjdelcmd = sp.add_parser("project-destroy",
464
469
description="Destroy a Mojo project and container")
465
470
prjdelcmd.add_argument("name", default=os.environ.get('MOJO_PROJECT'),
466
help="Base name of the project ([a-zA-Z0-9._]*)")
471
help="Base name of the project ([a-zA-Z0-9._]*)")
467
472
prjdelcmd.add_argument(*series_args, **series_kwargs)
468
473
prjdelcmd.set_defaults(func=call_project_destroy)
471
476
prjlistcmd = sp.add_parser("project-list",
472
description="List existing projects, found at the mojo root")
477
description="List existing projects, found at the mojo root")
473
478
prjlistcmd.add_argument("-n", "--names", action="store_true",
474
479
help="List only project names, without series")
475
480
prjlistcmd.set_defaults(func=list_projects)
477
482
# workspace-new subcommand - creates a new workspace for a specific spec
479
484
wsnewcmd = sp.add_parser("workspace-new",
480
description="Initialize a mojo workspace")
485
description="Initialize a mojo workspace")
481
486
wsnewcmd.add_argument("spec_url", nargs='?', default=None,
482
487
help='Location of the Mojo spec. Overrides the '
483
'MOJO_SPEC environment variable. If MOJO_SPEC '
484
'is unset, defaults to ".".')
488
'MOJO_SPEC environment variable. If MOJO_SPEC '
489
'is unset, defaults to ".".')
485
490
wsnewcmd.add_argument("workspace", nargs='?', default=None, help=workspace_kwargs['help'])
486
491
wsnewcmd.add_argument(*project_args, **project_kwargs)
487
492
wsnewcmd.add_argument(*series_args, **series_kwargs)
491
496
# workspace-destroy subcommand - deletes a mojo project
492
497
wsdelcmd = sp.add_parser("workspace-destroy",
493
description="Destroy a mojo workspace")
498
description="Destroy a mojo workspace")
494
499
wsdelcmd.add_argument(*project_args, **project_kwargs)
495
500
wsdelcmd.add_argument(*series_args, **series_kwargs)
496
501
wsdelcmd.add_argument(*workspace_args, **workspace_kwargs)
499
504
# workspace-list subcommand
500
505
wslistcmd = sp.add_parser("workspace-list",
501
description="List workspaces for a project")
506
description="List workspaces for a project")
502
507
wslistcmd.add_argument(*project_args, **project_kwargs)
503
508
wslistcmd.add_argument(*series_args, **series_kwargs)
504
509
wslistcmd.set_defaults(func=list_workspaces)
517
522
# charm-audit subcommand - runs a charm audit
518
523
charmauditcmd = sp.add_parser("charm-audit",
519
description="Run a charm audit",
524
description="Run a charm audit",
521
526
charmauditcmd.set_defaults(func=run_phase)
523
528
# build subcommand - run project build script inside container
524
529
buildcmd = sp.add_parser("build",
525
description="Execute project build script",
530
description="Execute project build script",
527
532
buildcmd.set_defaults(func=run_phase)
529
534
# repo subcommand - assembles charms into a repository
534
539
# sleep subcommand - sleeps for n seconds
535
540
sleepcmd = sp.add_parser("sleep", description="Sleep for time in seconds",
537
542
sleepcmd.set_defaults(func=run_phase)
539
544
# secrets subcommand - secretss for n seconds
540
545
secretscmd = sp.add_parser("secrets",
541
description="Copy secrets from staged "
542
"location to workspace local",
546
description="Copy secrets from staged "
547
"location to workspace local",
544
549
secretscmd.set_defaults(func=run_phase)
546
551
# script subcommand - run an arbitrary script inside container
547
552
scriptcmd = sp.add_parser("script", description="Execute a project script",
549
554
scriptcmd.set_defaults(func=run_phase)
551
556
# bundle subcommand - run a juju deploy using bundles
552
557
bundlecmd = sp.add_parser("bundle",
553
description="Deploy applications and relations using juju bundles",
558
description="Deploy applications and relations using juju bundles",
555
560
bundlecmd.set_defaults(func=run_phase)
557
562
# deploy subcommand - run a juju-deployer session
558
563
deploycmd = sp.add_parser("deploy",
559
description="Deploy services and/or create "
564
description="Deploy services and/or create "
562
567
deploycmd.add_argument("--ignore", action="store_true", default=False,
563
568
help="Exit 0 even if service deployment fails")
564
569
deploycmd.set_defaults(func=run_phase)
566
571
# deploy-show subcommand
567
572
deployshowcmd = sp.add_parser("deploy-show",
568
description="Show rendered juju-deployer "
573
description="Show rendered juju-deployer "
571
576
deployshowcmd.set_defaults(func=show_deploy)
573
578
# deploy-diff subcommand
574
579
deploydiffcmd = sp.add_parser("deploy-diff",
575
description="Show juju-deployer diff. "
576
"Generate a delta between a "
577
"configured deployment and a "
578
"running environment.",
580
description="Show juju-deployer diff. "
581
"Generate a delta between a "
582
"configured deployment and a "
583
"running environment.",
581
586
configapplicationgroup = deploydiffcmd.add_mutually_exclusive_group()
582
587
configapplicationgroup.add_argument(
593
598
# volumes subcommand - mount volumes
594
599
volcmd = sp.add_parser("volumes", description="Mount volumes",
596
601
volcmd.set_defaults(func=run_phase)
598
603
# verify subcommand - verify that a deployment was successful
599
604
verifycmd = sp.add_parser("verify",
600
description="Verify that the deployment is "
605
description="Verify that the deployment is "
603
608
verifycmd.set_defaults(func=run_phase)
605
610
# juju-check-wait subcommand - wait until juju environment reaches steady state
606
611
jujucheckwaitcmd = sp.add_parser("juju-check-wait",
607
description="Wait until juju environment "
608
"reaches steady state.",
612
description="Wait until juju environment "
613
"reaches steady state.",
610
615
jujucheckwaitcmd.set_defaults(func=run_phase)
612
617
# nagios-check subcommand - run all nagios checks in an environment
613
618
nagioscheckcmd = sp.add_parser("nagios-check",
614
description="Run all nagios checks in the environment",
619
description="Run all nagios checks in the environment",
616
621
nagioscheckcmd.set_defaults(func=run_phase)
618
623
# run subcommand - run an entire spec per its manifest
619
624
runcmd = sp.add_parser("run",
620
description="Run an entire deployment from start "
625
description="Run an entire deployment from start "
622
627
runcmd.add_argument("spec_url", nargs='?', default=None,
623
628
help='Location of the Mojo spec. Overrides the '
624
'MOJO_SPEC environment variable. If MOJO_SPEC '
625
'is unset, defaults to ".".')
629
'MOJO_SPEC environment variable. If MOJO_SPEC '
630
'is unset, defaults to ".".')
626
631
runcmd.add_argument("workspace", nargs='?', default=None, help=workspace_kwargs['help'])
627
632
runcmd.add_argument("-i", "--interactive", action="store_true", default=False,
628
633
help="Run the manifest in interactive mode, prompting for each phase before running it")
641
646
# help subcommand - get help for other subcommands
642
647
helpcmd = sp.add_parser("help", description="Interactive help")
643
648
helpcmd.add_argument("command", nargs='?', default=None,
644
help="Get help for this sub-command.")
649
help="Get help for this sub-command.")
645
650
helpcmd.set_defaults(func=display_help, parser=ap)