Example #1
0
def do_install(progress, status, priority=Priority.NONE):
    status.state = UpdaterStatus.INSTALLING_UPDATES
    status.save()

    track_data_and_sync('update-install-started', dict())

    if priority == Priority.URGENT:
        res = install_urgent(progress, status)
    else:
        res = install_standard(progress, status)

    if not res:
        return False

    run_cmd_log('apt-get --yes autoremove')
    run_cmd_log('apt-get --yes clean')

    status.state = UpdaterStatus.UPDATES_INSTALLED

    # Clear the list of independent packages.
    # They should all have been updated by the full update.
    status.updatable_independent_packages = []

    status.last_update = int(time.time())
    status.is_scheduled = False
    status.save()

    progress.finish(_("Update completed"))
    track_data_and_sync('update-install-finished', dict())

    return True
Example #2
0
    def beta_3_12_1_to_beta_3_13_0(self, dummy_progress):
        was_audio_hdmi = False

        # Get the currently set audio output channel.
        try:
            from kano_settings.system.audio import is_HDMI
            was_audio_hdmi = is_HDMI()
        except:
            logger.error("beta_3_12_1_to_beta_3_13_0: Failed to get audio output channel")

        # Replace the config.txt after numerous changes there (see kano-settings).
        try:
            import shutil
            shutil.copyfile(
                '/boot/config.txt',
                '/boot/beta_3_12_1_to_beta_3_13_0_bck_config.txt'
            )
            shutil.copyfile(
                '/usr/share/kano-settings/boot_default/config.txt',
                '/boot/config.txt'
            )
        except:
            logger.error("beta_3_12_1_to_beta_3_13_0: Failed to replace config.txt")

        # Set the audio output channel back to HDMI if it was set.
        try:
            from kano_settings.system.audio import set_to_HDMI
            if was_audio_hdmi:
                set_to_HDMI(True, force=True)
        except:
            logger.error("beta_3_12_1_to_beta_3_13_0: Failed to set HDMI audio back")

        # Remove the orphan udhcpc client, it is now obsoleted by dhcpcd5
        run_cmd_log('apt-get -y purge udhcpc')
Example #3
0
 def beta_134_to_beta_200(self, dummy_progress):
     if not is_installed('kano-character-cli'):
         logger.info("kano-character-cli not installed,"
                     " attempt to install kano-profile")
         install('kano-profile')
     run_cmd_log(
         'kano-character-cli -c "judoka" "Hair_Black" "Skin_Orange" -s')
Example #4
0
    def beta_3_16_1_to_beta_3_16_2(self, progress):
        ''' 3.16.2 is the last release for Debian Jessie. Every update past
        this point must update to 3.16.2 and then progress onwards, it can
        never happen that the system is of version 3.x.x (!= 3.16.2) and
        update directly to 4.x.x.

                          ->  3.16.2 Jessie (<= RPi 2)
        3.x.x -> 3.16.2 -{
                          ->  4.x.x Stretch (>= RPi 3)

        For those where the update should proceed past 3.16.2, duplicate the
        Stretch sources to a temporary list so that the new update can be
        located and the new sources package can be installed.
        '''

        if not has_min_performance(RPI_3_SCORE):
            return

        # Proceeding to update to 4.x.x - add new sources and relaunch
        if os.path.exists(REFERENCE_STRETCH_LIST_QA_TEST):
            # If there is a QA TEST version of the list, use that, otherwise
            # use the release version.
            shutil.copy(REFERENCE_STRETCH_LIST_QA_TEST, STRETCH_MIGRATION_LIST)
        else:
            shutil.copy(REFERENCE_STRETCH_LIST, STRETCH_MIGRATION_LIST)
        run_cmd_log("apt-get update")
Example #5
0
    def beta_3_12_1_to_beta_3_13_0(self, dummy_progress):
        was_audio_hdmi = False

        # Get the currently set audio output channel.
        try:
            from kano_settings.system.audio import is_HDMI
            was_audio_hdmi = is_HDMI()
        except:
            logger.error(
                "beta_3_12_1_to_beta_3_13_0: Failed to get audio output channel"
            )

        # Replace the config.txt after numerous changes there (see kano-settings).
        try:
            import shutil
            shutil.copyfile('/boot/config.txt',
                            '/boot/beta_3_12_1_to_beta_3_13_0_bck_config.txt')
            shutil.copyfile('/usr/share/kano-settings/boot_default/config.txt',
                            '/boot/config.txt')
        except:
            logger.error(
                "beta_3_12_1_to_beta_3_13_0: Failed to replace config.txt")

        # Set the audio output channel back to HDMI if it was set.
        try:
            from kano_settings.system.audio import set_to_HDMI
            if was_audio_hdmi:
                set_to_HDMI(True, force=True)
        except:
            logger.error(
                "beta_3_12_1_to_beta_3_13_0: Failed to set HDMI audio back")

        # Remove the orphan udhcpc client, it is now obsoleted by dhcpcd5
        run_cmd_log('apt-get -y purge udhcpc')
