cache: implement progress bar (ref #1170)
parent
0a13141889
commit
ade8d0b4e9
|
@ -226,7 +226,8 @@ unsigned int apk_db_get_pinning_mask_repos(struct apk_database *db, unsigned sho
|
||||||
|
|
||||||
int apk_db_cache_active(struct apk_database *db);
|
int apk_db_cache_active(struct apk_database *db);
|
||||||
int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
|
int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
|
||||||
struct apk_package *pkg, int verify);
|
struct apk_package *pkg, int verify,
|
||||||
|
apk_progress_cb cb, void *cb_ctx);
|
||||||
|
|
||||||
typedef void (*apk_cache_item_cb)(struct apk_database *db,
|
typedef void (*apk_cache_item_cb)(struct apk_database *db,
|
||||||
int dirfd, const char *name,
|
int dirfd, const char *name,
|
||||||
|
|
|
@ -98,7 +98,8 @@ struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream);
|
||||||
struct apk_bstream *apk_bstream_from_fd_pid(int fd, pid_t pid, int (*translate_status)(int));
|
struct apk_bstream *apk_bstream_from_fd_pid(int fd, pid_t pid, int (*translate_status)(int));
|
||||||
struct apk_bstream *apk_bstream_from_file(int atfd, const char *file);
|
struct apk_bstream *apk_bstream_from_file(int atfd, const char *file);
|
||||||
struct apk_bstream *apk_bstream_from_fd_url(int atfd, const char *url);
|
struct apk_bstream *apk_bstream_from_fd_url(int atfd, const char *url);
|
||||||
struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const char *to);
|
struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const char *to,
|
||||||
|
apk_progress_cb cb, void *cb_ctx);
|
||||||
|
|
||||||
static inline struct apk_bstream *apk_bstream_from_fd(int fd)
|
static inline struct apk_bstream *apk_bstream_from_fd(int fd)
|
||||||
{
|
{
|
||||||
|
|
29
src/cache.c
29
src/cache.c
|
@ -26,13 +26,26 @@
|
||||||
#define CACHE_CLEAN BIT(0)
|
#define CACHE_CLEAN BIT(0)
|
||||||
#define CACHE_DOWNLOAD BIT(1)
|
#define CACHE_DOWNLOAD BIT(1)
|
||||||
|
|
||||||
|
struct progress {
|
||||||
|
size_t done, total;
|
||||||
|
int flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void progress_cb(void *ctx, size_t bytes_done)
|
||||||
|
{
|
||||||
|
struct progress *prog = (struct progress *) ctx;
|
||||||
|
apk_print_progress(muldiv(100, prog->done + bytes_done, prog->total) | prog->flags);
|
||||||
|
prog->flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int cache_download(struct apk_database *db)
|
static int cache_download(struct apk_database *db)
|
||||||
{
|
{
|
||||||
struct apk_changeset changeset = {};
|
struct apk_changeset changeset = {};
|
||||||
struct apk_change *change;
|
struct apk_change *change;
|
||||||
struct apk_package *pkg;
|
struct apk_package *pkg;
|
||||||
struct apk_repository *repo;
|
struct apk_repository *repo;
|
||||||
int i, r, ret = 0;
|
struct progress prog = { 0, 0 };
|
||||||
|
int r, ret = 0;
|
||||||
|
|
||||||
r = apk_solver_solve(db, 0, db->world, &changeset);
|
r = apk_solver_solve(db, 0, db->world, &changeset);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
@ -40,8 +53,13 @@ static int cache_download(struct apk_database *db)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < changeset.changes->num; i++) {
|
foreach_array_item(change, changeset.changes) {
|
||||||
change = &changeset.changes->item[i];
|
pkg = change->new_pkg;
|
||||||
|
if ((pkg != NULL) && !(pkg->repos & db->local_repos))
|
||||||
|
prog.total += pkg->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach_array_item(change, changeset.changes) {
|
||||||
pkg = change->new_pkg;
|
pkg = change->new_pkg;
|
||||||
if ((pkg == NULL) || (pkg->repos & db->local_repos))
|
if ((pkg == NULL) || (pkg->repos & db->local_repos))
|
||||||
continue;
|
continue;
|
||||||
|
@ -50,11 +68,14 @@ static int cache_download(struct apk_database *db)
|
||||||
if (repo == NULL)
|
if (repo == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r = apk_cache_download(db, repo, pkg, APK_SIGN_VERIFY_IDENTITY);
|
prog.flags = APK_PRINT_PROGRESS_FORCE;
|
||||||
|
r = apk_cache_download(db, repo, pkg, APK_SIGN_VERIFY_IDENTITY,
|
||||||
|
progress_cb, &prog);
|
||||||
if (r) {
|
if (r) {
|
||||||
apk_error(PKG_VER_FMT ": %s", PKG_VER_PRINTF(pkg), apk_error_str(r));
|
apk_error(PKG_VER_FMT ": %s", PKG_VER_PRINTF(pkg), apk_error_str(r));
|
||||||
ret++;
|
ret++;
|
||||||
}
|
}
|
||||||
|
prog.done += pkg->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -122,6 +122,7 @@ struct progress {
|
||||||
struct apk_stats done;
|
struct apk_stats done;
|
||||||
struct apk_stats total;
|
struct apk_stats total;
|
||||||
struct apk_package *pkg;
|
struct apk_package *pkg;
|
||||||
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void progress_cb(void *ctx, size_t pkg_percent)
|
static void progress_cb(void *ctx, size_t pkg_percent)
|
||||||
|
@ -137,9 +138,8 @@ static void progress_cb(void *ctx, size_t pkg_percent)
|
||||||
prog->total.bytes + prog->total.packages);
|
prog->total.bytes + prog->total.packages);
|
||||||
else
|
else
|
||||||
percent = 0;
|
percent = 0;
|
||||||
if (pkg_percent == 0)
|
apk_print_progress(percent | prog->flags);
|
||||||
percent |= APK_PRINT_PROGRESS_FORCE;
|
prog->flags = 0;
|
||||||
apk_print_progress(percent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dump_packages(struct apk_changeset *changeset,
|
static int dump_packages(struct apk_changeset *changeset,
|
||||||
|
@ -298,6 +298,7 @@ int apk_solver_commit_changeset(struct apk_database *db,
|
||||||
|
|
||||||
if (print_change(db, change, prog.done.changes, prog.total.changes)) {
|
if (print_change(db, change, prog.done.changes, prog.total.changes)) {
|
||||||
prog.pkg = change->new_pkg;
|
prog.pkg = change->new_pkg;
|
||||||
|
prog.flags = APK_PRINT_PROGRESS_FORCE;
|
||||||
progress_cb(&prog, 0);
|
progress_cb(&prog, 0);
|
||||||
|
|
||||||
if (!(apk_flags & APK_SIMULATE)) {
|
if (!(apk_flags & APK_SIMULATE)) {
|
||||||
|
|
|
@ -624,7 +624,8 @@ int apk_repo_format_item(struct apk_database *db, struct apk_repository *repo, s
|
||||||
}
|
}
|
||||||
|
|
||||||
int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
|
int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
|
||||||
struct apk_package *pkg, int verify)
|
struct apk_package *pkg, int verify,
|
||||||
|
apk_progress_cb cb, void *cb_ctx)
|
||||||
{
|
{
|
||||||
struct apk_istream *is;
|
struct apk_istream *is;
|
||||||
struct apk_bstream *bs;
|
struct apk_bstream *bs;
|
||||||
|
@ -651,10 +652,13 @@ int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
|
||||||
if (apk_flags & APK_SIMULATE)
|
if (apk_flags & APK_SIMULATE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (cb)
|
||||||
|
cb(cb_ctx, 0);
|
||||||
|
|
||||||
if (verify != APK_SIGN_NONE) {
|
if (verify != APK_SIGN_NONE) {
|
||||||
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd);
|
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd);
|
||||||
bs = apk_bstream_from_url(url);
|
bs = apk_bstream_from_url(url);
|
||||||
bs = apk_bstream_tee(bs, db->cache_fd, tmpcacheitem);
|
bs = apk_bstream_tee(bs, db->cache_fd, tmpcacheitem, cb, cb_ctx);
|
||||||
is = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &sctx);
|
is = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &sctx);
|
||||||
r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, FALSE, &db->id_cache);
|
r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, FALSE, &db->id_cache);
|
||||||
apk_sign_ctx_free(&sctx);
|
apk_sign_ctx_free(&sctx);
|
||||||
|
@ -662,7 +666,7 @@ int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
|
||||||
is = apk_istream_from_url(url);
|
is = apk_istream_from_url(url);
|
||||||
fd = openat(db->cache_fd, tmpcacheitem, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
|
fd = openat(db->cache_fd, tmpcacheitem, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
r = apk_istream_splice(is, fd, APK_SPLICE_ALL, NULL, NULL);
|
r = apk_istream_splice(is, fd, APK_SPLICE_ALL, cb, cb_ctx);
|
||||||
close(fd);
|
close(fd);
|
||||||
} else {
|
} else {
|
||||||
r = -errno;
|
r = -errno;
|
||||||
|
@ -1977,7 +1981,7 @@ static int apk_repository_update(struct apk_database *db, struct apk_repository
|
||||||
{
|
{
|
||||||
int r, verify = (apk_flags & APK_ALLOW_UNTRUSTED) ? APK_SIGN_NONE : APK_SIGN_VERIFY;
|
int r, verify = (apk_flags & APK_ALLOW_UNTRUSTED) ? APK_SIGN_NONE : APK_SIGN_VERIFY;
|
||||||
|
|
||||||
r = apk_cache_download(db, repo, NULL, verify);
|
r = apk_cache_download(db, repo, NULL, verify, NULL, NULL);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
apk_error("%s: %s", repo->url, apk_error_str(r));
|
apk_error("%s: %s", repo->url, apk_error_str(r));
|
||||||
|
|
||||||
|
@ -2568,7 +2572,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
||||||
apk_blob_t b = APK_BLOB_BUF(tmpcacheitem);
|
apk_blob_t b = APK_BLOB_BUF(tmpcacheitem);
|
||||||
apk_blob_push_blob(&b, tmpprefix);
|
apk_blob_push_blob(&b, tmpprefix);
|
||||||
apk_pkg_format_cache_pkg(b, pkg);
|
apk_pkg_format_cache_pkg(b, pkg);
|
||||||
bs = apk_bstream_tee(bs, db->cache_fd, tmpcacheitem);
|
bs = apk_bstream_tee(bs, db->cache_fd, tmpcacheitem, NULL, NULL);
|
||||||
if (bs == NULL) {
|
if (bs == NULL) {
|
||||||
action = "unable cache package: ";
|
action = "unable cache package: ";
|
||||||
r = -errno;
|
r = -errno;
|
||||||
|
|
11
src/io.c
11
src/io.c
|
@ -385,6 +385,8 @@ struct apk_tee_bstream {
|
||||||
struct apk_bstream *inner_bs;
|
struct apk_bstream *inner_bs;
|
||||||
int fd;
|
int fd;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
apk_progress_cb cb;
|
||||||
|
void *cb_ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
static apk_blob_t tee_read(void *stream, apk_blob_t token)
|
static apk_blob_t tee_read(void *stream, apk_blob_t token)
|
||||||
|
@ -394,8 +396,11 @@ static apk_blob_t tee_read(void *stream, apk_blob_t token)
|
||||||
apk_blob_t blob;
|
apk_blob_t blob;
|
||||||
|
|
||||||
blob = tbs->inner_bs->read(tbs->inner_bs, token);
|
blob = tbs->inner_bs->read(tbs->inner_bs, token);
|
||||||
if (!APK_BLOB_IS_NULL(blob))
|
if (!APK_BLOB_IS_NULL(blob)) {
|
||||||
tbs->size += write(tbs->fd, blob.ptr, blob.len);
|
tbs->size += write(tbs->fd, blob.ptr, blob.len);
|
||||||
|
if (tbs->cb)
|
||||||
|
tbs->cb(tbs->cb_ctx, tbs->size);
|
||||||
|
}
|
||||||
|
|
||||||
return blob;
|
return blob;
|
||||||
}
|
}
|
||||||
|
@ -412,7 +417,7 @@ static void tee_close(void *stream, size_t *size)
|
||||||
free(tbs);
|
free(tbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const char *to)
|
struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const char *to, apk_progress_cb cb, void *cb_ctx)
|
||||||
{
|
{
|
||||||
struct apk_tee_bstream *tbs;
|
struct apk_tee_bstream *tbs;
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -435,6 +440,8 @@ struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const ch
|
||||||
tbs->inner_bs = from;
|
tbs->inner_bs = from;
|
||||||
tbs->fd = fd;
|
tbs->fd = fd;
|
||||||
tbs->size = 0;
|
tbs->size = 0;
|
||||||
|
tbs->cb = cb;
|
||||||
|
tbs->cb_ctx = cb_ctx;
|
||||||
|
|
||||||
return &tbs->bs;
|
return &tbs->bs;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue