def restore_install_uninstall(self): """Restore a failed install or uninstall attempt. Clone the snapshot, mount the BE and notify user of its existence. Rollback if not operating on a live BE""" if self.is_live_BE: # Create a new BE based on the previously taken # snapshot. ret, self.be_name_clone, not_used = \ be.beCopy(None, self.be_name, self.snapshot_name) if ret != 0: # If the above beCopy() failed we will try it # without expecting the BE clone name to be # returned by libbe. We do this in case an old # version of libbe is on a system with # a new version of pkg. self.be_name_clone = self.be_name + "_" + \ self.snapshot_name ret, not_used, not_used2 = \ be.beCopy(self.be_name_clone, \ self.be_name, self.snapshot_name) if ret != 0: emsg(_("pkg: unable to create BE %s") \ % self.be_name_clone) return if be.beMount(self.be_name_clone, self.clone_dir) != 0: emsg(_("pkg: unable to mount BE %(name)s " "on %(clone_dir)s") % { "name": self.be_name_clone, "clone_dir": self.clone_dir }) return emsg(_("The Boot Environment %(name)s failed to be " "updated. A snapshot was taken before the failed " "attempt and is mounted here %(clone_dir)s. Use " "'beadm unmount %(clone_name)s' and then 'beadm " "activate %(clone_name)s' if you wish to boot " "to this BE.") % { "name": self.be_name, "clone_dir": self.clone_dir, "clone_name": self.be_name_clone }) else: if be.beRollback(self.be_name, self.snapshot_name) != 0: emsg("pkg: unable to rollback BE %s" % \ self.be_name) self.destroy_snapshot() emsg(_("The Boot Environment %s failed to be updated. " "A snapshot was taken before the failed attempt " "and has been restored so no changes have been " "made to %s.") % (self.be_name, self.be_name))
def init_image_recovery(self, img, be_name=None): """Initialize for an update. If a be_name is given, validate it. If we're operating on a live BE then clone the live BE and operate on the clone. If we're operating on a non-live BE we use the already created snapshot""" self.img = img if self.is_live_BE: # Create a clone of the live BE and mount it. self.destroy_snapshot() self.check_be_name(be_name) # Do nothing with the returned snapshot name # that is taken of the clone during beCopy. ret, self.be_name_clone, not_used = be.beCopy() if ret != 0: raise api_errors.UnableToCopyBE() if be_name: ret = be.beRename(self.be_name_clone, be_name) if ret == 0: self.be_name_clone = be_name else: raise api_errors.UnableToRenameBE( self.be_name_clone, be_name) if be.beMount(self.be_name_clone, self.clone_dir) != 0: raise api_errors.UnableToMountBE( self.be_name_clone, self.clone_dir) # record the UUID of this cloned boot environment not_used, self.be_name_clone_uuid = \ BootEnv.get_be_name(self.clone_dir) # Set the image to our new mounted BE. img.find_root(self.clone_dir, exact_match=True) elif be_name is not None: raise api_errors.BENameGivenOnDeadBE(be_name)
def init_image_recovery(self, img, be_name=None): """Initialize for an update. If a be_name is given, validate it. If we're operating on a live BE then clone the live BE and operate on the clone. If we're operating on a non-live BE we use the already created snapshot""" self.img = img if self.is_live_BE: # Create a clone of the live BE and mount it. self.destroy_snapshot() self.check_be_name(be_name) # Do nothing with the returned snapshot name # that is taken of the clone during beCopy. ret, self.be_name_clone, not_used = be.beCopy() if ret != 0: raise api_errors.UnableToCopyBE() if be_name: ret = be.beRename(self.be_name_clone, be_name) if ret == 0: self.be_name_clone = be_name else: raise api_errors.UnableToRenameBE(self.be_name_clone, be_name) if be.beMount(self.be_name_clone, self.clone_dir) != 0: raise api_errors.UnableToMountBE(self.be_name_clone, self.clone_dir) # record the UUID of this cloned boot environment not_used, self.be_name_clone_uuid = \ BootEnv.get_be_name(self.clone_dir) # Set the image to our new mounted BE. img.find_root(self.clone_dir, exact_match=True) elif be_name is not None: raise api_errors.BENameGivenOnDeadBE(be_name)
def restore_install_uninstall(self): """Restore a failed install or uninstall attempt. Clone the snapshot, mount the BE and notify user of its existence. Rollback if not operating on a live BE""" if self.is_live_BE: # Create a new BE based on the previously taken # snapshot. ret, self.be_name_clone, not_used = \ be.beCopy(None, self.be_name, self.snapshot_name) if ret != 0: # If the above beCopy() failed we will try it # without expecting the BE clone name to be # returned by libbe. We do this in case an old # version of libbe is on a system with # a new version of pkg. self.be_name_clone = self.be_name + "_" + \ self.snapshot_name ret, not_used, not_used2 = \ be.beCopy(self.be_name_clone, \ self.be_name, self.snapshot_name) if ret != 0: emsg(_("pkg: unable to create BE %s") \ % self.be_name_clone) return if be.beMount(self.be_name_clone, self.clone_dir) != 0: emsg( _("pkg: unable to mount BE %(name)s " "on %(clone_dir)s") % { "name": self.be_name_clone, "clone_dir": self.clone_dir }) return emsg( _("The Boot Environment %(name)s failed to be " "updated. A snapshot was taken before the failed " "attempt and is mounted here %(clone_dir)s. Use " "'beadm unmount %(clone_name)s' and then 'beadm " "activate %(clone_name)s' if you wish to boot " "to this BE.") % { "name": self.be_name, "clone_dir": self.clone_dir, "clone_name": self.be_name_clone }) else: if be.beRollback(self.be_name, self.snapshot_name) != 0: emsg("pkg: unable to rollback BE %s" % \ self.be_name) self.destroy_snapshot() emsg( _("The Boot Environment %s failed to be updated. " "A snapshot was taken before the failed attempt " "and has been restored so no changes have been " "made to %s.") % (self.be_name, self.be_name))
def restore_install_uninstall(self): """Restore a failed install or uninstall attempt. Clone the snapshot, mount the BE and notify user of its existence. Rollback if not operating on a live BE""" # flush() is necessary here so that the warnings get printed # on a new line. if self.progress_tracker: self.progress_tracker.flush() if self.is_live_BE: # Create a new BE based on the previously taken # snapshot. ret, self.be_name_clone, not_used = \ be.beCopy(None, self.be_name, self.snapshot_name) if ret != 0: # If the above beCopy() failed we will try it # without expecting the BE clone name to be # returned by libbe. We do this in case an old # version of libbe is on a system with # a new version of pkg. self.be_name_clone = self.be_name + "_" + \ self.snapshot_name ret, not_used, not_used2 = \ be.beCopy(self.be_name_clone, \ self.be_name, self.snapshot_name) if ret != 0: logger.error( _("pkg: unable to create " "BE {0}").format(self.be_name_clone)) return if be.beMount(self.be_name_clone, self.clone_dir) != 0: logger.error( _("pkg: unable to mount BE " "{name} on {clone_dir}").format( name=self.be_name_clone, clone_dir=self.clone_dir)) return logger.error( _("The Boot Environment {name} failed " "to be updated. A snapshot was taken before the " "failed attempt and is mounted here {clone_dir}. " "Use 'beadm unmount {clone_name}' and then " "'beadm activate {clone_name}' if you wish to " "boot to this BE.").format(name=self.be_name, clone_dir=self.clone_dir, clone_name=self.be_name_clone)) else: if be.beRollback(self.be_name, self.snapshot_name) != 0: logger.error("pkg: unable to rollback BE " "{0}".format(self.be_name)) self.destroy_snapshot() logger.error( _("The Boot Environment {bename} failed " "to be updated. A snapshot was taken before the " "failed attempt and has been restored so no " "changes have been made to {bename}.").format( bename=self.be_name))
def mount_be(be_name, mntpt, include_bpool=False): return be.beMount(be_name, mntpt, include_bpool=include_bpool)