Search code examples
dockerpodman

Convert Docker Image from Directory to Archive


When I save images using podman save, there's an option to specify the format. Two available formats are docker-archive and docker-dir. However, podman load seems to always expect an archive. I've been given an image in docker-dir format and I'm having a surprisingly hard time converting it to docker-archive to load into podman. I can see how to do it manually except that there's one hash that I don't know how to compute.

As an example, podman save -o ./ubuntu-docker-dir --format docker-dir ubuntu && tree ./ubuntu-docker-dir/ gives:

./ubuntu-docker-dir/
├── 80098e3d304cd7858ad97b310cd16083fbe6fab2968be7a988fc6894cb85dc25
├── bf3dc08bfed031182827888bb15977e316ad797ee2ccb63b4c7a57fdfe7eb31d
├── manifest.json
└── version

By contrast, podman save -o ./ubuntu-docker-archive.tar.gz --format docker-archive ubuntu && mkdir ubuntu-docker-archive && cd ubuntu-docker-archive && tar -xf ../ubuntu-docker-archive.tar.gz && tree . gives:

.
├── 80098e3d304cd7858ad97b310cd16083fbe6fab2968be7a988fc6894cb85dc25.tar
├── 933bb35f5710a7515f24e7a4a8e8c6ca45a26a9c6590be5514e4af1f8dd56da1
│   ├── json
│   ├── layer.tar -> ../80098e3d304cd7858ad97b310cd16083fbe6fab2968be7a988fc6894cb85dc25.tar
│   └── VERSION
├── bf3dc08bfed031182827888bb15977e316ad797ee2ccb63b4c7a57fdfe7eb31d.json
├── manifest.json
└── repositories

By comparing the contents of the two directories, I can see how to translate from one to the other myself, except that I don't know how the hash of the folder in the archive version is computed (933bb). This is a single-layer image, so it's pretty simple, but I've looked at more complicated images and it looks like the hash-named folders with symlinks are basically used to establish parent-child relationships between layers. It looks like you can get the same information from the ordering of the layers in the manifest file, so if I can just figure out how that hash is computed, I should be able to convert with a relatively simple Python script.

Does anyone know how that hash is computed or if there's another tool that already does what I'm trying to do? I'm shocked that it's been this hard to find the answer by Googling, but I promise I've tried. Thanks


Solution

  • It's been a while but I solved the problem. It turns out that what I was trying to do can be accomplished by Skopeo. If you're in a folder where you have an image in docker-dir format at my-image, then you can do skopeo copy dir:my-image containers-storage:localhost/my-image. This will load it into the same local registry that podman uses and it should show up in podman image ls, so from there you can re-export it using podman save to any of the formats that command supports.