def wrapper(*args, **kwargs): if 'network_uuid' in kwargs: kwargs['network_from_db'] = db.get_network( kwargs['network_uuid']) if not kwargs.get('network_from_db'): return error(404, 'network not found') return func(*args, **kwargs)
def from_db(uuid): dbnet = db.get_network(uuid) if not dbnet: return None if dbnet['state'] == 'deleted': LOG.withNetwork(uuid).info('Network is deleted, returning None.') return None return Network(dbnet)
def wrapper(*args, **kwargs): if 'network_uuid' in kwargs: kwargs['network_from_db'] = db.get_network(kwargs['network_uuid']) if not kwargs.get('network_from_db'): logutil.info([net.ThinNetwork(kwargs['network_uuid'])], 'Network not found, missing or deleted') return error(404, 'network not found') return func(*args, **kwargs)
def wrapper(*args, **kwargs): if 'network_uuid' in kwargs: kwargs['network_from_db'] = db.get_network(kwargs['network_uuid']) if not kwargs.get('network_from_db'): LOG.info('network(%s): network not found, genuinely missing' % kwargs['network_uuid']) return error(404, 'network not found') return func(*args, **kwargs)
def is_dead(self): """Check if the network is deleted or being deleted, or in error. First, update the object model to the ensure latest configuration. Some callers will wait on a lock before calling this function. In this case we definitely need to update the in-memory object model. """ # TODO(andy): To be improved when object model mirrors Image class self.db_entry = db.get_network(self.db_entry['uuid']) return self.db_entry['state'] in ('deleted', 'deleting', 'error')
def from_db(uuid): dbnet = db.get_network(uuid) if not dbnet: return None return Network(uuid=dbnet['uuid'], vxlan_id=dbnet['vxid'], provide_dhcp=dbnet['provide_dhcp'], provide_nat=dbnet['provide_nat'], ipblock=dbnet['netblock'], physical_nic=config.parsed.get('NODE_EGRESS_NIC'), floating_gateway=dbnet['floating_gateway'], namespace=dbnet['namespace'])
def from_db(uuid): # TODO(andy): The whole system of unlocked in-memory objects needs to be # revisited. This lock avoids the network being deleted between the DB load # in the get_network() call and Network.__init__() loading the IPManager # from the DB. Under extreme load testing, instance starts on the same # network will have multi-second start delays due to lock contention . with db.get_lock('network', None, uuid, ttl=10, timeout=120, op='Object load from DB'): dbnet = db.get_network(uuid) if not dbnet: return None if dbnet['state'] in ('deleted', 'deleting'): LOG.withNetwork(uuid).info('Network is deleted, returning None.') return None return Network(dbnet)
def from_db(uuid): dbnet = db.get_network(uuid) if not dbnet: return None n = Network(uuid=dbnet['uuid'], vxlan_id=dbnet['vxid'], provide_dhcp=dbnet['provide_dhcp'], provide_nat=dbnet['provide_nat'], ipblock=dbnet['netblock'], physical_nic=config.parsed.get('NODE_EGRESS_NIC'), floating_gateway=dbnet['floating_gateway'], namespace=dbnet['namespace']) if dbnet['state'] == 'deleted': logutil.info([n], 'Netowrk is deleted, returning None.') return None return n
def main(): global DAEMON_IMPLEMENTATIONS global DAEMON_PIDS setproctitle.setproctitle(daemon.process_name('main')) # Log configuration on startup for key, value in config.dict().items(): LOG.info('Configuration item %s = %s' % (key, value)) daemon.set_log_level(LOG, 'main') # Check in early and often, also reset processing queue items db.clear_stale_locks() db.see_this_node() db.restart_queues() def _start_daemon(d): pid = os.fork() if pid == 0: DAEMON_IMPLEMENTATIONS[d].Monitor(d).run() DAEMON_PIDS[pid] = d LOG.withField('pid', pid).info('Started %s' % d) # Resource usage publisher, we need this early because scheduling decisions # might happen quite early on. _start_daemon('resources') # If I am the network node, I need some setup if util.is_network_node(): # Bootstrap the floating network in the Networks table floating_network = db.get_network('floating') if not floating_network: db.create_floating_network(config.get('FLOATING_NETWORK')) floating_network = net.from_db('floating') subst = { 'physical_bridge': util.get_safe_interface_name('phy-br-%s' % config.get('NODE_EGRESS_NIC')), 'physical_nic': config.get('NODE_EGRESS_NIC') } if not util.check_for_interface(subst['physical_bridge']): # NOTE(mikal): Adding the physical interface to the physical bridge # is considered outside the scope of the orchestration software as # it will cause the node to lose network connectivity. So instead # all we do is create a bridge if it doesn't exist and the wire # everything up to it. We can do egress NAT in that state, even if # floating IPs don't work. with util.RecordedOperation('create physical bridge', None): # No locking as read only ipm = db.get_ipmanager('floating') subst['master_float'] = ipm.get_address_at_index(1) subst['netmask'] = ipm.netmask util.create_interface(subst['physical_bridge'], 'bridge', '') util.execute(None, 'ip link set %(physical_bridge)s up' % subst) util.execute( None, 'ip addr add %(master_float)s/%(netmask)s ' 'dev %(physical_bridge)s' % subst) util.execute( None, 'iptables -A FORWARD -o %(physical_nic)s ' '-i %(physical_bridge)s -j ACCEPT' % subst) util.execute( None, 'iptables -A FORWARD -i %(physical_nic)s ' '-o %(physical_bridge)s -j ACCEPT' % subst) util.execute( None, 'iptables -t nat -A POSTROUTING ' '-o %(physical_nic)s -j MASQUERADE' % subst) def _audit_daemons(): running_daemons = [] for pid in DAEMON_PIDS: running_daemons.append(DAEMON_PIDS[pid]) for d in DAEMON_IMPLEMENTATIONS: if d not in running_daemons: _start_daemon(d) for d in DAEMON_PIDS: if not psutil.pid_exists(d): LOG.warning('%s pid is missing, restarting' % DAEMON_PIDS[d]) _start_daemon(DAEMON_PIDS[d]) _audit_daemons() restore_instances() while True: time.sleep(10) wpid, _ = os.waitpid(-1, os.WNOHANG) while wpid != 0: LOG.warning('%s died (pid %d)' % (DAEMON_PIDS.get(wpid, 'unknown'), wpid)) del DAEMON_PIDS[wpid] wpid, _ = os.waitpid(-1, os.WNOHANG) _audit_daemons() db.see_this_node()
def main(): # Log configuration on startup for key in config.parsed.config: LOG.info('Configuration item %s = %s' % (key, config.parsed.get(key))) # Check in early and often db.see_this_node() # Resource usage publisher, we need this early because scheduling decisions # might happen quite early on. resource_pid = os.fork() if resource_pid == 0: resource_daemon.monitor().run() # If I am the network node, I need some setup if config.parsed.get('NODE_IP') == config.parsed.get('NETWORK_NODE_IP'): # Bootstrap the floating network in the Networks table floating_network = db.get_network('floating') if not floating_network: db.create_floating_network(config.parsed.get('FLOATING_NETWORK')) floating_network = net.from_db('floating') subst = { 'physical_bridge': 'phy-br-%s' % config.parsed.get('NODE_EGRESS_NIC'), 'physical_nic': config.parsed.get('NODE_EGRESS_NIC') } if not util.check_for_interface(subst['physical_bridge']): # NOTE(mikal): Adding the physical interface to the physical bridge # is considered outside the scope of the orchestration software as it # will cause the node to lose network connectivity. So instead all we # do is create a bridge if it doesn't exist and the wire everything up # to it. We can do egress NAT in that state, even if floating IPs # don't work. with util.RecordedOperation('create physical bridge', 'startup') as _: # No locking as read only ipm = db.get_ipmanager('floating') subst['master_float'] = ipm.get_address_at_index(1) subst['netmask'] = ipm.netmask processutils.execute( 'ip link add %(physical_bridge)s type bridge' % subst, shell=True) processutils.execute('ip link set %(physical_bridge)s up' % subst, shell=True) processutils.execute( 'ip addr add %(master_float)s/%(netmask)s dev %(physical_bridge)s' % subst, shell=True) processutils.execute( 'iptables -A FORWARD -o %(physical_nic)s -i %(physical_bridge)s -j ACCEPT' % subst, shell=True) processutils.execute( 'iptables -A FORWARD -i %(physical_nic)s -o %(physical_bridge)s -j ACCEPT' % subst, shell=True) processutils.execute( 'iptables -t nat -A POSTROUTING -o %(physical_nic)s -j MASQUERADE' % subst, shell=True) # Network mesh maintenance net_pid = os.fork() if net_pid == 0: net_daemon.monitor().run() # Old object deleter cleaner_pid = os.fork() if cleaner_pid == 0: cleaner_daemon.monitor().run() # REST API external_api_pid = os.fork() if external_api_pid == 0: external_api_daemon.monitor().run() # Triggers trigger_pid = os.fork() if trigger_pid == 0: trigger_daemon.monitor().run() setproctitle.setproctitle('sf main') LOG.info('network monitor pid is %d' % net_pid) LOG.info('external api pid is %d' % external_api_pid) LOG.info('resources monitor pid is %d' % resource_pid) LOG.info('cleaner pid is %d' % cleaner_pid) LOG.info('trigger pid is %d' % trigger_pid) restore_instances() procnames = { external_api_pid: 'external api', net_pid: 'network monitor', resource_pid: 'resource monitor', cleaner_pid: 'cleaner' } while True: time.sleep(10) wpid, _ = os.waitpid(-1, os.WNOHANG) if wpid != 0: LOG.warning('Subprocess %d (%s) died' % (wpid, procnames.get(wpid, 'unknown')))