Example #6
0
def do_install(progress, status, priority=Priority.NONE):
    status.state = UpdaterStatus.INSTALLING_UPDATES
    status.save()

    track_data_and_sync('update-install-started', dict())

    if priority == Priority.URGENT:
        install_urgent(progress, status)
    else:
        install_standard(progress, status)

    run_cmd_log('apt-get --yes autoremove')

    status.state = UpdaterStatus.UPDATES_INSTALLED

    # Clear the list of independent packages.
    # They should all have been updated by the full update.
    status.updatable_independent_packages = []

    status.last_update = int(time.time())
    status.is_scheduled = False
    status.save()

    progress.finish(_("Update completed"))
    track_data_and_sync('update-install-finished', dict())

    return True
Example #7
0
    def beta_3_16_1_to_beta_3_16_2(self, progress):
        ''' 3.16.2 is the last release for Debian Jessie. Every update past
        this point must update to 3.16.2 and then progress onwards, it can
        never happen that the system is of version 3.x.x (!= 3.16.2) and
        update directly to 4.x.x.

                          ->  3.16.2 Jessie (<= RPi 2)
        3.x.x -> 3.16.2 -{
                          ->  4.x.x Stretch (>= RPi 3)

        For those where the update should proceed past 3.16.2, duplicate the
        Stretch sources to a temporary list so that the new update can be
        located and the new sources package can be installed.
        '''

        if not has_min_performance(RPI_3_SCORE):
            return

        # Proceeding to update to 4.x.x - add new sources and relaunch
        if os.path.exists(REFERENCE_STRETCH_LIST_QA_TEST):
            # If there is a QA TEST version of the list, use that, otherwise
            # use the release version.
            shutil.copy(REFERENCE_STRETCH_LIST_QA_TEST, STRETCH_MIGRATION_LIST)
        else:
            shutil.copy(REFERENCE_STRETCH_LIST, STRETCH_MIGRATION_LIST)
        run_cmd_log("apt-get update")
Example #8
0
    def beta_121_to_beta_122(self, dummy_progress):
        run_cmd_log("kano-apps install --no-gui --icon-only xbmc")

        if not os.path.exists("/etc/apt/sources.list.d/kano-xbmc.list"):
            run_cmd_log("apt-key adv --keyserver keyserver.ubuntu.com "
                        "--recv-key 5243CDED")
            with open("/etc/apt/sources.list.d/kano-xbmc.list", "w") as f:
                f.write("deb http://repo.kano.me/xbmc/ wheezy contrib\n")
Example #9
0
    def beta_121_to_beta_122(self, dummy_progress):
        run_cmd_log("kano-apps install --no-gui --icon-only xbmc")

        if not os.path.exists("/etc/apt/sources.list.d/kano-xbmc.list"):
            run_cmd_log("apt-key adv --keyserver keyserver.ubuntu.com "
                        "--recv-key 5243CDED")
            with open("/etc/apt/sources.list.d/kano-xbmc.list", "w") as f:
                f.write("deb http://repo.kano.me/xbmc/ wheezy contrib\n")
Example #10
0
 def beta_220_to_beta_230(self, dummy_progress):
     out, err, rv = run_cmd_log('apt-mark showauto | grep modemmanager')
     # If the user has manually installed modemmanager, it will be marked as
     # manually installed.
     # Return value will be 0 if modemmanager is marked as an auto installed
     if rv == 0:
         out, err, rv = run_cmd_log('apt-get -y purge modemmanager')
         if rv == 0:
             run_cmd_log('apt-get -y autoremove')
Example #11
0
 def beta_220_to_beta_230(self, dummy_progress):
     out, err, rv = run_cmd_log('apt-mark showauto | grep modemmanager')
     # If the user has manually installed modemmanager, it will be marked as
     # manually installed.
     # Return value will be 0 if modemmanager is marked as an auto installed
     if rv == 0:
         out, err, rv = run_cmd_log('apt-get -y purge modemmanager')
         if rv == 0:
             run_cmd_log('apt-get -y autoremove')
