Implemented "New repository scheme and configuration file" from issue 16.

This commit is contained in:
Juan RP 2011-11-07 20:28:35 +01:00
parent 27c5138324
commit 662b5acc08
8 changed files with 108 additions and 133 deletions

6
NEWS
View File

@ -1,5 +1,11 @@
xbps-0.11.0 (???): xbps-0.11.0 (???):
* Implemented "New repository scheme and configuration file" from issue 16.
The plist index file has been renamed to "index.plist", version bumped
to 1.3. The configuration file (repositories.plist) now expect the full
path to the directory storing the index.plist file. This will allow us
to use other directories (such as non-free, or alike) for such purpose.
* libxbps: improve xbps_purge_pkg() in case that the process was * libxbps: improve xbps_purge_pkg() in case that the process was
unexpectedly interrupted, do not error out unless the unregister unexpectedly interrupted, do not error out unless the unregister
phase return an error value. phase return an error value.

View File

@ -36,9 +36,6 @@
#include <xbps_api.h> #include <xbps_api.h>
#include "defs.h" #include "defs.h"
/* Array of valid architectures */
static const char *archdirs[] = { "i686", "x86_64", "noarch", NULL };
/* /*
* Removes stalled pkg entries in repository's pkg-index.plist file, if any * Removes stalled pkg entries in repository's pkg-index.plist file, if any
* binary package cannot be read (unavailable, not enough perms, etc). * binary package cannot be read (unavailable, not enough perms, etc).
@ -48,7 +45,7 @@ remove_missing_binpkg_entries(const char *repodir)
{ {
prop_array_t pkgarray; prop_array_t pkgarray;
prop_dictionary_t idxd, pkgd; prop_dictionary_t idxd, pkgd;
const char *arch, *filen; const char *filen;
char *binpkg, *plist; char *binpkg, *plist;
size_t i; size_t i;
int rv = 0; int rv = 0;
@ -77,9 +74,8 @@ again:
for (i = 0; i < prop_array_count(pkgarray); i++) { for (i = 0; i < prop_array_count(pkgarray); i++) {
pkgd = prop_array_get(pkgarray, i); pkgd = prop_array_get(pkgarray, i);
prop_dictionary_get_cstring_nocopy(pkgd, "architecture", &arch);
prop_dictionary_get_cstring_nocopy(pkgd, "filename", &filen); prop_dictionary_get_cstring_nocopy(pkgd, "filename", &filen);
binpkg = xbps_xasprintf("%s/%s/%s", repodir, arch, filen); binpkg = xbps_xasprintf("%s/%s", repodir, filen);
if (binpkg == NULL) { if (binpkg == NULL) {
errno = ENOMEM; errno = ENOMEM;
rv = -1; rv = -1;
@ -321,16 +317,11 @@ repo_genindex(const char *pkgdir)
prop_dictionary_t idxdict = NULL; prop_dictionary_t idxdict = NULL;
struct dirent *dp; struct dirent *dp;
DIR *dirp; DIR *dirp;
struct utsname un;
uint64_t npkgcnt = 0; uint64_t npkgcnt = 0;
char *binfile, *path, *plist; char *binfile, *plist;
size_t i;
int rv = 0; int rv = 0;
bool registered_newpkgs = false, foundpkg = false; bool registered_newpkgs = false, foundpkg = false;
if (uname(&un) == -1)
return errno;
/* /*
* Create or read existing package index plist file. * Create or read existing package index plist file.
*/ */
@ -343,74 +334,43 @@ repo_genindex(const char *pkgdir)
prop_object_release(idxdict); prop_object_release(idxdict);
return errno; return errno;
} }
/*
* Iterate over the known architecture directories to find dirp = opendir(pkgdir);
* binary packages. if (dirp == NULL) {
*/ xbps_error_printf("xbps-repo: cannot open `%s': %s\n",
for (i = 0; archdirs[i] != NULL; i++) { pkgdir, strerror(errno));
if ((strcmp(archdirs[i], un.machine)) && exit(EXIT_FAILURE);
(strcmp(archdirs[i], "noarch"))) }
while ((dp = readdir(dirp)) != NULL) {
if ((strcmp(dp->d_name, ".") == 0) ||
(strcmp(dp->d_name, "..") == 0))
continue; continue;
path = xbps_xasprintf("%s/%s", pkgdir, archdirs[i]); /* Ignore unknown files */
if (path == NULL) { if (strstr(dp->d_name, ".xbps") == NULL)
continue;
foundpkg = true;
binfile = xbps_xasprintf("%s/%s", pkgdir, dp->d_name);
if (binfile == NULL) {
(void)closedir(dirp);
rv = errno; rv = errno;
goto out; goto out;
} }
/* rv = add_binpkg_to_index(idxdict, pkgdir, binfile);
* If repo/<noarch|un.machine> does not exist, free(binfile);
* create it. if (rv == EEXIST) {
*/ rv = 0;
if ((access(path, X_OK) == -1) && errno == ENOENT) {
if (xbps_mkpath(path, 0755) == -1) {
xbps_error_printf("xbps-repo: cannot "
"create %s directory: %s\n",
path, strerror(errno));
return -1;
}
}
dirp = opendir(path);
if (dirp == NULL) {
xbps_error_printf("xbps-repo: unexistent '%s' "
"directory!\n", path);
free(path);
continue; continue;
} }
else if (rv != 0) {
while ((dp = readdir(dirp)) != NULL) { (void)closedir(dirp);
if ((strcmp(dp->d_name, ".") == 0) || goto out;
(strcmp(dp->d_name, "..") == 0))
continue;
/* Ignore unknown files */
if (strstr(dp->d_name, ".xbps") == NULL)
continue;
foundpkg = true;
binfile = xbps_xasprintf("%s/%s", path, dp->d_name);
if (binfile == NULL) {
(void)closedir(dirp);
free(path);
rv = errno;
goto out;
}
rv = add_binpkg_to_index(idxdict, path, binfile);
free(binfile);
if (rv == EEXIST) {
rv = 0;
continue;
}
else if (rv != 0) {
(void)closedir(dirp);
free(path);
goto out;
}
registered_newpkgs = true;
} }
(void)closedir(dirp); registered_newpkgs = true;
free(path);
} }
(void)closedir(dirp);
if (foundpkg == false) { if (foundpkg == false) {
/* No packages were found in directory */ /* No packages were found in directory */

View File

@ -2,24 +2,24 @@
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<array> <array>
<!-- You can specify here your list of repositories, <!--
the first repository that contains a package will You can specify here your list of repositories, the first
be used for most targets in xbps-bin(8) and repository that contains a package will be used for most
xbps-repo(8), with the exception for updating targets in xbps-bin(8) and xbps-repo(8), with the exception
on which all repositories will be looked at and for updating on which all repositories will be looked at and
the newest version will be choosen. the newest version will be choosen.
Optionally a non default HTTP port can also be
specified like that:
Optionally a non default HTTP port can also be specified such as:
http://foo.local:8080/xbps-repo http://foo.local:8080/xbps-repo
The order matters, and the top-most matching a package The order matters, and the top-most matching a package pattern
pattern or name will be used. or name will be used.
By default we use the official "public" repositories. By default we use the official "public" repositories. You can add
you can add your own local repositories by specifying your own repositories by specifying the path (without the trailing
the path to the directory. --> '/' character) to the directory where the index.plist file is stored.
<string>http://xbps.nopcode.org/repos/current</string> -->
<string>http://xbps.nopcode.org/repos/current/x86_64</string>
<string>http://xbps.nopcode.org/repos/current/noarch</string>
</array> </array>
</plist> </plist>

View File

@ -53,9 +53,9 @@
* @def XBPS_PKGINDEX_VERSION * @def XBPS_PKGINDEX_VERSION
* Current version for the repository package index format. * Current version for the repository package index format.
*/ */
#define XBPS_PKGINDEX_VERSION "1.2" #define XBPS_PKGINDEX_VERSION "1.3"
#define XBPS_API_VERSION "20111031-1" #define XBPS_API_VERSION "20111107"
#define XBPS_VERSION "0.11.0" #define XBPS_VERSION "0.11.0"
/** /**
@ -100,7 +100,7 @@
* @def XBPS_PKGINDEX * @def XBPS_PKGINDEX
* Filename for the repository package index property list. * Filename for the repository package index property list.
*/ */
#define XBPS_PKGINDEX "pkg-index.plist" #define XBPS_PKGINDEX "index.plist"
/** /**
* @def XBPS_SYSCONF_PATH * @def XBPS_SYSCONF_PATH

View File

@ -157,7 +157,7 @@ xbps_init(struct xbps_handle *xh)
prop_string_cstring_nocopy(repofile)); prop_string_cstring_nocopy(repofile));
xbps_dbg_printf("fetch_cache_conn: %zu\n", xbps_dbg_printf("fetch_cache_conn: %zu\n",
fetch_cache_conn); fetch_cache_conn);
xbps_dbg_printf("fetch_cacche_conn_host: %zu\n", xbps_dbg_printf("fetch_cache_conn_host: %zu\n",
fetch_cache_conn_host); fetch_cache_conn_host);
xbps_dbg_printf("fetch_timeout: %zu\n", xbps_dbg_printf("fetch_timeout: %zu\n",
xhp->fetch_timeout); xhp->fetch_timeout);

View File

@ -23,6 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <sys/utsname.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
@ -47,11 +48,6 @@ static SIMPLEQ_HEAD(rpool_head, repository_pool) rpool_queue =
static bool repolist_initialized; static bool repolist_initialized;
#define FETCH_ERROR(x) ((x == FETCH_UNAVAIL) || \
(x == FETCH_NETWORK) || \
(x == FETCH_ABORT) || \
(x == FETCH_TIMEOUT) || \
(x == FETCH_DOWN))
static int static int
sync_remote_repo(const char *plist, const char *repourl) sync_remote_repo(const char *plist, const char *repourl)
{ {
@ -60,14 +56,36 @@ sync_remote_repo(const char *plist, const char *repourl)
return 0; return 0;
/* file not found, fetch it */ /* file not found, fetch it */
if (xbps_repository_sync_pkg_index(repourl) == -1) { if (xbps_repository_sync_pkg_index(repourl) == -1)
if (FETCH_ERROR(fetchLastErrCode)) return -1;
return -1;
}
return 0; return 0;
} }
#undef FETCH_ERROR
/*
* Returns true if repository URI contains "noarch" or matching architecture
* in last component, false otherwise.
*/
static bool
check_repo_arch(const char *uri)
{
struct utsname un;
char *p;
uname(&un);
p = strrchr(uri, '/');
if (p == NULL)
return false;
p++;
if (*p == '\0')
return false;
else if (strcmp(p, "noarch") == 0)
return true;
else if (strcmp(p, un.machine) == 0)
return true;
return false;
}
int HIDDEN int HIDDEN
xbps_repository_pool_init(void) xbps_repository_pool_init(void)
@ -113,20 +131,33 @@ xbps_repository_pool_init(void)
if (duprepo) if (duprepo)
continue; continue;
ntotal++;
/*
* Check if repository doesn't match our architecture.
*/
if (!check_repo_arch(repouri)) {
xbps_dbg_printf("[rpool] `%s' arch not matched, "
"ignoring.\n", repouri);
nmissing++;
continue;
}
plist = xbps_pkg_index_plist(repouri); plist = xbps_pkg_index_plist(repouri);
if (plist == NULL) { if (plist == NULL) {
rv = errno; rv = errno;
goto out; goto out;
} }
ntotal++; /*
* If it's a remote repository and index file is not available,
* fetch it for the first time.
*/
if (sync_remote_repo(plist, repouri) == -1) { if (sync_remote_repo(plist, repouri) == -1) {
nmissing++; nmissing++;
free(plist); free(plist);
continue; continue;
} }
/* /*
* Iterate over the repository pool and add the dictionary * Internalize repository's index dictionary and add it
* for current repository into the queue. * into the queue.
*/ */
rpool = malloc(sizeof(struct repository_pool)); rpool = malloc(sizeof(struct repository_pool));
if (rpool == NULL) { if (rpool == NULL) {

View File

@ -23,7 +23,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <sys/utsname.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -56,11 +55,11 @@ xbps_get_remote_repo_string(const char *uri)
* Replace '.' ':' and '/' characters with underscores, so that * Replace '.' ':' and '/' characters with underscores, so that
* provided URL: * provided URL:
* *
* http://nocturno.local:8080/blah/xbps/binpkg-repo * http://nocturno.local:8080/repo/x86_64
* *
* becomes: * becomes:
* *
* http___nocturno_local_8080_blah_xbps_binpkg_repo * http___nocturno_local_8080_repo_x86_64
* *
*/ */
if (url->port != 0) if (url->port != 0)
@ -92,12 +91,11 @@ xbps_repository_sync_pkg_index(const char *uri)
prop_dictionary_t tmpd; prop_dictionary_t tmpd;
struct xbps_handle *xhp; struct xbps_handle *xhp;
struct url *url = NULL; struct url *url = NULL;
struct utsname un;
struct stat st; struct stat st;
const char *fetch_outputdir; const char *fetch_outputdir;
char *rpidx, *lrepodir, *uri_fixedp; char *rpidx, *lrepodir, *uri_fixedp;
char *metadir, *tmp_metafile, *lrepofile; char *metadir, *tmp_metafile, *lrepofile;
int sverrno, rv = 0; int rv = 0;
bool only_sync = false; bool only_sync = false;
assert(uri != NULL); assert(uri != NULL);
@ -108,9 +106,6 @@ xbps_repository_sync_pkg_index(const char *uri)
if (!xbps_check_is_repository_uri_remote(uri)) if (!xbps_check_is_repository_uri_remote(uri))
return 0; return 0;
if (uname(&un) == -1)
return -1;
if ((url = fetchParseURL(uri)) == NULL) if ((url = fetchParseURL(uri)) == NULL)
return -1; return -1;
@ -119,7 +114,6 @@ xbps_repository_sync_pkg_index(const char *uri)
fetchFreeURL(url); fetchFreeURL(url);
return -1; return -1;
} }
/* /*
* Create metadir if necessary. * Create metadir if necessary.
*/ */
@ -137,7 +131,7 @@ xbps_repository_sync_pkg_index(const char *uri)
/* /*
* Remote repository pkg-index.plist full URL. * Remote repository pkg-index.plist full URL.
*/ */
rpidx = xbps_xasprintf("%s/%s/%s", uri, un.machine, XBPS_PKGINDEX); rpidx = xbps_xasprintf("%s/%s", uri, XBPS_PKGINDEX);
if (rpidx == NULL) { if (rpidx == NULL) {
rv = -1; rv = -1;
goto out; goto out;
@ -181,20 +175,13 @@ xbps_repository_sync_pkg_index(const char *uri)
* Download pkg-index.plist file from repository. * Download pkg-index.plist file from repository.
*/ */
if (xbps_fetch_file(rpidx, fetch_outputdir, true, NULL) == -1) { if (xbps_fetch_file(rpidx, fetch_outputdir, true, NULL) == -1) {
sverrno = errno;
if (fetchLastErrCode)
rv = fetchLastErrCode;
else
rv = sverrno;
if (xhp->xbps_transaction_err_cb) { if (xhp->xbps_transaction_err_cb) {
xhp->xtcd->state = XBPS_TRANS_STATE_REPOSYNC; xhp->xtcd->state = XBPS_TRANS_STATE_REPOSYNC;
xhp->xtcd->repourl = uri; xhp->xtcd->repourl = uri;
xhp->xtcd->err = rv; xhp->xtcd->err = fetchLastErrCode;
xhp->xbps_transaction_err_cb(xhp->xtcd); xhp->xbps_transaction_err_cb(xhp->xtcd);
} }
rv = -1; rv = -1;
errno = sverrno;
goto out; goto out;
} }
if (only_sync) if (only_sync)

View File

@ -34,7 +34,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <ctype.h> #include <ctype.h>
#include <sys/utsname.h>
#include "config.h" #include "config.h"
#include "xbps_api_impl.h" #include "xbps_api_impl.h"
@ -227,24 +226,19 @@ get_pkg_index_remote_plist(const char *uri)
char * char *
xbps_pkg_index_plist(const char *uri) xbps_pkg_index_plist(const char *uri)
{ {
struct utsname un;
assert(uri != NULL); assert(uri != NULL);
if (uname(&un) == -1)
return NULL;
if (xbps_check_is_repository_uri_remote(uri)) if (xbps_check_is_repository_uri_remote(uri))
return get_pkg_index_remote_plist(uri); return get_pkg_index_remote_plist(uri);
return xbps_xasprintf("%s/%s/%s", uri, un.machine, XBPS_PKGINDEX); return xbps_xasprintf("%s/%s", uri, XBPS_PKGINDEX);
} }
char * char *
xbps_path_from_repository_uri(prop_dictionary_t pkg_repod, const char *repoloc) xbps_path_from_repository_uri(prop_dictionary_t pkg_repod, const char *repoloc)
{ {
struct xbps_handle *xhp; struct xbps_handle *xhp;
const char *filen, *arch; const char *filen;
char *lbinpkg = NULL; char *lbinpkg = NULL;
assert(prop_object_type(pkg_repod) == PROP_TYPE_DICTIONARY); assert(prop_object_type(pkg_repod) == PROP_TYPE_DICTIONARY);
@ -253,9 +247,6 @@ xbps_path_from_repository_uri(prop_dictionary_t pkg_repod, const char *repoloc)
if (!prop_dictionary_get_cstring_nocopy(pkg_repod, if (!prop_dictionary_get_cstring_nocopy(pkg_repod,
"filename", &filen)) "filename", &filen))
return NULL; return NULL;
if (!prop_dictionary_get_cstring_nocopy(pkg_repod,
"architecture", &arch))
return NULL;
xhp = xbps_handle_get(); xhp = xbps_handle_get();
/* /*
@ -273,7 +264,7 @@ xbps_path_from_repository_uri(prop_dictionary_t pkg_repod, const char *repoloc)
/* /*
* Local and remote repositories use the same path. * Local and remote repositories use the same path.
*/ */
return xbps_xasprintf("%s/%s/%s", repoloc, arch, filen); return xbps_xasprintf("%s/%s", repoloc, filen);
} }
bool bool