def find_node_package_lists(self, nodename, task): """Return all packages to be installed on ``nodename`` :param nodename: The name of the node to retrieve packages for :param task: The task initiating this request """ design_status, site_design = self.get_effective_site(task.design_ref) if site_design.bootactions is None: return None self.logger.debug("Extracting package install list for node %s" % nodename) pkg_list = dict() for ba in site_design.bootactions: if nodename in ba.target_nodes: # NOTE(sh8121att) the ulid generation below # is throw away data as these assets are only used to # get a full list of packages to deploy assets = ba.render_assets( nodename, site_design, ulid2.generate_binary_ulid(), ulid2.generate_binary_ulid(), task.design_ref, type_filter=hd_fields.BootactionAssetType.PackageList) for a in assets: pkg_list.update(a.package_list) return pkg_list
def create_bootaction_context(self, nodename, task): """Save a boot action context for ``nodename`` Generate a identity key and persist the boot action context for nodename pointing at the top level task. Return the generated identity key as ``bytes``. :param nodename: Name of the node the bootaction context is targeted for :param task: The task instigating the ndoe deployment """ design_status, site_design = self.get_effective_site(task.design_ref) if site_design.bootactions is None: return None identity_key = None for ba in site_design.bootactions: if nodename in ba.target_nodes: if identity_key is None: identity_key = os.urandom(32) self.state_manager.post_boot_action_context( nodename, task.get_id(), identity_key) action_id = ulid2.generate_binary_ulid() self.state_manager.post_boot_action(nodename, task.get_id(), identity_key, action_id, ba.name) return identity_key
def test_bootaction_tarbuilder(self, input_files, deckhand_ingester, setup): objects.register_all() input_file = input_files.join("deckhand_fullsite.yaml") design_state = DrydockState() design_ref = "file://%s" % str(input_file) design_status, design_data = deckhand_ingester.ingest_data( design_state=design_state, design_ref=design_ref) target_host = 'compute01' ba = design_data.get_bootaction('helloworld') action_id = ulid2.generate_binary_ulid() assets = ba.render_assets(target_host, design_data, action_id) assert len(assets) > 0 tarbytes = BootactionUtils.tarbuilder(assets) assert tarbytes is not None fileobj = io.BytesIO(tarbytes) tarball = tarfile.open(mode='r:gz', fileobj=fileobj) tarasset = tarball.getmember('/var/tmp/hello.sh') assert tarasset.mode == 0o555
def test_bootaction_post(self, populateddb, drydock_state): """Test that a boot action status can be added.""" id_key = os.urandom(32) action_id = ulid2.generate_binary_ulid() nodename = 'testnode' result = drydock_state.post_boot_action(nodename, populateddb.get_id(), id_key, action_id, 'helloworld') assert result
def test_bootaction_get(self, populateddb, drydock_state): """Test that a boot action status can be retrieved.""" id_key = os.urandom(32) action_id = ulid2.generate_binary_ulid() nodename = 'testnode' drydock_state.post_boot_action(nodename, populateddb.get_id(), id_key, action_id, 'helloworld') ba = drydock_state.get_boot_action(ulid2.encode_ulid_base32(action_id)) assert ba.get('identity_key') == id_key
def test_bootaction_put(self, populateddb, drydock_state): """Test that a boot action status can be updated.""" id_key = os.urandom(32) action_id = ulid2.generate_binary_ulid() nodename = 'testnode' drydock_state.post_boot_action(nodename, populateddb.get_id(), id_key, action_id, 'helloworld') result = drydock_state.put_bootaction_status( ulid2.encode_ulid_base32(action_id), action_status=objects.fields.ActionResult.Success) assert result
def test_bootaction_render(self, input_files, deckhand_ingester, setup): objects.register_all() input_file = input_files.join("deckhand_fullsite.yaml") design_state = DrydockState() design_ref = "file://%s" % str(input_file) design_status, design_data = deckhand_ingester.ingest_data( design_state=design_state, design_ref=design_ref) ba = design_data.get_bootaction('helloworld') action_id = ulid2.generate_binary_ulid() assets = ba.render_assets('compute01', design_data, action_id) assert 'compute01' in assets[0].rendered_bytes.decode('utf-8')
def create_bootaction_context(self, nodename, task): """Save a boot action context for ``nodename`` Generate a identity key and persist the boot action context for nodename pointing at the top level task. Return the generated identity key as ``bytes``. :param nodename: Name of the node the bootaction context is targeted for :param task: The task instigating the ndoe deployment """ design_status, site_design = self.get_effective_site(task.design_ref) if site_design.bootactions is None: return None identity_key = None self.logger.debug( "Creating boot action context for node %s" % nodename) for ba in site_design.bootactions: self.logger.debug( "Boot actions target nodes: %s" % ba.target_nodes) if nodename in ba.target_nodes: if identity_key is None: identity_key = os.urandom(32) self.state_manager.post_boot_action_context( nodename, task.get_id(), identity_key) self.logger.debug( "Adding boot action %s for node %s to the database." % (ba.name, nodename)) if ba.signaling: init_status = hd_fields.ActionResult.Incomplete else: init_status = hd_fields.ActionResult.Unreported self.logger.debug( "Boot action %s has disabled signaling, marking unreported." % ba.name) action_id = ulid2.generate_binary_ulid() self.state_manager.post_boot_action( nodename, task.get_id(), identity_key, action_id, ba.name, action_status=init_status) return identity_key
def test_bootaction_render_nodename(self, input_files, deckhand_ingester, setup): """Test the bootaction render routine provides expected output.""" input_file = input_files.join("deckhand_fullsite.yaml") design_state = DrydockState() design_ref = "file://%s" % str(input_file) design_status, design_data = deckhand_ingester.ingest_data( design_state=design_state, design_ref=design_ref) ba = design_data.get_bootaction('helloworld') action_id = ulid2.generate_binary_ulid() assets = ba.render_assets('compute01', design_data, action_id, design_ref) assert 'compute01' in assets[0].rendered_bytes.decode('utf-8')
def seed_bootaction_status(self, blank_state, test_orchestrator, input_files): """Add a task and boot action to the database for testing.""" input_file = input_files.join("fullsite.yaml") design_ref = "file://%s" % input_file test_task = test_orchestrator.create_task( action=hd_fields.OrchestratorAction.Noop, design_ref=design_ref) id_key = os.urandom(32) action_id = ulid2.generate_binary_ulid() blank_state.post_boot_action('compute01', test_task.get_id(), id_key, action_id, 'helloworld') ba = dict(nodename='compute01', task_id=test_task.get_id(), identity_key=id_key.hex(), action_id=ulid2.encode_ulid_base32(action_id)) return ba
def test_bootaction_render_key(self, input_files, deckhand_ingester, setup): """Test that a bootaction can render the correct action_id and action_key needed by the signalling API.""" input_file = input_files.join("deckhand_fullsite.yaml") design_state = DrydockState() design_ref = "file://%s" % str(input_file) design_status, design_data = deckhand_ingester.ingest_data( design_state=design_state, design_ref=design_ref) ba = design_data.get_bootaction('helloworld') action_id = ulid2.generate_binary_ulid() action_key = os.urandom(32) assets = ba.render_assets('compute01', design_data, action_id, action_key, design_ref) assert action_key.hex() in assets[2].rendered_bytes.decode('utf-8') assert ulid2.ulid_to_base32( action_id) in assets[2].rendered_bytes.decode('utf-8')
def test_conversion_roundtrip(): ulid = generate_binary_ulid() encoded = ulid_to_base32(ulid) uuid = ulid_to_uuid(ulid) assert ulid_to_binary(uuid) == ulid_to_binary(ulid) assert ulid_to_binary(encoded) == ulid_to_binary(ulid)
def test_ulid_binary_length(): assert len(generate_binary_ulid()) == 128 / 8