Example #12
0
 def beta_134_to_beta_200(self, dummy_progress):
     if not is_installed('kano-character-cli'):
         logger.info(
             "kano-character-cli not installed,"
             " attempt to install kano-profile"
         )
         install('kano-profile')
     run_cmd_log(
         'kano-character-cli -c "judoka" "Hair_Black" "Skin_Orange" -s'
     )
Example #13
0
    def beta_4_3_1_to_beta_4_3_2(self, dummy_progress):
        # Remove non COPPA compliant apps

        # web whatsapp has no debian candidate, remove manually
        run_cmd_log('rm -f /usr/share/applications/*whatsapp*')
        run_cmd_log('rm -f /usr/share/icons/Kano/66x66/apps/whatsapp.png')

        # aptitude purge removes package and all its exclusive dependencies
        run_cmd_log('aptitude purge pidgin -y')
        run_cmd_log('rm -f /usr/share/applications/pidgin*')
        run_for_every_user('rm -fv $HOME/.kdesktop/Pidgin.lnk')
        run_cmd_log('rm -f /usr/share/icons/Kano/66x66/apps/pidgin.png')
Example #14
0
def make_low_prio():
    # set IO class of this process to Idle
    pid = os.getpid()
    unused1, unused2, rc = run_cmd_log("ionice -c 3 -p {}".format(pid))
    if rc != 0:
        logger.error("ionice command returned non-zero code: [{}]".format(rc))

    # Set the lowest scheduling priority
    unused1, unused2, rc = run_cmd_log("schedtool -D {}".format(pid))
    if rc != 0:
        logger.error(
            "schedtool command returned non-zero code: [{}]".format(rc))
    os.nice(19)
Example #15
0
def play_sound(audio_file, background=False):
    from kano.logging import logger

    # Check if file exists
    if not os.path.isfile(audio_file):
        logger.error('audio file not found: {}'.format(audio_file))
        return False

    _, extension = os.path.splitext(audio_file)

    if extension in ['.wav', '.voc', '.raw', '.au']:
        cmd = 'aplay -q {}'.format(audio_file)
    else:
        volume_percent = get_volume()
        volume_str = '--vol {}'.format(
            percent_to_millibel(volume_percent, raspberry_mod=True))
        cmd = 'omxplayer -o both {volume} {link}'.format(
            volume=volume_str, link=audio_file)

    logger.debug('cmd: {}'.format(cmd))

    if background:
        run_bg(cmd)
        rc = 0
    else:
        dummy, dummy, rc = run_cmd_log(cmd)

    return rc == 0
Example #16
0
def make_normal_prio():
    # set IO class of this process to Idle
    pid = os.getpid()
    unused1, unused2, rc = run_cmd_log("ionice -c 0 -p {}".format(pid))
    if rc != 0:
        logger.error("ionice command returned non-zero code: [{}]".format(rc))

    # Set the lowest scheduling priority
    unused1, unused2, rc = run_cmd_log("schedtool -N {}".format(pid))
    if rc != 0:
        logger.error(
            "schedtool command returned non-zero code: [{}]".format(rc))
    try:
        current_niceness = os.nice(0)
        os.nice(-1 * current_niceness)
    except OSError as os_ex:
        logger.error("Can't renice to 0 due to permissions [{}]".format(os_ex))
Example #17
0
def _do_check(progress, priority=Priority.NONE):
    '''
    Perform checks for all priorities greater than the one provided.
    '''
    apt_handle = AptWrapper.get_instance()

    apt_handle.update(progress, sources_list=KANO_SOURCES_LIST)
    logger.info("Checking urgent: {}".format(priority <= Priority.URGENT))
    logger.info("Checking standard: {}".format(priority <= Priority.STANDARD))
    run_cmd_log('apt-get --yes autoclean')

    if (priority <= Priority.URGENT
            and apt_handle.is_update_available(priority=Priority.URGENT)):
        return Priority.URGENT

    if (priority <= Priority.STANDARD and apt_handle.is_update_available()):
        return Priority.STANDARD

    return Priority.NONE
