def _setup_dynamic(self): """Create a vcenter simulator using docker.""" container_id = get_docker_container_id() if container_id: display.info('Running in docker container: %s' % container_id, verbosity=1) self.container_name = self.DOCKER_SIMULATOR_NAME results = docker_inspect(self.args, self.container_name) if results and not results[0].get('State', {}).get('Running'): docker_rm(self.args, self.container_name) results = [] if results: display.info( 'Using the existing vCenter simulator docker container.', verbosity=1) else: display.info('Starting a new vCenter simulator docker container.', verbosity=1) if not self.args.docker and not container_id: # publish the simulator ports when not running inside docker publish_ports = [ '-p', '80:80', '-p', '443:443', '-p', '8080:8080', '-p', '8989:8989', '-p', '5000:5000', # control port for flask app in simulator ] else: publish_ports = [] docker_pull(self.args, self.image) docker_run( self.args, self.image, ['-d', '--name', self.container_name] + publish_ports, ) if self.args.docker: vcenter_host = self.DOCKER_SIMULATOR_NAME elif container_id: vcenter_host = self._get_simulator_address() display.info('Found vCenter simulator container address: %s' % vcenter_host, verbosity=1) else: vcenter_host = 'localhost' self._set_cloud_config('vcenter_host', vcenter_host)
def _setup_dynamic(self): """Create a CloudStack simulator using docker.""" config = self._read_config_template() self.container_name = self.DOCKER_SIMULATOR_NAME results = docker_inspect(self.args, self.container_name) if results and not results[0]['State']['Running']: docker_rm(self.args, self.container_name) results = [] if results: display.info('Using the existing CloudStack simulator docker container.', verbosity=1) else: display.info('Starting a new CloudStack simulator docker container.', verbosity=1) docker_pull(self.args, self.image) docker_run(self.args, self.image, ['-d', '-p', '8888:8888', '--name', self.container_name]) if not self.args.explain: display.notice('The CloudStack simulator will probably be ready in 5 - 10 minutes.') container_id = get_docker_container_id() if container_id: display.info('Running in docker container: %s' % container_id, verbosity=1) self.host = self._get_simulator_address() display.info('Found CloudStack simulator container address: %s' % self.host, verbosity=1) else: self.host = 'localhost' self.port = 8888 self.endpoint = 'http://%s:%d' % (self.host, self.port) self._wait_for_service() if self.args.explain: values = dict( HOST=self.host, PORT=str(self.port), ) else: credentials = self._get_credentials() if self.args.docker: host = self.DOCKER_SIMULATOR_NAME else: host = self.host values = dict( HOST=host, PORT=str(self.port), KEY=credentials['apikey'], SECRET=credentials['secretkey'], ) config = self._populate_config_template(config, values) self._write_config(config)
def _setup_dynamic(self): """Create a ACME test container using docker.""" container_id = get_docker_container_id() if container_id: display.info('Running in docker container: %s' % container_id, verbosity=1) self.container_name = self.DOCKER_SIMULATOR_NAME results = docker_inspect(self.args, self.container_name) if results and not results[0].get('State', {}).get('Running'): docker_rm(self.args, self.container_name) results = [] if results: display.info('Using the existing ACME docker test container.', verbosity=1) else: display.info('Starting a new ACME docker test container.', verbosity=1) if not self.args.docker and not container_id: # publish the simulator ports when not running inside docker publish_ports = [ '-p', '5000:5000', # control port for flask app in container '-p', '14000:14000', # Pebble ACME CA ] else: publish_ports = [] if not os.environ.get('ANSIBLE_ACME_CONTAINER'): docker_pull(self.args, self.image) docker_run( self.args, self.image, ['-d', '--name', self.container_name] + publish_ports, ) if self.args.docker: acme_host = self.DOCKER_SIMULATOR_NAME acme_host_ip = self._get_simulator_address() elif container_id: acme_host = self._get_simulator_address() acme_host_ip = acme_host display.info('Found ACME test container address: %s' % acme_host, verbosity=1) else: acme_host = 'localhost' acme_host_ip = acme_host self._set_cloud_config('acme_host', acme_host) self._wait_for_service('http', acme_host_ip, 5000, '', 'ACME controller') self._wait_for_service('https', acme_host_ip, 14000, 'dir', 'ACME CA endpoint')
def _setup_dynamic(self): """Create a vcenter simulator using docker.""" container_id = get_docker_container_id() if container_id: display.info('Running in docker container: %s' % container_id, verbosity=1) self.container_name = self.DOCKER_SIMULATOR_NAME results = docker_inspect(self.args, self.container_name) if results and not results[0].get('State', {}).get('Running'): docker_rm(self.args, self.container_name) results = [] if results: display.info('Using the existing vCenter simulator docker container.', verbosity=1) else: display.info('Starting a new vCenter simulator docker container.', verbosity=1) if not self.args.docker and not container_id: # publish the simulator ports when not running inside docker publish_ports = [ '-p', '80:80', '-p', '443:443', '-p', '8080:8080', '-p', '8989:8989', '-p', '5000:5000', # control port for flask app in simulator ] else: publish_ports = [] if not os.environ.get('ANSIBLE_VCSIM_CONTAINER'): docker_pull(self.args, self.image) docker_run( self.args, self.image, ['-d', '--name', self.container_name] + publish_ports, ) if self.args.docker: vcenter_host = self.DOCKER_SIMULATOR_NAME elif container_id: vcenter_host = self._get_simulator_address() display.info('Found vCenter simulator container address: %s' % vcenter_host, verbosity=1) else: vcenter_host = 'localhost' self._set_cloud_config('vcenter_host', vcenter_host)
def _setup_dynamic(self): """Create a OpenShift container using docker.""" self.container_name = self.DOCKER_CONTAINER_NAME results = docker_inspect(self.args, self.container_name) if results and not results[0]['State']['Running']: docker_rm(self.args, self.container_name) results = [] if results: display.info('Using the existing OpenShift docker container.', verbosity=1) else: display.info('Starting a new OpenShift docker container.', verbosity=1) docker_pull(self.args, self.image) cmd = ['start', 'master', '--listen', 'https://0.0.0.0:8443'] docker_run( self.args, self.image, ['-d', '-p', '8443:8443', '--name', self.container_name], cmd) container_id = get_docker_container_id() if container_id: display.info('Running in docker container: %s' % container_id, verbosity=1) host = self._get_container_address() display.info('Found OpenShift container address: %s' % host, verbosity=1) else: host = 'localhost' port = 8443 endpoint = 'https://%s:%s/' % (host, port) self._wait_for_service(endpoint) if self.args.explain: config = '# Unknown' else: if self.args.docker: host = self.DOCKER_CONTAINER_NAME server = 'https://%s:%s' % (host, port) config = self._get_config(server) self._write_config(config)
def _setup_dynamic(self): """Create a OpenShift container using docker.""" self.container_name = self.DOCKER_CONTAINER_NAME results = docker_inspect(self.args, self.container_name) if results and not results[0]['State']['Running']: docker_rm(self.args, self.container_name) results = [] if results: display.info('Using the existing OpenShift docker container.', verbosity=1) else: display.info('Starting a new OpenShift docker container.', verbosity=1) docker_pull(self.args, self.image) cmd = ['start', 'master', '--listen', 'https://0.0.0.0:8443'] docker_run(self.args, self.image, ['-d', '-p', '8443:8443', '--name', self.container_name], cmd) container_id = get_docker_container_id() if container_id: display.info('Running in docker container: %s' % container_id, verbosity=1) host = self._get_container_address() display.info('Found OpenShift container address: %s' % host, verbosity=1) else: host = 'localhost' port = 8443 endpoint = 'https://%s:%s/' % (host, port) self._wait_for_service(endpoint) if self.args.explain: config = '# Unknown' else: if self.args.docker: host = self.DOCKER_CONTAINER_NAME server = 'https://%s:%s' % (host, port) config = self._get_config(server) self._write_config(config)
def run_httptester(args, ports=None): """ :type args: EnvironmentConfig :type ports: dict[int, int] | None :rtype: str """ options = [ '--detach', ] if ports: for localhost_port, container_port in ports.items(): options += ['-p', '%d:%d' % (localhost_port, container_port)] httptester_id, _ = docker_run(args, args.httptester, options=options) if args.explain: httptester_id = 'httptester_id' else: httptester_id = httptester_id.strip() return httptester_id
def delegate_docker(args, exclude, require): """ :type args: EnvironmentConfig :type exclude: list[str] :type require: list[str] """ util_image = args.docker_util test_image = args.docker privileged = args.docker_privileged if util_image: docker_pull(args, util_image) docker_pull(args, test_image) util_id = None test_id = None options = { '--docker': 1, '--docker-privileged': 0, '--docker-util': 1, } cmd = generate_command(args, '/root/ansible/test/runner/test.py', options, exclude, require) if isinstance(args, TestConfig): if args.coverage and not args.coverage_label: image_label = re.sub('^ansible/ansible:', '', args.docker) image_label = re.sub('[^a-zA-Z0-9]+', '-', image_label) cmd += ['--coverage-label', 'docker-%s' % image_label] if isinstance(args, IntegrationConfig): if not args.allow_destructive: cmd.append('--allow-destructive') cmd_options = [] if isinstance(args, ShellConfig) or (isinstance(args, IntegrationConfig) and args.debug_strategy): cmd_options.append('-it') with tempfile.NamedTemporaryFile(prefix='ansible-source-', suffix='.tgz') as local_source_fd: try: if not args.explain: if args.docker_keep_git: tar_filter = lib.pytar.AllowGitTarFilter() else: tar_filter = lib.pytar.DefaultTarFilter() lib.pytar.create_tarfile(local_source_fd.name, '.', tar_filter) if util_image: util_options = [ '--detach', ] util_id, _ = docker_run(args, util_image, options=util_options) if args.explain: util_id = 'util_id' else: util_id = util_id.strip() else: util_id = None test_options = [ '--detach', '--volume', '/sys/fs/cgroup:/sys/fs/cgroup:ro', '--privileged=%s' % str(privileged).lower(), ] if args.docker_memory: test_options.extend([ '--memory=%d' % args.docker_memory, '--memory-swap=0', ]) docker_socket = '/var/run/docker.sock' if os.path.exists(docker_socket): test_options += ['--volume', '%s:%s' % (docker_socket, docker_socket)] if util_id: test_options += [ '--link', '%s:ansible.http.tests' % util_id, '--link', '%s:sni1.ansible.http.tests' % util_id, '--link', '%s:sni2.ansible.http.tests' % util_id, '--link', '%s:fail.ansible.http.tests' % util_id, '--env', 'HTTPTESTER=1', ] if isinstance(args, IntegrationConfig): cloud_platforms = get_cloud_providers(args) for cloud_platform in cloud_platforms: test_options += cloud_platform.get_docker_run_options() test_id, _ = docker_run(args, test_image, options=test_options) if args.explain: test_id = 'test_id' else: test_id = test_id.strip() # write temporary files to /root since /tmp isn't ready immediately on container start docker_put(args, test_id, 'test/runner/setup/docker.sh', '/root/docker.sh') docker_exec(args, test_id, ['/bin/bash', '/root/docker.sh']) docker_put(args, test_id, local_source_fd.name, '/root/ansible.tgz') docker_exec(args, test_id, ['mkdir', '/root/ansible']) docker_exec(args, test_id, ['tar', 'oxzf', '/root/ansible.tgz', '-C', '/root/ansible']) # docker images are only expected to have a single python version available if isinstance(args, UnitsConfig) and not args.python: cmd += ['--python', 'default'] try: docker_exec(args, test_id, cmd, options=cmd_options) finally: with tempfile.NamedTemporaryFile(prefix='ansible-result-', suffix='.tgz') as local_result_fd: docker_exec(args, test_id, ['tar', 'czf', '/root/results.tgz', '-C', '/root/ansible/test', 'results']) docker_get(args, test_id, '/root/results.tgz', local_result_fd.name) run_command(args, ['tar', 'oxzf', local_result_fd.name, '-C', 'test']) finally: if util_id: docker_rm(args, util_id) if test_id: docker_rm(args, test_id)
def delegate_docker(args, exclude, require): """ :type args: EnvironmentConfig :type exclude: list[str] :type require: list[str] """ util_image = args.docker_util test_image = args.docker privileged = args.docker_privileged if util_image: docker_pull(args, util_image) docker_pull(args, test_image) util_id = None test_id = None options = { '--docker': 1, '--docker-privileged': 0, '--docker-util': 1, } cmd = generate_command(args, '/root/ansible/test/runner/test.py', options, exclude, require) if isinstance(args, TestConfig): if args.coverage and not args.coverage_label: image_label = re.sub('^ansible/ansible:', '', args.docker) image_label = re.sub('[^a-zA-Z0-9]+', '-', image_label) cmd += ['--coverage-label', 'docker-%s' % image_label] if isinstance(args, IntegrationConfig): if not args.allow_destructive: cmd.append('--allow-destructive') cmd_options = [] if isinstance(args, ShellConfig) or (isinstance(args, IntegrationConfig) and args.debug_strategy): cmd_options.append('-it') with tempfile.NamedTemporaryFile(prefix='ansible-source-', suffix='.tgz') as local_source_fd: try: if not args.explain: lib.pytar.create_tarfile(local_source_fd.name, '.', lib.pytar.ignore) if util_image: util_options = [ '--detach', ] util_id, _ = docker_run(args, util_image, options=util_options) if args.explain: util_id = 'util_id' else: util_id = util_id.strip() else: util_id = None test_options = [ '--detach', '--volume', '/sys/fs/cgroup:/sys/fs/cgroup:ro', '--privileged=%s' % str(privileged).lower(), ] docker_socket = '/var/run/docker.sock' if os.path.exists(docker_socket): test_options += ['--volume', '%s:%s' % (docker_socket, docker_socket)] if util_id: test_options += [ '--link', '%s:ansible.http.tests' % util_id, '--link', '%s:sni1.ansible.http.tests' % util_id, '--link', '%s:sni2.ansible.http.tests' % util_id, '--link', '%s:fail.ansible.http.tests' % util_id, '--env', 'HTTPTESTER=1', ] if isinstance(args, IntegrationConfig): cloud_platforms = get_cloud_providers(args) for cloud_platform in cloud_platforms: test_options += cloud_platform.get_docker_run_options() test_id, _ = docker_run(args, test_image, options=test_options) if args.explain: test_id = 'test_id' else: test_id = test_id.strip() # write temporary files to /root since /tmp isn't ready immediately on container start docker_put(args, test_id, 'test/runner/setup/docker.sh', '/root/docker.sh') docker_exec(args, test_id, ['/bin/bash', '/root/docker.sh']) docker_put(args, test_id, local_source_fd.name, '/root/ansible.tgz') docker_exec(args, test_id, ['mkdir', '/root/ansible']) docker_exec(args, test_id, ['tar', 'oxzf', '/root/ansible.tgz', '-C', '/root/ansible']) # docker images are only expected to have a single python version available if isinstance(args, UnitsConfig) and not args.python: cmd += ['--python', 'default'] try: docker_exec(args, test_id, cmd, options=cmd_options) finally: with tempfile.NamedTemporaryFile(prefix='ansible-result-', suffix='.tgz') as local_result_fd: docker_exec(args, test_id, ['tar', 'czf', '/root/results.tgz', '-C', '/root/ansible/test', 'results']) docker_get(args, test_id, '/root/results.tgz', local_result_fd.name) run_command(args, ['tar', 'oxzf', local_result_fd.name, '-C', 'test']) finally: if util_id: docker_rm(args, util_id) if test_id: docker_rm(args, test_id)
def delegate_docker(args, exclude, require, integration_targets): """ :type args: EnvironmentConfig :type exclude: list[str] :type require: list[str] :type integration_targets: tuple[IntegrationTarget] """ test_image = args.docker privileged = args.docker_privileged if isinstance(args, ShellConfig): use_httptester = args.httptester else: use_httptester = args.httptester and any( 'needs/httptester/' in target.aliases for target in integration_targets) if use_httptester: docker_pull(args, args.httptester) docker_pull(args, test_image) httptester_id = None test_id = None options = { '--docker': 1, '--docker-privileged': 0, '--docker-util': 1, } cmd = generate_command(args, '/root/ansible/test/runner/test.py', options, exclude, require) if isinstance(args, TestConfig): if args.coverage and not args.coverage_label: image_label = args.docker_raw image_label = re.sub('[^a-zA-Z0-9]+', '-', image_label) cmd += ['--coverage-label', 'docker-%s' % image_label] if isinstance(args, IntegrationConfig): if not args.allow_destructive: cmd.append('--allow-destructive') cmd_options = [] if isinstance(args, ShellConfig) or (isinstance(args, IntegrationConfig) and args.debug_strategy): cmd_options.append('-it') with tempfile.NamedTemporaryFile(prefix='ansible-source-', suffix='.tgz') as local_source_fd: try: if not args.explain: if args.docker_keep_git: tar_filter = lib.pytar.AllowGitTarFilter() else: tar_filter = lib.pytar.DefaultTarFilter() lib.pytar.create_tarfile(local_source_fd.name, '.', tar_filter) if use_httptester: httptester_id = run_httptester(args) else: httptester_id = None test_options = [ '--detach', '--volume', '/sys/fs/cgroup:/sys/fs/cgroup:ro', '--privileged=%s' % str(privileged).lower(), ] if args.docker_memory: test_options.extend([ '--memory=%d' % args.docker_memory, '--memory-swap=%d' % args.docker_memory, ]) docker_socket = '/var/run/docker.sock' if args.docker_seccomp != 'default': test_options += [ '--security-opt', 'seccomp=%s' % args.docker_seccomp ] if os.path.exists(docker_socket): test_options += [ '--volume', '%s:%s' % (docker_socket, docker_socket) ] if httptester_id: test_options += ['--env', 'HTTPTESTER=1'] for host in HTTPTESTER_HOSTS: test_options += ['--link', '%s:%s' % (httptester_id, host)] if isinstance(args, IntegrationConfig): cloud_platforms = get_cloud_providers(args) for cloud_platform in cloud_platforms: test_options += cloud_platform.get_docker_run_options() test_id, _ = docker_run(args, test_image, options=test_options) if args.explain: test_id = 'test_id' else: test_id = test_id.strip() # write temporary files to /root since /tmp isn't ready immediately on container start docker_put(args, test_id, 'test/runner/setup/docker.sh', '/root/docker.sh') docker_exec(args, test_id, ['/bin/bash', '/root/docker.sh']) docker_put(args, test_id, local_source_fd.name, '/root/ansible.tgz') docker_exec(args, test_id, ['mkdir', '/root/ansible']) docker_exec( args, test_id, ['tar', 'oxzf', '/root/ansible.tgz', '-C', '/root/ansible']) # docker images are only expected to have a single python version available if isinstance(args, UnitsConfig) and not args.python: cmd += ['--python', 'default'] # run unit tests unprivileged to prevent stray writes to the source tree # also disconnect from the network once requirements have been installed if isinstance(args, UnitsConfig): writable_dirs = [ '/root/ansible/.pytest_cache', ] docker_exec(args, test_id, ['mkdir', '-p'] + writable_dirs) docker_exec(args, test_id, ['chmod', '777'] + writable_dirs) docker_exec(args, test_id, [ 'find', '/root/ansible/test/results/', '-type', 'd', '-exec', 'chmod', '777', '{}', '+' ]) docker_exec(args, test_id, ['chmod', '755', '/root']) docker_exec( args, test_id, ['chmod', '644', '/root/ansible/%s' % args.metadata_path]) docker_exec(args, test_id, ['useradd', 'pytest', '--create-home']) docker_exec(args, test_id, cmd + ['--requirements-mode', 'only'], options=cmd_options) networks = get_docker_networks(args, test_id) for network in networks: docker_network_disconnect(args, test_id, network) cmd += ['--requirements-mode', 'skip'] cmd_options += ['--user', 'pytest'] try: docker_exec(args, test_id, cmd, options=cmd_options) finally: with tempfile.NamedTemporaryFile( prefix='ansible-result-', suffix='.tgz') as local_result_fd: docker_exec(args, test_id, [ 'tar', 'czf', '/root/results.tgz', '-C', '/root/ansible/test', 'results' ]) docker_get(args, test_id, '/root/results.tgz', local_result_fd.name) run_command( args, ['tar', 'oxzf', local_result_fd.name, '-C', 'test']) finally: if httptester_id: docker_rm(args, httptester_id) if test_id: docker_rm(args, test_id)
def delegate_docker(args, exclude, require): """ :type args: EnvironmentConfig :type exclude: list[str] :type require: list[str] """ util_image = args.docker_util test_image = args.docker privileged = args.docker_privileged if util_image: docker_pull(args, util_image) docker_pull(args, test_image) util_id = None test_id = None options = { '--docker': 1, '--docker-privileged': 0, '--docker-util': 1, } cmd = generate_command(args, '/root/ansible/test/runner/test.py', options, exclude, require) if isinstance(args, IntegrationConfig): if not args.allow_destructive: cmd.append('--allow-destructive') cmd_options = [] if isinstance(args, ShellConfig): cmd_options.append('-it') if not args.explain: lib.pytar.create_tarfile('/tmp/ansible.tgz', '.', lib.pytar.ignore) try: if util_image: util_options = [ '--detach', ] util_id, _ = docker_run(args, util_image, options=util_options) if args.explain: util_id = 'util_id' else: util_id = util_id.strip() else: util_id = None test_options = [ '--detach', '--volume', '/sys/fs/cgroup:/sys/fs/cgroup:ro', '--privileged=%s' % str(privileged).lower(), ] if util_id: test_options += [ '--link', '%s:ansible.http.tests' % util_id, '--link', '%s:sni1.ansible.http.tests' % util_id, '--link', '%s:sni2.ansible.http.tests' % util_id, '--link', '%s:fail.ansible.http.tests' % util_id, '--env', 'HTTPTESTER=1', ] if isinstance(args, TestConfig): cloud_platforms = get_cloud_providers(args) for cloud_platform in cloud_platforms: test_options += cloud_platform.get_docker_run_options() test_id, _ = docker_run(args, test_image, options=test_options) if args.explain: test_id = 'test_id' else: test_id = test_id.strip() # write temporary files to /root since /tmp isn't ready immediately on container start docker_put(args, test_id, 'test/runner/setup/docker.sh', '/root/docker.sh') docker_exec(args, test_id, ['/bin/bash', '/root/docker.sh']) docker_put(args, test_id, '/tmp/ansible.tgz', '/root/ansible.tgz') docker_exec(args, test_id, ['mkdir', '/root/ansible']) docker_exec( args, test_id, ['tar', 'oxzf', '/root/ansible.tgz', '-C', '/root/ansible']) # docker images are only expected to have a single python version available if isinstance(args, UnitsConfig) and not args.python: cmd += ['--python', 'default'] try: docker_exec(args, test_id, cmd, options=cmd_options) finally: docker_exec(args, test_id, [ 'tar', 'czf', '/root/results.tgz', '-C', '/root/ansible/test', 'results' ]) docker_get(args, test_id, '/root/results.tgz', '/tmp/results.tgz') run_command(args, ['tar', 'oxzf', '/tmp/results.tgz', '-C', 'test']) finally: if util_id: docker_rm(args, util_id) if test_id: docker_rm(args, test_id)
def _setup_dynamic(self): """Create a CloudStack simulator using docker.""" config = self._read_config_template() self.container_name = self.DOCKER_SIMULATOR_NAME results = docker_inspect(self.args, self.container_name) if results and not results[0]['State']['Running']: docker_rm(self.args, self.container_name) results = [] if results: display.info( 'Using the existing CloudStack simulator docker container.', verbosity=1) else: display.info( 'Starting a new CloudStack simulator docker container.', verbosity=1) docker_pull(self.args, self.image) docker_run( self.args, self.image, ['-d', '-p', '8888:8888', '--name', self.container_name]) # apply work-around for OverlayFS issue # https://github.com/docker/for-linux/issues/72#issuecomment-319904698 docker_exec(self.args, self.container_name, [ 'find', '/var/lib/mysql', '-type', 'f', '-exec', 'touch', '{}', ';' ]) if not self.args.explain: display.notice( 'The CloudStack simulator will probably be ready in 2 - 4 minutes.' ) container_id = get_docker_container_id() if container_id: display.info('Running in docker container: %s' % container_id, verbosity=1) self.host = self._get_simulator_address() display.info('Found CloudStack simulator container address: %s' % self.host, verbosity=1) else: self.host = 'localhost' self.port = 8888 self.endpoint = 'http://%s:%d' % (self.host, self.port) self._wait_for_service() if self.args.explain: values = dict( HOST=self.host, PORT=str(self.port), ) else: credentials = self._get_credentials() if self.args.docker: host = self.DOCKER_SIMULATOR_NAME else: host = self.host values = dict( HOST=host, PORT=str(self.port), KEY=credentials['apikey'], SECRET=credentials['secretkey'], ) display.sensitive.add(values['SECRET']) config = self._populate_config_template(config, values) self._write_config(config)