From 5ce7b18b7ebc9c2fb6c431424646ed0dad0f1215 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 25 Feb 2014 16:35:07 +0000 Subject: Fix behaviour in bscs-merge when vUser and v2 don't have a file of v1 If a file was removed in vUser, and v2 doesn't have a new one, then the file is not longer needed. --- baserock-system-config-sync/baserock-system-config-sync | 5 +++-- tests/bscs-merge.pass/upgrades.out/systems/version2/run/etc/file1 | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 tests/bscs-merge.pass/upgrades.out/systems/version2/run/etc/file1 diff --git a/baserock-system-config-sync/baserock-system-config-sync b/baserock-system-config-sync/baserock-system-config-sync index e297197..a1a4a85 100755 --- a/baserock-system-config-sync/baserock-system-config-sync +++ b/baserock-system-config-sync/baserock-system-config-sync @@ -123,7 +123,7 @@ merge_regular_file() { # V1 Vuser V2 action # ------------------------------------------ # none none none inconceivable! - # exists none none use V1 + # exists none none do nothing # none exists none use Vuser # none none exists use V2 # exists none exists use V2 @@ -137,7 +137,8 @@ merge_regular_file() { case "$v1_exists $vu_exists $v2_exists" in 'exists none none') - cp -a "$v1" "$vt" + # Do nothing, if the file was removed in vu and v2 doesn't have it, + # then the file is not longer needed ;; 'none exists none') cp -a "$vu" "$vt" diff --git a/tests/bscs-merge.pass/upgrades.out/systems/version2/run/etc/file1 b/tests/bscs-merge.pass/upgrades.out/systems/version2/run/etc/file1 deleted file mode 100644 index b73be5d..0000000 --- a/tests/bscs-merge.pass/upgrades.out/systems/version2/run/etc/file1 +++ /dev/null @@ -1,2 +0,0 @@ -whereami=v1 -version=v1 -- cgit v1.2.1 From d8532bc2f93a80b5be8701955e668787be41ac3e Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 20 Feb 2014 18:34:46 +0000 Subject: Fix error in the baserock-system-config-sync behaviour table. When one file is present in v1 and in vUser, and is not present in v2, baserock-system-config-sync copies vUser version of the file. This was happening before this commit, but it was wrong explained in the behaviour table. --- baserock-system-config-sync/baserock-system-config-sync | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/baserock-system-config-sync/baserock-system-config-sync b/baserock-system-config-sync/baserock-system-config-sync index a1a4a85..f21f898 100755 --- a/baserock-system-config-sync/baserock-system-config-sync +++ b/baserock-system-config-sync/baserock-system-config-sync @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2013 Codethink Ltd. +# Copyright (c) 2013-2014 Codethink Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License Version 2 as @@ -127,7 +127,7 @@ merge_regular_file() { # none exists none use Vuser # none none exists use V2 # exists none exists use V2 - # exists exists none use V2 + # exists exists none use Vuser # none exists exists diff V2 Vuser applied to V2 # exists exists exists diff V1 Vuser applied to V2 -- cgit v1.2.1 From 2c6259f156087e2b99d02666c5323d598aca9f45 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 20 Feb 2014 18:42:15 +0000 Subject: Modify 'baserock-system-config-sync' to get two arguments using 'merge' Since with 'system-version-manager' is possible to change the default system, 'baserock-system-config-sync' shouldn't get the default system, and get an extra parameter to choose the system version to merge. --- baserock-system-config-sync/baserock-system-config-sync | 11 ++++++----- tests/run_tests.sh | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/baserock-system-config-sync/baserock-system-config-sync b/baserock-system-config-sync/baserock-system-config-sync index f21f898..7321a1b 100755 --- a/baserock-system-config-sync/baserock-system-config-sync +++ b/baserock-system-config-sync/baserock-system-config-sync @@ -23,7 +23,7 @@ set -eu usage() { - echo "Usage: $(basename $0) merge NEW_VERSION_LABEL" >&2 + echo "Usage: $(basename $0) merge OLD_VERSION_LABEL NEW_VERSION_LABEL" >&2 echo " $(basename $0) sync CANONICAL_VERSION_LABEL" >&2 exit 1 } @@ -187,18 +187,19 @@ fi if [ "$1" = "merge" ]; then - if [ "$#" != 2 ]; then + if [ "$#" != 3 ]; then usage "$0" fi - new_version="$2" + old_version="$2" + new_version="$3" mounting_point=$(mktemp -d) "$mounting_script" "$mounting_point" if [ ! -d "$mounting_point/systems/$new_version" ]; then "$unmount" "$mounting_point" die "Error: version not found - '$new_version'" fi - v1_dir="$mounting_point/systems/default/orig/etc" - vu_dir="$mounting_point/systems/default/run/etc" + v1_dir="$mounting_point/systems/$old_version/orig/etc" + vu_dir="$mounting_point/systems/$old_version/run/etc" v2_dir="$mounting_point/systems/$new_version/run/etc" vt_dir="$mounting_point/systems/$new_version/run/etc.new" mkdir "$vt_dir" diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 102aea6..d460bf7 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -53,7 +53,7 @@ for folder in "$merge_pass_folder/"*.in; do TMPDIR=$(mktemp -d) TMPDIR=$TMPDIR mounting_script="./fake_mounting_script.sh" unmount=true \ mounting_script_test_dir="$folder" "$bscs_script" "merge" \ - "version2" &>> "$bscs_log" + "default" "version2" &>> "$bscs_log" exit_code="$?" if [ "$exit_code" -ne 0 ]; then echo ": FAILED (exit code "$exit_code")" 1>&2 @@ -75,7 +75,7 @@ for folder in "$merge_fail_folder/"*.in; do TMPDIR=$(mktemp -d) TMPDIR=$TMPDIR mounting_script="./fake_mounting_script.sh" unmount=true \ mounting_script_test_dir="$folder" "$bscs_script" "merge" \ - "version2" &>> "$bscs_log" + "default" "version2" &>> "$bscs_log" if [ $? -eq 0 ]; then echo ": FAILED" 1>&2 exit 1 -- cgit v1.2.1 From 8ea4bfba8076af0f325b7be11761e64f2c96819b Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 26 Feb 2014 17:29:30 +0000 Subject: baserock-system-config-sync: Add some logging to the standard output. --- baserock-system-config-sync/baserock-system-config-sync | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/baserock-system-config-sync/baserock-system-config-sync b/baserock-system-config-sync/baserock-system-config-sync index 7321a1b..47da83d 100755 --- a/baserock-system-config-sync/baserock-system-config-sync +++ b/baserock-system-config-sync/baserock-system-config-sync @@ -139,18 +139,23 @@ merge_regular_file() { 'exists none none') # Do nothing, if the file was removed in vu and v2 doesn't have it, # then the file is not longer needed + echo "File $v1 was removed by the user, no longer exists" ;; 'none exists none') cp -a "$vu" "$vt" + echo "File $vu created by the user, copied to $vt" ;; 'none none exists') cp -a "$v2" "$vt" + echo "File $v2 only present in the new version, copied to $vt" ;; 'exists none exists') cp -a "$v2" "$vt" + echo "File $v2, removed by the user, copied to $vt" ;; 'exists exists none') cp -a "$vu" "$vt" + echo "File $vu, not present in the new version, copied to $vt" ;; 'none exists exists') cp -a "$v2" "$vt" @@ -160,7 +165,12 @@ merge_regular_file() { if ! (diff -u "$v2" --label="$v2" "$vu" --label="$vu" | patch "$vt" -f); then cp -a "$v2" "$vt" # merge failed, use v2 # 'patch' creates a file '.rej' with the diff that did not apply + echo "File $vt left as it was in $v2 as merging failed" + else + echo "File $vt was pached with diff between $v2 and $vu" fi + else + echo "Files $vu and $v2 are the same, not patching" fi ;; 'exists exists exists') @@ -171,7 +181,12 @@ merge_regular_file() { if ! (diff -u "$v1" --label="$v1" "$vu" --label="$vu" | patch "$vt" -f); then cp -a "$v2" "$vt" # merge failed, use v2 # 'patch' creates a file '.rej' with the diff that did not apply + echo "File $vt left as it was in $v2 as merging failed" + else + echo "File $vt was pached with diff between $v1 and $vu" fi + else + echo "Files $vu and $v2 are the same, not patching" fi ;; *) -- cgit v1.2.1 From 5afdc1e8e66c565bbe2d5c8bb4669351043a3841 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 28 Feb 2014 17:23:38 +0000 Subject: baserock-system-config-sync: Force copy /etc/passwd and /etc/group This change is to ensure the existing users will exist after an upgrade. Otherwise, if there are merge conflicts when upgrading, the users will be lost and the root password will be deactivated. If that happens and the only way to access to the system is through ssh and the system was rebooted after the upgrade (manually or automatically) then the system won't be accessible anymore. This change also means that we can no longer make changes to the base /etc/passwd or /etc/group in the 'fhs-dirs' chunk without adding a manual hook to add the new users/groups when upgrading old systems. In the following link is the email thread where was discussed this issue: http://vlists.pepperfish.net/pipermail/baserock-dev-baserock.org/2014-March/004581.html --- baserock-system-config-sync/baserock-system-config-sync | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/baserock-system-config-sync/baserock-system-config-sync b/baserock-system-config-sync/baserock-system-config-sync index 47da83d..7b7c697 100755 --- a/baserock-system-config-sync/baserock-system-config-sync +++ b/baserock-system-config-sync/baserock-system-config-sync @@ -224,6 +224,14 @@ if [ "$1" = "merge" ]; then merge "$vu_dir" "$v1_dir" "$vu_dir" "$v2_dir" "$vt_dir" merge "$v2_dir" "$v1_dir" "$vu_dir" "$v2_dir" "$vt_dir" + if [ -f "$vu_dir/passwd" ]; then + cp "$vu_dir/passwd" "$vt_dir/passwd" + fi + if [ -f "$vu_dir/group" ]; then + cp "$vu_dir/group" "$vt_dir/group" + fi + + rm -rf "$v2_dir" mv "$vt_dir" "$v2_dir" elif [ "$1" = "sync" ]; then -- cgit v1.2.1 From 3ff52dc3935ae52b5b633a98eec1eb1ff3be0f29 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 20 Feb 2014 18:41:28 +0000 Subject: Add script to modify the bootloader and manage different parallel OS. This is part of the upgrades work. With this tool you can now switch between versions of the OS, remove a version, list all the versions present in the system, get the default version and the running version, and deploy a new system. All of the above is possible with the following subcommands: - list - deploy - get-default - get-running - remove - set-default It also activates a bootloader menu to choose a version to boot. The menu is important to make sure the user can boot the old OS if the new kernel doesn't work. --- Makefile.am | 3 +- configure.ac | 3 +- system-version-manager/Makefile.am | 20 ++ system-version-manager/system-version-manager | 314 ++++++++++++++++++++++++++ 4 files changed, 338 insertions(+), 2 deletions(-) create mode 100644 system-version-manager/Makefile.am create mode 100755 system-version-manager/system-version-manager diff --git a/Makefile.am b/Makefile.am index 746bd9c..e3d38ef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ # vi:set ts=8 sw=8 noet ai nocindent: # - -# Copyright (c) 2011-2013 Codethink Ltd. +# Copyright (c) 2011-2014 Codethink Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License Version 2 as @@ -22,6 +22,7 @@ SUBDIRS = \ tb-switch \ tb-update \ baserock-system-config-sync \ + system-version-manager \ tests .PHONY: ChangeLog diff --git a/configure.ac b/configure.ac index 17ec2dd..0e12f62 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # vi:set et ai sw=2 sts=2 ts=2: */ # - -# Copyright (c) 2011-2012 Codethink Ltd. +# Copyright (c) 2011-2014 Codethink Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License Version 2 as @@ -122,6 +122,7 @@ tbdiff-deploy/Makefile tb-switch/Makefile tb-update/Makefile baserock-system-config-sync/Makefile +system-version-manager/Makefile tests/Makefile ]) diff --git a/system-version-manager/Makefile.am b/system-version-manager/Makefile.am new file mode 100644 index 0000000..ddd0588 --- /dev/null +++ b/system-version-manager/Makefile.am @@ -0,0 +1,20 @@ +# vi:set ts=8 sw=8 noet ai nocindent: +# - +# Copyright (c) 2014 Codethink Ltd. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License Version 2 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, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# vi:set ts=8 sw=8 noet ai nocindent: + +bin_SCRIPTS = \ + system-version-manager diff --git a/system-version-manager/system-version-manager b/system-version-manager/system-version-manager new file mode 100755 index 0000000..261333b --- /dev/null +++ b/system-version-manager/system-version-manager @@ -0,0 +1,314 @@ +#!/usr/bin/python +# +# Copyright (C) 2014 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. + + +import argparse +import subprocess +import tempfile +import os +import sys +import shutil + + +class AppException(Exception): + + pass + + +class SystemNotCompatibleError(Exception): + + pass + + +class SystemVersionManager(object): + + def __init__(self, args, mount_dir): + self.device, self.current_system = self._get_mount_info() + self.mount_dir = mount_dir + + # create the top-level parser + parser = argparse.ArgumentParser(prog='system-version-manager') + subparsers = parser.add_subparsers(help='sub-command help') + + # create the parser for the "list" command + parser_list = subparsers.add_parser('list', + help='list show you a list of systems') + parser_list.set_defaults(action='list') + + # create the parser for the "deploy" command + parser_deploy= subparsers.add_parser('deploy', + help='deploy an updated base OS version to the running Baserock system') + parser_deploy.set_defaults(action='deploy') + parser_deploy.add_argument('location') + + # create the parser for the "get-default" command + parser_get_default = subparsers.add_parser('get-default', + help='prints the default system') + parser_get_default.set_defaults(action='get-default') + + # create the parser for the "get-running" command + parser_get_running = subparsers.add_parser('get-running', + help='prints the running system') + parser_get_running.set_defaults(action='get-running') + + # create the parser for the "remove" command + parser_remove = subparsers.add_parser('remove', help='remove a system') + parser_remove.add_argument('system_name', help='name of the system to remove') + parser_remove.set_defaults(action='remove') + + # create the parser for the "set-default" command + parser_set_default = subparsers.add_parser('set-default', + help='set a system as default') + parser_set_default.add_argument('system_name', help='name of the system to set') + parser_set_default.set_defaults(action='set-default') + + self.args = parser.parse_args(args[1:]) + + def status(self, msg, *args): + print msg % args + + def _check_system_exists(self, system_name): + systems_list = self._get_systems() + + if system_name not in systems_list: + sys.stderr.write("ERROR: the system %s doesn't exist\n" % system_name) + sys.exit(1) + + # To get the systems the script lists the systems under the 'systems' + # folder which are directories and are not symlinks + def _get_systems(self): + systems = os.path.join(self.mount_dir, 'systems') + return [filename for filename in os.listdir(systems) + if os.path.isdir(os.path.join(systems, filename)) + and not os.path.islink(os.path.join(systems, filename))] + + # To check which system is the default one, it checks the 'ontimeout' + # value in the extlinux.conf file. If it's not present, then pick + # the first of the present systems. + def _get_default(self): + extlinux = os.path.join(self.mount_dir, 'extlinux.conf') + with open(extlinux, 'r') as f: + for line in f: + line = line.rstrip('\n') + key, value= line.split(' ', 1) + if key == "ontimeout": + return value + if key == "label": + break + + return self.current_system + + def _atomic_symlink_update(self, source, link_name): + dirname = os.path.dirname(link_name) + temp_dir = tempfile.mkdtemp(dir=dirname) + temp_link = os.path.join(temp_dir, 'temp_link') + try: + os.symlink(source, temp_link) + os.rename(temp_link, link_name) + except (OSError, IOError): + shutil.rmtree(temp_dir) + raise + # By this time, temp_dir will be empty. + os.rmdir(temp_dir) + + def _rewrite_boot_menu(self, device, default, systems): + # Logic copied from morphlib.SaveFile to not create + # a morphlib dependency. + fd, temp_config = tempfile.mkstemp(dir=self.mount_dir) + os.close(fd) + config = os.path.join(self.mount_dir, 'extlinux.conf') + with open(temp_config, 'w') as f: + f.write('default menu.c32\n') + f.write('timeout 50\n') + f.write('prompt 0\n') + f.write('ontimeout ' + default +'\n') + for system in systems: + f.write('label ' + system +'\n') + f.write('kernel /systems/'+ system +'/kernel\n') + f.write('append root='+ device +' ' + 'rootflags=subvol=systems/'+ system +'/run ' + 'init=/sbin/init rw\n') + os.rename(temp_config, config) + + default_path = os.path.join(self.mount_dir, 'systems', 'default') + default_path_tmp = os.path.join(self.mount_dir, 'systems', 'default-tmp') + if os.path.islink(default_path): + os.symlink(default, default_path_tmp) + os.rename(default_path_tmp, default_path) + + def cmd_list(self): + for system in self._get_systems(): + print system + + def cmd_get_default(self): + print self._get_default() + + def cmd_get_running(self): + print self.current_system + + def _parse_deploy_location(self, location): + label, snapshot = os.path.split(location) + root, label = os.path.split(label) + if root != '/systems' or snapshot != 'orig': + raise AppException( + "Invalid deploy location %s. Upgrades should be deployed " + "from a Btrfs snapshot following the pattern: " + "/systems/$LABEL/orig" % location) + return label + + def cmd_deploy(self, location): + '''Client-side deployment of a new base OS version. + + This code assumes that the 'orig' subvolume has been correctly created + already. In future it could be extended to receive a delta of the + upgraded version over network somehow. + + ''' + + label = self._parse_deploy_location(location) + version_root = os.path.join(self.mount_dir, 'systems', label) + + orig_dir = os.path.join(version_root, 'orig') + run_dir = os.path.join(version_root, 'run') + try: + self.status(msg="Creating 'run' subvolume") + subprocess.check_call( + ['btrfs', 'subvolume', 'snapshot', orig_dir, run_dir]) + + self.status(msg='Updating system configuration') + log = os.path.join('/var', 'log', 'baserock-system-config-sync.log') + + with open(log, 'w') as f: + subprocess.check_call( + ['baserock-system-config-sync', 'merge', + self.current_system, label], stdout=f) + + # Copy the content of /var of the system deployed. + state_dir = os.path.join(self.mount_dir, 'state') + shared_var = os.path.join(state_dir, 'var') + new_var=os.path.join(run_dir, 'var') + + for file in os.listdir(new_var): + subprocess.call(['cp', '-a', os.path.join(new_var, file), shared_var]) + + self.status(msg="Installing the kernel") + self._install_kernel(version_root) + + except Exception as e: + # We are not controlling if deleting the suvolume fails + subprocess.call(['btrfs', 'subvolume', 'delete', run_dir]) + raise + + self._rewrite_boot_menu(self.device, self._get_default(), self._get_systems()) + + def _install_kernel(self, version_root): + '''Install the kernel outside of 'orig' or 'run' subvolumes + + This code is kind of duplicated in morphlib/writeexts.py. + + ''' + image_names = ['vmlinuz', 'zImage', 'uImage'] + kernel_dest = os.path.join(version_root, 'kernel') + for name in image_names: + try_path = os.path.join(version_root, 'run', 'boot', name) + if os.path.exists(try_path): + shutil.copy2(try_path, kernel_dest) + break + + def _get_mount_info(self): + mountpoint = subprocess.check_output( + ['findmnt', '/', '-l', '-n', '-o', 'SOURCE']) + device, subvolume = mountpoint.split('[', 1) + subvolume = subvolume.split('/run', 1)[0] + current_system = os.path.basename(subvolume) + + # Following the symlink of the device. + device = os.path.realpath(device) + return device, current_system + + def cmd_remove (self, system_name): + self._check_system_exists(system_name) + + default_system = self._get_default() + + if system_name == default_system: + sys.stderr.write("ERROR: you can't remove the default system\n") + sys.exit(1) + if system_name == self.current_system: + sys.stderr.write("ERROR: you can't remove the running system\n") + sys.exit(1) + + self.status(msg="Removing system: %s" % system_name) + system_root = os.path.join(self.mount_dir, 'systems', system_name) + + # We are not controlling if deleting the suvolume fails + subprocess.call(['btrfs', 'subvolume', 'delete', + os.path.join(system_root, 'run')]) + subprocess.call(['btrfs', 'subvolume', 'delete', + os.path.join(system_root, 'orig')]) + shutil.rmtree(system_root) + + self._rewrite_boot_menu(self.device, default_system, self._get_systems()) + + def cmd_set_default (self, system_name): + self._check_system_exists(system_name) + self._rewrite_boot_menu(self.device, system_name, self._get_systems()) + + def mount_fs(self): + subprocess.check_call(['mount', self.device, self.mount_dir]) + + def umount_fs(self): + subprocess.call(['umount', self.mount_dir]) + + def _check_system_compatibility(self): + menu_file = os.path.join(self.mount_dir, 'menu.c32') + if not os.path.isfile(menu_file): + raise SystemNotCompatibleError("menu.c32 not found") + + def run(self): + args = self.args + action = args.action + + self.mount_fs() + try: + self._check_system_compatibility() + + if action == "list": + self.cmd_list() + elif action == "deploy": + self.cmd_deploy(args.location) + elif action == "remove": + self.cmd_remove(args.system_name) + elif action == "set-default": + self.cmd_set_default(args.system_name) + elif action == "get-default": + self.cmd_get_default() + elif action == "get-running": + self.cmd_get_running() + else: + raise NotImplementedError("Unknown command %s" % action) + except SystemNotCompatibleError, e: + sys.stderr.write("ERROR, system not compatible: %s\n" % e.args[0]) + raise + finally: + self.umount_fs() + +mount_dir = tempfile.mkdtemp() +try: + SystemVersionManager(sys.argv, mount_dir).run() +finally: + os.rmdir(mount_dir) -- cgit v1.2.1 From 1db1e045a3ce3d505718572ca14546bb4273e7a3 Mon Sep 17 00:00:00 2001 From: Sam Thursfield Date: Tue, 25 Feb 2014 18:09:05 +0000 Subject: system-version-manager: Allow specifying custom path for baserock-system-config-sync This is helpful when deploying an upgrade to a system that doesn't already have baserock-system-config-sync installed. --- system-version-manager/system-version-manager | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/system-version-manager/system-version-manager b/system-version-manager/system-version-manager index 261333b..6638a35 100755 --- a/system-version-manager/system-version-manager +++ b/system-version-manager/system-version-manager @@ -192,9 +192,13 @@ class SystemVersionManager(object): self.status(msg='Updating system configuration') log = os.path.join('/var', 'log', 'baserock-system-config-sync.log') + baserock_system_config_sync = os.environ.get( + 'BASEROCK_SYSTEM_CONFIG_SYNC', + 'baserock-system-config-sync') + with open(log, 'w') as f: subprocess.check_call( - ['baserock-system-config-sync', 'merge', + [baserock_system_config_sync, 'merge', self.current_system, label], stdout=f) # Copy the content of /var of the system deployed. -- cgit v1.2.1