Example #18
0
 def beta_4_2_0_to_beta_4_2_1(self, dummy_progress):
     #
     # On Kano OS 4.2.0 Christmas release, a hotfix was provided to a number of users
     # to recover from a faulty wireless reconnection on boot, by executing the command below.
     #
     # "sudo mv /lib/dhcpcd/dhcpcd-hooks/10-wpa_supplicant /root"
     #
     # This step reinstalls the dhcpcd5 package so that the file is restored back,
     # and the supplicant daemon is started correctly back again.
     #
     # Note that in 4.2.1 both kano-settings and kano-toolset were updated to use the original
     # wpa_supplicant. Updater's dependency list was *specifically* not updated to reflect this
     # in order to delay a potential issue for users with the workaround in case of a failed update.
     # When the dependency versions will be bumped, keep this case in mind.
     try:
         if os.path.isfile('/root/10-wpa_supplicant'):
             run_cmd_log('apt-get install --reinstall dhcpcd5')
             os.remove('/root/10-wpa_supplicant')
     except Exception as e:
         logger.error('Could not restore DHCP WPA supplicant hook', exception=e)
Example #19
0
def purge(pkgs, die_on_err=False):
    if isinstance(pkgs, list):
        pkgs = ' '.join(pkgs)

    _, _, rv = run_cmd_log('apt-get -y purge ' + str(pkgs))

    if die_on_err and rv != 0:
        msg = "Unable to purge '{}'".format(pkgs)
        update_failed(msg)
        raise Exception(msg)

    return rv
Example #20
0
 def beta_4_2_0_to_beta_4_2_1(self, dummy_progress):
     #
     # On Kano OS 4.2.0 Christmas release, a hotfix was provided to a number of users
     # to recover from a faulty wireless reconnection on boot, by executing the command below.
     #
     # "sudo mv /lib/dhcpcd/dhcpcd-hooks/10-wpa_supplicant /root"
     #
     # This step reinstalls the dhcpcd5 package so that the file is restored back,
     # and the supplicant daemon is started correctly back again.
     #
     # Note that in 4.2.1 both kano-settings and kano-toolset were updated to use the original
     # wpa_supplicant. Updater's dependency list was *specifically* not updated to reflect this
     # in order to delay a potential issue for users with the workaround in case of a failed update.
     # When the dependency versions will be bumped, keep this case in mind.
     try:
         if os.path.isfile('/root/10-wpa_supplicant'):
             run_cmd_log('apt-get install --reinstall dhcpcd5')
             os.remove('/root/10-wpa_supplicant')
     except Exception as e:
         logger.error('Could not restore DHCP WPA supplicant hook',
                      exception=e)
Example #21
0
def install(pkgs, die_on_err=True):
    if isinstance(pkgs, list):
        pkgs = ' '.join(pkgs)

    cmd = 'apt-get install --no-install-recommends -o Dpkg::Options::="--force-confdef" ' \
          '-o Dpkg::Options::="--force-confold" -y --force-yes ' + str(pkgs)
    _, _, rv = run_cmd_log(cmd)

    if die_on_err and rv != 0:
        msg = "Unable to install '{}'".format(pkgs)
        update_failed(msg)
        raise Exception(msg)

    return rv
Example #22
0
def _do_check(progress, priority=Priority.NONE):
    '''
    Perform checks for all priorities greater than the one provided.
    '''
    apt_handle = AptWrapper.get_instance()

    apt_handle.update(progress, sources_list=KANO_SOURCES_LIST)
    logger.info("Checking urgent: {}".format(priority <= Priority.URGENT))
    logger.info("Checking standard: {}".format(priority <= Priority.STANDARD))
    run_cmd_log('apt-get --yes autoclean')

    if (
            priority <= Priority.URGENT
            and apt_handle.is_update_available(priority=Priority.URGENT)
        ):
        return Priority.URGENT

    if (
            priority <= Priority.STANDARD
            and apt_handle.is_update_available()
        ):
        return Priority.STANDARD

    return Priority.NONE
Example #23
0
def play_sound(audio_file, background=False, delay=0):
    from kano.logging import logger

    # Check if file exists
    if not os.path.isfile(audio_file):
        logger.error('audio file not found: {}'.format(audio_file))
        return False

    _, extension = os.path.splitext(audio_file)

    if extension in ['.wav', '.voc', '.raw', '.au']:
        cmd = 'aplay -q {}'.format(audio_file)
    else:
        volume_percent = get_volume()
        volume_str = '--vol {}'.format(
            percent_to_millibel(volume_percent, raspberry_mod=True))

        # Set the audio output between HDMI or Jack. Default is HDMI since it's the
        # safest route given the PiHat lib getting destabilised if Jack is used.
        audio_out = 'hdmi'
        try:
            from kano_settings.system.audio import is_HDMI
            if not is_HDMI():
                audio_out = 'local'
        except Exception:
            pass

        cmd = 'omxplayer -o {audio_out} {volume} {link}'.format(
            audio_out=audio_out,
            volume=volume_str,
            link=audio_file
        )

    logger.debug('cmd: {}'.format(cmd))

    # Delay the sound playback if specified
    if delay:
        cmd = '/bin/sleep {} ; {}'.format(delay, cmd)

    if background:
        run_bg(cmd)
        rc = 0
    else:
        dummy, dummy, rc = run_cmd_log(cmd)

    return rc == 0
