Example #1
0
 def __init__(self, datadir=None, logdir=None):
     DistUpgradeView.__init__(self)
     self.config = DistUpgradeConfig(".")
     self._fetchProgress = NonInteractiveFetchProgress()
     self._installProgress = NonInteractiveInstallProgress(logdir)
     self._opProgress = apt.progress.base.OpProgress()
     sys.__excepthook__ = self.excepthook
def main():
    """ main method """

    # commandline setup and config
    (options, args) = do_commandline()
    config = DistUpgradeConfig(".")
    logdir = setup_logging(options, config)

    from DistUpgradeVersion import VERSION
    logging.info("release-upgrader version '%s' started" % VERSION)

    # create view and app objects
    view = setup_view(options, config, logdir)

    # gnu screen support
    if (view.needs_screen and not "RELEASE_UPGRADER_NO_SCREEN" in os.environ
            and not options.disable_gnu_screen):
        run_new_gnu_screen_window_or_reattach()

    app = DistUpgradeController(view, options, datadir=options.datadir)
    atexit.register(app._enableAptCronJob)

    # partial upgrade only
    if options.partial:
        if not app.doPartialUpgrade():
            sys.exit(1)
        sys.exit(0)

    # save system state (only if not doing just a partial upgrade)
    save_system_state(logdir)

    # full upgrade, return error code for success/failure
    if app.run():
        return 0
    return 1
Example #3
0
 def __init__(self, logdir):
     InstallProgress.__init__(self)
     logging.debug("setting up environ for non-interactive use")
     if not os.environ.has_key("DEBIAN_FRONTEND"):
         os.environ["DEBIAN_FRONTEND"] = "noninteractive"
     os.environ["APT_LISTCHANGES_FRONTEND"] = "none"
     os.environ["RELEASE_UPRADER_NO_APPORT"] = "1"
     self.config = DistUpgradeConfig(".")
     self.logdir = logdir
     self.install_run_number = 0
     try:
         if self.config.getWithDefault("NonInteractive","ForceOverwrite", False):
             apt_pkg.config.set("DPkg::Options::","--force-overwrite")
     except (NoSectionError, NoOptionError):
         pass
     # more debug
     #apt_pkg.Config.Set("Debug::pkgOrderList","true")
     #apt_pkg.Config.Set("Debug::pkgDPkgPM","true")
     # default to 2400 sec timeout
     self.timeout = 2400
     try:
         self.timeout = self.config.getint("NonInteractive","TerminalTimeout")
     except Exception:
         pass
 def __init__(self, logdir):
     InstallProgress.__init__(self)
     logging.debug("setting up environ for non-interactive use")
     os.environ["DEBIAN_FRONTEND"] = "noninteractive"
     os.environ["APT_LISTCHANGES_FRONTEND"] = "none"
     os.environ["RELEASE_UPRADER_NO_APPORT"] = "1"
     self.config = DistUpgradeConfig(".")
     self.logdir = logdir
     self.install_run_number = 0
     try:
         if self.config.getWithDefault("NonInteractive","ForceOverwrite", False):
             apt_pkg.config.set("DPkg::Options::","--force-overwrite")
     except (NoSectionError, NoOptionError):
         pass
     # more debug
     #apt_pkg.Config.Set("Debug::pkgOrderList","true")
     #apt_pkg.Config.Set("Debug::pkgDPkgPM","true")
     # default to 2400 sec timeout
     self.timeout = 2400
     try:
         self.timeout = self.config.getint("NonInteractive","TerminalTimeout")
     except Exception:
         pass
Example #5
0
    parser.add_option("--with-network",
                      dest="withNetwork",
                      action="store_true")
    parser.add_option("--without-network",
                      dest="withNetwork",
                      action="store_false")
    (options, args) = parser.parse_args()

    if not os.path.exists("/var/log/dist-upgrade"):
        os.mkdir("/var/log/dist-upgrade")
    logging.basicConfig(level=logging.DEBUG,
                        filename="/var/log/dist-upgrade/main.log",
                        format='%(asctime)s %(levelname)s %(message)s',
                        filemode='w')

    config = DistUpgradeConfig(".")
    requested_view = config.get("View", "View")
    try:
        view_modul = __import__(requested_view)
        view_class = getattr(view_modul, requested_view)
        view = view_class()
    except (ImportError, AttributeError):
        logging.error("can't import view '%s'" % requested_view)
        print "can't find %s" % requested_view
        sys.exit(1)
    app = DistUpgradeControler(view, options)

    app.run()

    # testcode to see if the bullets look nice in the dialog
    #for i in range(4):
