Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Implement new repo style.
Vsevolod Stakhov committed 11 years ago
commit 3eb182d12c4d492e720962a4ecf4eaf7020bf8fe
parent 1599509
6 files changed +101 -19
modified libpkg/pkg.h.in
@@ -959,9 +959,10 @@ int pkg_is_installed(struct pkgdb *db, const char *origin);
 * @param force If true, rebuild the repository catalogue from scratch
 * @param filesite If true, create a list of all files in repo
 * @param metafile Open meta from the specified file
+
 * @param legacy Create legacy (1.2 compatible) repo
 */
int pkg_create_repo(char *path, const char *output_dir, bool filelist,
-
	const char *metafile);
+
	const char *metafile, bool legacy);
int pkg_finish_repo(const char *output_dir, pem_password_cb *cb, char **argv,
    int argc, bool filelist);

modified libpkg/pkg_repo_create.c
@@ -256,17 +256,19 @@ pkg_create_repo_read_fts(struct pkg_fts_item **items, FTS *fts,

static int
pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,
-
	const char *mlfile, const char *flfile, int pip)
+
	const char *mlfile, const char *flfile, int pip,
+
	struct pkg_repo_meta *meta)
{
	pid_t pid;
	int mfd, ffd;
	bool read_files = (flfile != NULL);
+
	bool legacy = (meta == NULL);
	int flags, ret = EPKG_OK;
	size_t cur_job = 0;
	struct pkg_fts_item *cur;
	struct pkg *pkg = NULL;
	struct pkg_manifest_key *keys = NULL;
-
	char checksum[SHA256_DIGEST_LENGTH * 2 + 1], *mdigest;
+
	char checksum[SHA256_DIGEST_LENGTH * 3 + 1], *mdigest = NULL;
	char digestbuf[1024];
	struct iovec iov[2];

@@ -331,7 +333,21 @@ pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,
			 * TODO: use pkg_checksum for new manifests
			 */
			sbuf_clear(b);
-
			pkg_emit_manifest_sbuf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, &mdigest);
+
			if (legacy)
+
				pkg_emit_manifest_sbuf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, &mdigest);
+
			else {
+
				mdigest = malloc(pkg_checksum_type_size(meta->digest_format));
+

+
				pkg_emit_manifest_sbuf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, NULL);
+
				if (pkg_checksum_generate(pkg, mdigest,
+
				     pkg_checksum_type_size(meta->digest_format),
+
				     meta->digest_format) != EPKG_OK) {
+
					pkg_emit_error("Cannot generate digest for a package");
+
					ret = EPKG_FATAL;
+

+
					goto cleanup;
+
				}
+
			}
			mlen = sbuf_len(b);
			sbuf_finish(b);

@@ -379,6 +395,8 @@ pkg_create_repo_worker(struct pkg_fts_item *start, size_t nelts,
				(long)fpos,
				(long)mlen);

+
			free(mdigest);
+
			mdigest = NULL;
			write(pip, digestbuf, r);
		}
		cur_job ++;
@@ -391,6 +409,8 @@ cleanup:
	close(mfd);
	if (read_files)
		close(ffd);
+
	if (mdigest)
+
		free(mdigest);

	exit(ret);
}
@@ -473,7 +493,7 @@ pkg_create_repo_read_pipe(int fd, struct digest_list_entry **dlist)

int
pkg_create_repo(char *path, const char *output_dir, bool filelist,
-
	const char *metafile)
