Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Refactor pkg_create API
Baptiste Daroussin committed 6 years ago
commit 6cacf35d9197d7272089579b9afbd54aded9aeb5
parent ee95aca
5 files changed +207 -182
modified libpkg/libpkg.ver
@@ -23,9 +23,16 @@ global:
	pkg_config_files;
	pkg_config_get;
	pkg_conflicts;
+
	pkg_create;
+
	pkg_create_free;
	pkg_create_from_manifest;
+
	pkg_create_i;
	pkg_create_installed;
+
	pkg_create_new;
	pkg_create_repo;
+
	pkg_create_set_format;
+
	pkg_create_set_output_dir;
+
	pkg_create_set_rootdir;
	pkg_create_staged;
	pkg_dep_get;
	pkg_dep_is_locked;
modified libpkg/pkg.h.in
@@ -98,6 +98,7 @@ struct pkg_dir;
struct pkg_option;
struct pkg_license;
struct pkg_config_file;
+
struct pkg_create;

struct pkgdb;
struct pkgdb_it;
@@ -1131,22 +1132,7 @@ void pkg_solve_problem_free(struct pkg_solve_problem *problem);
 */
typedef enum pkg_formats { TAR, TGZ, TBZ, TXZ, TZS } pkg_formats;

-
/**
-
 * Create package from an installed & registered package
-
 */
-
int pkg_create_installed(const char *, pkg_formats, struct pkg *);
-

-
/**
-
 * Create package from stage install using just the manifest --
-
 * no old pkg_tools compatibility stuff
-
 */
-
int pkg_create_from_manifest(const char *, pkg_formats, const char *,
-
    const char *, const char *);

-
/**
-
 * Create package from stage install with a metadata directory
-
 */
-
int pkg_create_staged(const char *, pkg_formats, const char *, const char *, char *, bool);
int pkg_load_metadata(struct pkg *, const char *, const char *, const char *, const char *, bool);

/**
@@ -1715,6 +1701,19 @@ int pkg_get_dbdirfd(void);

int pkg_namecmp(struct pkg *, struct pkg *);

+
struct pkg_create *pkg_create_new(void);
+
void pkg_create_free(struct pkg_create *);
+
bool pkg_create_set_format(struct pkg_create *, const char *);
+
void pkg_create_set_rootdir(struct pkg_create *, const char *);
+
void pkg_create_set_output_dir(struct pkg_create *, const char *);
+
int pkg_create(struct pkg_create *, const char *, const char *, bool);
+
int pkg_create_i(struct pkg_create *, struct pkg *, bool);
+
/* deprecated */
+
int pkg_create_from_manifest(const char *, pkg_formats, const char *,
+
    const char *, const char *) __attribute__((deprecated));
+
int pkg_create_staged(const char *, pkg_formats, const char *, const char *, char *, bool) __attribute__((deprecated));
+
int pkg_create_installed(const char *, pkg_formats, struct pkg *) __attribute__((deprecated));
+

#ifdef __cplusplus
}
#endif
modified libpkg/pkg_create.c
@@ -41,7 +41,10 @@

#define TICK	100

+
static int load_metadata(struct pkg *pkg, const char *metadata, const char *plist,
+
    const char *rootdir);
static int pkg_create_from_dir(struct pkg *, const char *, struct packing *);
+
static void fixup_abi(struct pkg *pkg, const char *rootdir, bool testing);
static void counter_init(const char *what, int64_t max);
static void counter_count(void);
static void counter_end(void);
@@ -168,8 +171,7 @@ pkg_create_from_dir(struct pkg *pkg, const char *root,
}

static struct packing *
-
pkg_create_archive(const char *outdir, struct pkg *pkg, pkg_formats format,
-
    unsigned required_flags)
