Hi Yifan,

Would you mind updating mkfs.erofs manpage too?

Thanks,
Gao Xiang

On 2025/12/1 19:15, zhaoyifan (H) wrote:
Hi Chengyu,

Thanks for your review. I will try to deal with `mount.erofs` later.


Thanks,

Yifan Zhao


On 2025/12/1 17:25, hudsonZhu wrote:
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