+
	const char *metafile, bool legacy)
{
	FTS *fts = NULL;
	struct pkg_fts_item *fts_items = NULL, *fts_cur;
@@ -485,7 +505,7 @@ pkg_create_repo(char *path, const char *output_dir, bool filelist,
	struct digest_list_entry *dlist = NULL, *cur_dig, *dtmp;
	struct pollfd *pfd = NULL;
	int cur_pipe[2], fd;
-

+
	struct pkg_repo_meta *meta;
	int retcode = EPKG_OK;

	char *repopath[2];
@@ -515,6 +535,16 @@ pkg_create_repo(char *path, const char *output_dir, bool filelist,
		}
	}

+
	if (metafile != NULL) {
+
		if (pkg_repo_meta_load(metafile, &meta) != EPKG_OK) {
+
			pkg_emit_error("meta loading error while trying %s", metafile);
+
			return (EPKG_FATAL);
+
		}
+
	}
+
	else {
+
		meta = pkg_repo_meta_default();
+
	}
+

	repopath[0] = path;
	repopath[1] = NULL;

@@ -583,7 +613,8 @@ pkg_create_repo(char *path, const char *output_dir, bool filelist,
			}

			if (pkg_create_repo_worker(fts_cur, tasks_per_worker, packagesite,
-
				filelist ? filesite : NULL, cur_pipe[1]) == EPKG_FATAL) {
+
				filelist ? filesite : NULL, cur_pipe[1],
+
				legacy ? NULL : meta) == EPKG_FATAL) {
				close(cur_pipe[0]);
				close(cur_pipe[1]);
				retcode = EPKG_FATAL;
@@ -644,6 +675,23 @@ pkg_create_repo(char *path, const char *output_dir, bool filelist,
	pkg_repo_write_conflicts(conflicts, fconflicts);
#endif

+
	/* Write metafile */
+
	if (!legacy) {
+
		ucl_object_t *meta_dump;
+
		FILE *mfile;
+

+
		snprintf(repodb, sizeof(repodb), "%s/%s", output_dir,
+
			"meta");
+
		if ((mfile = fopen(repodb, "w")) != NULL) {
+
			meta_dump = pkg_repo_meta_to_ucl(meta);
+
			ucl_object_emit_file(meta_dump, UCL_EMIT_CONFIG, mfile);
+
			ucl_object_unref(meta_dump);
+
			fclose(mfile);
+
		}
+
		else {
+
			pkg_emit_notice("cannot create metafile at %s", repodb);
+
		}
+
	}
cleanup:
	HASH_ITER (hh, conflicts, curcb, tmpcb) {
		HASH_ITER (hh, curcb->conflicts, c, ctmp) {
@@ -673,6 +721,8 @@ cleanup:
		free(cur_dig);
	}

+
	pkg_repo_meta_free(meta);
+

	if (mandigests != NULL)
		fclose(mandigests);

@@ -826,7 +876,8 @@ pkg_finish_repo(const char *output_dir, pem_password_cb *password_cb,
	struct rsa_key *rsa = NULL;
	struct stat st;
	int ret = EPKG_OK;
-
	const int files_to_pack = 3;
+
	const int files_to_pack = 4;
+
	bool legacy = false;

	if (!is_dir(output_dir)) {
		pkg_emit_error("%s is not a directory", output_dir);
@@ -881,6 +932,24 @@ pkg_finish_repo(const char *output_dir, pem_password_cb *password_cb,
		goto cleanup;
	}

+
	snprintf(repo_path, sizeof(repo_path), "%s/%s", output_dir,
+
		repo_meta_file);
+
	snprintf(repo_archive, sizeof(repo_archive), "%s/%s", output_dir,
+
		repo_meta_archive);
+
	/*
+
	 * If no meta is defined, then it is a legacy repo
+
	 */
+
	if (access(repo_path, R_OK) != -1) {
+
		if (pkg_repo_pack_db(repo_meta_file, repo_archive, repo_path, rsa, argv, argc) != EPKG_OK) {
+
			ret = EPKG_FATAL;
+
			goto cleanup;
+
		}
+
	}
+
	else
+
		legacy = true;
+

+
	pkg_emit_progress_tick(3, files_to_pack);
+

#if 0
	snprintf(repo_path, sizeof(repo_path), "%s/%s", output_dir,
		repo_conflicts_file);
@@ -917,6 +986,11 @@ pkg_finish_repo(const char *output_dir, pem_password_cb *password_cb,
			    "%s/%s.txz", output_dir, repo_filesite_archive);
			utimes(repo_archive, ftimes);
		}
+
		if (!legacy) {
+
			snprintf(repo_archive, sizeof(repo_archive),
+
				"%s/%s.txz", output_dir, repo_meta_archive);
+
			utimes(repo_archive, ftimes);
+
		}
	}

cleanup:
modified libpkg/pkg_repo_meta.c
@@ -44,6 +44,7 @@ pkg_repo_meta_set_default(struct pkg_repo_meta *meta)
	meta->digests = strdup("digests");
	/* Not using fulldb */
	meta->fulldb = NULL;
+
	meta->version = 1;
}

void
@@ -293,13 +294,13 @@ pkg_repo_meta_default(void)
}

#define META_EXPORT_FIELD(result, meta, field, type)	do { 					\
-
	if (strcmp(#type, "string") != 0 || meta->field != 0)					\
+
	if (meta->field != 0)					\
		ucl_object_insert_key((result), ucl_object_from ## type (meta->field),	\
				#field, 0, false); 												\
	} while(0)

#define META_EXPORT_FIELD_FUNC(result, meta, field, type, func)	do {			\
-
	if (strcmp(#type, "string") != 0 || func(meta->field) != 0)				\
+
	if (func(meta->field) != 0)				\
		ucl_object_insert_key((result), ucl_object_from ## type (func(meta->field)), \
				#field, 0, false); 												\
	} while(0)
modified libpkg/private/pkg.h
@@ -482,6 +482,7 @@ int pkg_repo_fetch_meta(struct pkg_repo *repo, time_t *t);
struct pkg_repo_meta *pkg_repo_meta_default(void);
int pkg_repo_meta_load(const char *file, struct pkg_repo_meta **target);
void pkg_repo_meta_free(struct pkg_repo_meta *meta);
+
ucl_object_t * pkg_repo_meta_to_ucl(struct pkg_repo_meta *meta);

typedef enum {
	HASH_UNKNOWN,
modified libpkg/private/repodb.h
@@ -39,6 +39,7 @@ static const char repo_digests_file[] = "digests";
static const char repo_digests_archive[] = "digests";
static const char repo_conflicts_file[] = "conflicts";
static const char repo_conflicts_archive[] = "conflicts";
-

+
static const char repo_meta_file[] = "meta";
+
static const char repo_meta_archive[] = "meta";

#endif	/* _REPODB */
modified src/repo.c
@@ -70,24 +70,22 @@ int
exec_repo(int argc, char **argv)
{
	int	 ret;
-
	int	 pos = 0;
	int	 ch;
	bool	 filelist = false;
	char	*output_dir = NULL;
-
	void	(*progress_fn)(struct pkg *, void *);
-
	int	*pos_ptr;
+
	char	*meta_file = NULL;
+
	bool	legacy = false;

	struct option longopts[] = {
		{ "list-files", no_argument,		NULL,	'l' },
		{ "output-dir", required_argument,	NULL,	'o' },
		{ "quiet",	no_argument,		NULL,	'q' },
+
		{ "meta",	required_argument,	NULL,	'm' },
+
		{ "legacy",	no_argument,	NULL,	'L' },
		{ NULL,		0,			NULL,	0   },
	};

-
	progress_fn = NULL;
-
	pos_ptr = NULL;
-

-
	while ((ch = getopt_long(argc, argv, "lo:q", longopts, NULL)) != -1) {
+
	while ((ch = getopt_long(argc, argv, "lo:qm:L", longopts, NULL)) != -1) {
		switch (ch) {
		case 'l':
			filelist = true;
@@ -98,6 +96,12 @@ exec_repo(int argc, char **argv)
		case 'q':
			quiet = true;
			break;
+
		case 'm':
+
			meta_file = optarg;
+
			break;
+
		case 'L':
+
			legacy = true;
+
			break;
		default:
			usage_repo();
			return (EX_USAGE);
@@ -119,7 +123,7 @@ exec_repo(int argc, char **argv)
	if (output_dir == NULL)
		output_dir = argv[0];

-
	ret = pkg_create_repo(argv[0], output_dir, filelist);
+
	ret = pkg_create_repo(argv[0], output_dir, filelist, meta_file, legacy);

	if (ret != EPKG_OK) {
		printf("Cannot create repository catalogue\n");