Пример #1
0
    def check_available(self, attrs=None):
        """
        Checks if there is an update available from update server.

        status:
          - REBOOT_REQUIRED: an update has already been applied
          - AVAILABLE: an update is available
          - UNAVAILABLE: no update available

        .. examples(websocket)::

          Check available update using default train:

            :::javascript
            {
                "id": "6841f242-840a-11e6-a437-00e04d680384",
                "msg": "method",
                "method": "update.check_available"
            }
        """

        try:
            applied = self.middleware.call('cache.get', 'update.applied')
        except Exception:
            applied = False
        if applied is True:
            return {'status': 'REBOOT_REQUIRED'}

        train = (attrs or {}).get('train') or self.get_trains()['selected']

        handler = CheckUpdateHandler()
        manifest = CheckForUpdates(
            diff_handler=handler.diff_call,
            handler=handler.call,
            train=train,
        )

        if not manifest:
            return {'status': 'UNAVAILABLE'}

        data = {
            'status': 'AVAILABLE',
            'changes': handler.changes,
        }

        conf = Configuration.Configuration()
        sys_mani = conf.SystemManifest()
        if sys_mani:
            sequence = sys_mani.Sequence()
        else:
            sequence = ''
        data['changelog'] = get_changelog(train,
                                          start=sequence,
                                          end=manifest.Sequence())

        data['version'] = manifest.Version()
        return data
Пример #2
0
def check_updates(dispatcher, configstore, cache_dir=None, check_now=False):
    "Utility function to just check for Updates"
    update_cache.invalidate('updateAvailable')
    update_cache.invalidate('updateNotes')
    update_cache.invalidate('updateNotice')
    update_cache.invalidate('updateOperations')
    update_cache.invalidate('changelog')

    conf = Configuration.Configuration()
    update_ops = None
    handler = CheckUpdateHandler()
    train = configstore.get('update.train')
    notes = None
    notice = None

    try:
        update = CheckForUpdates(
            handler=handler.call,
            train=train,
            cache_dir=None if check_now else cache_dir,
        )
    except Exception:
        update_cache.put('updateAvailable', False)
        update_cache.put('updateNotes', None)
        update_cache.put('updateNotice', None)
        update_cache.put('updateOperations', update_ops)
        update_cache.put('changelog', '')
        raise

    if update:
        logger.debug("An update is available")
        update_ops = handler.output()
        sys_mani = conf.SystemManifest()
        if sys_mani:
            sequence = sys_mani.Sequence()
        else:
            sequence = ''
        changelog = get_changelog(train,
                                  cache_dir=cache_dir,
                                  start=sequence,
                                  end=update.Sequence())
        notes = update.Notes()
        notice = update.Notice()
    else:
        logger.debug("No update available")
        changelog = None

    update_cache.put('updateAvailable', True if update else False)
    update_cache.put('updateOperations', update_ops)
    update_cache.put('changelog', changelog)
    update_cache.put('updateNotes', notes)
    update_cache.put('updateNotice', notice)
Пример #3
0
    def run(self):
        alerts = []
        try:
            update = Update.objects.order_by('-id')[0]
        except IndexError:
            update = Update.objects.create()

        path = notifier().system_dataset_path()
        if not path:
            return None
        try:
            check = CheckForUpdates(train=update.get_train(), cache_dir=path)
        except:
            check = None
        if check:
            alerts.append(
                Alert(
                    Alert.OK,
                    _(
                        'There is a new update available! Apply it in System '
                        '-> Update tab.'
                    ),
                )
            )
        return alerts
Пример #4
0
    def check_train(self, train):
        handler = CheckUpdateHandler()
        manifest = CheckForUpdates(
            diff_handler=handler.diff_call,
            handler=handler.call,
            train=train,
        )

        if not manifest:
            return {'status': 'UNAVAILABLE'}

        data = {
            'status': 'AVAILABLE',
            'changes': handler.changes,
            'notice': manifest.Notice(),
            'notes': manifest.Notes(),
        }

        conf = Configuration.Configuration()
        sys_mani = conf.SystemManifest()
        if sys_mani:
            sequence = sys_mani.Sequence()
        else:
            sequence = ''
        data['changelog'] = get_changelog(train,
                                          start=sequence,
                                          end=manifest.Sequence())

        data['version'] = manifest.Version()
        return data
