Exemple #1
0
def main(tmp_db_path, sync_cmd=None):
  # Use a temporary database path to avoid issues caused by synchronizing the
  # sync database without a full system upgrade.

  # See the discussion here:
  #   https://bbs.archlinux.org/viewtopic.php?pid=951285#p951285

  # Basically, if you sync the database and then install packages without first
  # upgrading the system (-y), you can do some damage.


  tmp_db_path = os.path.abspath(tmp_db_path)
#   conf = config.PacmanConfig(conf = '/etc/pacman.conf')
  h = config.init_with_config("/etc/pacman.conf")
  db_path = h.dbpath
  if tmp_db_path == db_path:
    print("temporary path cannot be %s" % db_path)
    sys.exit(1)
  local_db_path = os.path.join(db_path, 'local')
  tmp_local_db_path = os.path.join(tmp_db_path, 'local')

  # Set up the temporary database path
  if not os.path.exists(tmp_db_path):
    os.makedirs(tmp_db_path)
    os.symlink(local_db_path, tmp_local_db_path)
  elif not os.path.islink(tmp_local_db_path):
    # Move instead of unlinking just in case.
    if os.path.exists(tmp_local_db_path):
      sys.stderr.write(
        "warning: expected file or directory at %s\n" % tmp_local_db_path
      )
      i = 1
      backup_path = tmp_local_db_path + ('.%d' % i)
      while os.path.exists(backup_path):
        i += 1
        backup_path = tmp_local_db_path + ('.%d' % i)
      sys.stderr.write("attempting to move to %s\n" % backup_path)
      os.rename(tmp_local_db_path, backup_path)
    os.symlink(local_db_path, tmp_local_db_path)

  # Copy in the existing database files. If a repo is offline when paconky is
  # run then no database will be downloaded. If the databases are not copied
  # first then the output will be inconsistent due to missing information. For
  # example, if the Haskell repo is offline then Haskell packages will appear
  # in the [community] and [AUR] sections of the output.
  tmp_sync_db_path = os.path.join(tmp_db_path, 'sync')
  os.makedirs(tmp_sync_db_path, exist_ok=True)
  sync_db_path = os.path.join(db_path, 'sync')

  for db in glob.iglob(os.path.join(sync_db_path,'*.db')):
    tmp_db = os.path.join(tmp_sync_db_path, os.path.basename(db))
    try:
      mtime = os.path.getmtime(tmp_db)
    except OSError as e:
      if e.errno != errno.ENOENT:
        raise e
      else:
        mtime = 0
    if mtime < os.path.getmtime(db):
      shutil.copy2(db, tmp_db)



  # Sync the temporary database.
  # Support external synchronizers such as parisync.
  if sync_cmd:
    for index, item in enumerate(sync_cmd):
      if item == '%d':
        sync_cmd[index] = tmp_sync_db_path
      elif item == '%r':
        sync_cmd[index] = os.path.dirname(tmp_sync_db_path)
    p = subprocess.Popen(sync_cmd, stdout=subprocess.PIPE)
    e = p.wait()
    if e != 0:
      sys.stderr.write("sync command exited with %d\n" % e)
    # Re-initialize with new databases.
    args = action_sync.parse_options(('-b', tmp_db_path))
    h = config.init_with_config_and_options(args)
  else:
    args = action_sync.parse_options(('-b', tmp_db_path, '-y'))
    h = config.init_with_config_and_options(args)
    sys.stdout = sys.__stderr__
    try:
      t = transaction.init_from_options(h, args)
    except pyalpm.error as e:
      sys.stderr.write('%s\n' % (e,))
      eno = e.args[1]
      if eno == 10:
        lckpath = os.path.join(tmp_db_path, 'db.lck')
        sys.stderr.write('  %s\n' % lckpath)
      sys.exit(1)
    for db in h.get_syncdbs():
      try:
        db.update(False)
      except pyalpm.error as e:
        sys.stderr.write('%s: %s\n' % (db.name, e))
    t.release()
    sys.stdout = sys.__stdout__


  installed = set(p for p in h.get_localdb().pkgcache)
  upgradable = OrderedDict()

  syncdbs = h.get_syncdbs()
  for db in syncdbs:
    # Without "list" the set cannot be altered with "remove" below.
    for pkg in list(installed):
      pkgname = pkg.name
      syncpkg = db.get_pkg(pkgname)
      if syncpkg:
        if pyalpm.vercmp(syncpkg.version, pkg.version) > 0:
          try:
            upgradable[db.name].add((pkg, syncpkg))
          except KeyError:
            upgradable[db.name] = set(((pkg, syncpkg),))
        installed.remove(pkg)

  foreign = dict([(p.name,p) for p in installed])

  try:
    aur = AUR.AurRpc()
    aur_pkgs = aur.info(foreign.keys())
    upgradable_aur = list()
    for aur_pkg in aur_pkgs:
      try:
        installed_pkg = foreign[aur_pkg['Name']]
      except KeyError:
        upgradable_aur.append(aur_pkg)
        continue
      if pyalpm.vercmp(aur_pkg['Version'], installed_pkg.version) > 0:
        upgradable_aur.append(aur_pkg)
      installed.remove(installed_pkg)
  except AUR.AurError as e:
    sys.stderr.write(str(e))
    sys.exit(1)
  except urllib.error.URLError as e:
    sys.stderr.write(
      'error: failed to retrieve information from the AUR (%s)\n' % e.reason
    )
    upgradable_aur = None
  except TypeError:
    upgradable_aur = None


  display(upgradable, upgradable_aur)
