[gnome-ostree/wip/libostree: 3/3] Use the native APIs for checkout as well
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-ostree/wip/libostree: 3/3] Use the native APIs for checkout as well
- Date: Sat, 7 Sep 2013 16:15:49 +0000 (UTC)
commit d1d45e07b09dd6d3a32a80449aced9ee5b169edd
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Sat Sep 7 01:59:31 2013 -0400
Use the native APIs for checkout as well
src/js/tasks/task-build.js | 208 ++++++++++-----------------------
src/js/tasks/task-integrationtest.js | 17 +++-
2 files changed, 77 insertions(+), 148 deletions(-)
---
diff --git a/src/js/tasks/task-build.js b/src/js/tasks/task-build.js
index e17b9f4..42461cd 100644
--- a/src/js/tasks/task-build.js
+++ b/src/js/tasks/task-build.js
@@ -35,6 +35,11 @@ const Snapshot = imports.snapshot;
const BuildUtil = imports.buildutil;
const Vcs = imports.vcs;
+// From ot-gio-utils.h.
+// XXX: Introspect this.
+const 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");
+
const OPT_COMMON_CFLAGS = {'i686': '-O2 -g -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables',
'x86_64': '-O2 -g -m64 -mtune=generic'};
@@ -104,26 +109,12 @@ const TaskBuild = new Lang.Class({
toChecksumData += etcPasswd;
toChecksumData += etcGroup;
- let [tmpPath, stream] = Gio.File.new_tmp("ostbuild-buildroot-XXXXXX.txt");
- let dataOut = Gio.DataOutputStream.new(stream.get_output_stream());
- for (let i = 0; i < rootContents.length; i++) {
- let [branch, subpath] = rootContents[i];
- let rev = refToRev[branch];
- toChecksumData += refToRev[branch];
- dataOut.put_string(refToRev[branch], cancellable);
- dataOut.put_byte(0, cancellable);
- dataOut.put_string(subpath, cancellable);
- dataOut.put_byte(0, cancellable);
- }
- dataOut.close(cancellable);
-
let newRootCacheid = GLib.compute_checksum_for_bytes(GLib.ChecksumType.SHA256, new
GLib.Bytes(toChecksumData));
let cachedRoot = buildrootCachedir.get_child(newRootCacheid);
if (cachedRoot.query_exists(cancellable)) {
print("Reusing cached buildroot: " + cachedRoot.get_path());
this._cleanStaleBuildroots(buildrootCachedir, cachedRoot, cancellable);
- GSystem.file_unlink(tmpPath, cancellable);
return cachedRoot;
}
@@ -134,10 +125,18 @@ const TaskBuild = new Lang.Class({
let cachedRootTmp = cachedRoot.get_parent().get_child(cachedRoot.get_basename() + '.tmp');
GSystem.shutil_rm_rf(cachedRootTmp, cancellable);
- ProcUtil.runSync(['ostree', '--repo=' + this.repo.get_path(),
- 'checkout', '--user-mode', '--union',
- '--from-file=' + tmpPath.get_path(), cachedRootTmp.get_path()], cancellable);
- GSystem.file_unlink(tmpPath, cancellable);
+
+ rootContents.forEach(Lang.bind(this, function([branch, subpath]) {
+ let [, root] = this.ostreeRepo.read_commit(branch, cancellable);
+ let subtree = root.resolve_relative_path(subpath);
+ let subtreeInfo = subtree.query_info(OSTREE_GIO_FAST_QUERYINFO,
+ Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
+ cancellable);
+
+ this.ostreeRepo.checkout_tree(OSTree.RepoCheckoutMode.USER,
+ OSTree.RepoCheckoutOverwriteMode.UNION_FILES,
+ cachedRootTmp, subtree, subtreeInfo, cancellable);
+ }));
this._runTriggersInRoot(cachedRootTmp, cancellable);
@@ -721,56 +720,40 @@ const TaskBuild = new Lang.Class({
this._rebuiltComponents.push(basename);
return ostreeRevision;
},
-
- _checkoutOneTreeCoreAsync: function(name, composeContents, cancellable, callback,
- params) {
+
+ _checkoutOneTreeCore: function(name, composeContents, cancellable, params) {
params = Params.parse(params, { runTriggers: true });
let composeRootdir = Gio.File.new_for_path(name);
print("Checking out " + composeRootdir.get_path());
GSystem.shutil_rm_rf(composeRootdir, cancellable);
GSystem.file_ensure_directory(composeRootdir, true, cancellable);
- let [contentsTmpPath, stream] = Gio.File.new_tmp("ostbuild-compose-XXXXXX.txt");
- let dataOut = Gio.DataOutputStream.new(stream.get_output_stream());
- for (let i = 0; i < composeContents.length; i++) {
- let [branch, subpath] = composeContents[i];
- dataOut.put_string(branch, cancellable);
- dataOut.put_byte(0, cancellable);
- dataOut.put_string(subpath, cancellable);
- dataOut.put_byte(0, cancellable);
- }
- dataOut.close(cancellable);
-
- let argv = ['ostree', '--repo=' + this.repo.get_path(),
- 'checkout', '--allow-noent', '--user-mode', '--union',
- '--from-file=' + contentsTmpPath.get_path(), composeRootdir.get_path()];
- print("Running: " + argv.map(GLib.shell_quote).join(' '));
- let proc = GSystem.Subprocess.new_simple_argv(argv,
- GSystem.SubprocessStreamDisposition.INHERIT,
- GSystem.SubprocessStreamDisposition.INHERIT,
- cancellable);
- proc.wait(cancellable, Lang.bind(this, function(proc, result) {
- GSystem.file_unlink(contentsTmpPath, cancellable);
- let [success, ecode] = proc.wait_finish(result);
- try {
- GLib.spawn_check_exit_status(ecode);
- } catch (e) {
- callback(null, ""+e);
- return;
- }
+ composeContents.forEach(Lang.bind(this, function([branch, subpath]) {
+ let [, root] = this.ostreeRepo.read_commit(branch, cancellable);
+ let subtree = root.resolve_relative_path(subpath);
+ let subtreeInfo;
+ try {
+ subtreeInfo = subtree.query_info(OSTREE_GIO_FAST_QUERYINFO,
+ Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
+ cancellable);
+ } catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND)) {
+ return;
+ }
- if (params.runTriggers)
- this._runTriggersInRoot(composeRootdir, cancellable);
-
- let contentsPath = composeRootdir.resolve_relative_path('usr/share/contents.json');
- GSystem.file_ensure_directory(contentsPath.get_parent(), true, cancellable);
- JsonUtil.writeJsonFileAtomic(contentsPath, this._snapshot.data, cancellable);
+ this.ostreeRepo.checkout_tree(OSTree.RepoCheckoutMode.USER,
+ OSTree.RepoCheckoutOverwriteMode.UNION_FILES,
+ composeRootdir, subtree, subtreeInfo, cancellable);
+ }));
+
+ if (params.runTriggers)
+ this._runTriggersInRoot(composeRootdir, cancellable);
- callback(composeRootdir, null);
- }));
+ let contentsPath = composeRootdir.resolve_relative_path('usr/share/contents.json');
+ GSystem.file_ensure_directory(contentsPath.get_parent(), true, cancellable);
+ JsonUtil.writeJsonFileAtomic(contentsPath, this._snapshot.data, cancellable);
},
- _checkoutOneTreeAsync: function(target, componentBuildRevs, cancellable, callback) {
+ _checkoutOneTree: function(target, componentBuildRevs, cancellable) {
let base = target['base'];
let baseName = this.osname + '/bases/' + base['name'];
let runtimeName = this.osname +'/bases/' + base['runtime'];
@@ -792,18 +775,9 @@ const TaskBuild = new Lang.Class({
}
}
- this._checkoutOneTreeCoreAsync(target['name'], composeContents, cancellable,
- Lang.bind(this, function(result, err) {
- if (err) {
- callback(null, err);
- return;
- } else {
- let composeRootdir = result;
-
- this._postComposeTransform(composeRootdir, cancellable);
- callback(composeRootdir, null);
- }
- }));
+ let composeRootdir = this._checkoutOneTreeCore(target['name'], composeContents, cancellable);
+ this._postComposeTransform(composeRootdir, cancellable);
+ return composeRootdir;
},
_runTriggersInRoot: function(rootdir, cancellable) {
@@ -1375,10 +1349,6 @@ const TaskBuild = new Lang.Class({
targets: targetRevisions };
buildData['installed-tests'] = finalInstalledTestRevisions;
- let composeTreeTaskCount = 0;
- let composeTreeTaskError = null;
- let composeTreeTaskLoop = GLib.MainLoop.new(null, true);
-
// First loop over the -devel trees per architecture, and
// generate an initramfs.
let archInitramfsImages = {};
@@ -1398,34 +1368,17 @@ const TaskBuild = new Lang.Class({
initramfsDepends.push(component['name'] + ':' + buildRev);
}
- composeTreeTaskCount++;
- this._checkoutOneTreeAsync(develTarget, componentBuildRevs, cancellable,
- Lang.bind(this, function (result, err) {
- if (err) {
- if (composeTreeTaskError === null)
- composeTreeTaskError = err;
- composeTreeTaskLoop.quit();
- return;
- }
- let composeRootdir = result;
- let kernelInitramfsData =
this._prepareKernelAndInitramfs(architecture, composeRootdir, initramfsDepends, cancellable);
- archInitramfsImages[architecture] = kernelInitramfsData;
- this._installKernelAndInitramfs(kernelInitramfsData,
composeRootdir, cancellable);
- let [treename, ostreeRev] =
this._commitComposedTree(develTargetName, composeRootdir, cancellable);
- targetRevisions[treename] = ostreeRev;
- // Also note the revision of this, since it will be used
- // as the buildroot for installed tests
- this._installedTestsBuildrootRev[architecture] = ostreeRev;
- composeTreeTaskCount--;
- if (composeTreeTaskCount == 0)
- composeTreeTaskLoop.quit();
- }));
+ let composeRootdir = this._checkoutOneTree(develTarget, componentBuildRevs, cancellable);
+ let kernelInitramfsData = this._prepareKernelAndInitramfs(architecture, composeRootdir,
initramfsDepends, cancellable);
+ archInitramfsImages[architecture] = kernelInitramfsData;
+ this._installKernelAndInitramfs(kernelInitramfsData, composeRootdir, cancellable);
+ let [treename, ostreeRev] = this._commitComposedTree(develTargetName, composeRootdir,
cancellable);
+ targetRevisions[treename] = ostreeRev;
+ // Also note the revision of this, since it will be used
+ // as the buildroot for installed tests
+ this._installedTestsBuildrootRev[architecture] = ostreeRev;
}
- composeTreeTaskLoop.run();
- if (composeTreeTaskError)
- throw new Error(composeTreeTaskError);
-
// Now loop over the other targets per architecture, reusing
// the initramfs cached from -devel generation.
let nonDevelTargets = ['runtime', 'runtime-debug', 'devel-debug'];
@@ -1436,32 +1389,15 @@ const TaskBuild = new Lang.Class({
let runtimeTargetName = 'buildmaster/' + architecture + '-' + target;
let runtimeTarget = this._findTargetInList(runtimeTargetName, targetsList);
- composeTreeTaskCount++;
- this._checkoutOneTreeAsync(runtimeTarget, componentBuildRevs, cancellable,
- Lang.bind(this, function(result, err) {
- if (err) {
- if (composeTreeTaskError === null)
- composeTreeTaskError = err;
- composeTreeTaskLoop.quit();
- return;
- }
- let composeRootdir = result;
- let kernelInitramfsData = archInitramfsImages[architecture];
- this._installKernelAndInitramfs(kernelInitramfsData,
composeRootdir, cancellable);
- this._cleanupGarbage(composeRootdir, cancellable);
- let [treename, ostreeRev] =
this._commitComposedTree(runtimeTargetName, composeRootdir, cancellable);
- targetRevisions[treename] = ostreeRev;
- composeTreeTaskCount--;
- if (composeTreeTaskCount == 0)
- composeTreeTaskLoop.quit();
- }));
+ let composeRootdir = this._checkoutOneTree(runtimeTarget, componentBuildRevs, cancellable);
+ let kernelInitramfsData = archInitramfsImages[architecture];
+ this._installKernelAndInitramfs(kernelInitramfsData, composeRootdir, cancellable);
+ this._cleanupGarbage(composeRootdir, cancellable);
+ let [treename, ostreeRev] = this._commitComposedTree(runtimeTargetName, composeRootdir,
cancellable);
+ targetRevisions[treename] = ostreeRev;
}
}
- composeTreeTaskLoop.run();
- if (composeTreeTaskError)
- throw new Error(composeTreeTaskError);
-
let installedTestComponentNames = this._snapshot.data['installed-tests-components'] || [];
print("Using installed test components: " + installedTestComponentNames.join(', '));
let installedTestContents = {};
@@ -1507,29 +1443,11 @@ const TaskBuild = new Lang.Class({
for (let j = 0; j < contents.length; j++) {
composeContents.push(contents[j]);
}
- composeTreeTaskCount++;
- this._checkoutOneTreeCoreAsync(rootName, composeContents, cancellable,
- Lang.bind(this, function(result, err) {
- if (err) {
- if (composeTreeTaskError === null)
- composeTreeTaskError = err;
- composeTreeTaskLoop.quit();
- return;
- }
- let composeRootdir = result;
-
- let [treename, rev] = this._commitComposedTree(rootName,
composeRootdir, cancellable);
- finalInstalledTestRevisions[treename] = rev;
- composeTreeTaskCount--;
- if (composeTreeTaskCount == 0)
- composeTreeTaskLoop.quit();
- }),
- { runTriggers: false });
- }
- composeTreeTaskLoop.run();
- if (composeTreeTaskError)
- throw new Error(composeTreeTaskError);
+ let composeRootdir = this._checkoutOneTreeCore(rootName, composeContents, cancellable, {
runTriggers: false });
+ let [treename, rev] = this._commitComposedTree(rootName, composeRootdir, cancellable);
+ finalInstalledTestRevisions[treename] = rev;
+ }
this._writeStatus('built: ' + this._rebuiltComponents.join(' '), cancellable);
diff --git a/src/js/tasks/task-integrationtest.js b/src/js/tasks/task-integrationtest.js
index afe9695..99e7c55 100644
--- a/src/js/tasks/task-integrationtest.js
+++ b/src/js/tasks/task-integrationtest.js
@@ -32,6 +32,11 @@ const LibQA = imports.libqa;
const JSUtil = imports.jsutil;
const JSONUtil = imports.jsonutil;
+// From ot-gio-utils.h.
+// XXX: Introspect this.
+const 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");
+
const TaskIntegrationTest = new Lang.Class({
Name: 'TaskIntegrationTest',
Extends: TestBase.TestBase,
@@ -71,9 +76,15 @@ const TaskIntegrationTest = new Lang.Class({
let installedTestsRev = this._buildData['installed-tests'][installedTestsName];
if (!installedTestsRev)
throw new Error("No installed tests rev for " + installedTestsName);
- ProcUtil.runSync(['ostree', '--repo=' + this.repo.get_path(),
- 'checkout', '--user-mode', '--union', installedTestsRev, deployDir.get_path()],
cancellable,
- { logInitiation: true });
+
+ let [, root] = this.ostreeRepo.read_commit(installedTestsRev, cancellable);
+ let rootInfo = root.query_info(OSTREE_GIO_FAST_QUERYINFO,
+ Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
+ cancellable);
+ this.ostreeRepo.checkout_tree(OSTree.RepoCheckoutMode.USER,
+ OSTree.RepoCheckoutOverwriteMode.UNION_FILES,
+ cachedRootTmp, root, rootInfo, cancellable);
+
let xfailTests = this._buildData['snapshot']['installed-tests-xfail'] || [];
for (let i = 0; i < xfailTests.length; i++) {
let xfail = xfailTests[i];
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]