def exec_cmd_in_container(self, container_name, cmd): """Execute command in running container :param name: name of the container, like fuel-core-5.1-nailgun """ db_container_id = self.container_docker_id(container_name) utils.exec_cmd("dockerctl shell {0} {1}".format(db_container_id, cmd))
def save_astute_keys(self): """Copy any astute generated keys.""" container_name = self.make_container_name('astute', self.from_version) utils.remove(self.config.astute_keys_path) try: utils.exec_cmd('docker cp {0}:{1} {2}'.format( container_name, self.config.astute_container_keys_path, self.config.working_directory)) except errors.ExecutedErrorNonZeroExitCode as exc: # If there was error, mostly it's because of error # # Error: Could not find the file /var/lib/astute # in container fuel-core-5.0-astute # # It means that user didn't run deployment on his # env, because this directory is created by orchestrator # during the first deployment. # Also it can fail if there was no running container # in both case we should create empty directory to copy # it in after container creation section logger.debug( 'Cannot copy astute keys, creating empty directory ' '%s: %s', self.config.astute_keys_path, exc) if not utils.file_exists(self.config.astute_keys_path): os.mkdir(self.config.astute_keys_path)
def run_puppet(self): """Run puppet to upgrade host system """ utils.exec_cmd( 'puppet apply -d -v ' '{0} --modulepath={1}'.format( self.manifest_path, self.puppet_modules_path))
def clean_docker_iptables_rules(self, ports): """Sometimes when we run docker stop (version dc9c28f/0.10.0) it doesn't clean iptables rules, as result when we run new container on the same port we have two rules with the same port but with different IPs, we have to clean this rules to prevent services unavailability. Example of the problem: $ iptables -t nat -S ... -A DOCKER -p tcp -m tcp --dport 443 -j DNAT \ --to-destination 172.17.0.7:443 -A DOCKER -p tcp -m tcp --dport 443 -j DNAT \ --to-destination 172.17.0.3:443 :param ports: list of ports to clean up """ rules_to_deletion = [] patterns = [re.compile( '^-A DOCKER .+ --dport {0} ' '-j DNAT --to-destination .+'.format(port)) for port in ports] for rule in utils.exec_cmd_iterator('iptables -t nat -S'): for pattern in patterns: if pattern.match(rule): rules_to_deletion.append(rule) for rule in rules_to_deletion: # Remove -A (add) prefix and use -D (delete) instead utils.exec_cmd('iptables -t nat -D {0}'.format(rule[2:]))
def clean_docker_iptables_rules(self, ports): """Sometimes when we run docker stop (version dc9c28f/0.10.0) it doesn't clean iptables rules, as result when we run new container on the same port we have two rules with the same port but with different IPs, we have to clean this rules to prevent services unavailability. Example of the problem: $ iptables -t nat -S ... -A DOCKER -p tcp -m tcp --dport 443 -j DNAT \ --to-destination 172.17.0.7:443 -A DOCKER -p tcp -m tcp --dport 443 -j DNAT \ --to-destination 172.17.0.3:443 :param ports: list of ports to clean up """ rules_to_deletion = [] patterns = [ re.compile('^-A DOCKER .+ --dport {0} ' '-j DNAT --to-destination .+'.format(port)) for port in ports ] for rule in utils.exec_cmd_iterator('iptables -t nat -S'): for pattern in patterns: if pattern.match(rule): rules_to_deletion.append(rule) for rule in rules_to_deletion: # Remove -A (add) prefix and use -D (delete) instead utils.exec_cmd('iptables -t nat -D {0}'.format(rule[2:]))
def update_repo(self): """Add new centos repository """ utils.render_template_to_file( self.repo_template_path, self.repo_config_path, {'version': self.version, 'repo_path': self.host_system_config['repo_master']}) utils.exec_cmd('yum clean all')
def update_repo(self): """Add new centos repository """ utils.render_template_to_file(self.repo_template_path, self.repo_config_path, { 'version': self.version, 'repo_path': self.repo_dst }) utils.exec_cmd('yum clean all')
def update_repo(self): """Add new centos repository """ utils.render_template_to_file( self.repo_template_path, self.repo_config_path, { 'name': '{0}_nailgun'.format(self.version), 'baseurl': self.host_system_config['repo_master'], 'gpgcheck': 0, 'skip_if_unavailable': 0, }) utils.exec_cmd('yum clean all')
def test_exec_cmd_executes_sucessfuly(self): cmd = 'some command' process_mock = self.make_process_mock() with patch.object(subprocess, 'Popen', return_value=process_mock) as popen_mock: exec_cmd(cmd) popen_mock.assert_called_once_with(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
def update_repo(self): """Add new centos repository""" utils.render_template_to_file( self.repo_template_path, self.repo_config_path, { 'name': '{0}_nailgun'.format(self.version), 'baseurl': self.host_system_config['repo_master'], 'gpgcheck': 0, 'skip_if_unavailable': 0, }) utils.exec_cmd('yum clean all')
def test_exec_cmd_executes_sucessfuly(self): cmd = 'some command' process_mock = self.make_process_mock() with patch.object( subprocess, 'Popen', return_value=process_mock) as popen_mock: exec_cmd(cmd) popen_mock.assert_called_once_with( cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
def exec_cmd_in_container(self, container_name, cmd): """Execute command in running container :param name: name of the container, like fuel-core-5.1-nailgun """ db_container_id = self.container_docker_id(container_name) # NOTE(eli): we don't use dockerctl shell # instead of lxc-attach here because # release 5.0 has a bug which doesn't # allow us to use quotes in command # https://bugs.launchpad.net/fuel/+bug/1324200 utils.exec_cmd("lxc-attach --name {0} -- {1}".format( db_container_id, cmd))
def exec_cmd_in_container(self, container_name, cmd): """Execute command in running container :param name: name of the container, like fuel-core-5.1-nailgun """ db_container_id = self.container_docker_id(container_name) # NOTE(eli): we don't use dockerctl shell # instead of lxc-attach here because # release 5.0 has a bug which doesn't # allow us to use quotes in command # https://bugs.launchpad.net/fuel/+bug/1324200 utils.exec_cmd( "lxc-attach --name {0} -- {1}".format( db_container_id, cmd))
def save_cobbler_configs(self): """Copy config files from container """ container_name = self.make_container_name('cobbler', self.from_version) try: utils.exec_cmd('docker cp {0}:{1} {2}'.format( container_name, self.config.cobbler_container_config_path, self.cobbler_config_path)) except errors.ExecutedErrorNonZeroExitCode: utils.rmtree(self.cobbler_config_path) raise self.verify_cobbler_configs()
def upload_images(self): """Uploads images to docker """ logger.info(u'Start image uploading') if not os.path.exists(self.config.images): logger.warn(u'Cannot find docker images "%s"', self.config.images) return # NOTE(eli): docker-py binding # doesn't have equal call for # image importing which equals to # `docker load` utils.exec_cmd(u'docker load -i "{0}"'.format(self.config.images))
def save_astute_keys(self): """Copy any astute generated keys.""" container_name = self.make_container_name('astute', self.from_version) try: utils.exec_cmd('docker cp {0}:{1} {2}'.format( container_name, self.config.astute_container_keys_path, self.config.working_directory)) except errors.ExecutedErrorNonZeroExitCode: # we need to create default directory because in # after_container_creation_command will use it # but we want to remove keys if os.path.exists(self.config.astute_keys_path): utils.rmtree(self.config.astute_keys_path) raise os.mkdir(self.config.astute_keys_path)
def save_cobbler_configs(self): """Copy config files from container """ container_name = self.make_container_name( 'cobbler', self.from_version) try: utils.exec_cmd('docker cp {0}:{1} {2}'.format( container_name, self.config.cobbler_container_config_path, self.cobbler_config_path)) except errors.ExecutedErrorNonZeroExitCode: utils.rmtree(self.cobbler_config_path) raise self.verify_cobbler_configs()
def upload_images(self): """Uploads images to docker """ logger.info(u'Start image uploading') for image in self.new_release_images: logger.debug(u'Try to upload docker image %s', image) docker_image = image['docker_image'] if not os.path.exists(docker_image): logger.warn(u'Cannot find docker image "%s"', docker_image) continue # NOTE(eli): docker-py binding # doesn't have equal call for # image importing which equals to # `docker load` utils.exec_cmd(u'docker load < "{0}"'.format(docker_image))
def clean_docker_iptables_rules(self, ports): """Sometimes when we run docker stop (version dc9c28f/0.10.0) it doesn't clean iptables rules, as result when we run new container on the same port we have two rules with the same port but with different IPs, we have to clean this rules to prevent services unavailability. Example of the problem: $ iptables -t nat -S ... -A DOCKER -p tcp -m tcp --dport 443 -j DNAT \ --to-destination 172.17.0.7:443 -A DOCKER -p tcp -m tcp --dport 443 -j DNAT \ --to-destination 172.17.0.3:443 :param ports: list of ports to clean up """ rules_to_deletion = [] patterns = [re.compile( '^-A DOCKER .+ --dport {0} ' '-j DNAT --to-destination .+'.format(port)) for port in ports] for rule in utils.exec_cmd_iterator('iptables -t nat -S'): for pattern in patterns: if pattern.match(rule): rules_to_deletion.append(rule) for rule in rules_to_deletion: # Remove -A (add) prefix and use -D (delete) instead utils.exec_cmd('iptables -t nat -D {0}'.format(rule[2:])) # NOTE(eli): Run list of rules again, # it's required to debug the problem # with inter-container communication # https://bugs.launchpad.net/fuel/+bug/1349287 utils.exec_cmd('iptables -t nat -S') utils.exec_cmd('iptables -S') utils.exec_cmd('cat /etc/sysconfig/iptables') utils.exec_cmd('cat /etc/sysconfig/iptables.save')
def run(self): """Move files to new directory """ if not utils.file_exists(self.dst_path): os.makedirs(self.dst_path) container_name = '{0}{1}-astute'.format(self.config.container_prefix, self.config.from_version) try: utils.exec_cmd('docker cp {0}:{1} {2}'.format( container_name, self.src_path, self.dst_path)) # we need move and remove folder, because docker copy also folder # not only content utils.exec_cmd('mv {0}astute/* {0}'.format(self.dst_path)) utils.exec_cmd('rm -r {0}astute/'.format(self.dst_path)) except errors.ExecutedErrorNonZeroExitCode as exc: # Error means that user didn't run deployment on his # env, because this directory is created only then logger.warning('Cannot copy astute keys %s', exc)
def run(self): """Move files to new directory""" if not utils.file_exists(self.dst_path): os.makedirs(self.dst_path) container_name = '{0}{1}-astute'.format( self.config.container_prefix, self.config.from_version) try: utils.exec_cmd('docker cp {0}:{1} {2}'.format( container_name, self.src_path, self.dst_path)) # we need move and remove folder, because docker copy also folder # not only content utils.exec_cmd('mv {0}astute/* {0}'.format(self.dst_path)) utils.exec_cmd('rm -r {0}astute/'.format(self.dst_path)) except errors.ExecutedErrorNonZeroExitCode as exc: # Error means that user didn't run deployment on his # env, because this directory is created only then logger.warning( 'Cannot copy astute keys %s', exc)
def install_packages(self): """Install packages for new release """ for package in self.packages: utils.exec_cmd('yum install -v -y {0}'.format(package))
def backup(self): exec_cmd(self.puppet_cmd + '"include backup"')
def rollback(self): exec_cmd(self.puppet_cmd + '"include rollback"')
def upgrade(self): exec_cmd(self.puppet_cmd + '"include upgrade"')