Example #1
0
GFile *
fetch_archive (const gchar  *url,
               const gchar  *sha,
               const gchar  *module_name,
               GFile        *destination,
               guint         strip_components,
               GError      **error)
{
  g_autoptr(GFile) archive_file = NULL;
  g_autoptr(GFile) source_dir = NULL;
  g_autoptr(SoupURI) uri = NULL;
  g_autofree char *archive_name = NULL;
  GError *local_error = NULL;

  source_dir = g_file_get_child (destination, module_name);
  if (!g_file_make_directory_with_parents (source_dir, NULL, &local_error))
    {
      if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
        {
          g_propagate_error (error, local_error);
          return NULL;
        }

      g_error_free (local_error);
    }

  uri = soup_uri_new (url);
  archive_name = g_path_get_basename (soup_uri_get_path (uri));
  archive_file = g_file_get_child (source_dir, archive_name);

  if (!download_archive (uri, sha, archive_file, error))
    return NULL;

  if (!extract_archive (source_dir, archive_file, strip_components, error))
    return NULL;

  return g_steal_pointer (&source_dir);
}
Example #2
0
/*
 * At CREATE EXTENSION time we check if the extension is already available,
 * which is driven by the presence of its control file on disk.
 *
 * If the extension is not already available, we ask the repository server for
 * it, and unpack received binary archive to the right place.
 *
 * TODO: actually talk to the repository server. Current prototype version
 * directly uses the local archive cache.
 */
void
download_and_unpack_archive(const char *extname)
{
    PlatformData platform;
    char *control_filename = get_extension_control_filename(extname);
    char *archive_filename;

    /*
     * No cache, download again each time asked: any existing control file for
     * the extension could be one we left behind from a previous version of the
     * extension's archive.
     *
     * This also means that if an extension is already provided by the
     * operating system, by installing pginstall you give preference to
     * pginstall builds.
     */
    current_platform(&platform);
    archive_filename = psprintf("%s/%s--%s--%s--%s--%s.tar.gz",
                                pginstall_archive_dir,
                                extname,
                                PG_VERSION,
                                escape_filename(platform.os_name),
                                escape_filename(platform.os_version),
                                escape_filename(platform.arch));

    /*
     * The local repository might be added to directly by the pginstall build
     * client, and pginstall.serve_from_archive_dir allows to setup the
     * pginstall.archive_dir as a local authoritative source.
     *
     * Given that, we only download an archive file when
     *
     *  1. we have a pginstall.repository
     *  2. pginstall.serve_from_archive_dir is false
     *  3. pginstall.serve_from_archive_dir is true but we don't have the
     *     needed file locally
     */
    if (pginstall_repository != NULL && strcmp(pginstall_repository, "") != 0)
    {
        if (pginstall_serve_from_archive_dir
            && access(archive_filename, R_OK) == 0)
        {
            /* no download here. */
            (void)0;
        }
        else
        {
            download_archive(archive_filename, extname, &platform);
        }
    }

    /*
     * Even if we didn't find any extension's archive file for our platform on
     * the repository server, it could be that the extension is available
     * locally either through the OS packages or maybe a local developer setup
     * (make install).
     *
     * In case when when extension control file still doesn't exists after
     * we've been communicating with the repository server, PostgreSQL will
     * issue its usual error message about a missing control file.
     */
    if (access(archive_filename, R_OK) == 0)
    {
        extract(extname, archive_filename);

        /* now rewrite the control file to "relocate" the extension */
        rewrite_control_file(extname, control_filename);
    }
    return;
}