Пример #5
0
    def check_train(self, train):
        if 'SCALE' in train:
            old_version = self.middleware.call_sync('system.version').split(
                '-', 1)[1]
            return self.middleware.call_sync('update.get_scale_update', train,
                                             old_version)

        handler = CheckUpdateHandler()
        manifest = CheckForUpdates(
            diff_handler=handler.diff_call,
            handler=handler.call,
            train=train,
        )

        if not manifest:
            return {'status': 'UNAVAILABLE'}

        data = {
            'status': 'AVAILABLE',
            'changes': handler.changes,
            'notice': manifest.Notice(),
            'notes': manifest.Notes(),
        }

        conf = Configuration.Configuration()
        sys_mani = conf.SystemManifest()
        if sys_mani:
            sequence = sys_mani.Sequence()
        else:
            sequence = ''
        data['changelog'] = get_changelog(train,
                                          start=sequence,
                                          end=manifest.Sequence())

        data['version'] = manifest.Version()
        return data
Пример #6
0
    def check_available(self, attrs=None):
        """
        Checks if there is an update available from update server.

        status:
          - REBOOT_REQUIRED: an update has already been applied
          - AVAILABLE: an update is available
          - UNAVAILABLE: no update available

        .. examples(websocket)::

          Check available update using default train:

            :::javascript
            {
                "id": "6841f242-840a-11e6-a437-00e04d680384",
                "msg": "method",
                "method": "update.check_available"
            }
        """

        try:
            applied = self.middleware.call_sync('cache.get', 'update.applied')
        except Exception:
            applied = False
        if applied is True:
            return {'status': 'REBOOT_REQUIRED'}

        if (not self.middleware.call_sync('system.is_freenas')
                and self.middleware.call_sync('failover.licensed')):
            # If its HA and standby is running old version we assume
            # legacy upgrade and check update on standby.
            try:
                self.middleware.call_sync(
                    'failover.call_remote',
                    'failover.upgrade_version',
                )
            except CallError as e:
                if e.errno != CallError.ENOMETHOD:
                    raise
                return self.middleware.call_sync(
                    'failover.call_remote',
                    'update.check_available',
                    [attrs],
                )

        trains = self.middleware.call_sync('update.get_trains')
        train = (attrs or {}).get('train')
        if not train:
            train = trains['selected']
        elif train not in trains['trains']:
            raise CallError('Invalid train name.', errno.ENOENT)

        handler = CheckUpdateHandler()
        manifest = CheckForUpdates(
            diff_handler=handler.diff_call,
            handler=handler.call,
            train=train,
        )

        if not manifest:
            return {'status': 'UNAVAILABLE'}

        data = {
            'status': 'AVAILABLE',
            'changes': handler.changes,
            'notice': manifest.Notice(),
            'notes': manifest.Notes(),
        }

        conf = Configuration.Configuration()
        sys_mani = conf.SystemManifest()
        if sys_mani:
            sequence = sys_mani.Sequence()
        else:
            sequence = ''
        data['changelog'] = get_changelog(train,
                                          start=sequence,
                                          end=manifest.Sequence())

        data['version'] = manifest.Version()
        return data
Пример #7
0
def check_updates(dispatcher, configstore, cache_dir=None, check_now=False):
    """
    Utility function to just check for Updates
    """
    update_cache_value_dict = default_update_dict.copy()

    # If the current check is an online one (and not in the cache_dir)
    # then store the current update info and use them to restore the update cache
    # if the update check fails, this way a downloaded update is not lost from
    # the cache if a live online one fails!
    current_update_info = None
    try:
        current_update_info = dispatcher.call_sync('update.update_info')
    except RpcException:
        pass

    if current_update_info:
        update_cache_value_dict['installed'] = current_update_info.get(
            'installed')
        update_cache_value_dict['installed_version'] = current_update_info.get(
            'installed_version')
        if check_now and current_update_info['downloaded']:
            update_cache_value_dict.update(current_update_info.copy())
            update_cache_value_dict['available'] = True

    dispatcher.call_sync('update.update_cache_invalidate',
                         list(update_cache_value_dict.keys()))

    conf = Configuration.Configuration()
    handler = CheckUpdateHandler()
    train = configstore.get('update.train')

    try:
        update = CheckForUpdates(
            handler=handler.call,
            train=train,
            cache_dir=None if check_now else cache_dir,
        )

        if update:
            version = update.Version()
            update_installed_bootenv = list(
                is_update_applied(dispatcher, version))
            if version == update_cache_value_dict[
                    'installed_version'] or update_installed_bootenv:
                logger.debug('Update is already installed')
                update_cache_value_dict = default_update_dict.copy()
                update_cache_value_dict.update({
                    'installed': True,
                    'installed_version': version
                })
                dispatcher.call_sync(
                    'update.update_alert_set', 'UpdateInstalled', version,
                    {'update_installed_bootenv': update_installed_bootenv})
                return
            logger.debug("An update is available")
            sys_mani = conf.SystemManifest()
            if sys_mani:
                sequence = sys_mani.Sequence()
            else:
                sequence = ''
            try:
                if check_now:
                    changelog = get_changelog(train,
                                              cache_dir=cache_dir,
                                              start=sequence,
                                              end=update.Sequence())
                else:
                    changelog_file = "{0}/ChangeLog.txt".format(cache_dir)
                    changelog = parse_changelog(changelog_file.read(),
                                                start=sequence,
                                                end=update.Sequence())
            except Exception:
                changelog = ''
            update_cache_value_dict.update({
                'available':
                True,
                'notes':
                update.Notes(),
                'notice':
                update.Notice(),
                'operations':
                handler.output(),
                'version':
                version,
                'changelog':
                changelog,
                'downloaded':
                False if check_now else True
            })

            dispatcher.call_sync(
                'update.update_alert_set', 'UpdateDownloaded' if
                update_cache_value_dict['downloaded'] else 'UpdateAvailable',
                update_cache_value_dict['version'])

        else:
            logger.debug('No update available')
    finally:
        dispatcher.call_sync('update.update_cache_putter',
                             update_cache_value_dict)
