docs: def upgrade(refresh=True,
              dryrun=False,
              dist_upgrade=False,
              fromrepo=None,
              novendorchange=False,
              skip_verify=False,
              no_recommends=False,
              root=None,
              **kwargs):  # pylint: disable=unused-argument
      '''
      .. versionchanged:: 2015.8.12,2016.3.3,2016.11.0
          On minions running systemd>=205, `systemd-run(1)`_ is now used to
          isolate commands which modify installed packages from the
          ``salt-minion`` daemon's control group. This is done to keep systemd
          from killing any zypper commands spawned by Salt when the
          ``salt-minion`` service is restarted. (see ``KillMode`` in the
          `systemd.kill(5)`_ manpage for more information). If desired, usage of
          `systemd-run(1)`_ can be suppressed by setting a :mod:`config option
          <salt.modules.config.get>` called ``systemd.scope``, with a value of
          ``False`` (no quotes).
  
      .. _`systemd-run(1)`: https://www.freedesktop.org/software/systemd/man/systemd-run.html
      .. _`systemd.kill(5)`: https://www.freedesktop.org/software/systemd/man/systemd.kill.html
  
      Run a full system upgrade, a zypper upgrade
  
      refresh
          force a refresh if set to True (default).
          If set to False it depends on zypper if a refresh is
          executed.
  
      dryrun
          If set to True, it creates a debug solver log file and then perform
          a dry-run upgrade (no changes are made). Default: False
  
      dist_upgrade
          Perform a system dist-upgrade. Default: False
  
      fromrepo
          Specify a list of package repositories to upgrade from. Default: None
  
      novendorchange
          If set to True, no allow vendor changes. Default: False
  
      skip_verify
          Skip the GPG verification check (e.g., ``--no-gpg-checks``)
  
      no_recommends
          Do not install recommended packages, only required ones.
  
      root
          Operate on a different root directory.
  
      Returns a dictionary containing the changes:
  
      .. code-block:: python
  
          {'<package>':  {'old': '<old-version>',
                          'new': '<new-version>'}}
  
      CLI Example:
  
      .. code-block:: bash
  
          salt '*' pkg.upgrade
          salt '*' pkg.upgrade dist-upgrade=True fromrepo='["MyRepoName"]' novendorchange=True
          salt '*' pkg.upgrade dist-upgrade=True dryrun=True
      '''
      cmd_update = (['dist-upgrade'] if dist_upgrade else ['update']) + ['--auto-agree-with-licenses']
  
      if skip_verify:
          # The '--no-gpg-checks' needs to be placed before the Zypper command.
          cmd_update.insert(0, '--no-gpg-checks')
  
      if refresh:
          refresh_db(root)
  
      if dryrun:
          cmd_update.append('--dry-run')
  
      if dist_upgrade:
          if fromrepo:
              for repo in fromrepo:
                  cmd_update.extend(['--from', repo])
              log.info('Targeting repos: %s', fromrepo)
  
          if novendorchange:
              # TODO: Grains validation should be moved to Zypper class
              if __grains__['osrelease_info'][0] > 11:
                  cmd_update.append('--no-allow-vendor-change')
                  log.info('Disabling vendor changes')
              else:
                  log.warning('Disabling vendor changes is not supported on this Zypper version')
  
          if no_recommends:
              cmd_update.append('--no-recommends')
              log.info('Disabling recommendations')
  
          if dryrun:
              # Creates a solver test case for debugging.
              log.info('Executing debugsolver and performing a dry-run dist-upgrade')
              __zypper__(systemd_scope=_systemd_scope(), root=root).noraise.call(*cmd_update + ['--debug-solver'])
  
      old = list_pkgs(root=root)
  
      __zypper__(systemd_scope=_systemd_scope(), root=root).noraise.call(*cmd_update)
      _clean_cache()
      new = list_pkgs(root=root)
      ret = salt.utils.data.compare_dicts(old, new)
  
      if __zypper__.exit_code not in __zypper__.SUCCESS_EXIT_CODES:
          result = {
              'retcode': __zypper__.exit_code,
              'stdout': __zypper__.stdout,
              'stderr': __zypper__.stderr,
              'pid': __zypper__.pid,
          }
          raise CommandExecutionError(
              'Problem encountered upgrading packages',
              info={'changes': ret, 'result': result}
          )
  
      if dryrun:
          ret = (__zypper__.stdout + os.linesep + __zypper__.stderr).strip()
  
      return ret