From 78e26c7d57c7ec6e1c3ec6c51861e3d319bb4e5a Mon Sep 17 00:00:00 2001 From: Adam Coldrick Date: Wed, 1 Apr 2015 13:06:21 +0000 Subject: fixup: Clean up OSTree wrapper --- morphlib/ostree.py | 109 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 35 deletions(-) diff --git a/morphlib/ostree.py b/morphlib/ostree.py index a2c133f2..ed2c59da 100644 --- a/morphlib/ostree.py +++ b/morphlib/ostree.py @@ -1,35 +1,70 @@ +# Copyright (C) 2013-2015 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# =*= License: GPL-2 =*= + + from gi.repository import OSTree from gi.repository import Gio from gi.repository import GLib import os +import logging class OSTreeRepo(object): """Class to wrap the OSTree API.""" - OSTREE_GIO_FAST_QUERYINFO = 'standard::name,standard::type,standard::' \ - 'size,standard::is-symlink,standard::syml' \ - 'ink-target,unix::device,unix::inode,unix' \ - '::mode,unix::uid,unix::gid,unix::rdev' G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS = Gio.FileQueryInfoFlags(1) - cancellable = Gio.Cancellable.new() + OSTREE_GIO_FAST_QUERYINFO = ( + 'standard::name,' + 'standard::type,' + 'standard::size,' + 'standard::is-symlink,' + 'standard::symlink-target,' + 'unix::device,' + 'unix::inode,' + 'unix::mode,' + 'unix::uid,' + 'unix::gid,' + 'unix::rdev') - def __init__(self, path, disable_fsync=True): + def __init__(self, path, disable_fsync=True, mode='bare'): self.path = path - self.repo = self._open_repo(path, disable_fsync) + self.repo = self._open_repo(path, disable_fsync, mode) - def _open_repo(self, path, disable_fsync=True): + def _open_repo(self, path, disable_fsync=True, mode='bare'): """Create and open and OSTree.Repo, and return it.""" repo_dir = Gio.file_new_for_path(path) repo = OSTree.Repo.new(repo_dir) + logging.debug('using %s' % mode) + if mode == 'bare': + mode = OSTree.RepoMode.BARE + elif mode == 'archive_z2': + mode = OSTree.RepoMode.ARCHIVE_Z2 + else: + raise Exception('Mode %s is not supported' % mode) + try: - repo.open(self.cancellable) + repo.open(None) + logging.debug('opened') except GLib.GError: if not os.path.exists(path): os.makedirs(path) - repo.create(OSTree.RepoMode.ARCHIVE_Z2, self.cancellable) + logging.debug('failed to open, creating') + repo.create(mode, None) repo.set_disable_fsync(disable_fsync) return repo @@ -47,13 +82,13 @@ class OSTreeRepo(object): def read_commit(self, branch): """Return an OSTree.RepoFile representing a committed tree.""" - return self.repo.read_commit(branch, self.cancellable)[1] + return self.repo.read_commit(branch, None)[1] def query_info(self, file_object): """Quickly return a Gio.FileInfo for file_object.""" return file_object.query_info(self.OSTREE_GIO_FAST_QUERYINFO, self.G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - self.cancellable) + None) def checkout(self, branch, destdir): """Checkout branch into destdir.""" @@ -64,26 +99,27 @@ class OSTreeRepo(object): commit = self.read_commit(branch) commit_info = self.query_info(commit) - self.repo.checkout_tree(0, 1, checkout, commit, - commit_info, self.cancellable) + self.repo.checkout_tree(OSTree.RepoCheckoutMode.NONE, + OSTree.RepoCheckoutOverwriteMode.UNION_FILES, + checkout, commit,commit_info, None) - def commit(self, subject, srcdir, branch): - """Commit the contents of 'srcdir' to 'branch'.""" - self.repo.prepare_transaction(self.cancellable) - parent = self.resolve_rev(branch) - if parent: - parent_root = self.read_commit(parent) + def commit(self, subject, srcdir, branch, body=''): + """Commit the contents of 'srcdir' to 'branch'. + + The subject parameter is the title of the commit message, and the + body parameter is the body of the commit message. + """ + self.repo.prepare_transaction(None) + parent = self.resolve_rev(branch) mtree = OSTree.MutableTree() src = Gio.file_new_for_path(srcdir) - self.repo.write_directory_to_mtree(src, mtree, None, self.cancellable) - root = self.repo.write_mtree(mtree, self.cancellable)[1] - if parent and root.equal(parent_root): - return - checksum = self.repo.write_commit(parent, subject, '', None, - root, self.cancellable)[1] + self.repo.write_directory_to_mtree(src, mtree, None, None) + root = self.repo.write_mtree(mtree, None)[1] + checksum = self.repo.write_commit(parent, subject, body, + None, root, None)[1] self.repo.transaction_set_ref(None, branch, checksum) - stats = self.repo.commit_transaction(self.cancellable) + stats = self.repo.commit_transaction(None) def cat_file(self, ref, path): """Return the file descriptor of path at ref.""" @@ -92,9 +128,12 @@ class OSTreeRepo(object): ret, content, etag = relative.load_contents() return content - def list_refs(self, resolved=False): + def list_refs(self, ref=None, resolved=False): """Return a list of all refs in the repo.""" - refs = self.repo.list_refs()[1] + if ref: + refs = self.repo.list_refs(ref)[1] + else: + refs = self.repo.list_refs()[1] if not resolved: return refs.keys() return refs @@ -103,23 +142,23 @@ class OSTreeRepo(object): """Remove refspec from the repo.""" if not self.list_refs(ref): raise Exception("Failed to delete ref, it doesn't exist") - self.repo.set_ref_immediate(None, ref, None, self.cancellable) + self.repo.set_ref_immediate(None, ref, None, None) def prune(self): """Remove unreachable objects from the repo.""" - return self.repo.prune(OSTree.RepoPruneFlags.REFS_ONLY, - -1, self.cancellable) + depth = -1 # no recursion limit + return self.repo.prune(OSTree.RepoPruneFlags.REFS_ONLY, depth, None) def add_remote(self, name, url): """Add a remote with a given name and url.""" options_type = GLib.VariantType.new('a{sv}') options_builder = GLib.VariantBuilder.new(options_type) options = options_builder.end() - self.repo.remote_add(name, url, options, self.cancellable) + self.repo.remote_add(name, url, options, None) def remove_remote(self, name): """Remove a remote with a given name.""" - self.repo.remote_delete(name, self.cancellable) + self.repo.remote_delete(name, None) def get_remote_url(self, name): """Return the URL for a remote.""" @@ -136,4 +175,4 @@ class OSTreeRepo(object): def pull(self, refs, remote): """Pull ref from remote into the local repo.""" flags = OSTree.RepoPullFlags.NONE - self.repo.pull(remote, refs, flags, None, self.cancellable) + self.repo.pull(remote, refs, flags, None, None) -- cgit v1.2.1