#docker run instead of docker exec (golang.Exec(dagger.ContainerExecOpts...)

1 messages Β· Page 1 of 1 (latest)

faint dock
#

Hi everyone,

I am trying to get https://hub.docker.com/r/gittools/gitversion to run with dagger go SDK.

If I understood correctly:

client.Container().From(.... golang.WithMountedDirectory(... golang.Exec(...

Builds a container and then does "docker exec ....".

I want to do something along:
docker run --rm -v "$(pwd):/repo" gittools/gitversion:5.10.0-alpine.3.14-6.0 /repo

Is there a way?

Kind regards,
Chris

azure nymph
#

Hey πŸ‘‹ Can you clarify what you're trying to do? Do you want to run that container as a daemon, or execute it's default entrypoint?

#

The reason I ask is because with the above container as an example, to have it run GitVersion against /repo, you would

client.Container.From("gittools/gitversion:5.10.0-alpine.3.14-6.0")
.WithMountedDirectory("/",mydir)
.Exec( ... Args: []string{"/tools/dotnet-gitversion", "/repo"})

which would be the equivalent of the docker run above

faint dock
#

Hey Kyle, thanks for answering. Yes I was trying to use the default entry point. Partially because I didn't find a good way to figure out why my mounting didn't work as I wanted. But that could be solved differently.

azure nymph
#

I see! Can you elaborate on what wasn't working with the mounting? Was it the mounting location, or writing back to the host?

faint dock
#

Yes, I am trying to understand how it really works.

project structure:

   |- .ci
        |- main.go
   |- .git
   |- src```

    ```go
    client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stdout), dagger.WithWorkdir("../"))
    if err != nil {
        return err
    }
    defer client.Close()

    if err := generateVersion(client, ctx); err != nil {
        fmt.Println(err)
    }```


```go
  func generateVersion(client *dagger.Client, ctx context.Context) error {
    fmt.Println("generate-version")

    // get reference to the local project
    src := client.Host().Workdir()

    // get `gittools/gitversion:latest` image
    golang := client.Container().From("gittools/gitversion:latest")

    // mount sources into `gittools/gitversion:latest` image
    golang = golang.WithMountedDirectory("/repo", src)

    // execute version generation in container
    golang = golang.Exec(dagger.ContainerExecOpts{
        Args: []string{"/repo", "/nonormalize", "/nocache", "/output", "file", "/outputfile", "/repo/version.json"},
    })````
#

So I want to mount the project root in /repo here.

I am not really getting how the sdk works here. I assumed that with dagger.WithWorkdir(../) i navigated to the project root and with src := client.Host().Workdir() I am mounting that into /repo.

Isn't that right?

azure nymph
#

Yeah good question, those two instances of Workdir represent different things πŸ™‚ Host().Workdir() will get the current directory on your host, which is what you want to mount into the container. Container.WithWorkdir() sets the workdir of the container, similar to a WORKDIR statement in a dockerfile. So that's the directory in the container where the exec will be run from.
The other thing to note is that Exec doesn't use the container's entrypoint, it should be a full command. So your first argument in exec should be /tools/dotnet-version I think. That's a common point of confusion, which is why we have this issue to consider renaming Exec to something else: https://github.com/dagger/dagger/issues/3709

And then finally, to get that /repo/version.json back to your host, you have to explicitly write it back out of the container. Working off of the above code, that would look like:

_, err := golang.File("/repo/version.json").Export(ctx, "version.json")
faint dock
#

That helped heaps. Thank you.

golang = golang.Exec(dagger.ContainerExecOpts{
        Args: []string{"/repo", "/nonormalize", "/nocache", "/output", "file", "/outputfile", "/repo/version.json"},
    })

is correct though in that case according to my logs. So with Host().Workdir().Directory("somedir") i can navigate around. That seems quite nice πŸ™‚

azure nymph
#

Host().Workdir().Directory("somedir") i can navigate around
Exactly!

is correct though in that case according to my logs
in the logs its actually executing the dotnet-version tool? That's curious

faint dock
#

It seems to:

#15 resolve docker.io/gittools/gitversion:latest 0.1s done
#15 CACHED

#16 /tools/dotnet-gitversion /tools/dotnet-version /repo /nonormalize /nocache /output file /outputfile /repo/version.json
#

it runs without the /tools/dotnet-version (which should be dotnet-gitversion) directly

#

now that I removed the Withworkdir("../") it somehow behaves differently. Let me check first what happens there. Confused now

#
"Entrypoint": [
                "/tools/dotnet-gitversion"
            ],
azure nymph
faint dock
#

What is confusing to me at the moment.

When I use:

    client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stdout), dagger.WithWorkdir("../"))

and

src := client.Host().Workdir().Directory("../.git")

I get what I want.

#

When I use:

