def yes(self, answer: str) -> None: log.info('enabling and starting ' + self.__class__.__name__) for service in self.services: enable(service) log.info(self.__class__.__name__ + ' enabled')
def yes(self, answer: str) -> None: log.info('Configuring the Placement service...') if not call('openstack', 'user', 'show', 'placement'): check( 'openstack', 'user', 'create', '--domain', 'default', '--password', shell.config_get('config.credentials.placement-password'), 'placement', ) check('openstack', 'role', 'add', '--project', 'service', '--user', 'placement', 'admin') if not call('openstack', 'service', 'show', 'placement'): check('openstack', 'service', 'create', '--name', 'placement', '--description', '"Placement API"', 'placement') for endpoint in ['public', 'internal', 'admin']: call('openstack', 'endpoint', 'create', '--region', 'microstack', 'placement', endpoint, 'http://{control_ip}:8778'.format(**_env)) log.info('Running Placement DB migrations...') check('snap-openstack', 'launch', 'placement-manage', 'db', 'sync') enable('placement-uwsgi')
def yes(self, answer: str) -> None: log.info('Configuring Glance ...') if not call('openstack', 'user', 'show', 'glance'): check('openstack', 'user', 'create', '--domain', 'default', '--password', shell.config_get('config.credentials.glance-password'), 'glance') check('openstack', 'role', 'add', '--project', 'service', '--user', 'glance', 'admin') if not call('openstack', 'service', 'show', 'image'): check('openstack', 'service', 'create', '--name', 'glance', '--description', '"OpenStack Image"', 'image') for endpoint in ['internal', 'admin', 'public']: check('openstack', 'endpoint', 'create', '--region', 'microstack', 'image', endpoint, 'http://{compute_ip}:9292'.format(**_env)) check('snap-openstack', 'launch', 'glance-manage', 'db_sync') # TODO: remove the glance registry # https://blueprints.launchpad.net/glance/+spec/deprecate-registry for service in [ 'glance-api', 'registry', ]: enable(service) nc_wait(_env['compute_ip'], '9292') sleep(5) # TODO: log_wait self._fetch_cirros()
def yes(self, answer: str) -> None: log.info('Configuring Glance ...') if not call('openstack', 'user', 'show', 'glance'): check('openstack', 'user', 'create', '--domain', 'default', '--password', 'glance', 'glance') check('openstack', 'role', 'add', '--project', 'service', '--user', 'glance', 'admin') if not call('openstack', 'service', 'show', 'image'): check('openstack', 'service', 'create', '--name', 'glance', '--description', '"OpenStack Image"', 'image') for endpoint in ['internal', 'admin', 'public']: check('openstack', 'endpoint', 'create', '--region', 'microstack', 'image', endpoint, 'http://{extgateway}:9292'.format(**_env)) check('snap-openstack', 'launch', 'glance-manage', 'db_sync') restart('glance*') nc_wait(_env['extgateway'], '9292') sleep(5) # TODO: log_wait self._fetch_cirros()
def yes(self, answer: str) -> None: log.info('Configuring the Cinder services...') if not call('openstack', 'user', 'show', 'cinder'): check('openstack', 'user', 'create', '--domain', 'default', '--password', shell.config_get('config.credentials.cinder-password'), 'cinder') check('openstack', 'role', 'add', '--project', 'service', '--user', 'cinder', 'admin') control_ip = _env['control_ip'] for endpoint in ['public', 'internal', 'admin']: for api_version in ['v2', 'v3']: if not call('openstack', 'service', 'show', f'cinder{api_version}'): check('openstack', 'service', 'create', '--name', f'cinder{api_version}', '--description', f'"Cinder {api_version} API"', f'volume{api_version}') if not check_output('openstack', 'endpoint', 'list', '--service', f'volume{api_version}', '--interface', endpoint): check( 'openstack', 'endpoint', 'create', '--region', 'microstack', f'volume{api_version}', endpoint, f'http://{control_ip}:8776/{api_version}/' '$(project_id)s') log.info('Running Cinder DB migrations...') check('snap-openstack', 'launch', 'cinder-manage', 'db', 'sync') enable('cinder-uwsgi') enable('cinder-scheduler')
def no(self, answer): log.info('Disabling Cinder services...') for service in [ 'cinder-uwsgi', 'cinder-scheduler', 'cinder-volume', 'cinder-backup' ]: disable(service)
def no(self, answer): log.info('Disabling nova control plane services ...') for service in [ 'nova-api', 'nova-conductor', 'nova-scheduler', 'nova-api-metadata' ]: disable(service)
def yes(self, answer: str) -> None: log.info('Configuring Neutron') if not call('openstack', 'user', 'show', 'neutron'): check('openstack', 'user', 'create', '--domain', 'default', '--password', 'neutron', 'neutron') check('openstack', 'role', 'add', '--project', 'service', '--user', 'neutron', 'admin') if not call('openstack', 'service', 'show', 'network'): check('openstack', 'service', 'create', '--name', 'neutron', '--description', '"OpenStack Network"', 'network') for endpoint in ['public', 'internal', 'admin']: call('openstack', 'endpoint', 'create', '--region', 'microstack', 'network', endpoint, 'http://{extgateway}:9696'.format(**_env)) for service in [ environ['SNAP_INSTANCE_NAME'] + '.neutron-api', environ['SNAP_INSTANCE_NAME'] + '.neutron-dhcp-agent', environ['SNAP_INSTANCE_NAME'] + '.neutron-l3-agent', environ['SNAP_INSTANCE_NAME'] + '.neutron-metadata-agent', environ['SNAP_INSTANCE_NAME'] + '.neutron-openvswitch-agent', ]: check('snapctl', 'start', service) check('snap-openstack', 'launch', 'neutron-db-manage', 'upgrade', 'head') restart('neutron-*') nc_wait(_env['extgateway'], '9696') sleep(5) # TODO: log_wait if not call('openstack', 'network', 'show', 'test'): check('openstack', 'network', 'create', 'test') if not call('openstack', 'subnet', 'show', 'test-subnet'): check('openstack', 'subnet', 'create', '--network', 'test', '--subnet-range', '192.168.222.0/24', 'test-subnet') if not call('openstack', 'network', 'show', 'external'): check('openstack', 'network', 'create', '--external', '--provider-physical-network=physnet1', '--provider-network-type=flat', 'external') if not call('openstack', 'subnet', 'show', 'external-subnet'): check('openstack', 'subnet', 'create', '--network', 'external', '--subnet-range', _env['extcidr'], '--no-dhcp', 'external-subnet') if not call('openstack', 'router', 'show', 'test-router'): check('openstack', 'router', 'create', 'test-router') check('openstack', 'router', 'add', 'subnet', 'test-router', 'test-subnet') check('openstack', 'router', 'set', '--external-gateway', 'external', 'test-router')
def yes(self, answer: str) -> None: log.info('restarting libvirt and virtlogd ...') # This fixes an issue w/ logging not getting set. # TODO: fix issue. restart('*virt*') check('snapctl', 'set', 'initialized=true') log.info('Complete. Marked microstack as initialized!')
def yes(self, answer: bool) -> None: check( 'snapctl', 'set', f'config.cinder.setup-loop-based-cinder-lvm-backend' f'={str(answer).lower()}') log.info('Setting up cinder-volume service with the LVM backend...') enable('setup-lvm-loopdev') enable('cinder-volume') enable('target') enable('iscsid')
def yes(self, answer: str) -> None: log.info('restarting libvirt and virtlogd ...') # This fixes an issue w/ logging not getting set. # TODO: fix issue. restart('*virt*') # Start horizon check('snapctl', 'start', environ['SNAP_INSTANCE_NAME'] + '.horizon-uwsgi') check('snapctl', 'set', 'initialized=true') log.info('Complete. Marked microstack as initialized!')
def _maybe_enable_emulation(self): log.info('Checking virtualization extensions presence on the host') # Use KVM if it is supported, alternatively fall back to software # emulation. if self._is_hw_virt_supported(): log.info('Hardware virtualization is supported - KVM will be used' ' for Nova instances') shell.config_set(**{'config.nova.virt-type': 'kvm'}) shell.config_set(**{'config.nova.cpu-mode': 'host-passthrough'}) else: log.warning('Hardware virtualization is not supported - software' ' emulation will be used for Nova instances') shell.config_set(**{'config.nova.virt-type': 'qemu'}) shell.config_set(**{'config.nova.cpu-mode': 'host-passthrough'})
def yes(self, answer: str) -> None: log.info('Waiting for RabbitMQ to start ...') self._wait() log.info('RabbitMQ started!') log.info('Configuring RabbitMQ ...') self._configure() log.info('RabbitMQ Configured!')
def yes(self, answer: str) -> None: log.info('Configuring Neutron') if not call('openstack', 'user', 'show', 'neutron'): check('openstack', 'user', 'create', '--domain', 'default', '--password', shell.config_get('config.credentials.neutron-password'), 'neutron') check('openstack', 'role', 'add', '--project', 'service', '--user', 'neutron', 'admin') if not call('openstack', 'service', 'show', 'network'): check('openstack', 'service', 'create', '--name', 'neutron', '--description', '"OpenStack Network"', 'network') for endpoint in ['public', 'internal', 'admin']: call('openstack', 'endpoint', 'create', '--region', 'microstack', 'network', endpoint, 'http://{control_ip}:9696'.format(**_env)) check('snap-openstack', 'launch', 'neutron-db-manage', 'upgrade', 'head') enable('neutron-api') enable('neutron-ovn-metadata-agent') nc_wait(_env['control_ip'], '9696') sleep(5) # TODO: log_wait if not call('openstack', 'network', 'show', 'test'): check('openstack', 'network', 'create', 'test') if not call('openstack', 'subnet', 'show', 'test-subnet'): check('openstack', 'subnet', 'create', '--network', 'test', '--subnet-range', '192.168.222.0/24', 'test-subnet') if not call('openstack', 'network', 'show', 'external'): check('openstack', 'network', 'create', '--external', '--provider-physical-network=physnet1', '--provider-network-type=flat', 'external') if not call('openstack', 'subnet', 'show', 'external-subnet'): check('openstack', 'subnet', 'create', '--network', 'external', '--subnet-range', _env['extcidr'], '--no-dhcp', 'external-subnet') if not call('openstack', 'router', 'show', 'test-router'): check('openstack', 'router', 'create', 'test-router') check('openstack', 'router', 'add', 'subnet', 'test-router', 'test-subnet') check('openstack', 'router', 'set', '--external-gateway', 'external', 'test-router')
def yes(self, answer: str) -> None: log.info('Configuring nova control plane services ...') if not call('openstack', 'user', 'show', 'nova'): check('openstack', 'user', 'create', '--domain', 'default', '--password', shell.config_get('config.credentials.nova-password'), 'nova') check('openstack', 'role', 'add', '--project', 'service', '--user', 'nova', 'admin') # Assign the reader role to the nova user so that read-only # application credentials can be created. check('openstack', 'role', 'add', '--project', 'service', '--user', 'nova', 'reader') log.info('Running Nova API DB migrations' ' (this may take a lot of time)...') check('snap-openstack', 'launch', 'nova-manage', 'api_db', 'sync') if 'cell0' not in check_output('snap-openstack', 'launch', 'nova-manage', 'cell_v2', 'list_cells'): check('snap-openstack', 'launch', 'nova-manage', 'cell_v2', 'map_cell0') if 'cell1' not in check_output('snap-openstack', 'launch', 'nova-manage', 'cell_v2', 'list_cells'): check('snap-openstack', 'launch', 'nova-manage', 'cell_v2', 'create_cell', '--name=cell1', '--verbose') log.info('Running Nova DB migrations' ' (this may take a lot of time)...') check('snap-openstack', 'launch', 'nova-manage', 'db', 'sync') enable('nova-api') restart('nova-compute') for service in [ 'nova-api-metadata', 'nova-conductor', 'nova-scheduler', ]: enable(service) nc_wait(_env['compute_ip'], '8774') sleep(5) # TODO: log_wait if not call('openstack', 'service', 'show', 'compute'): check('openstack', 'service', 'create', '--name', 'nova', '--description', '"Openstack Compute"', 'compute') for endpoint in ['public', 'internal', 'admin']: call('openstack', 'endpoint', 'create', '--region', 'microstack', 'compute', endpoint, 'http://{control_ip}:8774/v2.1'.format(**_env)) log.info('Creating default flavors...') self._flavors()
def yes(self, answer: str) -> None: if 'microstack' not in check_output('openstack', 'keypair', 'list'): log.info('Creating microstack keypair (~/.ssh/{})'.format(answer)) check('mkdir', '-p', '{HOME}/.ssh'.format(**_env)) check('chmod', '700', '{HOME}/.ssh'.format(**_env)) id_ = check_output('openstack', 'keypair', 'create', 'microstack') id_path = '{HOME}/.ssh/{answer}'.format(HOME=_env['HOME'], answer=answer) with open(id_path, 'w') as file_: file_.write(id_) check('chmod', '600', id_path) # TODO: too many assumptions in the below. Make it portable! user = _env['HOME'].split("/")[2] check('chown', '{}:{}'.format(user, user), id_path)
def yes(self, answer: str) -> None: log.info('restarting libvirt and virtlogd ...') # This fixes an issue w/ logging not getting set. # TODO: fix issue. restart('libvirtd') restart('virtlogd') restart('nova-compute') role = shell.config_get('config.cluster.role') if role == 'control': # TODO: since snap-openstack launch is used, this depends on the # database readiness and hence the clustering service is enabled # and started here. There needs to be a better way to do this. enable('cluster-uwsgi') enable('horizon-uwsgi') check('snapctl', 'set', 'initialized=true') log.info('Complete. Marked microstack as initialized!')
def yes(self, answer: str) -> None: """Since this is an auto question, we always execute yes.""" log.info('Loading config and writing templates ...') log.info('Validating config ...') for key in ['ospassword', 'extgateway', 'extcidr', 'dns']: val = check_output('snapctl', 'get', key) if not val: raise ConfigError( 'Expected config value {} is not set.'.format(key)) _env[key] = val log.info('Writing out templates ...') check('snap-openstack', 'setup') # Parse microstack.rc, and load into _env # TODO: write something more robust (this breaks on comments # at end of line.) mstackrc = '{SNAP_COMMON}/etc/microstack.rc'.format(**_env) with open(mstackrc, 'r') as rc_file: for line in rc_file.readlines(): if not line.startswith('export'): continue key, val = line[7:].split('=') _env[key.strip()] = val.strip()
def _fetch_cirros(self) -> None: if call('openstack', 'image', 'show', 'cirros'): return env = dict(**_env) env['VER'] = '0.4.0' env['IMG'] = 'cirros-{VER}-x86_64-disk.img'.format(**env) log.info('Fetching cirros image ...') cirros_path = '{SNAP_COMMON}/images/{IMG}'.format(**env) if not path.exists(cirros_path): check('mkdir', '-p', '{SNAP_COMMON}/images'.format(**env)) download( 'http://download.cirros-cloud.net/{VER}/{IMG}'.format(**env), '{SNAP_COMMON}/images/{IMG}'.format(**env)) check('openstack', 'image', 'create', '--file', '{SNAP_COMMON}/images/{IMG}'.format(**env), '--public', '--container-format=bare', '--disk-format=qcow2', 'cirros')
def yes(self, answer: str) -> None: # Create security group rules log.info('Creating security group rules ...') group_id = check_output('openstack', 'security', 'group', 'list', '--project', 'admin', '-f', 'value', '-c', 'ID') rules = check_output('openstack', 'security', 'group', 'rule', 'list', '--format', 'json') ping_rule = False ssh_rule = False for rule in json.loads(rules): if rule['Security Group'] == group_id: if rule['IP Protocol'] == 'icmp': ping_rule = True if rule['IP Protocol'] == 'tcp': ssh_rule = True if not ping_rule: check('openstack', 'security', 'group', 'rule', 'create', group_id, '--proto', 'icmp') if not ssh_rule: check('openstack', 'security', 'group', 'rule', 'create', group_id, '--proto', 'tcp', '--dst-port', '22')
def yes(self, answer: bool): log.info('Configuring clustering ...') role_question = clustering.Role() if not (self.interactive and self.role_interactive): role_question.interactive = False role_question.ask() questions = [ # Skipped for the compute role and is automatically taken # from the connection string. clustering.ControlIp(), # Skipped for the control role since it is identical to the # control node IP. clustering.ComputeIp(), ] for question in questions: if not self.interactive: question.interactive = False question.ask() connection_string_question = clustering.ConnectionString() if not (self.interactive and self.connection_string_interactive): connection_string_question.interactive = False connection_string_question.ask() role = shell.config_get('config.cluster.role') if role == 'compute': log.info('Setting up as a compute node.') # Gets config info and sets local env vals. check_output('microstack_join') shell.config_set( **{ 'config.services.control-plane': 'false', 'config.services.hypervisor': 'true', }) if role == 'control': log.info('Setting up as a control node.') shell.config_set( **{ 'config.services.control-plane': 'true', 'config.services.hypervisor': 'true', }) # Generate a self-signed certificate for the clustering service. cluster_tls.generate_selfsigned() # Write templates check('snap-openstack', 'setup')
def yes(self, answer: str) -> None: """Use sysctl to setup ip forwarding.""" log.info('Setting up ipv4 forwarding...') check('sysctl', 'net.ipv4.ip_forward=1')
def no(self, answer): log.info('Disabling the Placement service...') disable('placement-uwsgi')
def yes(self, answer: str) -> None: log.info('Configuring nova ...') if not call('openstack', 'user', 'show', 'nova'): check('openstack', 'user', 'create', '--domain', 'default', '--password', 'nova', 'nova') check('openstack', 'role', 'add', '--project', 'service', '--user', 'nova', 'admin') if not call('openstack', 'user', 'show', 'placement'): check('openstack', 'user', 'create', '--domain', 'default', '--password', 'placement', 'placement') check('openstack', 'role', 'add', '--project', 'service', '--user', 'placement', 'admin') if not call('openstack', 'service', 'show', 'compute'): check('openstack', 'service', 'create', '--name', 'nova', '--description', '"Openstack Compute"', 'compute') for endpoint in ['public', 'internal', 'admin']: call('openstack', 'endpoint', 'create', '--region', 'microstack', 'compute', endpoint, 'http://{extgateway}:8774/v2.1'.format(**_env)) if not call('openstack', 'service', 'show', 'placement'): check('openstack', 'service', 'create', '--name', 'placement', '--description', '"Placement API"', 'placement') for endpoint in ['public', 'internal', 'admin']: call('openstack', 'endpoint', 'create', '--region', 'microstack', 'placement', endpoint, 'http://{extgateway}:8778'.format(**_env)) # Grant nova user access to cell0 sql( "GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'{extgateway}' \ IDENTIFIED BY \'nova';".format(**_env)) check('snap-openstack', 'launch', 'nova-manage', 'api_db', 'sync') if 'cell0' not in check_output('snap-openstack', 'launch', 'nova-manage', 'cell_v2', 'list_cells'): check('snap-openstack', 'launch', 'nova-manage', 'cell_v2', 'map_cell0') if 'cell1' not in check_output('snap-openstack', 'launch', 'nova-manage', 'cell_v2', 'list_cells'): check('snap-openstack', 'launch', 'nova-manage', 'cell_v2', 'create_cell', '--name=cell1', '--verbose') check('snap-openstack', 'launch', 'nova-manage', 'db', 'sync') restart('nova-*') nc_wait(_env['extgateway'], '8774') sleep(5) # TODO: log_wait log.info('Creating default flavors...') self._flavors()
def yes(self, answer: str) -> None: """Setup Databases. Create all the MySQL databases we require, then setup the fernet keys and create the service project. """ log.info('Waiting for MySQL server to start ...') self._wait() log.info('Mysql server started! Creating databases ...') self._create_dbs() log.info('Configuring Keystone Fernet Keys ...') check('snap-openstack', 'launch', 'keystone-manage', 'fernet_setup', '--keystone-user', 'root', '--keystone-group', 'root') check('snap-openstack', 'launch', 'keystone-manage', 'db_sync') restart('keystone-*') log.info('Bootstrapping Keystone ...') self._bootstrap() log.info('Creating service project ...') if not call('openstack', 'project', 'show', 'service'): check('openstack', 'project', 'create', '--domain', 'default', '--description', 'Service Project', 'service') log.info('Keystone configured!')
def no(self, answer): log.info('Disabling nova compute service ...') disable('nova-spicehtml5proxy')
def no(self, answer: str): # We assume that the control node has a connection setup for us. check('snapctl', 'set', 'database.ready=true') log.info('Disabling local MySQL ...') disable('mysqld')
def yes(self, answer): log.info('Configuring nova compute hypervisor ...') enable('libvirtd') enable('virtlogd') enable('nova-compute')
def yes(self, answer): log.info('Configuring the Spice HTML5 console service...') enable('nova-spicehtml5proxy')
def no(self, answer): log.info('Disabling nova compute service ...') disable('libvirtd') disable('virtlogd') disable('nova-compute')