def execute(self, exit=True): util.print_info( 'Idempotence test in progress (can take a few minutes)...') c = converge.Converge(self.command_args, self.args, self.molecule) status, output = c.execute(idempotent=True, exit=False, hide_errors=True) if status is not None: msg = 'Skipping due to errors during converge.' util.print_info(msg) return status, None idempotent, changed_tasks = self.molecule._parse_provisioning_output( output) if idempotent: util.print_success('Idempotence test passed.') return None, None # Display the details of the idempotence test. if changed_tasks: LOG.error( 'Idempotence test failed because of the following tasks:') LOG.error('{}'.format('\n'.join(changed_tasks))) else: # But in case the idempotence callback plugin was not found, we just display an error message. LOG.error('Idempotence test failed.') warning_msg = "The idempotence plugin was not found or did not provide the required information. " \ "Therefore the failure details cannot be displayed." LOG.warning(warning_msg) if exit: util.sysexit() return 1, None
def execute(self, exit=True): """ Execute the actions necessary to perform a `molecule init` and exit. :param exit: (Unused) Provided to complete method signature. :return: None """ role = self.command_args.get('role') role_path = os.getcwd() driver = self._get_driver() verifier = self._get_verifier() if not role: role = os.getcwd().split(os.sep)[-1] role_path = os.path.abspath(os.path.join(os.getcwd(), os.pardir)) self._init_existing_role(role, role_path, driver, verifier) else: if os.path.isdir(role): msg = 'The directory {} exists. Cannot create new role.' LOG.error(msg.format(role)) util.sysexit() self._init_new_role(role, role_path, driver, verifier) msg = 'Successfully initialized new role in {} ...' util.print_success(msg.format(os.path.join(role_path, role))) util.sysexit(0)
def execute(self, exit=True): """ Execute the actions necessary to perform a `molecule idempotence` and return a tuple. :param exit: An optional flag to toggle the exiting of the module on command failure. :return: Return a tuple of (`exit status`, `command output`), otherwise sys.exit on command failure. """ util.print_info( 'Idempotence test in progress (can take a few minutes) ...') c = converge.Converge(self.args, self.command_args, self.molecule) status, output = c.execute( idempotent=True, exit=False, hide_errors=True) if status is not None: msg = 'Skipping due to errors during converge.' util.print_info(msg) return status, None idempotent = self._is_idempotent(output) if idempotent: util.print_success('Idempotence test passed.') return None, None else: LOG.error( 'Idempotence test failed because of the following tasks:') LOG.error('\n'.join(self._non_idempotent_tasks(output))) if exit: util.sysexit() return 1, None
def destroy(self): LOG.info("Deleting openstack instances ...") active_instances = self._openstack.list_servers() active_instance_names = { instance['name']: instance['id'] for instance in active_instances } for instance in self.instances: LOG.warning("\tRemoving {} ...".format(instance['name'])) if instance['name'] in active_instance_names: if not self._openstack.delete_server( active_instance_names[instance['name']], wait=True): LOG.error("Unable to remove {}!".format(instance['name'])) else: util.print_success('\tRemoved {}'.format(instance['name'])) instance['created'] = False # cleanup any molecule generated files if self._molecule_generated_keypair() and self._keypair_name: self._openstack.delete_keypair(self._keypair_name) if self._molecule_generated_ssh_key: self._remove_temp_ssh_key()
def execute(self, exit=True): """ Execute the actions necessary to perform a `molecule idempotence` and return a tuple. :param exit: An optional flag to toggle the exiting of the module on command failure. :return: Return a tuple of (`exit status`, `command output`), otherwise sys.exit on command failure. """ util.print_info("Idempotence test in progress (can take a few minutes) ...") c = converge.Converge(self.command_args, self.args, self.molecule) status, output = c.execute(idempotent=True, exit=False, hide_errors=True) if status is not None: msg = "Skipping due to errors during converge." util.print_info(msg) return status, None idempotent = self._is_idempotent(output) if idempotent: util.print_success("Idempotence test passed.") return None, None else: LOG.error("Idempotence test failed because of the following tasks:") LOG.error("\n".join(self._non_idempotent_tasks(output))) if exit: util.sysexit() return 1, None
def test_print_success(capsys): util.print_success('test') result, _ = capsys.readouterr() print '{}{}'.format(colorama.Fore.GREEN, 'test'.rstrip()) expected, _ = capsys.readouterr() assert expected == result
def test_print_success(capsys): util.print_success("test") result, _ = capsys.readouterr() print "{}{}".format(colorama.Fore.GREEN, "test".rstrip()) expected, _ = capsys.readouterr() assert expected == result
def up(self, no_provision=True, image_tag='molecule_local/{}:{}'): self.molecule.state.change_state('driver', self.name) for container in self.instances: # check global docker driver or specific container config for # overrides for molecule image creation if (container.get('build_image') or (self.molecule.config.config['docker']['build_image'] and container.get('build_image', True))): container['image_tag'] = image_tag self._build_ansible_compatible_image(container) else: container['image_tag'] = '{}:{}' privileged = container.get('privileged', False) port_bindings = container.get('port_bindings', {}) volume_mounts = container.get('volume_mounts', []) links = container.get('links', {}) network_mode = container.get('network_mode', '') cap_add = container.get('cap_add', []) cap_drop = container.get('cap_drop', []) command = container.get('command', '') environment = container.get('environment') docker_host_config = self._docker.create_host_config( privileged=privileged, port_bindings=port_bindings, binds=volume_mounts, links=links, network_mode=network_mode, cap_add=cap_add, cap_drop=cap_drop) if (container['created'] is not True): msg = ('Creating container {} ' 'with base image {}:{}...').format( container['name'], container['image'], container['image_version']) util.print_warn(msg) container = self._docker.create_container( image=container['image_tag'].format( container['image'], container['image_version']), tty=True, detach=False, name=container['name'], ports=port_bindings.keys(), host_config=docker_host_config, environment=environment, command=command) self._docker.start(container=container.get('Id')) container['created'] = True util.print_success('Container created.') else: self._docker.start(container['name']) msg = 'Starting container {}...'.format(container['name']) util.print_info(msg)
def destroy(self): for container in self.instances: if (container['created']): msg = 'Stopping container {}...'.format(container['name']) util.print_warn(msg) self._docker.stop(container['name'], timeout=0) self._docker.remove_container(container['name']) msg = 'Removed container {}.'.format(container['name']) util.print_success(msg) container['created'] = False
def up(self, no_provision=True): self.molecule.state.change_state('driver', self.name) if self.molecule.config.config['docker']['build_image']: self._build_ansible_compatible_image() else: self.image_tag = '{}:{}' for container in self.instances: if 'privileged' not in container: container['privileged'] = False if 'port_bindings' not in container: container['port_bindings'] = {} if 'volume_mounts' not in container: container['volume_mounts'] = [] if 'cap_add' not in container: container['cap_add'] = [] if 'cap_drop' not in container: container['cap_drop'] = [] if 'command' not in container: container['command'] = "" docker_host_config = self._docker.create_host_config( privileged=container['privileged'], port_bindings=container['port_bindings'], binds=container['volume_mounts'], cap_add=container['cap_add'], cap_drop=container['cap_drop']) if (container['created'] is not True): LOG.warning( 'Creating container {} with base image {}:{} ...'.format( container['name'], container['image'], container['image_version']), ) container = self._docker.create_container( image=self.image_tag.format(container['image'], container['image_version']), tty=True, detach=False, name=container['name'], ports=container['port_bindings'].keys(), host_config=docker_host_config, command=container['command']) self._docker.start(container=container.get('Id')) container['created'] = True util.print_success('Container created.') else: self._docker.start(container['name']) util.print_success('Starting container {}...'.format(container[ 'name']))
def _cleanup_temp_keypair(self): # if we don't have a keypair config, delete the temp one if ('keypair' not in self.molecule.config.config['openstack']): kpn = self._get_temp_keyname() if self._openstack.search_keypairs(kpn): LOG.warning("\tRemoving openstack keypair {} ...".format(kpn)) if not self._openstack.delete_keypair(kpn): LOG.error("Unable to remove openstack keypair {}!".format( kpn)) else: util.print_success('\tRemoved openstack keypair {}'.format( kpn))
def _cleanup_temp_keypair(self): # if we don't have a keypair config, delete the temp one if ('keypair' not in self.molecule.config.config['openstack']): kpn = self._get_temp_keyname() if self._openstack.search_keypairs(kpn): msg = '\tRemoving openstack keypair {}...'.format(kpn) util.print_warn(msg) if not self._openstack.delete_keypair(kpn): msg = 'Unable to remove openstack keypair {}.'.format(kpn) util.print_error(msg) else: msg = '\tRemoved openstack keypair {}.'.format(kpn) util.print_success(msg)
def up(self, no_provision=True): self.molecule.state.change_state('driver', self.name) if self.molecule.config.config['docker']['build_image']: self._build_ansible_compatible_image() else: self.image_tag = '{}:{}' for container in self.instances: privileged = container.get('privileged', False) port_bindings = container.get('port_bindings', {}) volume_mounts = container.get('volume_mounts', []) links = container.get('links', {}) network_mode = container.get('network_mode', '') cap_add = container.get('cap_add', []) cap_drop = container.get('cap_drop', []) command = container.get('command', '') environment = container.get('environment') docker_host_config = self._docker.create_host_config( privileged=privileged, port_bindings=port_bindings, binds=volume_mounts, links=links, network_mode=network_mode, cap_add=cap_add, cap_drop=cap_drop) if (container['created'] is not True): msg = ('Creating container {} ' 'with base image {}:{}...').format( container['name'], container['image'], container['image_version']) util.print_warn(msg) container = self._docker.create_container( image=self.image_tag.format(container['image'], container['image_version']), tty=True, detach=False, name=container['name'], ports=port_bindings.keys(), host_config=docker_host_config, environment=environment, command=command) self._docker.start(container=container.get('Id')) container['created'] = True util.print_success('Container created.') else: self._docker.start(container['name']) msg = 'Starting container {}...'.format(container['name']) util.print_info(msg)
def up(self, no_provision=True): self.molecule.state.change_state('driver', self.name) if self.molecule.config.config['docker']['build_image']: self._build_ansible_compatible_image() else: self.image_tag = '{}:{}' for container in self.instances: privileged = container.get('privileged', False) port_bindings = container.get('port_bindings', {}) volume_mounts = container.get('volume_mounts', []) links = container.get('links', {}) cap_add = container.get('cap_add', []) cap_drop = container.get('cap_drop', []) command = container.get('command', '') environment = container.get('environment') docker_host_config = self._docker.create_host_config( privileged=privileged, port_bindings=port_bindings, binds=volume_mounts, links=links, cap_add=cap_add, cap_drop=cap_drop) if (container['created'] is not True): msg = ('Creating container {} ' 'with base image {}:{}...').format( container['name'], container['image'], container['image_version']) util.print_warn(msg) container = self._docker.create_container( image=self.image_tag.format(container['image'], container['image_version']), tty=True, detach=False, name=container['name'], ports=port_bindings.keys(), host_config=docker_host_config, environment=environment, command=command) self._docker.start(container=container.get('Id')) container['created'] = True util.print_success('Container created.') else: self._docker.start(container['name']) msg = 'Starting container {}...'.format(container['name']) util.print_info(msg)
def destroy(self): util.print_info('Deleting openstack instances...') active_instances = self._openstack.list_servers() active_instance_names = { instance['name']: instance['id'] for instance in active_instances } for instance in self.instances: util.print_warn('\tRemoving {}...'.format(instance['name'])) if instance['name'] in active_instance_names: if not self._openstack.delete_server( active_instance_names[instance['name']], wait=True): msg = 'Unable to remove {}.'.format(instance['name']) util.print_error(msg) else: util.print_success('\tRemoved {}.'.format(instance[ 'name'])) instance['created'] = False # cleanup any molecule generated ssh keysfiles self._cleanup_temp_keypair() self._cleanup_temp_keyfile()
def destroy(self): util.print_info('Deleting openstack instances...') active_instances = self._openstack.list_servers() active_instance_names = { instance['name']: instance['id'] for instance in active_instances } for instance in self.instances: util.print_warn('\tRemoving {}...'.format(instance['name'])) if instance['name'] in active_instance_names: if not self._openstack.delete_server( active_instance_names[instance['name']], wait=True): msg = 'Unable to remove {}.'.format(instance['name']) util.print_error(msg) else: util.print_success('\tRemoved {}.'.format( instance['name'])) instance['created'] = False # cleanup any molecule generated ssh keysfiles self._cleanup_temp_keypair() self._cleanup_temp_keyfile()
def destroy(self): for container in self.instances: if (container['created']): msg = 'Stopping container {}...'.format(container['name']) util.print_warn(msg) self._docker.stop(container['name'], timeout=0) self._docker.remove_container(container['name']) msg = 'Removed container {}.'.format(container['name']) util.print_success(msg) container['created'] = False if self._network is not None: for network in self._network: try: d_net = self._docker.networks(names=[network['name']])[0] msg = 'Removing network {}'.format(network['name']) util.print_warn(msg) self._docker.remove_network(d_net['Id']) except IndexError: msg = ('Could not find network {}. ' 'Skipping remove').format(network['name']) util.print_warn(msg) util.print_success('Network(s) removed')
def up(self, no_provision=True, image_tag='molecule_local/{}:{}'): self.molecule.state.change_state('driver', self.name) if self._network is not None: for network in self._network: driver = network.get('driver', 'bridge') msg = ('Creating network {} ' 'with driver {}').format(network['name'], driver) util.print_warn(msg) self._docker.create_network(network['name'], driver=driver) util.print_success('Network(s) created') for container in self.instances: # check global docker driver or specific container config for # overrides for molecule image creation if (container.get('build_image') or (self.molecule.config.config['docker']['build_image'] and container.get('build_image', True))): container['image_tag'] = image_tag self._build_ansible_compatible_image(container) else: container['image_tag'] = '{}:{}' privileged = container.get('privileged', False) port_bindings = container.get('port_bindings', {}) volume_mounts = container.get('volume_mounts', []) links = container.get('links', {}) network_mode = container.get('network_mode', '') cap_add = container.get('cap_add', []) cap_drop = container.get('cap_drop', []) command = container.get('command', '') environment = container.get('environment') hostname = container.get('hostname') docker_host_config = self._docker.create_host_config( privileged=privileged, port_bindings=port_bindings, binds=volume_mounts, links=links, network_mode=network_mode, cap_add=cap_add, cap_drop=cap_drop) if (container['created'] is not True): msg = ('Creating container {} ' 'with base image {}:{}...').format( container['name'], container['image'], container['image_version']) util.print_warn(msg) container = self._docker.create_container( image=container['image_tag'].format( container['image'], container['image_version']), tty=True, detach=False, name=container['name'], ports=port_bindings.keys(), host_config=docker_host_config, environment=environment, command=command, hostname=hostname) self._docker.start(container=container.get('Id')) container['created'] = True util.print_success('Container created.') else: self._docker.start(container['name']) msg = 'Starting container {}...'.format(container['name']) util.print_info(msg)
def _build_ansible_compatible_image(self): available_images = [ tag.encode('utf-8') for image in self._docker.images() for tag in image.get('RepoTags') ] for container in self.instances: if 'install_python' in container and container[ 'install_python'] is False: continue else: util.print_info( "Creating Ansible compatible image of {}:{} ...".format( container['image'], container['image_version'])) if 'registry' in container: container['registry'] += '/' else: container['registry'] = '' dockerfile = ''' FROM {}:{} RUN bash -c 'if [ -x "$(command -v apt-get)" ]; then apt-get update && apt-get install -y python sudo; fi' RUN bash -c 'if [ -x "$(command -v yum)" ]; then yum makecache fast && yum update -y && yum install -y python sudo; fi' ''' # noqa dockerfile = dockerfile.format( container['registry'] + container['image'], container['image_version']) f = io.BytesIO(dockerfile.encode('utf-8')) container['image'] = container['registry'].replace( '/', '_').replace(':', '_') + container['image'] tag_string = self.image_tag.format(container['image'], container['image_version']) errors = False if tag_string not in available_images: util.print_info('Building ansible compatible image ...') previous_line = '' for line in self._docker.build(fileobj=f, tag=tag_string): for line_split in line.split('\n'): if len(line_split) > 0: line = json.loads(line_split) if 'stream' in line: LOG.warning('\t{}'.format(line['stream'])) if 'errorDetail' in line: LOG.warning('\t{}'.format( line['errorDetail']['message'])) errors = True if 'status' in line: if previous_line not in line['status']: LOG.warning('\t{} ...'.format( line['status'])) previous_line = line['status'] if errors: LOG.error('Build failed for {}'.format(tag_string)) return else: util.print_success( 'Finished building {}'.format(tag_string))
def _build_ansible_compatible_image(self): available_images = [tag.encode('utf-8') for image in self._docker.images() for tag in image.get('RepoTags')] for container in self.instances: if 'build_image' in container and container[ 'build_image'] is False: continue else: util.print_info( "Creating Ansible compatible image of {}:{} ...".format( container['image'], container['image_version'])) if 'registry' in container: container['registry'] += '/' else: container['registry'] = '' dockerfile = ''' FROM {}:{} RUN bash -c 'if [ -x "$(command -v apt-get)" ]; then apt-get update && apt-get install -y python sudo; fi' RUN bash -c 'if [ -x "$(command -v yum)" ]; then yum makecache fast && yum update -y && yum install -y python sudo; fi' RUN bash -c 'if [ -x "$(command -v zypper)" ]; then zypper refresh && zypper update -y && zypper install -y python sudo; fi' ''' # noqa if 'dockerfile' in container: dockerfile = container['dockerfile'] f = io.open(dockerfile) else: dockerfile = dockerfile.format( container['registry'] + container['image'], container['image_version']) f = io.BytesIO(dockerfile.encode('utf-8')) container['image'] = container['registry'].replace( '/', '_').replace(':', '_') + container['image'] tag_string = self.image_tag.format(container['image'], container['image_version']) errors = False if tag_string not in available_images or 'dockerfile' in container: util.print_info('Building ansible compatible image ...') previous_line = '' for line in self._docker.build(fileobj=f, tag=tag_string): for line_split in line.split('\n'): if len(line_split) > 0: line = json.loads(line_split) if 'stream' in line: LOG.warning('\t{}'.format(line['stream'])) if 'errorDetail' in line: LOG.warning('\t{}'.format(line['errorDetail'][ 'message'])) errors = True if 'status' in line: if previous_line not in line['status']: LOG.warning('\t{} ...'.format(line[ 'status'])) previous_line = line['status'] if errors: LOG.error('Build failed for {}'.format(tag_string)) return else: util.print_success('Finished building {}'.format( tag_string))
def _build_ansible_compatible_image(self, container): available_images = [ tag.encode('utf-8') for image in self._docker.images() if image.get('RepoTags') is not None for tag in image.get('RepoTags') ] msg = ('Creating Ansible compatible ' 'image of {}:{} ...').format(container['image'], container['image_version']) util.print_info(msg) if 'registry' in container: container['registry'] += '/' else: container['registry'] = '' dockerfile = ''' FROM {container_image}:{container_version} {container_environment} RUN /bin/sh -c 'if [ -x "$(command -v apt-get)" ]; then apt-get update && apt-get install -y python sudo bash; fi' RUN /bin/sh -c 'if [ -x "$(command -v yum)" ]; then touch /var/lib/rpm/* && yum makecache fast && yum update -y && yum install -y python sudo yum-plugin-ovl bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf; fi' RUN /bin/sh -c 'if [ -x "$(command -v zypper)" ]; then zypper refresh && zypper update -y && zypper install -y python sudo bash; fi' RUN /bin/sh -c 'if [ -x "$(command -v apk)" ]; then apk update && apk add python sudo bash; fi' RUN /bin/sh -c 'if [ -x "$(command -v pacman)" ]; then pacman --sync --noconfirm --refresh python2 bash; fi' RUN /bin/sh -c 'if [ -x "$(command -v dnf)" ]; then dnf makecache fast; dnf --assumeyes install python python-devel python2-dnf bash; fi' RUN /bin/sh -c 'if [ -x "$(command -v emerge)" ]; then emerge --ask n =dev-lang/python-2\* gentoolkit; fi' ''' # noqa if 'dockerfile' in container: dockerfile = container['dockerfile'] f = io.open(dockerfile) else: environment = container.get('environment') if environment: environment = '\n'.join('ENV {} {}'.format(k, v) for k, v in environment.iteritems()) else: environment = '' dockerfile = dockerfile.format( container_image=container['registry'] + container['image'], container_version=container['image_version'], container_environment=environment) f = io.BytesIO(dockerfile.encode('utf-8')) container['image'] = container['registry'].replace( '/', '_').replace(':', '_') + container['image'] tag_string = container['image_tag'].format(container['image'], container['image_version']) errors = False if tag_string not in available_images or 'dockerfile' in container: util.print_info('Building ansible compatible image...') previous_line = '' for line in self._docker.build(fileobj=f, tag=tag_string): for line_split in line.split('\n'): if len(line_split) > 0: line = json.loads(line_split) if 'stream' in line: msg = '\t{}'.format(line['stream']) util.print_warn(msg) if 'errorDetail' in line: ed = line['errorDetail']['message'] msg = '\t{}'.format(ed) util.print_warn(msg) errors = True if 'status' in line: if previous_line not in line['status']: msg = '\t{} ...'.format(line['status']) util.print_warn(msg) previous_line = line['status'] if errors: msg = 'Build failed for {}.'.format(tag_string) util.print_error(msg) return else: util.print_success('Finished building {}.'.format(tag_string))
def _build_ansible_compatible_image(self): available_images = [ tag.encode('utf-8') for image in self._docker.images() for tag in image.get('RepoTags', []) ] for container in self.instances: if container.get('build_image'): msg = ('Creating Ansible compatible ' 'image of {}:{} ...').format(container['image'], container['image_version']) util.print_info(msg) if 'registry' in container: container['registry'] += '/' else: container['registry'] = '' dockerfile = ''' FROM {container_image}:{container_version} {container_environment} RUN bash -c 'if [ -x "$(command -v apt-get)" ]; then apt-get update && apt-get install -y python sudo; fi' RUN bash -c 'if [ -x "$(command -v yum)" ]; then yum makecache fast && yum update -y && yum install -y python sudo yum-plugin-ovl && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf; fi' RUN bash -c 'if [ -x "$(command -v zypper)" ]; then zypper refresh && zypper update -y && zypper install -y python sudo; fi' ''' # noqa if 'dockerfile' in container: dockerfile = container['dockerfile'] f = io.open(dockerfile) else: environment = container.get('environment') if environment: environment = '\n'.join( 'ENV {} {}'.format(k, v) for k, v in environment.iteritems()) else: environment = '' dockerfile = dockerfile.format( container_image=container['registry'] + container['image'], container_version=container['image_version'], container_environment=environment) f = io.BytesIO(dockerfile.encode('utf-8')) container['image'] = container['registry'].replace( '/', '_').replace(':', '_') + container['image'] tag_string = self.image_tag.format(container['image'], container['image_version']) errors = False if tag_string not in available_images or 'dockerfile' in container: util.print_info('Building ansible compatible image...') previous_line = '' for line in self._docker.build(fileobj=f, tag=tag_string): for line_split in line.split('\n'): if len(line_split) > 0: line = json.loads(line_split) if 'stream' in line: msg = '\t{}'.format(line['stream']) util.print_warn(msg) if 'errorDetail' in line: ed = line['errorDetail']['message'] msg = '\t{}'.format(ed) util.print_warn(msg) errors = True if 'status' in line: if previous_line not in line['status']: msg = '\t{} ...'.format(line['status']) util.print_warn(msg) previous_line = line['status'] if errors: msg = 'Build failed for {}.'.format(tag_string) util.print_error(msg) return else: util.print_success('Finished building {}.'.format( tag_string))
def execute(self): role = self.molecule._args['<role>'] if not role: role = os.getcwd().split(os.sep)[-1] role_path = os.getcwd() util.print_info("Initializing molecule in current directory...") else: if os.path.isdir(role): msg = 'The directory {} already exists. Cannot create new role.' LOG.error(msg.format(role)) util.sysexit() role_path = os.path.join(os.curdir, role) util.print_info("Initializing role {}...".format(role)) try: if self.molecule._args['--offline']: sh.ansible_galaxy('init', '--offline', role) else: sh.ansible_galaxy('init', role) except (subprocess.CalledProcessError, sh.ErrorReturnCode_1) as e: LOG.error('ERROR: {}'.format(e)) util.sysexit(e.returncode) self.clean_meta_main(role_path) env = jinja2.Environment(loader=jinja2.PackageLoader( 'molecule', 'template'), keep_trailing_newline=True) t_molecule = env.get_template(self.molecule.config.config['molecule'] ['init']['templates']['molecule']) t_playbook = env.get_template(self.molecule.config.config['molecule'] ['init']['templates']['playbook']) t_test_default = env.get_template( self.molecule.config.config['molecule']['init']['templates'] ['test_default']) if (self.molecule._args['--docker']): t_molecule = env.get_template( self.molecule.config.config['molecule']['init']['templates'] ['molecule_docker']) if (self.molecule._args['--openstack']): t_molecule = env.get_template( self.molecule.config.config['molecule']['init']['templates'] ['molecule_openstack']) sanitized_role = re.sub('[._]', '-', role) with open(os.path.join(role_path, self.molecule.config.molecule_file), 'w') as f: f.write( t_molecule.render(config=self.molecule.config.config, role=sanitized_role)) with open( os.path.join( role_path, self.molecule.config.config['ansible']['playbook']), 'w') as f: f.write(t_playbook.render(role=role)) testinfra_path = os.path.join( role_path, self.molecule.config.config['molecule']['testinfra_dir']) if not os.path.isdir(testinfra_path): os.mkdir(testinfra_path) with open(os.path.join(testinfra_path, 'test_default.py'), 'w') as f: f.write(t_test_default.render()) msg = 'Successfully initialized new role in {}' util.print_success(msg.format(role_path)) util.sysexit(0)
def _build_ansible_compatible_image(self): available_images = [ tag.encode('utf-8') for image in self._docker.images() for tag in image.get('RepoTags', []) ] for container in self.instances: if container.get('build_image'): msg = ('Creating Ansible compatible ' 'image of {}:{} ...').format(container['image'], container['image_version']) util.print_info(msg) if 'registry' in container: container['registry'] += '/' else: container['registry'] = '' dockerfile = ''' FROM {container_image}:{container_version} {container_environment} RUN bash -c 'if [ -x "$(command -v apt-get)" ]; then apt-get update && apt-get install -y python sudo; fi' RUN bash -c 'if [ -x "$(command -v yum)" ]; then yum makecache fast && yum update -y && yum install -y python sudo which yum-plugin-ovl && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf; fi' RUN bash -c 'if [ -x "$(command -v zypper)" ]; then zypper refresh && zypper update -y && zypper install -y python sudo; fi' ''' # noqa if 'dockerfile' in container: dockerfile = container['dockerfile'] f = io.open(dockerfile) else: environment = container.get('environment') if environment: environment = '\n'.join( 'ENV {} {}'.format(k, v) for k, v in environment.iteritems()) else: environment = '' dockerfile = dockerfile.format( container_image=container['registry'] + container['image'], container_version=container['image_version'], container_environment=environment) f = io.BytesIO(dockerfile.encode('utf-8')) container['image'] = container['registry'].replace( '/', '_').replace(':', '_') + container['image'] tag_string = self.image_tag.format(container['image'], container['image_version']) errors = False if tag_string not in available_images or 'dockerfile' in container: util.print_info('Building ansible compatible image...') previous_line = '' for line in self._docker.build(fileobj=f, tag=tag_string): for line_split in line.split('\n'): if len(line_split) > 0: line = json.loads(line_split) if 'stream' in line: msg = '\t{}'.format(line['stream']) util.print_warn(msg) if 'errorDetail' in line: ed = line['errorDetail']['message'] msg = '\t{}'.format(ed) util.print_warn(msg) errors = True if 'status' in line: if previous_line not in line['status']: msg = '\t{} ...'.format(line['status']) util.print_warn(msg) previous_line = line['status'] if errors: msg = 'Build failed for {}.'.format(tag_string) util.print_error(msg) return else: util.print_success( 'Finished building {}.'.format(tag_string))
def execute(self): role = self.molecule._args['<role>'] if not role: role = os.getcwd().split(os.sep)[-1] role_path = os.getcwd() util.print_info("Initializing molecule in current directory...") else: if os.path.isdir(role): msg = 'The directory {} already exists. Cannot create new role.' LOG.error(msg.format(role)) util.sysexit() role_path = os.path.join(os.curdir, role) util.print_info("Initializing role {}...".format(role)) try: if self.molecule._args['--offline']: sh.ansible_galaxy('init', '--offline', role) else: sh.ansible_galaxy('init', role) except (subprocess.CalledProcessError, sh.ErrorReturnCode_1) as e: LOG.error('ERROR: {}'.format(e)) util.sysexit(e.returncode) self.clean_meta_main(role_path) env = jinja2.Environment( loader=jinja2.PackageLoader('molecule', 'template'), keep_trailing_newline=True) t_molecule = env.get_template(self.molecule.config.config['molecule'][ 'init']['templates']['molecule']) t_playbook = env.get_template(self.molecule.config.config['molecule'][ 'init']['templates']['playbook']) t_test_default = env.get_template(self.molecule.config.config[ 'molecule']['init']['templates']['test_default']) if (self.molecule._args['--docker']): t_molecule = env.get_template(self.molecule.config.config[ 'molecule']['init']['templates']['molecule_docker']) if (self.molecule._args['--openstack']): t_molecule = env.get_template(self.molecule.config.config[ 'molecule']['init']['templates']['molecule_openstack']) sanitized_role = re.sub('[._]', '-', role) with open( os.path.join(role_path, self.molecule.config.molecule_file), 'w') as f: f.write(t_molecule.render(config=self.molecule.config.config, role=sanitized_role)) with open( os.path.join( role_path, self.molecule.config.config['ansible']['playbook']), 'w') as f: f.write(t_playbook.render(role=role)) testinfra_path = os.path.join( role_path, self.molecule.config.config['molecule']['testinfra_dir']) if not os.path.isdir(testinfra_path): os.mkdir(testinfra_path) with open(os.path.join(testinfra_path, 'test_default.py'), 'w') as f: f.write(t_test_default.render()) msg = 'Successfully initialized new role in {}' util.print_success(msg.format(role_path)) util.sysexit(0)