def install_auth(ctx=None, output_path=None, **kwargs): """Install auth directory. Agrs: ctx (object): Click Context object. output_path (path): Path to place auth dir. """ if not ctx: # Using API. Else handled by cli. _set_init_vars(kwargs.get("cwd"), kwargs.get("tmpdir")) if not output_path: output_path = get_env_var("cwd") license_dir = os.path.join(output_path, "auth/licenses") try: os.makedirs(license_dir) except FileExistsError: pass # Dir already created. Moving on. utils.echo( "Any (license) files you put in %s will be synced into your VM." % license_dir) for filename in os.listdir( os.path.join(get_env_var("env"), "auth/env_scripts")): dst_dir = os.path.join(output_path, "auth/keys") dst = os.path.join(dst_dir, os.path.splitext(filename)[0]) if not os.path.isfile(dst): os.makedirs(dst_dir, exist_ok=True) # Make parent dirs if needed. # Py 3.2+ shutil.copy( os.path.join(get_env_var("env"), "auth/env_scripts", filename), dst) utils.echo("Added template key loading scripts %s to auth/keys." % filename) else: utils.echo("File %s exists. Leaving it." % dst)
def vagrant_destroy(ctx=None, vagrant_cwd=None, vagrant_dotfile_path=None): '''Destroy a VM / container and all its metadata. Default leaves logs. All str args can also be set as an environment variable; arg takes precedence. Agrs: ctx (object): Click Context object. vagrant_cwd (str): Location of `Vagrantfile`. vagrant_dotfile_path (str): Location of `.vagrant` metadata directory. ''' # TODO add finding and deleting of all VMs registered to this installation. # TODO (optional) add finding and deleting of all VMs across all installations. # TODO add an --all flag to delete the whole .rambo-tmp dir. Default leaves logs. if not ctx: # Else handled by cli. set_init_vars() set_vagrant_vars(vagrant_cwd, vagrant_dotfile_path) dir_create(get_env_var('TMP') + '/logs') # TODO: Better logs. bash('vagrant destroy --force >' + get_env_var('TMP') + '/logs/vagrant-destroy-log 2>&1') follow_log_file( get_env_var('TMP') + '/logs/vagrant-destroy-log', ['Vagrant done with destroy.', 'Print this help']) file_delete(get_env_var('TMP') + '/provider') file_delete(get_env_var('TMP') + '/random_tag') dir_delete(os.environ.get('VAGRANT_DOTFILE_PATH')) click.echo('Temporary files removed') click.echo('Destroy complete.')
def vagrant_up_thread(): '''Make the final call over the shell to `vagrant up`, and redirect all output to log file. ''' dir_create(get_env_var('TMP') + '/logs') # TODO: Better logs. bash('vagrant up >' + get_env_var('TMP') + '/logs/vagrant-up-log 2>&1')
def docker(): """Docker specific preparation for Vagrant. Setting and validating env vars. Set env vars: docker_box """ if get_env_var("guest_os"): # only set during `up` set_env_var( "docker_box", SETTINGS["GUEST_OSES"][get_env_var("guest_os")]["docker"] )
def install_gitignore(ctx=None, output_path=None, **kwargs): """Install config file. Agrs: ctx (object): Click Context object. output_path (path): Path to place conf file. """ if not ctx: # Using API. Else handled by cli. _set_init_vars(kwargs.get("cwd"), kwargs.get("tmpdir")) if not output_path: output_path = get_env_var("cwd") path = os.path.join(output_path, ".gitignore") if os.path.exists(path): pass else: with open(path, "w") as f: f.write("""\ .rambo-tmp/ .vagrant/ my_rambo.conf auth/ """) utils.echo("Created .gitignore")
def install_config(ctx=None, output_path=None, **kwargs): """Install config file. Agrs: ctx (object): Click Context object. output_path (path): Path to place conf file. """ if not ctx: # Using API. Else handled by cli. _set_init_vars(kwargs.get("cwd"), kwargs.get("tmpdir")) if not output_path: output_path = get_env_var("cwd") path = os.path.join(output_path, "%s.conf" % PROJECT_NAME) if os.path.exists(path): utils.abort("%s.conf already esists." % PROJECT_NAME) else: with open(path, "w") as f: f.write("""\ [up] provider = virtualbox box = ubuntu/bionic64 sync_dirs = [["saltstack/etc", "/etc/salt"], ["saltstack/srv", "/srv"]] """) utils.echo("Created config at %s" % path)
def ec2(**params): """EC2 specific preparation for Vagrant. Setting and validating env vars. Set env vars: ami Sanitize against non-whitelist ramsize. """ if get_env_var("guest_os"): # only set during `up` set_env_var("ami", SETTINGS["GUEST_OSES"][get_env_var("guest_os")]["ec2"]) if get_env_var("ramsize") not in SETTINGS["SIZES"]: abort( "Sorry, we really need a RAM size from our whitelist for " "digitalocean. \nThe only way around that is if you specify " "a machine-type like m3.medium." ) if params.get("ec2_security_groups"): set_env_var("ec2_security_groups", params["ec2_security_groups"])
def _set_tmpdir(tmpdir=None): """Set tmpdir and log_path locations. This should defaut to be inside the cwd. Args: tmpdir (path): Location of project's tmp dir. """ # loc of tmpdir if tmpdir: # cli / api set_env_var("TMPDIR", os.path.join(tmpdir, ".%s-tmp" % PROJECT_NAME)) elif get_env_var("TMPDIR"): # Previously set env var set_env_var( "TMPDIR", os.path.join(get_env_var("TMPDIR"), ".%s-tmp" % PROJECT_NAME)) else: # Not set, set to default loc set_env_var("TMPDIR", os.path.join(os.getcwd(), ".%s-tmp" % PROJECT_NAME)) # default (cwd) set_env_var("LOG_PATH", os.path.join(get_env_var("TMPDIR"), "logs"))
def _set_cwd(cwd=None): """Set cwd environment variable and change the actual cwd to it. Args: cwd (path): Location of project (conf file, provisioning scripts, etc.) """ # effective CWD (likely real CWD, but may be changed by user. if cwd: # cli / api set_env_var("cwd", cwd) elif get_env_var("cwd"): pass # Already set - keep it. else: found_project = utils.find_conf(os.getcwd()) if found_project: set_env_var("cwd", found_project) else: set_env_var("cwd", os.getcwd()) os.chdir(get_env_var("cwd")) return get_env_var("cwd")
def digitalocean(): """DigitalOcean specific preparation for Vagrant. Setting and validating env vars. Set env vars: do_image Sanitize against non-whitelist ramsize and drivesize. """ if get_env_var("guest_os"): # only set during `up` set_env_var("do_image", SETTINGS["GUEST_OSES"][get_env_var("guest_os")]["do"]) if get_env_var("ramsize") not in SETTINGS["SIZES"]: abort( "Sorry, we really need a RAM size from our whitelist for " "digitalocean. \nThe only way around that is if you specify " "a machine-type like s-8vcpu-32gb." ) if get_env_var("drivesize") not in SETTINGS["SIZES"].values(): abort( "Sorry, we really need a drive size from our whitelist for " "digitalocean. \nThe only way around that is if you specify " "a machine-type like s-8vcpu-32gb." )
def destroy(ctx=None, **params): """Destroy a VM / container and all its metadata. Default leaves logs. All str args can also be set as an environment variable; arg takes precedence. Agrs: ctx (object): Click Context object. vagrant_cwd (path): Location of `Vagrantfile`. Used if invoked with API only. vagrant_dotfile_path (path): Location of `.vagrant` metadata directory. Used if invoked with API only. """ # TODO add finding and deleting of all VMs registered to this installation. # TODO (optional) add finding and deleting of all VMs across all installations. # TODO add an --all flag to delete the whole .rambo-tmp dir. Default leaves logs. if not ctx: # Using API. Else handled by cli. _set_init_vars(params.get("cwd"), params.get("tmpdir")) _set_vagrant_vars(params.get("vagrant_cwd"), params.get("vagrant_dotfile_path")) destroy_cmd = vagrant_general_command("destroy --force") # If there's any error code from Vagrant, don't delete the metadata. if not destroy_cmd: # I.e. we succeeded - ret code == 0 utils.file_delete(os.path.join(get_env_var("TMPDIR"), "provider")) utils.file_delete(os.path.join(get_env_var("TMPDIR"), "random_tag")) utils.dir_delete(os.environ.get("VAGRANT_DOTFILE_PATH")) utils.echo("Temporary files removed") if params.get("vm_name"): # Additionally remove the box if we can. utils.echo( f"Now removing base VirtualBox data for VM {params['vm_name']}." ) os.system(f"vboxmanage controlvm {params['vm_name']} poweroff") os.system(f"vboxmanage unregistervm {params['vm_name']} --delete") utils.echo("Destroy complete.") else: utils.echo("We received an error. Destroy may not be complete.")
def vagrant_up(ctx=None, provider=None, vagrant_cwd=None, vagrant_dotfile_path=None): '''Start a VM / container with `vagrant up`. All str args can also be set as an environment variable; arg takes precedence. Agrs: ctx (object): Click Context object. Used to detect if CLI is used. provider (str): Sets provider used. vagrant_cwd (str): Location of `Vagrantfile`. vagrant_dotfile_path (str): Location of `.vagrant` metadata directory. ''' # TODO: Add registering of VM for all of this installation to see if not ctx: # Else handled by cli. set_init_vars() set_vagrant_vars(vagrant_cwd, vagrant_dotfile_path) # TODO See if there's a better exit / error system if provider: set_env_var('provider', provider) if provider not in PROVIDERS: sys.exit('ABORTED - Target provider "%s" is not in the providers ' 'list. Did you have a typo?' % provider) elif get_env_var('PROVIDER') and get_env_var('PROVIDER') not in PROVIDERS: sys.exit('ABORTED - Target provider "%s" is set as an environment ' ' variable, and is not in the providers list. Did you ' 'have a typo?' % provider) if not dir_exists(get_env_var('TMP')): dir_create(get_env_var('TMP')) dir_create(get_env_var('TMP') + '/logs') # TODO: Better logs. open(get_env_var('TMP') + '/logs/vagrant-up-log','w').close() # Create log file. Vagrant will write to it, we'll read it. thread = Thread(target = vagrant_up_thread) # Threaded to write, read, and echo as `up` progresses. thread.start() follow_log_file(get_env_var('TMP') + '/logs/vagrant-up-log', ['Total run time:', 'Provisioners marked to run always will still run', 'Print this help', 'try again.']) click.echo('Up complete.')
def up(ctx=None, **params): """Start a VM / container with `vagrant up`. All str args can also be set as an environment variable; arg takes precedence. Agrs: ctx (object): Click Context object. Used to detect if CLI is used. params (dict): Dict of all args passed to `up`. In params, this looks for: provider (str): Provider to use. box (str): Vagrant box to use. cpus (int): Number of CPUs to give VirtualBox VM. guest_os (str): Guest OS to use. ram_size (int): RAM in MB to use. drive_size (int): Drive size in GB to use. machine_type (str): Machine type to use for cloud providers. sync_dirs (path): Paths to sync into VM. sync_type (str): Type of syncing to use. ports (str): Ports to forward. provision (bool): vagrant provisioning flag. command (str): Command used at beginning of provisioning. destroy_on_error (bool): vagrant destroy-on-error flag. vagrant_cwd (path): Location of `Vagrantfile`. Used if invoked with API only. vagrant_dotfile_path (path): Location of `.vagrant` metadata directory. Used if invoked with API only. vm_name (str): Name of the VM or container. """ # TODO: Add registering of VM for all of this installation to see if not ctx: # Using API. Else handled by cli. _set_init_vars(params.get("cwd"), params.get("tmpdir")) _set_vagrant_vars(params.get("vagrant_cwd"), params.get("vagrant_dotfile_path")) # Option Handling - These might modify the params dict and/or set env vars. params["guest_os"] = options.guest_os_option(params.get("guest_os")) params["box"] = options.box_option(params.get("box")) params["cpus"] = options.cpus_option(params.get("cpus")) params["hostname"] = options.hostname_option(params.get("hostname")) params["machine_type"] = options.machine_type_option( params.get("machine_type"), params.get("provider")) params["project_dir"] = options.project_dir_option( params.get("project_dir")) params["provider"] = options.provider_option(params.get("provider")) params["command"] = options.command_option(params.get("command")) params["ram_size"], params["drive_size"] = options.size_option( params.get("ram_size"), params.get("drive_size")) # both ram and drive size params["sync_dirs"] = options.sync_dirs_option(params.get("sync_dirs")) params["sync_type"] = options.sync_type_option(params.get("sync_type")) params["ports"] = options.ports_option(params.get("ports")) params["vm_name"] = options.vm_name_option(params.get("vm_name")) cmd = "up" # Provider specific handling. # Must come after all else, because logic may be done on params above. if params["provider"] == "digitalocean": vagrant_providers.digitalocean() elif params["provider"] == "docker": vagrant_providers.docker() elif params["provider"] == "ec2": vagrant_providers.ec2(**params) else: cmd += " --provider={}".format(params["provider"]) # Add straight pass-through flags. Keep test for True/False explicit as only those values should work if params.get("provision") is True: cmd = "{} {}".format(cmd, "--provision") elif params.get("provision") is False: cmd = "{} {}".format(cmd, "--no-provision") if params.get("destroy_on_error") is True: cmd = "{} {}".format(cmd, "--destroy-on-error") elif params.get("destroy_on_error") is False: cmd = "{} {}".format(cmd, "--no-destroy-on-error") exit_code = vagrant_general_command(cmd) if exit_code: with open(Path(get_env_var("LOG_PATH")) / "stderr.log") as fp: stderr = fp.readlines() for idx, line in enumerate(reversed(stderr)): if "Unknown configuration section 'disksize'" in line: abort("You probably don't have plugins installed.\nRun:\n" "\trambo install-plugins") elif idx > 5: # Only look through the recent stderr. break