[node-patches] Change in ovirt-node[master]: add ovirt-upgrade-tool to perform online upgrades with new c...

jboggs at redhat.com jboggs at redhat.com
Thu Mar 21 19:24:23 UTC 2013


Joey Boggs has uploaded a new change for review.

Change subject: add ovirt-upgrade-tool to perform online upgrades with new codebase
......................................................................

add ovirt-upgrade-tool to perform online upgrades with new codebase

rhbz#858596

Signed-off-by: Joey Boggs <jboggs at redhat.com>
Change-Id: I238b49b0a85d910d9db2c2b41e222afcce6b99c5
---
M ovirt-node.spec.in
M recipe/common-pkgs.ks
M scripts/Makefile.am
A scripts/ovirt-upgrade-tool.py
M scripts/ovirtnode/install.py
5 files changed, 202 insertions(+), 3 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/64/13264/1

diff --git a/ovirt-node.spec.in b/ovirt-node.spec.in
index 59fe1cc..ee6add5 100644
--- a/ovirt-node.spec.in
+++ b/ovirt-node.spec.in
@@ -167,6 +167,10 @@
 %install
 %{__rm} -rf %{buildroot}
 make install DESTDIR=%{buildroot}
+%{__install} -d -m0755 %{buildroot}%{_libexecdir}/ovirt-node/hooks
+%{__install} -d -m0755 %{buildroot}%{_libexecdir}/ovirt-node/hooks/pre-upgrade
+%{__install} -d -m0755 %{buildroot}%{_libexecdir}/ovirt-node/hooks/post-upgrade
+%{__install} -d -m0755 %{buildroot}%{_libexecdir}/ovirt-node/hooks/rollback
 
 %if %{is_f16}
 # install libvirtd systemd service
@@ -332,7 +336,7 @@
 
 %{_sysconfdir}/sysconfig/modules/vlan.modules
 %{_sysconfdir}/modprobe.d/ovirt-qla4xxx.conf
-
+%{_libexecdir}/ovirt-node/hooks
 
 %doc COPYING
 # should be ifarch i386
@@ -356,6 +360,7 @@
 %{_libexecdir}/ovirt-config-installer
 %{_libexecdir}/ovirt-config-setup
 %{_libexecdir}/ovirt-admin-shell
+%{_libexecdir}/ovirt-upgrade-tool
 %{_libexecdir}/ovirt-init-functions.sh
 %{_sbindir}/persist
 %{_sbindir}/unpersist
diff --git a/recipe/common-pkgs.ks b/recipe/common-pkgs.ks
index 82b6ced..4ba6a4b 100644
--- a/recipe/common-pkgs.ks
+++ b/recipe/common-pkgs.ks
@@ -115,3 +115,5 @@
 NetworkManager-glib
 
 bridge-utils
+
+squashfs-tools
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index cccbb38..36eaf25 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -34,6 +34,7 @@
   ovirt-config-installer.py \
   ovirt-config-setup.py \
   ovirt-auto-install.py \
+  ovirt-upgrade-tool.py \
   ovirt-admin-shell
 
 # default hook for local_boot_trigger
@@ -44,6 +45,7 @@
 	mv $(DESTDIR)$(libexecdir)/ovirt-config-installer.py $(DESTDIR)$(libexecdir)/ovirt-config-installer
 	mv $(DESTDIR)$(libexecdir)/ovirt-config-setup.py $(DESTDIR)$(libexecdir)/ovirt-config-setup
 	mv $(DESTDIR)$(libexecdir)/ovirt-auto-install.py $(DESTDIR)$(libexecdir)/ovirt-auto-install
+	mv $(DESTDIR)$(libexecdir)/ovirt-upgrade-tool.py $(DESTDIR)$(libexecdir)/ovirt-upgrade-tool
 	mkdir -p --mode=0755 \
 	  $(DESTDIR)$(localboottriggerdir) \
 	  $(DESTDIR)$(sysconfdir)/node.d \