Example #24
0
def play_sound(audio_file, background=False, delay=0):
    from kano.logging import logger

    # Check if file exists
    if not os.path.isfile(audio_file):
        logger.error('audio file not found: {}'.format(audio_file))
        return False

    _, extension = os.path.splitext(audio_file)

    if extension in ['.wav', '.voc', '.raw', '.au']:
        cmd = 'aplay -q {}'.format(audio_file)
    else:
        volume_percent = get_volume()
        volume_str = '--vol {}'.format(
            percent_to_millibel(volume_percent, raspberry_mod=True))

        # Set the audio output between HDMI or Jack. Default is HDMI since it's the
        # safest route given the PiHat lib getting destabilised if Jack is used.
        audio_out = 'hdmi'
        try:
            from kano_settings.system.audio import is_HDMI
            if not is_HDMI():
                audio_out = 'local'
        except Exception:
            pass

        cmd = 'omxplayer -o {audio_out} {volume} {link}'.format(
            audio_out=audio_out, volume=volume_str, link=audio_file)

    logger.debug('cmd: {}'.format(cmd))

    # Delay the sound playback if specified
    if delay:
        cmd = '/bin/sleep {} ; {}'.format(delay, cmd)

    if background:
        run_bg(cmd)
        rc = 0
    else:
        dummy, dummy, rc = run_cmd_log(cmd)

    return rc == 0
Example #25
0
 def beta_111_to_beta_120(self, dummy_progress):
     purge("kano-unlocker")
     repo_url = "deb http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi"
     write_file_contents('/etc/apt/sources.list', repo_url + '\n')
     run_cmd_log('apt-get -y clean')
     run_cmd_log('apt-get -y update')
Example #26
0
 def beta_132_to_beta_133(self, dummy_progress):
     # Downgrade the improved FBTurbo X11 driver
     # to the official stable version
     run_cmd_log('apt-get -y remove xf86-video-fbturbo-improved')
     run_cmd_log('apt-get -y install xserver-xorg-video-fbturbo')
Example #27
0
 def beta_200_to_beta_201(self, dummy_progress):
     # All users upgrading from KanoOS 1.* should have their
     # users home directory permissions fixed
     run_cmd_log('/usr/bin/repair-homedir-permissions')
Example #28
0
    def beta_370_to_beta_380(self, progress):
        # linux kernel 4.4.21 shipped with Kano 3.8.0 emits systemd boot messages.
        # fix by telling the kernel to enable an empty splash screen.
        command = "sed -i 's/\\bsystemd.show_status=0\\b/splash/' {}".format(
            '/boot/cmdline.txt')
        run_cmd_log(command)

        self._bootconfig_set_value_helper("gpu_mem", "256")

        try:
            # Install 3rd party apps from Kano World using the App Store.
            # Before, the disk space requirement was part of the update itself.
            # Moved away from that model to install apps separately of the update
            # to minimise the requirement (divide and conquer).
            # However, the App Store does not check for disk space before
            # installing an app so account for this here naively.
            # Requirements (disk_req) in MB were made with apt on a clean system.

            from kano.utils.disk import get_free_space

            new_apps = [
                {
                    'kw_app': 'tux-paint',
                    'disk_req': 413
                },
                {
                    'kw_app': 'numpty-physics',
                    'disk_req': 2
                },
                {
                    'kw_app': 'gmail',
                    'disk_req': 1
                },
                {
                    'kw_app': 'google-drive',
                    'disk_req': 1
                },
                {
                    'kw_app': 'google-maps',
                    'disk_req': 1
                },
                {
                    'kw_app': 'wikipedia',
                    'disk_req': 1
                },
                {
                    'kw_app': 'whatsapp',
                    'disk_req': 1
                },
                {
                    'kw_app': 'adventure',
                    'disk_req': 5
                },
                {
                    'kw_app': 'openttd',
                    'disk_req': 21
                },
                {
                    'kw_app': 'tux-typing',
                    'disk_req': 26
                },
                {
                    'kw_app': 'libreoffice',
                    'disk_req': 385
                },
            ]
            phases = [
                Phase(
                    app['kw_app'],
                    _("Installing {} from the App Store").format(
                        app['kw_app']), app['disk_req']) for app in new_apps
            ]
            # TODO: Because the Pre/PostUpdate scenarios don't split the
            # progress, this last phase essentially is used to preserve the
            # phase from install.
            phases.append(
                Phase('continue-postupdate',
                      _("Running The Postupdate Scripts")))
            progress.split(*phases)

            run_cmd_log('apt-get autoremove -y')

            for app in new_apps:
                run_cmd_log('apt-get clean')

                mb_free = get_free_space()
                mb_required = app['disk_req'] + 250  # MB buffer

                if mb_free > mb_required:
                    progress.start(app['kw_app'])
                    run_cmd_log('kano-apps install --no-gui {app}'.format(
                        app=app['kw_app']))
                else:
                    logger.warn(
                        "Cannot install {app} as it requires {mb_required} but"
                        " only has {mb_free}".format(app=app['kw_app'],
                                                     mb_required=mb_required,
                                                     mb_free=mb_free))
        except Exception as e:
            logger.error("Failed to install 3rd party apps", exception=e)
            send_crash_report(
                "PostUpdate 3.7 to 3.8 app install",
                "Failed with unexpected exception\n{}".format(
                    traceback.format_exc()))
        finally:
            run_cmd_log('apt-get clean')
            progress.start('continue-postupdate')

        # Tell kano-init to put the automatic logins up-to-date
        reconfigure_autostart_policy()
