示例#1
0
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
示例#2
0
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
示例#3
0
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
示例#4
0
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
示例#5
0
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
示例#6
0
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
示例#7
0
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
示例#8
0
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
示例#9
0
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
示例#10
0
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
示例#11
0
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