From: Arvin Schnell Date: Mon, 16 Feb 2015 11:00:20 +0000 (+0100) Subject: - added installation-helper X-Git-Tag: v0.2.6~1^2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=470db02a25a2ae5ea10baa93e73266b24e8388a4;p=thirdparty%2Fsnapper.git - added installation-helper --- diff --git a/client/.gitignore b/client/.gitignore index e250d9b7..896fc183 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -1,3 +1,4 @@ *.o snapper systemd-helper +installation-helper diff --git a/client/Makefile.am b/client/Makefile.am index af0c9916..951ee6db 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -18,6 +18,15 @@ snapper_SOURCES = \ snapper_LDADD = ../snapper/libsnapper.la utils/libutils.la ../dbus/libdbus.la +libexecdir = /usr/lib/snapper + +libexec_PROGRAMS = installation-helper + +installation_helper_SOURCES = \ + installation-helper.cc + +installation_helper_LDADD = ../snapper/libsnapper.la utils/libutils.la + noinst_PROGRAMS = systemd-helper systemd_helper_SOURCES = \ diff --git a/client/installation-helper.cc b/client/installation-helper.cc new file mode 100644 index 00000000..fff26a48 --- /dev/null +++ b/client/installation-helper.cc @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2015 Novell, Inc. + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * 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, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you may + * find current contact information at www.novell.com. + */ + + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "utils/GetOpts.h" + + +using namespace snapper; +using namespace std; + + +void +step1(const string& device) +{ + // step runs in inst-sys + + cout << "step 1 device:" << device << endl; + + cout << "temporarily mounting device" << endl; + + SDir s_dir("/"); + + TmpMount tmp_mount(s_dir, device, "tmp-mnt-XXXXXX", "btrfs", 0, ""); + + cout << "copying config-file" << endl; + + mkdir((tmp_mount.getFullname() + "/etc").c_str(), 0777); + mkdir((tmp_mount.getFullname() + "/etc/snapper").c_str(), 0777); + mkdir((tmp_mount.getFullname() + "/etc/snapper/configs").c_str(), 0777); + + try + { + SysconfigFile config(CONFIGTEMPLATEDIR "/" "default"); + + config.setName(tmp_mount.getFullname() + CONFIGSDIR "/" "root"); + + config.setValue(KEY_SUBVOLUME, "/"); + config.setValue(KEY_FSTYPE, "btrfs"); + } + catch (const FileNotFoundException& e) + { + cerr << "copying config-file failed" << endl; + } + + cout << "creating filesystem config" << endl; + + Btrfs btrfs("/", tmp_mount.getFullname()); + + btrfs.createConfig(); + + cout << "creating snapshot" << endl; + + Snapper snapper("root", tmp_mount.getFullname()); + + SCD scd; + scd.read_only = false; + + Snapshots::iterator snapshot = snapper.createSingleSnapshot(scd); + + cout << "setting default subvolume" << endl; + + snapper.getFilesystem()->setDefault(snapshot->getNum()); + + cout << "done" << endl; +} + + +void +step2(const string& device, const string& root_prefix, const string& default_subvolume_name) +{ + // step runs in inst-sys + + cout << "step 2 device:" << device << " root-prefix:" << root_prefix + << " default-subvolume-name:" << default_subvolume_name << endl; + + cout << "mounting device" << endl; + + string subvol_option = default_subvolume_name; + if (!subvol_option.empty()) + subvol_option += "/"; + subvol_option += ".snapshots"; + + SDir s_dir(root_prefix + "/.snapshots"); + if (!s_dir.mount(device, "btrfs", 0, "subvol=" + subvol_option)) + { + cerr << "mounting .snapshots failed" << endl; + } + + cout << "done" << endl; +} + + +void +step3(const string& root_prefix, const string& default_subvolume_name) +{ + // step runs in inst-sys + + cout << "step 3 root-prefix:" << root_prefix << " default_subvolume_name:" + << default_subvolume_name << endl; + + cout << "adding .snapshots to fstab" << endl; + + Btrfs btrfs("/", root_prefix); + + btrfs.addToFstab(default_subvolume_name); + + cout << "done" << endl; +} + + +void +step4() +{ + // step runs in chroot + + cout << "step 4" << endl; + + cout << "modifying sysconfig-file" << endl; + + try + { + SysconfigFile sysconfig(SYSCONFIGFILE); + sysconfig.setValue("SNAPPER_CONFIGS", { "root" }); + } + catch (const FileNotFoundException& e) + { + cerr << "sysconfig-file not found" << endl; + } + + Btrfs btrfs("/", ""); + + cout << "running external programs" << endl; + + Hooks::create_config("/", &btrfs); + + cout << "done" << endl; +} + + +int +main(int argc, char** argv) +{ + setlocale(LC_ALL, ""); + + const struct option options[] = { + { "step", required_argument, 0, 0 }, + { "device", required_argument, 0, 0 }, + { "root-prefix", required_argument, 0, 0 }, + { "default-subvolume-name", required_argument, 0, 0 }, + { 0, 0, 0, 0 } + }; + + string step; + string device; + string root_prefix = "/"; + string default_subvolume_name; + + GetOpts getopts; + + getopts.init(argc, argv); + + GetOpts::parsed_opts opts = getopts.parse(options); + + GetOpts::parsed_opts::const_iterator opt; + + if ((opt = opts.find("step")) != opts.end()) + step = opt->second; + + if ((opt = opts.find("device")) != opts.end()) + device = opt->second; + + if ((opt = opts.find("root-prefix")) != opts.end()) + root_prefix = opt->second; + + if ((opt = opts.find("default-subvolume-name")) != opts.end()) + default_subvolume_name = opt->second; + + if (step == "1") + step1(device); + else if (step == "2") + step2(device, root_prefix, default_subvolume_name); + else if (step == "3") + step3(root_prefix, default_subvolume_name); + else if (step == "4") + step4(); +} diff --git a/snapper.spec.in b/snapper.spec.in index d09478cb..ffcee450 100644 --- a/snapper.spec.in +++ b/snapper.spec.in @@ -1,7 +1,7 @@ # # spec file for package snapper # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -109,6 +109,7 @@ rm -rf "$RPM_BUILD_ROOT" %defattr(-,root,root) %{prefix}/bin/snapper %{prefix}/sbin/snapperd +%{prefix}/lib/snapper %doc %{_mandir}/*/snapper.8* %doc %{_mandir}/*/snapperd.8* %doc %{_mandir}/*/snapper-configs.5* diff --git a/snapper/FileUtils.cc b/snapper/FileUtils.cc index c92b3f9a..3017451b 100644 --- a/snapper/FileUtils.cc +++ b/snapper/FileUtils.cc @@ -661,6 +661,13 @@ namespace snapper } + string + TmpDir::getFullname() const + { + return base_dir.fullname() + "/" + name; + } + + TmpMount::TmpMount(SDir& base_dir, const string& device, const string& name_template, const string& mount_type, unsigned long mount_flags, const string& mount_data) diff --git a/snapper/FileUtils.h b/snapper/FileUtils.h index f4cb8e07..f35a0ac6 100644 --- a/snapper/FileUtils.h +++ b/snapper/FileUtils.h @@ -152,6 +152,8 @@ namespace snapper const string& getName() const { return name; } + string getFullname() const; + protected: SDir& base_dir;