I figure "pull-dck" is not a good name, given that one could certainly
read the verb in a way that might be funny for 16year-olds. ;-)
Also, don't hardcode the index URL to use, make it runtime and configure
time configurable instead.
systemd_import_SOURCES = \
src/import/import.c \
systemd_import_SOURCES = \
src/import/import.c \
- src/import/import-dck.c \
- src/import/import-dck.h \
+ src/import/import-dkr.c \
+ src/import/import-dkr.h \
src/import/curl-util.c \
src/import/curl-util.h \
src/import/aufs-util.c \
src/import/curl-util.c \
src/import/curl-util.h \
src/import/aufs-util.c \
* make "machinectl login" use a new machined call AllocateMachinePty() or so to get a pty in a machine. That would open up logins to unprivileged clients
* make "machinectl login" use a new machined call AllocateMachinePty() or so to get a pty in a machine. That would open up logins to unprivileged clients
-* add transparent btrfs pool in a loopback file in /var if btrfs operations (such as systemd-import pull-dck) are used and /var is not a btrfs file system
+* add transparent btrfs pool in a loopback file in /var if btrfs operations (such as systemd-import pull-dkr) are used and /var is not a btrfs file system
* machined: open up certain commands to unprivileged clients via polkit
* machined: open up certain commands to unprivileged clients via polkit
+AC_ARG_WITH([dkr-index-url],
+ [AS_HELP_STRING([--dkr-index-url=URL], [Specify the default index URL to use for image downloads])],
+ [DEFAULT_DKR_INDEX_URL="\"$withval\""],
+ [DEFAULT_DKR_INDEX_URL="NULL"])
+
+AC_DEFINE_UNQUOTED(DEFAULT_DKR_INDEX_URL, [$DEFAULT_DKR_INDEX_URL], [Default index URL to use for image downloads])
+AC_SUBST(DEFAULT_DKR_INDEX_URL)
+
AS_IF([test "x${enable_split_usr}" = "xyes"], [
AC_DEFINE(HAVE_SPLIT_USR, 1, [Define if /bin, /sbin aren't symlinks into /usr])
])
AS_IF([test "x${enable_split_usr}" = "xyes"], [
AC_DEFINE(HAVE_SPLIT_USR, 1, [Define if /bin, /sbin aren't symlinks into /usr])
])
Maximum System UID: ${SYSTEM_UID_MAX}
Maximum System GID: ${SYSTEM_GID_MAX}
Certificate root: ${CERTIFICATEROOT}
Maximum System UID: ${SYSTEM_UID_MAX}
Maximum System GID: ${SYSTEM_GID_MAX}
Certificate root: ${CERTIFICATEROOT}
+ Default dkr Index ${DEFAULT_DKR_INDEX_URL}
CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
#include "json.h"
#include "strv.h"
#include "curl-util.h"
#include "json.h"
#include "strv.h"
#include "curl-util.h"
#include "btrfs-util.h"
#include "aufs-util.h"
#include "btrfs-util.h"
#include "aufs-util.h"
/* TODO:
- convert json bits
/* TODO:
- convert json bits
- fall back to btrfs loop pool device
*/
- fall back to btrfs loop pool device
*/
-typedef struct DckImportJob DckImportJob;
-typedef struct DckImportName DckImportName;
+typedef struct DkrImportJob DkrImportJob;
+typedef struct DkrImportName DkrImportName;
-typedef enum DckImportJobType {
- DCK_IMPORT_JOB_IMAGES,
- DCK_IMPORT_JOB_TAGS,
- DCK_IMPORT_JOB_ANCESTRY,
- DCK_IMPORT_JOB_JSON,
- DCK_IMPORT_JOB_LAYER,
-} DckImportJobType;
+typedef enum DkrImportJobType {
+ DKR_IMPORT_JOB_IMAGES,
+ DKR_IMPORT_JOB_TAGS,
+ DKR_IMPORT_JOB_ANCESTRY,
+ DKR_IMPORT_JOB_JSON,
+ DKR_IMPORT_JOB_LAYER,
+} DkrImportJobType;
-struct DckImportJob {
- DckImport *import;
- DckImportJobType type;
+struct DkrImportJob {
+ DkrImport *import;
+ DkrImportJobType type;
- Set *needed_by; /* DckImport Name objects */
+ Set *needed_by; /* DkrImport Name objects */
CURL *curl;
struct curl_slist *request_header;
CURL *curl;
struct curl_slist *request_header;
-struct DckImportName {
- DckImport *import;
+struct DkrImportName {
+ DkrImport *import;
char *name;
char *tag;
char *id;
char *local;
char *name;
char *tag;
char *id;
char *local;
- DckImportJob *job_images, *job_tags, *job_ancestry, *job_json, *job_layer;
+ DkrImportJob *job_images, *job_tags, *job_ancestry, *job_json, *job_layer;
char **ancestry;
unsigned current_ancestry;
char **ancestry;
unsigned current_ancestry;
sd_event *event;
CurlGlue *glue;
Hashmap *names;
Hashmap *jobs;
sd_event *event;
CurlGlue *glue;
Hashmap *names;
Hashmap *jobs;
- dck_import_on_finished on_finished;
+ dkr_import_on_finished on_finished;
void *userdata;
};
#define PROTOCOL_PREFIX "https://"
void *userdata;
};
#define PROTOCOL_PREFIX "https://"
-#define INDEX_HOST "index.do" /* the URL we get the data from */ "cker.io"
#define HEADER_TOKEN "X-Do" /* the HTTP header for the auth token */ "cker-Token:"
#define HEADER_REGISTRY "X-Do" /*the HTTP header for the registry */ "cker-Endpoints:"
#define HEADER_TOKEN "X-Do" /* the HTTP header for the auth token */ "cker-Token:"
#define HEADER_REGISTRY "X-Do" /*the HTTP header for the registry */ "cker-Endpoints:"
#define PAYLOAD_MAX (16*1024*1024)
#define LAYERS_MAX 2048
#define PAYLOAD_MAX (16*1024*1024)
#define LAYERS_MAX 2048
-static int dck_import_name_add_job(DckImportName *name, DckImportJobType type, const char *url, DckImportJob **ret);
+static int dkr_import_name_add_job(DkrImportName *name, DkrImportJobType type, const char *url, DkrImportJob **ret);
-static DckImportJob *dck_import_job_unref(DckImportJob *job) {
+static DkrImportJob *dkr_import_job_unref(DkrImportJob *job) {
-static DckImportName *dck_import_name_unref(DckImportName *name) {
+static DkrImportName *dkr_import_name_unref(DkrImportName *name) {
if (name->job_layer)
set_remove(name->job_layer->needed_by, name);
if (name->job_layer)
set_remove(name->job_layer->needed_by, name);
free(name->name);
free(name->id);
free(name->tag);
free(name->name);
free(name->id);
free(name->tag);
-DEFINE_TRIVIAL_CLEANUP_FUNC(DckImportJob*, dck_import_job_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(DckImportName*, dck_import_name_unref);
+DEFINE_TRIVIAL_CLEANUP_FUNC(DkrImportJob*, dkr_import_job_unref);
+DEFINE_TRIVIAL_CLEANUP_FUNC(DkrImportName*, dkr_import_name_unref);
-static void dck_import_finish(DckImport *import, int error) {
+static void dkr_import_finish(DkrImport *import, int error) {
assert(import);
if (import->on_finished)
assert(import);
if (import->on_finished)
if (t != JSON_END)
return -EBADMSG;
if (t != JSON_END)
return -EBADMSG;
- if (!dck_id_is_valid(id))
+ if (!dkr_id_is_valid(id))
return -EBADMSG;
*ret = id;
return -EBADMSG;
*ret = id;
case STATE_ITEM:
if (t == JSON_STRING) {
case STATE_ITEM:
if (t == JSON_STRING) {
- if (!dck_id_is_valid(str))
+ if (!dkr_id_is_valid(str))
return -EBADMSG;
if (n+1 > LAYERS_MAX)
return -EBADMSG;
if (n+1 > LAYERS_MAX)
-static const char *dck_import_name_current_layer(DckImportName *name) {
+static const char *dkr_import_name_current_layer(DkrImportName *name) {
assert(name);
if (strv_isempty(name->ancestry))
assert(name);
if (strv_isempty(name->ancestry))
return name->ancestry[name->current_ancestry];
}
return name->ancestry[name->current_ancestry];
}
-static const char *dck_import_name_current_base_layer(DckImportName *name) {
+static const char *dkr_import_name_current_base_layer(DkrImportName *name) {
assert(name);
if (strv_isempty(name->ancestry))
assert(name);
if (strv_isempty(name->ancestry))
return name->ancestry[name->current_ancestry-1];
}
return name->ancestry[name->current_ancestry-1];
}
-static char** dck_import_name_get_registries(DckImportName *name) {
+static char** dkr_import_name_get_registries(DkrImportName *name) {
assert(name);
if (!name->job_images)
assert(name);
if (!name->job_images)
return name->job_images->response_registries;
}
return name->job_images->response_registries;
}
-static const char*dck_import_name_get_token(DckImportName *name) {
+static const char*dkr_import_name_get_token(DkrImportName *name) {
assert(name);
if (!name->job_images)
assert(name);
if (!name->job_images)
return name->job_images->response_token;
}
return name->job_images->response_token;
}
-static void dck_import_name_maybe_finish(DckImportName *name) {
+static void dkr_import_name_maybe_finish(DkrImportName *name) {
if (name->job_layer && !name->job_json->done)
return;
if (name->job_layer && !name->job_json->done)
return;
- if (dck_import_name_current_layer(name))
+ if (dkr_import_name_current_layer(name))
return;
if (name->local) {
return;
if (name->local) {
assert(name->id);
p = strappenda("/var/lib/container/", name->local);
assert(name->id);
p = strappenda("/var/lib/container/", name->local);
- q = strappenda("/var/lib/container/.dck-", name->id);
+ q = strappenda("/var/lib/container/.dkr-", name->id);
if (name->force_local) {
(void) btrfs_subvol_remove(p);
if (name->force_local) {
(void) btrfs_subvol_remove(p);
r = btrfs_subvol_snapshot(q, p, false, false);
if (r < 0) {
log_error_errno(r, "Failed to snapshot final image: %m");
r = btrfs_subvol_snapshot(q, p, false, false);
if (r < 0) {
log_error_errno(r, "Failed to snapshot final image: %m");
- dck_import_finish(name->import, r);
+ dkr_import_finish(name->import, r);
return;
}
log_info("Created new image %s.", p);
}
return;
}
log_info("Created new image %s.", p);
}
- dck_import_finish(name->import, 0);
+ dkr_import_finish(name->import, 0);
-static int dck_import_job_run_tar(DckImportJob *job) {
+static int dkr_import_job_run_tar(DkrImportJob *job) {
_cleanup_close_pair_ int pipefd[2] = { -1, -1 };
bool gzip;
_cleanup_close_pair_ int pipefd[2] = { -1, -1 };
bool gzip;
-static int dck_import_name_pull_layer(DckImportName *name) {
+static int dkr_import_name_pull_layer(DkrImportName *name) {
_cleanup_free_ char *path = NULL, *temp = NULL;
const char *url, *layer = NULL, *base = NULL;
char **rg;
_cleanup_free_ char *path = NULL, *temp = NULL;
const char *url, *layer = NULL, *base = NULL;
char **rg;
- layer = dck_import_name_current_layer(name);
+ layer = dkr_import_name_current_layer(name);
- dck_import_name_maybe_finish(name);
+ dkr_import_name_maybe_finish(name);
- path = strjoin("/var/lib/container/.dck-", layer, NULL);
+ path = strjoin("/var/lib/container/.dkr-", layer, NULL);
if (!path)
return log_oom();
if (!path)
return log_oom();
- rg = dck_import_name_get_registries(name);
+ rg = dkr_import_name_get_registries(name);
assert(rg && rg[0]);
url = strappenda(PROTOCOL_PREFIX, rg[0], "/v1/images/", layer, "/layer");
assert(rg && rg[0]);
url = strappenda(PROTOCOL_PREFIX, rg[0], "/v1/images/", layer, "/layer");
- r = dck_import_name_add_job(name, DCK_IMPORT_JOB_LAYER, url, &name->job_layer);
+ r = dkr_import_name_add_job(name, DKR_IMPORT_JOB_LAYER, url, &name->job_layer);
if (r < 0) {
log_error_errno(r, "Failed to issue HTTP request: %m");
return r;
if (r < 0) {
log_error_errno(r, "Failed to issue HTTP request: %m");
return r;
if (r < 0)
return log_oom();
if (r < 0)
return log_oom();
- base = dck_import_name_current_base_layer(name);
+ base = dkr_import_name_current_base_layer(name);
if (base) {
const char *base_path;
if (base) {
const char *base_path;
- base_path = strappend("/var/lib/container/.dck-", base);
+ base_path = strappend("/var/lib/container/.dkr-", base);
r = btrfs_subvol_snapshot(base_path, temp, false, true);
} else
r = btrfs_subvol_make(temp);
r = btrfs_subvol_snapshot(base_path, temp, false, true);
} else
r = btrfs_subvol_make(temp);
-static void dck_import_name_job_finished(DckImportName *name, DckImportJob *job) {
+static void dkr_import_name_job_finished(DkrImportName *name, DkrImportJob *job) {
assert(!name->job_json);
assert(!name->job_layer);
assert(!name->job_json);
assert(!name->job_layer);
- rg = dck_import_name_get_registries(name);
+ rg = dkr_import_name_get_registries(name);
if (strv_isempty(rg)) {
log_error("Didn't get registry information.");
r = -EBADMSG;
if (strv_isempty(rg)) {
log_error("Didn't get registry information.");
r = -EBADMSG;
url = strappenda(PROTOCOL_PREFIX, rg[0], "/v1/repositories/", name->name, "/tags/", name->tag);
url = strappenda(PROTOCOL_PREFIX, rg[0], "/v1/repositories/", name->name, "/tags/", name->tag);
- r = dck_import_name_add_job(name, DCK_IMPORT_JOB_TAGS, url, &name->job_tags);
+ r = dkr_import_name_add_job(name, DKR_IMPORT_JOB_TAGS, url, &name->job_tags);
if (r < 0) {
log_error_errno(r, "Failed to issue HTTP request: %m");
goto fail;
if (r < 0) {
log_error_errno(r, "Failed to issue HTTP request: %m");
goto fail;
free(name->id);
name->id = id;
free(name->id);
name->id = id;
- rg = dck_import_name_get_registries(name);
+ rg = dkr_import_name_get_registries(name);
assert(rg && rg[0]);
log_info("Tag lookup succeeded, resolved to layer %s.", name->id);
url = strappenda(PROTOCOL_PREFIX, rg[0], "/v1/images/", name->id, "/ancestry");
assert(rg && rg[0]);
log_info("Tag lookup succeeded, resolved to layer %s.", name->id);
url = strappenda(PROTOCOL_PREFIX, rg[0], "/v1/images/", name->id, "/ancestry");
- r = dck_import_name_add_job(name, DCK_IMPORT_JOB_ANCESTRY, url, &name->job_ancestry);
+ r = dkr_import_name_add_job(name, DKR_IMPORT_JOB_ANCESTRY, url, &name->job_ancestry);
if (r < 0) {
log_error_errno(r, "Failed to issue HTTP request: %m");
goto fail;
}
url = strappenda(PROTOCOL_PREFIX, rg[0], "/v1/images/", name->id, "/json");
if (r < 0) {
log_error_errno(r, "Failed to issue HTTP request: %m");
goto fail;
}
url = strappenda(PROTOCOL_PREFIX, rg[0], "/v1/images/", name->id, "/json");
- r = dck_import_name_add_job(name, DCK_IMPORT_JOB_JSON, url, &name->job_json);
+ r = dkr_import_name_add_job(name, DKR_IMPORT_JOB_JSON, url, &name->job_json);
if (r < 0) {
log_error_errno(r, "Failed to issue HTTP request: %m");
goto fail;
if (r < 0) {
log_error_errno(r, "Failed to issue HTTP request: %m");
goto fail;
name->ancestry = ancestry;
name->current_ancestry = 0;
name->ancestry = ancestry;
name->current_ancestry = 0;
- r = dck_import_name_pull_layer(name);
+ r = dkr_import_name_pull_layer(name);
if (r < 0)
goto fail;
} else if (name->job_json == job) {
if (r < 0)
goto fail;
} else if (name->job_json == job) {
- dck_import_name_maybe_finish(name);
+ dkr_import_name_maybe_finish(name);
} else if (name->job_layer == job) {
name->current_ancestry ++;
} else if (name->job_layer == job) {
name->current_ancestry ++;
- r = dck_import_name_pull_layer(name);
+ r = dkr_import_name_pull_layer(name);
- dck_import_finish(name->import, r);
+ dkr_import_finish(name->import, r);
-static void dck_import_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
- DckImportJob *job = NULL;
+static void dkr_import_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
+ DkrImportJob *job = NULL;
long status;
Iterator i;
int r;
long status;
Iterator i;
int r;
- case DCK_IMPORT_JOB_LAYER: {
+ case DKR_IMPORT_JOB_LAYER: {
siginfo_t si;
if (!job->tar_stream) {
siginfo_t si;
if (!job->tar_stream) {
}
SET_FOREACH(n, job->needed_by, i)
}
SET_FOREACH(n, job->needed_by, i)
- dck_import_name_job_finished(n, job);
+ dkr_import_name_job_finished(n, job);
- dck_import_finish(job->import, r);
+ dkr_import_finish(job->import, r);
-static size_t dck_import_job_write_callback(void *contents, size_t size, size_t nmemb, void *userdata) {
- DckImportJob *j = userdata;
+static size_t dkr_import_job_write_callback(void *contents, size_t size, size_t nmemb, void *userdata) {
+ DkrImportJob *j = userdata;
size_t sz = size * nmemb;
char *p;
int r;
size_t sz = size * nmemb;
char *p;
int r;
j->payload_size += sz;
j->payload = p;
j->payload_size += sz;
j->payload = p;
- r = dck_import_job_run_tar(j);
+ r = dkr_import_job_run_tar(j);
if (r < 0)
goto fail;
return sz;
fail:
if (r < 0)
goto fail;
return sz;
fail:
- dck_import_finish(j->import, r);
+ dkr_import_finish(j->import, r);
-static size_t dck_import_job_header_callback(void *contents, size_t size, size_t nmemb, void *userdata) {
+static size_t dkr_import_job_header_callback(void *contents, size_t size, size_t nmemb, void *userdata) {
_cleanup_free_ char *registry = NULL;
size_t sz = size * nmemb;
_cleanup_free_ char *registry = NULL;
size_t sz = size * nmemb;
- DckImportJob *j = userdata;
+ DkrImportJob *j = userdata;
- dck_import_finish(j->import, r);
+ dkr_import_finish(j->import, r);
-static int dck_import_name_add_job(DckImportName *name, DckImportJobType type, const char *url, DckImportJob **ret) {
- _cleanup_(dck_import_job_unrefp) DckImportJob *j = NULL;
- DckImportJob *f = NULL;
+static int dkr_import_name_add_job(DkrImportName *name, DkrImportJobType type, const char *url, DkrImportJob **ret) {
+ _cleanup_(dkr_import_job_unrefp) DkrImportJob *j = NULL;
+ DkrImportJob *f = NULL;
const char *t, *token;
int r;
const char *t, *token;
int r;
- j = new0(DckImportJob, 1);
+ j = new0(DkrImportJob, 1);
- token = dck_import_name_get_token(name);
+ token = dkr_import_name_get_token(name);
if (token)
t = strappenda("Authorization: Token ", token);
else
if (token)
t = strappenda("Authorization: Token ", token);
else
if (curl_easy_setopt(j->curl, CURLOPT_HTTPHEADER, j->request_header) != CURLE_OK)
return -EIO;
if (curl_easy_setopt(j->curl, CURLOPT_HTTPHEADER, j->request_header) != CURLE_OK)
return -EIO;
- if (curl_easy_setopt(j->curl, CURLOPT_WRITEFUNCTION, dck_import_job_write_callback) != CURLE_OK)
+ if (curl_easy_setopt(j->curl, CURLOPT_WRITEFUNCTION, dkr_import_job_write_callback) != CURLE_OK)
return -EIO;
if (curl_easy_setopt(j->curl, CURLOPT_WRITEDATA, j) != CURLE_OK)
return -EIO;
return -EIO;
if (curl_easy_setopt(j->curl, CURLOPT_WRITEDATA, j) != CURLE_OK)
return -EIO;
- if (curl_easy_setopt(j->curl, CURLOPT_HEADERFUNCTION, dck_import_job_header_callback) != CURLE_OK)
+ if (curl_easy_setopt(j->curl, CURLOPT_HEADERFUNCTION, dkr_import_job_header_callback) != CURLE_OK)
return -EIO;
if (curl_easy_setopt(j->curl, CURLOPT_HEADERDATA, j) != CURLE_OK)
return -EIO;
if (curl_easy_setopt(j->curl, CURLOPT_HEADERDATA, j) != CURLE_OK)
-static int dck_import_name_begin(DckImportName *name) {
+static int dkr_import_name_begin(DkrImportName *name) {
const char *url;
assert(name);
assert(!name->job_images);
const char *url;
assert(name);
assert(!name->job_images);
- url = strappenda(PROTOCOL_PREFIX, INDEX_HOST, "/v1/repositories/", name->name, "/images");
+ url = strappenda(name->index_url, "/v1/repositories/", name->name, "/images");
- return dck_import_name_add_job(name, DCK_IMPORT_JOB_IMAGES, url, &name->job_images);
+ return dkr_import_name_add_job(name, DKR_IMPORT_JOB_IMAGES, url, &name->job_images);
-int dck_import_new(DckImport **import, sd_event *event, dck_import_on_finished on_finished, void *userdata) {
- _cleanup_(dck_import_unrefp) DckImport *i = NULL;
+int dkr_import_new(DkrImport **import, sd_event *event, dkr_import_on_finished on_finished, void *userdata) {
+ _cleanup_(dkr_import_unrefp) DkrImport *i = NULL;
- i = new0(DckImport, 1);
+ i = new0(DkrImport, 1);
- i->glue->on_finished = dck_import_curl_on_finished;
+ i->glue->on_finished = dkr_import_curl_on_finished;
i->glue->userdata = i;
*import = i;
i->glue->userdata = i;
*import = i;
-DckImport* dck_import_unref(DckImport *import) {
- DckImportName *n;
- DckImportJob *j;
+DkrImport* dkr_import_unref(DkrImport *import) {
+ DkrImportName *n;
+ DkrImportJob *j;
if (!import)
return NULL;
while ((n = hashmap_steal_first(import->names)))
if (!import)
return NULL;
while ((n = hashmap_steal_first(import->names)))
- dck_import_name_unref(n);
+ dkr_import_name_unref(n);
hashmap_free(import->names);
while ((j = hashmap_steal_first(import->jobs)))
hashmap_free(import->names);
while ((j = hashmap_steal_first(import->jobs)))
- dck_import_job_unref(j);
+ dkr_import_job_unref(j);
hashmap_free(import->jobs);
curl_glue_unref(import->glue);
sd_event_unref(import->event);
free(import);
hashmap_free(import->jobs);
curl_glue_unref(import->glue);
sd_event_unref(import->event);
free(import);
-int dck_import_cancel(DckImport *import, const char *name) {
- DckImportName *n;
+int dkr_import_cancel(DkrImport *import, const char *name) {
+ DkrImportName *n;
assert(import);
assert(name);
assert(import);
assert(name);
- dck_import_name_unref(n);
+ dkr_import_name_unref(n);
-int dck_import_pull(DckImport *import, const char *name, const char *tag, const char *local, bool force_local) {
- _cleanup_(dck_import_name_unrefp) DckImportName *n = NULL;
+int dkr_import_pull(DkrImport *import, const char *index_url, const char *name, const char *tag, const char *local, bool force_local) {
+ _cleanup_(dkr_import_name_unrefp) DkrImportName *n = NULL;
+ char *e;
- assert(dck_name_is_valid(name));
- assert(dck_tag_is_valid(tag));
+ assert(dkr_url_is_valid(index_url));
+ assert(dkr_name_is_valid(name));
+ assert(dkr_tag_is_valid(tag));
assert(!local || machine_name_is_valid(local));
if (hashmap_get(import->names, name))
assert(!local || machine_name_is_valid(local));
if (hashmap_get(import->names, name))
- n = new0(DckImportName, 1);
+ n = new0(DkrImportName, 1);
if (!n)
return -ENOMEM;
n->import = import;
if (!n)
return -ENOMEM;
n->import = import;
+ n->index_url = strdup(index_url);
+ if (!n->index_url)
+ return -ENOMEM;
+ e = endswith(n->index_url, "/");
+ if (e)
+ *e = NULL;
+
n->name = strdup(name);
if (!n->name)
return -ENOMEM;
n->name = strdup(name);
if (!n->name)
return -ENOMEM;
- r = dck_import_name_begin(n);
+ r = dkr_import_name_begin(n);
- dck_import_cancel(import, n->name);
+ dkr_import_cancel(import, n->name);
-bool dck_name_is_valid(const char *name) {
+bool dkr_name_is_valid(const char *name) {
const char *slash, *p;
if (isempty(name))
const char *slash, *p;
if (isempty(name))
-bool dck_id_is_valid(const char *id) {
+bool dkr_id_is_valid(const char *id) {
if (!filename_is_valid(id))
return false;
if (!filename_is_valid(id))
return false;
+
+bool dkr_url_is_valid(const char *url) {
+
+ if (!startswith(url, "http://") &&
+ !startswith(url, "https://"))
+ return false;
+
+ return ascii_is_valid(url);
+}
#include "sd-event.h"
#include "util.h"
#include "sd-event.h"
#include "util.h"
-typedef struct DckImport DckImport;
+typedef struct DkrImport DkrImport;
-typedef void (*dck_import_on_finished)(DckImport *import, int error, void *userdata);
+typedef void (*dkr_import_on_finished)(DkrImport *import, int error, void *userdata);
-int dck_import_new(DckImport **import, sd_event *event, dck_import_on_finished on_finished, void *userdata);
-DckImport* dck_import_unref(DckImport *import);
+int dkr_import_new(DkrImport **import, sd_event *event, dkr_import_on_finished on_finished, void *userdata);
+DkrImport* dkr_import_unref(DkrImport *import);
-DEFINE_TRIVIAL_CLEANUP_FUNC(DckImport*, dck_import_unref);
+DEFINE_TRIVIAL_CLEANUP_FUNC(DkrImport*, dkr_import_unref);
-int dck_import_pull(DckImport *import, const char *name, const char *tag, const char *local, bool force_local);
-int dck_import_cancel(DckImport *import, const char *name);
+int dkr_import_pull(DkrImport *import, const char *index_url, const char *name, const char *tag, const char *local, bool force_local);
+int dkr_import_cancel(DkrImport *import, const char *name);
-bool dck_name_is_valid(const char *name);
-bool dck_id_is_valid(const char *id);
-#define dck_tag_is_valid(tag) filename_is_valid(tag)
+bool dkr_name_is_valid(const char *name);
+bool dkr_id_is_valid(const char *id);
+#define dkr_tag_is_valid(tag) filename_is_valid(tag)
+bool dkr_url_is_valid(const char *url);
#include "event-util.h"
#include "verbs.h"
#include "build.h"
#include "event-util.h"
#include "verbs.h"
#include "build.h"
static bool arg_force = false;
static bool arg_force = false;
-static void on_finished(DckImport *import, int error, void *userdata) {
+static const char* arg_dkr_index_url = DEFAULT_DKR_INDEX_URL;
+
+static void on_finished(DkrImport *import, int error, void *userdata) {
sd_event *event = userdata;
assert(import);
sd_event *event = userdata;
assert(import);
sd_event_exit(event, error);
}
sd_event_exit(event, error);
}
-static int pull_dck(int argc, char *argv[], void *userdata) {
- _cleanup_(dck_import_unrefp) DckImport *import = NULL;
+static int pull_dkr(int argc, char *argv[], void *userdata) {
+ _cleanup_(dkr_import_unrefp) DkrImport *import = NULL;
_cleanup_event_unref_ sd_event *event = NULL;
const char *name, *tag, *local;
int r;
_cleanup_event_unref_ sd_event *event = NULL;
const char *name, *tag, *local;
int r;
+ if (!arg_dkr_index_url) {
+ log_error("Please specify an index URL with --dkr-index-url=");
+ return -EINVAL;
+ }
+
tag = strchr(argv[1], ':');
if (tag) {
name = strndupa(argv[1], tag - argv[1]);
tag = strchr(argv[1], ':');
if (tag) {
name = strndupa(argv[1], tag - argv[1]);
if (streq(local, "-") || isempty(local))
local = NULL;
if (streq(local, "-") || isempty(local))
local = NULL;
- if (!dck_name_is_valid(name)) {
+ if (!dkr_name_is_valid(name)) {
log_error("Remote name '%s' is not valid.", name);
return -EINVAL;
}
log_error("Remote name '%s' is not valid.", name);
return -EINVAL;
}
- if (!dck_tag_is_valid(tag)) {
+ if (!dkr_tag_is_valid(tag)) {
log_error("Tag name '%s' is not valid.", tag);
return -EINVAL;
}
log_error("Tag name '%s' is not valid.", tag);
return -EINVAL;
}
sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
- r = dck_import_new(&import, event, on_finished, event);
+ r = dkr_import_new(&import, event, on_finished, event);
if (r < 0)
return log_error_errno(r, "Failed to allocate importer: %m");
if (r < 0)
return log_error_errno(r, "Failed to allocate importer: %m");
- r = dck_import_pull(import, name, tag, local, arg_force);
+ r = dkr_import_pull(import, arg_dkr_index_url, name, tag, local, arg_force);
if (r < 0)
return log_error_errno(r, "Failed to pull image: %m");
if (r < 0)
return log_error_errno(r, "Failed to pull image: %m");
"Import container or virtual machine image.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
"Import container or virtual machine image.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
- " --force Force creation of image\n\n"
+ " --force Force creation of image\n"
+ " --dkr-index-url=URL Specify index URL to use for downloads\n\n"
- " pull-dck REMOTE [NAME] Download an image\n",
+ " pull-dkr REMOTE [NAME] Download an image\n",
program_invocation_short_name);
return 0;
program_invocation_short_name);
return 0;
enum {
ARG_VERSION = 0x100,
ARG_FORCE,
enum {
ARG_VERSION = 0x100,
ARG_FORCE,
};
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
{ "force", no_argument, NULL, ARG_FORCE },
};
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
{ "force", no_argument, NULL, ARG_FORCE },
+ { "dkr-index-url", required_argument, NULL, ARG_DKR_INDEX_URL },
+ case ARG_DKR_INDEX_URL:
+ if (!dkr_url_is_valid(optarg)) {
+ log_error("Index URL is not valid: %s", optarg);
+ return -EINVAL;
+ }
+
+ arg_dkr_index_url = optarg;
+ break;
+
case '?':
return -EINVAL;
case '?':
return -EINVAL;
static const Verb verbs[] = {
{ "help", VERB_ANY, VERB_ANY, 0, help },
static const Verb verbs[] = {
{ "help", VERB_ANY, VERB_ANY, 0, help },
- { "pull-dck", 2, 3, 0, pull_dck },
+ { "pull-dkr", 2, 3, 0, pull_dkr },