def create_network_interface(interface_uuid, netdesc, instance_uuid, order): if 'macaddress' not in netdesc or not netdesc['macaddress']: with etcd.get_lock('macaddress', None, 'all', ttl=120): possible_mac = str(randmac.RandMac( '00:00:00:00:00:00', False)).lstrip('\'').rstrip('\'') while etcd.get('macaddress', None, possible_mac): possible_mac = str(randmac.RandMac( '00:00:00:00:00:00', False)).lstrip('\'').rstrip('\'') etcd.put('macaddress', None, possible_mac, {'interface_uuid': interface_uuid}) netdesc['macaddress'] = possible_mac etcd.put( 'networkinterface', None, interface_uuid, { 'uuid': interface_uuid, 'network_uuid': netdesc['network_uuid'], 'instance_uuid': instance_uuid, 'macaddr': netdesc['macaddress'], 'ipv4': netdesc['address'], 'order': order, 'floating': None, 'state': 'initial', 'state_updated': time.time(), 'model': netdesc['model'] })
def create_instance(instance_uuid, name, cpus, memory_mb, disk_spec, ssh_key, user_data, namespace, video, requested_placement): d = { 'uuid': instance_uuid, 'name': name, 'cpus': cpus, 'memory': memory_mb, 'disk_spec': disk_spec, 'ssh_key': ssh_key, 'node': config.NODE_NAME, 'console_port': 0, 'vdi_port': 0, 'user_data': user_data, 'block_devices': None, 'state': 'initial', 'state_updated': time.time(), 'namespace': namespace, 'power_state': 'initial', 'video': video, 'node_history': [], 'error_message': None, 'requested_placement': None, 'placement_attempts': 0, } etcd.put('instance', None, instance_uuid, d) return d
def persist_console_ports(instance_uuid, console_port, vdi_port): # TODO(andy): When Instance class is modified to model Image class this # repetitive write will be moved to a single persist() function. i = get_instance(instance_uuid) i['console_port'] = console_port i['vdi_port'] = vdi_port etcd.put('instance', None, instance_uuid, i)
def update_instance_error_message(instance_uuid, error_message): i = get_instance(instance_uuid) i['error_message'] = error_message etcd.put('instance', None, instance_uuid, i) add_event('instance', instance_uuid, 'error message', error_message, None, None)
def test_put_FetchImageTask(self, mock_put): etcd.put('objecttype', 'subtype', 'name', tasks.FetchImageTask('http://server/image')) path = '/sf/objecttype/subtype/name' encoded = '''{ "instance_uuid": null, "task": "image_fetch", "url": "http://server/image", "version": 1 }''' mock_put.assert_called_with(path, encoded, lease=None) etcd.put( 'objecttype', 'subtype', 'name', tasks.FetchImageTask('http://server/image', instance_uuid='fake_uuid')) path = '/sf/objecttype/subtype/name' encoded = '''{ "instance_uuid": "fake_uuid", "task": "image_fetch", "url": "http://server/image", "version": 1 }''' mock_put.assert_called_with(path, encoded, lease=None)
def allocate_network(netblock, provide_dhcp=True, provide_nat=False, name=None, namespace=None): net_id = str(uuid.uuid4()) ipm = ipmanager.NetBlock(netblock) etcd.put('ipmanager', None, net_id, ipm.save()) vxid = 1 while not etcd.create('vxlan', None, vxid, {'network_uuid': net_id}): vxid += 1 d = { 'uuid': net_id, 'vxid': vxid, 'netblock': netblock, 'provide_dhcp': provide_dhcp, 'provide_nat': provide_nat, 'namespace': namespace, 'floating_gateway': None, 'name': name, 'state': 'initial', 'state_updated': time.time() } etcd.put('network', None, net_id, d) return d
def update_network_interface_state(interface_uuid, state): ni = get_interface(interface_uuid) ni['state'] = state ni['state_updated'] = time.time() etcd.put('networkinterface', None, interface_uuid, ni) if state == 'deleted': etcd.delete('macaddress', None, ni['macaddr'])
def create_snapshot(snapshot_uuid, device, instance_uuid, created): etcd.put( 'snapshot', instance_uuid, created, { 'uuid': snapshot_uuid, 'device': device, 'instance_uuid': instance_uuid, 'created': created })
def update_metrics_bulk(metrics): etcd.put('metrics', config.NODE_NAME, None, { 'fqdn': config.NODE_NAME, 'timestamp': time.time(), 'metrics': metrics }, ttl=120)
def update_network_state(network_uuid, state): n = get_network(network_uuid) n['state'] = state n['state_updated'] = time.time() etcd.put('network', None, network_uuid, n) if state == 'deleted': etcd.delete('vxlan', None, n['vxid']) etcd.delete('ipmanager', None, n['uuid'])
def see_this_node(): etcd.put('node', None, config.parsed.get('NODE_NAME'), { 'fqdn': config.parsed.get('NODE_NAME'), 'ip': config.parsed.get('NODE_IP'), 'lastseen': time.time(), }, ttl=120)
def see_this_node(): etcd.put('node', None, config.NODE_NAME, { 'fqdn': config.NODE_NAME, 'ip': config.NODE_IP, 'lastseen': time.time(), 'version': util.get_version() }, ttl=120)
def update_metrics_bulk(metrics): node = config.parsed.get('NODE_NAME') etcd.put('metrics', node, None, { 'fqdn': node, 'timestamp': time.time(), 'metrics': metrics }, ttl=120)
def place_instance(instance_uuid, node): i = get_instance(instance_uuid) # We don't write unchanged things to the database if i.get('node') == node: return i['node'] = node i['placement_attempts'] = i.get('placement_attempts', 0) + 1 etcd.put('instance', None, instance_uuid, i)
def _db_set_attribute(self, attribute, value): if self.__in_memory_only: self.__in_memory_values[attribute] = json.dumps( value, indent=4, sort_keys=True, cls=etcd.JSONEncoderCustomTypes) else: etcd.put('attribute/%s' % self.object_type, self.__uuid, attribute, value)
def test_put_DeployNetworkTask(self, mock_put): etcd.put('objecttype', 'subtype', 'name', tasks.DeployNetworkTask('fake_uuid')) path = '/sf/objecttype/subtype/name' encoded = '''{ "network_uuid": "fake_uuid", "task": "network_deploy", "version": 1 }''' mock_put.assert_called_with(path, encoded, lease=None)
def test_put_DeleteInstanceTask(self, mock_put): etcd.put('objecttype', 'subtype', 'name', tasks.DeleteInstanceTask('fake_uuid')) path = '/sf/objecttype/subtype/name' encoded = '''{ "instance_uuid": "fake_uuid", "network": [], "task": "instance_delete", "version": 1 }''' mock_put.assert_called_with(path, encoded, lease=None)
def add_event(object_type, object_uuid, operation, phase, duration, message): t = time.time() etcd.put( 'event/%s' % object_type, object_uuid, t, { 'timestamp': t, 'object_type': object_type, 'object_uuid': object_uuid, 'fqdn': config.parsed.get('NODE_NAME'), 'operation': operation, 'phase': phase, 'duration': duration, 'message': message })
def test_put_ErrorInstanceTask(self, mock_put): etcd.put('objecttype', 'subtype', 'name', tasks.ErrorInstanceTask('fake_uuid', 'dunno')) path = '/sf/objecttype/subtype/name' encoded = '''{ "error_msg": "dunno", "instance_uuid": "fake_uuid", "network": [], "task": "instance_error", "version": 1 }''' mock_put.assert_called_with(path, encoded, lease=None)
def update_instance_state(instance_uuid, state): i = get_instance(instance_uuid) # We don't write unchanged things to the database if i.get('state') == state: return orig_state = i.get('state', 'unknown') i['state'] = state i['state_updated'] = time.time() etcd.put('instance', None, instance_uuid, i) add_event('instance', instance_uuid, 'state changed', '%s -> %s' % (orig_state, state), None, None)
def allocate_console_port(instance_uuid): node = config.parsed.get('NODE_NAME') with etcd.get_lock('console', None, node): consumed = [] for value in etcd.get_all('console', node): consumed.append(value['port']) port = random.randint(30000, 50000) while port in consumed or not _port_free(port): port = random.randint(30000, 50000) etcd.put('console', node, port, { 'instance_uuid': instance_uuid, 'port': port, }) return port
def create_floating_network(netblock): ipm = ipmanager.NetBlock(netblock) etcd.put('ipmanager', None, 'floating', ipm.save()) etcd.put( 'network', None, 'floating', { 'uuid': 'floating', 'vxid': 0, 'netblock': netblock, 'provide_dhcp': False, 'provide_nat': False, 'namespace': None, 'floating_gateway': None, 'name': 'floating', 'state': 'initial', 'state_updated': time.time() })
def allocate_console_port(instance_uuid): see_this_node() node = config.parsed.get('NODE_NAME') with etcd.get_lock('sf/console/%s' % node) as _: consumed = [] for value in etcd.get_all('console', node): consumed.append(value['port']) port = random.randint(30000, 50000) while port in consumed: port = random.randint(30000, 50000) etcd.put('console', node, port, { 'instance_uuid': instance_uuid, 'port': port, }) return port
def update_instance_power_state(instance_uuid, state): i = get_instance(instance_uuid) # We don't write unchanged things to the database if i.get('power_state') == state: return # If we are in transition, and its new, then we might # not want to update just yet state_age = time.time() - i.get('power_state_updated', 0) if (i.get('power_state', '').startswith('transition-to-') and i.get('power_state_previous') == state and state_age < 70): return i['power_state_previous'] = i.get('power_state', 'unknown') i['power_state'] = state i['power_state_updated'] = time.time() etcd.put('instance', None, instance_uuid, i)
def update_instance_state(instance_uuid, state): i = get_instance(instance_uuid) if not i: LOG.withField('instance_uuid', instance_uuid).error( 'update_instance_state() Instance does not exist') return # We don't write unchanged things to the database if i.get('state') == state: return orig_state = i.get('state', 'unknown') i['state'] = state i['state_updated'] = time.time() etcd.put('instance', None, instance_uuid, i) add_event('instance', instance_uuid, 'state changed', '%s -> %s' % (orig_state, state), None, None)
def update_metrics(): global last_metrics stats = _get_stats() for metric in stats: if metric not in gauges: gauges[metric] = Gauge(metric, '') gauges[metric].set(stats[metric]) etcd.put('metrics', config.NODE_NAME, None, { 'fqdn': config.NODE_NAME, 'timestamp': time.time(), 'metrics': stats }, ttl=120) gauges['updated_at'].set_to_current_time()
def add_event(object_type, object_uuid, operation, phase, duration, message): t = time.time() LOG.withFields({ object_type: object_uuid, 'fqdn': config.NODE_NAME, 'operation': operation, 'phase': phase, 'duration': duration, 'message': message }).info('Added event') etcd.put( 'event/%s' % object_type, object_uuid, t, { 'timestamp': t, 'object_type': object_type, 'object_uuid': object_uuid, 'fqdn': config.NODE_NAME, 'operation': operation, 'phase': phase, 'duration': duration, 'message': message })
def create_network_interface(interface_uuid, netdesc, instance_uuid, order): if 'macaddress' not in netdesc or not netdesc['macaddress']: possible_mac = util.random_macaddr() mac_iface = {'interface_uuid': interface_uuid} while not etcd.create('macaddress', None, possible_mac, mac_iface): possible_mac = util.random_macaddr() netdesc['macaddress'] = possible_mac etcd.put( 'networkinterface', None, interface_uuid, { 'uuid': interface_uuid, 'network_uuid': netdesc['network_uuid'], 'instance_uuid': instance_uuid, 'macaddr': netdesc['macaddress'], 'ipv4': netdesc['address'], 'order': order, 'floating': None, 'state': 'initial', 'state_updated': time.time(), 'model': netdesc['model'] })
def create_instance(instance_uuid, name, cpus, memory_mb, disk_spec, ssh_key, user_data, namespace): see_this_node() d = { 'uuid': instance_uuid, 'name': name, 'cpus': cpus, 'memory': memory_mb, 'disk_spec': disk_spec, 'ssh_key': ssh_key, 'node': config.parsed.get('NODE_NAME'), 'console_port': allocate_console_port(instance_uuid), 'vdi_port': allocate_console_port(instance_uuid), 'user_data': user_data, 'block_devices': None, 'state': 'initial', 'state_updated': time.time(), 'namespace': namespace } etcd.put('instance', None, instance_uuid, d) return d
def allocate_network(netblock, provide_dhcp=True, provide_nat=False, name=None, namespace=None): see_this_node() netid = str(uuid.uuid4()) ipm = ipmanager.NetBlock(netblock) etcd.put('ipmanager', None, netid, ipm.save()) with etcd.get_lock('sf/vxlan') as _: vxid = 1 while etcd.get('vxlan', None, vxid): vxid += 1 etcd.put('vxlan', None, vxid, {'network_uuid': netid}) d = { 'uuid': netid, 'vxid': vxid, 'netblock': netblock, 'provide_dhcp': provide_dhcp, 'provide_nat': provide_nat, 'namespace': namespace, 'floating_gateway': None, 'name': name, 'state': 'initial', 'state_updated': time.time() } etcd.put('network', None, netid, d) return d