def setup_chroot(parser, **kwargs): """Unpacks the files and run with chroot setup/create creates the directory (needs the pack filename) setup/mount mounts --bind /dev and /proc inside the chroot (do NOT rm -Rf the directory after that!) upload replaces input files in the directory (without arguments, lists input files) run runs the experiment download gets output files (without arguments, lists output files) destroy/unmount unmounts /dev and /proc from the directory destroy/dir removes the unpacked directory Upload specifications are either: :input_id restores the original input file from the pack filename:input_id replaces the input file with the specified local file Download specifications are either: output_id: print the output file to stdout output_id:filename extracts the output file to the corresponding local path """ subparsers = parser.add_subparsers(title="actions", metavar='', help=argparse.SUPPRESS) def add_opt_general(opts): opts.add_argument('target', nargs=1, help="Experiment directory") # setup/create def add_opt_setup(opts): opts.add_argument('pack', nargs=1, help="Pack to extract") def add_opt_owner(opts): opts.add_argument('--preserve-owner', action='store_true', dest='restore_owner', default=None, help="Restore files' owner/group when extracting") opts.add_argument('--dont-preserve-owner', action='store_false', dest='restore_owner', default=None, help="Don't restore files' owner/group when " "extracting, use current users") parser_setup_create = subparsers.add_parser('setup/create') add_opt_setup(parser_setup_create) add_opt_general(parser_setup_create) add_opt_owner(parser_setup_create) parser_setup_create.set_defaults(func=chroot_create) # setup/mount parser_setup_mount = subparsers.add_parser('setup/mount') add_opt_general(parser_setup_mount) parser_setup_mount.set_defaults(func=chroot_mount) # setup parser_setup = subparsers.add_parser('setup') add_opt_setup(parser_setup) add_opt_general(parser_setup) add_opt_owner(parser_setup) parser_setup.add_argument( '--bind-magic-dirs', action='store_true', dest='bind_magic_dirs', default=None, help="Mount /dev and /proc inside the chroot") parser_setup.add_argument( '--dont-bind-magic-dirs', action='store_false', dest='bind_magic_dirs', default=None, help="Don't mount /dev and /proc inside the chroot") parser_setup.set_defaults(func=chroot_setup) # upload parser_upload = subparsers.add_parser('upload') add_opt_general(parser_upload) add_opt_owner(parser_upload) parser_upload.add_argument('file', nargs=argparse.ZERO_OR_MORE, help="<path>:<input_file_name>") parser_upload.set_defaults(func=upload, type='chroot') # run parser_run = subparsers.add_parser('run') add_opt_general(parser_run) parser_run.add_argument('run', default=None, nargs=argparse.OPTIONAL) parser_run.add_argument('--cmdline', nargs=argparse.REMAINDER, help="Command line to run") parser_run.add_argument('--enable-x11', action='store_true', default=False, dest='x11', help="Enable X11 support (needs an X server on " "the host)") parser_run.add_argument('--x11-display', dest='x11_display', help="Display number to use on the experiment " "side (change the host display with the " "DISPLAY environment variable)") add_environment_options(parser_run) parser_run.set_defaults(func=chroot_run) # download parser_download = subparsers.add_parser('download') add_opt_general(parser_download) parser_download.add_argument('file', nargs=argparse.ZERO_OR_MORE, help="<output_file_name>[:<path>]") parser_download.add_argument('--all', action='store_true', help="Download all output files to the " "current directory") parser_download.set_defaults(func=download, type='chroot') # destroy/unmount parser_destroy_unmount = subparsers.add_parser('destroy/unmount') add_opt_general(parser_destroy_unmount) parser_destroy_unmount.set_defaults(func=chroot_destroy_unmount) # destroy/dir parser_destroy_dir = subparsers.add_parser('destroy/dir') add_opt_general(parser_destroy_dir) parser_destroy_dir.set_defaults(func=chroot_destroy_dir) # destroy parser_destroy = subparsers.add_parser('destroy') add_opt_general(parser_destroy) parser_destroy.set_defaults(func=chroot_destroy) return {'test_compatibility': test_linux_same_arch}
def setup(parser, **kwargs): """Runs the experiment in a Docker container You will need Docker to be installed on your machine if you want to run the experiment. setup setup/create creates Dockerfile (needs the pack filename) setup/build builds the container from the Dockerfile reset resets the Docker image to the initial state (just after setup) upload replaces input files in the container (without arguments, lists input files) run runs the experiment in the container download gets output files from the container (without arguments, lists output files) destroy destroy/docker destroys the container and associated images destroy/dir removes the unpacked directory For example: $ reprounzip docker setup mypack.rpz experiment; cd experiment $ reprounzip docker run . $ reprounzip docker download . results:/home/user/theresults.txt $ cd ..; reprounzip docker destroy experiment Upload specifications are either: :input_id restores the original input file from the pack filename:input_id replaces the input file with the specified local file Download specifications are either: output_id: print the output file to stdout output_id:filename extracts the output file to the corresponding local path """ subparsers = parser.add_subparsers(title="actions", metavar='', help=argparse.SUPPRESS) def add_opt_general(opts): opts.add_argument('target', nargs=1, help="Experiment directory") # setup/create def add_opt_setup(opts): opts.add_argument('pack', nargs=1, help="Pack to extract") opts.add_argument('--base-image', nargs=1, help="Base image to use") opts.add_argument('--distribution', nargs=1, help="Distribution used in the base image (for " "package installer selection)") opts.add_argument('--install-pkgs', action='store_true', default=False, help="Install packages rather than extracting " "them from RPZ file") opts.add_argument('--unpack-pkgs', action='store_false', default=False, dest='install_pkgs', help=argparse.SUPPRESS) # --docker-option def add_raw_docker_option(opts): opts.add_argument('--docker-option', action='append', default=[], help="Argument passed to Docker directly; may be " "specified multiple times") parser_setup_create = subparsers.add_parser('setup/create') add_opt_setup(parser_setup_create) add_opt_general(parser_setup_create) parser_setup_create.set_defaults(func=docker_setup_create) # setup/build parser_setup_build = subparsers.add_parser('setup/build') add_opt_general(parser_setup_build) add_raw_docker_option(parser_setup_build) parser_setup_build.set_defaults(func=docker_setup_build) # setup parser_setup = subparsers.add_parser('setup') add_opt_setup(parser_setup) add_opt_general(parser_setup) add_raw_docker_option(parser_setup) parser_setup.set_defaults(func=docker_setup) # reset parser_reset = subparsers.add_parser('reset') add_opt_general(parser_reset) parser_reset.set_defaults(func=docker_reset) # upload parser_upload = subparsers.add_parser('upload') add_opt_general(parser_upload) parser_upload.add_argument('file', nargs=argparse.ZERO_OR_MORE, help="<path>:<input_file_name") parser_upload.set_defaults(func=docker_upload) # run parser_run = subparsers.add_parser('run') add_opt_general(parser_run) parser_run.add_argument('run', default=None, nargs=argparse.OPTIONAL) parser_run.add_argument('--cmdline', nargs=argparse.REMAINDER, help="Command line to run") parser_run.add_argument('--enable-x11', action='store_true', default=False, dest='x11', help="Enable X11 support (needs an X server on " "the host)") parser_run.add_argument('--x11-display', dest='x11_display', help="Display number to use on the experiment " "side (change the host display with the " "DISPLAY environment variable)") parser_run.add_argument( '--tunneled-x11', dest='tunneled_x11', action='store_true', default=False, help="Connect X11 to local machine from Docker container instead of " "trying to connect to this one (useful if the Docker machine has " "an X server or if a tunnel is used to access this one)") parser_run.add_argument('-d', '--detach', action='store_true', help="Don't attach or commit the created " "container, just start it and leave it be") add_raw_docker_option(parser_run) add_environment_options(parser_run) parser_run.set_defaults(func=docker_run) # download parser_download = subparsers.add_parser('download') add_opt_general(parser_download) parser_download.add_argument('file', nargs=argparse.ZERO_OR_MORE, help="<output_file_name>[:<path>]") parser_download.add_argument('--all', action='store_true', help="Download all output files to the " "current directory") parser_download.set_defaults(func=docker_download) # destroy/docker parser_destroy_docker = subparsers.add_parser('destroy/docker') add_opt_general(parser_destroy_docker) parser_destroy_docker.set_defaults(func=docker_destroy_docker) # destroy/dir parser_destroy_dir = subparsers.add_parser('destroy/dir') add_opt_general(parser_destroy_dir) parser_destroy_dir.set_defaults(func=docker_destroy_dir) # destroy parser_destroy = subparsers.add_parser('destroy') add_opt_general(parser_destroy) parser_destroy.set_defaults( func=composite_action(docker_destroy_docker, docker_destroy_dir)) return {'test_compatibility': test_has_docker}
def setup_directory(parser, **kwargs): """Unpacks the files in a directory and runs with PATH and LD_LIBRARY_PATH setup creates the directory (needs the pack filename) upload replaces input files in the directory (without arguments, lists input files) run runs the experiment download gets output files (without arguments, lists output files) destroy removes the unpacked directory Upload specifications are either: :input_id restores the original input file from the pack filename:input_id replaces the input file with the specified local file Download specifications are either: output_id: print the output file to stdout output_id:filename extracts the output file to the corresponding local path """ subparsers = parser.add_subparsers(title="actions", metavar='', help=argparse.SUPPRESS) def add_opt_general(opts): opts.add_argument('target', nargs=1, help="Experiment directory") # setup parser_setup = subparsers.add_parser('setup') parser_setup.add_argument('pack', nargs=1, help="Pack to extract") # Note: add_opt_general is called later so that 'pack' is before 'target' add_opt_general(parser_setup) parser_setup.set_defaults(func=directory_create) # upload parser_upload = subparsers.add_parser('upload') add_opt_general(parser_upload) parser_upload.add_argument('file', nargs=argparse.ZERO_OR_MORE, help="<path>:<input_file_name>") parser_upload.set_defaults(func=upload, type='directory') # run parser_run = subparsers.add_parser('run') add_opt_general(parser_run) parser_run.add_argument('run', default=None, nargs=argparse.OPTIONAL) parser_run.add_argument('--cmdline', nargs=argparse.REMAINDER, help="Command line to run") parser_run.add_argument('--enable-x11', action='store_true', default=False, dest='x11', help="Enable X11 support (needs an X server)") add_environment_options(parser_run) parser_run.set_defaults(func=directory_run) # download parser_download = subparsers.add_parser('download') add_opt_general(parser_download) parser_download.add_argument('file', nargs=argparse.ZERO_OR_MORE, help="<output_file_name>[:<path>]") parser_download.add_argument('--all', action='store_true', help="Download all output files to the " "current directory") parser_download.set_defaults(func=download, type='directory') # destroy parser_destroy = subparsers.add_parser('destroy') add_opt_general(parser_destroy) parser_destroy.set_defaults(func=directory_destroy) return {'test_compatibility': test_linux_same_arch}
def setup(parser, **kwargs): """Runs the experiment in a virtual machine created through Vagrant You will need Vagrant to be installed on your machine if you want to run the experiment. setup setup/create creates Vagrantfile (needs the pack filename) setup/start starts or resume the virtual machine upload replaces input files in the machine (without arguments, lists input files) run runs the experiment in the virtual machine suspend suspend the virtual machine without destroying it download gets output files from the machine (without arguments, lists output files) destroy destroy/vm destroys the virtual machine destroy/dir removes the unpacked directory For example: $ reprounzip vagrant setup mypack.rpz experiment; cd experiment $ reprounzip vagrant run . $ reprounzip vagrant download . results:/home/user/theresults.txt $ cd ..; reprounzip vagrant destroy experiment Upload specifications are either: :input_id restores the original input file from the pack filename:input_id replaces the input file with the specified local file Download specifications are either: output_id: print the output file to stdout output_id:filename extracts the output file to the corresponding local path """ subparsers = parser.add_subparsers(title="actions", metavar='', help=argparse.SUPPRESS) def add_opt_general(opts): opts.add_argument('target', nargs=1, help="Experiment directory") # setup/create def add_opt_setup(opts): opts.add_argument('pack', nargs=1, help="Pack to extract") opts.add_argument( '--use-chroot', action='store_true', default=True, help=argparse.SUPPRESS) opts.add_argument( '--dont-use-chroot', action='store_false', dest='use_chroot', default=True, help=("Don't prefer original files nor use chroot in the virtual " "machine")) opts.add_argument( '--no-use-chroot', action='store_false', dest='use_chroot', default=True, help=argparse.SUPPRESS) opts.add_argument( '--dont-bind-magic-dirs', action='store_false', default=True, dest='bind_magic_dirs', help="Don't mount /dev and /proc inside the chroot (no effect if " "--dont-use-chroot is set)") opts.add_argument('--base-image', nargs=1, help="Vagrant box to use") opts.add_argument('--distribution', nargs=1, help=("Distribution used in the Vagrant box (for " "package installer selection)")) opts.add_argument('--memory', nargs=1, help="Amount of RAM to allocate to VM (megabytes, " "default: box default)") parser_setup_create = subparsers.add_parser('setup/create') add_opt_setup(parser_setup_create) add_opt_general(parser_setup_create) parser_setup_create.set_defaults(func=vagrant_setup_create) # setup/start parser_setup_start = subparsers.add_parser('setup/start') add_opt_general(parser_setup_start) parser_setup_start.set_defaults(func=vagrant_setup_start) # setup parser_setup = subparsers.add_parser('setup') add_opt_setup(parser_setup) add_opt_general(parser_setup) parser_setup.set_defaults(func=composite_action(vagrant_setup_create, vagrant_setup_start)) # upload parser_upload = subparsers.add_parser('upload') add_opt_general(parser_upload) parser_upload.add_argument('file', nargs=argparse.ZERO_OR_MORE, help="<path>:<input_file_name") parser_upload.set_defaults(func=vagrant_upload) # run parser_run = subparsers.add_parser('run') add_opt_general(parser_run) parser_run.add_argument('run', default=None, nargs='?') parser_run.add_argument('--no-stdin', action='store_true', default=False, help=("Don't connect program's input stream to " "this terminal")) parser_run.add_argument('--no-pty', action='store_true', default=False, help="Don't request a PTY from the SSH server") parser_run.add_argument('--cmdline', nargs=argparse.REMAINDER, help="Command line to run") parser_run.add_argument('--enable-x11', action='store_true', default=False, dest='x11', help=("Enable X11 support (needs an X server on " "the host)")) parser_run.add_argument('--x11-display', dest='x11_display', help=("Display number to use on the experiment " "side (change the host display with the " "DISPLAY environment variable)")) add_environment_options(parser_run) parser_run.set_defaults(func=vagrant_run) # download parser_download = subparsers.add_parser('download') add_opt_general(parser_download) parser_download.add_argument('file', nargs=argparse.ZERO_OR_MORE, help="<output_file_name>:<path>") parser_download.set_defaults(func=vagrant_download) # destroy/vm parser_destroy_vm = subparsers.add_parser('destroy/vm') add_opt_general(parser_destroy_vm) parser_destroy_vm.set_defaults(func=vagrant_destroy_vm) # destroy/dir parser_destroy_dir = subparsers.add_parser('destroy/dir') add_opt_general(parser_destroy_dir) parser_destroy_dir.set_defaults(func=vagrant_destroy_dir) # destroy parser_destroy = subparsers.add_parser('destroy') add_opt_general(parser_destroy) parser_destroy.set_defaults(func=composite_action(vagrant_destroy_vm, vagrant_destroy_dir)) return {'test_compatibility': test_has_vagrant}
def setup(parser, **kwargs): """Runs the experiment in a Docker container You will need Docker to be installed on your machine if you want to run the experiment. setup setup/create creates Dockerfile (needs the pack filename) setup/build builds the container from the Dockerfile reset resets the Docker image to the initial state (just after setup) upload replaces input files in the container (without arguments, lists input files) run runs the experiment in the container download gets output files from the container (without arguments, lists output files) destroy destroy/docker destroys the container and associated images destroy/dir removes the unpacked directory For example: $ reprounzip docker setup mypack.rpz experiment; cd experiment $ reprounzip docker run . $ reprounzip docker download . results:/home/user/theresults.txt $ cd ..; reprounzip docker destroy experiment Upload specifications are either: :input_id restores the original input file from the pack filename:input_id replaces the input file with the specified local file Download specifications are either: output_id: print the output file to stdout output_id:filename extracts the output file to the corresponding local path """ parser.add_argument('--docker-cmd', action='store', default='docker', help="Change the Docker command; split on spaces") subparsers = parser.add_subparsers(title="actions", metavar='', help=argparse.SUPPRESS) def add_opt_general(opts): opts.add_argument('target', nargs=1, help="Experiment directory") # Common between setup and setup/create def add_opt_setup_create(opts): opts.add_argument('pack', nargs=1, help="Pack to extract") opts.add_argument('--base-image', nargs=1, help="Base image to use") opts.add_argument('--distribution', nargs=1, help="Distribution used in the base image (for " "package installer selection)") opts.add_argument('--install-pkgs', action='store_true', default=False, help="Install packages rather than extracting " "them from RPZ file") opts.add_argument('--unpack-pkgs', action='store_false', default=False, dest='install_pkgs', help=argparse.SUPPRESS) # Common between setup and setup/build def add_opt_setup_build(opts): opts.add_argument('--image-name', nargs=1, help="Name of the image to create (by default, a " "random name beginning with " "'reprounzip_image_' is generated)") add_raw_docker_option(opts) # --docker-option def add_raw_docker_option(opts): opts.add_argument('--docker-option', action='append', default=[], help="Argument passed to Docker directly; may be " "specified multiple times") parser_setup_create = subparsers.add_parser('setup/create') add_opt_setup_create(parser_setup_create) add_opt_general(parser_setup_create) parser_setup_create.set_defaults(func=docker_setup_create) # setup/build parser_setup_build = subparsers.add_parser('setup/build') add_opt_general(parser_setup_build) add_opt_setup_build(parser_setup_build) parser_setup_build.set_defaults(func=docker_setup_build) # setup parser_setup = subparsers.add_parser('setup') add_opt_setup_create(parser_setup) add_opt_setup_build(parser_setup) add_opt_general(parser_setup) parser_setup.set_defaults(func=docker_setup) # reset parser_reset = subparsers.add_parser('reset') add_opt_general(parser_reset) parser_reset.set_defaults(func=docker_reset) # upload parser_upload = subparsers.add_parser('upload') add_opt_general(parser_upload) parser_upload.add_argument('file', nargs=argparse.ZERO_OR_MORE, help="<path>:<input_file_name>") parser_upload.set_defaults(func=docker_upload) # run parser_run = subparsers.add_parser('run') add_opt_general(parser_run) parser_run.add_argument('run', default=None, nargs=argparse.OPTIONAL) parser_run.add_argument('--cmdline', nargs=argparse.REMAINDER, help="Command line to run") parser_run.add_argument('--expose-port', '-p', action='append', default=[], help="Expose a network port, " "host[:experiment[/proto]]. Example: 8000:80") parser_run.add_argument('--enable-x11', action='store_true', default=False, dest='x11', help="Enable X11 support (needs an X server on " "the host)") parser_run.add_argument('--x11-display', dest='x11_display', help="Display number to use on the experiment " "side (change the host display with the " "DISPLAY environment variable)") parser_run.add_argument( '--tunneled-x11', dest='tunneled_x11', action='store_true', default=False, help="Connect X11 to local machine from Docker container instead of " "trying to connect to this one (useful if the Docker machine has " "an X server or if a tunnel is used to access this one)") parser_run.add_argument('-d', '--detach', action='store_true', help="Don't attach or commit the created " "container, just start it and leave it be") add_raw_docker_option(parser_run) add_environment_options(parser_run) parser_run.set_defaults(func=docker_run) # download parser_download = subparsers.add_parser('download') add_opt_general(parser_download) parser_download.add_argument('file', nargs=argparse.ZERO_OR_MORE, help="<output_file_name>[:<path>]") parser_download.add_argument('--all', action='store_true', help="Download all output files to the " "current directory") parser_download.set_defaults(func=docker_download) # destroy/docker parser_destroy_docker = subparsers.add_parser('destroy/docker') add_opt_general(parser_destroy_docker) parser_destroy_docker.set_defaults(func=docker_destroy_docker) # destroy/dir parser_destroy_dir = subparsers.add_parser('destroy/dir') add_opt_general(parser_destroy_dir) parser_destroy_dir.set_defaults(func=docker_destroy_dir) # destroy parser_destroy = subparsers.add_parser('destroy') add_opt_general(parser_destroy) parser_destroy.set_defaults(func=composite_action(docker_destroy_docker, docker_destroy_dir)) return {'test_compatibility': test_has_docker}
def setup(parser, **kwargs): """Runs the experiment in a virtual machine created through Vagrant You will need Vagrant to be installed on your machine if you want to run the experiment. setup setup/create creates Vagrantfile (needs the pack filename) setup/start starts or resume the virtual machine upload replaces input files in the machine (without arguments, lists input files) run runs the experiment in the virtual machine suspend suspend the virtual machine without destroying it download gets output files from the machine (without arguments, lists output files) destroy destroy/vm destroys the virtual machine destroy/dir removes the unpacked directory For example: $ reprounzip vagrant setup mypack.rpz experiment; cd experiment $ reprounzip vagrant run . $ reprounzip vagrant download . results:/home/user/theresults.txt $ cd ..; reprounzip vagrant destroy experiment Upload specifications are either: :input_id restores the original input file from the pack filename:input_id replaces the input file with the specified local file Download specifications are either: output_id: print the output file to stdout output_id:filename extracts the output file to the corresponding local path """ subparsers = parser.add_subparsers(title="actions", metavar='', help=argparse.SUPPRESS) def add_opt_general(opts): opts.add_argument('target', nargs=1, help="Experiment directory") # setup/create def add_opt_setup(opts): opts.add_argument('pack', nargs=1, help="Pack to extract") opts.add_argument( '--use-chroot', action='store_true', default=True, help=argparse.SUPPRESS) opts.add_argument( '--dont-use-chroot', action='store_false', dest='use_chroot', default=True, help="Don't prefer original files nor use chroot in the virtual " "machine") opts.add_argument( '--no-use-chroot', action='store_false', dest='use_chroot', default=True, help=argparse.SUPPRESS) opts.add_argument( '--dont-bind-magic-dirs', action='store_false', default=True, dest='bind_magic_dirs', help="Don't mount /dev and /proc inside the chroot (no effect if " "--dont-use-chroot is set)") opts.add_argument('--base-image', nargs=1, help="Vagrant box to use") opts.add_argument('--distribution', nargs=1, help="Distribution used in the Vagrant box (for " "package installer selection)") opts.add_argument('--memory', nargs=1, help="Amount of RAM to allocate to VM (megabytes, " "default: box default)") opts.add_argument('--use-gui', action='store_true', default=False, dest='gui', help="Use the VM's X server") parser_setup_create = subparsers.add_parser('setup/create') add_opt_setup(parser_setup_create) add_opt_general(parser_setup_create) parser_setup_create.set_defaults(func=vagrant_setup_create) # setup/start parser_setup_start = subparsers.add_parser('setup/start') add_opt_general(parser_setup_start) parser_setup_start.set_defaults(func=vagrant_setup_start) # setup parser_setup = subparsers.add_parser('setup') add_opt_setup(parser_setup) add_opt_general(parser_setup) parser_setup.set_defaults(func=composite_action(vagrant_setup_create, vagrant_setup_start)) # upload parser_upload = subparsers.add_parser('upload') add_opt_general(parser_upload) parser_upload.add_argument('file', nargs=argparse.ZERO_OR_MORE, help="<path>:<input_file_name") parser_upload.set_defaults(func=vagrant_upload) # run parser_run = subparsers.add_parser('run') add_opt_general(parser_run) parser_run.add_argument('run', default=None, nargs=argparse.OPTIONAL) parser_run.add_argument('--no-stdin', action='store_true', default=False, help="Don't connect program's input stream to " "this terminal") parser_run.add_argument('--no-pty', action='store_true', default=False, help="Don't request a PTY from the SSH server") parser_run.add_argument('--cmdline', nargs=argparse.REMAINDER, help="Command line to run") parser_run.add_argument('--enable-x11', action='store_true', default=False, dest='x11', help="Enable X11 support (needs an X server on " "the host)") parser_run.add_argument('--x11-display', dest='x11_display', help="Display number to use on the experiment " "side (change the host display with the " "DISPLAY environment variable)") add_environment_options(parser_run) parser_run.set_defaults(func=vagrant_run) # download parser_download = subparsers.add_parser('download') add_opt_general(parser_download) parser_download.add_argument('file', nargs=argparse.ZERO_OR_MORE, help="<output_file_name>[:<path>]") parser_download.add_argument('--all', action='store_true', help="Download all output files to the " "current directory") parser_download.set_defaults(func=vagrant_download) parser_suspend = subparsers.add_parser('suspend') add_opt_general(parser_suspend) parser_suspend.set_defaults(func=vagrant_suspend) # destroy/vm parser_destroy_vm = subparsers.add_parser('destroy/vm') add_opt_general(parser_destroy_vm) parser_destroy_vm.set_defaults(func=vagrant_destroy_vm) # destroy/dir parser_destroy_dir = subparsers.add_parser('destroy/dir') add_opt_general(parser_destroy_dir) parser_destroy_dir.set_defaults(func=vagrant_destroy_dir) # destroy parser_destroy = subparsers.add_parser('destroy') add_opt_general(parser_destroy) parser_destroy.set_defaults(func=composite_action(vagrant_destroy_vm, vagrant_destroy_dir)) return {'test_compatibility': test_has_vagrant}