return object;
}
+static PyObject* Pakfire_repo_compose(PakfireObject* self, PyObject* args, PyObject* kwargs) {
+ char* kwlist[] = { "path", NULL };
+ const char* path = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &path))
+ return NULL;
+
+ const int flags = 0;
+
+ int r = pakfire_repo_compose(self->pakfire, path, flags);
+ if (r) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
static struct PyMethodDef Pakfire_methods[] = {
{
"bind",
METH_VARARGS,
NULL,
},
+ {
+ "repo_compose",
+ (PyCFunction)Pakfire_repo_compose,
+ METH_VARARGS|METH_KEYWORDS,
+ NULL
+ },
{
"search",
(PyCFunction)Pakfire_search,
// Refresh metadata
return pakfire_repo_refresh_metadata(repo, force);
}
+
+static int pakfire_repo_write_database(struct pakfire_repo* repo, const char* path) {
+ char database[PATH_MAX];
+ char filename[NAME_MAX];
+ char tmp[PATH_MAX];
+ int r;
+
+ // Create path for a temporary database export file
+ r = pakfire_string_format(tmp, "%s/repodata/.pakfire-solv.XXXXXX", path);
+ if (r < 0)
+ return r;
+
+ // Create a temporary file to write to
+ FILE* f = pakfire_mktemp(tmp);
+ if (!f) {
+ ERROR(repo->pakfire, "Could not open temporary file for writing: %m\n");
+ return 1;
+ }
+
+ // Write the SOLV database to the temporary file
+ r = pakfire_repo_write_solv_fp(repo, f, 0);
+ if (r) {
+ ERROR(repo->pakfire, "Could not write SOLV data: %m\n");
+ goto ERROR;
+ }
+
+ // Close file
+ fclose(f);
+ f = NULL;
+
+ // Create a filename for the database file
+ r = pakfire_strftime_now(filename, "repodata/%Y-%m-%d-%H%M.%s.db");
+ if (r) {
+ ERROR(repo->pakfire, "Could not format database filename: %m\n");
+ goto ERROR;
+ }
+
+ // Make final database path
+ r = pakfire_path_join(database, path, filename);
+ if (r < 0) {
+ ERROR(repo->pakfire, "Could not join database path: %m\n");
+ goto ERROR;
+ }
+
+ // Link database to its destination
+ r = link(tmp, database);
+ if (r) {
+ ERROR(repo->pakfire, "Could not link database %s: %m\n", database);
+ goto ERROR;
+ }
+
+ERROR:
+ if (f)
+ fclose(f);
+
+ // Remove temporary file
+ unlink(tmp);
+
+ return r;
+}
+
+static int pakfire_repo_write_metadata(struct pakfire_repo* repo) {
+ int r = 1;
+
+ // This can only be called for local repositories
+ if (!pakfire_repo_is_local(repo)) {
+ errno = ENOTSUP;
+ return 1;
+ }
+
+ // Fetch the base path
+ const char* path = pakfire_repo_get_path(repo);
+ if (!path)
+ return 1;
+
+ // Write the database
+ r = pakfire_repo_write_database(repo, path);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+PAKFIRE_EXPORT int pakfire_repo_compose(struct pakfire* pakfire, const char* path, int flags) {
+ struct pakfire_repo* repo = NULL;
+ int r;
+
+ // path cannot be NULL
+ if (!path) {
+ errno = EINVAL;
+ return 1;
+ }
+
+ char baseurl[PATH_MAX];
+
+ // Prefix path with file:// to form baseurl
+ r = pakfire_string_format(baseurl, "file://%s", path);
+ if (r < 0)
+ return 1;
+
+ // Create a new temporary repository at path
+ r = pakfire_repo_create(&repo, pakfire, "@tmp");
+ if (r) {
+ ERROR(pakfire, "Could not create a temporary repository: %m\n");
+ return r;
+ }
+
+ // Set baseurl to path
+ r = pakfire_repo_set_baseurl(repo, baseurl);
+ if (r) {
+ ERROR(pakfire, "Could not set baseurl %s: %m\n", baseurl);
+ goto ERROR;
+ }
+
+ // Find everything that is already part of the repository
+ r = pakfire_repo_scan(repo, 0);
+ if (r) {
+ ERROR(pakfire, "Could not refresh repository: %m\n");
+ goto ERROR;
+ }
+
+ // XXX Add more files
+
+ // Write metadata to disk
+ r = pakfire_repo_write_metadata(repo);
+ if (r)
+ goto ERROR;
+
+ // Success
+ r = 0;
+
+ERROR:
+ pakfire_repo_clear(repo);
+ pakfire_repo_unref(repo);
+
+ return r;
+}
help=_("List all currently enabled repositories"))
repolist.set_defaults(func=self._repolist)
+ # Repo
+ repo = subparsers.add_parser("repo",
+ help=_("Deal with repositories"))
+
+ repo_subparsers = repo.add_subparsers()
+
+ # repo compose
+ repo_compose = repo_subparsers.add_parser("compose",
+ help=_("Create a new repository"))
+ repo_compose.add_argument("path",
+ help=_("The path to the repository"),
+ )
+ repo_compose.add_argument("archive", nargs="+",
+ help=_("Archives to be added to this repository")
+ )
+ repo_compose.add_argument("--key",
+ help=_("Key used to sign archives"),
+ )
+ repo_compose.set_defaults(func=self._repo_compose)
+
# search
search = subparsers.add_parser("search", help=_("Search for a given pattern"))
search.add_argument("pattern", help=_("A pattern to search for"))
for repo in p.repos:
print(FORMAT % (repo.name, repo.enabled, repo.priority, len(repo)))
+ def _repo_compose(self, ns):
+ """
+ Composes a repository
+ """
+ p = self.pakfire(ns)
+ p.repo_compose(ns.path)
+
def _shell(self, ns):
"""
Open a shell in a build environment