diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst index ae64ba8b3..1f4eea811 100644 --- a/doc/source/configuration.rst +++ b/doc/source/configuration.rst @@ -147,7 +147,6 @@ providers or images are used to create them). Example:: - name: provider2 - name: multi-precise image: precise - subnodes: 2 min-ready: 2 ready-script: setup_multinode.sh providers: @@ -172,17 +171,6 @@ providers or images are used to create them). Example:: label considered disabled. ``min-ready`` is best-effort based on available capacity and is not a guaranteed allocation. - ``subnodes`` - Used to configure multi-node support. If a `subnodes` key is supplied to - an image, it indicates that the specified number of additional nodes of the - same image type should be created and associated with each node for that - image. - - Only one node from each such group will be added to the target, the - subnodes are expected to communicate directly with each other. In the - example above, for each Precise node added to the target system, two - additional nodes will be created and associated with it. - ``ready-script`` A script to be used to perform any last minute changes to a node after it has been launched but before it is put in the READY state to receive jobs. diff --git a/nodepool/allocation.py b/nodepool/allocation.py index cf34afb18..c834dffc0 100644 --- a/nodepool/allocation.py +++ b/nodepool/allocation.py @@ -236,11 +236,11 @@ class AllocationRequest(object): art = AllocationRequestTarget(self, target, current) self.request_targets[target] = art - def addProvider(self, provider, target, subnodes): + def addProvider(self, provider, target): # Handle being called multiple times with different targets. s = self.sub_requests.get(provider) if not s: - s = AllocationSubRequest(self, provider, subnodes) + s = AllocationSubRequest(self, provider) agt = s.addTarget(self.request_targets[target]) self.sub_requests[provider] = s if s not in provider.sub_requests: @@ -263,11 +263,10 @@ class AllocationRequest(object): class AllocationSubRequest(object): """A request for a number of images from a specific provider.""" - def __init__(self, request, provider, subnodes): + def __init__(self, request, provider): self.request = request self.provider = provider self.amount = 0.0 - self.subnodes = subnodes self.targets = [] def __repr__(self): @@ -313,8 +312,7 @@ class AllocationSubRequest(object): self.amount = amount # Adjust provider and request values accordingly. self.request.amount -= amount - subnode_factor = 1 + self.subnodes - self.provider.available -= (amount * subnode_factor) + self.provider.available -= (amount) # Adjust the requested values for related sub-requests. self.request.makeRequests() # Allocate these granted nodes to targets. diff --git a/nodepool/cmd/config_validator.py b/nodepool/cmd/config_validator.py index 3a8a69553..65afd65cc 100644 --- a/nodepool/cmd/config_validator.py +++ b/nodepool/cmd/config_validator.py @@ -86,7 +86,6 @@ class ConfigValidator: 'image': str, 'min-ready': int, 'ready-script': str, - 'subnodes': int, 'providers': [{ 'name': str, }], diff --git a/nodepool/config.py b/nodepool/config.py index 1d218ed58..7a49152ba 100644 --- a/nodepool/config.py +++ b/nodepool/config.py @@ -269,7 +269,6 @@ def loadConfig(config_path): newconfig.labels[l.name] = l l.image = label['image'] l.min_ready = label.get('min-ready', 2) - l.subnodes = label.get('subnodes', 0) l.ready_script = label.get('ready-script') l.providers = {} for provider in label['providers']: diff --git a/nodepool/nodedb.py b/nodepool/nodedb.py index 62abb29da..d7ae959b7 100644 --- a/nodepool/nodedb.py +++ b/nodepool/nodedb.py @@ -43,7 +43,7 @@ STATE_NAMES = { from sqlalchemy import Table, Column, Integer, String, \ MetaData, create_engine -from sqlalchemy.orm import scoped_session, mapper, relationship, foreign +from sqlalchemy.orm import scoped_session, mapper from sqlalchemy.orm.session import Session, sessionmaker metadata = MetaData() @@ -75,24 +75,6 @@ node_table = Table( Column('comment', String(255)), mysql_engine='InnoDB', ) -subnode_table = Table( - 'subnode', metadata, - Column('id', Integer, primary_key=True), - Column('node_id', Integer, index=True, nullable=False), - # Machine name - Column('hostname', String(255), index=True), - # Provider assigned id for this machine - Column('external_id', String(255)), - # Primary IP address - Column('ip', String(255)), - # Internal/fixed IP address - Column('ip_private', String(255)), - # One of the above values - Column('state', Integer), - # Time of last state change - Column('state_time', Integer), - mysql_engine='InnoDB', - ) job_table = Table( 'job', metadata, Column('id', Integer, primary_key=True), @@ -138,38 +120,6 @@ class Node(object): session.commit() -class SubNode(object): - def __init__(self, node, - hostname=None, external_id=None, ip=None, ip_private=None, - state=BUILDING): - self.node_id = node.id - self.provider_name = node.provider_name - self.label_name = node.label_name - self.target_name = node.target_name - self.external_id = external_id - self.ip = ip - self.ip_private = ip_private - self.hostname = hostname - self.state = state - - def delete(self): - session = Session.object_session(self) - session.delete(self) - session.commit() - - @property - def state(self): - return self._state - - @state.setter - def state(self, state): - self._state = state - self.state_time = int(time.time()) - session = Session.object_session(self) - if session: - session.commit() - - class Job(object): def __init__(self, name=None, hold_on_failure=0): self.name = name @@ -184,19 +134,9 @@ class Job(object): mapper(Job, job_table) -mapper(SubNode, subnode_table, - properties=dict(_state=subnode_table.c.state)) - - mapper(Node, node_table, properties=dict( - _state=node_table.c.state, - subnodes=relationship( - SubNode, - cascade='all, delete-orphan', - uselist=True, - primaryjoin=foreign(subnode_table.c.node_id) == node_table.c.id, - backref='node'))) + _state=node_table.c.state)) class NodeDatabase(object): @@ -259,24 +199,12 @@ class NodeDatabaseSession(object): self.commit() return new - def createSubNode(self, *args, **kwargs): - new = SubNode(*args, **kwargs) - self.session().add(new) - self.commit() - return new - def getNode(self, id): nodes = self.session().query(Node).filter_by(id=id).all() if not nodes: return None return nodes[0] - def getSubNode(self, id): - nodes = self.session().query(SubNode).filter_by(id=id).all() - if not nodes: - return None - return nodes[0] - def getNodeByHostname(self, hostname): nodes = self.session().query(Node).filter_by(hostname=hostname).all() if not nodes: diff --git a/nodepool/nodepool.py b/nodepool/nodepool.py index 92c5ad038..d08c1101e 100644 --- a/nodepool/nodepool.py +++ b/nodepool/nodepool.py @@ -364,20 +364,7 @@ class OLDNodeLauncher(threading.Thread): # Save the elapsed time for statsd dt = int((time.time() - start_time) * 1000) - if self.label.subnodes: - self.log.info("Node id: %s is waiting on subnodes" % self.node.id) - - while ((time.time() - start_time) < (NODE_CLEANUP - 60)): - session.commit() - ready_subnodes = [n for n in self.node.subnodes - if n.state == nodedb.READY] - if len(ready_subnodes) == self.label.subnodes: - break - time.sleep(5) - nodelist = [] - for subnode in self.node.subnodes: - nodelist.append(('sub', subnode)) nodelist.append(('primary', self.node)) self.writeNodepoolInfo(nodelist) @@ -460,16 +447,6 @@ class OLDNodeLauncher(threading.Thread): f = ftp.open('/etc/nodepool/primary_node_private', 'w') f.write(self.node.ip_private + '\n') f.close() - # The IPs of all sub nodes in this node set - f = ftp.open('/etc/nodepool/sub_nodes', 'w') - for subnode in self.node.subnodes: - f.write(subnode.ip + '\n') - f.close() - # The private IPs of all sub nodes in this node set - f = ftp.open('/etc/nodepool/sub_nodes_private', 'w') - for subnode in self.node.subnodes: - f.write(subnode.ip_private + '\n') - f.close() # The SSH key for this node set f = ftp.open('/etc/nodepool/id_rsa', 'w') key.write_private_key(f) @@ -511,166 +488,6 @@ class OLDNodeLauncher(threading.Thread): output=True) -class SubNodeLauncher(threading.Thread): - log = logging.getLogger("nodepool.SubNodeLauncher") - - def __init__(self, nodepool, provider, label, subnode_id, - node_id, node_target_name, timeout, launch_timeout, node_az, - manager_name): - threading.Thread.__init__(self, name='SubNodeLauncher for %s' - % subnode_id) - self.provider = provider - self.label = label - self.image = provider.images[label.image] - self.node_target_name = node_target_name - self.subnode_id = subnode_id - self.node_id = node_id - self.timeout = timeout - self.nodepool = nodepool - self.launch_timeout = launch_timeout - self.node_az = node_az - self.manager_name = manager_name - - def run(self): - try: - self._run() - except Exception: - self.log.exception("Exception in run method:") - - def _run(self): - with self.nodepool.getDB().getSession() as session: - self.log.debug("Launching subnode id: %s for node id: %s" % - (self.subnode_id, self.node_id)) - try: - self.subnode = session.getSubNode(self.subnode_id) - self.manager = self.nodepool.getProviderManager(self.provider) - except Exception: - self.log.exception("Exception preparing to launch subnode " - "id: %s for node id: %s:" - % (self.subnode_id, self.node_id)) - return - - try: - start_time = time.time() - dt = self.launchSubNode(session) - failed = False - statsd_key = 'ready' - except Exception as e: - self.log.exception("%s launching subnode id: %s " - "for node id: %s in provider: %s error:" % - (e.__class__.__name__, self.subnode_id, - self.node_id, self.provider.name)) - dt = int((time.time() - start_time) * 1000) - failed = True - if hasattr(e, 'statsd_key'): - statsd_key = e.statsd_key - else: - statsd_key = 'error.unknown' - - try: - self.nodepool.launchStats(statsd_key, dt, self.image.name, - self.provider.name, - self.node_target_name, - self.node_az, - self.manager_name) - except Exception: - self.log.exception("Exception reporting launch stats:") - - if failed: - try: - self.nodepool.deleteSubNode(self.subnode, self.manager) - except Exception: - self.log.exception("Exception deleting subnode id: %s: " - "for node id: %s:" % - (self.subnode_id, self.node_id)) - return - - def launchSubNode(self, session): - start_time = time.time() - timestamp = int(start_time) - - target = self.nodepool.config.targets[self.node_target_name] - hostname = target.subnode_hostname.format( - label=self.label, provider=self.provider, node_id=self.node_id, - subnode_id=self.subnode_id, timestamp=str(timestamp)) - self.subnode.hostname = hostname - self.subnode.nodename = hostname.split('.')[0] - - cloud_image = self.nodepool.zk.getMostRecentImageUpload( - self.image.name, self.provider.name) - if not cloud_image: - raise LaunchNodepoolException("Unable to find current cloud " - "image %s in %s" % - (self.image.name, - self.provider.name)) - - self.log.info("Creating server with hostname %s in %s from image %s " - "for subnode id: %s for node id: %s" - % (hostname, self.provider.name, - self.image.name, self.subnode_id, self.node_id)) - server = self.manager.createServer( - hostname, self.image.min_ram, cloud_image.external_id, - name_filter=self.image.name_filter, az=self.node_az, - config_drive=self.image.config_drive, - nodepool_node_id=self.node_id, - nodepool_image_name=self.image.name) - server_id = server['id'] - self.subnode.external_id = server_id - session.commit() - - self.log.debug("Waiting for server %s for subnode id: %s for " - "node id: %s" % - (server_id, self.subnode_id, self.node_id)) - server = self.manager.waitForServer(server, self.launch_timeout) - if server['status'] != 'ACTIVE': - raise LaunchStatusException("Server %s for subnode id: " - "%s for node id: %s " - "status: %s" % - (server_id, self.subnode_id, - self.node_id, server['status'])) - - ip = server.get('public_v4') - ip_v6 = server.get('public_v6') - if self.provider.ipv6_preferred: - if ip_v6: - ip = ip_v6 - else: - self.log.warning('Preferred ipv6 not available, ' - 'falling back to ipv4.') - if not ip: - raise LaunchNetworkException("Unable to find public IP of server") - - self.subnode.ip_private = server.get('private_v4') - # devstack-gate multi-node depends on private_v4 being populated - # with something. On clouds that don't have a private address, use - # the public. - if not self.subnode.ip_private: - self.subnode.ip_private = server.get('public_v4') - self.subnode.ip = ip - self.log.debug("Subnode id: %s for node id: %s is running, " - "ipv4: %s, ipv6: %s" % - (self.subnode_id, self.node_id, server.get('public_v4'), - server.get('public_v6'))) - - self.log.debug("Subnode id: %s for node id: %s testing ssh at ip: %s" % - (self.subnode_id, self.node_id, ip)) - connect_kwargs = dict(key_filename=self.image.private_key) - if not utils.ssh_connect(ip, self.image.username, - connect_kwargs=connect_kwargs, - timeout=self.timeout): - raise LaunchAuthException("Unable to connect via ssh") - - # Save the elapsed time for statsd - dt = int((time.time() - start_time) * 1000) - - self.subnode.state = nodedb.READY - self.log.info("Subnode id: %s for node id: %s is ready" - % (self.subnode_id, self.node_id)) - self.nodepool.updateStats(session, self.provider.name) - - return dt - - class NodeLauncher(threading.Thread): def __init__(self, zk, node, retries): threading.Thread.__init__(self) @@ -1340,12 +1157,12 @@ class NodePool(threading.Thread): n.label_name == label_name and n.state == state)]) - def count_nodes_and_subnodes(provider_name): + def count_provider_nodes(provider_name): count = 0 for n in nodes: if n.provider_name != provider_name: continue - count += 1 + len(n.subnodes) + count += 1 return count # Add a provider for each node provider, along with current @@ -1353,7 +1170,7 @@ class NodePool(threading.Thread): allocation_providers = {} for provider in self.config.providers.values(): provider_max = provider.max_servers - n_provider = count_nodes_and_subnodes(provider.name) + n_provider = count_provider_nodes(provider.name) available = provider_max - n_provider if available < 0: self.log.warning("Provider %s over-allocated: " @@ -1436,7 +1253,7 @@ class NodePool(threading.Thread): # request should be distributed to this target). sr, agt = ar.addProvider( allocation_providers[provider.name], - at, label.subnodes) + at, 0) tlps[agt] = (target, label, self.config.providers[provider.name]) else: @@ -1470,19 +1287,6 @@ class NodePool(threading.Thread): self.log.debug("Finished node launch calculation") return nodes_to_launch - def getNeededSubNodes(self, session): - nodes_to_launch = [] - for node in session.getNodes(): - if node.label_name in self.config.labels: - expected_subnodes = \ - self.config.labels[node.label_name].subnodes - active_subnodes = len([n for n in node.subnodes - if n.state != nodedb.DELETE]) - deficit = max(expected_subnodes - active_subnodes, 0) - if deficit: - nodes_to_launch.append((node, deficit)) - return nodes_to_launch - def updateConfig(self): config = self.loadConfig() self.reconfigureZooKeeper(config) @@ -1527,16 +1331,6 @@ class NodePool(threading.Thread): self._wake_condition.release() def _run(self, session, allocation_history): - # Make up the subnode deficit first to make sure that an - # already allocated node has priority in filling its subnodes - # ahead of new nodes. - subnodes_to_launch = self.getNeededSubNodes(session) - for (node, num_to_launch) in subnodes_to_launch: - self.log.info("Need to launch %s subnodes for node id: %s" % - (num_to_launch, node.id)) - for i in range(num_to_launch): - self.launchSubNode(session, node) - nodes_to_launch = self.getNeededNodes(session, allocation_history) for (tlp, num_to_launch) in nodes_to_launch: @@ -1575,39 +1369,6 @@ class NodePool(threading.Thread): launch_timeout) t.start() - def launchSubNode(self, session, node): - try: - self._launchSubNode(session, node) - except Exception: - self.log.exception( - "Could not launch subnode for node id: %s", node.id) - - def _launchSubNode(self, session, node): - provider = self.config.providers[node.provider_name] - label = self.config.labels[node.label_name] - timeout = provider.boot_timeout - launch_timeout = provider.launch_timeout - subnode = session.createSubNode(node) - t = SubNodeLauncher(self, provider, label, subnode.id, - node.id, node.target_name, timeout, launch_timeout, - node_az=node.az, manager_name=node.manager_name) - t.start() - - def deleteSubNode(self, subnode, manager): - # Don't try too hard here, the actual node deletion will make - # sure this is cleaned up. - if subnode.external_id: - try: - self.log.debug('Deleting server %s for subnode id: ' - '%s of node id: %s' % - (subnode.external_id, subnode.id, - subnode.node.id)) - manager.cleanupServer(subnode.external_id) - manager.waitForServerDeletion(subnode.external_id) - except provider_manager.NotFound: - pass - subnode.delete() - def deleteNode(self, node_id): try: self._delete_threads_lock.acquire() @@ -1654,16 +1415,6 @@ class NodePool(threading.Thread): self.log.exception("Exception revoking node id: %s" % node.id) - for subnode in node.subnodes: - if subnode.external_id: - try: - self.log.debug('Deleting server %s for subnode id: ' - '%s of node id: %s' % - (subnode.external_id, subnode.id, node.id)) - manager.cleanupServer(subnode.external_id) - except provider_manager.NotFound: - pass - if node.external_id: try: self.log.debug('Deleting server %s for node id: %s' % @@ -1674,11 +1425,6 @@ class NodePool(threading.Thread): pass node.external_id = None - for subnode in node.subnodes: - if subnode.external_id: - manager.waitForServerDeletion(subnode.external_id) - subnode.delete() - node.delete() self.log.info("Deleted node id: %s" % node.id) @@ -1886,7 +1632,7 @@ class NodePool(threading.Thread): continue state = nodedb.STATE_NAMES[node.state] key = 'nodepool.nodes.%s' % state - total_nodes = self.config.labels[node.label_name].subnodes + 1 + total_nodes = 1 states[key] += total_nodes # NOTE(pabelanger): Check if we assign nodes via Gearman if so, use diff --git a/nodepool/tests/fixtures/config_validate/good.yaml b/nodepool/tests/fixtures/config_validate/good.yaml index dd9cafeee..087bdfa9e 100644 --- a/nodepool/tests/fixtures/config_validate/good.yaml +++ b/nodepool/tests/fixtures/config_validate/good.yaml @@ -21,7 +21,6 @@ labels: - name: trusty-2-node image: trusty ready-script: multinode_setup.sh - subnodes: 1 min-ready: 0 providers: - name: cloud1 diff --git a/nodepool/tests/fixtures/config_validate/yaml_error.yaml b/nodepool/tests/fixtures/config_validate/yaml_error.yaml index 08dd9626c..c8996334e 100644 --- a/nodepool/tests/fixtures/config_validate/yaml_error.yaml +++ b/nodepool/tests/fixtures/config_validate/yaml_error.yaml @@ -21,7 +21,6 @@ labels: - name: trusty-2-node image: trusty ready-script: multinode_setup.sh - subnodes: 1 min-ready: 0 providers: - name: cloud1 diff --git a/nodepool/tests/fixtures/subnodes.yaml b/nodepool/tests/fixtures/subnodes.yaml deleted file mode 100644 index 53c9ff8b3..000000000 --- a/nodepool/tests/fixtures/subnodes.yaml +++ /dev/null @@ -1,61 +0,0 @@ -elements-dir: . -images-dir: '{images_dir}' - -cron: - check: '*/15 * * * *' - cleanup: '*/1 * * * *' - -zookeeper-servers: - - host: {zookeeper_host} - port: {zookeeper_port} - chroot: {zookeeper_chroot} - -labels: - - name: fake-label - image: fake-image - min-ready: 2 - providers: - - name: fake-provider - - name: multi-fake - image: fake-image - ready-script: multinode_setup.sh - subnodes: 2 - min-ready: 2 - providers: - - name: fake-provider - -providers: - - name: fake-provider - region-name: fake-region - keypair: 'if-present-use-this-keypair' - username: 'fake' - password: 'fake' - auth-url: 'fake' - project-id: 'fake' - max-servers: 96 - pool: 'fake' - networks: - - net-id: 'some-uuid' - rate: 0.0001 - images: - - name: fake-image - min-ram: 8192 - name-filter: 'Fake' - meta: - key: value - key2: value - -targets: - - name: fake-target - -diskimages: - - name: fake-image - elements: - - fedora - - vm - release: 21 - env-vars: - TMPDIR: /opt/dib_tmp - DIB_IMAGE_CACHE: /opt/dib_cache - DIB_CLOUD_IMAGES: http://download.fedoraproject.org/pub/fedora/linux/releases/test/21-Beta/Cloud/Images/x86_64/ - BASE_IMAGE_FILE: Fedora-Cloud-Base-20141029-21_Beta.x86_64.qcow2 diff --git a/nodepool/tests/test_allocator.py b/nodepool/tests/test_allocator.py index cdcdc408b..23279f606 100644 --- a/nodepool/tests/test_allocator.py +++ b/nodepool/tests/test_allocator.py @@ -40,7 +40,7 @@ class OneLabel(tests.AllocatorTestCase, tests.BaseTestCase): at1 = allocation.AllocationTarget('target1') ar1 = allocation.AllocationRequest('label1', self.label1) ar1.addTarget(at1, 0) - self.agt.append(ar1.addProvider(ap1, at1, 0)[1]) + self.agt.append(ar1.addProvider(ap1, at1)[1]) ap1.makeGrants() @@ -67,8 +67,8 @@ class TwoLabels(tests.AllocatorTestCase, tests.BaseTestCase): ar2 = allocation.AllocationRequest('label2', self.label2) ar1.addTarget(at1, 0) ar2.addTarget(at1, 0) - self.agt.append(ar1.addProvider(ap1, at1, 0)[1]) - self.agt.append(ar2.addProvider(ap1, at1, 0)[1]) + self.agt.append(ar1.addProvider(ap1, at1)[1]) + self.agt.append(ar2.addProvider(ap1, at1)[1]) ap1.makeGrants() @@ -115,10 +115,10 @@ class TwoProvidersTwoLabels(tests.AllocatorTestCase, tests.BaseTestCase): ar2 = allocation.AllocationRequest('label2', self.label2) ar1.addTarget(at1, 0) ar2.addTarget(at1, 0) - self.agt.append(ar1.addProvider(ap1, at1, 0)[1]) - self.agt.append(ar2.addProvider(ap1, at1, 0)[1]) - self.agt.append(ar1.addProvider(ap2, at1, 0)[1]) - self.agt.append(ar2.addProvider(ap2, at1, 0)[1]) + self.agt.append(ar1.addProvider(ap1, at1)[1]) + self.agt.append(ar2.addProvider(ap1, at1)[1]) + self.agt.append(ar1.addProvider(ap2, at1)[1]) + self.agt.append(ar2.addProvider(ap2, at1)[1]) ap1.makeGrants() ap2.makeGrants() @@ -170,9 +170,9 @@ class TwoProvidersTwoLabelsOneShared(tests.AllocatorTestCase, ar2 = allocation.AllocationRequest('label2', self.label2) ar1.addTarget(at1, 0) ar2.addTarget(at1, 0) - self.agt.append(ar1.addProvider(ap1, at1, 0)[1]) - self.agt.append(ar2.addProvider(ap1, at1, 0)[1]) - self.agt.append(ar2.addProvider(ap2, at1, 0)[1]) + self.agt.append(ar1.addProvider(ap1, at1)[1]) + self.agt.append(ar2.addProvider(ap1, at1)[1]) + self.agt.append(ar2.addProvider(ap2, at1)[1]) ap1.makeGrants() ap2.makeGrants() @@ -293,8 +293,8 @@ class RoundRobinAllocation(tests.RoundRobinTestCase, tests.BaseTestCase): # providers for ar in ars: ar.addTarget(at1, 0) - ar.addProvider(ap1, at1, 0) - ar.addProvider(ap2, at1, 0) + ar.addProvider(ap1, at1) + ar.addProvider(ap2, at1) ap1.makeGrants() for g in ap1.grants: @@ -414,15 +414,15 @@ class RoundRobinFixedProvider(tests.RoundRobinTestCase, tests.BaseTestCase): # first ar can only go to provider1, the last only to # provider2 ars[0].addTarget(at1, 0) - ars[0].addProvider(ap1, at1, 0) + ars[0].addProvider(ap1, at1) ars[-1].addTarget(at1, 0) - ars[-1].addProvider(ap2, at1, 0) + ars[-1].addProvider(ap2, at1) # the rest can go anywhere for ar in ars[1:-1]: ar.addTarget(at1, 0) - ar.addProvider(ap1, at1, 0) - ar.addProvider(ap2, at1, 0) + ar.addProvider(ap1, at1) + ar.addProvider(ap2, at1) ap1.makeGrants() for g in ap1.grants: diff --git a/nodepool/tests/test_nodepool.py b/nodepool/tests/test_nodepool.py index c614a9cbd..c82cba68f 100644 --- a/nodepool/tests/test_nodepool.py +++ b/nodepool/tests/test_nodepool.py @@ -214,69 +214,6 @@ class TestNodepool(tests.DBTestCase): state=nodedb.READY) self.assertEqual(len(nodes), 2) - @skip("Disabled for early v3 development") - def test_subnodes(self): - """Test that an image and node are created""" - configfile = self.setup_config('subnodes.yaml') - pool = self.useNodepool(configfile, watermark_sleep=1) - self._useBuilder(configfile) - pool.start() - self.waitForImage('fake-provider', 'fake-image') - self.waitForNodes(pool) - - with pool.getDB().getSession() as session: - nodes = session.getNodes(provider_name='fake-provider', - label_name='fake-label', - target_name='fake-target', - state=nodedb.READY) - self.assertEqual(len(nodes), 2) - nodes = session.getNodes(provider_name='fake-provider', - label_name='multi-fake', - target_name='fake-target', - state=nodedb.READY) - self.assertEqual(len(nodes), 2) - for node in nodes: - self.assertEqual(len(node.subnodes), 2) - for subnode in node.subnodes: - self.assertEqual(subnode.state, nodedb.READY) - - @skip("Disabled for early v3 development") - def test_subnode_deletion_success(self): - """Test that subnodes are deleted with parent node""" - configfile = self.setup_config('subnodes.yaml') - pool = self.useNodepool(configfile, watermark_sleep=1) - self._useBuilder(configfile) - pool.start() - self.waitForImage('fake-provider', 'fake-image') - self.waitForNodes(pool) - - subnode_ids = [] - node_ids = [] - - with pool.getDB().getSession() as session: - nodes = session.getNodes(provider_name='fake-provider', - label_name='multi-fake', - target_name='fake-target', - state=nodedb.READY) - self.assertEqual(len(nodes), 2) - for node in nodes: - self.assertEqual(len(node.subnodes), 2) - for subnode in node.subnodes: - self.assertEqual(subnode.state, nodedb.READY) - subnode_ids.append(subnode.id) - node_ids.append(node.id) - - for node_id in node_ids: - pool.deleteNode(node_id) - - self.wait_for_threads() - self.waitForNodes(pool) - - with pool.getDB().getSession() as session: - for subnode_id in subnode_ids: - s = session.getSubNode(subnode_id) - self.assertIsNone(s) - @skip("Disabled for early v3 development") def test_node_az(self): """Test that an image and node are created with az specified""" diff --git a/tools/fake.yaml b/tools/fake.yaml index faf6e87c5..94425ce63 100644 --- a/tools/fake.yaml +++ b/tools/fake.yaml @@ -28,7 +28,6 @@ labels: - name: multi-fake image: fake-nodepool ready-script: multinode_setup.sh - subnodes: 2 min-ready: 2 providers: - name: fake-provider