def main(tmp_db_path, sync_cmd=None):
  # Use a temporary database path to avoid issues caused by synchronizing the
  # sync database without a full system upgrade.

  # See the discussion here:
  #   https://bbs.archlinux.org/viewtopic.php?pid=951285#p951285

  # Basically, if you sync the database and then install packages without first
  # upgrading the system (-y), you can do some damage.


  tmp_db_path = os.path.abspath(tmp_db_path)
#   conf = config.PacmanConfig(conf = '/etc/pacman.conf')
  h = config.init_with_config("/etc/pacman.conf")
  db_path = h.dbpath
  if tmp_db_path == db_path:
    print("temporary path cannot be %s" % db_path)
    sys.exit(1)
  local_db_path = os.path.join(db_path, 'local')
  tmp_local_db_path = os.path.join(tmp_db_path, 'local')

  # Set up the temporary database path
  if not os.path.exists(tmp_db_path):
    os.makedirs(tmp_db_path)
    os.symlink(local_db_path, tmp_local_db_path)
  elif not os.path.islink(tmp_local_db_path):
    # Move instead of unlinking just in case.
    if os.path.exists(tmp_local_db_path):
      sys.stderr.write(
        "warning: expected file or directory at %s\n" % tmp_local_db_path
      )
      i = 1
      backup_path = tmp_local_db_path + ('.%d' % i)
      while os.path.exists(backup_path):
        i += 1
        backup_path = tmp_local_db_path + ('.%d' % i)
      sys.stderr.write("attempting to move to %s\n" % backup_path)
      os.rename(tmp_local_db_path, backup_path)
    os.symlink(local_db_path, tmp_local_db_path)

  # Copy in the existing database files. If a repo is offline when paconky is
  # run then no database will be downloaded. If the databases are not copied
  # first then the output will be inconsistent due to missing information. For
  # example, if the Haskell repo is offline then Haskell packages will appear
  # in the [community] and [AUR] sections of the output.
  tmp_sync_db_path = os.path.join(tmp_db_path, 'sync')
  os.makedirs(tmp_sync_db_path, exist_ok=True)
  sync_db_path = os.path.join(db_path, 'sync')

  for db in glob.iglob(os.path.join(sync_db_path,'*.db')):
    tmp_db = os.path.join(tmp_sync_db_path, os.path.basename(db))
    try:
      mtime = os.path.getmtime(tmp_db)
    except OSError as e:
      if e.errno != errno.ENOENT:
        raise e
      else:
        mtime = 0
    if mtime < os.path.getmtime(db):
      shutil.copy2(db, tmp_db)



  # Sync the temporary database.
  # Support external synchronizers such as parisync.
  if sync_cmd:
    for index, item in enumerate(sync_cmd):
      if item == '%d':
        sync_cmd[index] = tmp_sync_db_path
      elif item == '%r':
        sync_cmd[index] = os.path.dirname(tmp_sync_db_path)
    p = subprocess.Popen(sync_cmd, stdout=subprocess.PIPE)
    e = p.wait()
    if e != 0:
      sys.stderr.write("sync command exited with %d\n" % e)
    # Re-initialize with new databases.
    args = action_sync.parse_options(('-b', tmp_db_path))
    h = config.init_with_config_and_options(args)
  else:
    args = action_sync.parse_options(('-b', tmp_db_path, '-y'))
    h = config.init_with_config_and_options(args)
    sys.stdout = sys.__stderr__
    try:
      t = transaction.init_from_options(h, args)
    except pyalpm.error as e:
      sys.stderr.write('%s\n' % (e,))
      eno = e.args[1]
      if eno == 10:
        lckpath = os.path.join(tmp_db_path, 'db.lck')
        sys.stderr.write('  %s\n' % lckpath)
      sys.exit(1)
    for db in h.get_syncdbs():
      try:
        db.update(False)
      except pyalpm.error as e:
        sys.stderr.write('%s: %s\n' % (db.name, e))
    t.release()
    sys.stdout = sys.__stdout__


  installed = set(p for p in h.get_localdb().pkgcache)
  upgradable = OrderedDict()

  syncdbs = h.get_syncdbs()
  for db in syncdbs:
    # Without "list" the set cannot be altered with "remove" below.
    for pkg in list(installed):
      pkgname = pkg.name
      syncpkg = db.get_pkg(pkgname)
      if syncpkg:
        if pyalpm.vercmp(syncpkg.version, pkg.version) > 0:
          try:
            upgradable[db.name].add((pkg, syncpkg))
          except KeyError:
            upgradable[db.name] = set(((pkg, syncpkg),))
        installed.remove(pkg)

  foreign = dict([(p.name,p) for p in installed])

  try:
    aur = AUR.AUR()
    aur_pkgs = aur.info(foreign.keys())
    upgradable_aur = list()
    for aur_pkg in aur_pkgs:
      try:
        installed_pkg = foreign[aur_pkg['Name']]
      except KeyError:
        upgradable_aur.append(aur_pkg)
        continue
      if pyalpm.vercmp(aur_pkg['Version'], installed_pkg.version) > 0:
        upgradable_aur.append(aur_pkg)
      installed.remove(installed_pkg)
  except AUR.AURError as e:
    sys.stderr.write(str(e))
    sys.exit(1)
  except urllib.error.URLError as e:
    sys.stderr.write(
      'error: failed to retrieve information from the AUR (%s)\n' % e.reason
    )
    upgradable_aur = None
  except TypeError:
    upgradable_aur = None


  display(upgradable, upgradable_aur)