Пример #8
0
def main():
    def usage():
        print >> sys.stderr, "Usage: %s [-R root] [-M manifest_file] <cmd>, where cmd is one of:" % sys.argv[
            0]
        print >> sys.stderr, "\tcheck\tCheck for updates"
        print >> sys.stderr, "\tupdate\tDo an update"
        print >> sys.stderr, "\tinstall\tInstall"
        sys.exit(1)

    try:
        opts, args = getopt.getopt(sys.argv[1:], "qvdR:M:T:")
    except getopt.GetoptError as err:
        print str(err)
        usage()

    root = None
    manifile = None
    verbose = 0
    debug = 0
    tmpdir = None
    config_file = None
    config = None

    for o, a in opts:
        if o == "-v":
            verbose += 1
        elif o == "-q":
            quiet = True
        elif o == "-d":
            debug += 1
        elif o == "-R":
            root = a
        elif o == "-M":
            manifile = a
        elif o == '-C':
            config_file = a
        elif o == "-T":
            tmpdir = a
        else:
            assert False, "unhandled option"

    logging.config.dictConfig({
        'version': 1,
        'disable_existing_loggers': True,
        'formatters': {
            'simple': {
                'format': '[%(name)s:%(lineno)s] %(message)s',
            },
        },
        'handlers': {
            'std': {
                'class': 'logging.StreamHandler',
                'level': 'DEBUG',
                'stream': 'ext://sys.stdout',
            },
        },
        'loggers': {
            '': {
                'handlers': ['std'],
                'level': 'DEBUG',
                'propagate': True,
            },
        },
    })

    sys.path.append("/usr/local/lib")

    import freenasOS.Configuration as Configuration
    from freenasOS.Update import CheckForUpdates, Update

    if root is not None and os.path.isdir(root) is False:
        print >> sys.stderr, "Specified root (%s) does not exist" % root
        sys.exit(1)

    if config_file is not None:
        # We want the system configuration file
        config = Configuration.Configuration(file=config_file, root=None)

    if len(args) != 1:
        usage()

    if args[0] == "check":

        def Handler(op, pkg, old):
            if op == "upgrade":
                print "%s:  %s -> %s" % (pkg.Name(), old.Version(),
                                         pkg.Version())
            else:
                print "%s:  %s %s" % (pkg.Name(), op, pkg.Version())

        if verbose > 0 or debug > 0:
            pfcn = Handler
        else:
            pfcn = None
        try:
            update = CheckForUpdates(root, pfcn)
        except ValueError:
            print >> sys.stderr, "No manifest found"
            return 1
        if update is not None:
            print >> sys.stderr, "Newer manifest found"
            return 0
        else:
            print >> sys.stderr, "No newer manifest found"
            return 1
    elif args[0] == "update":
        r = Update(root, config)
        if r:
            return 0
        else:
            return 1
    else:
        usage()
Пример #9
0
                handler.finished = True
                handler.dump()
                os.kill(handler.pid, 9)
        else:
            if handler.error is not False:
                raise MiddlewareError(handler.error)
            if not handler.finished:
                return HttpResponse(handler.uuid, status=202)
            handler.exit()
            request.session['allow_reboot'] = True
            return render(request, 'system/done.html')
    else:
        handler = CheckUpdateHandler()
        try:
            update = CheckForUpdates(
                handler=handler.call,
                train=updateobj.get_train(),
            )
        except:
            update = None
        return render(request, 'system/update.html', {
            'update': update,
            'handler': handler,
        })


def update_check(request):

    try:
        updateobj = models.Update.objects.order_by('-id')[0]
    except IndexError:
        updateobj = models.Update.objects.create()