Example #29
0
 def beta_330_to_beta_340(self, dummy_progress):
     # fix locale database if it was
     # corrupted by the NOOBS file hole problem
     run_cmd_log('locale-gen')
Example #30
0
    def beta_3_9_2_to_beta_3_10_0(self, dummy_progress):
        # The new Overture onboarding needs to be enabled - disabling old tty-based kano-init
        run_cmd_log('kano-init finalise --force')

        # Install the kano-os metapackage for top level OS packages.
        install('kano-os')
Example #31
0
 def beta_3_10_2_to_beta_3_10_3(self, dummy_progress):
     # Attempt to fix overture starting after the update.
     run_cmd_log('kano-init finalise --force')
Example #32
0
 def beta_3_10_2_to_beta_3_10_3(self, dummy_progress):
     # Attempt to fix overture starting after the update.
     run_cmd_log('kano-init finalise --force')
Example #33
0
    def beta_3_9_2_to_beta_3_10_0(self, dummy_progress):
        # The new Overture onboarding needs to be enabled - disabling old tty-based kano-init
        run_cmd_log('kano-init finalise --force')

        # Install the kano-os metapackage for top level OS packages.
        install('kano-os')
Example #34
0
 def beta_111_to_beta_120(self, dummy_progress):
     run_cmd_log("kano-apps install --no-gui painter epdfview geany "
                 "codecademy calculator leafpad vnc")
Example #35
0
 def beta_132_to_beta_133(self, dummy_progress):
     run_cmd_log('kano-apps install --no-gui terminal-quest')
Example #36
0
    def beta_220_to_beta_230(self, dummy_progress):
        # A few helper fns to keep the scenario tidy
        def ensure_system_group_exists(group):
            if (os.system('getent group {}'.format(group)) != 0):
                rc = os.system('groupadd -f -r {}'.format(group))
                if rc != 0:
                    logger.error("could not create group")

        def add_users_to_group(group):
            try:
                linux_users = get_users()
                if not linux_users:
                    logger.error('beta_220_to_beta_230: linux_users is empty!')

                for user in linux_users:
                    os.system('sudo usermod -a -G {} {}'.format(group, user))

            except Exception as e:
                logger.error("Couldn't add users to {} group - [{}]".format(
                    group, e))

        def add_i2c_module_to_auto_loaded():
            try:
                found_i2c_dev = False

                with open('/etc/modules', 'r') as f:
                    for line in f:
                        if line.strip() == 'i2c_dev':
                            found_i2c_dev = True

                if not found_i2c_dev:
                    with open('/etc/modules', 'a') as f:
                        f.write('\ni2c_dev\n')

            except Exception as e:
                logger.error(
                    "Couldn't add i2c_dev to /etc/modules - [{}]".format(e))

        def remove_powerup_lnk_file():
            try:
                linux_users = get_users()
                if not linux_users:
                    logger.error('beta_220_to_beta_230: linux_users is empty!')

                lnk_dir_template = os.path.join(os.sep, 'home', '{user}',
                                                '.kdesktop', 'Powerup.lnk')
                for user in linux_users:
                    lnk_dir = lnk_dir_template.format(user=user)
                    if os.path.exists(lnk_dir):
                        os.remove(lnk_dir)
            except Exception as e:
                logger.error("Couldn't remove Powerup.lnk - [{}]".format(e))

        def enable_spi_device():
            from kano_settings.boot_config import set_config_value
            set_config_value("dtparam=spi", "on")
            try:
                from kano_settings.boot_config import end_config_transaction
                end_config_transaction()
            except ImportError:
                logger.error(
                    "end_config_transaciton not present - update to kano-settings failed?"
                )

        # Scenario work starts here
        install('rsync')
        run_cmd_log('kano-apps install --no-gui powerup')

        remove_powerup_lnk_file()

        ensure_system_group_exists('gpio')
        ensure_system_group_exists('spi')
        add_users_to_group('i2c')
        add_users_to_group('gpio')
        add_users_to_group('spi')
        add_i2c_module_to_auto_loaded()

        # enable spi device
        enable_spi_device()
