summaryrefslogtreecommitdiff
path: root/src/import/import-dkr.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-01-23 01:16:31 +0100
committerLennart Poettering <lennart@poettering.net>2015-01-23 01:17:55 +0100
commit7079cfeffb6d520f20ddff53fd78467e72e6cc94 (patch)
tree4762322f62febd444e01def3e6bfb771d2887422 /src/import/import-dkr.c
parenta92ccc5ba22ec40fee560a46c478321d1c5df5af (diff)
importd: when listing transfers, show progress percentage
With this change the pull protocol implementation processes will pass progress data to importd which then passes this information on via the bus. We use sd_notify() as generic transport for this communication, making importd listen to them, while matching the incoming messages to the right transfer.
Diffstat (limited to 'src/import/import-dkr.c')
-rw-r--r--src/import/import-dkr.c88
1 files changed, 86 insertions, 2 deletions
diff --git a/src/import/import-dkr.c b/src/import/import-dkr.c
index 24ba766b13..78ea80846c 100644
--- a/src/import/import-dkr.c
+++ b/src/import/import-dkr.c
@@ -22,7 +22,7 @@
#include <curl/curl.h>
#include <sys/prctl.h>
-#include "set.h"
+#include "sd-daemon.h"
#include "json.h"
#include "strv.h"
#include "btrfs-util.h"
@@ -35,6 +35,14 @@
#include "import-common.h"
#include "import-dkr.h"
+typedef enum DkrProgress {
+ DKR_SEARCHING,
+ DKR_RESOLVING,
+ DKR_METADATA,
+ DKR_DOWNLOADING,
+ DKR_COPYING,
+} DkrProgress;
+
struct DkrImport {
sd_event *event;
CurlGlue *glue;
@@ -56,6 +64,7 @@ struct DkrImport {
char **response_registries;
char **ancestry;
+ unsigned n_ancestry;
unsigned current_ancestry;
DkrImportFinished on_finished;
@@ -176,6 +185,53 @@ int dkr_import_new(
return 0;
}
+static void dkr_import_report_progress(DkrImport *i, DkrProgress p) {
+ unsigned percent;
+
+ assert(i);
+
+ switch (p) {
+
+ case DKR_SEARCHING:
+ percent = 0;
+ if (i->images_job)
+ percent += i->images_job->progress_percent * 5 / 100;
+ break;
+
+ case DKR_RESOLVING:
+ percent = 5;
+ if (i->tags_job)
+ percent += i->tags_job->progress_percent * 5 / 100;
+ break;
+
+ case DKR_METADATA:
+ percent = 10;
+ if (i->ancestry_job)
+ percent += i->ancestry_job->progress_percent * 5 / 100;
+ if (i->json_job)
+ percent += i->json_job->progress_percent * 5 / 100;
+ break;
+
+ case DKR_DOWNLOADING:
+ percent = 20;
+ percent += 75 * i->current_ancestry / MAX(1U, i->n_ancestry);
+ if (i->layer_job)
+ percent += i->layer_job->progress_percent * 75 / MAX(1U, i->n_ancestry) / 100;
+
+ break;
+
+ case DKR_COPYING:
+ percent = 95;
+ break;
+
+ default:
+ assert_not_reached("Unknown progress state");
+ }
+
+ sd_notifyf(false, "X_IMPORT_PROGRESS=%u", percent);
+ log_debug("Combined progress %u%%", percent);
+}
+
static int parse_id(const void *payload, size_t size, char **ret) {
_cleanup_free_ char *buf = NULL, *id = NULL, *other = NULL;
union json_value v = {};
@@ -438,6 +494,22 @@ static int dkr_import_job_on_open_disk(ImportJob *j) {
return 0;
}
+static void dkr_import_job_on_progress(ImportJob *j) {
+ DkrImport *i;
+
+ assert(j);
+ assert(j->userdata);
+
+ i = j->userdata;
+
+ dkr_import_report_progress(
+ i,
+ j == i->images_job ? DKR_SEARCHING :
+ j == i->tags_job ? DKR_RESOLVING :
+ j == i->ancestry_job || j == i->json_job ? DKR_METADATA :
+ DKR_DOWNLOADING);
+}
+
static int dkr_import_pull_layer(DkrImport *i) {
_cleanup_free_ char *path = NULL;
const char *url, *layer = NULL;
@@ -488,6 +560,7 @@ static int dkr_import_pull_layer(DkrImport *i) {
i->layer_job->on_finished = dkr_import_job_on_finished;
i->layer_job->on_open_disk = dkr_import_job_on_open_disk;
+ i->layer_job->on_progress = dkr_import_job_on_progress;
r = import_job_begin(i->layer_job);
if (r < 0)
@@ -535,6 +608,7 @@ static void dkr_import_job_on_finished(ImportJob *j) {
}
log_info("Index lookup succeeded, directed to registry %s.", i->response_registries[0]);
+ dkr_import_report_progress(i, DKR_RESOLVING);
url = strappenda(PROTOCOL_PREFIX, i->response_registries[0], "/v1/repositories/", i->name, "/tags/", i->tag);
r = import_job_new(&i->tags_job, url, i->glue, i);
@@ -550,6 +624,7 @@ static void dkr_import_job_on_finished(ImportJob *j) {
}
i->tags_job->on_finished = dkr_import_job_on_finished;
+ i->tags_job->on_progress = dkr_import_job_on_progress;
r = import_job_begin(i->tags_job);
if (r < 0) {
@@ -575,6 +650,7 @@ static void dkr_import_job_on_finished(ImportJob *j) {
i->id = id;
log_info("Tag lookup succeeded, resolved to layer %s.", i->id);
+ dkr_import_report_progress(i, DKR_METADATA);
url = strappenda(PROTOCOL_PREFIX, i->response_registries[0], "/v1/images/", i->id, "/ancestry");
r = import_job_new(&i->ancestry_job, url, i->glue, i);
@@ -590,6 +666,7 @@ static void dkr_import_job_on_finished(ImportJob *j) {
}
i->ancestry_job->on_finished = dkr_import_job_on_finished;
+ i->ancestry_job->on_progress = dkr_import_job_on_progress;
url = strappenda(PROTOCOL_PREFIX, i->response_registries[0], "/v1/images/", i->id, "/json");
r = import_job_new(&i->json_job, url, i->glue, i);
@@ -605,6 +682,7 @@ static void dkr_import_job_on_finished(ImportJob *j) {
}
i->json_job->on_finished = dkr_import_job_on_finished;
+ i->json_job->on_progress = dkr_import_job_on_progress;
r = import_job_begin(i->ancestry_job);
if (r < 0) {
@@ -644,8 +722,11 @@ static void dkr_import_job_on_finished(ImportJob *j) {
strv_free(i->ancestry);
i->ancestry = ancestry;
-
+ i->n_ancestry = n;
i->current_ancestry = 0;
+
+ dkr_import_report_progress(i, DKR_DOWNLOADING);
+
r = dkr_import_pull_layer(i);
if (r < 0)
goto finish;
@@ -699,6 +780,8 @@ static void dkr_import_job_on_finished(ImportJob *j) {
if (!dkr_import_is_done(i))
return;
+ dkr_import_report_progress(i, DKR_COPYING);
+
r = dkr_import_make_local_copy(i);
if (r < 0)
goto finish;
@@ -802,6 +885,7 @@ int dkr_import_pull(DkrImport *i, const char *name, const char *tag, const char
i->images_job->on_finished = dkr_import_job_on_finished;
i->images_job->on_header = dkr_import_job_on_header;
+ i->images_job->on_progress = dkr_import_job_on_progress;
return import_job_begin(i->images_job);
}