summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clusters/minimal-system-deploy-ostree.morph22
-rw-r--r--extensions/ostree.check67
-rw-r--r--extensions/ostree.write88
-rw-r--r--extensions/ostree.write.help73
-rw-r--r--extensions/strip-device-nodes.configure40
-rw-r--r--extensions/strip-device-nodes.configure.help29
-rw-r--r--systems/minimal-system-x86_64-generic.morph1
7 files changed, 320 insertions, 0 deletions
diff --git a/clusters/minimal-system-deploy-ostree.morph b/clusters/minimal-system-deploy-ostree.morph
new file mode 100644
index 00000000..c0f4ed7c
--- /dev/null
+++ b/clusters/minimal-system-deploy-ostree.morph
@@ -0,0 +1,22 @@
+name: minimal-system-deploy-ostree
+kind: cluster
+description: |
+ Example of deploying a minimal system to a local OSTree repo.
+systems:
+- morph: systems/minimal-system-x86_64-generic.morph
+ deploy:
+ minimal-system:
+ type: extensions/ostree
+
+ # This is the default location for the repo on systems that were
+ # *deployed* with OSTree. You can use any repo created with `ostree init`
+ # here for testing purposes.
+ location: /ostree/repo
+
+ OSTREE_BRANCH: minimal-system-x86_64
+ OSTREE_COMMIT_SUBJECT: Example deployment of minimal-system-x86_64
+
+ STRIP_DEVICE_NODES: true
+
+ HOSTNAME: tiny-x86_64
+ INIT_SYSTEM: busybox
diff --git a/extensions/ostree.check b/extensions/ostree.check
new file mode 100644
index 00000000..e5fefe36
--- /dev/null
+++ b/extensions/ostree.check
@@ -0,0 +1,67 @@
+#!/usr/bin/python
+# Copyright (C) 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 <http://www.gnu.org/licenses/>.
+
+'''Preparatory checks for Baserock 'ostree' write extension.'''
+
+from gi.repository import GLib
+from gi.repository import Gio
+from gi.repository import OSTree
+
+import logging
+import os
+import urlparse
+
+import writeexts
+
+
+class OSTreeCheckExtension(writeexts.WriteExtension):
+
+ def process_args(self, args):
+ if len(args) != 1:
+ raise writeexts.ExtensionError(
+ 'Wrong number of command line args')
+
+ upgrade = self.get_environment_boolean('UPGRADE')
+ if upgrade:
+ raise writeexts.ExtensionError(
+ 'Use the `ssh-rsync` write extension to deploy upgrades to an '
+ 'existing remote system.')
+
+ location = args[0]
+ self.check_location(location)
+
+ self.check_ostree_parameters()
+
+ def check_location(self, location):
+ repo = OSTree.Repo.new(Gio.File.new_for_path(location))
+ try:
+ repo.open()
+ except GLib.GError as e:
+ logging.debug("Error from OSTree: %s", e)
+ if 'No such file or directory' in e.message:
+ raise writeexts.ExtensionError(
+ "OSTree repo %s was not found." % location)
+ else:
+ raise writeexts.ExtensionError(
+ "Error opening OSTree repo %s: %s" % (location, e))
+
+ def check_ostree_parameters(self):
+ required = ['OSTREE_BRANCH', 'OSTREE_COMMIT_SUBJECT']
+ for var in required:
+ if os.environ.get(var, '') == '':
+ raise writeexts.ExtensionError('%s was not given' % var)
+
+
+OSTreeCheckExtension().run()
diff --git a/extensions/ostree.write b/extensions/ostree.write
new file mode 100644
index 00000000..b2b5d6e1
--- /dev/null
+++ b/extensions/ostree.write
@@ -0,0 +1,88 @@
+#!/usr/bin/python
+# Copyright (C) 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 <http://www.gnu.org/licenses/>.
+
+
+'''A Baserock write extension for deploying to OSTree repositories.'''
+
+
+from gi.repository import GLib
+from gi.repository import Gio
+from gi.repository import OSTree
+
+import os
+import subprocess
+import tempfile
+import urlparse
+
+import writeexts
+
+
+def ostree_repo_resolve_rev(repo, branch, allow_noent=True):
+ '''Return the SHA256 corresponding to 'branch'.'''
+ return repo.resolve_rev(branch, allow_noent)[1]
+
+
+def ostree_repo_commit_tree(repo, tree_dir, branch, commit_subject,
+ commit_body=''):
+ '''Commit the contents of 'tree_dir' to 'branch'.'''
+
+ repo.prepare_transaction(None)
+
+ parent = ostree_repo_resolve_rev(repo, branch)
+
+ ostree_mtree = OSTree.MutableTree()
+ tree_dir_gfile = Gio.file_new_for_path(tree_dir)
+ repo.write_directory_to_mtree(tree_dir_gfile, ostree_mtree, None, None)
+
+ root = repo.write_mtree(ostree_mtree, None)[1]
+ checksum = repo.write_commit(
+ parent, commit_subject, commit_body, None, root, None)[1]
+
+ repo.transaction_set_ref(None, branch, checksum)
+
+ stats = repo.commit_transaction(None)
+ return stats
+
+
+class OSTreeWriteExtension(writeexts.WriteExtension):
+ '''See ostree.write.help for documentation.'''
+
+ def process_args(self, args):
+ if len(args) != 2:
+ raise writeexts.ExtensionError(
+ 'Wrong number of command line args')
+
+ temp_root, location = args
+
+ repo = OSTree.Repo.new(Gio.File.new_for_path(location))
+ repo.open()
+
+ branch = os.environ.get('OSTREE_BRANCH')
+ commit_subject = os.environ.get('OSTREE_COMMIT_SUBJECT')
+ commit_body = os.environ.get('OSTREE_COMMIT_BODY')
+
+ try:
+ ostree_repo_commit_tree(repo, temp_root, branch, commit_subject, commit_body)
+ except GLib.GError as e:
+ raise writeexts.ExtensionError(
+ '%s. Failed to commit system to repo %s.' %
+ (e.message, location))
+
+ self.status(
+ msg='Created commit on branch %s in OSTree repo at %s' % (
+ branch, location))
+
+
+OSTreeWriteExtension().run()
diff --git a/extensions/ostree.write.help b/extensions/ostree.write.help
new file mode 100644
index 00000000..90a181be
--- /dev/null
+++ b/extensions/ostree.write.help
@@ -0,0 +1,73 @@
+# Copyright (C) 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 <http://www.gnu.org/licenses/>.
+
+help: |
+
+ Deploy a Baserock system to an existing OSTree repository.
+
+ Parameters:
+
+ * location: the path to the OSTree repo.
+
+ * OSTREE_BRANCH=branchname: the branch to commit to
+
+ * OSTREE_COMMIT_SUBJECT=subject: one-line commit title
+
+ * OSTREE_COMMIT_BODY=text: full commit message (optional)
+
+ See `morph help deploy` for details of how to pass parameters to write
+ extensions.
+
+ This extension requires a local OSTree repository to deploy to, which must
+ already exist. You can create a new repository using the `ostree init`
+ command.
+
+ If you want to deploy straight to the local machine, you should use a
+ 'bare' mode repository, which allows the resulting system to be quickly
+ checked out.
+
+ If you want to serve the results of a deployment from an OSTree server,
+ you need to use a local 'archive-z2' mode repository. You can then use
+ `ostree pull` on the server to pull the results of the deployment from the
+ build machine. Note that 'push' style transfers are not currently supported
+ by OSTree.
+
+ For full OSTree documentation, see <https://wiki.gnome.org/Projects/OSTree>.
+
+ IMPORTANT NOTE: OSTree can only store regular files. It cannot store device
+ nodes. If your system contains static device nodes (which all of the
+ Baserock reference systems do, at time of writing) you can use the
+ strip-device-nodes.configure extension to remove them, and leave devtmpfs
+ to create the device nodes.
+
+ If you seen an error like "Not a regular file or symlink: null.", you have
+ hit this problem.
+
+ ANOTHER IMPORTANT NOTE: OSTree uses hardlinks to checkout files quickly.
+ This has an important consequence: any files checked out from OSTree MUST
+ not be overwritten at runtime, or you *will* cause corruption in the
+ repository and/or your checked-out system. In general, if you want to
+ use OSTree for container systems or chroots, it is enough to create a
+ read-only bindmount:
+
+ mount --bind ./ostree-checkout-dir ./sysroot-dir
+ mount -o bind,remount,ro ./sysroot-dir
+
+ If you want to run a system using OSTree as the real OS of a system, you
+ are best off following this guide:
+
+ https://developer.gnome.org/ostree/stable/adapting-existing.html
+
+ This extension requires that the libostree-1 library and the Python
+ GObject-introspection bindings are available.
diff --git a/extensions/strip-device-nodes.configure b/extensions/strip-device-nodes.configure
new file mode 100644
index 00000000..9f09b560
--- /dev/null
+++ b/extensions/strip-device-nodes.configure
@@ -0,0 +1,40 @@
+#!/bin/sh
+# Copyright (C) 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+# See strip-device-nodes.configure.help for documentation.
+
+set -eu
+
+case "$STRIP_DEVICE_NODES" in
+ yes|Yes|YES|true|True|TRUE|1)
+ run=yes ;;
+ *)
+ run=no ;;
+esac
+
+if [ "$run" = "yes" ]; then
+ echo "Stripping device nodes"
+
+ root="$1"
+
+ # Be VERY CAREFUL because this runs in the host system as root.
+ if [ "$(readlink -f $1)" = / ]; then
+ echo "Refusing to remove files from /, as a safety precausion."
+ exit 1
+ fi
+
+ rm -R "$1"/dev/*
+fi
diff --git a/extensions/strip-device-nodes.configure.help b/extensions/strip-device-nodes.configure.help
new file mode 100644
index 00000000..43b79a77
--- /dev/null
+++ b/extensions/strip-device-nodes.configure.help
@@ -0,0 +1,29 @@
+# Copyright (C) 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 <http://www.gnu.org/licenses/>.
+
+help: |
+ A Baserock configuration extension for removing static device nodes.
+
+ Parameters:
+
+ STRIP_DEVICE_NODES=<1|0>: whether to strip device nodes
+
+ This extension is a workaround for a flaw in the Baserock reference systems.
+ They still contain statically created device nodes, which is not useful any
+ more for Linux systems due to the existance of the 'devtmpfs' filesystem.
+ The 'devtmpfs' filesystem creates device nodes automatically at run time.
+
+ Static device nodes are deliberately not supported by the OSTree tool, so this
+ .configure extension is needed to use the Baserock reference systems with the
+ ostree.write deployment extension.
diff --git a/systems/minimal-system-x86_64-generic.morph b/systems/minimal-system-x86_64-generic.morph
index afd9460c..418c3ac3 100644
--- a/systems/minimal-system-x86_64-generic.morph
+++ b/systems/minimal-system-x86_64-generic.morph
@@ -19,3 +19,4 @@ configuration-extensions:
- extensions/install-files
- extensions/busybox-init
- extensions/install-essential-files
+- extensions/strip-device-nodes