genuinetools / img

Standalone, daemon-less, unprivileged Dockerfile and OCI compatible container image builder.
https://blog.jessfraz.com/post/building-container-images-securely-on-kubernetes/
MIT License
3.89k stars 230 forks source link

Programmatic usage #223

Open jeromegn opened 5 years ago

jeromegn commented 5 years ago

I'm trying to use this package programmatically, but I'm running into a few issues. I'm sure this is not the intended way to use this tool, but it'd work nicely for us if we could use the Client in our own go package.

Specifically, I'm trying to pull an image, unpack it and save the containerd ImageConfig to a file. As far as I can tell, I should be able to do most of this with a few changes.

Example program:

import (
    "github.com/genuinetools/img/client"
    "github.com/containerd/containerd/content"
    "github.com/containerd/containerd/namespaces"
    "github.com/containerd/containerd/platforms"
    "github.com/moby/buildkit/identity"
    "github.com/moby/buildkit/session"
)

func main() {
    fullImageName := "redis:latest"

    c, err := client.New("/tmp/img", "auto", nil)
    check(err)

    cCtx := context.Background()
    id := identity.NewID()
    cCtx = session.NewContext(cCtx, id)
    cCtx = namespaces.WithNamespace(cCtx, "buildkit")

    img, err := c.Pull(cCtx, fullImageName)
    check(err)

    err = c.Unpack(cCtx, fullImageName, "./rootfs")
    check(err)

    // all good up to here

    // `createWorkerOpt` is private, can't call it (obviously).
    conf, err := img.Config(cCtx, c.createWorkerOpt(false), platforms.Default())
    check(err)
}

func check(e error) {
    if e != nil {
        panic(e)
    }
}

Would it be possible to expose a way to get the ImageConfig from ListedImage?

Since dependencies are vendored, I couldn't easily get at the nested dependencies. For example, containerd's content.Provider don't match since they're considered different from the vendored code and anything I'd import.

It would also help if this package could be installed via Go modules (by pushing the forks vendored into repositories and including them with go.mod? Not sure.)

If nothing of this is desirable, that's fine, I'll wrap my bit of logic in a script that'll use the provided img binaries.

AkihiroSuda commented 5 years ago

Why not just use buidkit library directly?

jeromegn commented 5 years ago

@AkihiroSuda I might end up doing that, but I hoped I wouldn't have to re-implement the same logic present in this package.

universam1 commented 4 years ago

We would also need this functionality to leverage it from our orchestrating tools. Why should one reinvent what has been accomplished here? @AkihiroSuda

AkihiroSuda commented 4 years ago

The BuildKit upstream (https://github.com/moby/buildkit) has full featured and actively maintained libraries.

I don't think img has really "accomplished here" stuff w.r.t. API.

For rootless execution you need to reexec your app with a user namespace. Take a look at how k3s is consuming RootlessKit for this: https://github.com/rancher/k3s/blob/0aeea78060bed1829713f7a8a0eb9898af4bd6e3/pkg/rootless/rootless.go