Exemple #3
0
def main(tmp_db_path):
  # Use a temporary database path to avoid issues caused by synchronizing the
  # sync database without a full system upgrade.

  # See the discussion here:
  #   https://bbs.archlinux.org/viewtopic.php?pid=951285#p951285

  # Basically, if you sync the database and then install packages without first
  # upgrading the system (-y), you can do some damage.


  tmp_db_path = os.path.abspath(tmp_db_path)
#   conf = config.PacmanConfig(conf = '/etc/pacman.conf')
  h = config.init_with_config("/etc/pacman.conf")
  db_path = h.dbpath
  if tmp_db_path == db_path:
    print("temporary path cannot be %s" % db_path)
    sys.exit(1)
  local_db_path = os.path.join(db_path, 'local')
  tmp_local_db_path = os.path.join(tmp_db_path, 'local')

  # Set up the temporary database path
  if not os.path.exists(tmp_db_path):
    os.makedirs(tmp_db_path)
    os.symlink(local_db_path, tmp_local_db_path)
  elif not os.path.islink(tmp_local_db_path):
    # Move instead of unlinking just in case.
    if os.path.exists(tmp_local_db_path):
      os.rename(tmp_local_db_path, tmp_local_db_path + '.old')
    os.symlink(local_db_path, tmp_local_db_path)


  # Sync the temporary database.
  args = action_sync.parse_options(('-b', tmp_db_path, '-y'))
  h = config.init_with_config_and_options(args)
  sys.stdout = sys.__stderr__
  for db in h.get_syncdbs():
    t = transaction.init_from_options(h, args)
    try:
      db.update(False)
    except pyalpm.error as e:
      sys.stderr.write('%s: %s\n' % (db.name, e))
    t.release()
  sys.stdout = sys.__stdout__


  installed = set(p for p in h.get_localdb().pkgcache)
  upgradable = OrderedDict()

  syncdbs = h.get_syncdbs()
  for db in syncdbs:
    # Without "list" the set cannot be altered with "remove" below.
    for pkg in list(installed):
      pkgname = pkg.name
      syncpkg = db.get_pkg(pkgname)
      if syncpkg:
        if pyalpm.vercmp(syncpkg.version, pkg.version) > 0:
          try:
            upgradable[db.name].add((pkg, syncpkg))
          except KeyError:
            upgradable[db.name] = set(((pkg, syncpkg),))
        installed.remove(pkg)

  foreign = dict([(p.name,p) for p in installed])

  try:
    aur = AUR.AUR()
    aur_pkgs = aur.info(foreign.keys())
  except AUR.AURError as e:
    sys.stderr.write(str(e))
    sys.exit(1)

  upgradable_aur = list()
  for aur_pkg in aur_pkgs:
    installed_pkg = foreign[aur_pkg['Name']]
    if pyalpm.vercmp(aur_pkg['Version'], installed_pkg.version) > 0:
      upgradable_aur.append((installed_pkg, aur_pkg))
    installed.remove(installed_pkg)

  display(upgradable, upgradable_aur)