client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stdout))

and

src := client.Host().Workdir().Directory(".git")

it does:

/var/lib/buildkit/runc-overlayfs/cachemounts/buildkit3391576765/.git: no such file or directory

I have no idea where this directory is coming from now

#

I mixed things up again, didnt I

azure nymph
#

Is this executed from the dir that has .git in it?

faint dock
#

yes, but the host Directory still seems weird

#

it is

azure nymph
#

I didn't catch that dagger.WithWorkdir("../") was in your Connect configuration, I thought you were calling Container.WithWorkdir

faint dock
#

Ah

#

So what I am trying to do is have it run in a .ci directory below project root.
And then I want to mount .git which is from .ci: .ci/../.git

#

and now it that /var/lib/buildkit thing shows up, which has me lost

azure nymph
#

got it. And when you run the pipeline, you have something resembling cd .ci && go run ci.go, or go run .ci/ci.go

faint dock
#

yes

#

I have a monorepo where i need to stitch stuff together

#

so I'll always navigate out of .ci or wherever I find my root pointer

#

(maybe that is a bit too much bash thinking and I am offered different ways to access directories, etc)

azure nymph
#

so if I'm understanding it correctly, in the 2nd scenario it's basically trying to get .ci/.git since your workdir would be .ci. And in the first example, I'm betting you can get rid of the ../ from ../.git as long as you have the dagger.WithWorkdir("../")

faint dock
#

no, I want to get .ci/../.git but workdir .ci

#

problem with dagger.WithWorkdir("../") is, that it actually moves in the whole project. And since it is a mono-repo that is massive. I'd like to avoid that, but it is one way, I am getting it to work atm

azure nymph
#

got it. I think there's still a restriction on moving outside the workdir (correct me here @steel radish @trail heart )

#

one possibility:

#

actually my suggestion was going to be virtually the same as your working scenario but using include, which I don't know if that's any different

#

could you have the workdir as ../.git/?

faint dock
#

I understand. Okay. The problem with that is

That is fine:

#7 local:///workspace/swat/.ci
#7 transferring /workspace/swat/.ci: 131B done
#7 DONE 0.0s

But I want to avoid an expensive workdir

#

I will try. But I was aiming on chaining many different things, with many different workdirs (different jobs for different directories).

#

and have them in functions seperated with the go sdk

azure nymph
#

there's also Host().Directory() (without the .Workdir() in the middle.) I don't know if that is more efficient here

faint dock
#

let me check

#

Host().Directory() is .ci and allows not to do relative paths πŸ˜„

#

that would work for having .ci/../.git as dagger workdir, but then I could not put in multiple functions

#

Would I rather split up multiple steps through multiple go files? I assumed putting them together and organize by functions makes sense

#

If I split up, I'd need to handle artifact storing in a more organized way

#

What seems to work nicely is:

#
    client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stdout), dagger.WithWorkdir("../"))

and

    src := client.Host().Directory(".git")
#

it then transfers ../.git and not the complete project

#

key to that was not to use Workdir() after Host()

#

That looks controllable without overhead. And I could split it all up in functions, running from .ci

azure nymph
#

yes exactly! that's what I was meaning to suggest, I was just testing that as well

faint dock
#

I do not completely understand why to be honest, But I learned πŸ˜„

azure nymph
#

I think what's happening is when you say client.Host().Workdir().Directory(".git"), it first transfers workdir as a directory and then grabs .git as a directory from that, rather than directly transferring .git right away

#

because client.Host().Workdir() returns a directory, and then we're chaining off of that to get another directory. Instead client.Host().Directory() will get that directly

faint dock
#

should not have blindly copy pasted the docs

azure nymph
#

and then moving the workdir added another layer of confusion πŸ˜‚

#

So just to make sure, the directory loading is in a good spot now right? or could it still be improved?

faint dock
#

The dagger.WithWorkdirseems something I'd always want to be conscious of. It was quite a bit hidden in the docs

#

loading is in a good spot. Now I need to make that .net container work (why ever that is in that terrible language πŸ˜„ )

#

I feel set up well at the moment

#

And as I am planning to move a multi stage circleci config to dagger, I bet other stuff will come up πŸ™‚

azure nymph
#

Awesome! Yeah I have not used the workdir option on connect, which is why I was confused at first too πŸ˜‚ That sounds awesome! When you get to a good spot with that, we'd love for you to talk about your setup in the weekly community call if you're up for it!

faint dock
#

Sure, I'll let you know

#

Thanks a lot for your help

azure nymph
#

My pleasure!

steel radish
#

just catching up, glad y'all figured it out - but worth also nothing that in client.Host().DIrectory(path) you can also pass an absolute path. it just doesn't want you to do ../ since we want to reserve the right to have magical types of workdirs that don't have anything outside of them