Example #37
0
 def beta_330_to_beta_340(self, dummy_progress):
     # fix locale database if it was
     # corrupted by the NOOBS file hole problem
     run_cmd_log('locale-gen')
Example #38
0
 def _finalise(self):
     # When bluez is installed through a dependency it fails to configure
     # Get around this by installing it first
     run_cmd_log('apt-get -y install bluez')
Example #39
0
 def _finalise(self):
     # When bluez is installed through a dependency it fails to configure
     # Get around this by installing it first
     run_cmd_log('apt-get -y install bluez')
Example #40
0
 def beta_111_to_beta_120(self, dummy_progress):
     run_cmd_log("kano-apps install --no-gui painter epdfview geany "
                 "codecademy calculator leafpad vnc")
Example #41
0
 def beta_200_to_beta_201(self, dummy_progress):
     # All users upgrading from KanoOS 1.* should have their
     # users home directory permissions fixed
     run_cmd_log('/usr/bin/repair-homedir-permissions')
Example #42
0
 def beta_132_to_beta_133(self, dummy_progress):
     run_cmd_log('kano-apps install --no-gui terminal-quest')
Example #43
0
 def beta_111_to_beta_120(self, dummy_progress):
     purge("kano-unlocker")
     repo_url = "deb http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi"
     write_file_contents('/etc/apt/sources.list', repo_url + '\n')
     run_cmd_log('apt-get -y clean')
     run_cmd_log('apt-get -y update')
Example #44
0
    def beta_220_to_beta_230(self, dummy_progress):
        # A few helper fns to keep the scenario tidy
        def ensure_system_group_exists(group):
            if(os.system('getent group {}'.format(group)) != 0):
                rc = os.system('groupadd -f -r {}'.format(group))
                if rc != 0:
                    logger.error("could not create group")

        def add_users_to_group(group):
            try:
                linux_users = get_users()
                if not linux_users:
                    logger.error('beta_220_to_beta_230: linux_users is empty!')

                for user in linux_users:
                    os.system('sudo usermod -a -G {} {}'.format(group, user))

            except Exception as e:
                logger.error(
                    "Couldn't add users to {} group - [{}]".format(group, e)
                )

        def add_i2c_module_to_auto_loaded():
            try:
                found_i2c_dev = False

                with open('/etc/modules', 'r') as f:
                    for line in f:
                        if line.strip() == 'i2c_dev':
                            found_i2c_dev = True

                if not found_i2c_dev:
                    with open('/etc/modules', 'a') as f:
                        f.write('\ni2c_dev\n')

            except Exception as e:
                logger.error(
                    "Couldn't add i2c_dev to /etc/modules - [{}]".format(e)
                )

        def remove_powerup_lnk_file():
            try:
                linux_users = get_users()
                if not linux_users:
                    logger.error('beta_220_to_beta_230: linux_users is empty!')

                lnk_dir_template = os.path.join(
                    os.sep,
                    'home',
                    '{user}',
                    '.kdesktop',
                    'Powerup.lnk'
                )
                for user in linux_users:
                    lnk_dir = lnk_dir_template.format(user=user)
                    if os.path.exists(lnk_dir):
                        os.remove(lnk_dir)
            except Exception as e:
                logger.error("Couldn't remove Powerup.lnk - [{}]".format(e))

        def enable_spi_device():
            from kano_settings.boot_config import set_config_value
            set_config_value("dtparam=spi", "on")
            try:
                from kano_settings.boot_config import end_config_transaction
                end_config_transaction()
            except ImportError:
                logger.error("end_config_transaciton not present - update to kano-settings failed?")

        # Scenario work starts here
        install('rsync')
        run_cmd_log('kano-apps install --no-gui powerup')

        remove_powerup_lnk_file()

        ensure_system_group_exists('gpio')
        ensure_system_group_exists('spi')
        add_users_to_group('i2c')
        add_users_to_group('gpio')
        add_users_to_group('spi')
        add_i2c_module_to_auto_loaded()

        # enable spi device
        enable_spi_device()
