Thanks for this patch, Yifan ! It looks good to me. I have tested the patch and it works as expected. One suggestion: it would be nice to have similar functionality in mount.erofs as well, for consistency across the toolkit.
Reviewed-and-tested-by: Chengyu Zhu <[email protected]> Thanks, Chengyu > 2025年11月30日 18:42,Yifan Zhao <[email protected]> 写道: > > Currently, the URL used to send requests to the registry is hardcoded > with "https://". This patch introduces an optional insecure option for > `--oci`, enabling registry access via the HTTP protocol. > > Also, this patch refactors the deeply nested logic in the `--oci` > argument parsing. > > Signed-off-by: Yifan Zhao <[email protected]> > --- > lib/liberofs_oci.h | 3 ++ > lib/remotes/oci.c | 40 +++++++++++-------- > mkfs/main.c | 97 ++++++++++++++++++++-------------------------- > 3 files changed, 70 insertions(+), 70 deletions(-) > > diff --git a/lib/liberofs_oci.h b/lib/liberofs_oci.h > index 5298f18..9e0571f 100644 > --- a/lib/liberofs_oci.h > +++ b/lib/liberofs_oci.h > @@ -23,6 +23,7 @@ struct erofs_importer; > * @password: password for authentication (optional) > * @blob_digest: specific blob digest to extract (NULL for all layers) > * @layer_index: specific layer index to extract (negative for all layers) > + * @insecure: use HTTP for registry communication (optional) > * > * Configuration structure for OCI image parameters including registry > * location, image identification, platform specification, and authentication > @@ -37,6 +38,7 @@ struct ocierofs_config { > int layer_index; > char *tarindex_path; > char *zinfo_path; > + bool insecure; > }; > > struct ocierofs_layer_info { > @@ -57,6 +59,7 @@ struct ocierofs_ctx { > struct ocierofs_layer_info **layers; > char *blob_digest; > int layer_count; > + const char *schema; > }; > > struct ocierofs_iostream { > diff --git a/lib/remotes/oci.c b/lib/remotes/oci.c > index c1d6cae..d5afd6a 100644 > --- a/lib/remotes/oci.c > +++ b/lib/remotes/oci.c > @@ -496,8 +496,8 @@ static char *ocierofs_discover_auth_endpoint(struct > ocierofs_ctx *ctx, > > api_registry = ocierofs_get_api_registry(registry); > > - if (asprintf(&test_url, "https://%s/v2/%s/manifests/nonexistent", > - api_registry, repository) < 0) > + if (asprintf(&test_url, "%s%s/v2/%s/manifests/nonexistent", > + ctx->schema, api_registry, repository) < 0) > return NULL; > > curl_easy_reset(ctx->curl); > @@ -528,9 +528,9 @@ static char *ocierofs_get_auth_token(struct ocierofs_ctx > *ctx, const char *regis > const char *password) > { > static const char * const auth_patterns[] = { > - "https://%s/v2/auth", > - "https://auth.%s/token", > - "https://%s/token", > + "%s%s/v2/auth", > + "%sauth.%s/token", > + "%s%s/token", > NULL, > }; > char *auth_header = NULL; > @@ -561,8 +561,8 @@ static char *ocierofs_get_auth_token(struct ocierofs_ctx > *ctx, const char *regis > > api_registry = ocierofs_get_api_registry(registry); > > - if (asprintf(&test_url, > "https://%s/v2/%s/manifests/nonexistent", > - api_registry, repository) >= 0) { > + if (asprintf(&test_url, "%s%s/v2/%s/manifests/nonexistent", > + ctx->schema, api_registry, repository) >= 0) { > curl_easy_reset(ctx->curl); > ocierofs_curl_setup_common_options(ctx->curl); > > @@ -598,7 +598,7 @@ static char *ocierofs_get_auth_token(struct ocierofs_ctx > *ctx, const char *regis > for (i = 0; auth_patterns[i]; i++) { > char *auth_url; > > - if (asprintf(&auth_url, auth_patterns[i], registry) < 0) > + if (asprintf(&auth_url, auth_patterns[i], ctx->schema, > registry) < 0) > continue; > > auth_header = ocierofs_get_auth_token_with_url(ctx, auth_url, > @@ -629,8 +629,8 @@ static char *ocierofs_get_manifest_digest(struct > ocierofs_ctx *ctx, > int ret = 0, len, i; > > api_registry = ocierofs_get_api_registry(registry); > - if (asprintf(&req.url, "https://%s/v2/%s/manifests/%s", > - api_registry, repository, tag) < 0) > + if (asprintf(&req.url, "%s%s/v2/%s/manifests/%s", > + ctx->schema, api_registry, repository, tag) < 0) > return ERR_PTR(-ENOMEM); > > if (auth_header && strstr(auth_header, "Bearer")) > @@ -749,8 +749,8 @@ static int ocierofs_fetch_layers_info(struct ocierofs_ctx > *ctx) > ctx->layer_count = 0; > api_registry = ocierofs_get_api_registry(registry); > > - if (asprintf(&req.url, "https://%s/v2/%s/manifests/%s", > - api_registry, repository, digest) < 0) > + if (asprintf(&req.url, "%s%s/v2/%s/manifests/%s", > + ctx->schema, api_registry, repository, digest) < 0) > return -ENOMEM; > > if (auth_header && strstr(auth_header, "Bearer")) > @@ -1124,10 +1124,18 @@ static int ocierofs_init(struct ocierofs_ctx *ctx, > const struct ocierofs_config > if (!ctx->registry || !ctx->tag || !ctx->platform) > return -ENOMEM; > > + ctx->schema = config->insecure ? "http://" : "https://"; > + > ret = ocierofs_parse_ref(ctx, config->image_ref); > if (ret) > return ret; > > + if (config->insecure && (!strcmp(ctx->registry, DOCKER_API_REGISTRY) || > + !strcmp(ctx->registry, DOCKER_REGISTRY))) { > + erofs_err("Insecure connection to Docker registry is not > allowed"); > + return -EINVAL; > + } > + > ret = ocierofs_prepare_layers(ctx, config); > if (ret) > return ret; > @@ -1152,8 +1160,8 @@ static int ocierofs_download_blob_to_fd(struct > ocierofs_ctx *ctx, > }; > > api_registry = ocierofs_get_api_registry(ctx->registry); > - if (asprintf(&req.url, "https://%s/v2/%s/blobs/%s", > - api_registry, ctx->repository, digest) == -1) > + if (asprintf(&req.url, "%s%s/v2/%s/blobs/%s", > + ctx->schema, api_registry, ctx->repository, digest) == -1) > return -ENOMEM; > > if (auth_header && strstr(auth_header, "Bearer")) > @@ -1344,8 +1352,8 @@ static int ocierofs_download_blob_range(struct > ocierofs_ctx *ctx, off_t offset, > length = (size_t)(blob_size - offset); > > api_registry = ocierofs_get_api_registry(ctx->registry); > - if (asprintf(&req.url, "https://%s/v2/%s/blobs/%s", > - api_registry, ctx->repository, digest) == -1) > + if (asprintf(&req.url, "%s%s/v2/%s/blobs/%s", > + ctx->schema, api_registry, ctx->repository, digest) == -1) > return -ENOMEM; > > if (length) > diff --git a/mkfs/main.c b/mkfs/main.c > index 7aa8eae..5710948 100644 > --- a/mkfs/main.c > +++ b/mkfs/main.c > @@ -218,11 +218,12 @@ static void usage(int argc, char **argv) > #endif > #ifdef OCIEROFS_ENABLED > " --oci=[f|i] generate a full (f) or index-only (i) > image from OCI remote source\n" > - " [,=platform=X] X=platform (default: linux/amd64)\n" > + " [,platform=X] X=platform (default: linux/amd64)\n" > " [,layer=#] #=layer index to extract (0-based; omit > to extract all layers)\n" > " [,blob=Y] Y=blob digest to extract (omit to > extract all layers)\n" > " [,username=Z] Z=username for authentication > (optional)\n" > " [,password=W] W=password for authentication > (optional)\n" > + " [,insecure] use HTTP instead of HTTPS (optional)\n" > #endif > " --tar=X generate a full or index-only image > from a tarball(-ish) source\n" > " (X = f|i|headerball; f=full mode, > i=index mode,\n" > @@ -744,7 +745,7 @@ static int mkfs_parse_s3_cfg(char *cfg_str) > * Parse OCI options string containing comma-separated key=value pairs. > * > * Supported options include f|i, platform, blob|layer, username, password, > - * and zinfo. > + * and insecure. > * > * Return: 0 on success, negative errno on failure > */ > @@ -772,67 +773,55 @@ static int mkfs_parse_oci_options(struct > ocierofs_config *oci_cfg, char *options > if (q) > *q = '\0'; > > - > - p = strstr(opt, "platform="); > - if (p) { > + if ((p = strstr(opt, "platform="))) { > p += strlen("platform="); > free(oci_cfg->platform); > oci_cfg->platform = strdup(p); > if (!oci_cfg->platform) > return -ENOMEM; > - } else { > - p = strstr(opt, "blob="); > - if (p) { > - p += strlen("blob="); > - free(oci_cfg->blob_digest); > + } else if ((p = strstr(opt, "blob="))) { > + p += strlen("blob="); > + free(oci_cfg->blob_digest); > > - if (oci_cfg->layer_index >= 0) { > - erofs_err("invalid --oci: blob and > layer cannot be set together"); > - return -EINVAL; > - } > + if (oci_cfg->layer_index >= 0) { > + erofs_err("invalid --oci: blob and layer cannot > be set together"); > + return -EINVAL; > + } > > - if (!strncmp(p, "sha256:", 7)) { > - oci_cfg->blob_digest = strdup(p); > - if (!oci_cfg->blob_digest) > - return -ENOMEM; > - } else if (asprintf(&oci_cfg->blob_digest, > "sha256:%s", p) < 0) { > + if (!strncmp(p, "sha256:", 7)) { > + oci_cfg->blob_digest = strdup(p); > + if (!oci_cfg->blob_digest) > return -ENOMEM; > - } > - } else { > - p = strstr(opt, "layer="); > - if (p) { > - p += strlen("layer="); > - if (oci_cfg->blob_digest) { > - erofs_err("invalid --oci: layer > and blob cannot be set together"); > - return -EINVAL; > - } > - idx = strtol(p, NULL, 10); > - if (idx < 0) > - return -EINVAL; > - oci_cfg->layer_index = (int)idx; > - } else { > - p = strstr(opt, "username="); > - if (p) { > - p += strlen("username="); > - free(oci_cfg->username); > - oci_cfg->username = strdup(p); > - if (!oci_cfg->username) > - return -ENOMEM; > - } else { > - p = strstr(opt, "password="); > - if (p) { > - p += > strlen("password="); > - free(oci_cfg->password); > - oci_cfg->password = > strdup(p); > - if (!oci_cfg->password) > - return -ENOMEM; > - } else { > - erofs_err("mkfs: > invalid --oci value %s", opt); > - return -EINVAL; > - } > - } > - } > + } else if (asprintf(&oci_cfg->blob_digest, "sha256:%s", > p) < 0) { > + return -ENOMEM; > } > + } else if ((p = strstr(opt, "layer="))) { > + p += strlen("layer="); > + if (oci_cfg->blob_digest) { > + erofs_err("invalid --oci: layer and blob cannot > be set together"); > + return -EINVAL; > + } > + idx = strtol(p, NULL, 10); > + if (idx < 0) > + return -EINVAL; > + oci_cfg->layer_index = (int)idx; > + } else if ((p = strstr(opt, "username="))) { > + p += strlen("username="); > + free(oci_cfg->username); > + oci_cfg->username = strdup(p); > + if (!oci_cfg->username) > + return -ENOMEM; > + } else if ((p = strstr(opt, "password="))) { > + p += strlen("password="); > + free(oci_cfg->password); > + oci_cfg->password = strdup(p); > + if (!oci_cfg->password) > + return -ENOMEM; > + } else if ((p = strstr(opt, "insecure"))) { > + oci_cfg->insecure = true; > + } else { > + erofs_err("mkfs: invalid --oci value %s", opt); > + return -EINVAL; > } > > opt = q ? q + 1 : NULL; > -- > 2.43.0 >