Example #6
0
class NonInteractiveInstallProgress(InstallProgress):
    """ 
    Non-interactive version of the install progress class
    
    This ensures that conffile prompts are handled and that
    hanging scripts are killed after a (long) timeout via ctrl-c
    """

    def __init__(self, logdir):
        InstallProgress.__init__(self)
        logging.debug("setting up environ for non-interactive use")
        if not os.environ.has_key("DEBIAN_FRONTEND"):
            os.environ["DEBIAN_FRONTEND"] = "noninteractive"
        os.environ["APT_LISTCHANGES_FRONTEND"] = "none"
        os.environ["RELEASE_UPRADER_NO_APPORT"] = "1"
        self.config = DistUpgradeConfig(".")
        self.logdir = logdir
        self.install_run_number = 0
        try:
            if self.config.getWithDefault("NonInteractive","ForceOverwrite", False):
                apt_pkg.config.set("DPkg::Options::","--force-overwrite")
        except (NoSectionError, NoOptionError):
            pass
        # more debug
        #apt_pkg.Config.Set("Debug::pkgOrderList","true")
        #apt_pkg.Config.Set("Debug::pkgDPkgPM","true")
        # default to 2400 sec timeout
        self.timeout = 2400
        try:
            self.timeout = self.config.getint("NonInteractive","TerminalTimeout")
        except Exception:
            pass

    def error(self, pkg, errormsg):
        logging.error("got a error from dpkg for pkg: '%s': '%s'" % (pkg, errormsg))
        # check if re-run of maintainer script is requested
        if not self.config.getWithDefault(
            "NonInteractive","DebugBrokenScripts", False):
            return
        # re-run maintainer script with sh -x/perl debug to get a better 
        # idea what went wrong
        # 
        # FIXME: this is just a approximation for now, we also need
        #        to pass:
        #        - a version after remove (if upgrade to new version)
        #
        #        not everything is a shell or perl script
        #
        # if the new preinst fails, its not yet in /var/lib/dpkg/info
        # so this is inaccurate as well
        environ = copy.copy(os.environ)
        environ["PYCENTRAL"] = "debug"
        cmd = []

        # find what maintainer script failed
        if "post-installation" in errormsg:
            prefix = "/var/lib/dpkg/info/"
            name = "postinst"
            argument = "configure"
            maintainer_script = "%s/%s.%s" % (prefix, pkg, name)
        elif "pre-installation" in errormsg:
            prefix = "/var/lib/dpkg/tmp.ci/"
            #prefix = "/var/lib/dpkg/info/"
            name = "preinst"
            argument = "install"
            maintainer_script = "%s/%s" % (prefix, name)
        elif "pre-removal" in errormsg:
            prefix = "/var/lib/dpkg/info/"
            name = "prerm"
            argument = "remove"
            maintainer_script = "%s/%s.%s" % (prefix, pkg, name)
        elif "post-removal" in errormsg:
            prefix = "/var/lib/dpkg/info/"
            name = "postrm"
            argument = "remove"
            maintainer_script = "%s/%s.%s" % (prefix, pkg, name)
        else:
            print "UNKNOWN (trigger?) dpkg/script failure for %s (%s) " % (pkg, errormsg)
            return

        # find out about the interpreter
        if not os.path.exists(maintainer_script):
            logging.error("can not find failed maintainer script '%s' " % maintainer_script)
            return
        interp = open(maintainer_script).readline()[2:].strip().split()[0]
        if ("bash" in interp) or ("/bin/sh" in interp):
            debug_opts = ["-ex"]
        elif ("perl" in interp):
            debug_opts = ["-d"]
            environ["PERLDB_OPTS"] = "AutoTrace NonStop"
        else:
            logging.warning("unknown interpreter: '%s'" % interp)

        # check if debconf is used and fiddle a bit more if it is
        if ". /usr/share/debconf/confmodule" in open(maintainer_script).read():
            environ["DEBCONF_DEBUG"] = "developer"
            environ["DEBIAN_HAS_FRONTEND"] = "1"
            interp = "/usr/share/debconf/frontend"
            debug_opts = ["sh","-ex"]

        # build command
        cmd.append(interp)
        cmd.extend(debug_opts)
        cmd.append(maintainer_script)
        cmd.append(argument)

        # check if we need to pass a version
        if name == "postinst":
            version = Popen("dpkg-query -s %s|grep ^Config-Version" % pkg,shell=True, stdout=PIPE).communicate()[0]
            if version:
                cmd.append(version.split(":",1)[1].strip())
        elif name == "preinst":
            pkg = os.path.basename(pkg)
            pkg = pkg.split("_")[0]
            version = Popen("dpkg-query -s %s|grep ^Version" % pkg,shell=True, stdout=PIPE).communicate()[0]
            if version:
                cmd.append(version.split(":",1)[1].strip())

        logging.debug("re-running '%s' (%s)" % (cmd, environ))
        ret = subprocess.call(cmd, env=environ)
        logging.debug("%s script returned: %s" % (name,ret))
        
    def conffile(self, current, new):
        logging.warning("got a conffile-prompt from dpkg for file: '%s'" % current)
        # looks like we have a race here *sometimes*
        time.sleep(5)
	try:
          # don't overwrite
	  os.write(self.master_fd,"n\n")
 	except Exception, e:
	  logging.error("error '%s' when trying to write to the conffile"%e)
