def _export_deployment_manifest(self, deployment, deployment_dir): deployment_dir.mkdir(parents=True, exist_ok=True) deployment_manifest_file = deployment_dir / UvnDefaults["registry"][ "deployment_file"] db_args = self.identity_db.get_export_args() yml(deployment, to_file=deployment_manifest_file, **db_args) # Generate a human-readable summary report_file = deployment_dir / UvnDefaults["registry"][ "deployment_report"] deployment_summary = UvnDeploymentSummary(self, deployment) render(deployment_summary, "human", to_file=report_file) logger.activity("generated deployment summary: {}", report_file)
def export(self, force=False): def exportable(obj): return not obj.loaded or obj.dirty or force if exportable(self): outfile = self.identity_db.registry_id.basedir / UvnDefaults[ "nameserver"]["persist_file"] logger.debug("exporting nameserver to {}", outfile) db_args = self.identity_db.get_export_args() yml(self, to_file=outfile, **db_args) self.dirty = False self.loaded = True
def export(self, cell=None, drop_old_deployments=False, drop_stale_deployments=False, force=False, keep=False): if drop_old_deployments or drop_stale_deployments: self._drop_deployments(keep_last=drop_old_deployments, stale_only=drop_stale_deployments) latest_deployment_dir = self.paths.dir_deployment( deployment_id=UvnDefaults["registry"]["deployment_default"]) if latest_deployment_dir.exists(): latest_deployment_dir.unlink() outfile = self.paths.basedir / UvnDefaults["registry"]["persist_file"] def exportable(obj): return not obj.loaded or obj.dirty or force if exportable(self): logger.debug("exporting registry to {}", outfile) db_args = self.identity_db.get_export_args() yml(self, to_file=outfile, owner_cell=cell, **db_args) # Export particle packages for p in self.particles.values(): pkg_dir = self.paths.dir_particles(p.name) self._export_particle_package(pkg_dir, particle=p, keep=keep) else: logger.debug("skipping exporting registry to {}", outfile) self.nameserver.export(force=force) for cell_name, cell in self.cells.items(): if exportable(cell): # or exportable(self): pkg_dir = self.paths.dir_cell_bootstrap(cell.id.name) self._export_cell_package(pkg_dir, cell=cell, keep=keep) for deployment in self.deployments: if exportable(deployment): deployment_dir = self.paths.dir_deployment(deployment.id) self._export_deployment_manifest(deployment, deployment_dir) for cell_cfg in deployment.deployed_cells: pkg_dir = self.paths.dir_cell_pkg(cell_cfg.cell.id.name, deployment.id) self._export_cell_package(pkg_dir, cell_cfg=cell_cfg, deployment=deployment, keep=keep) if len(self.deployments) > 0 and not self.packaged: self._link_latest_deployment()
def export(self, basedir, keep=False): basedir = pathlib.Path(basedir) # Create directory for installer files installer_dir = basedir / UvnDefaults["cell"]["pkg"]["installer"]["filename_fmt"].format( self.uvn_address, self.uvn_deployment, self.cell_name) installer_dir.mkdir(parents=True, exist_ok=True) installer_files = UvnCellInstaller._installer_files( installer_dir, bootstrap=self._bootstrap) # Export installer manifest yml(self, to_file=installer_files["manifest"]) # Copy cell's package shutil.copyfile(str(self.cell_pkg), installer_files["cell_pkg"]) # Copy cell's package signature shutil.copyfile(str(self.cell_sig), installer_files["cell_sig"]) if self._bootstrap: # Export uvn's public key with installer_files["uvn_public_key"].open("w") as output: output.write(self.uvn_public_key) # Export cells's public key with installer_files["cell_public_key"].open("w") as output: output.write(self.cell_public_key) # Export cells's private key with installer_files["cell_private_key"].open("w") as output: output.write(self.cell_private_key) # Export cells's secret with installer_files["cell_secret"].open("w") as output: output.write(self.cell_secret) shutil.make_archive(str(installer_dir), UvnDefaults["cell"]["pkg"]["clear_format"], root_dir=installer_dir) if not keep: shutil.rmtree(str(installer_dir)) else: logger.warning("[tmp] not deleted: {}", installer_dir) installer = "".join([str(installer_dir), UvnDefaults["cell"]["pkg"]["ext_clear"]]) installer = pathlib.Path(installer) logger.activity("generated installer: {}", installer.name)
def format(t, obj): if t == DataFormat.JSON: return json(obj, public_only=True) elif t == DataFormat.YAML: return yml(obj, public_only=True) else: return str(obj)
def render_yml(self, obj, **kwargs): return yml(obj, **kwargs)
def _export_cell_package(self, pkg_dir, cell=None, cell_cfg=None, deployment=None, keep=False): # Check if we are generating a "bootstrap" or a "deployment" package bootstrap = cell_cfg is None or deployment is None if cell_cfg is not None and deployment is None: raise UvnException("no deployment with cell_cfg: {}", cell_cfg.cell.id.name) if not bootstrap: cell = cell_cfg.cell deployment_id = deployment.id archive_out_dir = self.paths.dir_deployment( deployment_id) / UvnDefaults["registry"]["deployment_packages"] else: deployment_id = UvnDefaults["registry"]["deployment_bootstrap"] archive_out_dir = self.paths.dir_cell_bootstrap( ) / UvnDefaults["registry"]["deployment_packages"] logger.debug("Generating package for cell {} in {}", cell.id.name, pkg_dir) pkg_dir.mkdir(parents=True, exist_ok=True) db_args = self.identity_db.get_export_args() # Serialize cell manifest cell_manifest = pkg_dir / UvnDefaults["registry"]["cell_file"] yml(cell, to_file=cell_manifest, **db_args) # Serialize registry manifest registry_manifest = pkg_dir / UvnDefaults["registry"]["persist_file"] yml(self, to_file=registry_manifest, target_cell=cell, deployed_cell=cell_cfg, deployment_id=deployment_id, **db_args) # Serialize nameserver database ns_db = pkg_dir / UvnDefaults["nameserver"]["persist_file"] yml(self.nameserver, to_file=ns_db, **db_args) db_export_args = {"tgt_cell": cell} # Serialize identity database (db_dir, db_manifest, cell_secret) = self.identity_db.export_cell(self, pkg_dir=pkg_dir, **db_export_args) if not bootstrap: # Serialize deployment deployment_manifest = self.paths.dir_deployment( deployment_id=deployment.id, basedir=pkg_dir) / UvnDefaults["registry"]["deployment_file"] yml(deployment, to_file=deployment_manifest, tgt_cell_cfg=cell_cfg, deployment_id=deployment.id, **db_args) # Create package archive archive_path = self._zip_cell_pkg(deployment_id=deployment_id, cell_name=cell.id.name, cell_pkg_dir=pkg_dir, archive_out_dir=archive_out_dir) # Encrypt archive encrypt_result = self._encrypt_file_for_cell(cell.id.name, archive_path) if not keep: # Delete unencrypted archive archive_path.unlink() # Delete staging directory try: # For some reason, this call succeeds on x86_64, but fails # on RPi with error: "No such file or directory: 'S.gpg-agent.ssh'" shutil.rmtree(str(pkg_dir)) except Exception as e: logger.exception(e) logger.warning("failed to remove build directory: {}", pkg_dir) else: logger.warning("[tmp] not deleted: {}", archive_path) logger.warning("[tmp] not deleted: {}", pkg_dir) cell_record = self.identity_db.get_cell_record(cell.id.name) if not cell_record: raise UvnException( f"cell record not found in db: {cell.id.address}") installer = UvnCellInstaller( uvn_admin=self.identity_db.registry_id.admin, uvn_address=self.identity_db.registry_id.address, uvn_deployment=deployment_id, cell_name=cell.id.name, cell_address=cell.id.address, cell_admin=cell.id.admin, uvn_public_key=self.identity_db.registry_id.key.public, cell_public_key=cell_record.key.public, cell_private_key=cell_record.key.private, cell_secret=self.identity_db._secret_cell(cell.id.name, cell.id.admin), cell_pkg=str(encrypt_result["output"]), cell_sig=str(encrypt_result["signature"])) basedir = self.paths.basedir / UvnDefaults["registry"]["installers_dir"] installer.export(basedir=basedir, keep=keep)
def _on_stat(self): self._file.parent.mkdir(exist_ok=True, parents=True) with self._agent._lock: stat = self._stat() yml(stat, to_file=self._file)