Пример #10
0
def check_updates(dispatcher, configstore, cache_dir=None, check_now=False):
    """
    Utility function to just check for Updates
    """
    update_cache_value_dict = default_update_dict.copy()

    # If the current check is an online one (and not in the cache_dir)
    # then store the current update info and use them to restore the update cache
    # if the update check fails, this way a downloaded update is not lost from
    # the cache if a live online one fails!
    current_update_info = None
    try:
        current_update_info = dispatcher.call_sync('update.update_info')
        if (current_update_info.get('installed') and is_update_applied(
                dispatcher, current_update_info.get('installed_version'))):
            update_cache_value_dict.update({
                'installed':
                True,
                'installed_version':
                current_update_info.get('installed_version')
            })

        if check_now and current_update_info['downloaded']:
            update_cache_value_dict.update(current_update_info.copy())
            update_cache_value_dict['available'] = True
    except RpcException:
        pass

    logger.trace('check_updates: this is the current_update_info: {0}'.format(
        current_update_info))
    dispatcher.call_sync('update.update_cache_invalidate',
                         list(update_cache_value_dict.keys()))

    conf = Configuration.Configuration()
    handler = CheckUpdateHandler()
    train = configstore.get('update.train')

    logger.trace('check_updates: Update server name: {0}, url: {1}'.format(
        conf.UpdateServerName(), conf.UpdateServerURL()))

    try:
        update = CheckForUpdates(
            handler=handler.call,
            train=train,
            cache_dir=None if check_now else cache_dir,
        )

        if update:
            version = update.Version()
            update_installed_bootenv = is_update_applied(dispatcher, version)
            sys_mani = conf.SystemManifest()
            sequence = sys_mani.Sequence() if sys_mani else ''
            if version == update_cache_value_dict[
                    'installed_version'] or update_installed_bootenv:
                if update_installed_bootenv and update_installed_bootenv[
                        'active']:
                    # it could be possible that the installed os has the same version as
                    # the one available from the server and yet the one on the server has
                    # something new to offer, hence check for seequence numbers to rule out
                    # all doubt
                    if update.Sequence() == sequence:
                        logger.debug(
                            'Update has same sequence number as current OS')
                        # At this point clear any installed version stuff
                        update_cache_value_dict.update({
                            'installed': False,
                            'installed_version': ''
                        })
                    else:
                        logger.debug(
                            'Update has same version but different sequence number as current OS'
                        )
                else:
                    # TODO: mount the BE in question to inspect sequence number
                    logger.debug(
                        'Update version {0} is already installed in BE {1}'.
                        format(version, update_installed_bootenv))
                    update_cache_value_dict = default_update_dict.copy()
                    update_cache_value_dict.update({
                        'installed': True,
                        'installed_version': version
                    })
                    dispatcher.call_sync(
                        'update.update_alert_set', 'UpdateInstalled', version,
                        {'update_installed_bootenv': update_installed_bootenv})
            else:
                logger.debug('Update {0} is available'.format(version))
                try:
                    if check_now:
                        changelog = get_changelog(train,
                                                  cache_dir=cache_dir,
                                                  start=sequence,
                                                  end=update.Sequence())
                    else:
                        with open("{0}/ChangeLog.txt".format(cache_dir),
                                  'r') as changelog_file:
                            changelog = parse_changelog(changelog_file.read(),
                                                        start=sequence,
                                                        end=update.Sequence())
                except Exception:
                    changelog = ''
                update_cache_value_dict.update({
                    'available':
                    True,
                    'notes':
                    update.Notes(),
                    'notice':
                    update.Notice(),
                    'operations':
                    handler.output(),
                    'version':
                    version,
                    'changelog':
                    changelog,
                    'downloaded':
                    False if check_now else True
                })

                dispatcher.call_sync(
                    'update.update_alert_set',
                    'UpdateDownloaded' if update_cache_value_dict['downloaded']
                    else 'UpdateAvailable', update_cache_value_dict['version'])

        else:
            logger.debug('No update available')
    finally:
        dispatcher.call_sync('update.update_cache_putter',
                             update_cache_value_dict)
Пример #11
0
                    handler.error = unicode(e)
                handler.finished = True
                handler.dump()
                os.kill(handler.pid, 9)
        else:
            if handler.error is not False:
                raise MiddlewareError(handler.error)
            if not handler.finished:
                return HttpResponse(handler.uuid, status=202)
            handler.exit()
            request.session['allow_reboot'] = True
            return render(request, 'system/done.html')

    handler = CheckUpdateHandler()
    try:
        update = CheckForUpdates(handler=handler.call)
    except ValueError:
        update = False
    return render(request, 'system/upgrade.html', {
        'update': update,
        'handler': handler,
    })


def upgrade_progress(request):
    handler = UpdateHandler()
    return HttpResponse(
        json.dumps(handler.load()),
        content_type='application/json',
    )