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 (???):
* 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
unexpectedly interrupted, do not error out unless the unregister
phase return an error value.

View File

@ -36,9 +36,6 @@
#include <xbps_api.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
* 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_dictionary_t idxd, pkgd;
const char *arch, *filen;
const char *filen;
char *binpkg, *plist;
size_t i;
int rv = 0;
@ -77,9 +74,8 @@ again:
for (i = 0; i < prop_array_count(pkgarray); i++) {
pkgd = prop_array_get(pkgarray, i);
prop_dictionary_get_cstring_nocopy(pkgd, "architecture", &arch);
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) {
errno = ENOMEM;
rv = -1;
@ -321,16 +317,11 @@ repo_genindex(const char *pkgdir)
prop_dictionary_t idxdict = NULL;
struct dirent *dp;
DIR *dirp;
struct utsname un;
uint64_t npkgcnt = 0;
char *binfile, *path, *plist;
size_t i;
char *binfile, *plist;
int rv = 0;
bool registered_newpkgs = false, foundpkg = false;
if (uname(&un) == -1)
return errno;
/*
* Create or read existing package index plist file.
*/
@ -343,74 +334,43 @@ repo_genindex(const char *pkgdir)
prop_object_release(idxdict);
return errno;
}
/*
* Iterate over the known architecture directories to find
* binary packages.
*/
for (i = 0; archdirs[i] != NULL; i++) {
if ((strcmp(archdirs[i], un.machine)) &&
(strcmp(archdirs[i], "noarch")))
dirp = opendir(pkgdir);
if (dirp == NULL) {
xbps_error_printf("xbps-repo: cannot open `%s': %s\n",
pkgdir, strerror(errno));
exit(EXIT_FAILURE);
}
while ((dp = readdir(dirp)) != NULL) {
if ((strcmp(dp->d_name, ".") == 0) ||
(strcmp(dp->d_name, "..") == 0))
continue;
path = xbps_xasprintf("%s/%s", pkgdir, archdirs[i]);
if (path == NULL) {
/* Ignore unknown files */
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;
goto out;
}
/*
* If repo/<noarch|un.machine> does not exist,
* create it.
*/
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);
rv = add_binpkg_to_index(idxdict, pkgdir, binfile);
free(binfile);
if (rv == EEXIST) {
rv = 0;
continue;
}
while ((dp = readdir(dirp)) != NULL) {
if ((strcmp(dp->d_name, ".") == 0) ||
(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;
else if (rv != 0) {
(void)closedir(dirp);
goto out;
}
(void)closedir(dirp);
free(path);
registered_newpkgs = true;
}
(void)closedir(dirp);
if (foundpkg == false) {
/* 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">
<plist version="1.0">
<array>
<!-- You can specify here your list of repositories,
the first repository that contains a package will
be used for most targets in xbps-bin(8) and
xbps-repo(8), with the exception for updating
on which all repositories will be looked at and
the newest version will be choosen.
Optionally a non default HTTP port can also be
specified like that:
<!--
You can specify here your list of repositories, the first
repository that contains a package will be used for most
targets in xbps-bin(8) and xbps-repo(8), with the exception
for updating on which all repositories will be looked at and
the newest version will be choosen.
Optionally a non default HTTP port can also be specified such as:
http://foo.local:8080/xbps-repo
The order matters, and the top-most matching a package
pattern or name will be used.
The order matters, and the top-most matching a package pattern
or name will be used.
By default we use the official "public" repositories.
you can add your own local repositories by specifying
the path to the directory. -->
<string>http://xbps.nopcode.org/repos/current</string>
By default we use the official "public" repositories. You can add
your own repositories by specifying the path (without the trailing
'/' character) to the directory where the index.plist file is stored.
-->
<string>http://xbps.nopcode.org/repos/current/x86_64</string>
<string>http://xbps.nopcode.org/repos/current/noarch</string>
</array>
</plist>

View File

@ -53,9 +53,9 @@
* @def XBPS_PKGINDEX_VERSION
* 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"
/**
@ -100,7 +100,7 @@
* @def XBPS_PKGINDEX
* Filename for the repository package index property list.
*/
#define XBPS_PKGINDEX "pkg-index.plist"
#define XBPS_PKGINDEX "index.plist"
/**
* @def XBPS_SYSCONF_PATH

View File

@ -157,7 +157,7 @@ xbps_init(struct xbps_handle *xh)
prop_string_cstring_nocopy(repofile));
xbps_dbg_printf("fetch_cache_conn: %zu\n",
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);
xbps_dbg_printf("fetch_timeout: %zu\n",
xhp->fetch_timeout);

View File

@ -23,6 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/utsname.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
@ -47,11 +48,6 @@ static SIMPLEQ_HEAD(rpool_head, repository_pool) rpool_queue =
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
sync_remote_repo(const char *plist, const char *repourl)
{
@ -60,14 +56,36 @@ sync_remote_repo(const char *plist, const char *repourl)
return 0;
/* file not found, fetch it */
if (xbps_repository_sync_pkg_index(repourl) == -1) {
if (FETCH_ERROR(fetchLastErrCode))
return -1;
}
if (xbps_repository_sync_pkg_index(repourl) == -1)
return -1;
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
xbps_repository_pool_init(void)
@ -113,20 +131,33 @@ xbps_repository_pool_init(void)
if (duprepo)
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);
if (plist == NULL) {
rv = errno;
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) {
nmissing++;
free(plist);
continue;
}
/*
* Iterate over the repository pool and add the dictionary
* for current repository into the queue.
* Internalize repository's index dictionary and add it
* into the queue.
*/
rpool = malloc(sizeof(struct repository_pool));
if (rpool == NULL) {

View File

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

View File

@ -34,7 +34,6 @@
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <sys/utsname.h>
#include "config.h"
#include "xbps_api_impl.h"
@ -227,24 +226,19 @@ get_pkg_index_remote_plist(const char *uri)
char *
xbps_pkg_index_plist(const char *uri)
{
struct utsname un;
assert(uri != NULL);
if (uname(&un) == -1)
return NULL;
if (xbps_check_is_repository_uri_remote(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 *
xbps_path_from_repository_uri(prop_dictionary_t pkg_repod, const char *repoloc)
{
struct xbps_handle *xhp;
const char *filen, *arch;
const char *filen;
char *lbinpkg = NULL;
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,
"filename", &filen))
return NULL;
if (!prop_dictionary_get_cstring_nocopy(pkg_repod,
"architecture", &arch))
return NULL;
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.
*/
return xbps_xasprintf("%s/%s/%s", repoloc, arch, filen);
return xbps_xasprintf("%s/%s", repoloc, filen);
}
bool