Example #45
0
 def beta_132_to_beta_133(self, dummy_progress):
     # Downgrade the improved FBTurbo X11 driver
     # to the official stable version
     run_cmd_log('apt-get -y remove xf86-video-fbturbo-improved')
     run_cmd_log('apt-get -y install xserver-xorg-video-fbturbo')
Example #46
0
    def beta_370_to_beta_380(self, progress):
        # linux kernel 4.4.21 shipped with Kano 3.8.0 emits systemd boot messages.
        # fix by telling the kernel to enable an empty splash screen.
        command = "sed -i 's/\\bsystemd.show_status=0\\b/splash/' {}".format('/boot/cmdline.txt')
        run_cmd_log(command)

        self._bootconfig_set_value_helper("gpu_mem", "256")

        try:
            # Install 3rd party apps from Kano World using the App Store.
            # Before, the disk space requirement was part of the update itself.
            # Moved away from that model to install apps separately of the update
            # to minimise the requirement (divide and conquer).
            # However, the App Store does not check for disk space before
            # installing an app so account for this here naively.
            # Requirements (disk_req) in MB were made with apt on a clean system.

            from kano.utils.disk import get_free_space

            new_apps = [
                {'kw_app': 'tux-paint', 'disk_req': 413},
                {'kw_app': 'numpty-physics', 'disk_req': 2},
                {'kw_app': 'gmail', 'disk_req': 1},
                {'kw_app': 'google-drive', 'disk_req': 1},
                {'kw_app': 'google-maps', 'disk_req': 1},
                {'kw_app': 'wikipedia', 'disk_req': 1},
                {'kw_app': 'whatsapp', 'disk_req': 1},
                {'kw_app': 'adventure', 'disk_req': 5},
                {'kw_app': 'openttd', 'disk_req': 21},
                {'kw_app': 'tux-typing', 'disk_req': 26},
                {'kw_app': 'libreoffice', 'disk_req': 385},
            ]
            phases = [
                Phase(
                    app['kw_app'],
                    _("Installing {} from the App Store")
                    .format(app['kw_app']),
                    app['disk_req']
                )
                for app in new_apps
            ]
            # TODO: Because the Pre/PostUpdate scenarios don't split the
            # progress, this last phase essentially is used to preserve the
            # phase from install.
            phases.append(
                Phase(
                    'continue-postupdate',
                    _("Running The Postupdate Scripts")
                )
            )
            progress.split(*phases)

            run_cmd_log('apt-get autoremove -y')

            for app in new_apps:
                run_cmd_log('apt-get clean')

                mb_free = get_free_space()
                mb_required = app['disk_req'] + 250  # MB buffer

                if mb_free > mb_required:
                    progress.start(app['kw_app'])
                    run_cmd_log('kano-apps install --no-gui {app}'.format(app=app['kw_app']))
                else:
                    logger.warn(
                        "Cannot install {app} as it requires {mb_required} but"
                        " only has {mb_free}"
                        .format(
                            app=app['kw_app'],
                            mb_required=mb_required,
                            mb_free=mb_free
                        )
                    )
        except Exception as e:
            logger.error("Failed to install 3rd party apps", exception=e)
            send_crash_report(
                "PostUpdate 3.7 to 3.8 app install",
                "Failed with unexpected exception\n{}"
                .format(traceback.format_exc())
            )
        finally:
            run_cmd_log('apt-get clean')
            progress.start('continue-postupdate')

        # Tell kano-init to put the automatic logins up-to-date
        reconfigure_autostart_policy()
Example #47
0
def run_for_every_user(cmd):
    for user in get_users():
        run_cmd_log("sudo su -c '{cmd}' - {user}".format(cmd=cmd, user=user))