def _inspect_system_branch(self, repo, imagebranch): commit_rev = repo.resolve_rev(imagebranch, False)[1] commit = repo.load_commit(commit_rev)[1] branch_id = imagebranch.replace(OSTREE_OCIIMAGE_PREFIX, "") tag = ":".join(branch_id.rsplit('-', 1)) timestamp = OSTree.commit_get_timestamp(commit) labels = {} manifest = self._image_manifest(repo, commit_rev) if len(branch_id) == 64: image_id = branch_id tag = "<none>" else: image_id = commit_rev if manifest: manifest = json.loads(manifest) if 'Labels' in manifest: labels = manifest['Labels'] if 'Digest' in manifest: image_id = manifest['Digest'].replace("sha256:", "") if self.user: image_type = "user" else: image_type = "system" return {'Id' : image_id, 'ImageId' : image_id, 'RepoTags' : [tag], 'Names' : [], 'Created': timestamp, 'ImageType' : image_type, 'Labels' : labels, 'OSTree-rev' : commit_rev}
def create_disks(self): [res,rev] = self.repo.resolve_rev(self.ref, False) [res,commit] = self.repo.load_variant(OSTree.ObjectType.COMMIT, rev) commitdate = GLib.DateTime.new_from_unix_utc(OSTree.commit_get_timestamp(commit)).format("%c") print commitdate # XXX - Define this somewhere? imageoutputdir=os.path.join(self.outputdir, 'images') imagedir = os.path.join(imageoutputdir, rev[:8]) if not os.path.exists(imagedir): os.makedirs(imagedir) imagestmpdir = os.path.join(self.workdir, 'images') if not os.path.exists(imagestmpdir): os.mkdir(imagestmpdir) generated = [] imgtargetcloud=os.path.join(imagestmpdir, self._name, '%s.qcow2' % self.os_name) self.create_cloud_image(self.workdir, imgtargetcloud, self._kickstart) generated.append(imgtargetcloud) for f in generated: destpath = os.path.join(imagedir, os.path.basename(f)) print "Created: " + destpath shutil.move(f, destpath)
def get_system_image(rev): commit_rev = repo.resolve_rev(rev, False)[1] commit = repo.load_commit(commit_rev)[1] tag = ":".join(rev.replace("ociimage/", "").rsplit('-', 1)) timestamp = OSTree.commit_get_timestamp(commit) return {'Id' : commit_rev, 'RepoTags' : [tag], 'Names' : [], 'Created': timestamp }
def create_disks(self): [res, rev] = self.repo.resolve_rev(self.ref, False) [res, commit] = self.repo.load_variant(OSTree.ObjectType.COMMIT, rev) commitdate = GLib.DateTime.new_from_unix_utc( OSTree.commit_get_timestamp(commit)).format("%c") print commitdate # XXX - Define this somewhere? imageoutputdir = os.path.join(self.outputdir, 'images') imagedir = os.path.join(imageoutputdir, rev[:8]) if not os.path.exists(imagedir): os.makedirs(imagedir) imagestmpdir = os.path.join(self.workdir, 'images') os.mkdir(imagestmpdir) generated = [] imgtargetinstaller = os.path.join(imagestmpdir, 'install', '%s-installer.iso' % self.os_name) self.create_installer_image(self.workdir, imgtargetinstaller) generated.append(imgtargetinstaller) for f in generated: destpath = os.path.join(imagedir, os.path.basename(f)) print "Created: " + destpath shutil.move(f, destpath)
def create(self, outputdir, post=None): [res,rev] = self.repo.resolve_rev(self.ref, False) [res,commit] = self.repo.load_variant(OSTree.ObjectType.COMMIT, rev) commitdate = GLib.DateTime.new_from_unix_utc(OSTree.commit_get_timestamp(commit)).format("%c") print commitdate lorax_opts = [] if self.local_overrides: lorax_opts.extend([ '-s', self.local_overrides ]) if self.lorax_additional_repos: for repourl in self.lorax_additional_repos.split(','): lorax_opts.extend(['-s', repourl.strip()]) http_proxy = os.environ.get('http_proxy') if http_proxy: lorax_opts.extend([ '--proxy', http_proxy ]) template_src = self.pkgdatadir + '/lorax-embed-repo.tmpl' template_dest = self.workdir + '/lorax-embed-repo.tmpl' shutil.copy(template_src, template_dest) if post is not None: # Yeah, this is pretty awful. post_str = '%r' % ('%post --erroronfail\n' + open(post).read() + '\n%end\n', ) with open(template_dest, 'a') as f: f.write('\nappend usr/share/anaconda/interactive-defaults.ks %s\n' % (post_str, )) lorax_workdir = os.path.join(self.workdir, 'lorax') os.makedirs(lorax_workdir) run_sync(['lorax', '--nomacboot', '--add-template=%s' % template_dest, '--add-template-var=ostree_osname=%s' % self.os_name, '--add-template-var=ostree_repo=%s' % self.ostree_repo, '--add-template-var=ostree_ref=%s' % self.ref, '-p', self.os_pretty_name, '-v', self.release, '-r', self.release, '-s', self.yum_baseurl, '-e', 'systemd-container', ] + lorax_opts + ['output'], cwd=lorax_workdir) # We injected data into boot.iso, so it's now installer.iso lorax_output = lorax_workdir + '/output' lorax_images = lorax_output + '/images' os.rename(lorax_images + '/boot.iso', lorax_images + '/installer.iso') treeinfo = lorax_output + '/.treeinfo' treeinfo_tmp = treeinfo + '.tmp' with open(treeinfo) as treein: with open(treeinfo_tmp, 'w') as treeout: for line in treein: if line.startswith('boot.iso'): treeout.write(line.replace('boot.iso', 'installer.iso')) else: treeout.write(line) os.rename(treeinfo_tmp, treeinfo) for p in os.listdir(lorax_output): print "Generated: " + p shutil.move(os.path.join(lorax_output, p), os.path.join(outputdir, p))
def create_disks(self, outputdir): [res,rev] = self.repo.resolve_rev(self.ref, False) [res,commit] = self.repo.load_variant(OSTree.ObjectType.COMMIT, rev) commitdate = GLib.DateTime.new_from_unix_utc(OSTree.commit_get_timestamp(commit)).format("%c") print commitdate imagestmpdir = os.path.join(self.workdir, 'images') os.mkdir(imagestmpdir) generated = [] imgtargetinstaller=os.path.join(imagestmpdir, 'install', '%s-installer.iso' % self.os_name) self.create_installer_image(self.workdir, imgtargetinstaller) generated.append(imgtargetinstaller) for f in generated: destpath = os.path.join(outputdir, os.path.basename(f)) print "Created: " + destpath shutil.move(f, destpath)
def _inspect_system_branch(self, repo, imagebranch): commit_rev = repo.resolve_rev(imagebranch, False)[1] commit = repo.load_commit(commit_rev)[1] branch_id = SystemContainers._decode_from_ostree_ref(imagebranch.replace(OSTREE_OCIIMAGE_PREFIX, "")) tag = ":".join(branch_id.rsplit(":", 1)) timestamp = OSTree.commit_get_timestamp(commit) labels = {} manifest = self._image_manifest(repo, commit_rev) if len(branch_id) == 64: image_id = branch_id tag = "<none>" else: image_id = commit_rev if manifest: manifest = json.loads(manifest) if "Labels" in manifest: labels = manifest["Labels"] if "Digest" in manifest: image_id = manifest["Digest"].replace("sha256:", "") if self.user: image_type = "user" else: image_type = "system" return { "Id": image_id, "ImageId": image_id, "RepoTags": [tag], "Names": [], "Created": timestamp, "ImageType": image_type, "Labels": labels, "OSTree-rev": commit_rev, }
def _inspect_system_branch(self, repo, imagebranch): commit_rev = repo.resolve_rev(imagebranch, False)[1] commit = repo.load_commit(commit_rev)[1] branch_id = imagebranch.replace(OSTREE_OCIIMAGE_PREFIX, "") tag = ":".join(branch_id.rsplit('-', 1)) timestamp = OSTree.commit_get_timestamp(commit) labels = {} manifest = self._image_manifest(repo, commit_rev) if len(branch_id) == 64: image_id = branch_id tag = "<none>" else: image_id = commit_rev if manifest: manifest = json.loads(manifest) if 'Labels' in manifest: labels = manifest['Labels'] if 'Digest' in manifest: image_id = manifest['Digest'].replace("sha256:", "") if self.user: image_type = "User" else: image_type = "System" return { 'Id': image_id, 'RepoTags': [tag], 'Names': [], 'Created': timestamp, 'ImageType': image_type, 'Labels': labels, 'OSTree-rev': commit_rev }
def _inspect_system_branch(self, repo, imagebranch): if imagebranch.startswith(OSTREE_OCIIMAGE_PREFIX): commit_rev = repo.resolve_rev(imagebranch, False)[1] else: _, commit_rev = self._resolve_image(repo, imagebranch) if commit_rev is None: raise ValueError("Image %s not found" % imagebranch) commit = repo.load_commit(commit_rev)[1] branch_id = SystemContainers._decode_from_ostree_ref(imagebranch.replace(OSTREE_OCIIMAGE_PREFIX, "")) tag = ":".join(branch_id.rsplit(':', 1)) timestamp = OSTree.commit_get_timestamp(commit) labels = {} manifest = self._image_manifest(repo, commit_rev) if len(branch_id) == 64: image_id = branch_id tag = "<none>" else: image_id = commit_rev if manifest: manifest = json.loads(manifest) if 'Labels' in manifest: labels = manifest['Labels'] if 'Digest' in manifest: image_id = manifest['Digest'].replace("sha256:", "") if self.user: image_type = "user" else: image_type = "system" return {'Id' : image_id, 'Version' : tag, 'ImageId' : image_id, 'RepoTags' : [tag], 'Names' : [], 'Created': timestamp, 'ImageType' : image_type, 'Labels' : labels, 'OSTree-rev' : commit_rev}
def create(self, outputdir, name, ksfile, tdl, imageouttypes): self._name = name self._tdl = tdl self._kickstart = ksfile imgfunc = ImageFunctions() [res, rev] = self.repo.resolve_rev(self.ref, False) [res, commit] = self.repo.load_variant(OSTree.ObjectType.COMMIT, rev) commitdate = GLib.DateTime.new_from_unix_utc(OSTree.commit_get_timestamp(commit)).format("%c") print commitdate port_file_path = self.workdir + '/repo-port' # Start trivial-httpd trivhttp = TrivialHTTP() trivhttp.start(self.ostree_repo) httpd_port = str(trivhttp.http_port) print "trivial httpd port=%s, pid=%s" % (httpd_port, trivhttp.http_pid) ks_basename = os.path.basename(ksfile) flattened_ks = os.path.join(self.workdir, ks_basename) # FIXME - eventually stop hardcoding this via some mapping if ks_basename.find('fedora') >= 0: kickstart_version = 'F21' else: kickstart_version = 'RHEL7' run_sync(['ksflatten', '--version', kickstart_version, '-c', ksfile, '-o', flattened_ks]) # TODO: Pull kickstart from separate git repo ksdata = open(flattened_ks).read() substitutions = { 'OSTREE_PORT': httpd_port, 'OSTREE_REF': self.ref, 'OSTREE_OSNAME': self.os_name} if '@OSTREE_HOST_IP@' in ksdata: host_ip = getDefaultIP(hostnet=self.virtnetwork) substitutions['OSTREE_HOST_IP'] = host_ip for subname, subval in substitutions.iteritems(): print subname, subval ksdata = ksdata.replace('@%s@' % (subname, ), subval) imgfunc.checkoz() parameters = { "install_script": ksdata, "generate_icicle": False, "oz_overrides": json.dumps(imgfunc.ozoverrides) } print "Starting build" image = self.builder.build(template=open(self._tdl).read(), parameters=parameters) # For debug, you can comment out the above and enable the code below # to skip the initial image creation. Just point myuuid at the proper # image uuid # self.builder.download() # myuuid = "fd301dce-fba3-421d-a2e8-182cf2cefaf8" # pim = PersistentImageManager.default_manager() # image = pim.image_with_id(myuuid) imageoutputdir = os.path.join(outputdir, "images") if not os.path.exists(imageoutputdir): os.mkdir(imageoutputdir) # Copy the qcow2 file to the outputdir outputname = os.path.join(imageoutputdir, '%s.qcow2' % (self.os_nr)) shutil.copyfile(image.data, outputname) print "Created: {0}".format(outputname) if 'raw' in imageouttypes: print "Processing image from qcow2 to raw" print image.data outputname = os.path.join(imageoutputdir, '%s.raw' % (self.os_nr)) print outputname qemucmd = ['qemu-img', 'convert', '-f', 'qcow2', '-O', 'raw', image.data, outputname] subprocess.check_call(qemucmd) imageouttypes.pop(imageouttypes.index("raw")) print "Created: {0}".format(outputname) for imagetype in imageouttypes: if imagetype in ['vsphere', 'rhevm']: # Imgfac will ensure proper qemu type is used print "Creating {0} image".format(imagetype) target_image = self.builder.buildimagetype(imagetype, image.identifier) infile = target_image.data outfile = os.path.join(imageoutputdir, '%s-%s.ova' % (self._name, imagetype)) shutil.copyfile(infile, outfile) print "Created: {0}".format(outfile) trivhttp.stop()
def copy_commit(repo, src_rev, dest_ref): """Copy commit src_rev to dest_ref This makes the new commit at dest_ref have the proper collection binding for this repo. The caller is expected to manage the ostree transaction. This is like "flatpak build-commit-from", but we need more control over the transaction. """ logging.info('Copying commit %s to %s', src_rev, dest_ref) _, src_root, _ = repo.read_commit(src_rev) _, src_variant, src_state = repo.load_commit(src_rev) # Only copy normal commits if src_state != 0: raise Exception('Cannot copy irregular commit {}'.format(src_rev)) # If the dest ref exists, use the current commit as the new # commit's parent _, dest_parent = repo.resolve_rev_ext( dest_ref, allow_noent=True, flags=OSTree.RepoResolveRevExtFlags.REPO_RESOLVE_REV_EXT_NONE) if dest_parent is not None: logging.info('Using %s as new commit parent', dest_parent) # Make a copy of the commit metadata to update. Like flatpak # build-commit-from, the detached metadata is not copied since # the only known usage is for GPG signatures, which would become # invalid. commit_metadata = GLib.VariantDict.new(src_variant.get_child_value(0)) # Set the collection binding if the repo has a collection ID, # otherwise remove it collection_id = get_collection_id(repo) if collection_id is not None: commit_metadata.insert_value(OSTree.COMMIT_META_KEY_COLLECTION_BINDING, GLib.Variant('s', collection_id)) else: commit_metadata.remove(OSTree.COMMIT_META_KEY_COLLECTION_BINDING) # Include the destination ref in the ref bindings ref_bindings = commit_metadata.lookup_value( OSTree.COMMIT_META_KEY_REF_BINDING, GLib.VariantType('as')) if ref_bindings is None: ref_bindings = [] ref_bindings = set(ref_bindings) ref_bindings.add(dest_ref) commit_metadata.insert_value(OSTree.COMMIT_META_KEY_REF_BINDING, GLib.Variant('as', sorted(ref_bindings))) # Add flatpak specific metadata. xa.ref is deprecated, but some # flatpak clients might expect it. xa.from_commit will be used # by the app verifier to make sure the commit it sent actually # got there commit_metadata.insert_value('xa.ref', GLib.Variant('s', dest_ref)) commit_metadata.insert_value('xa.from_commit', GLib.Variant('s', src_rev)) # Convert from GVariantDict to GVariant vardict commit_metadata = commit_metadata.end() # Copy other commit data from source commit commit_subject = src_variant[COMMIT_SUBJECT_INDEX] commit_body = src_variant[COMMIT_BODY_INDEX] commit_time = OSTree.commit_get_timestamp(src_variant) # Make the new commit assuming the caller started a transaction mtree = OSTree.MutableTree.new() repo.write_directory_to_mtree(src_root, mtree, None) _, dest_root = repo.write_mtree(mtree) _, dest_checksum = repo.write_commit_with_time(dest_parent, commit_subject, commit_body, commit_metadata, dest_root, commit_time) logging.info('Created new commit %s', dest_checksum) return dest_checksum
def create(self, outputdir, name, ksfile, tdl, imageouttypes): self._name = name self._tdl = tdl self._kickstart = ksfile [res, rev] = self.repo.resolve_rev(self.ref, False) [res, commit] = self.repo.load_variant(OSTree.ObjectType.COMMIT, rev) commitdate = GLib.DateTime.new_from_unix_utc(OSTree.commit_get_timestamp(commit)).format("%c") print commitdate target = os.path.join(outputdir, '%s.raw' % (self._name)) port_file_path = self.workdir + '/repo-port' subprocess.check_call(['ostree', 'trivial-httpd', '--autoexit', '--daemonize', '--port-file', port_file_path], cwd=self.ostree_repo) httpd_port = open(port_file_path).read().strip() print "trivial httpd port=%s" % (httpd_port, ) ks_basename = os.path.basename(ksfile) flattened_ks = os.path.join(self.workdir, ks_basename) # FIXME - eventually stop hardcoding this via some mapping if ks_basename.find('fedora') >= 0: kickstart_version = 'F21' else: kickstart_version = 'RHEL7' run_sync(['ksflatten', '--version', kickstart_version, '-c', ksfile, '-o', flattened_ks]) # TODO: Pull kickstart from separate git repo ksdata = open(flattened_ks).read() substitutions = { 'OSTREE_PORT': httpd_port, 'OSTREE_REF': self.ref, 'OSTREE_OSNAME': self.os_name } for subname, subval in substitutions.iteritems(): ksdata = ksdata.replace('@%s@' % (subname, ), subval) parameters = { "install_script": ksdata, "generate_icicle": False, } defaultimagetype = checkoz() print "Starting build" image = self.builder.build(template=open(self._tdl).read(), parameters=parameters) # For debug, you can comment out the above and enable the code below # to skip the initial image creation. Just point myuuid at the proper # image uuid # self.builder.download() # myuuid = "32a2d0b8-da84-415c-aec6-90bb5a7f8e8b" # pim = PersistentImageManager.default_manager() # image = pim.image_with_id(myuuid) # This should probably be broken out to a sep. function if defaultimagetype == "raw": # Always create a qcow2 print "Processing image from raw to qcow2" print image.data outputname = os.path.join(outputdir, '%s.qcow2' % (self._name)) print outputname qemucmd = ['qemu-img', 'convert', '-f', 'raw', '-O', 'qcow2', image.data, outputname] imageouttypes.pop(imageouttypes.index("kvm")) subprocess.check_call(qemucmd) if 'kvm' in imageouttypes: print "Processing image from qcow2 to raw" print image.data outputname = os.path.join(outputdir, '%s.raw' % (self._name)) print outputname # We use compat=0.10 to ensure we run on RHEL6 era QEMU qemucmd = ['qemu-img', 'convert', '-f', 'raw', '-O', 'qcow2', '-o', 'compat=0.10', image.data, outputname] imageouttypes.pop(imageouttypes.index("raw")) subprocess.check_call(qemucmd) shutil.copyfile(image.data, target) print "Created: " + target for imagetype in imageouttypes: print "Creating {0} image".format(imagetype) target_image = self.builder.buildimagetype(imagetype, image.identifier) infile = target_image.data outfile = os.path.join(outputdir, '%s-%s.ova' % (self._name, imagetype)) shutil.copyfile(infile, outfile)