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
> 


Reply via email to