Example #7
0
class DistUpgradeViewNonInteractive(DistUpgradeView):
    " non-interactive version of the upgrade view "
    def __init__(self, datadir=None, logdir=None):
        DistUpgradeView.__init__(self)
        self.config = DistUpgradeConfig(".")
        self._fetchProgress = NonInteractiveFetchProgress()
        self._installProgress = NonInteractiveInstallProgress(logdir)
        self._opProgress = apt.progress.base.OpProgress()
        sys.__excepthook__ = self.excepthook
    def excepthook(self, type, value, traceback):
        " on uncaught exceptions -> print error and reboot "
        logging.exception("got exception '%s': %s " % (type, value))
        #sys.excepthook(type, value, traceback)
        self.confirmRestart()
    def getOpCacheProgress(self):
        " return a OpProgress() subclass for the given graphic"
        return self._opProgress
    def getFetchProgress(self):
        " return a fetch progress object "
        return self._fetchProgress
    def getInstallProgress(self, cache=None):
        " return a install progress object "
        return self._installProgress
    def updateStatus(self, msg):
        """ update the current status of the distUpgrade based
            on the current view
        """
        pass
    def setStep(self, step):
        """ we have 5 steps current for a upgrade:
        1. Analyzing the system
        2. Updating repository information
        3. Performing the upgrade
        4. Post upgrade stuff
        5. Complete
        """
        pass
    def confirmChanges(self, summary, changes, demotions, downloadSize,
                       actions=None, removal_bold=True):
        DistUpgradeView.confirmChanges(self, summary, changes, demotions, 
                                       downloadSize, actions)
	logging.debug("toinstall: '%s'" % [p.name for p in self.toInstall])
        logging.debug("toupgrade: '%s'" % [p.name for p in self.toUpgrade])
        logging.debug("toremove: '%s'" % [p.name for p in self.toRemove])
        return True
    def askYesNoQuestion(self, summary, msg, default='No'):
        " ask a Yes/No question and return True on 'Yes' "
        # if this gets enabled upgrades over ssh with the non-interactive
        # frontend will no longer work
        #if default.lower() == "no":
        #    return False
        return True
    def confirmRestart(self):
        " generic ask about the restart, can be overridden "
	logging.debug("confirmRestart() called")
        # rebooting here makes sense if we run e.g. in qemu
        return self.config.getWithDefault("NonInteractive","RealReboot", False)
    def error(self, summary, msg, extended_msg=None):
        " display a error "
        logging.error("%s %s (%s)" % (summary, msg, extended_msg))
    def abort(self):
        logging.error("view.abort called")
    )
    parser.add_option("--have-backports", dest="haveBackports", action="store_true", default=False)
    parser.add_option("--with-network", dest="withNetwork", action="store_true")
    parser.add_option("--without-network", dest="withNetwork", action="store_false")
    (options, args) = parser.parse_args()

    if not os.path.exists("/var/log/dist-upgrade"):
        os.mkdir("/var/log/dist-upgrade")
    logging.basicConfig(
        level=logging.DEBUG,
        filename="/var/log/dist-upgrade/main.log",
        format="%(asctime)s %(levelname)s %(message)s",
        filemode="w",
    )

    config = DistUpgradeConfig(".")
    requested_view = config.get("View", "View")
    try:
        view_modul = __import__(requested_view)
        view_class = getattr(view_modul, requested_view)
        view = view_class()
    except (ImportError, AttributeError):
        logging.error("can't import view '%s'" % requested_view)
        print "can't find %s" % requested_view
        sys.exit(1)
    app = DistUpgradeControler(view, options)

    app.run()

    # testcode to see if the bullets look nice in the dialog
    # for i in range(4):