def _create_test_instance_with_nic(self, return_server, name): stack_name = '%s_s' % name t = template_format.parse(wp_template_with_nic) template = parser.Template(t) kwargs = {'KeyName': 'test', 'InstanceType': 'm1.large', 'SubnetId': '4156c7a5-e8c4-4aff-a6e1-8f3c7bc83861'} stack = parser.Stack(utils.dummy_context(), stack_name, template, environment.Environment(kwargs), stack_id=str(uuid.uuid4())) t['Resources']['WebServer']['Properties']['ImageId'] = 'CentOS 5.2' nic = network_interfaces.NetworkInterface('%s_nic' % name, t['Resources']['nic1'], stack) instance = instances.Instance('%s_name' % name, t['Resources']['WebServer'], stack) self.m.StubOutWithMock(nic, 'neutron') nic.neutron().MultipleTimes().AndReturn(FakeNeutron()) self.m.StubOutWithMock(instance, 'nova') instance.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) nic.t = nic.stack.resolve_runtime_data(nic.t) instance.t = instance.stack.resolve_runtime_data(instance.t) # need to resolve the template functions server_userdata = nova_utils.build_userdata( instance, instance.t['Properties']['UserData'], 'ec2-user') self.m.StubOutWithMock(nova_utils, 'build_userdata') nova_utils.build_userdata( instance, instance.t['Properties']['UserData'], 'ec2-user').AndReturn(server_userdata) self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( image=1, flavor=3, key_name='test', name=utils.PhysName(stack_name, instance.name), security_groups=None, userdata=server_userdata, scheduler_hints=None, meta=None, nics=[{'port-id': '64d913c1-bcb1-42d2-8f0a-9593dbcaf251'}], availability_zone=None).AndReturn( return_server) self.m.ReplayAll() # create network interface scheduler.TaskRunner(nic.create)() stack["nic1"] = nic scheduler.TaskRunner(instance.create)() return instance
def test_default_instance_user(self): """The default value for instance_user in heat.conf is ec2-user.""" return_server = self.fc.servers.list()[1] instance = self._setup_test_instance(return_server, 'default_user') self.m.StubOutWithMock(nova_utils, 'build_userdata') nova_utils.build_userdata(instance, 'wordpress', 'ec2-user') self.m.ReplayAll() scheduler.TaskRunner(instance.create)() self.m.VerifyAll()
def _create_test_instance(self, return_server, name): stack_name = '%s_s' % name t = template_format.parse(wp_template) template = parser.Template(t) kwargs = {'KeyName': 'test', 'InstanceType': 'm1.large', 'SubnetId': '4156c7a5-e8c4-4aff-a6e1-8f3c7bc83861'} stack = parser.Stack(utils.dummy_context(), stack_name, template, environment.Environment(kwargs), stack_id=str(uuid.uuid4())) image_id = 'CentOS 5.2' t['Resources']['WebServer']['Properties']['ImageId'] = image_id resource_defns = stack.t.resource_definitions(stack) instance = instances.Instance('%s_name' % name, resource_defns['WebServer'], stack) self.m.StubOutWithMock(nova.NovaClientPlugin, '_create') nova.NovaClientPlugin._create().AndReturn(self.fc) self._mock_get_image_id_success(image_id, 1) self.m.StubOutWithMock(instance, 'neutron') instance.neutron().MultipleTimes().AndReturn(FakeNeutron()) # need to resolve the template functions server_userdata = nova_utils.build_userdata( instance, instance.t['Properties']['UserData'], 'ec2-user') self.m.StubOutWithMock(nova_utils, 'build_userdata') nova_utils.build_userdata( instance, instance.t['Properties']['UserData'], 'ec2-user').AndReturn(server_userdata) self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( image=1, flavor=3, key_name='test', name=utils.PhysName(stack_name, instance.name), security_groups=None, userdata=server_userdata, scheduler_hints=None, meta=None, nics=[{'port-id': '64d913c1-bcb1-42d2-8f0a-9593dbcaf251'}], availability_zone=None).AndReturn( return_server) self.m.ReplayAll() scheduler.TaskRunner(instance.create)() return instance
def handle_create(self): security_groups = self.properties.get(self.SECURITY_GROUPS) user_data_format = self.properties.get(self.USER_DATA_FORMAT) userdata = nova_utils.build_userdata( self, self.properties.get(self.USER_DATA), instance_user=self.properties[self.ADMIN_USER], user_data_format=user_data_format) flavor = self.properties[self.FLAVOR] availability_zone = self.properties[self.AVAILABILITY_ZONE] key_name = self.properties[self.KEY_NAME] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image = self.properties.get(self.IMAGE) if image: image = nova_utils.get_image_id(self.nova(), image) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) instance_meta = self.properties.get(self.METADATA) if instance_meta is not None: instance_meta = nova_utils.meta_serialize(instance_meta) scheduler_hints = self.properties.get(self.SCHEDULER_HINTS) nics = self._build_nics(self.properties.get(self.NETWORKS)) block_device_mapping = self._build_block_device_mapping( self.properties.get(self.BLOCK_DEVICE_MAPPING)) reservation_id = self.properties.get(self.RESERVATION_ID) config_drive = self.properties.get(self.CONFIG_DRIVE) disk_config = self.properties.get(self.DISK_CONFIG) server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=userdata, meta=instance_meta, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone, block_device_mapping=block_device_mapping, reservation_id=reservation_id, config_drive=config_drive, disk_config=disk_config) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server
def test_nokey_create(self): stack_name = 'instance_create_test_nokey_stack' t = template_format.parse(nokey_template) stack = utils.parse_stack(t, stack_name=stack_name) t['Resources']['WebServer']['Properties']['ImageId'] = 'CentOS 5.2' t['Resources']['WebServer']['Properties']['InstanceType'] = \ '256 MB Server' instance = instances.Instance('create_instance_name', t['Resources']['WebServer'], stack) self.m.StubOutWithMock(instance, 'nova') instance.nova().MultipleTimes().AndReturn(self.fc) instance.t = instance.stack.resolve_runtime_data(instance.t) # need to resolve the template functions server_userdata = nova_utils.build_userdata( instance, instance.t['Properties']['UserData']) instance.mime_string = server_userdata self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( image=1, flavor=1, key_name=None, name=utils.PhysName(stack_name, instance.name), security_groups=None, userdata=server_userdata, scheduler_hints=None, meta=None, nics=None, availability_zone=None).AndReturn( self.fc.servers.list()[1]) self.m.ReplayAll() scheduler.TaskRunner(instance.create)()
def _run_userdata(self): msg = _("Running user_data") self._add_event(self.action, self.status, msg) # Create heat-script and userdata files on server raw_userdata = self.properties[self.USER_DATA] userdata = nova_utils.build_userdata(self, raw_userdata) files = [{'path': "/tmp/userdata", 'data': userdata}, {'path': "/root/heat-script.sh", 'data': self.script}] if self._sftp_files(files) is False: return False # Connect via SSH and run script cmd = "bash -ex /root/heat-script.sh > /root/heat-script.log 2>&1" exit_code = self._run_ssh_command(cmd) if exit_code == 42: raise exception.Error(self.SCRIPT_ERROR_MSG % {'path': "cfn-userdata", 'ip': self.server.accessIPv4, 'log': "/root/cfn-userdata.log"}) elif exit_code != 0: raise exception.Error(self.SCRIPT_ERROR_MSG % {'path': "heat-script.sh", 'ip': self.server.accessIPv4, 'log': "/root/heat-script.log"}) msg = _("Successfully ran user_data") self._add_event(self.action, self.status, msg)
def _setup_test_instance(self, return_server, name, image_id=None): stack_name = '%s_stack' % name (t, stack) = self._setup_test_stack(stack_name) t['Resources']['WebServer']['Properties']['ImageId'] = \ image_id or 'CentOS 5.2' t['Resources']['WebServer']['Properties']['InstanceType'] = \ '256 MB Server' instance = instances.Instance('%s_name' % name, t['Resources']['WebServer'], stack) self.m.StubOutWithMock(instance, 'nova') instance.nova().MultipleTimes().AndReturn(self.fc) instance.t = instance.stack.resolve_runtime_data(instance.t) # need to resolve the template functions server_userdata = nova_utils.build_userdata( instance, instance.t['Properties']['UserData']) instance.mime_string = server_userdata self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( image=1, flavor=1, key_name='test', name=utils.PhysName(stack_name, instance.name), security_groups=None, userdata=server_userdata, scheduler_hints=None, meta=None, nics=None, availability_zone=None).AndReturn( return_server) return instance
def _setup_test_instance(self, intags=None, nova_tags=None): stack_name = 'tag_test' t = template_format.parse(instance_template) template = parser.Template(t) stack = parser.Stack(utils.dummy_context(), stack_name, template, environment.Environment({'KeyName': 'test'}), stack_id=uuidutils.generate_uuid()) t['Resources']['WebServer']['Properties']['Tags'] = intags instance = instances.Instance(stack_name, t['Resources']['WebServer'], stack) self.m.StubOutWithMock(instance, 'nova') instance.nova().MultipleTimes().AndReturn(self.fc) instance.t = instance.stack.resolve_runtime_data(instance.t) # need to resolve the template functions server_userdata = nova_utils.build_userdata( instance, instance.t['Properties']['UserData']) instance.mime_string = server_userdata self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( image=1, flavor=1, key_name='test', name=utils.PhysName(stack_name, instance.name), security_groups=None, userdata=server_userdata, scheduler_hints=None, meta=nova_tags, nics=None, availability_zone=None).AndReturn( self.fc.servers.list()[1]) return instance
def _setup_test_instance(self, return_server, name, image_id=None, stub_create=True): stack_name = "%s_s" % name (t, stack) = self._setup_test_stack(stack_name) t["Resources"]["WebServer"]["Properties"]["ImageId"] = image_id or "CentOS 5.2" t["Resources"]["WebServer"]["Properties"]["InstanceType"] = "256 MB Server" instance = instances.Instance(name, t["Resources"]["WebServer"], stack) self.m.StubOutWithMock(instance, "nova") instance.nova().MultipleTimes().AndReturn(self.fc) instance.t = instance.stack.resolve_runtime_data(instance.t) if stub_create: # need to resolve the template functions server_userdata = nova_utils.build_userdata(instance, instance.t["Properties"]["UserData"]) instance.mime_string = server_userdata self.m.StubOutWithMock(self.fc.servers, "create") self.fc.servers.create( image=1, flavor=1, key_name="test", name=utils.PhysName(stack_name, instance.name, limit=instance.physical_resource_name_limit), security_groups=None, userdata=server_userdata, scheduler_hints=None, meta=None, nics=None, availability_zone=None, ).AndReturn(return_server) return instance
def check_create_complete(self, cookie): """Check if server creation is complete and handle server configs.""" if not self._check_active(cookie): return False if self.has_userdata: # Create heat-script and userdata files on server raw_userdata = self.properties['user_data'] or '' userdata = nova_utils.build_userdata(self, raw_userdata) files = [{'path': "/tmp/userdata", 'data': userdata}, {'path': "/root/heat-script.sh", 'data': self.script}] self._sftp_files(files) # Connect via SSH and run script cmd = "bash -ex /root/heat-script.sh > /root/heat-script.log 2>&1" exit_code = self._run_ssh_command(cmd) if exit_code == 42: raise exception.Error(self.script_error_msg % {'path': "cfn-userdata", 'log': "/root/cfn-userdata.log"}) elif exit_code != 0: raise exception.Error(self.script_error_msg % {'path': "heat-script.sh", 'log': "/root/heat-script.log"}) return True
def test_nokey_create(self): stack_name = 's_nokey' t = template_format.parse(nokey_template) stack = utils.parse_stack(t, stack_name=stack_name) t['Resources']['WebServer']['Properties']['ImageId'] = 'CentOS 5.2' t['Resources']['WebServer']['Properties']['InstanceType'] = \ '256 MB Server' resource_defns = stack.t.resource_definitions(stack) instance = instances.Instance('create_instance_name', resource_defns['WebServer'], stack) self.m.StubOutWithMock(nova.NovaClientPlugin, '_create') nova.NovaClientPlugin._create().AndReturn(self.fc) g_cli_mock = self.m.CreateMockAnything() self.m.StubOutWithMock(clients.OpenStackClients, '_glance') clients.OpenStackClients._glance().MultipleTimes().AndReturn( g_cli_mock) self.m.StubOutWithMock(glance_utils, 'get_image_id') glance_utils.get_image_id(g_cli_mock, 'CentOS 5.2').MultipleTimes().\ AndReturn(1) # need to resolve the template functions server_userdata = nova_utils.build_userdata( instance, instance.t['Properties']['UserData'], 'ec2-user') self.m.StubOutWithMock(nova_utils, 'build_userdata') nova_utils.build_userdata( instance, instance.t['Properties']['UserData'], 'ec2-user').AndReturn(server_userdata) self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( image=1, flavor=1, key_name=None, name=utils.PhysName(stack_name, instance.name), security_groups=None, userdata=server_userdata, scheduler_hints=None, meta=None, nics=None, availability_zone=None).AndReturn( self.fc.servers.list()[1]) self.m.ReplayAll() scheduler.TaskRunner(instance.create)() self.m.VerifyAll()
def test_custom_instance_user(self): """Test instance_user in heat.conf being set to a custom value. Launching the instance should call build_userdata with the custom user name. This option is deprecated and will be removed in Juno. """ return_server = self.fc.servers.list()[1] instance = self._setup_test_instance(return_server, 'custom_user') self.m.StubOutWithMock(instances.cfg.CONF, 'instance_user') instances.cfg.CONF.instance_user = '******' self.m.StubOutWithMock(nova_utils, 'build_userdata') nova_utils.build_userdata(instance, 'wordpress', 'custom_user') self.m.ReplayAll() scheduler.TaskRunner(instance.create)() self.m.VerifyAll()
def test_empty_instance_user(self): """Test instance_user in heat.conf being empty. Launching the instance should call build_userdata with "ec2-user". This behaviour is compatible with CloudFormation and will be the default in Juno once the instance_user option gets removed. """ return_server = self.fc.servers.list()[1] instance = self._setup_test_instance(return_server, 'empty_user') self.m.StubOutWithMock(instances.cfg.CONF, 'instance_user') instances.cfg.CONF.instance_user = '' self.m.StubOutWithMock(nova_utils, 'build_userdata') nova_utils.build_userdata(instance, 'wordpress', 'ec2-user') self.m.ReplayAll() scheduler.TaskRunner(instance.create)() self.m.VerifyAll()
def _setup_test_instance(self, intags=None, nova_tags=None): stack_name = "tag_test" t = template_format.parse(instance_template) template = parser.Template(t) stack = parser.Stack( utils.dummy_context(), stack_name, template, environment.Environment({"KeyName": "test"}), stack_id=str(uuid.uuid4()), ) t["Resources"]["WebServer"]["Properties"]["Tags"] = intags instance = instances.Instance(stack_name, t["Resources"]["WebServer"], stack) self.m.StubOutWithMock(instance, "nova") instance.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, "nova") clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) instance.t = instance.stack.resolve_runtime_data(instance.t) # need to resolve the template functions server_userdata = nova_utils.build_userdata(instance, instance.t["Properties"]["UserData"]) self.m.StubOutWithMock(nova_utils, "build_userdata") nova_utils.build_userdata(instance, instance.t["Properties"]["UserData"]).AndReturn(server_userdata) self.m.StubOutWithMock(self.fc.servers, "create") self.fc.servers.create( image=1, flavor=1, key_name="test", name=utils.PhysName(stack_name, instance.name), security_groups=None, userdata=server_userdata, scheduler_hints=None, meta=nova_tags, nics=None, availability_zone=None, ).AndReturn(self.fc.servers.list()[1]) return instance
def handle_create(self): security_groups = self._get_security_groups() userdata = self.properties[self.USER_DATA] or '' flavor = self.properties[self.INSTANCE_TYPE] availability_zone = self.properties[self.AVAILABILITY_ZONE] image_name = self.properties[self.IMAGE_ID] image_id = nova_utils.get_image_id(self.nova(), image_name) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) scheduler_hints = {} if self.properties[self.NOVA_SCHEDULER_HINTS]: for tm in self.properties[self.NOVA_SCHEDULER_HINTS]: scheduler_hints[tm[self.TAG_KEY]] = tm[self.TAG_VALUE] else: scheduler_hints = None nics = self._build_nics(self.properties[self.NETWORK_INTERFACES], security_groups=security_groups, subnet_id=self.properties[self.SUBNET_ID]) server = None # FIXME(shadower): the instance_user config option is deprecated. Once # it's gone, we should always use ec2-user for compatibility with # CloudFormation. if cfg.CONF.instance_user: instance_user = cfg.CONF.instance_user else: instance_user = '******' try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image_id, flavor=flavor_id, key_name=self.properties[self.KEY_NAME], security_groups=security_groups, userdata=nova_utils.build_userdata(self, userdata, instance_user), meta=self._get_nova_metadata(self.properties), scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server, scheduler.TaskRunner(self._attach_volumes_task())
def _setup_test_instance(self, intags=None, nova_tags=None): stack_name = 'tag_test' t = template_format.parse(instance_template) template = parser.Template(t) stack = parser.Stack(utils.dummy_context(), stack_name, template, environment.Environment({'KeyName': 'test'}), stack_id=str(uuid.uuid4())) t['Resources']['WebServer']['Properties']['Tags'] = intags resource_defns = template.resource_definitions(stack) instance = instances.Instance(stack_name, resource_defns['WebServer'], stack) self.m.StubOutWithMock(instance, 'nova') instance.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) self._mock_get_image_id_success('CentOS 5.2', 1) # need to resolve the template functions server_userdata = nova_utils.build_userdata( instance, instance.t['Properties']['UserData'], 'ec2-user') self.m.StubOutWithMock(nova_utils, 'build_userdata') nova_utils.build_userdata( instance, instance.t['Properties']['UserData'], 'ec2-user').AndReturn(server_userdata) self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( image=1, flavor=1, key_name='test', name=utils.PhysName(stack_name, instance.name), security_groups=None, userdata=server_userdata, scheduler_hints=None, meta=nova_tags, nics=None, availability_zone=None).AndReturn( self.fc.servers.list()[1]) return instance
def test_build_userdata_with_instance_user(self): """Add the custom instance user when requested.""" resource = self.m.CreateMockAnything() resource.metadata = {} self.m.StubOutWithMock(nova_utils.cfg, "CONF") cnf = nova_utils.cfg.CONF cnf.instance_user = "******" cnf.heat_metadata_server_url = "http://server.test:123" cnf.heat_watch_server_url = "http://server.test:345" self.m.ReplayAll() data = nova_utils.build_userdata(resource, instance_user="******") self.assertNotIn("config_instance_user", data) self.assertIn("custominstanceuser", data) self.m.VerifyAll()
def handle_create(self): security_groups = self._get_security_groups() userdata = self.properties[self.USER_DATA] or '' flavor = self.properties[self.INSTANCE_TYPE] availability_zone = self.properties[self.AVAILABILITY_ZONE] key_name = self.properties[self.KEY_NAME] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image_name = self.properties[self.IMAGE_ID] image_id = nova_utils.get_image_id(self.nova(), image_name) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) scheduler_hints = {} if self.properties[self.NOVA_SCHEDULER_HINTS]: for tm in self.properties[self.NOVA_SCHEDULER_HINTS]: scheduler_hints[tm[self.TAG_KEY]] = tm[self.TAG_VALUE] else: scheduler_hints = None nics = self._build_nics(self.properties[self.NETWORK_INTERFACES], security_groups=security_groups, subnet_id=self.properties[self.SUBNET_ID]) server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image_id, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=nova_utils.build_userdata(self, userdata), meta=self._get_nova_metadata(self.properties), scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server, scheduler.TaskRunner(self._attach_volumes_task())
def handle_create(self): security_groups = self._get_security_groups() userdata = self.properties['UserData'] or '' flavor = self.properties['InstanceType'] availability_zone = self.properties['AvailabilityZone'] key_name = self.properties['KeyName'] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image_name = self.properties['ImageId'] image_id = nova_utils.get_image_id(self.nova(), image_name) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) scheduler_hints = {} if self.properties['NovaSchedulerHints']: for tm in self.properties['NovaSchedulerHints']: scheduler_hints[tm['Key']] = tm['Value'] else: scheduler_hints = None nics = self._build_nics(self.properties['NetworkInterfaces'], security_groups=security_groups, subnet_id=self.properties['SubnetId']) server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image_id, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=nova_utils.build_userdata(self, userdata), meta=self._get_nova_metadata(self.properties), scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server, scheduler.TaskRunner(self._attach_volumes_task())
def test_build_userdata_without_instance_user(self): """Don't add a custom instance user when not requested.""" resource = self.m.CreateMockAnything() resource.metadata = {} self.m.StubOutWithMock(nova_utils.cfg, 'CONF') cnf = nova_utils.cfg.CONF cnf.instance_user = '******' cnf.heat_metadata_server_url = 'http://server.test:123' cnf.heat_watch_server_url = 'http://server.test:345' self.m.ReplayAll() data = nova_utils.build_userdata(resource, instance_user=None) self.assertNotIn('user: '******'useradd', data) self.assertNotIn('config_instance_user', data) self.m.VerifyAll()
def _run_userdata(self): # Create heat-script and userdata files on server raw_userdata = self.properties[self.USER_DATA] userdata = nova_utils.build_userdata(self, raw_userdata) files = [{"path": "/tmp/userdata", "data": userdata}, {"path": "/root/heat-script.sh", "data": self.script}] self._sftp_files(files) # Connect via SSH and run script cmd = "bash -ex /root/heat-script.sh > /root/heat-script.log 2>&1" exit_code = self._run_ssh_command(cmd) if exit_code == 42: raise exception.Error(self.SCRIPT_ERROR_MSG % {"path": "cfn-userdata", "log": "/root/cfn-userdata.log"}) elif exit_code != 0: raise exception.Error(self.SCRIPT_ERROR_MSG % {"path": "heat-script.sh", "log": "/root/heat-script.log"})
def test_build_userdata_with_instance_user(self): """Add the custom instance user when requested.""" resource = self.m.CreateMockAnything() resource.metadata_get().AndReturn(None) self.m.StubOutWithMock(nova_utils.cfg, 'CONF') cnf = nova_utils.cfg.CONF cnf.instance_user = '******' cnf.heat_metadata_server_url = 'http://server.test:123' cnf.heat_watch_server_url = 'http://server.test:345' self.m.ReplayAll() data = nova_utils.build_userdata(resource, instance_user="******") self.assertNotIn('config_instance_user', data) self.assertIn("custominstanceuser", data) self.m.VerifyAll()
def handle_create(self): security_groups = self._get_security_groups() userdata = self.properties[self.USER_DATA] or '' flavor = self.properties[self.INSTANCE_TYPE] availability_zone = self.properties[self.AVAILABILITY_ZONE] image_name = self.properties[self.IMAGE_ID] image_id = nova_utils.get_image_id(self.nova(), image_name) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) scheduler_hints = {} if self.properties[self.NOVA_SCHEDULER_HINTS]: for tm in self.properties[self.NOVA_SCHEDULER_HINTS]: scheduler_hints[tm[self.TAG_KEY]] = tm[self.TAG_VALUE] else: scheduler_hints = None nics = self._build_nics(self.properties[self.NETWORK_INTERFACES], security_groups=security_groups, subnet_id=self.properties[self.SUBNET_ID]) server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image_id, flavor=flavor_id, key_name=self.properties[self.KEY_NAME], security_groups=security_groups, userdata=nova_utils.build_userdata(self, userdata), meta=self._get_nova_metadata(self.properties), scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server, scheduler.TaskRunner(self._attach_volumes_task())
def check_create_complete(self, cookie): """Check if server creation is complete and handle server configs.""" if not self._check_active(cookie): return False if self.has_userdata: # Create heat-script and userdata files on server raw_userdata = self.properties['user_data'] or '' userdata = nova_utils.build_userdata(self, raw_userdata) files = [{'path': "/tmp/userdata", 'data': userdata}, {'path': "/root/heat-script.sh", 'data': self.script}] self._sftp_files(files) # Connect via SSH and run script cmd = "bash -ex /root/heat-script.sh > /root/heat-script.log 2>&1" self._run_ssh_command(cmd) return True
def _setup_test_instance(self, return_server, name, image_id=None, stub_create=True): stack_name = '%s_s' % name (t, stack) = self._setup_test_stack(stack_name) t['Resources']['WebServer']['Properties']['ImageId'] = \ image_id or 'CentOS 5.2' t['Resources']['WebServer']['Properties']['InstanceType'] = \ '256 MB Server' instance = instances.Instance(name, t['Resources']['WebServer'], stack) self.m.StubOutWithMock(instance, 'nova') instance.nova().MultipleTimes().AndReturn(self.fc) instance.t = instance.stack.resolve_runtime_data(instance.t) if stub_create: # need to resolve the template functions server_userdata = nova_utils.build_userdata( instance, instance.t['Properties']['UserData']) instance.mime_string = server_userdata self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create( image=1, flavor=1, key_name='test', name=utils.PhysName( stack_name, instance.name, limit=instance.physical_resource_name_limit), security_groups=None, userdata=server_userdata, scheduler_hints=None, meta=None, nics=None, availability_zone=None).AndReturn(return_server) return instance
def test_build_userdata(self): """Tests the build_userdata function.""" resource = self.m.CreateMockAnything() resource.metadata_get().AndReturn({}) self.m.StubOutWithMock(nova_utils.cfg, 'CONF') cnf = nova_utils.cfg.CONF cnf.heat_metadata_server_url = 'http://server.test:123' cnf.heat_watch_server_url = 'http://server.test:345' cnf.instance_connection_is_secure = False cnf.instance_connection_https_validate_certificates = False self.m.ReplayAll() data = nova_utils.build_userdata(resource) self.assertIn("Content-Type: text/cloud-config;", data) self.assertIn("Content-Type: text/cloud-boothook;", data) self.assertIn("Content-Type: text/part-handler;", data) self.assertIn("Content-Type: text/x-cfninitdata;", data) self.assertIn("Content-Type: text/x-shellscript;", data) self.assertIn("http://server.test:345", data) self.assertIn("http://server.test:123", data) self.assertIn("[Boto]", data) self.m.VerifyAll()
def test_build_userdata(self): """Tests the build_userdata function.""" resource = self.m.CreateMockAnything() resource.metadata = {} self.m.StubOutWithMock(nova_utils.cfg, 'CONF') cnf = nova_utils.cfg.CONF cnf.heat_metadata_server_url = 'http://server.test:123' cnf.heat_watch_server_url = 'http://server.test:345' cnf.instance_connection_is_secure = False cnf.instance_connection_https_validate_certificates = False self.m.ReplayAll() data = nova_utils.build_userdata(resource) self.assertIn("Content-Type: text/cloud-config;", data) self.assertIn("Content-Type: text/cloud-boothook;", data) self.assertIn("Content-Type: text/part-handler;", data) self.assertIn("Content-Type: text/x-cfninitdata;", data) self.assertIn("Content-Type: text/x-shellscript;", data) self.assertIn("http://server.test:345", data) self.assertIn("http://server.test:123", data) self.assertIn("[Boto]", data) self.m.VerifyAll()
def _run_userdata(self): msg = _("Running user_data") self._add_event(self.action, self.status, msg) # Create heat-script and userdata files on server raw_userdata = self.properties[self.USER_DATA] userdata = nova_utils.build_userdata(self, raw_userdata) files = [{ 'path': "/tmp/userdata", 'data': userdata }, { 'path': "/root/heat-script.sh", 'data': self.script }] if self._sftp_files(files) is False: return False # Connect via SSH and run script cmd = "bash -ex /root/heat-script.sh > /root/heat-script.log 2>&1" exit_code = self._run_ssh_command(cmd) if exit_code == 42: raise exception.Error( self.SCRIPT_ERROR_MSG % { 'path': "cfn-userdata", 'ip': self.server.accessIPv4, 'log': "/root/cfn-userdata.log" }) elif exit_code != 0: raise exception.Error( self.SCRIPT_ERROR_MSG % { 'path': "heat-script.sh", 'ip': self.server.accessIPv4, 'log': "/root/heat-script.log" }) msg = _("Successfully ran user_data") self._add_event(self.action, self.status, msg)
def _setup_test_instance(self, intags=None, nova_tags=None): stack_name = 'tag_test' t = template_format.parse(instance_template) template = parser.Template(t) stack = parser.Stack(utils.dummy_context(), stack_name, template, environment.Environment({'KeyName': 'test'}), stack_id=uuidutils.generate_uuid()) t['Resources']['WebServer']['Properties']['Tags'] = intags instance = instances.Instance(stack_name, t['Resources']['WebServer'], stack) self.m.StubOutWithMock(instance, 'nova') instance.nova().MultipleTimes().AndReturn(self.fc) instance.t = instance.stack.resolve_runtime_data(instance.t) # need to resolve the template functions server_userdata = nova_utils.build_userdata( instance, instance.t['Properties']['UserData']) instance.mime_string = server_userdata self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create(image=1, flavor=1, key_name='test', name=utils.PhysName(stack_name, instance.name), security_groups=None, userdata=server_userdata, scheduler_hints=None, meta=nova_tags, nics=None, availability_zone=None).AndReturn( self.fc.servers.list()[1]) return instance
def test_nokey_create(self): stack_name = 's_nokey' t = template_format.parse(nokey_template) stack = utils.parse_stack(t, stack_name=stack_name) t['Resources']['WebServer']['Properties']['ImageId'] = 'CentOS 5.2' t['Resources']['WebServer']['Properties']['InstanceType'] = \ '256 MB Server' instance = instances.Instance('create_instance_name', t['Resources']['WebServer'], stack) self.m.StubOutWithMock(instance, 'nova') instance.nova().MultipleTimes().AndReturn(self.fc) instance.t = instance.stack.resolve_runtime_data(instance.t) # need to resolve the template functions server_userdata = nova_utils.build_userdata( instance, instance.t['Properties']['UserData']) instance.mime_string = server_userdata self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create(image=1, flavor=1, key_name=None, name=utils.PhysName(stack_name, instance.name), security_groups=None, userdata=server_userdata, scheduler_hints=None, meta=None, nics=None, availability_zone=None).AndReturn( self.fc.servers.list()[1]) self.m.ReplayAll() scheduler.TaskRunner(instance.create)()
def handle_create(self): security_groups = self.properties.get(self.SECURITY_GROUPS) user_data_format = self.properties.get(self.USER_DATA_FORMAT) ud_content = self.properties.get(self.USER_DATA) if self.user_data_software_config() or self.user_data_raw(): if uuidutils.is_uuid_like(ud_content): # attempt to load the userdata from software config try: ud_content = sc.SoftwareConfig.get_software_config( self.heat(), ud_content) except exception.SoftwareConfigMissing: # no config was found, so do not modify the user_data pass if self.user_data_software_config(): self._create_transport_credentials() if self.properties[self.ADMIN_USER]: instance_user = self.properties[self.ADMIN_USER] elif cfg.CONF.instance_user: instance_user = cfg.CONF.instance_user else: instance_user = None userdata = nova_utils.build_userdata(self, ud_content, instance_user=instance_user, user_data_format=user_data_format) flavor = self.properties[self.FLAVOR] availability_zone = self.properties[self.AVAILABILITY_ZONE] image = self.properties.get(self.IMAGE) if image: image = nova_utils.get_image_id(self.nova(), image) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) instance_meta = self.properties.get(self.METADATA) if instance_meta is not None: instance_meta = nova_utils.meta_serialize(instance_meta) scheduler_hints = self.properties.get(self.SCHEDULER_HINTS) nics = self._build_nics(self.properties.get(self.NETWORKS)) block_device_mapping = self._build_block_device_mapping( self.properties.get(self.BLOCK_DEVICE_MAPPING)) reservation_id = self.properties.get(self.RESERVATION_ID) config_drive = self.properties.get(self.CONFIG_DRIVE) disk_config = self.properties.get(self.DISK_CONFIG) admin_pass = self.properties.get(self.ADMIN_PASS) or None server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image, flavor=flavor_id, key_name=self._key_name(), security_groups=security_groups, userdata=userdata, meta=instance_meta, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone, block_device_mapping=block_device_mapping, reservation_id=reservation_id, config_drive=config_drive, disk_config=disk_config, files=self._personality(), admin_pass=admin_pass) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server
def handle_create(self): security_groups = self.properties.get(self.SECURITY_GROUPS) user_data_format = self.properties.get(self.USER_DATA_FORMAT) ud_content = self.properties.get(self.USER_DATA) if self.user_data_software_config() or self.user_data_raw(): if uuidutils.is_uuid_like(ud_content): # attempt to load the userdata from software config try: ud_content = sc.SoftwareConfig.get_software_config( self.heat(), ud_content) except exception.SoftwareConfigMissing: # no config was found, so do not modify the user_data pass if self.user_data_software_config(): self._create_transport_credentials() self._populate_deployments_metadata() if self.properties[self.ADMIN_USER]: instance_user = self.properties[self.ADMIN_USER] elif cfg.CONF.instance_user: instance_user = cfg.CONF.instance_user else: instance_user = None userdata = nova_utils.build_userdata( self, ud_content, instance_user=instance_user, user_data_format=user_data_format) flavor = self.properties[self.FLAVOR] availability_zone = self.properties[self.AVAILABILITY_ZONE] image = self.properties.get(self.IMAGE) if image: image = self.client_plugin('glance').get_image_id(image) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) instance_meta = self.properties.get(self.METADATA) if instance_meta is not None: instance_meta = nova_utils.meta_serialize(instance_meta) scheduler_hints = self.properties.get(self.SCHEDULER_HINTS) nics = self._build_nics(self.properties.get(self.NETWORKS)) block_device_mapping = self._build_block_device_mapping( self.properties.get(self.BLOCK_DEVICE_MAPPING)) reservation_id = self.properties.get(self.RESERVATION_ID) disk_config = self.properties.get(self.DISK_CONFIG) admin_pass = self.properties.get(self.ADMIN_PASS) or None personality_files = self.properties.get(self.PERSONALITY) key_name = self.properties.get(self.KEY_NAME) server = None try: server = self.nova().servers.create( name=self._server_name(), image=image, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=userdata, meta=instance_meta, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone, block_device_mapping=block_device_mapping, reservation_id=reservation_id, config_drive=self._config_drive(), disk_config=disk_config, files=personality_files, admin_pass=admin_pass) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server
def _create_test_instance_with_nic(self, return_server, name): stack_name = '%s_s' % name t = template_format.parse(wp_template_with_nic) template = parser.Template(t) kwargs = { 'KeyName': 'test', 'InstanceType': 'm1.large', 'SubnetId': '4156c7a5-e8c4-4aff-a6e1-8f3c7bc83861' } stack = parser.Stack(utils.dummy_context(), stack_name, template, environment.Environment(kwargs), stack_id=str(uuid.uuid4())) t['Resources']['WebServer']['Properties']['ImageId'] = 'CentOS 5.2' nic = network_interfaces.NetworkInterface('%s_nic' % name, t['Resources']['nic1'], stack) instance = instances.Instance('%s_name' % name, t['Resources']['WebServer'], stack) self.m.StubOutWithMock(nic, 'neutron') nic.neutron().MultipleTimes().AndReturn(FakeNeutron()) self.m.StubOutWithMock(instance, 'nova') instance.nova().MultipleTimes().AndReturn(self.fc) self.m.StubOutWithMock(clients.OpenStackClients, 'nova') clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) nic.t = nic.stack.resolve_runtime_data(nic.t) instance.t = instance.stack.resolve_runtime_data(instance.t) # need to resolve the template functions server_userdata = nova_utils.build_userdata( instance, instance.t['Properties']['UserData']) self.m.StubOutWithMock(nova_utils, 'build_userdata') nova_utils.build_userdata( instance, instance.t['Properties']['UserData']).AndReturn(server_userdata) self.m.StubOutWithMock(self.fc.servers, 'create') self.fc.servers.create(image=1, flavor=3, key_name='test', name=utils.PhysName(stack_name, instance.name), security_groups=None, userdata=server_userdata, scheduler_hints=None, meta=None, nics=[{ 'port-id': '64d913c1-bcb1-42d2-8f0a-9593dbcaf251' }], availability_zone=None).AndReturn(return_server) self.m.ReplayAll() # create network interface scheduler.TaskRunner(nic.create)() stack["nic1"] = nic scheduler.TaskRunner(instance.create)() return instance
def handle_create(self): security_groups = self.properties.get(self.SECURITY_GROUPS) user_data_format = self.properties.get(self.USER_DATA_FORMAT) userdata = nova_utils.build_userdata( self, self.properties.get(self.USER_DATA), instance_user=self.properties[self.ADMIN_USER], user_data_format=user_data_format) flavor = self.properties[self.FLAVOR] availability_zone = self.properties[self.AVAILABILITY_ZONE] key_name = self.properties[self.KEY_NAME] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image = self.properties.get(self.IMAGE) if image: image = nova_utils.get_image_id(self.nova(), image) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) instance_meta = self.properties.get(self.METADATA) if instance_meta is not None: instance_meta = nova_utils.meta_serialize(instance_meta) scheduler_hints = self.properties.get(self.SCHEDULER_HINTS) nics = self._build_nics(self.properties.get(self.NETWORKS)) block_device_mapping = self._build_block_device_mapping( self.properties.get(self.BLOCK_DEVICE_MAPPING)) reservation_id = self.properties.get(self.RESERVATION_ID) config_drive = self.properties.get(self.CONFIG_DRIVE) disk_config = self.properties.get(self.DISK_CONFIG) server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=userdata, meta=instance_meta, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone, block_device_mapping=block_device_mapping, reservation_id=reservation_id, config_drive=config_drive, disk_config=disk_config, files=self._personality()) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server
def handle_create(self): security_groups = self._get_security_groups() userdata = self.properties[self.USER_DATA] or '' flavor = self.properties[self.INSTANCE_TYPE] availability_zone = self.properties[self.AVAILABILITY_ZONE] image_name = self.properties[self.IMAGE_ID] image_id = nova_utils.get_image_id(self.nova(), image_name) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) scheduler_hints = {} if self.properties[self.NOVA_SCHEDULER_HINTS]: for tm in self.properties[self.NOVA_SCHEDULER_HINTS]: # adopted from novaclient shell hint = tm[self.TAG_KEY] hint_value = tm[self.TAG_VALUE] if hint in scheduler_hints: if isinstance(scheduler_hints[hint], six.string_types): scheduler_hints[hint] = [scheduler_hints[hint]] scheduler_hints[hint].append(hint_value) else: scheduler_hints[hint] = hint_value else: scheduler_hints = None nics = self._build_nics(self.properties[self.NETWORK_INTERFACES], security_groups=security_groups, subnet_id=self.properties[self.SUBNET_ID]) server = None # FIXME(shadower): the instance_user config option is deprecated. Once # it's gone, we should always use ec2-user for compatibility with # CloudFormation. if cfg.CONF.instance_user: instance_user = cfg.CONF.instance_user else: instance_user = '******' try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image_id, flavor=flavor_id, key_name=self.properties[self.KEY_NAME], security_groups=security_groups, userdata=nova_utils.build_userdata(self, userdata, instance_user), meta=self._get_nova_metadata(self.properties), scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server, scheduler.TaskRunner(self._attach_volumes_task())
def get_mime_string(self, userdata): if not self.mime_string: self.mime_string = nova_utils.build_userdata( self, userdata, instance_user=self.properties['admin_user']) return self.mime_string
def handle_create(self): security_groups = self.properties.get('security_groups') user_data_format = self.properties.get('user_data_format') userdata = nova_utils.build_userdata( self, self.properties.get('user_data'), instance_user=self.properties['admin_user'], user_data_format=user_data_format) flavor = self.properties['flavor'] availability_zone = self.properties['availability_zone'] key_name = self.properties['key_name'] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image = self.properties.get('image') if image: image = nova_utils.get_image_id(self.nova(), image) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) instance_meta = self.properties.get('metadata') if instance_meta is not None: instance_meta = dict((key, str(value)) for (key, value) in instance_meta.items()) scheduler_hints = self.properties.get('scheduler_hints') nics = self._build_nics(self.properties.get('networks')) block_device_mapping = self._build_block_device_mapping( self.properties.get('block_device_mapping')) reservation_id = self.properties.get('reservation_id') config_drive = self.properties.get('config_drive') disk_config = self.properties.get('diskConfig') server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=userdata, meta=instance_meta, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone, block_device_mapping=block_device_mapping, reservation_id=reservation_id, config_drive=config_drive, disk_config=disk_config) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server
def check_create_complete(self, cookie): """Check if server creation is complete and handle server configs.""" if not self._check_active(cookie): return False server = cookie[0] if 'rack_connect' in self.context.roles: # Account has RackConnect if 'rackconnect_automation_status' not in server.metadata: logger.debug("RackConnect server does not have the " "rackconnect_automation_status metadata tag yet") return False rc_status = server.metadata['rackconnect_automation_status'] logger.debug("RackConnect automation status: " + rc_status) if rc_status == 'DEPLOYING': return False elif rc_status == 'DEPLOYED': self._public_ip = None # The public IP changed, forget old one elif rc_status == 'FAILED': raise exception.Error("RackConnect automation FAILED") elif rc_status == 'UNPROCESSABLE': reason = server.metadata.get( "rackconnect_unprocessable_reason", None) if reason is not None: logger.warning("RackConnect unprocessable reason: " + reason) # UNPROCESSABLE means the RackConnect automation was # not attempted (eg. Cloud Server in a different DC # than dedicated gear, so RackConnect does not apply). # It is okay if we do not raise an exception. else: raise exception.Error("Unknown RackConnect automation status: " + rc_status) if self.has_userdata: # Create heat-script and userdata files on server raw_userdata = self.properties['user_data'] or '' userdata = nova_utils.build_userdata(self, raw_userdata) files = [{'path': "/tmp/userdata", 'data': userdata}, {'path': "/root/heat-script.sh", 'data': self.script}] self._sftp_files(files) # Connect via SSH and run script cmd = "bash -ex /root/heat-script.sh > /root/heat-script.log 2>&1" exit_code = self._run_ssh_command(cmd) if exit_code == 42: raise exception.Error(self.script_error_msg % {'path': "cfn-userdata", 'log': "/root/cfn-userdata.log"}) elif exit_code != 0: raise exception.Error(self.script_error_msg % {'path': "heat-script.sh", 'log': "/root/heat-script.log"}) return True
def get_mime_string(self, userdata): if not self.mime_string: self.mime_string = nova_utils.build_userdata(self, userdata) return self.mime_string
def check_create_complete(self, cookie): """Check if server creation is complete and handle server configs.""" if not self._check_active(cookie): return False server = cookie[0] server.get() if "rack_connect" in self.context.roles: # Account has RackConnect if "rackconnect_automation_status" not in server.metadata: logger.debug("RackConnect server does not have the " "rackconnect_automation_status metadata tag yet") return False rc_status = server.metadata["rackconnect_automation_status"] logger.debug("RackConnect automation status: " + rc_status) if rc_status == "DEPLOYING": return False elif rc_status == "DEPLOYED": self._public_ip = None # The public IP changed, forget old one elif rc_status == "FAILED": raise exception.Error("RackConnect automation FAILED") elif rc_status == "UNPROCESSABLE": reason = server.metadata.get("rackconnect_unprocessable_reason", None) if reason is not None: logger.warning("RackConnect unprocessable reason: " + reason) # UNPROCESSABLE means the RackConnect automation was # not attempted (eg. Cloud Server in a different DC # than dedicated gear, so RackConnect does not apply). # It is okay if we do not raise an exception. else: raise exception.Error("Unknown RackConnect automation status: " + rc_status) if "rax_managed" in self.context.roles: # Managed Cloud account if "rax_service_level_automation" not in server.metadata: logger.debug("Managed Cloud server does not have the " "rax_service_level_automation metadata tag yet") return False mc_status = server.metadata["rax_service_level_automation"] logger.debug("Managed Cloud automation status: " + mc_status) if mc_status == "In Progress": return False elif mc_status == "Complete": pass elif mc_status == "Build Error": raise exception.Error("Managed Cloud automation failed") else: raise exception.Error("Unknown Managed Cloud automation " "status: " + mc_status) if self.has_userdata: # Create heat-script and userdata files on server raw_userdata = self.properties["user_data"] or "" userdata = nova_utils.build_userdata(self, raw_userdata) files = [{"path": "/tmp/userdata", "data": userdata}, {"path": "/root/heat-script.sh", "data": self.script}] self._sftp_files(files) # Connect via SSH and run script cmd = "bash -ex /root/heat-script.sh > /root/heat-script.log 2>&1" exit_code = self._run_ssh_command(cmd) if exit_code == 42: raise exception.Error(self.script_error_msg % {"path": "cfn-userdata", "log": "/root/cfn-userdata.log"}) elif exit_code != 0: raise exception.Error( self.script_error_msg % {"path": "heat-script.sh", "log": "/root/heat-script.log"} ) return True
def check_create_complete(self, cookie): """Check if server creation is complete and handle server configs.""" if not self._check_active(cookie): return False server = cookie[0] server.get() if 'rack_connect' in self.context.roles: # Account has RackConnect if 'rackconnect_automation_status' not in server.metadata: logger.debug("RackConnect server does not have the " "rackconnect_automation_status metadata tag yet") return False rc_status = server.metadata['rackconnect_automation_status'] logger.debug("RackConnect automation status: " + rc_status) if rc_status == 'DEPLOYING': return False elif rc_status == 'DEPLOYED': self._public_ip = None # The public IP changed, forget old one elif rc_status == 'FAILED': raise exception.Error("RackConnect automation FAILED") elif rc_status == 'UNPROCESSABLE': reason = server.metadata.get( "rackconnect_unprocessable_reason", None) if reason is not None: logger.warning("RackConnect unprocessable reason: " + reason) # UNPROCESSABLE means the RackConnect automation was # not attempted (eg. Cloud Server in a different DC # than dedicated gear, so RackConnect does not apply). # It is okay if we do not raise an exception. else: raise exception.Error( "Unknown RackConnect automation status: " + rc_status) if 'rax_managed' in self.context.roles: # Managed Cloud account if 'rax_service_level_automation' not in server.metadata: logger.debug("Managed Cloud server does not have the " "rax_service_level_automation metadata tag yet") return False mc_status = server.metadata['rax_service_level_automation'] logger.debug("Managed Cloud automation status: " + mc_status) if mc_status == 'In Progress': return False elif mc_status == 'Complete': pass elif mc_status == 'Build Error': raise exception.Error("Managed Cloud automation failed") else: raise exception.Error("Unknown Managed Cloud automation " "status: " + mc_status) if self.has_userdata: # Create heat-script and userdata files on server raw_userdata = self.properties['user_data'] or '' userdata = nova_utils.build_userdata(self, raw_userdata) files = [{ 'path': "/tmp/userdata", 'data': userdata }, { 'path': "/root/heat-script.sh", 'data': self.script }] self._sftp_files(files) # Connect via SSH and run script cmd = "bash -ex /root/heat-script.sh > /root/heat-script.log 2>&1" exit_code = self._run_ssh_command(cmd) if exit_code == 42: raise exception.Error(self.script_error_msg % { 'path': "cfn-userdata", 'log': "/root/cfn-userdata.log" }) elif exit_code != 0: raise exception.Error(self.script_error_msg % { 'path': "heat-script.sh", 'log': "/root/heat-script.log" }) return True