def install(progress=None, gui=True): progress.split( Phase('checks', _('Checking system'), 1, is_main=True), Phase('download', _("Downloading updates"), 39, is_main=True), Phase('install', _("Installing updates"), 60, is_main=True), ) progress.start('checks') status = UpdaterStatus.get_instance() logger.debug("Installing update (updater state = {})".format(status.state)) if not progress: progress = DummyProgress() priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT run_cmd('sudo kano-empty-trash') enough_space, space_msg = check_disk_space(priority) if not enough_space: logger.error(space_msg) progress.abort(_(space_msg)) RCState.get_instance().rc = RC.NOT_ENOUGH_SPACE return False logger.debug("Downloading any new updates that might be available.") progress.start('download') if not download(progress): logger.error("Downloading updates failed, cannot update.") return False progress.start('install') logger.debug("Installing with priority {}".format(priority.priority)) try: return do_install(progress, status, priority=priority) except Relaunch as err: raise except Exception as err: # Reset the state back to the previous one, so the updater # doesn't get stuck in 'installing' forever. status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() logger.error(err.message) progress.fail(err.message) RCState.get_instance().rc = RC.UNEXPECTED_ERROR return False
def install(progress=None): status = UpdaterStatus.get_instance() logger.debug("Installing update (updater state = {})".format(status.state)) if not progress: progress = DummyProgress() if status.state == UpdaterStatus.INSTALLING_UPDATES: msg = 'The install is already running' logger.warn(msg) progress.abort(_(msg)) return False elif status.state != UpdaterStatus.UPDATES_DOWNLOADED: logger.debug('Updates weren\'t downloaded, running download first.') progress.split( Phase('download', _('Downloading updates'), 40, is_main=True), Phase('install', _('Installing updates'), 60, is_main=True), ) progress.start('download') if not download(progress): logger.error('Downloading updates failed, cannot update.') return False progress.start('install') try: return do_install(progress, status) except Relaunch as err: raise except Exception as err: # Reset the state back to the previous one, so the updater # doesn't get stuck in 'installing' forever. status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() logger.error(err.message) progress.fail(err.message) return False
def install(progress=None, gui=True): progress.split( Phase( 'checks', _('Checking system'), 1, is_main=True ), Phase( 'download', _("Downloading updates"), 39, is_main=True ), Phase( 'install', _("Installing updates"), 60, is_main=True ), ) progress.start('checks') status = UpdaterStatus.get_instance() logger.info("Installing update (updater state = {})".format(status.state)) if not progress: progress = DummyProgress() priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT run_cmd('sudo kano-empty-trash') enough_space, space_msg = check_disk_space(priority) if not enough_space: logger.error(space_msg) progress.abort(_(space_msg)) RCState.get_instance().rc = RC.NOT_ENOUGH_SPACE return False logger.info("Downloading any new updates that might be available.") progress.start('download') if not download(progress): logger.error("Downloading updates failed, cannot update.") return False progress.start('install') logger.info("Installing with priority {}".format(priority.priority)) try: return do_install(progress, status, priority=priority) except Relaunch as err: raise except Exception as err: # Reset the state back to the previous one, so the updater # doesn't get stuck in 'installing' forever. status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() logger.error(err.message) progress.fail(err.message) RCState.get_instance().rc = RC.UNEXPECTED_ERROR return False
def download(progress=None, gui=True): status = UpdaterStatus.get_instance() dialog_proc = None if not progress: progress = DummyProgress() if status.state == UpdaterStatus.NO_UPDATES: progress.split( Phase( 'checking', _('Checking for updates'), 10, is_main=True ), Phase( 'downloading', _('Downloading updates'), 90, is_main=True ) ) progress.start('checking') check_for_updates(progress=progress) if status.state == UpdaterStatus.NO_UPDATES: progress.finish(_('No updates to download')) return False progress.start('downloading') elif status.state == UpdaterStatus.UPDATES_DOWNLOADED: err_msg = _('Updates have been downloaded already') logger.error(err_msg) progress.abort(err_msg) return True elif status.state == UpdaterStatus.DOWNLOADING_UPDATES: err_msg = _('The download is already running') logger.error(err_msg) progress.abort(err_msg) return False elif status.state == UpdaterStatus.INSTALLING_UPDATES: err_msg = _('Updates are already being installed') logger.error(err_msg) progress.abort(err_msg) return False if not is_internet(): err_msg = _('Must have internet to download the updates') logger.error(err_msg) progress.fail(err_msg) return False if not is_server_available(): err_msg = _('Could not connect to the download server') logger.error(err_msg) progress.fail(err_msg) return False # show a dialog informing the user of an automatic urgent download if status.is_urgent and not gui: # TODO: mute notifications? title = "Updater" description = "Kano HQ has just released a critical update that will repair" \ " some important things on your system! We'll download these automatically," \ " and ask you to schedule the install when they finish." buttons = "OK:green:1" dialog_proc = show_kano_dialog(title, description, buttons, blocking=False) status.state = UpdaterStatus.DOWNLOADING_UPDATES status.save() priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT logger.info('Urgent update detected, bumping to normal priority') make_normal_prio() logger.debug('Downloading with priority {}'.format(priority.priority)) try: success = do_download(progress, status, priority=priority, dialog_proc=dialog_proc) except Exception as err: progress.fail(err.message) logger.error(err.message) status.state = UpdaterStatus.UPDATES_AVAILABLE status.save() return False status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() return success
def install(progress=None, gui=True): status = UpdaterStatus.get_instance() logger.debug("Installing update (updater state = {})".format(status.state)) if not progress: progress = DummyProgress() # run_cmd('sudo kano-empty-trash') # Check for available disk space before updating # We require at least 1GB of space for the update to proceed # TODO: Take this value from apt mb_free = get_free_space() if mb_free < 1536: err_msg = N_("Only {}MB free, at least 1.5GB is needed.".format(mb_free)) logger.warn(err_msg) answer = progress.prompt( _("Not enough space to update!"), _("But I can make more room if you'd like?"), [_("OK"), _("CANCEL")] ) if answer == _("OK"): run_cmd('sudo expand-rootfs') status.state = UpdaterStatus.INSTALLING_UPDATES status.save() os.system('sudo systemctl reboot') else: logger.error(err_msg) progress.fail(_(err_msg)) return False if (status.state == UpdaterStatus.INSTALLING_UPDATES or status.state == UpdaterStatus.INSTALLING_INDEPENDENT): msg = "The install is already running" logger.warn(msg) progress.abort(msg) return False elif status.state != UpdaterStatus.UPDATES_DOWNLOADED: logger.debug("Updates weren't downloaded, running download first.") progress.split( Phase( 'download', _("Downloading updates"), 40, is_main=True ), Phase( 'install', _("Installing updates"), 60, is_main=True ), ) progress.start('download') if not download(progress): logger.error("Downloading updates failed, cannot update.") return False progress.start('install') priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT logger.debug("Installing with priority {}".format(priority.priority)) try: return do_install(progress, status, priority=priority) except Relaunch as err: raise except Exception as err: # Reset the state back to the previous one, so the updater # doesn't get stuck in 'installing' forever. status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() logger.error(err.message) progress.fail(err.message) return False
def download(progress=None, gui=True): status = UpdaterStatus.get_instance() dialog_proc = None if not progress: progress = DummyProgress() if status.state in [UpdaterStatus.NO_UPDATES, UpdaterStatus.UPDATES_DOWNLOADED]: progress.split( Phase( 'checking', _("Checking for updates"), 10, is_main=True ), Phase( 'downloading', _("Downloading updates"), 90, is_main=True ) ) pre_check_state = status.state progress.start('checking') check_for_updates(progress=progress) if status.state == UpdaterStatus.NO_UPDATES: if pre_check_state == UpdaterStatus.NO_UPDATES: msg = N_("No updates to download") logger.info(msg) progress.finish(_(msg)) return False elif pre_check_state == UpdaterStatus.UPDATES_DOWNLOADED: err_msg = N_("Latest updates have been downloaded already") logger.info(err_msg) progress.abort(_(err_msg)) return True progress.start('downloading') elif status.state == UpdaterStatus.DOWNLOADING_UPDATES: err_msg = N_("The download is already running") logger.error(err_msg) progress.abort(_(err_msg)) return False if not is_internet(): err_msg = N_("Must have internet to download the updates") logger.error(err_msg) progress.fail(_(err_msg)) RCState.get_instance().rc = RC.NO_NETWORK return False priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT if not is_server_available(): err_msg = N_("Could not connect to the download server") logger.error(err_msg) progress.fail(_(err_msg)) RCState.get_instance().rc = RC.CANNOT_REACH_KANO return False run_cmd('sudo kano-empty-trash') enough_space, space_msg = check_disk_space(priority) if not enough_space: logger.error(space_msg) progress.abort(_(space_msg)) RCState.get_instance().rc = RC.NOT_ENOUGH_SPACE return False # show a dialog informing the user of an automatic urgent download if status.is_urgent and not gui: # TODO: mute notifications? title = _("Updater") description = _( "Kano HQ has just released a critical update that will repair some" " important things on your system! We'll download these automatically," " and ask you to schedule the install when they finish." ) buttons = _("OK:green:1") dialog_proc = show_kano_dialog(title, description, buttons, blocking=False) # If the Updater is running in recovery mode, do not update the state # out of the installing ones, otherwise the recovery flow will quit. if not status.is_recovery_needed(): status.state = UpdaterStatus.DOWNLOADING_UPDATES status.save() priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT logger.info("Urgent update detected, bumping to normal priority") make_normal_prio() logger.debug("Downloading with priority {}".format(priority.priority)) try: success = do_download( progress, status, priority=priority, dialog_proc=dialog_proc ) except Exception as err: progress.fail(err.message) logger.error(err.message) RCState.get_instance().rc = RC.UNEXPECTED_ERROR status.state = UpdaterStatus.UPDATES_AVAILABLE status.save() return False if not status.is_recovery_needed(): status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() return success
def install(progress=None, gui=True): status = UpdaterStatus.get_instance() logger.debug("Installing update (updater state = {})".format(status.state)) if not progress: progress = DummyProgress() # run_cmd('sudo kano-empty-trash') # Check for available disk space before updating # We require at least 1GB of space for the update to proceed # TODO: Take this value from apt mb_free = get_free_space() if mb_free < 1536: err_msg = N_( "Only {}MB free, at least 1.5GB is needed.".format(mb_free)) logger.warn(err_msg) answer = progress.prompt(_("Not enough space to update!"), _("But I can make more room if you'd like?"), [_("OK"), _("CANCEL")]) if answer == _("OK"): run_cmd('sudo expand-rootfs') status.state = UpdaterStatus.INSTALLING_UPDATES status.save() os.system('sudo systemctl reboot') else: logger.error(err_msg) progress.fail(_(err_msg)) return False if (status.state == UpdaterStatus.INSTALLING_UPDATES or status.state == UpdaterStatus.INSTALLING_INDEPENDENT): msg = "The install is already running" logger.warn(msg) progress.abort(msg) return False elif status.state != UpdaterStatus.UPDATES_DOWNLOADED: logger.debug("Updates weren't downloaded, running download first.") progress.split( Phase('download', _("Downloading updates"), 40, is_main=True), Phase('install', _("Installing updates"), 60, is_main=True), ) progress.start('download') if not download(progress): logger.error("Downloading updates failed, cannot update.") return False progress.start('install') priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT logger.debug("Installing with priority {}".format(priority.priority)) try: return do_install(progress, status, priority=priority) except Relaunch as err: raise except Exception as err: # Reset the state back to the previous one, so the updater # doesn't get stuck in 'installing' forever. status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() logger.error(err.message) progress.fail(err.message) return False
def download(progress=None, gui=True): status = UpdaterStatus.get_instance() dialog_proc = None if not progress: progress = DummyProgress() if status.state in [ UpdaterStatus.NO_UPDATES, UpdaterStatus.UPDATES_DOWNLOADED ]: progress.split( Phase('checking', _("Checking for updates"), 10, is_main=True), Phase('downloading', _("Downloading updates"), 90, is_main=True)) pre_check_state = status.state progress.start('checking') check_for_updates(progress=progress) if status.state == UpdaterStatus.NO_UPDATES: if pre_check_state == UpdaterStatus.NO_UPDATES: msg = N_("No updates to download") logger.info(msg) progress.finish(_(msg)) return False elif pre_check_state == UpdaterStatus.UPDATES_DOWNLOADED: err_msg = N_("Latest updates have been downloaded already") logger.info(err_msg) progress.abort(_(err_msg)) return True progress.start('downloading') elif status.state == UpdaterStatus.DOWNLOADING_UPDATES: err_msg = N_("The download is already running") logger.error(err_msg) progress.abort(_(err_msg)) return False if not is_internet(): err_msg = N_("Must have internet to download the updates") logger.error(err_msg) progress.fail(_(err_msg)) RCState.get_instance().rc = RC.NO_NETWORK return False if not is_server_available(): err_msg = N_("Could not connect to the download server") logger.error(err_msg) progress.fail(_(err_msg)) RCState.get_instance().rc = RC.CANNOT_REACH_KANO return False # show a dialog informing the user of an automatic urgent download if status.is_urgent and not gui: # TODO: mute notifications? title = _("Updater") description = _( "Kano HQ has just released a critical update that will repair" " some important things on your system! We'll download these" " automatically, and ask you to schedule the install when they finish." ) buttons = _("OK:green:1") dialog_proc = show_kano_dialog(title, description, buttons, blocking=False) # If the Updater is running in recovery mode, do not update the state # out of the installing ones, otherwise the recovery flow will quit. if not status.is_recovery_needed(): status.state = UpdaterStatus.DOWNLOADING_UPDATES status.save() priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT logger.info("Urgent update detected, bumping to normal priority") make_normal_prio() logger.debug("Downloading with priority {}".format(priority.priority)) try: success = do_download(progress, status, priority=priority, dialog_proc=dialog_proc) except Exception as err: progress.fail(err.message) logger.error(err.message) RCState.get_instance().rc = RC.UNEXPECTED_ERROR status.state = UpdaterStatus.UPDATES_AVAILABLE status.save() return False if not status.is_recovery_needed(): status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() return success
def download(progress=None, gui=True): status = UpdaterStatus.get_instance() dialog_proc = None if not progress: progress = DummyProgress() if status.state == UpdaterStatus.NO_UPDATES: progress.split( Phase( 'checking', _("Checking for updates"), 10, is_main=True ), Phase( 'downloading', _("Downloading updates"), 90, is_main=True ) ) progress.start('checking') check_for_updates(progress=progress) if status.state == UpdaterStatus.NO_UPDATES: logger.info("No updates to download") progress.finish(_("No updates to download")) return False progress.start('downloading') elif status.state == UpdaterStatus.UPDATES_DOWNLOADED: err_msg = N_("Updates have been downloaded already") logger.error(err_msg) progress.abort(_(err_msg)) return True elif status.state == UpdaterStatus.DOWNLOADING_UPDATES: err_msg = N_("The download is already running") logger.error(err_msg) progress.abort(_(err_msg)) return False elif status.state == UpdaterStatus.INSTALLING_UPDATES: err_msg = N_("Updates are already being installed") logger.error(err_msg) progress.abort(_(err_msg)) return False if not is_internet(): err_msg = N_("Must have internet to download the updates") logger.error(err_msg) progress.fail(_(err_msg)) return False if not is_server_available(): err_msg = N_("Could not connect to the download server") logger.error(err_msg) progress.fail(_(err_msg)) return False # show a dialog informing the user of an automatic urgent download if status.is_urgent and not gui: # TODO: mute notifications? title = _("Updater") description = _("Kano HQ has just released a critical update that will repair" \ " some important things on your system! We'll download these automatically," \ " and ask you to schedule the install when they finish.") buttons = _("OK:green:1") dialog_proc = show_kano_dialog(title, description, buttons, blocking=False) status.state = UpdaterStatus.DOWNLOADING_UPDATES status.save() priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT logger.info("Urgent update detected, bumping to normal priority") make_normal_prio() logger.debug("Downloading with priority {}".format(priority.priority)) try: success = do_download(progress, status, priority=priority, dialog_proc=dialog_proc) except Exception as err: progress.fail(err.message) logger.error(err.message) status.state = UpdaterStatus.UPDATES_AVAILABLE status.save() return False status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() return success
def download(progress=None): status = UpdaterStatus.get_instance() if not progress: progress = DummyProgress() if status.state == UpdaterStatus.NO_UPDATES: progress.split( Phase('checking', _('Checking for updates'), 10, is_main=True), Phase('downloading', _('Downloading updates'), 90, is_main=True)) progress.start('checking') check_for_updates(progress=progress) if status.state == UpdaterStatus.NO_UPDATES: progress.finish(_('No updates to download')) return False progress.start('downloading') elif status.state == UpdaterStatus.UPDATES_DOWNLOADED: err_msg = _('Updates have been downloaded already') logger.error(err_msg) progress.abort(err_msg) return True elif status.state == UpdaterStatus.DOWNLOADING_UPDATES: err_msg = _('The download is already running') logger.error(err_msg) progress.abort(err_msg) return False elif status.state == UpdaterStatus.INSTALLING_UPDATES: err_msg = _('Updates are already being installed') logger.error(err_msg) progress.abort(err_msg) return False if not is_internet(): err_msg = _('Must have internet to download the updates') logger.error(err_msg) progress.fail(err_msg) return False if not is_server_available(): err_msg = _('Could not connect to the download server') logger.error(err_msg) progress.fail(err_msg) return False status.state = UpdaterStatus.DOWNLOADING_UPDATES status.save() try: success = do_download(progress, status) except Exception as err: progress.fail(err.message) logger.error(err.message) status.state = UpdaterStatus.UPDATES_AVAILABLE status.save() return False status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() return success
def install(progress=None, gui=True): status = UpdaterStatus.get_instance() logger.debug("Installing update (updater state = {})".format(status.state)) if not progress: progress = DummyProgress() # run_cmd('sudo kano-empty-trash') # Check for available disk space before updating # We require at least 1GB of space for the update to proceed # TODO: Take this value from apt mb_free = get_free_space() if mb_free < 1024: err_msg = _("Only {}MB free, at least 1GB is needed.".format(mb_free)) logger.warn(err_msg) answer = progress.prompt( 'Feeling full!', 'My brain is feeling a bit full, but I can make some more ' 'room if you\'d like?', ['OK', 'CANCEL'] ) if answer.lower() == 'ok': run_cmd('sudo expand-rootfs') status.state = UpdaterStatus.INSTALLING_UPDATES status.save() os.system('sudo reboot') else: logger.error(err_msg) progress.fail(err_msg) return False if status.state == UpdaterStatus.INSTALLING_UPDATES: msg = 'The install is already running' logger.warn(msg) progress.abort(_(msg)) return False elif status.state != UpdaterStatus.UPDATES_DOWNLOADED: logger.debug('Updates weren\'t downloaded, running download first.') progress.split( Phase( 'download', _('Downloading updates'), 40, is_main=True ), Phase( 'install', _('Installing updates'), 60, is_main=True ), ) progress.start('download') if not download(progress): logger.error('Downloading updates failed, cannot update.') return False progress.start('install') priority = Priority.NONE if status.is_urgent: priority = Priority.URGENT logger.debug('Installing with priority {}'.format(priority.priority)) try: return do_install(progress, status, priority=priority) except Relaunch as err: raise except Exception as err: # Reset the state back to the previous one, so the updater # doesn't get stuck in 'installing' forever. status.state = UpdaterStatus.UPDATES_DOWNLOADED status.save() logger.error(err.message) progress.fail(err.message) return False
def check_for_updates(min_time_between_checks=0, progress=None): status = UpdaterStatus.get_instance() # FIXME: FOR DEBUGGING ONLY #status.state = UpdaterStatus.UPDATES_AVAILABLE #status.last_check = int(time.time()) #status.save() #return True if not progress: progress = DummyProgress() if status.state != UpdaterStatus.NO_UPDATES: msg = _('No need to check for updates') logger.info(msg) progress.abort(msg) # Return True in all cases except when the state is UPDATES_INSTALLED # In that case, we've just updated and don't want to check for updates # again. return status.state != UpdaterStatus.UPDATES_INSTALLED if min_time_between_checks: target_delta = float(min_time_between_checks) * 60 * 60 time_now = time.time() delta = time_now - status.last_check if delta > target_delta: logger.info(_('Time check passed, doing update check!')) else: msg = _('Not enough time passed for a new update check!') logger.info(msg) progress.abort(msg) return False if not is_internet(): err_msg = _('Must have internet to check for updates') logger.error(err_msg) progress.fail(err_msg) return False if not is_server_available(): err_msg = _('Could not connect to the download server') logger.error(err_msg) progress.fail(err_msg) return False if _do_check(progress): status.state = UpdaterStatus.UPDATES_AVAILABLE logger.debug('Updates available') rv = True else: status.state = UpdaterStatus.NO_UPDATES logger.debug('No updates available') rv = False status.last_check = int(time.time()) status.save() return rv