diff --git a/scripts/ovirt-upgrade-tool.py b/scripts/ovirt-upgrade-tool.py
new file mode 100644
index 0000000..e7a866d
--- /dev/null
+++ b/scripts/ovirt-upgrade-tool.py
@@ -0,0 +1,190 @@
+#!/usr/bin/env python
+#
+# ovirt-upgrade-tool - Copyright (C) 2013 Red Hat, Inc.
+# Written by Joey Boggs <jboggs at redhat.com>
+#
+# 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.  A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+import os
+import sys
+import shutil
+import glob
+import tempfile
+import subprocess
+from subprocess import PIPE
+import logging
+import optparse
+import time
+
+def system(command):
+    system_cmd = subprocess.Popen(command, shell=True, stdout=PIPE, stderr=PIPE)
+    output, err = system_cmd.communicate()
+    logger.propagate = False
+    logger.debug(command)
+    logger.debug(output)
+    if system_cmd.returncode == 0:
+        return True
+    else:
+        return False
+
+def fail(msg):
+    print "%s" % msg
+    logger.error(msg)
+    sys.exit(1)
+
+class UpgradeTool():
+
+    def __init__(self):
+        self.options = None
+        self.iso_file = None
+        self.python_lib = None
+        self.tmp_python_path = None
+        self.tmp_dir = tempfile.mkdtemp(prefix = "/data/tmp")
+        self.chroot_path = self.tmp_dir + "/rootfs"
+        self.hooks_path = "/usr/libexec/ovirt-node/hooks/"
+        logger.debug(self.tmp_dir)
+
+    def parse_options(self, args):
+        parser = optparse.OptionParser(usage = """
+           %prog
+           [--reboot]
+           [--no-existing-hooks]
+           [--iso]
+           """)
+
+        parser.add_option("--reboot", type="int", default="10", dest="reboot",
+                          help="Amount of time before reboot after upgrade")
+
+        parser.add_option("--no-existing-hooks", action="store_true",
+                          dest="no_existing_hooks", default="False",
+                          help="Use only new hooks from provided iso")
+
+        parser.add_option("--iso", type="string", dest="iso_file",
+                          help="Use only new hooks from provided iso")
+        (self.options, args) = parser.parse_args()
+        return self.options
+
+    def run_hooks(self, stage):
+        hooks_path = os.path.join(self.hooks_path, stage)
+        if os.path.exists(hooks_path):
+            print "Running %s hooks" % stage
+            for i in os.listdir(hooks_path):
+                hook = os.path.join(hooks_path, i)
+                print "Running: %s" % i
+                if not system(hook):
+                    print "%s hook failed: %s" % (stage, hook)
+                    return False
+            print "%s hooks completed" % stage
+            return True
+        else:
+            print "Warning: %s does not exist" % hooks_path
+            return True
+
+    def extract_rootfs(self):
+        system("cp /live/LiveOS/squashfs.img %s" % self.tmp_dir)
+        os.chdir(self.tmp_dir)
+        self.chroot_path = self.tmp_dir + "/rootfs"
+        if not system("unsquashfs squashfs.img"):
+            fail("unsquashfs failed....exiting")
+        shutil.move("squashfs-root/LiveOS/ext3fs.img", "./ext3fs.img")
+        os.mkdir("rootfs")
+        if not system("mount -o loop ext3fs.img rootfs"):
+            fail("mounting failed....exiting")
+
+    def run_upgrade(self):
+        logger.debug("hooks: %s" % self.options.no_existing_hooks)
+        if self.options.no_existing_hooks is True:
+            self.python_lib = glob.glob("%s/rootfs/usr/lib/python*" \
+                                        % self.tmp_dir)
+            if self.python_lib:
+                self.python_lib = self.python_lib[0]
+            else:
+                fail("Unable to determine python path")
+            self.tmp_python_path = "%s/site-packages/" % self.python_lib
+            # sys.path 0 is blank or working dir
+            sys.path.insert(0, self.tmp_python_path)
+
+        logger.debug(sys.path)
+        import ovirtnode.install as install
+        import ovirtnode.ovirtfunctions as _function
+        upgrade = install.Install()
+        print "Installing Bootloader"
+        if upgrade.ovirt_boot_setup():
+            print "Finishing Install"
+            if _function.finish_install():
+                print "Installation Completed"
+                return True
+            else:
+                print "Installation Failed"
+                return False
+        else:
+            print "Bootloader Installation Failed"
+            return False
+
+    def cleanup(self):
+        print "Cleaning up temporary directory"
+        system("umount %s" % self.chroot_path)
+        if system("rm -rf %s" % self.tmp_dir):
+            return True
+
+
+def main():
+    u = UpgradeTool()
+    options = u.parse_options(sys.argv[1:])
+    logger.debug(options)
+    if os.geteuid () != 0:
+        print >> sys.stderr, "You must run as root"
+        return 1
+
+    if not options.iso_file:
+        fail("iso file not defined")
+    if not os.path.exists(options.iso_file):
+        fail("%s does not exist" % options.iso_file)
+    else:
+        system("mount -o loop %s /live" % options.iso_file)
+
+    if not os.path.ismount("/live"):
+        fail("Mounting %s to /live failed. Exiting...")
+    else:
+        u.extract_rootfs()
+        if not u.run_hooks("pre-upgrade"):
+            if u.run_hooks("rollback"):
+                fail("Upgrade Failed, Rollback Completed")
+            else:
+                fail("Upgrade Failed, Rollback Failed")
+        if not u.run_upgrade():
+            fail("Upgrade Failed")
+        if not u.run_hooks("post-upgrade"):
+            if u.run_hooks("rollback"):
+                fail("Rollback Completed")
+            else:
+                fail("Rollback Failed")
+        if not u.cleanup():
+            fail("Cleanup Failed")
+        print "Pausing %s secs for reboot" % options.reboot
+        time.sleep(options.reboot)
+        system("/sbin/reboot")
+
+# setup logging facility
+formatter = logging.Formatter(fmt='%(asctime)s - %(levelname)s - %(module)s - %(message)s')
+handler = logging.FileHandler("/var/log/ovirt.log")
+handler.setFormatter(formatter)
+logger = logging.getLogger("ovirt")
+logger.setLevel(logging.DEBUG)
+logger.addHandler(handler)
+
+if __name__ == "__main__":
+    main()
diff --git a/scripts/ovirtnode/install.py b/scripts/ovirtnode/install.py
index d78ba1b..de9601b 100755
--- a/scripts/ovirtnode/install.py
+++ b/scripts/ovirtnode/install.py
@@ -295,8 +295,8 @@
                 grub_config_file = "/dev/.initramfs/live/grub/grub.conf"
             elif os.path.ismount("/run/initramfs/live"):
                 grub_config_file = "/run/initramfs/live/grub/grub.conf"
-            if is_upgrade() and not _functions.is_iscsi_install():
-                mount_liveos()
+            if _functions.is_upgrade() and not _functions.is_iscsi_install():
+                _functions.mount_liveos()
                 grub_config_file = "/liveos/grub/grub.conf"
         if _functions.is_efi_boot():
             logger.debug(str(os.listdir("/liveos")))


--
To view, visit http://gerrit.ovirt.org/13264
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I238b49b0a85d910d9db2c2b41e222afcce6b99c5
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: master
Gerrit-Owner: Joey Boggs <jboggs at redhat.com>



More information about the node-patches mailing list