+
pkg_create_archive(struct pkg *pkg, struct pkg_create *pc, unsigned required_flags)
{
	char		*pkg_path = NULL;
	struct packing	*pkg_archive = NULL;
@@ -180,15 +182,15 @@ pkg_create_archive(const char *outdir, struct pkg *pkg, pkg_formats format,
	if (pkg->type != PKG_OLD_FILE)
		assert((pkg->flags & required_flags) == required_flags);

-
	if (mkdirs(outdir) != EPKG_OK)
+
	if (mkdirs(pc->outdir) != EPKG_OK)
		return NULL;

-
	if (pkg_asprintf(&pkg_path, "%S/%n-%v", outdir, pkg, pkg) == -1) {
+
	if (pkg_asprintf(&pkg_path, "%S/%n-%v", pc->outdir, pkg, pkg) == -1) {
		pkg_emit_errno("pkg_asprintf", "");
		return (NULL);
	}

-
	if (packing_init(&pkg_archive, pkg_path, format) != EPKG_OK)
+
	if (packing_init(&pkg_archive, pkg_path, pc->format) != EPKG_OK)
		pkg_archive = NULL;

	free(pkg_path);
@@ -221,43 +223,162 @@ static const char * const lua_scripts[] = {
	NULL
};

+
struct pkg_create *
+
pkg_create_new(void)
+
{
+
	struct pkg_create *pc;
+

+
	pc = xcalloc(1, sizeof(pc));
+
	pc->format = TXZ;
+

+
	return (pc);
+
}
+

+
void
+
pkg_create_free(struct pkg_create *pc)
+
{
+
	free(pc);
+
}
+

+
bool
+
pkg_create_set_format(struct pkg_create *pc, const char *format)
+
{
+
	if (strcmp(format, "tzst") == 0)
+
		pc->format = TZS;
+
	else if (strcmp(format, "txz") == 0)
+
		pc->format = TXZ;
+
	else if (strcmp(format, "tbz") == 0)
+
		pc->format = TBZ;
+
	else if (strcmp(format, "tgz") == 0)
+
		pc->format = TGZ;
+
	else if (strcmp(format, "tar") == 0)
+
		pc->format = TAR;
+
	else
+
		return (false);
+
	return (true);
+
}
+

+
void
+
pkg_create_set_rootdir(struct pkg_create *pc, const char *rootdir)
+
{
+
	pc->rootdir = rootdir;
+
}
+

+
void
+
pkg_create_set_output_dir(struct pkg_create *pc, const char *outdir)
+
{
+
	pc->outdir = outdir;
+
}
+

+
static int
+
hash_file(struct pkg_create *pc, struct pkg *pkg)
+
{
+
	char hash_dest[MAXPATHLEN];
+
	char filename[MAXPATHLEN];
+

+
	/* Find the hash and rename the file and create a symlink */
+
	pkg_snprintf(filename, sizeof(filename), "%n-%v.%S",
+
			pkg, pkg, packing_format_to_string(pc->format));
+
	pkg->sum = pkg_checksum_file(filename,
+
			PKG_HASH_TYPE_SHA256_HEX);
+
	pkg_snprintf(hash_dest, sizeof(hash_dest), "%n-%v-%z.%S",
+
			pkg, pkg, pkg, packing_format_to_string(pc->format));
+

+
	pkg_debug(1, "Rename the pkg file from: %s to: %s",
+
			filename, hash_dest);
+
	if (rename(filename, hash_dest) == -1) {
+
		pkg_emit_errno("rename", hash_dest);
+
		unlink(hash_dest);
+
		return (EPKG_FATAL);
+
	}
+
	if (symlink(hash_dest, filename) == -1) {
+
		pkg_emit_errno("symlink", hash_dest);
+
		return (EPKG_FATAL);
+
	}
+
	return (EPKG_OK);
+
}

-
/* The "no concessions to old pkg_tools" variant: just get everything
-
 * from the manifest */
int
-
pkg_create_from_manifest(const char *outdir, pkg_formats format,
-
    const char *rootdir, const char *manifest, const char *plist)
+
pkg_create_i(struct pkg_create *pc, struct pkg *pkg, bool hash)
{
-
	struct pkg	*pkg = NULL;
-
	struct packing	*pkg_archive = NULL;
-
	int		 ret = ENOMEM;
+
	struct packing *pkg_archive = NULL;
+
	int ret;
+

+
	unsigned required_flags = PKG_LOAD_DEPS | PKG_LOAD_FILES |
+
		PKG_LOAD_CATEGORIES | PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS |
+
		PKG_LOAD_OPTIONS | PKG_LOAD_LICENSES | PKG_LOAD_LUA_SCRIPTS;
+

+
	assert(pkg->type == PKG_INSTALLED || pkg->type == PKG_OLD_FILE);

-
	pkg_debug(1, "Creating package from stage directory: '%s'", rootdir);
+
	pkg_archive = pkg_create_archive(pkg, pc, required_flags);
+
	if (pkg_archive == NULL) {
+
		pkg_emit_error("unable to create archive");
+
		return (EPKG_FATAL);
+
	}
+

+
	if ((ret = pkg_create_from_dir(pkg, NULL, pkg_archive)) != EPKG_OK) {
+
		packing_finish(pkg_archive);
+
		pkg_emit_error("package creation failed");
+
	}
+

+
	if (hash && ret == EPKG_OK)
+
		ret = hash_file(pc, pkg);
+

+
	return (ret);
+
}
+

+
int
+
pkg_create(struct pkg_create *pc, const char *metadata, const char *plist,
+
    bool hash)
+
{
+
	struct pkg *pkg = NULL;
+
	struct packing *pkg_archive = NULL;
+
	int ret = ENOMEM;

-
	if(pkg_new(&pkg, PKG_FILE) != EPKG_OK) {
-
		ret = EPKG_FATAL;
-
		goto cleanup;
+
	pkg_debug(1, "Creating package");
+
	if (pkg_new(&pkg, PKG_FILE) != EPKG_OK) {
+
		return (EPKG_FATAL);
	}

-
	if ((ret = pkg_load_metadata(pkg, manifest, NULL, plist, rootdir, false))
-
	    != EPKG_OK) {
-
		ret = EPKG_FATAL;
-
		goto cleanup;
+
	if ((ret = load_metadata(pkg, metadata, plist, pc->rootdir)) != EPKG_OK) {
+
		pkg_free(pkg);
+
		return (EPKG_FATAL);
	}
+
	fixup_abi(pkg, pc->rootdir, false);

-
	/* Create the archive */
-
	pkg_archive = pkg_create_archive(outdir, pkg, format, 0);
+
	pkg_archive = pkg_create_archive(pkg, pc, 0);
	if (pkg_archive == NULL) {
-
		ret = EPKG_FATAL; /* XXX do better */
-
		goto cleanup;
+
		pkg_free(pkg);
+
		return (EPKG_FATAL);
	}

-
	if ((ret = pkg_create_from_dir(pkg, rootdir, pkg_archive)) != EPKG_OK)
+
	if ((ret = pkg_create_from_dir(pkg, pc->rootdir, pkg_archive)) != EPKG_OK)
		pkg_emit_error("package creation failed");

-
cleanup:
-
	free(pkg);
	packing_finish(pkg_archive);
+
	if (hash && ret == EPKG_OK)
+
		ret = hash_file(pc, pkg);
+

+
	pkg_free(pkg);
+
	return (ret);
+
}
+

+
/* The "no concessions to old pkg_tools" variant: just get everything
+
 * from the manifest */
+
int
+
pkg_create_from_manifest(const char *outdir, pkg_formats format,
+
    const char *rootdir, const char *manifest, const char *plist)
+
{
+
	struct pkg_create *pc;
+
	int ret;
+

+
	pc = pkg_create_new();
+
	pc->format = format;
+
	pkg_create_set_rootdir(pc, rootdir);
+
	pkg_create_set_output_dir(pc, outdir);
+

+
	ret = pkg_create(pc, manifest, plist, false);
+
	pkg_create_free(pc);
	return (ret);
}

@@ -422,91 +543,31 @@ int
pkg_create_staged(const char *outdir, pkg_formats format, const char *rootdir,
    const char *md_dir, char *plist, bool hash)
{
-
	char		 hash_dest[MAXPATHLEN];
-
	char		 filename[MAXPATHLEN];
-
	struct pkg	*pkg = NULL;
-
	struct pkg_file	*file = NULL;
-
	struct pkg_dir	*dir = NULL;
-
	struct packing	*pkg_archive = NULL;
-
	int		 ret = EPKG_FATAL;
-

-
	pkg_debug(1, "Creating package from stage directory: '%s'", rootdir);
-

-
	if ((ret = pkg_new(&pkg, PKG_FILE)) != EPKG_OK)
-
		goto cleanup;
-

-
	if ((ret = pkg_load_metadata(pkg, NULL, md_dir, plist, rootdir, false))
-
	    != EPKG_OK)
-
		goto cleanup;
-

-
	/* Create the archive */
-
	pkg_archive = pkg_create_archive(outdir, pkg, format, 0);
-
	if (pkg_archive == NULL) {
-
		ret = EPKG_FATAL; /* XXX do better */
-
		goto cleanup;
-
	}
-

-
	/* XXX: autoplist support doesn't work right with meta-ports */
-
	if (0 && pkg_files(pkg, &file) != EPKG_OK &&
-
	    pkg_dirs(pkg, &dir) != EPKG_OK) {
-
		/* Now traverse the file directories, adding to the archive */
-
		packing_append_tree(pkg_archive, md_dir, NULL);
-
		packing_append_tree(pkg_archive, rootdir, "/");
-
		ret = EPKG_OK;
-
	} else {
-
		ret = pkg_create_from_dir(pkg, rootdir, pkg_archive);
-
	}
-

-
cleanup:
-
	packing_finish(pkg_archive);
-
	if (hash && ret == EPKG_OK) {
-
		/* Find the hash and rename the file and create a symlink */
-
		pkg_snprintf(filename, sizeof(filename), "%n-%v.%S",
-
			pkg, pkg, packing_format_to_string(format));
-
		pkg->sum = pkg_checksum_file(filename,
-
			PKG_HASH_TYPE_SHA256_HEX);
-
		pkg_snprintf(hash_dest, sizeof(hash_dest), "%n-%v-%z.%S",
-
			pkg, pkg, pkg, packing_format_to_string(format));
+
	struct pkg_create *pc;
+
	int ret;

-
		pkg_debug(1, "Rename the pkg file from: %s to: %s",
-
			filename, hash_dest);
+
	pc = pkg_create_new();
+
	pc->format = format;
+
	pkg_create_set_rootdir(pc, rootdir);
+
	pkg_create_set_output_dir(pc, outdir);

-
		if (rename(filename, hash_dest) == -1) {
-
			pkg_emit_errno("rename", hash_dest);
-
			unlink(hash_dest);
-
			return (EPKG_FATAL);
-
		}
-
		if (symlink(hash_dest, filename) == -1) {
-
			pkg_emit_errno("symlink", hash_dest);
-
			return (EPKG_FATAL);
-
		}
-
	}
-
	free(pkg);
+
	ret = pkg_create(pc, md_dir, plist, hash);
	return (ret);
}

int
pkg_create_installed(const char *outdir, pkg_formats format, struct pkg *pkg)
{
-
	struct packing	*pkg_archive;
-

-
	unsigned	 required_flags = PKG_LOAD_DEPS | PKG_LOAD_FILES |
-
		PKG_LOAD_CATEGORIES | PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS |
-
		PKG_LOAD_OPTIONS | PKG_LOAD_LICENSES | PKG_LOAD_LUA_SCRIPTS;
-

-
	assert(pkg->type == PKG_INSTALLED || pkg->type == PKG_OLD_FILE);
-

-
	pkg_archive = pkg_create_archive(outdir, pkg, format, required_flags);
-
	if (pkg_archive == NULL) {
-
		pkg_emit_error("unable to create archive");
-
		return (EPKG_FATAL);
-
	}
-

-
	pkg_create_from_dir(pkg, NULL, pkg_archive);
+
	struct pkg_create *pc;
+
	int ret;

-
	packing_finish(pkg_archive);
+
	pc = pkg_create_new();
+
	pc->format = format;
+
	pkg_create_set_output_dir(pc, outdir);

-
	return (EPKG_OK);
+
	ret = pkg_create_i(pc, pkg, false);
+
	pkg_create_free(pc);
+
	return (ret);
}

static int64_t	count;
modified libpkg/private/pkg.h
@@ -332,6 +332,14 @@ struct pkg {
	struct pkg_repo		*repo;
};

+
struct pkg_create {
+
	uint8_t	compression_level;
+
	pkg_formats format;
+
	time_t timestamp;
+
	const char *rootdir;
+
	const char *outdir;
+
};
+

struct pkg_dep {
	char		*origin;
	char		*name;
modified src/create.c
@@ -1,5 +1,5 @@
/*-
-
 * Copyright (c) 2011-2015 Baptiste Daroussin <bapt@FreeBSD.org>
+
 * Copyright (c) 2011-2020 Baptiste Daroussin <bapt@FreeBSD.org>
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2011 Will Andrews <will@FreeBSD.org>
 * Copyright (c) 2015 Matthew Seaman <matthew@FreeBSD.org>
@@ -74,8 +74,7 @@ usage_create(void)
}

static int
-
pkg_create_matches(int argc, char **argv, match_t match, pkg_formats fmt,
-
    const char * const outdir, bool overwrite)
+
pkg_create_matches(int argc, char **argv, match_t match, struct pkg_create *pc)
{
	int i, ret = EPKG_OK, retcode = EPKG_OK;
	struct pkg *pkg = NULL;
@@ -103,24 +102,6 @@ pkg_create_matches(int argc, char **argv, match_t match, pkg_formats fmt,
		return (EX_TEMPFAIL);
	}

-
	switch (fmt) {
-
	case TZS:
-
		format = "tzst";
-
		break;
-
	case TXZ:
-
		format = "txz";
-
		break;
-
	case TBZ:
-
		format = "tbz";
-
		break;
-
	case TGZ:
-
		format = "tgz";
-
		break;
-
	case TAR:
-
		format = "tar";
-
		break;
-
	}
-

	for (i = 0; i < argc || match == MATCH_ALL; i++) {
		if (match == MATCH_ALL) {
			printf("Loading the package list...\n");
@@ -153,20 +134,8 @@ pkg_create_matches(int argc, char **argv, match_t match, pkg_formats fmt,

	DL_FOREACH_SAFE(pkg_head, e, etmp) {
		DL_DELETE(pkg_head, e);
-

-
		if (!overwrite) {
-
			pkg_snprintf(pkgpath, sizeof(pkgpath), "%S/%n-%v.%S",
-
			    outdir, e->pkg, e->pkg, format);
-
			if (access(pkgpath, F_OK) == 0) {
-
				pkg_printf("%n-%v already packaged, skipping...\n",
-
				    e->pkg, e->pkg);
-
				pkg_free(e->pkg);
-
				free(e);
-
				continue;
-
			}
-
		}
		pkg_printf("Creating package for %n-%v\n", e->pkg, e->pkg);
-
		if (pkg_create_installed(outdir, fmt, e->pkg) !=
+
		if (pkg_create_i(pc, e->pkg, false) !=
		    EPKG_OK)
			retcode++;
		pkg_free(e->pkg);
@@ -196,6 +165,7 @@ cleanup:
int
exec_create(int argc, char **argv)
{
+
	struct pkg_create *pc;
	match_t		 match = MATCH_EXACT;
	const char	*outdir = NULL;
	const char	*format = NULL;
@@ -205,7 +175,6 @@ exec_create(int argc, char **argv)
	char		*plist = NULL;
	pkg_formats	 fmt;
	int		 ch;
-
	bool		 overwrite = true;
	bool		 hash = false;


@@ -252,9 +221,6 @@ exec_create(int argc, char **argv)
		case 'M':
			manifest = optarg;
			break;
-
		case 'n':
-
			overwrite = false;
-
			break;
		case 'o':
			outdir = optarg;
			break;
@@ -297,36 +263,20 @@ exec_create(int argc, char **argv)
	if (outdir == NULL)
		outdir = "./";

-
	if (format == NULL) {
-
		fmt = TXZ;
-
	} else {
+
	pc = pkg_create_new();
+
	if (format != NULL) {
		if (format[0] == '.')
			++format;
-
		if (strcmp(format, "tzst") == 0)
-
			fmt = TZS;
-
		else if (strcmp(format, "txz") == 0)
-
			fmt = TXZ;
-
		else if (strcmp(format, "tbz") == 0)
-
			fmt = TBZ;
-
		else if (strcmp(format, "tgz") == 0)
-
			fmt = TGZ;
-
		else if (strcmp(format, "tar") == 0)
-
			fmt = TAR;
-
		else {
-
			warnx("unknown format %s, using txz", format);
-
			fmt = TXZ;
-
		}
+
		if (!pkg_create_set_format(pc, format))
+
			warnx("unknown format %s, using the default", format);
	}

-
	if (metadatadir == NULL && manifest == NULL) {
-
		return (pkg_create_matches(argc, argv, match, fmt, outdir,
-
		    overwrite) == EPKG_OK ? EX_OK : EX_SOFTWARE);
-
	} else if (metadatadir != NULL) {
-
		return (pkg_create_staged(outdir, fmt, rootdir, metadatadir,
-
		    plist, hash) == EPKG_OK ? EX_OK : EX_SOFTWARE);
-
	} else  { /* (manifest != NULL) */
-
		return (pkg_create_from_manifest(outdir, fmt, rootdir,
-
		    manifest, plist) == EPKG_OK ? EX_OK : EX_SOFTWARE);
-
	}
+
	pkg_create_set_rootdir(pc, rootdir);
+
	pkg_create_set_output_dir(pc, outdir);
+

+
	if (metadatadir == NULL && manifest == NULL)
+
		return (pkg_create_matches(argc, argv, match, pc) == EPKG_OK ? EX_OK : EX_SOFTWARE);
+
	return (pkg_create(pc, metadatadir != NULL ? metadatadir : manifest, plist,
+
	    hash) == EPKG_OK ? EX_OK : EX_SOFTWARE);
}