1195 lines
39 KiB
Diff
1195 lines
39 KiB
Diff
Description: add support for a zfs-snapshot backend.
|
|
Author: Steve Langasek <vorlon@debian.org>
|
|
Last-Update: 2020-01-04
|
|
Bug-Debian: https://bugs.debian.org/947919
|
|
|
|
Index: schroot/sbuild/sbuild-chroot-zfs-snapshot.cc
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ schroot/sbuild/sbuild-chroot-zfs-snapshot.cc
|
|
@@ -0,0 +1,304 @@
|
|
+/* Copyright © 2005-2009 Roger Leigh <rleigh@debian.org>
|
|
+ * Copyright © 2019 Steve Langasek <vorlon@debian.org>
|
|
+ *
|
|
+ * schroot 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, either version 3 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * schroot 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/>.
|
|
+ *
|
|
+ *********************************************************************/
|
|
+
|
|
+#include <config.h>
|
|
+
|
|
+#include "sbuild-chroot-zfs-snapshot.h"
|
|
+#include "sbuild-chroot-facet-session.h"
|
|
+#include "sbuild-chroot-facet-session-clonable.h"
|
|
+#include "sbuild-chroot-facet-source-clonable.h"
|
|
+#include "sbuild-chroot-facet-source.h"
|
|
+#include "sbuild-chroot-facet-mountable.h"
|
|
+#include "sbuild-format-detail.h"
|
|
+
|
|
+#include <cassert>
|
|
+#include <cerrno>
|
|
+
|
|
+#include <boost/format.hpp>
|
|
+
|
|
+using std::endl;
|
|
+using boost::format;
|
|
+using namespace sbuild;
|
|
+
|
|
+chroot_zfs_snapshot::chroot_zfs_snapshot ():
|
|
+ chroot(),
|
|
+ dataset(),
|
|
+ clone_name(),
|
|
+ snapshot_name(),
|
|
+ snapshot_options()
|
|
+{
|
|
+ add_facet(chroot_facet_source_clonable::create());
|
|
+ add_facet(chroot_facet_mountable::create());
|
|
+}
|
|
+
|
|
+chroot_zfs_snapshot::chroot_zfs_snapshot (const chroot_zfs_snapshot& rhs):
|
|
+ chroot(rhs),
|
|
+ dataset(rhs.dataset),
|
|
+ clone_name(rhs.clone_name),
|
|
+ snapshot_name(rhs.snapshot_name),
|
|
+ snapshot_options(rhs.snapshot_options)
|
|
+{
|
|
+}
|
|
+
|
|
+chroot_zfs_snapshot::~chroot_zfs_snapshot ()
|
|
+{
|
|
+}
|
|
+
|
|
+sbuild::chroot::ptr
|
|
+chroot_zfs_snapshot::clone () const
|
|
+{
|
|
+ return ptr(new chroot_zfs_snapshot(*this));
|
|
+}
|
|
+
|
|
+sbuild::chroot::ptr
|
|
+chroot_zfs_snapshot::clone_session (std::string const& session_id,
|
|
+ std::string const& alias,
|
|
+ std::string const& user,
|
|
+ bool root) const
|
|
+{
|
|
+ chroot_facet_session_clonable::const_ptr psess
|
|
+ (get_facet<chroot_facet_session_clonable>());
|
|
+ assert(psess);
|
|
+
|
|
+ ptr session(new chroot_zfs_snapshot(*this));
|
|
+ psess->clone_session_setup(*this, session, session_id, alias, user, root);
|
|
+
|
|
+ return session;
|
|
+}
|
|
+
|
|
+sbuild::chroot::ptr
|
|
+chroot_zfs_snapshot::clone_source () const
|
|
+{
|
|
+ ptr clone(new chroot_zfs_snapshot(*this));
|
|
+
|
|
+ chroot_facet_source_clonable::const_ptr psrc
|
|
+ (get_facet<chroot_facet_source_clonable>());
|
|
+ assert(psrc);
|
|
+
|
|
+ psrc->clone_source_setup(*this, clone);
|
|
+
|
|
+ return clone;
|
|
+}
|
|
+
|
|
+std::string const&
|
|
+chroot_zfs_snapshot::get_dataset () const
|
|
+{
|
|
+ return this->dataset;
|
|
+}
|
|
+
|
|
+void
|
|
+chroot_zfs_snapshot::set_dataset (std::string const& dataset)
|
|
+{
|
|
+ this->dataset = dataset;
|
|
+}
|
|
+
|
|
+std::string const&
|
|
+chroot_zfs_snapshot::get_clone_name () const
|
|
+{
|
|
+ return this->clone_name;
|
|
+}
|
|
+
|
|
+void
|
|
+chroot_zfs_snapshot::set_clone_name (std::string const& clone_name)
|
|
+{
|
|
+ this->clone_name = clone_name;
|
|
+
|
|
+ chroot_facet_mountable::ptr pmnt
|
|
+ (get_facet<chroot_facet_mountable>());
|
|
+ if (pmnt)
|
|
+ if (! get_facet<chroot_facet_source>())
|
|
+ pmnt->set_mount_device(this->clone_name);
|
|
+ else
|
|
+ pmnt->set_mount_device(get_dataset());
|
|
+}
|
|
+
|
|
+std::string const&
|
|
+chroot_zfs_snapshot::get_snapshot_name () const
|
|
+{
|
|
+ return this->snapshot_name;
|
|
+}
|
|
+
|
|
+void
|
|
+chroot_zfs_snapshot::set_snapshot_name (std::string const& snapshot_name)
|
|
+{
|
|
+ this->snapshot_name = snapshot_name;
|
|
+}
|
|
+
|
|
+std::string const&
|
|
+chroot_zfs_snapshot::get_snapshot_options () const
|
|
+{
|
|
+ return this->snapshot_options;
|
|
+}
|
|
+
|
|
+void
|
|
+chroot_zfs_snapshot::set_snapshot_options (std::string const& snapshot_options)
|
|
+{
|
|
+ this->snapshot_options = snapshot_options;
|
|
+}
|
|
+
|
|
+std::string const&
|
|
+chroot_zfs_snapshot::get_chroot_type () const
|
|
+{
|
|
+ static const std::string type("zfs-snapshot");
|
|
+
|
|
+ return type;
|
|
+}
|
|
+
|
|
+std::string
|
|
+chroot_zfs_snapshot::get_path () const
|
|
+{
|
|
+ chroot_facet_mountable::const_ptr pmnt
|
|
+ (get_facet<chroot_facet_mountable>());
|
|
+
|
|
+ std::string path(get_mount_location());
|
|
+
|
|
+ if (pmnt)
|
|
+ path += pmnt->get_location();
|
|
+
|
|
+ return path;
|
|
+}
|
|
+
|
|
+void
|
|
+chroot_zfs_snapshot::setup_env (chroot const& chroot,
|
|
+ environment& env) const
|
|
+{
|
|
+ chroot::setup_env(chroot, env);
|
|
+
|
|
+ env.add("CHROOT_ZFS_DATASET", get_dataset());
|
|
+
|
|
+ // if this is a source chroot, avoid configuring snapshotting.
|
|
+ if (chroot.get_facet<chroot_facet_source>())
|
|
+ return;
|
|
+
|
|
+ env.add("CHROOT_ZFS_SNAPSHOT_NAME", get_snapshot_name());
|
|
+ env.add("CHROOT_ZFS_CLONE_NAME", get_clone_name());
|
|
+ env.add("CHROOT_ZFS_SNAPSHOT_OPTIONS", get_snapshot_options());
|
|
+}
|
|
+
|
|
+void
|
|
+chroot_zfs_snapshot::setup_lock (chroot::setup_type type,
|
|
+ bool lock,
|
|
+ int status)
|
|
+{
|
|
+ /* Create or unlink session information. */
|
|
+ if ((type == SETUP_START && lock == true) ||
|
|
+ (type == SETUP_STOP && lock == false && status == 0))
|
|
+ {
|
|
+ bool start = (type == SETUP_START);
|
|
+ setup_session_info(start);
|
|
+ }
|
|
+}
|
|
+
|
|
+sbuild::chroot::session_flags
|
|
+chroot_zfs_snapshot::get_session_flags (chroot const& chroot) const
|
|
+{
|
|
+ session_flags flags = SESSION_NOFLAGS;
|
|
+
|
|
+ if (get_facet<chroot_facet_session>())
|
|
+ flags = flags | SESSION_PURGE;
|
|
+
|
|
+ return flags;
|
|
+}
|
|
+
|
|
+void
|
|
+chroot_zfs_snapshot::get_details (chroot const& chroot,
|
|
+ format_detail& detail) const
|
|
+{
|
|
+ chroot::get_details(chroot, detail);
|
|
+
|
|
+ if (!this->dataset.empty())
|
|
+ detail.add(_("ZFS Source Dataset"), get_dataset());
|
|
+ if (!this->snapshot_name.empty())
|
|
+ detail.add(_("ZFS Snapshot Name"), get_snapshot_name());
|
|
+ if (!this->clone_name.empty())
|
|
+ detail.add(_("ZFS Clone Dataset"), get_clone_name());
|
|
+ if (!this->snapshot_options.empty())
|
|
+ detail.add(_("ZFS Snapshot Options"), get_snapshot_options());
|
|
+}
|
|
+
|
|
+void
|
|
+chroot_zfs_snapshot::get_keyfile (chroot const& chroot,
|
|
+ keyfile& keyfile) const
|
|
+{
|
|
+ chroot::get_keyfile(chroot, keyfile);
|
|
+
|
|
+ bool session = static_cast<bool>(get_facet<chroot_facet_session>());
|
|
+
|
|
+ if (session)
|
|
+ {
|
|
+ keyfile::set_object_value(*this,
|
|
+ &chroot_zfs_snapshot::get_snapshot_name,
|
|
+ keyfile, get_name(),
|
|
+ "zfs-snapshot-name");
|
|
+ keyfile::set_object_value(*this,
|
|
+ &chroot_zfs_snapshot::get_clone_name,
|
|
+ keyfile, get_name(),
|
|
+ "zfs-clone-name");
|
|
+ }
|
|
+
|
|
+ if (!session)
|
|
+ {
|
|
+ keyfile::set_object_value(*this,
|
|
+ &chroot_zfs_snapshot::get_dataset,
|
|
+ keyfile, get_name(),
|
|
+ "zfs-dataset-name");
|
|
+ keyfile::set_object_value(*this,
|
|
+ &chroot_zfs_snapshot::get_snapshot_options,
|
|
+ keyfile, get_name(),
|
|
+ "zfs-snapshot-options");
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+chroot_zfs_snapshot::set_keyfile (chroot& chroot,
|
|
+ keyfile const& keyfile,
|
|
+ string_list& used_keys)
|
|
+{
|
|
+ chroot::set_keyfile(chroot, keyfile, used_keys);
|
|
+
|
|
+ bool session = static_cast<bool>(get_facet<chroot_facet_session>());
|
|
+
|
|
+ keyfile::get_object_value(*this, &chroot_zfs_snapshot::set_dataset,
|
|
+ keyfile, get_name(), "zfs-dataset",
|
|
+ session ?
|
|
+ keyfile::PRIORITY_DISALLOWED :
|
|
+ keyfile::PRIORITY_REQUIRED);
|
|
+ used_keys.push_back("zfs-dataset");
|
|
+
|
|
+ keyfile::get_object_value(*this, &chroot_zfs_snapshot::set_snapshot_name,
|
|
+ keyfile, get_name(), "zfs-snapshot-name",
|
|
+ session ?
|
|
+ keyfile::PRIORITY_REQUIRED :
|
|
+ keyfile::PRIORITY_DISALLOWED);
|
|
+ used_keys.push_back("zfs-snapshot-name");
|
|
+
|
|
+ keyfile::get_object_value(*this, &chroot_zfs_snapshot::set_clone_name,
|
|
+ keyfile, get_name(), "zfs-clone-name",
|
|
+ session ?
|
|
+ keyfile::PRIORITY_REQUIRED :
|
|
+ keyfile::PRIORITY_DISALLOWED);
|
|
+ used_keys.push_back("zfs-clone-name");
|
|
+
|
|
+ keyfile::get_object_value(*this, &chroot_zfs_snapshot::set_snapshot_options,
|
|
+ keyfile, get_name(), "zfs-snapshot-options",
|
|
+ session ?
|
|
+ keyfile::PRIORITY_DISALLOWED :
|
|
+ keyfile::PRIORITY_OPTIONAL); // Only needed for creating snapshot, not using snapshot
|
|
+ used_keys.push_back("zfs-snapshot-options");
|
|
+}
|
|
Index: schroot/test/sbuild-chroot-zfs-snapshot.cc
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ schroot/test/sbuild-chroot-zfs-snapshot.cc
|
|
@@ -0,0 +1,318 @@
|
|
+/* Copyright © 2006-2008 Roger Leigh <rleigh@debian.org>
|
|
+ * Copyright © 2019 Steve Langasek <vorlon@debian.org>
|
|
+ *
|
|
+ * schroot 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, either version 3 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * schroot 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/>.
|
|
+ *
|
|
+ *********************************************************************/
|
|
+
|
|
+#include <config.h>
|
|
+
|
|
+#include <sbuild/sbuild-chroot-zfs-snapshot.h>
|
|
+#include <sbuild/sbuild-chroot-facet-mountable.h>
|
|
+#include <sbuild/sbuild-i18n.h>
|
|
+#include <sbuild/sbuild-util.h>
|
|
+
|
|
+#include "test-helpers.h"
|
|
+#include "test-sbuild-chroot.h"
|
|
+
|
|
+#include <algorithm>
|
|
+#include <set>
|
|
+
|
|
+#include <cppunit/extensions/HelperMacros.h>
|
|
+
|
|
+using namespace CppUnit;
|
|
+
|
|
+using sbuild::_;
|
|
+
|
|
+class chroot_zfs_snapshot : public sbuild::chroot_zfs_snapshot
|
|
+{
|
|
+public:
|
|
+ chroot_zfs_snapshot():
|
|
+ sbuild::chroot_zfs_snapshot()
|
|
+ {}
|
|
+
|
|
+ virtual ~chroot_zfs_snapshot()
|
|
+ {}
|
|
+};
|
|
+
|
|
+class test_chroot_zfs_snapshot : public test_chroot_base<chroot_zfs_snapshot>
|
|
+{
|
|
+ CPPUNIT_TEST_SUITE(test_chroot_zfs_snapshot);
|
|
+ CPPUNIT_TEST(test_snapshot_name);
|
|
+ CPPUNIT_TEST(test_snapshot_options);
|
|
+ CPPUNIT_TEST(test_chroot_type);
|
|
+ CPPUNIT_TEST(test_setup_env);
|
|
+ CPPUNIT_TEST(test_setup_env_session);
|
|
+ CPPUNIT_TEST(test_setup_env_source);
|
|
+ CPPUNIT_TEST(test_setup_env_session_source);
|
|
+ CPPUNIT_TEST(test_setup_keyfile);
|
|
+ CPPUNIT_TEST(test_setup_keyfile_session);
|
|
+ CPPUNIT_TEST(test_setup_keyfile_source);
|
|
+ CPPUNIT_TEST(test_setup_keyfile_session_source);
|
|
+ CPPUNIT_TEST(test_session_flags);
|
|
+ CPPUNIT_TEST(test_print_details);
|
|
+ CPPUNIT_TEST(test_print_config);
|
|
+ CPPUNIT_TEST(test_run_setup_scripts);
|
|
+ CPPUNIT_TEST_SUITE_END();
|
|
+
|
|
+public:
|
|
+ test_chroot_zfs_snapshot():
|
|
+ test_chroot_base<chroot_zfs_snapshot>()
|
|
+ {}
|
|
+
|
|
+ void setUp()
|
|
+ {
|
|
+ test_chroot_base<chroot_zfs_snapshot>::setUp();
|
|
+ CPPUNIT_ASSERT(chroot);
|
|
+ CPPUNIT_ASSERT(session);
|
|
+ CPPUNIT_ASSERT(source);
|
|
+ CPPUNIT_ASSERT(session_source);
|
|
+ }
|
|
+
|
|
+ virtual void setup_chroot_props (sbuild::chroot::ptr& chroot)
|
|
+ {
|
|
+ test_chroot_base<chroot_zfs_snapshot>::setup_chroot_props(chroot);
|
|
+
|
|
+ std::shared_ptr<sbuild::chroot_zfs_snapshot> c = std::dynamic_pointer_cast<sbuild::chroot_zfs_snapshot>(chroot);
|
|
+
|
|
+ c->set_dataset("schroot-pool/testdev");
|
|
+ c->set_snapshot_options("-o checksum=off");
|
|
+
|
|
+ sbuild::chroot_facet_mountable::ptr pmnt(chroot->get_facet<sbuild::chroot_facet_mountable>());
|
|
+ CPPUNIT_ASSERT(pmnt);
|
|
+
|
|
+ pmnt->set_mount_options("-t jfs -o quota,rw");
|
|
+ pmnt->set_location("/squeeze");
|
|
+ }
|
|
+
|
|
+ void
|
|
+ test_snapshot_name()
|
|
+ {
|
|
+ std::shared_ptr<sbuild::chroot_zfs_snapshot> c = std::dynamic_pointer_cast<sbuild::chroot_zfs_snapshot>(chroot);
|
|
+ CPPUNIT_ASSERT(c);
|
|
+ c->set_snapshot_name("some-snapshot-name");
|
|
+ CPPUNIT_ASSERT(c->get_snapshot_name() == "some-snapshot-name");
|
|
+ }
|
|
+
|
|
+ void
|
|
+ test_snapshot_options()
|
|
+ {
|
|
+ std::shared_ptr<sbuild::chroot_zfs_snapshot> c = std::dynamic_pointer_cast<sbuild::chroot_zfs_snapshot>(chroot);
|
|
+ CPPUNIT_ASSERT(c);
|
|
+ c->set_snapshot_options("-o opt1,opt2");
|
|
+ CPPUNIT_ASSERT(c->get_snapshot_options() == "-o opt1,opt2");
|
|
+ }
|
|
+
|
|
+ void test_chroot_type()
|
|
+ {
|
|
+ CPPUNIT_ASSERT(chroot->get_chroot_type() == "zfs-snapshot");
|
|
+ }
|
|
+
|
|
+ void setup_env_gen(sbuild::environment &expected)
|
|
+ {
|
|
+ setup_env_chroot(expected);
|
|
+ expected.add("CHROOT_LOCATION", "/squeeze");
|
|
+ expected.add("CHROOT_MOUNT_LOCATION", "/mnt/mount-location");
|
|
+ expected.add("CHROOT_PATH", "/mnt/mount-location/squeeze");
|
|
+ expected.add("CHROOT_ZFS_DATASET", "schroot-pool/testdev");
|
|
+ expected.add("CHROOT_MOUNT_OPTIONS", "-t jfs -o quota,rw");
|
|
+ }
|
|
+
|
|
+ void test_setup_env()
|
|
+ {
|
|
+ sbuild::environment expected;
|
|
+ setup_env_gen(expected);
|
|
+ expected.add("CHROOT_TYPE", "zfs-snapshot");
|
|
+ expected.add("CHROOT_ZFS_SNAPSHOT_OPTIONS", "-o checksum=off");
|
|
+ expected.add("CHROOT_SESSION_CLONE", "true");
|
|
+ expected.add("CHROOT_SESSION_CREATE", "true");
|
|
+ expected.add("CHROOT_SESSION_PURGE", "false");
|
|
+ expected.add("CHROOT_SESSION_SOURCE", "false");
|
|
+
|
|
+ test_chroot_base<chroot_zfs_snapshot>::test_setup_env(chroot, expected);
|
|
+ }
|
|
+
|
|
+ void test_setup_env_session()
|
|
+ {
|
|
+ std::shared_ptr<sbuild::chroot_zfs_snapshot> c = std::dynamic_pointer_cast<sbuild::chroot_zfs_snapshot>(chroot);
|
|
+
|
|
+ sbuild::environment expected;
|
|
+ setup_env_gen(expected);
|
|
+ expected.add("CHROOT_TYPE", "zfs-snapshot");
|
|
+ expected.add("SESSION_ID", "test-session-name");
|
|
+ expected.add("CHROOT_ALIAS", "test-session-name");
|
|
+ expected.add("CHROOT_DESCRIPTION", chroot->get_description() + ' ' + _("(session chroot)"));
|
|
+ expected.add("CHROOT_MOUNT_DEVICE", "schroot-pool/testdev/schroot-test-session-name");
|
|
+ expected.add("CHROOT_ZFS_SNAPSHOT_NAME", "schroot-pool/testdev@test-session-name");
|
|
+ expected.add("CHROOT_ZFS_CLONE_NAME", "schroot-pool/testdev/schroot-test-session-name");
|
|
+ expected.add("CHROOT_ZFS_SNAPSHOT_OPTIONS", "-o checksum=off");
|
|
+ expected.add("CHROOT_SESSION_CLONE", "false");
|
|
+ expected.add("CHROOT_SESSION_CREATE", "false");
|
|
+ expected.add("CHROOT_SESSION_PURGE", "true");
|
|
+ expected.add("CHROOT_SESSION_SOURCE", "false");
|
|
+
|
|
+ test_chroot_base<chroot_zfs_snapshot>::test_setup_env(session, expected);
|
|
+ }
|
|
+
|
|
+ void test_setup_env_source()
|
|
+ {
|
|
+ sbuild::environment expected;
|
|
+ setup_env_gen(expected);
|
|
+ expected.add("CHROOT_TYPE", "zfs-snapshot");
|
|
+ expected.add("CHROOT_NAME", "test-name");
|
|
+ expected.add("CHROOT_DESCRIPTION", chroot->get_description() + ' ' + _("(source chroot)"));
|
|
+ expected.add("CHROOT_SESSION_CLONE", "false");
|
|
+ expected.add("CHROOT_SESSION_CREATE", "true");
|
|
+ expected.add("CHROOT_SESSION_PURGE", "false");
|
|
+ expected.add("CHROOT_SESSION_SOURCE", "false");
|
|
+
|
|
+ test_chroot_base<chroot_zfs_snapshot>::test_setup_env(source, expected);
|
|
+ }
|
|
+
|
|
+ void test_setup_env_session_source()
|
|
+ {
|
|
+ sbuild::environment expected;
|
|
+ setup_env_gen(expected);
|
|
+ expected.add("CHROOT_TYPE", "zfs-snapshot");
|
|
+ expected.add("CHROOT_NAME", "test-name");
|
|
+ expected.add("SESSION_ID", "test-session-name");
|
|
+ expected.add("CHROOT_DESCRIPTION", chroot->get_description() + ' ' + _("(source chroot) (session chroot)"));
|
|
+ expected.add("CHROOT_ALIAS", "test-session-name");
|
|
+ expected.add("CHROOT_MOUNT_DEVICE", "schroot-pool/testdev");
|
|
+ expected.add("CHROOT_SESSION_CLONE", "false");
|
|
+ expected.add("CHROOT_SESSION_CREATE", "false");
|
|
+ expected.add("CHROOT_SESSION_PURGE", "true");
|
|
+ expected.add("CHROOT_SESSION_SOURCE", "true");
|
|
+
|
|
+ test_chroot_base<chroot_zfs_snapshot>::test_setup_env(session_source, expected);
|
|
+ }
|
|
+
|
|
+ void setup_keyfile_zfs(sbuild::keyfile &expected, std::string group)
|
|
+ {
|
|
+ expected.set_value(group, "location", "/squeeze");
|
|
+ expected.set_value(group, "mount-options", "-t jfs -o quota,rw");
|
|
+ }
|
|
+
|
|
+ void test_setup_keyfile()
|
|
+ {
|
|
+ sbuild::keyfile expected;
|
|
+ std::string group = chroot->get_name();
|
|
+ setup_keyfile_chroot(expected, group);
|
|
+ setup_keyfile_source(expected, group);
|
|
+ setup_keyfile_zfs(expected, group);
|
|
+ expected.set_value(group, "type", "zfs-snapshot");
|
|
+ expected.set_value(group, "zfs-snapshot-options", "-o checksum=off");
|
|
+ expected.set_value(group, "zfs-dataset-name", "schroot-pool/testdev");
|
|
+
|
|
+ test_chroot_base<chroot_zfs_snapshot>::test_setup_keyfile
|
|
+ (chroot,expected, chroot->get_name());
|
|
+ }
|
|
+
|
|
+ void test_setup_keyfile_session()
|
|
+ {
|
|
+ sbuild::keyfile expected;
|
|
+ const std::string group(session->get_name());
|
|
+ setup_keyfile_session(expected, group);
|
|
+ setup_keyfile_zfs(expected, group);
|
|
+ expected.set_value(group, "type", "zfs-snapshot");
|
|
+ expected.set_value(group, "name", "test-session-name");
|
|
+ expected.set_value(group, "selected-name", "test-session-name");
|
|
+ expected.set_value(group, "description", chroot->get_description() + ' ' + _("(session chroot)"));
|
|
+ expected.set_value(group, "aliases", "");
|
|
+ expected.set_value(group, "zfs-snapshot-name", "schroot-pool/testdev@test-session-name");
|
|
+ expected.set_value(group, "zfs-clone-name", "schroot-pool/testdev/schroot-test-session-name");
|
|
+ expected.set_value(group, "mount-device", "schroot-pool/testdev/schroot-test-session-name");
|
|
+ expected.set_value(group, "mount-location", "/mnt/mount-location");
|
|
+
|
|
+ test_chroot_base<chroot_zfs_snapshot>::test_setup_keyfile
|
|
+ (session, expected, group);
|
|
+ }
|
|
+
|
|
+ void test_setup_keyfile_source()
|
|
+ {
|
|
+ sbuild::keyfile expected;
|
|
+ const std::string group(source->get_name());
|
|
+ setup_keyfile_chroot(expected, group);
|
|
+ setup_keyfile_zfs(expected, group);
|
|
+ expected.set_value(group, "type", "zfs-snapshot");
|
|
+ expected.set_value(group, "description", chroot->get_description() + ' ' + _("(source chroot)"));
|
|
+ expected.set_value(group, "aliases", "test-name-source,test-alias-1-source,test-alias-2-source");
|
|
+ expected.set_value(group, "zfs-snapshot-options", "-o checksum=off");
|
|
+ expected.set_value(group, "zfs-dataset-name", "schroot-pool/testdev");
|
|
+ setup_keyfile_source_clone(expected, group);
|
|
+
|
|
+ test_chroot_base<chroot_zfs_snapshot>::test_setup_keyfile
|
|
+ (source, expected, group);
|
|
+ }
|
|
+
|
|
+ void test_setup_keyfile_session_source()
|
|
+ {
|
|
+ sbuild::keyfile expected;
|
|
+ const std::string group(source->get_name());
|
|
+ setup_keyfile_chroot(expected, group);
|
|
+ setup_keyfile_zfs(expected, group);
|
|
+ expected.set_value(group, "type", "zfs-snapshot");
|
|
+ expected.set_value(group, "mount-device", "schroot-pool/testdev");
|
|
+ expected.set_value(group, "mount-location", "/mnt/mount-location");
|
|
+ expected.set_value(group, "zfs-clone-name", "schroot-pool/testdev/schroot-test-session-name");
|
|
+ expected.set_value(group, "zfs-snapshot-name", "schroot-pool/testdev@test-session-name");
|
|
+ setup_keyfile_session_source_clone(expected, group);
|
|
+
|
|
+ test_chroot_base<chroot_zfs_snapshot>::test_setup_keyfile
|
|
+ (session_source, expected, group);
|
|
+ }
|
|
+
|
|
+ void test_session_flags()
|
|
+ {
|
|
+ CPPUNIT_ASSERT(chroot->get_session_flags() ==
|
|
+ (sbuild::chroot::SESSION_CREATE |
|
|
+ sbuild::chroot::SESSION_CLONE));
|
|
+
|
|
+ CPPUNIT_ASSERT(session->get_session_flags() ==
|
|
+ (sbuild::chroot::SESSION_PURGE));
|
|
+
|
|
+ /// @todo: Should return NOFLAGS? This depends upon if source
|
|
+ /// chroots need transforming into sessions as well (which should
|
|
+ /// probably happen and be tested for independently).
|
|
+ CPPUNIT_ASSERT(source->get_session_flags() ==
|
|
+ (sbuild::chroot::SESSION_CREATE));
|
|
+ }
|
|
+
|
|
+ void test_print_details()
|
|
+ {
|
|
+ std::ostringstream os;
|
|
+ os << chroot;
|
|
+ // TODO: Compare output.
|
|
+ CPPUNIT_ASSERT(!os.str().empty());
|
|
+ }
|
|
+
|
|
+ void test_print_config()
|
|
+ {
|
|
+ std::ostringstream os;
|
|
+ sbuild::keyfile config;
|
|
+ config << chroot;
|
|
+ os << config;
|
|
+ // TODO: Compare output.
|
|
+ CPPUNIT_ASSERT(!os.str().empty());
|
|
+ }
|
|
+
|
|
+ void test_run_setup_scripts()
|
|
+ {
|
|
+ CPPUNIT_ASSERT(chroot->get_run_setup_scripts());
|
|
+ }
|
|
+
|
|
+};
|
|
+
|
|
+CPPUNIT_TEST_SUITE_REGISTRATION(test_chroot_zfs_snapshot);
|
|
Index: schroot/etc/setup.d/05zfs
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ schroot/etc/setup.d/05zfs
|
|
@@ -0,0 +1,67 @@
|
|
+#!/bin/sh
|
|
+# Copyright © 2005-2007 Roger Leigh <rleigh@debian.org>
|
|
+# Copyright © 2019 Steve Langasek <vorlon@debian.org>
|
|
+#
|
|
+# schroot 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, either version 3 of the License, or
|
|
+# (at your option) any later version.
|
|
+#
|
|
+# schroot 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/>.
|
|
+#
|
|
+#####################################################################
|
|
+
|
|
+set -e
|
|
+
|
|
+. "$SETUP_DATA_DIR/common-data"
|
|
+. "$SETUP_DATA_DIR/common-functions"
|
|
+. "$SETUP_DATA_DIR/common-config"
|
|
+
|
|
+if [ "$CHROOT_TYPE" = "zfs-snapshot" ] && [ -n "$CHROOT_ZFS_CLONE_NAME" ]; then
|
|
+
|
|
+ if [ $STAGE = "setup-start" ]; then
|
|
+
|
|
+ if ! zfs list "$CHROOT_ZFS_DATASET" >/dev/null 2>&1; then
|
|
+ fatal "Dataset '$CHROOT_ZFS_DATASET' does not exist"
|
|
+ fi
|
|
+
|
|
+ if [ "$VERBOSE" = "verbose" ]; then
|
|
+ zfs snapshot "$CHROOT_ZFS_SNAPSHOT_NAME" \
|
|
+ $CHROOT_ZFS_SNAPSHOT_OPTIONS
|
|
+ zfs clone "$CHROOT_ZFS_SNAPSHOT_NAME" \
|
|
+ "$CHROOT_ZFS_CLONE_NAME" -o mountpoint=legacy
|
|
+ else
|
|
+ zfs snapshot "$CHROOT_ZFS_SNAPSHOT_NAME" \
|
|
+ $CHROOT_ZFS_SNAPSHOT_OPTIONS > /dev/null
|
|
+ zfs clone "$CHROOT_ZFS_SNAPSHOT_NAME" \
|
|
+ "$CHROOT_ZFS_CLONE_NAME" -o mountpoint=legacy > /dev/null
|
|
+ fi
|
|
+
|
|
+ elif [ $STAGE = "setup-stop" ]; then
|
|
+
|
|
+ if zfs list "$CHROOT_ZFS_CLONE_NAME" >/dev/null 2>&1
|
|
+ then
|
|
+ if [ "$VERBOSE" = "verbose" ]; then
|
|
+ zfs destroy "$CHROOT_ZFS_CLONE_NAME"
|
|
+ zfs destroy "$CHROOT_ZFS_SNAPSHOT_NAME"
|
|
+ else
|
|
+ zfs destroy "$CHROOT_ZFS_CLONE_NAME" > /dev/null
|
|
+ zfs destroy "$CHROOT_ZFS_SNAPSHOT_NAME" > /dev/null
|
|
+ fi
|
|
+ else
|
|
+ # The dataset no longer exists, or was never created,
|
|
+ # for example on zfs clone failure.
|
|
+ warn "$CHROOT_ZFS_SNAPSHOT_NAME does not exist (it may have been removed previously)"
|
|
+ fi
|
|
+
|
|
+ fi
|
|
+
|
|
+fi
|
|
+
|
|
Index: schroot/sbuild/sbuild-chroot-zfs-snapshot.h
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ schroot/sbuild/sbuild-chroot-zfs-snapshot.h
|
|
@@ -0,0 +1,175 @@
|
|
+/* Copyright © 2005-2008 Roger Leigh <rleigh@debian.org>
|
|
+ * Copyright © 2019 Steve Langasek <vorlon@debian.org>
|
|
+ *
|
|
+ * schroot 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, either version 3 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * schroot 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/>.
|
|
+ *
|
|
+ *********************************************************************/
|
|
+
|
|
+#ifndef SBUILD_CHROOT_ZFS_SNAPSHOT_H
|
|
+#define SBUILD_CHROOT_ZFS_SNAPSHOT_H
|
|
+
|
|
+#include <sbuild/sbuild-chroot.h>
|
|
+
|
|
+namespace sbuild
|
|
+{
|
|
+
|
|
+ /**
|
|
+ * A chroot stored on a ZFS dataset.
|
|
+ *
|
|
+ * A clone dataset will be created and mounted on demand.
|
|
+ */
|
|
+ class chroot_zfs_snapshot : public chroot
|
|
+ {
|
|
+ protected:
|
|
+ /// The constructor.
|
|
+ chroot_zfs_snapshot ();
|
|
+
|
|
+ /// The copy constructor.
|
|
+ chroot_zfs_snapshot (const chroot_zfs_snapshot& rhs);
|
|
+
|
|
+ friend class chroot;
|
|
+
|
|
+ public:
|
|
+ /// The destructor.
|
|
+ virtual ~chroot_zfs_snapshot ();
|
|
+
|
|
+ virtual chroot::ptr
|
|
+ clone () const;
|
|
+
|
|
+ virtual chroot::ptr
|
|
+ clone_session (std::string const& session_id,
|
|
+ std::string const& alias,
|
|
+ std::string const& user,
|
|
+ bool root) const;
|
|
+
|
|
+ virtual chroot::ptr
|
|
+ clone_source () const;
|
|
+
|
|
+ /**
|
|
+ * Get the ZFS source dataset name. This is used by "zfs clone".
|
|
+ *
|
|
+ * @returns the dataset name.
|
|
+ */
|
|
+ std::string const&
|
|
+ get_dataset () const;
|
|
+
|
|
+ /**
|
|
+ * Set the ZFS source dataset name. This is used by "zfs clone".
|
|
+ *
|
|
+ * @param dataset the source dataset name.
|
|
+ */
|
|
+ void
|
|
+ set_dataset (std::string const& dataset);
|
|
+
|
|
+ /**
|
|
+ * Get the ZFS clone name. This is used by "zfs clone".
|
|
+ *
|
|
+ * @returns the clone name.
|
|
+ */
|
|
+ std::string const&
|
|
+ get_clone_name () const;
|
|
+
|
|
+ /**
|
|
+ * Set the clone name. This is used by "zfs clone".
|
|
+ *
|
|
+ * @param clone_name the clone name.
|
|
+ */
|
|
+ void
|
|
+ set_clone_name (std::string const& clone_name);
|
|
+
|
|
+ /**
|
|
+ * Get the ZFS snapshot name. This is used by "zfs snapshot".
|
|
+ *
|
|
+ * @returns the snapshot name.
|
|
+ */
|
|
+ std::string const&
|
|
+ get_snapshot_name () const;
|
|
+
|
|
+ /**
|
|
+ * Set the snapshot name. This is used by "zfs snapshot".
|
|
+ *
|
|
+ * @param snapshot_name the snapshot name.
|
|
+ */
|
|
+ void
|
|
+ set_snapshot_name (std::string const& snapshot_name);
|
|
+
|
|
+ /**
|
|
+ * Get the ZFS snapshot options. These are used by "zfs snapshot".
|
|
+ *
|
|
+ * @returns the options.
|
|
+ */
|
|
+ std::string const&
|
|
+ get_snapshot_options () const;
|
|
+
|
|
+ /**
|
|
+ * Set the ZFS snapshot options. These are used by "zfs snapshot".
|
|
+ *
|
|
+ * @param snapshot_options the options.
|
|
+ */
|
|
+ void
|
|
+ set_snapshot_options (std::string const& snapshot_options);
|
|
+
|
|
+ virtual std::string const&
|
|
+ get_chroot_type () const;
|
|
+
|
|
+ virtual std::string
|
|
+ get_path () const;
|
|
+
|
|
+ virtual void
|
|
+ setup_env (chroot const& chroot,
|
|
+ environment& env) const;
|
|
+
|
|
+ virtual session_flags
|
|
+ get_session_flags (chroot const& chroot) const;
|
|
+
|
|
+ protected:
|
|
+ virtual void
|
|
+ setup_lock (chroot::setup_type type,
|
|
+ bool lock,
|
|
+ int status);
|
|
+
|
|
+ virtual void
|
|
+ get_details (chroot const& chroot,
|
|
+ format_detail& detail) const;
|
|
+
|
|
+ virtual void
|
|
+ get_keyfile (chroot const& chroot,
|
|
+ keyfile& keyfile) const;
|
|
+
|
|
+ virtual void
|
|
+ set_keyfile (chroot& chroot,
|
|
+ keyfile const& keyfile,
|
|
+ string_list& used_keys);
|
|
+
|
|
+ private:
|
|
+ /// ZFS source dataset
|
|
+ std::string dataset;
|
|
+ /// ZFS clone name for "zfs clone"
|
|
+ std::string clone_name;
|
|
+ /// ZFS snapshot name for "zfs snapshot"
|
|
+ std::string snapshot_name;
|
|
+ /// ZFS snapshot options for "zfs snapshot"
|
|
+ std::string snapshot_options;
|
|
+ };
|
|
+
|
|
+}
|
|
+
|
|
+#endif /* SBUILD_CHROOT_ZFS_SNAPSHOT_H */
|
|
+
|
|
+/*
|
|
+ * Local Variables:
|
|
+ * mode:C++
|
|
+ * End:
|
|
+ */
|
|
Index: schroot/CMakeLists.txt
|
|
===================================================================
|
|
--- schroot.orig/CMakeLists.txt
|
|
+++ schroot/CMakeLists.txt
|
|
@@ -223,6 +223,19 @@
|
|
set(BLOCKDEV_DEFAULT ON)
|
|
endif(lvm-snapshot)
|
|
|
|
+# ZFS snapshot mount feature
|
|
+find_program(ZFS_EXECUTABLE zfs PATHS /sbin /usr/sbin /usr/local/sbin)
|
|
+set(ZFSSNAP_DEFAULT OFF)
|
|
+if (ZFS_EXECUTABLE)
|
|
+ set (ZFSSNAP_DEFAULT ON)
|
|
+endif (ZFS_EXECUTABLE)
|
|
+option(zfs-snapshot "Enable support for ZFS snapshots (requires ZFS)" ${ZFSSNAP_DEFAULT})
|
|
+set(BUILD_ZFSSNAP ${zfs-snapshot})
|
|
+set(SBUILD_FEATURE_ZFSSNAP ${zfs-snapshot})
|
|
+if (zfs-snapshot)
|
|
+ set(BLOCKDEV_DEFAULT ON)
|
|
+endif(zfs-snapshot)
|
|
+
|
|
# Btrfs snapshot mount feature
|
|
find_program(BTRFS_EXECUTABLE btrfs PATHS /sbin /usr/sbin /usr/local/sbin)
|
|
set(BTRFSSNAP_DEFAULT OFF)
|
|
@@ -244,6 +257,9 @@
|
|
if(lvm-snapshot AND NOT block-device)
|
|
message(FATAL_ERROR "block-device must be enabled when lvm-snapshot is enabled")
|
|
endif(lvm-snapshot AND NOT block-device)
|
|
+if(zfs-snapshot AND NOT block-device)
|
|
+ message(FATAL_ERROR "block-device must be enabled when zfs-snapshot is enabled")
|
|
+endif(zfs-snapshot AND NOT block-device)
|
|
if(btrfs-snapshot AND NOT block-device)
|
|
message(FATAL_ERROR "block-device must be enabled when btrfs-snapshot is enabled")
|
|
endif(btrfs-snapshot AND NOT block-device)
|
|
Index: schroot/test/CMakeLists.txt
|
|
===================================================================
|
|
--- schroot.orig/test/CMakeLists.txt
|
|
+++ schroot/test/CMakeLists.txt
|
|
@@ -46,6 +46,11 @@
|
|
sbuild-chroot-lvm-snapshot.cc)
|
|
endif(BUILD_LVMSNAP)
|
|
|
|
+if(BUILD_ZFSSNAP)
|
|
+ set(sbuild_chroot_zfssnap_sources
|
|
+ sbuild-chroot-zfs-snapshot.cc)
|
|
+endif(BUILD_ZFSSNAP)
|
|
+
|
|
if(BUILD_BTRFSSNAP)
|
|
set(sbuild_chroot_btrfssnap_sources
|
|
sbuild-chroot-btrfs-snapshot.cc)
|
|
@@ -64,6 +69,7 @@
|
|
sbuild-chroot-directory.cc
|
|
${sbuild_chroot_blockdev_sources}
|
|
${sbuild_chroot_lvmsnap_sources}
|
|
+ ${sbuild_chroot_zfssnap_sources}
|
|
${sbuild_chroot_btrfssnap_sources}
|
|
${sbuild_chroot_loopback_sources}
|
|
sbuild-chroot-facet-userdata.cc)
|
|
Index: schroot/test/Makefile.am
|
|
===================================================================
|
|
--- schroot.orig/test/Makefile.am
|
|
+++ schroot/test/Makefile.am
|
|
@@ -36,6 +36,7 @@
|
|
sbuild-chroot-loopback \
|
|
sbuild-chroot-lvm-snapshot \
|
|
sbuild-chroot-btrfs-snapshot \
|
|
+ sbuild-chroot-zfs-snapshot \
|
|
sbuild-chroot-config \
|
|
sbuild-chroot-facet-userdata \
|
|
sbuild-environment \
|
|
@@ -62,6 +63,7 @@
|
|
sbuild-chroot-loopback \
|
|
sbuild-chroot-lvm-snapshot \
|
|
sbuild-chroot-btrfs-snapshot \
|
|
+ sbuild-chroot-zfs-snapshot \
|
|
sbuild-chroot-config \
|
|
sbuild-chroot-facet-userdata \
|
|
sbuild-environment \
|
|
@@ -102,6 +104,11 @@
|
|
sbuild-chroot-btrfs-snapshot.cc
|
|
endif
|
|
|
|
+if BUILD_ZFSSNAP
|
|
+sbuild_chroot_zfssnap_sources = \
|
|
+ sbuild-chroot-zfs-snapshot.cc
|
|
+endif
|
|
+
|
|
sbuild_chroot_SOURCES = \
|
|
sbuild-chroot.cc \
|
|
test-sbuild-chroot.h
|
|
@@ -142,6 +149,11 @@
|
|
test-sbuild-chroot.h
|
|
sbuild_chroot_btrfs_snapshot_LDADD = libtest.la
|
|
|
|
+sbuild_chroot_zfs_snapshot_SOURCES = \
|
|
+ $(sbuild_chroot_zfssnap_sources) \
|
|
+ test-sbuild-chroot.h
|
|
+sbuild_chroot_zfs_snapshot_LDADD = libtest.la
|
|
+
|
|
sbuild_chroot_loopback_SOURCES = \
|
|
$(sbuild_chroot_loopback_sources) \
|
|
test-sbuild-chroot.h
|
|
Index: schroot/sbuild/CMakeLists.txt
|
|
===================================================================
|
|
--- schroot.orig/sbuild/CMakeLists.txt
|
|
+++ schroot/sbuild/CMakeLists.txt
|
|
@@ -59,6 +59,13 @@
|
|
sbuild-chroot-lvm-snapshot.cc)
|
|
endif(BUILD_LVMSNAP)
|
|
|
|
+if(BUILD_ZFSSNAP)
|
|
+ set(public_zfssnap_h_sources
|
|
+ sbuild-chroot-zfs-snapshot.h)
|
|
+ set(public_zfssnap_cc_sources
|
|
+ sbuild-chroot-zfs-snapshot.cc)
|
|
+endif(BUILD_ZFSSNAP)
|
|
+
|
|
if(BUILD_BTRFSSNAP)
|
|
set(public_btrfssnap_h_sources
|
|
sbuild-chroot-btrfs-snapshot.h)
|
|
@@ -148,6 +155,7 @@
|
|
${public_blockdev_base_h_sources}
|
|
${public_blockdev_h_sources}
|
|
${public_lvmsnap_h_sources}
|
|
+ ${public_zfssnap_h_sources}
|
|
${public_btrfssnap_h_sources}
|
|
${public_loopback_h_sources})
|
|
|
|
@@ -162,6 +170,7 @@
|
|
${public_blockdev_base_cc_sources}
|
|
${public_blockdev_cc_sources}
|
|
${public_lvmsnap_cc_sources}
|
|
+ ${public_zfssnap_cc_sources}
|
|
${public_btrfssnap_cc_sources}
|
|
${public_loopback_cc_sources})
|
|
|
|
Index: schroot/config.h.cmake
|
|
===================================================================
|
|
--- schroot.orig/config.h.cmake
|
|
+++ schroot/config.h.cmake
|
|
@@ -140,6 +140,9 @@
|
|
/* Set if the lvm-snapshot chroot type is present */
|
|
#cmakedefine SBUILD_FEATURE_LVMSNAP 1
|
|
|
|
+/* Set if the zfs-snapshot chroot type is present */
|
|
+#cmakedefine SBUILD_FEATURE_ZFSSNAP 1
|
|
+
|
|
/* Set if PAM support is available */
|
|
#cmakedefine SBUILD_FEATURE_PAM 1
|
|
|
|
Index: schroot/sbuild/sbuild-chroot-facet-session-clonable.cc
|
|
===================================================================
|
|
--- schroot.orig/sbuild/sbuild-chroot-facet-session-clonable.cc
|
|
+++ schroot/sbuild/sbuild-chroot-facet-session-clonable.cc
|
|
@@ -36,6 +36,9 @@
|
|
#ifdef SBUILD_FEATURE_BTRFSSNAP
|
|
#include "sbuild-chroot-btrfs-snapshot.h"
|
|
#endif // SBUILD_FEATURE_BTRFSSNAP
|
|
+#ifdef SBUILD_FEATURE_ZFSSNAP
|
|
+#include "sbuild-chroot-zfs-snapshot.h"
|
|
+#endif // SBUILD_FEATURE_ZFSSNAP
|
|
#ifdef SBUILD_FEATURE_UNION
|
|
#include "sbuild-chroot-facet-union.h"
|
|
#endif // SBUILD_FEATURE_UNION
|
|
@@ -194,6 +197,20 @@
|
|
}
|
|
#endif // SBUILD_FEATURE_BTRFSSNAP
|
|
|
|
+#ifdef SBUILD_FEATURE_ZFSSNAP
|
|
+ /* ZFS devices need the snapshot device name specifying. */
|
|
+ std::shared_ptr<chroot_zfs_snapshot> zfs_snapshot(std::dynamic_pointer_cast<chroot_zfs_snapshot>(clone));
|
|
+ if (zfs_snapshot && !zfs_snapshot->get_dataset().empty())
|
|
+ {
|
|
+ std::string snapname(zfs_snapshot->get_dataset());
|
|
+ snapname += "@" + clone->get_name();
|
|
+ zfs_snapshot->set_snapshot_name(snapname);
|
|
+
|
|
+ std::string clonename(zfs_snapshot->get_dataset());
|
|
+ clonename += "/schroot-" + clone->get_name();
|
|
+ zfs_snapshot->set_clone_name(clonename);
|
|
+ }
|
|
+#endif // SBUILD_FEATURE_LVMSNAP
|
|
#ifdef SBUILD_FEATURE_UNION
|
|
// If the parent did not have a union facet, then neither should we.
|
|
chroot_facet_union::const_ptr pparentuni(parent.get_facet<chroot_facet_union>());
|
|
Index: schroot/etc/schroot.conf
|
|
===================================================================
|
|
--- schroot.orig/etc/schroot.conf
|
|
+++ schroot/etc/schroot.conf
|
|
@@ -37,6 +37,17 @@
|
|
#groups=root,sbuild
|
|
#root-groups=root,sbuild
|
|
#
|
|
+#[sid-znap]
|
|
+#type=zfs-snapshot
|
|
+#description=Debian sid ZFS snapshot
|
|
+#groups=sbuild,root
|
|
+#root-users=rleigh
|
|
+#root-groups=root,sbuild
|
|
+#source-root-users=rleigh
|
|
+#zfs-dataset=rpool/CHROOT/sid
|
|
+#mount-options=-o atime,sync,user_xattr
|
|
+#zfs-snapshot-options=-o checksum=off
|
|
+#
|
|
#[squeeze]
|
|
#description=Debian squeeze (stable) 32-bit
|
|
#directory=/srv/chroot/squeeze
|
|
Index: schroot/man/schroot.conf.5.man
|
|
===================================================================
|
|
--- schroot.orig/man/schroot.conf.5.man
|
|
+++ schroot/man/schroot.conf.5.man
|
|
@@ -46,7 +46,7 @@
|
|
\f[CBI]type=\fP\f[CI]type\fP
|
|
The type of the chroot. Valid types are \[oq]plain\[cq], \[oq]directory\[cq],
|
|
\[oq]file\[cq], \[oq]loopback\[cq], \[oq]block\-device\[cq],
|
|
-\[oq]btrfs\-snapshot\[cq] and \[oq]lvm\-snapshot\[cq]. If empty or omitted,
|
|
+\[oq]btrfs\-snapshot\[cq], \[oq]zfs\-snapshot\[cq] and \[oq]lvm\-snapshot\[cq]. If empty or omitted,
|
|
the default type is \[oq]plain\[cq]. Note that \[oq]plain\[cq] chroots do not
|
|
run setup scripts and mount filesystems; \[oq]directory\[cq] is recommended for
|
|
normal use (see \[lq]\fIPlain and directory chroots\fP\[rq], below).
|
|
@@ -323,6 +323,23 @@
|
|
.TP
|
|
\f[CBI]btrfs\-snapshot\-directory=\fP\f[CI]directory\fP
|
|
The directory in which to store the snapshots of the above source subvolume.
|
|
+.SS ZFS snapshot chroots
|
|
+Chroots of type \[oq]zfs\-snapshot\[cq] are a ZFS clone created from an
|
|
+existing ZFS dataset. A snapshot and clone will be created from this source
|
|
+subvolume on demand at the start of a session, and then the clone will be
|
|
+mounted. At the end of the session, the clone will be unmounted and the
|
|
+clone and snapshot will be deleted. This chroot type implements the
|
|
+\fBsource chroot\fP options (see \[lq]\fISource chroot options\fP\[rq],
|
|
+below). Note that a corresponding source chroot (of type
|
|
+\[oq]directory\[cq]) will be created for each chroot of this type; this is
|
|
+for convenient access to the source volume. These additional options are
|
|
+also implemented:
|
|
+.TP
|
|
+\f[CBI]zfs\-dataset=\fP\f[CI]dataset_name\fP
|
|
+Name of the ZFS source dataset to use.
|
|
+.TP
|
|
+\f[CBI]zfs\-snapshot\-options=\fP\f[CI]snapshot_options\fP
|
|
+Snapshot options. These are additional options to pass to zfs snapshot.
|
|
.SS LVM snapshot chroots
|
|
Chroots of type \[oq]lvm\-snapshot\[cq] are a filesystem available on an LVM
|
|
logical volume (LV). A snapshot LV will be created from this LV on demand, and
|
|
Index: schroot/sbuild/sbuild-chroot.cc
|
|
===================================================================
|
|
--- schroot.orig/sbuild/sbuild-chroot.cc
|
|
+++ schroot/sbuild/sbuild-chroot.cc
|
|
@@ -33,6 +33,9 @@
|
|
#ifdef SBUILD_FEATURE_LVMSNAP
|
|
#include "sbuild-chroot-lvm-snapshot.h"
|
|
#endif // SBUILD_FEATURE_LVMSNAP
|
|
+#ifdef SBUILD_FEATURE_ZFSSNAP
|
|
+#include "sbuild-chroot-zfs-snapshot.h"
|
|
+#endif // SBUILD_FEATURE_LVMSNAP
|
|
#ifdef SBUILD_FEATURE_BTRFSSNAP
|
|
#include "sbuild-chroot-btrfs-snapshot.h"
|
|
#endif // SBUILD_FEATURE_BTRFSSNAP
|
|
@@ -193,6 +196,10 @@
|
|
else if (type == "lvm-snapshot")
|
|
new_chroot = new chroot_lvm_snapshot();
|
|
#endif // SBUILD_FEATURE_LVMSNAP
|
|
+#ifdef SBUILD_FEATURE_ZFSSNAP
|
|
+ else if (type == "zfs-snapshot")
|
|
+ new_chroot = new chroot_zfs_snapshot();
|
|
+#endif // SBUILD_FEATURE_LVMSNAP
|
|
#ifdef SBUILD_FEATURE_BTRFSSNAP
|
|
else if (type == "btrfs-snapshot")
|
|
new_chroot = new chroot_btrfs_snapshot();
|
|
Index: schroot/etc/setup.d/CMakeLists.txt
|
|
===================================================================
|
|
--- schroot.orig/etc/setup.d/CMakeLists.txt
|
|
+++ schroot/etc/setup.d/CMakeLists.txt
|
|
@@ -27,6 +27,7 @@
|
|
05btrfs
|
|
05lvm
|
|
05union
|
|
+ 05zfs
|
|
10mount
|
|
15binfmt
|
|
15killprocs
|
|
Index: schroot/etc/setup.d/10mount
|
|
===================================================================
|
|
--- schroot.orig/etc/setup.d/10mount
|
|
+++ schroot/etc/setup.d/10mount
|
|
@@ -156,6 +156,7 @@
|
|
|| [ "$CHROOT_TYPE" = "loopback" ] \
|
|
|| [ "$CHROOT_TYPE" = "block-device" ] \
|
|
|| [ "$CHROOT_TYPE" = "lvm-snapshot" ] \
|
|
+ || [ "$CHROOT_TYPE" = "zfs-snapshot" ] \
|
|
|| [ "$CHROOT_TYPE" = "btrfs-snapshot" ]; then
|
|
|
|
if [ "${CHROOT_UNION_TYPE:-none}" != "none" ]; then
|
|
@@ -211,6 +212,11 @@
|
|
fi
|
|
;;
|
|
esac
|
|
+ elif [ "$CHROOT_TYPE" = "zfs-snapshot" ]; then
|
|
+ CHROOT_MOUNT_OPTIONS="-t zfs $CHROOT_MOUNT_OPTIONS"
|
|
+ if [ -n "$CHROOT_ZFS_CLONE_NAME" ]; then
|
|
+ CHROOT_MOUNT_DEVICE="$CHROOT_ZFS_CLONE_NAME"
|
|
+ fi
|
|
fi
|
|
|
|
if [ ! -d "$CHROOT_MOUNT_LOCATION" ]; then
|