def test___create_allow_all_security_group_if_needed(self): bcc = BaseCloudConnector(self._getMockedConfigHolder()) bcc._create_allow_all_security_group = Mock() nis = { 'comp.1': NodeInstance({ NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.' + NodeDecorator.SECURITY_GROUPS_KEY: 'foo, bar' }) } bcc._BaseCloudConnector__create_allow_all_security_group_if_needed(nis) assert not bcc._create_allow_all_security_group.called nis.update({ 'comp.2': NodeInstance({ NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.' + NodeDecorator.SECURITY_GROUPS_KEY: 'foo, ' + NodeDecorator.SECURITY_GROUP_ALLOW_ALL_NAME }) }) bcc._BaseCloudConnector__create_allow_all_security_group_if_needed(nis) assert bcc._create_allow_all_security_group.called
def test_no_scaling(self): """ No scaling is happening. Node instances are in terminal states. """ node_instances = { 'n.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.1', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_OPERATIONAL }), 'm.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.1', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_GONE }) } cw = CloudWrapper(self.config_holder) cw._get_nodes_instances = Mock(return_value=node_instances) assert {} == cw._get_effective_scale_states() assert None == cw._get_global_scale_state() assert False == cw.is_vertical_scaling() node_and_instances = cw.get_scaling_node_and_instance_names() assert '' == node_and_instances[0] assert [] == node_and_instances[1]
def test_wait_scale_state(self): node_instances = [ NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.1'}), NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.2'}), NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.3'}), NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.1'}) ] cw = CloudWrapper(self.config_holder) # All set before timeout. cw._get_effective_scale_state = Mock( return_value=CloudWrapper.SCALE_STATE_RESIZED) cw._get_state_timeout_time = Mock(return_value=(time.time() + 5)) cw._wait_scale_state(CloudWrapper.SCALE_STATE_RESIZED, node_instances) # Timeout is in the past. cw._get_effective_scale_state = Mock( return_value=CloudWrapper.SCALE_STATE_RESIZED) cw._get_state_timeout_time = Mock(return_value=(time.time() - 1)) self.failUnlessRaises( TimeoutException, cw._wait_scale_state, *(CloudWrapper.SCALE_STATE_RESIZED, node_instances)) # VMs do not set proper value and we timeout. cw._get_effective_scale_state = Mock( return_value=CloudWrapper.SCALE_STATE_RESIZING) cw._get_state_timeout_time = Mock(return_value=(time.time() + 2)) self.failUnlessRaises( TimeoutException, cw._wait_scale_state, *(CloudWrapper.SCALE_STATE_RESIZED, node_instances))
def setUp(self): os.environ['SLIPSTREAM_CONNECTOR_INSTANCE'] = 'physicalhost' os.environ['SLIPSTREAM_BOOTSTRAP_BIN'] = 'http://example.com/bootstrap' os.environ['SLIPSTREAM_DIID'] = '00000000-0000-0000-0000-000000000000' if not os.path.exists(CONFIG_FILE): raise Exception('Configuration file %s not found.' % CONFIG_FILE) self.ch = ConfigHolder(configFile=CONFIG_FILE, context={'foo': 'bar'}) os.environ['PHYSICALHOST_ORCHESTRATOR_HOST'] = self.ch.config[ 'PHYSICALHOST_ORCHESTRATOR_HOST'] self.client = PhysicalHostClientCloud(self.ch) self.user_info = UserInfo('physicalhost') self.user_info['physicalhost.private.key'] = self.ch.config[ 'physicalhost.private.key'] self.user_info['physicalhost.password'] = self.ch.config[ 'physicalhost.password'] self.user_info['physicalhost.username'] = self.ch.config[ 'physicalhost.username'] hosta = self.ch.config['physicalhost.hosta'] hostb = self.ch.config['physicalhost.hostb'] node_instance_name_a = 'test_node_a' node_instance_name_b = 'test_node_b' self.node_instances = {} self.node_instances[node_instance_name_a] = NodeInstance({ 'name': node_instance_name_a, 'cloudservice': 'physicalhost', 'image.platform': 'Ubuntu', 'image.imageId': hosta, 'image.id': hosta, 'network': 'private', }) self.node_instances[node_instance_name_b] = NodeInstance({ 'name': node_instance_name_b, 'cloudservice': 'physicalhost', 'image.platform': 'Ubuntu', 'image.imageId': hostb, 'image.id': hostb, 'network': 'private', })
def test_get_disk_attach_detach(self): ni = NodeInstance() assert None == ni.get_disk_attach_size() assert None == ni.get_disk_detach_device() ni = NodeInstance() ni.set_parameter(NodeDecorator.SCALE_DISK_ATTACH_SIZE, 1) assert 1 == ni.get_disk_attach_size() ni.set_parameter(NodeDecorator.SCALE_DISK_DETACH_DEVICE, 'foo') assert 'foo' == ni.get_disk_detach_device()
def _get_node_instance(self): runtime_parameters = { NodeDecorator.NODE_INSTANCE_NAME_KEY: self.get_node_instance_name(), 'cloudservice': self._cloud_instance_name, 'image.platform': self.get_option(self.PLATFORM_KEY), 'image.imageId': self.get_option(self.IMAGE_ID_KEY), 'image.id': self.get_option(self.IMAGE_ID_KEY), 'network': self.get_option(self.NETWORK_TYPE) } if self.get_option(self.ROOT_DISK_SIZE): runtime_parameters.update( {'disk.GB': self.get_option(self.ROOT_DISK_SIZE)}) if self.get_option(self.EXTRA_DISK_VOLATILE): runtime_parameters.update({ 'extra.disk.volatile': self.get_option(self.EXTRA_DISK_VOLATILE) }) if self.get_option(self.LOGIN_USER_KEY): runtime_parameters.update({ NodeInstance.IMAGE_ATTRIBUTE_PREFIX + '.' + NodeDecorator.LOGIN_USER_KEY: self.get_option(self.LOGIN_USER_KEY) }) return NodeInstance(runtime_parameters)
def _initialization(self, user_info): # pylint: disable=attribute-defined-outside-init # for node_info in nodes_info: # if node_info['multiplicity'] > 1: # raise Exceptions.ExecutionException('Multiplicity not yet supported by this connector.') # TODO: username, password and private_key should be taken from Image Info self.username = user_info.get_cloud_username() self.password = user_info.get_cloud_password() self.private_key = user_info.get_private_key() # TODO: check if this is needed. The orchestrator should be handled server side. node_instance = NodeInstance({ 'name': 'orchestrator-physicalhost', 'loginUser': self.username, 'cloudservice': self.cloudName, self.cloudName + '.login.password': self.password }) vm = { 'username': self.username, 'password': self.password, 'private_key': self.private_key, 'host': os.environ['PHYSICALHOST_ORCHESTRATOR_HOST'], 'id': os.environ['PHYSICALHOST_ORCHESTRATOR_HOST'], 'ip': os.environ['PHYSICALHOST_ORCHESTRATOR_HOST'] } super(PhysicalHostClientCloud, self).__add_vm(vm, node_instance) # pylint: disable=protected-access
def _get_node_instance(self): # the runtime parameters are not the same as for VMs runtime_parameters = { NodeDecorator.NODE_INSTANCE_NAME_KEY: self.get_node_instance_name(), 'cloudservice': self._cloud_instance_name } return NodeInstance(runtime_parameters)
def test_launch_target_script_bad_exec_format(self): wrapper = Mock() wrapper.fail = Mock() wrapper.isAbort = Mock(return_value=False) nde = NodeDeploymentExecutor(wrapper, config_holder=self.ch) target = 'foo' nde.node_instance = NodeInstance() nde.node_instance.set_image_targets({target: [{'script': 'oops'}]}) self.assertRaises(OSError, nde._execute_target, *(target, {}, True)) assert 1 == nde.wrapper.fail.call_count
def test_wait_pre_scale_done(self): node_instances = [ NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.1'}), NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.2'}), NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.3'}), NodeInstance({NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.1'}) ] cw = CloudWrapper(self.config_holder) cw.get_pre_scale_done = Mock(return_value='true') cw._get_state_timeout_time = Mock(return_value=(time.time() + 10)) cw._wait_pre_scale_done(node_instances) cw.get_pre_scale_done = Mock(return_value='true') cw._get_state_timeout_time = Mock(return_value=(time.time() - 1)) self.failUnlessRaises(TimeoutException, cw._wait_pre_scale_done, node_instances) cw.get_pre_scale_done = Mock(return_value='') cw._get_state_timeout_time = Mock(return_value=(time.time() + 2)) self.failUnlessRaises(TimeoutException, cw._wait_pre_scale_done, node_instances)
def test_get_pre_scale_done(self): bw = BaseWrapper(self.config_holder) bw._get_runtime_parameter = Mock(return_value='true') node_instance = NodeInstance( {NodeDecorator.NODE_INSTANCE_NAME_KEY: 'foo'}) assert 'true' == bw.get_pre_scale_done(node_instance) assert bw._get_runtime_parameter.called_with( 'foo:' + NodeDecorator.PRE_SCALE_DONE) bw._get_runtime_parameter = Mock(return_value='') assert '' == bw.get_pre_scale_done('foo') assert bw._get_runtime_parameter.called_with( 'foo:' + NodeDecorator.PRE_SCALE_DONE)
def test_launch_target_script_failure(self): wrapper = Mock() wrapper.fail = Mock() wrapper.isAbort = Mock(return_value=False) nde = NodeDeploymentExecutor(wrapper, config_holder=self.ch) nde.TARGET_POLL_INTERVAL = 1 target = 'foo' nde.node_instance = NodeInstance() nde.node_instance.set_image_targets( {target: [{ 'script': '#!/bin/bash \n/command/not/found\n' }]}) self.assertRaises(AbortException, nde._execute_target, *(target, {}, True)) assert 1 == nde.wrapper.fail.call_count
def test_put_image_id(self): # pylint: disable=protected-access self.config_holder.set( CONFIGPARAM_CONNECTOR_MODULE_NAME, self.get_cloudconnector_modulename_by_cloudname('local')) cw = CloudWrapper(self.config_holder) cw.initCloudConnector() cw._ss_client.httpClient._call = Mock(return_value=Mock()) cw._update_slipstream_image( NodeInstance({'image.resourceUri': 'module/Name'}), 'ABC') cw._ss_client.httpClient._call.assert_called_with( '%s/module/Name/Test' % self.serviceurl, 'PUT', 'ABC', 'application/xml', 'application/xml', retry=True)
def test_launch_target_script_failure_with_stderr(self): wrapper = Mock() wrapper.fail = Mock() wrapper.isAbort = Mock(return_value=False) nde = NodeDeploymentExecutor(wrapper, config_holder=self.ch) nde.TARGET_POLL_INTERVAL = 1 target = 'foo' error = 'The error' nde.node_instance = NodeInstance() nde.node_instance.set_image_targets({ target: [{ 'script': '#!/bin/bash \n>&2 echo "' + error + '" \nexit 1\n' }] }) try: nde._execute_target(target, abort_on_err=True) except AbortException as e: assert error in str(e) assert 1 == nde.wrapper.fail.call_count
def test_extraDisksOnStratusLabRunner(self): stratuslabClient = StratusLabClientCloud( SlipstreamConfigHolder(context={'foo': 'bar'}, config={'foo': 'bar'})) slch = StratusLabConfigHolder() slch.set('username', 'foo') slch.set('password', 'bar') slch.set('endpoint', 'example.com') slch.set('verboseLevel', 0) node_instance = NodeInstance({ 'cloudservice': 'stratuslab', 'extra.disk.volatile': '123', 'stratuslab.extra_disk_persistent': '1-2-3', 'stratuslab.extra_disk_readonly': 'ABC' }) stratuslabClient._set_extra_disks_on_config_holder(slch, node_instance) Runner._setPersistentDiskOptional = Mock() runner = stratuslabClient._get_stratuslab_runner('abc', slch) assert runner.extraDiskSize == int('123') * 1024 # MB assert runner.persistentDiskUUID == '1-2-3' assert runner.readonlyDiskId == 'ABC'
def test_get_networks(self): ni = NodeInstance() assert [] == ni.get_networks() ni = NodeInstance({'test.networks': ''}) assert [] == ni.get_networks() ni = NodeInstance({NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.networks': 'foo'}) assert ['foo'] == ni.get_networks() ni = NodeInstance({NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.networks': 'foo, bar'}) assert ['foo', 'bar'] == ni.get_networks() ni = NodeInstance({'test.networks': []}) assert [] == ni.get_networks() ni = NodeInstance({NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.networks': ['foo']}) assert ['foo'] == ni.get_networks()
def setUp(self): cloudName = TestOkeanosClientCloud.CLOUD_NAME flavorKey = TestOkeanosClientCloud.FLAVOR_KEY resizeFlavorKey = TestOkeanosClientCloud.RESIZE_FLAVOR_KEY os.environ['SLIPSTREAM_CONNECTOR_INSTANCE'] = cloudName os.environ['SLIPSTREAM_BOOTSTRAP_BIN'] = 'http://example.com/bootstrap' os.environ['SLIPSTREAM_DIID'] = \ '%s-1234-1234-1234-123456789012' % str(int(time.time()))[2:] if not os.path.exists(CONFIG_FILE): raise Exception('Configuration file %s not found.' % CONFIG_FILE) self.ch = ConfigHolder(configFile=CONFIG_FILE, context={'foo': 'bar'}) self.ch.verboseLevel = int(self.ch.verboseLevel) flavor = self.ch.config[flavorKey] resizeFlavor = self.ch.config[resizeFlavorKey] self.log("Initial Flavor: '%s' = %s" % (flavorKey, flavor)) self.log("Resize Flavor: '%s' = %s" % (resizeFlavorKey, resizeFlavor)) self.user_info = UserInfo(cloudName) self.user_info['General.ssh.public.key'] = self.ch.config['General.ssh.public.key'] self.user_info[cloudName + '.endpoint'] = self.ch.config[cloudName + '.auth_url'] self.user_info[cloudName + '.username'] = self.ch.config[cloudName + '.user.uuid'] self.user_info[cloudName + '.password'] = self.ch.config[cloudName + '.token'] self.user_info[cloudName + '.project.id'] = self.ch.config[cloudName + '.project.id'] node_name = 'test_node' self.multiplicity = int(self.ch.config['multiplicity']) self.node_instances = {} for i in range(1, self.multiplicity + 1): node_instance_name = node_name + '.' + str(i) ni = NodeInstance({ NodeDecorator.NODE_NAME_KEY: node_name, NodeDecorator.NODE_INSTANCE_NAME_KEY: node_instance_name, 'cloudservice': cloudName, 'image.description': 'This is a test image.', 'image.platform': self.ch.config[cloudName + '.image.platform'], 'image.id': self.ch.config[cloudName + '.imageid'], flavorKey: flavor, resizeFlavorKey: resizeFlavor, 'network': self.ch.config['network'] }) ni.set_parameter(NodeDecorator.SCALE_DISK_ATTACH_SIZE, 1) self.node_instances[node_instance_name] = ni self.node_instance = NodeInstance({ NodeDecorator.NODE_NAME_KEY: node_name, NodeDecorator.NODE_INSTANCE_NAME_KEY: NodeDecorator.MACHINE_NAME, 'cloudservice': cloudName, 'disk.attach.size': self.ch.config[cloudName + '.disk.attach.size'], 'image.description': 'This is a test image.', 'image.platform': self.ch.config[cloudName + '.image.platform'], 'image.loginUser': self.ch.config[cloudName + '.image.loginuser'], 'image.id': self.ch.config[cloudName + '.imageid'], flavorKey: flavor, resizeFlavorKey: resizeFlavor, 'network': self.ch.config['network'], 'image.prerecipe': """#!/bin/sh set -e set -x ls -l /tmp dpkg -l | egrep "nano|lvm" || true """, 'image.packages': ['lvm2', 'nano'], 'image.recipe': """#!/bin/sh set -e set -x dpkg -l | egrep "nano|lvm" || true lvs """ })
def get_nodes_instances(self, cloud_service_name=None): '''Return dict {<node_instance_name>: NodeInstance, } ''' nodes_instances = {} self._retrieveAndSetRun() nodes_instances_runtime_parameters = \ DomExtractor.extract_nodes_instances_runtime_parameters(self.run_dom, cloud_service_name) nodes_runtime_parameters = DomExtractor.extract_nodes_runtime_parameters(self.run_dom) for node_instance_name, node_instance_runtime_parameters in nodes_instances_runtime_parameters.items(): node_instance = NodeInstance(node_instance_runtime_parameters) node_name = node_instance.get_node_name() if nodes_runtime_parameters: node_runtime_parameters = nodes_runtime_parameters.get(node_name, {}) if node_runtime_parameters: node_instance.set_parameter(NodeDecorator.MAX_PROVISIONING_FAILURES_KEY, node_runtime_parameters.get(NodeDecorator.MAX_PROVISIONING_FAILURES_KEY, '0')) image_attributes = DomExtractor.extract_node_image_attributes(self.run_dom, node_name) node_instance.set_image_attributes(image_attributes) image_targets = DomExtractor.extract_node_image_targets(self.run_dom, node_name) node_instance.set_image_targets(image_targets) build_state = DomExtractor.extract_node_image_build_state(self.run_dom, node_name) node_instance.set_build_state(build_state) nodes_instances[node_instance_name] = node_instance return nodes_instances
def setUp(self): BaseCloudConnector._publish_vm_info = Mock() # pylint: disable=protected-access os.environ[ 'SLIPSTREAM_CONNECTOR_INSTANCE'] = self.connector_instance_name os.environ['SLIPSTREAM_BOOTSTRAP_BIN'] = 'http://example.com/bootstrap' os.environ[ 'SLIPSTREAM_DIID'] = '00000000-0000-0000-0000-%s' % time.time() if not os.path.exists(CONFIG_FILE): raise Exception('Configuration file %s not found.' % CONFIG_FILE) self.ch = ConfigHolder(configFile=CONFIG_FILE, context={'foo': 'bar'}) self.ch.set(KEY_RUN_CATEGORY, '') self.ch.set('verboseLevel', self.ch.config['General.verbosity']) self.client = CloudStackClientCloud(self.ch) self.user_info = UserInfo(self.connector_instance_name) self.user_info[self.constructKey( 'endpoint')] = self.ch.config['cloudstack.endpoint'] self.user_info[self.constructKey( 'zone')] = self.ch.config['cloudstack.zone'] self.user_info[self.constructKey( 'username')] = self.ch.config['cloudstack.key'] self.user_info[self.constructKey( 'password')] = self.ch.config['cloudstack.secret'] security_groups = self.ch.config['cloudstack.security.groups'] instance_type = self.ch.config['cloudstack.instance.type'] self.user_info['General.ssh.public.key'] = self.ch.config[ 'General.ssh.public.key'] image_id = self.ch.config[self.constructKey('template')] self.multiplicity = 2 self.max_iaas_workers = self.ch.config.get( 'cloudstack.max.iaas.workers', str(self.multiplicity)) self.node_name = 'test_node' self.node_instances = {} for i in range(1, self.multiplicity + 1): node_instance_name = self.node_name + '.' + str(i) self.node_instances[node_instance_name] = NodeInstance({ NodeDecorator.NODE_NAME_KEY: self.node_name, NodeDecorator.NODE_INSTANCE_NAME_KEY: node_instance_name, 'cloudservice': self.connector_instance_name, # 'index': i,s 'image.platform': 'linux', 'image.imageId': image_id, 'image.id': image_id, self.constructKey('instance.type'): instance_type, self.constructKey('security.groups'): security_groups, 'network': 'private' })
def setUp(self): os.environ[ 'SLIPSTREAM_CONNECTOR_INSTANCE'] = self.connector_instance_name os.environ['SLIPSTREAM_BOOTSTRAP_BIN'] = 'http://example.com/bootstrap' os.environ['SLIPSTREAM_DIID'] = '00000000-0000-0000-0000-000000000000' if not os.path.exists(CONFIG_FILE): raise Exception('Configuration file %s not found.' % CONFIG_FILE) self.ch = ConfigHolder(configFile=CONFIG_FILE, context={'foo': 'bar'}) self.ch.set(KEY_RUN_CATEGORY, '') OpenNebulaClientCloud._publish_vm_info = publish_vm_info # pylint: disable=protected-access self.client = OpenNebulaClientCloud(self.ch) self.user_info = UserInfo(self.connector_instance_name) self.user_info[ 'General.' + UserInfo.SSH_PUBKEY_KEY] = self.ch.config['General.ssh.public.key'] self.user_info[self.constructKey( 'endpoint')] = self.ch.config['opennebula.endpoint'] self.user_info[self.constructKey( 'username')] = self.ch.config['opennebula.username'] self.user_info[self.constructKey( 'password')] = self.ch.config['opennebula.password'] self.user_info[self.constructKey( UserInfo.NETWORK_PUBLIC_KEY )] = self.ch.config['opennebula.networkPublic'] self.user_info[self.constructKey( UserInfo.NETWORK_PRIVATE_KEY )] = self.ch.config['opennebula.networkPrivate'] self.user_info[self.constructKey('cpuRatio')] = '1.0' image_id = self.ch.config['opennebula.imageid'] instance_type = self.ch.config.get('opennebula.intance.type', 'm1.tiny') node_name = 'test_node' self.multiplicity = 1 self.node_instances = {} for i in range(1, self.multiplicity + 1): node_instance_name = node_name + '.' + str(i) self.node_instances[node_instance_name] = NodeInstance({ NodeDecorator.NODE_NAME_KEY: node_name, NodeDecorator.NODE_INSTANCE_NAME_KEY: node_instance_name, 'cloudservice': self.connector_instance_name, 'image.platform': 'Ubuntu', 'image.imageId': image_id, 'image.id': image_id, 'network': self.ch.config['opennebula.network'], self.constructKey('instance.type'): instance_type, self.constructKey('ram'): '2', self.constructKey('cpu'): '1' }) self.node_instance = NodeInstance({ NodeDecorator.NODE_NAME_KEY: NodeDecorator.MACHINE_NAME, NodeDecorator.NODE_INSTANCE_NAME_KEY: NodeDecorator.MACHINE_NAME, 'cloudservice': self.connector_instance_name, 'image.platform': 'Ubuntu', 'image.imageId': image_id, 'image.id': image_id, self.constructKey('instance.type'): instance_type, 'image.prerecipe': """#!/bin/sh set -e set -x ls -l /tmp dpkg -l | egrep "nano|lvm" || true """, 'image.packages': ['lvm2', 'nano'], 'image.recipe': """#!/bin/sh set -e set -x dpkg -l | egrep "nano|lvm" || true lvs """ })
def test_inconsistent_scale_state_inconsistent_scaling_nodes(self): """ Inconsistent scale state: different scaling actions at a time are not allowed. In case node instance is not in a terminal state (as set on the NodeInstance object), we check the state directly on the Run (via CloudWrapper._get_runtime_parameter()). Inconsistent scaling nodes: only one node type at a time is allowed to be scaled. """ def _get_runtime_parameter(key): if key.startswith('n.'): return CloudWrapper.SCALE_STATE_RESIZING elif key.startswith('m.'): return CloudWrapper.SCALE_STATE_DISK_ATTACHING else: return 'unknown' node_instances = { 'n.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.1', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: 'not terminal' }), 'n.2': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.2', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_OPERATIONAL }), 'm.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.1', NodeDecorator.NODE_NAME_KEY: 'm', NodeDecorator.SCALE_STATE_KEY: 'not terminal' }) } cw = CloudWrapper(self.config_holder) cw._get_runtime_parameter = Mock(side_effect=_get_runtime_parameter) cw._get_nodes_instances = Mock(return_value=node_instances) scale_states = cw._get_effective_scale_states() assert 2 == len(scale_states) assert CloudWrapper.SCALE_STATE_RESIZING in scale_states assert 1 == len(scale_states[CloudWrapper.SCALE_STATE_RESIZING]) assert ['n.1'] == scale_states[CloudWrapper.SCALE_STATE_RESIZING] assert CloudWrapper.SCALE_STATE_DISK_ATTACHING in scale_states assert 1 == len(scale_states[CloudWrapper.SCALE_STATE_DISK_ATTACHING]) assert ['m.1'] == scale_states[CloudWrapper.SCALE_STATE_DISK_ATTACHING] self.failUnlessRaises(InconsistentScaleStateError, cw._get_global_scale_state) self.failUnlessRaises(InconsistentScaleStateError, cw.is_vertical_scaling) self.failUnlessRaises(InconsistentScaleStateError, cw.check_scale_state_consistency) self.failUnlessRaises(InconsistentScalingNodesError, cw.get_scaling_node_and_instance_names)
def test_consistent_scale_state_consistent_scaling_nodes(self): """ Consistent scale state: different scaling actions at a time are not allowed. In case node instance is not in a terminal state (as set on the NodeInstance object), we check the state directly on the Run (via CloudWrapper._get_runtime_parameter()). Consistent scaling nodes: only one node type at a time is allowed to be scaled. """ def _get_runtime_parameter(key): if key.endswith(NodeDecorator.NODE_PROPERTY_SEPARATOR + NodeDecorator.SCALE_STATE_KEY): return CloudWrapper.SCALE_STATE_RESIZING else: return 'unknown' node_instances = { 'n.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.1', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: 'not terminal' }), 'n.2': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.2', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: 'not terminal' }), 'm.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.1', NodeDecorator.NODE_NAME_KEY: 'm', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_OPERATIONAL }) } cw = CloudWrapper(self.config_holder) cw._get_runtime_parameter = Mock(side_effect=_get_runtime_parameter) cw._get_nodes_instances = Mock(return_value=node_instances) scale_states = cw._get_effective_scale_states() assert 1 == len(scale_states) assert CloudWrapper.SCALE_STATE_RESIZING in scale_states assert 2 == len(scale_states[CloudWrapper.SCALE_STATE_RESIZING]) assert ['n.1', 'n.2' ] == sorted(scale_states[CloudWrapper.SCALE_STATE_RESIZING]) assert CloudWrapper.SCALE_STATE_RESIZING == cw._get_global_scale_state( ) try: cw.check_scale_state_consistency() except InconsistentScaleStateError as ex: self.fail('Should not have failed with: %s' % str(ex)) node_and_instances = cw.get_scaling_node_and_instance_names() assert 'n' == node_and_instances[0] assert ['n.1', 'n.2'] == sorted(node_and_instances[1])
def test_consistent_scale_state_inconsistent_scaling_nodes(self): """ Consistent scale state: only one scaling action at a time on different node instances. In case node instance is not in a terminal state (as set on the NodeInstance object), we check the state directly on the Run (via CloudWrapper._get_runtime_parameter()). Inconsistent scaling nodes: only one node type at a time is allowed to be scaled. """ def _get_runtime_parameter(key): if key.endswith(NodeDecorator.NODE_PROPERTY_SEPARATOR + NodeDecorator.SCALE_STATE_KEY): return CloudWrapper.SCALE_STATE_RESIZING else: return 'unknown' node_instances = { 'n.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.1', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: 'not terminal' }), 'n.2': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.2', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_OPERATIONAL }), 'm.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.1', NodeDecorator.NODE_NAME_KEY: 'm', NodeDecorator.SCALE_STATE_KEY: 'not terminal' }), 'm.2': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.2', NodeDecorator.NODE_NAME_KEY: 'm', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_GONE }), } cw = CloudWrapper(self.config_holder) cw._get_runtime_parameter = Mock(side_effect=_get_runtime_parameter) cw._get_nodes_instances = Mock(return_value=node_instances) scale_states = cw._get_effective_scale_states() assert 1 == len(scale_states) assert CloudWrapper.SCALE_STATE_RESIZING in scale_states assert 2 == len(scale_states[CloudWrapper.SCALE_STATE_RESIZING]) assert ['m.1', 'n.1' ] == sorted(scale_states[CloudWrapper.SCALE_STATE_RESIZING]) assert CloudWrapper.SCALE_STATE_RESIZING == cw._get_global_scale_state( ) assert True == cw.is_vertical_scaling() self.failUnlessRaises(InconsistentScalingNodesError, cw.get_scaling_node_and_instance_names)
def test_get_disk_attach_detach(self): ni = NodeInstance() assert None == ni.get_disk_attach_size() assert None == ni.get_disk_detach_device() ni = NodeInstance() ni.set_parameter(NodeDecorator.SCALE_DISK_ATTACH_SIZE, 1) assert 1 == ni.get_disk_attach_size() ni.set_parameter(NodeDecorator.SCALE_DISK_DETACH_DEVICE, 'foo') assert 'foo' == ni.get_disk_detach_device()
def handle_deployment(self): node_instance_name = 'machine' module_content = self.deployment['module'].get('content', {}) cpu = module_content.get('cpu') ram = module_content.get('ram') disk = module_content.get('disk') network_type = module_content.get('networkType') login_user = module_content.get('loginUser') ports = module_content.get('ports', []) mounts = module_content.get('mounts', []) node_params = self.get_node_parameters(module_content) self.create_deployment_parameters(node_instance_name, node_params.values(), ports) cloud_credential_id = node_params['credential.id'].get('value') if cloud_credential_id is None: raise ValueError("Credential is not set!") cloud_credential = self.ss_api.cimi_get(cloud_credential_id).json cloud_href = cloud_credential['connector']['href'] cloud_configuration = self.ss_api.cimi_get(cloud_href).json cloud_instance_name = cloud_configuration['instanceName'] connector_instance, user_info = DeploymentStartJob.connector_instance_userinfo( cloud_configuration, cloud_credential) ssh_pub_key = self.user_params.get('sshPublicKey') user_info.set_public_keys(ssh_pub_key) ssh_pub_keys = filter(None, [x.strip() for x in ssh_pub_key.splitlines()]) if ssh_pub_keys: self.ss_api.cimi_edit(self.deployment['id'], {'sshPublicKeys': ssh_pub_keys}) deployment_owner = self.deployment['acl']['owner']['principal'] image_id = module_content.get('imageIDs', {}).get(cloud_instance_name) node = NodeInstance({ '{}.cpu'.format(cloud_instance_name): str(cpu), '{}.ram'.format(cloud_instance_name): str(ram / 1024), '{}.disk'.format(cloud_instance_name): str(disk), '{}.ports'.format(cloud_instance_name): ports, '{}.mounts'.format(cloud_instance_name): mounts, '{}.security.groups'.format(cloud_instance_name): 'slipstream_managed', '{}.networks'.format(cloud_instance_name): '', '{}.instance.type'.format(cloud_instance_name): 'Micro', 'image.platform': 'linux', 'network': network_type, 'cloudservice': cloud_instance_name, 'image.id': image_id, 'image.imageId': image_id, 'node_instance_name': node_instance_name, 'image.loginUser': login_user }) node_context = { 'SLIPSTREAM_DIID': self.deployment.get('id'), 'SLIPSTREAM_SERVICEURL': self.slipstream_configuration.get('serviceURL'), 'SLIPSTREAM_NODE_INSTANCE_NAME': node_instance_name, 'SLIPSTREAM_CLOUD': cloud_instance_name, 'SLIPSTREAM_BUNDLE_URL': self.slipstream_configuration.get('clientURL').replace( '.tgz', '-cimi.tgz'), 'SLIPSTREAM_BOOTSTRAP_BIN': self.slipstream_configuration.get('clientBootstrapURL').replace( '.bootstrap', '-cimi.bootstrap'), 'SLIPSTREAM_USERNAME': deployment_owner, 'SLIPSTREAM_API_KEY': self.deployment['clientAPIKey']['href'], 'SLIPSTREAM_API_SECRET': self.deployment['clientAPIKey']['secret'], 'SLIPSTREAM_SS_CACHE_KEY': self.deployment.get('id') } node.set_deployment_context(node_context) connector_instance._BaseCloudConnector__start_node_instance_and_client( user_info, node) self.set_deployment_parameter(param_name=NodeDecorator.INSTANCEID_KEY, param_value=node.get_instance_id(), node_id=node_instance_name) self.set_deployment_parameter(param_name='hostname', param_value=node.get_cloud_node_ip(), node_id=node_instance_name) if node.get_cloud_node_ssh_url(): self.set_deployment_parameter('url.ssh', node.get_cloud_node_ssh_url(), node_instance_name) if node.get_cloud_node_ssh_password(): self.set_deployment_parameter('password.ssh', node.get_cloud_node_ssh_password(), node_instance_name) if node.get_cloud_node_ssh_keypair_name(): self.set_deployment_parameter( 'keypair.name', node.get_cloud_node_ssh_keypair_name(), node_instance_name) if node.get_cloud_node_ports_mapping(): for port_mapping in node.get_cloud_node_ports_mapping().split(): port_param_name, port_param_value = self.get_port_name_value( port_mapping) self.set_deployment_parameter(param_name=port_param_name, param_value=port_param_value, node_id=node_instance_name) self.ss_api.cimi_edit(self.deployment['id'], {'state': 'STARTED'}) return 0
def test_get_security_groups(self): ni = NodeInstance() assert [] == ni.get_security_groups() ni = NodeInstance({'test.' + NodeDecorator.SECURITY_GROUPS_KEY: ''}) assert [] == ni.get_security_groups() ni = NodeInstance({NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.' + NodeDecorator.SECURITY_GROUPS_KEY: 'foo'}) assert ['foo'] == ni.get_security_groups() ni = NodeInstance({NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.' + NodeDecorator.SECURITY_GROUPS_KEY: ' foo, bar'}) assert ['foo', 'bar'] == ni.get_security_groups() ni = NodeInstance({'test.' + NodeDecorator.SECURITY_GROUPS_KEY: []}) assert [] == ni.get_security_groups() ni = NodeInstance({NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.' + NodeDecorator.SECURITY_GROUPS_KEY: ['foo']}) assert ['foo'] == ni.get_security_groups() ni = NodeInstance({NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.' + NodeDecorator.SECURITY_GROUPS_KEY: [' foo', 'bar ']}) assert ['foo', 'bar'] == ni.get_security_groups()
def test_get_security_groups(self): ni = NodeInstance() assert [] == ni.get_security_groups() ni = NodeInstance({'test.' + NodeDecorator.SECURITY_GROUPS_KEY: ''}) assert [] == ni.get_security_groups() ni = NodeInstance({ NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.' + NodeDecorator.SECURITY_GROUPS_KEY: 'foo' }) assert ['foo'] == ni.get_security_groups() ni = NodeInstance({ NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.' + NodeDecorator.SECURITY_GROUPS_KEY: ' foo, bar' }) assert ['foo', 'bar'] == ni.get_security_groups() ni = NodeInstance({'test.' + NodeDecorator.SECURITY_GROUPS_KEY: []}) assert [] == ni.get_security_groups() ni = NodeInstance({ NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.' + NodeDecorator.SECURITY_GROUPS_KEY: ['foo'] }) assert ['foo'] == ni.get_security_groups() ni = NodeInstance({ NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.' + NodeDecorator.SECURITY_GROUPS_KEY: [' foo', 'bar '] }) assert ['foo', 'bar'] == ni.get_security_groups()
def setUp(self): cn = getConnectorClass().cloudName os.environ['SLIPSTREAM_CONNECTOR_INSTANCE'] = cn os.environ['SLIPSTREAM_BOOTSTRAP_BIN'] = 'http://example.com/bootstrap' os.environ['SLIPSTREAM_DIID'] = \ '%s-1234-1234-1234-123456789012' % str(int(time.time()))[2:] if not os.path.exists(CONFIG_FILE): raise Exception('Configuration file %s not found.' % CONFIG_FILE) self.ch = ConfigHolder(configFile=CONFIG_FILE, context={'foo': 'bar'}) self.ch.verboseLevel = int(self.ch.verboseLevel) self.user_info = UserInfo(cn) self.user_info['General.ssh.public.key'] = self.ch.config[ 'General.ssh.public.key'] self.user_info[cn + '.user.uuid'] = self.ch.config[cn + '.user.uuid'] self.user_info[cn + '.username'] = self.ch.config[cn + '.username'] self.user_info[cn + '.password'] = self.ch.config[cn + '.password'] self.user_info[cn + '.endpoint'] = self.ch.config[cn + '.endpoint'] node_name = 'test_node' self.multiplicity = int(self.ch.config['multiplicity']) self.node_instances = {} for i in range(1, self.multiplicity + 1): node_instance_name = node_name + '.' + str(i) self.node_instances[node_instance_name] = NodeInstance({ NodeDecorator.NODE_NAME_KEY: node_name, NodeDecorator.NODE_INSTANCE_NAME_KEY: node_instance_name, 'cloudservice': cn, 'image.description': 'This is a test image.', 'image.platform': self.ch.config[cn + '.image.platform'], 'image.id': self.ch.config[cn + '.imageid'], cn + '.ram': self.ch.config[cn + '.ram'], cn + '.cpu': self.ch.config[cn + '.cpu'], 'network': self.ch.config['network'] }) self.node_instance = NodeInstance({ NodeDecorator.NODE_NAME_KEY: NodeDecorator.MACHINE_NAME, NodeDecorator.NODE_INSTANCE_NAME_KEY: NodeDecorator.MACHINE_NAME, 'cloudservice': cn, 'image.description': 'This is a test image.', 'image.platform': self.ch.config[cn + '.image.platform'], 'image.loginUser': self.ch.config[cn + '.image.loginuser'], 'image.id': self.ch.config[cn + '.imageid'], cn + '.ram': self.ch.config[cn + '.ram'], cn + '.cpu': self.ch.config[cn + '.cpu'], 'network': self.ch.config['network'], 'image.prerecipe': """#!/bin/sh set -e set -x ls -l /tmp dpkg -l | egrep "nano|lvm" || true """, 'image.packages': ['lvm2', 'nano'], 'image.recipe': """#!/bin/sh set -e set -x dpkg -l | egrep "nano|lvm" || true lvs """ })
def test_vertically_scalle_instances_nowait(self): _scale_state = None def _get_runtime_parameter(key): if key.endswith(NodeDecorator.NODE_PROPERTY_SEPARATOR + NodeDecorator.SCALE_STATE_KEY): return _scale_state else: return 'unknown' node_instances = { 'n.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.1', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_RESIZING }), 'n.2': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.2', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_DISK_ATTACHING }), 'n.3': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'n.3', NodeDecorator.NODE_NAME_KEY: 'n', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_DISK_DETACHING }), 'm.1': NodeInstance({ NodeDecorator.NODE_INSTANCE_NAME_KEY: 'm.1', NodeDecorator.NODE_NAME_KEY: 'm', NodeDecorator.SCALE_STATE_KEY: CloudWrapper.SCALE_STATE_OPERATIONAL }) } self.config_holder.set('verboseLevel', 3) setattr(self.config_holder, 'cloud', 'local') setattr(self.config_holder, CONFIGPARAM_CONNECTOR_MODULE_NAME, 'slipstream.cloudconnectors.dummy.DummyClientCloud') cw = CloudWrapper(self.config_holder) cw._get_nodes_instances = Mock(return_value=node_instances) cw.initCloudConnector(self.config_holder) cw._set_runtime_parameter = Mock() cw._get_user_timeout = Mock(return_value=2) # No waiting. cw._wait_pre_scale_done = Mock() cw._wait_scale_state = Mock() _scale_state = 'resizing' cw._get_runtime_parameter = Mock(side_effect=_get_runtime_parameter) cw._cloud_client.resize = Mock(wraps=cw._cloud_client.resize) cw.vertically_scale_instances() assert True == cw._cloud_client.resize.called node_instance = cw._cloud_client.resize.call_args[0][0][0] assert 'n.1' in node_instance.get_name() assert cw._set_runtime_parameter.called_with( 'n.1:' + NodeDecorator.SCALE_IAAS_DONE, 'true') _scale_state = 'disk_attaching' cw._get_runtime_parameter = Mock(side_effect=_get_runtime_parameter) cw._cloud_client.attach_disk = Mock(wraps=cw._cloud_client.attach_disk) cw.vertically_scale_instances() assert True == cw._cloud_client.attach_disk.called node_instance = cw._cloud_client.attach_disk.call_args[0][0][0] assert 'n.2' in node_instance.get_name() assert cw._set_runtime_parameter.called_with( 'n.2:' + NodeDecorator.SCALE_IAAS_DONE, 'true') _scale_state = 'disk_detaching' cw._get_runtime_parameter = Mock(side_effect=_get_runtime_parameter) cw._cloud_client.detach_disk = Mock(wraps=cw._cloud_client.detach_disk) cw.vertically_scale_instances() assert True == cw._cloud_client.detach_disk.called node_instance = cw._cloud_client.detach_disk.call_args[0][0][0] assert 'n.3' in node_instance.get_name() assert cw._set_runtime_parameter.called_with( 'n.3:' + NodeDecorator.SCALE_IAAS_DONE, 'true')
def test_get_networks(self): ni = NodeInstance() assert [] == ni.get_networks() ni = NodeInstance({'test.networks': ''}) assert [] == ni.get_networks() ni = NodeInstance({ NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.networks': 'foo' }) assert ['foo'] == ni.get_networks() ni = NodeInstance({ NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.networks': 'foo, bar' }) assert ['foo', 'bar'] == ni.get_networks() ni = NodeInstance({'test.networks': []}) assert [] == ni.get_networks() ni = NodeInstance({ NodeDecorator.CLOUDSERVICE_KEY: 'cloud-x', 'cloud-x.networks': ['foo'] }) assert ['foo'] == ni.get_networks()
def setUp(self): os.environ['SLIPSTREAM_CONNECTOR_INSTANCE'] = 'stratuslab' os.environ['SLIPSTREAM_BOOTSTRAP_BIN'] = 'http://example.com/bootstrap' os.environ['SLIPSTREAM_DIID'] = '00000000-0000-0000-0000-00%s' % int( time.time()) config_file = self._get_config_file() if not os.path.exists(config_file): raise Exception('Configuration file %s not found.' % config_file) self.ch = ConfigHolder(configFile=config_file, context={'foo': 'bar'}) self.ch.set('verboseLevel', int(self.ch.config['General.verbosity'])) os.environ['SLIPSTREAM_PDISK_ENDPOINT'] = self.ch.config[ 'SLIPSTREAM_PDISK_ENDPOINT'] self.client = self._get_connector_class()(self.ch) self.client._publish_vm_info = Mock() self.user_info = UserInfo('stratuslab') self.user_info['stratuslab.endpoint'] = self.ch.config[ 'stratuslab.endpoint'] self.user_info['stratuslab.ip.type'] = self.ch.config[ 'stratuslab.ip.type'] self.user_info['stratuslab.marketplace.endpoint'] = self.ch.config[ 'stratuslab.marketplace.endpoint'] self.user_info['stratuslab.password'] = self.ch.config[ 'stratuslab.password'] self.user_info['General.ssh.public.key'] = self.ch.config[ 'General.ssh.public.key'] self.user_info['stratuslab.username'] = self.ch.config[ 'stratuslab.username'] self.user_info['User.firstName'] = 'Foo' self.user_info['User.lastName'] = 'Bar' self.user_info['User.email'] = '*****@*****.**' extra_disk_volatile = self.ch.config['stratuslab.extra.disk.volatile'] image_id = self.ch.config['stratuslab.imageid'] self.multiplicity = int( self.ch.config.get('stratuslab.multiplicity', 2)) self.max_iaas_workers = self.ch.config.get( 'stratuslab.max.iaas.workers', 10) self.node_name = 'test_node' self.node_instances = {} for i in range(1, self.multiplicity + 1): node_instance_name = self.node_name + '.' + str(i) self.node_instances[node_instance_name] = NodeInstance({ NodeDecorator.NODE_NAME_KEY: self.node_name, NodeDecorator.NODE_INSTANCE_NAME_KEY: node_instance_name, 'cloudservice': 'stratuslab', 'extra.disk.volatile': extra_disk_volatile, 'image.resourceUri': '', 'image.platform': 'Ubuntu', 'image.imageId': image_id, 'image.id': image_id, 'stratuslab.instance.type': 'm1.small', 'stratuslab.disks,bus.type': 'virtio', 'stratuslab.cpu': '', 'stratuslab.ram': '', 'network': 'public' }) self.node_instance = NodeInstance({ NodeDecorator.NODE_NAME_KEY: NodeDecorator.MACHINE_NAME, NodeDecorator.NODE_INSTANCE_NAME_KEY: NodeDecorator.MACHINE_NAME, 'cloudservice': 'stratuslab', 'extra.disk.volatile': extra_disk_volatile, 'image.resourceUri': '', 'image.platform': 'Ubuntu', 'image.imageId': image_id, 'image.id': image_id, 'stratuslab.instance.type': 'm1.small', 'stratuslab.disks,bus.type': 'virtio', 'stratuslab.cpu': '', 'stratuslab.ram': '', 'network': 'public', 'image.prerecipe': [{ "name": "prerecipe", "order": 1, "module": "component", "module_uri": "path/to/component", "script": """#!/bin/sh set -e set -x ls -l /tmp dpkg -l | egrep "nano|lvm" || true """ }], 'image.packages': ['lvm2', 'nano'], 'image.recipe': [{ "name": "prerecipe", "order": 1, "module": "component", "module_uri": "path/to/component", "script": """#!/bin/sh set -e set -x dpkg -l | egrep "nano|lvm" || true lvs """ }] })
def setUp(self): self._setUp(OpenStackClientCloud, CONFIG_FILE, self.conf_keys) self._update_user_info() security_groups = self._conf_val('security.groups') image_id = self._conf_val('imageid') instance_type = self._conf_val('intance.type', 'm1.tiny') network_type = self._conf_val('network.type') node_name = 'test_node' self.node_instances = {} for i in range(1, self.multiplicity + 1): node_instance_name = node_name + '.' + str(i) self.node_instances[node_instance_name] = NodeInstance({ NodeDecorator.NODE_NAME_KEY: node_name, NodeDecorator.NODE_INSTANCE_NAME_KEY: node_instance_name, 'cloudservice': self.cin, 'image.platform': 'Ubuntu', 'image.imageId': image_id, 'image.id': image_id, self.construct_key('instance.type'): instance_type, self.construct_key('security.groups'): security_groups, 'network': network_type }) self.node_instance = NodeInstance({ NodeDecorator.NODE_NAME_KEY: NodeDecorator.MACHINE_NAME, NodeDecorator.NODE_INSTANCE_NAME_KEY: NodeDecorator.MACHINE_NAME, 'cloudservice': self.cin, 'image.platform': 'Ubuntu', 'image.imageId': image_id, 'image.id': image_id, self.construct_key('instance.type'): instance_type, self.construct_key('security.groups'): security_groups, 'network': network_type, 'image.prerecipe': """#!/bin/sh set -e set -x ls -l /tmp dpkg -l | egrep "nano|lvm" || true """, 'image.packages': ['lvm2', 'nano'], 'image.recipe': """#!/bin/sh set -e set -x dpkg -l | egrep "nano|lvm" || true lvs """ }) self.node_instance_with_additional_disk = NodeInstance({ NodeDecorator.NODE_NAME_KEY: NodeDecorator.MACHINE_NAME, NodeDecorator.NODE_INSTANCE_NAME_KEY: NodeDecorator.MACHINE_NAME, 'cloudservice': self.cin, 'image.platform': 'Ubuntu', 'image.imageId': image_id, 'image.id': image_id, self.construct_key('instance.type'): instance_type, 'network': network_type, 'extra.disk.volatile': '20' })
def test_build_rtp(self): assert 'foo:bar' == BaseWrapper._build_rtp('foo', 'bar') node_instance = NodeInstance( {NodeDecorator.NODE_INSTANCE_NAME_KEY: 'foo'}) assert 'foo:bar' == BaseWrapper._build_rtp(node_instance, 'bar')