#WithRegistryAuth fails when using dockerbuild()

1 messages · Page 1 of 1 (latest)

crystal forge
#
    // c := config.SourceCode().DockerBuild()
    c := containers.NewBaseContainer(ctx, dag, "node")

    c = c.WithExec([]string{"echo", "Building Jenkins container with version " + version})
    c, err = c.Sync(ctx)
    if err != nil {
        return fmt.Errorf("failed to sync container: %w", err)
    }
    c = c.WithRegistryAuth(consts.Registry, consts.Username, dag.SetSecret("password", consts.Token))
    c = c.WithLabel("org.opencontainers.image.source", fmt.Sprintf("https://github.com/%s/devops-jenkins", consts.Username))
    _, err = c.Publish(ctx, fmt.Sprintf("%s:%s", repository, version))
    if err != nil {
        return fmt.Errorf("failed to publish Jenkins container: %w", err)
    }

This works for publishing.

But If I uncomment the DockerBuild() and comment the NewBaseContainer it fails with

Error: failed to publish Jenkins container: secret xxh3:bd8413b0c8b3ad00: not found
failed to publish Jenkins container: secret xxh3:bd8413b0c8b3ad00: not found
exit status 1
compact oriole
#

is NewBaseContainer coming from another module by any chance?

#

cc @idle saffron might have a clue here 🙏

idle saffron
#

although

#

i guess they should get overridden

compact oriole
#

@crystal forge if you could get us a trace, that would help

crystal forge
#

This is the base container

func NewBaseContainer(_ context.Context, client *dagger.Client, img string) *dagger.Container {
    containerOpts := dagger.ContainerOpts{Platform: consts.Platform}
    c := client.Container(containerOpts)
    c = c.From(img)
    c = c.WithoutEntrypoint()
    c = c.WithWorkdir(consts.Workdir)

    return c
}

Trace https://dagger.cloud/Stavros-Kois/traces/1490701ef719037138daf772b06d5de0

compact oriole
crystal forge
#

nope, nowhere.

compact oriole
#

let me check if I can repro without modules

compact oriole
#

@crystal forge I don't seem to be able to repro in v0.18.10. I came up with a minimal example

func main() {
    ctx := context.Background()
    d := dag.Directory().
        WithNewFile("plugins.yaml", `
jenkins:
  systemMessage: "Testing"
plugins:
  - artifactId: git
    source:
      version: latest
  - artifactId: job-import-plugin
    source:
      version: 2.1
tool:
  git:
    installations:
    - home: "git"
      name: "Default"
        `).
        WithNewFile("Dockerfile", `FROM jenkins/jenkins:2.514-jdk21@sha256:caa27ff2f0481af249f5bf0e10598516821364664be1fb37ad24f4e094e44765

ENV CASC_JENKINS_CONFIG="/var/jenkins_home/casc_configs"
ENV CASC_MERGE_STRATEGY="errorOnConflict"

COPY --chown=jenkins:jenkins ./plugins.yaml /usr/share/jenkins/ref/plugins.yaml

# Update center https://updates.jenkins.io/
ENV JENKINS_UC="https://updates.jenkins.io/update-center.json"

# Install plugins
RUN jenkins-plugin-cli --clean-download-directory
RUN jenkins-plugin-cli --plugin-file /usr/share/jenkins/ref/plugins.yaml --verbose

# Skip initial setup
RUN echo $JENKINS_VERSION > /usr/share/jenkins/ref/jenkins.install.UpgradeWizard.state
    `)
    c, err := d.DockerBuild().
        WithExec([]string{"echo", "hello"}).Sync(ctx)
    fmt.Println(err)
    c.WithRegistryAuth("docker.io", "marcosnils", dag.SetSecret("password", "$mytoken")).
        WithLabel("org.opencontainers.image.source", fmt.Sprintf("https://github.com/%s/devops-jenkins", "lala")).
        Publish(ctx, "marcosnils/private-test:foo")
}

^ mind checking if the above fails for you also?

#

you should modify the Publish target registry and creds accordingly

compact oriole
#

@idle saffron any ideas how the "secret not found" could have happened outside modules?

idle saffron
#

pff

#

not really

#

fyi @winter basalt, more secret weirdness?

winter basalt
#

(accidentally @'d wrong person and pressed enter instead of delete, sorry)

#

@crystal forge I have been looking closely through your traces and seeing if I can reproduce but no success so far. To try unblocking, could you clear out the cache and reset the engine w/ docker rm -fv dagger-engine-v0.18.10?

It'll get automatically reprovisioned when you run the command next time. Let me know if that fixes it. If so clearly something got into a bad state

crystal forge
#

I’ll try again tomorrow to see if I can reproduce. I ended moving all dockerfile directives into dagger which works

#

I remember I removed the container but I don’t think I deleted the volume

winter basalt
#

For the others, the big thing that sticks out is this: https://dagger.cloud/Stavros-Kois/traces/1490701ef719037138daf772b06d5de0?span=e9686b9c0fbe082c&debug

Somehow there's never an explicit SetSecret trace showing up in the "top-level", only an internal one in withRegistryAuth that ends up being cached. I can't figure out how to get that to happen though, despite trying for a while. Doesn't seem like it should be possible for setSecret to never appear as a top-level post to /query (as seen with ?debug in the full trace)

#

Clearly is possible though, just haven't discerned how

crystal forge
#

I tried changing the “key” in set secret in case of caching but didn’t change anything. I even tried to create the secret first then sync then pass the secret. Same thing persisted.
Let’s see if I can reproduce tomorrow

compact oriole
crystal forge
#

So your example worked just fine.
Mine was still failing, removed container with -fv still same outcome.
Removed volumes as well, still same

#

Doing it like this works

    socket := dag.Host().UnixSocket(os.Getenv(consts.EnvSSHAuthSocket))
    d := dag.Git("git@github.com:org/devops-jenkins.git", dagger.GitOpts{
        SSHAuthSocket: socket,
    }).Ref("master").Tree()
    c, err := d.DockerBuild().WithExec([]string{"echo", "hello"}).Sync(ctx)

Which is copied from the config.SourceCode() ...

#

Still weird to say that secret is missing if there is something wrong with the directory

#
func handleSSHGitSource(ctx context.Context) (*dagger.Directory, string, error) {
    var err error
    var dir *dagger.Directory
    var commit string

    client := config.Dag()

    socket := client.Host().UnixSocket(os.Getenv(consts.EnvSSHAuthSocket))
    ref := client.Git(config.GitURL(), dagger.GitOpts{SSHAuthSocket: socket}).Ref(config.GitRef())
    dir = ref.Tree()
    commit, err = ref.Commit(ctx)
    if err != nil {
        return nil, "", fmt.Errorf("failed to get commit: %s", err)
    }

    return dir, commit, nil
}
func GetSourceCode(ctx context.Context) (*dagger.Directory, string, error) {
    var err error
    var dir *dagger.Directory
    var commit string

    switch config.GitProtocol() {
    case consts.GitSourceLocal:
        dir, commit, err = handleLocalGitSource(ctx)
    case consts.GitSourceSSH:
        dir, commit, err = handleSSHGitSource(ctx)
    case consts.GitSourceHTTPS:
        dir, commit, err = handleHTTPSGitSource(ctx)
    default:
        return nil, "", fmt.Errorf("invalid git source: %s", config.GitProtocol())
    }

    if err != nil {
        return nil, "", fmt.Errorf("failed to get source code for git protocol [%s]: %w", config.GitProtocol(), err)
    }

    return dir, commit, nil
}
compact oriole
#

Does this work to push the image afterwards?

compact oriole
crystal forge
#

Sorry I meant if there was something wrong. But it souldnt be, as I can correctly get the contents of the Dockerfile and print it.

crystal forge
compact oriole
crystal forge
#

correct

compact oriole
#

I might have an idea on how to repro. I'll come back in a bit. Running an errand currently

crystal forge
#

No worries, I solved it another way anyway. I'm just here to help you figure this out

compact oriole
#

FWIW you don't need to do this since the dagger client is already global

#

after checking the code a bit the difference seems to be that the config.GetSource() and NewBaseContainer are using different dagger clients

#

given that in the NewBaseContainer, you're passing the contextual client as an argument

#

but in the config package, I'd assume you're initializing a new client somewhere else

#

in go it's not required to pass the client anymore, the SDK already has a global client that you can use as dag.$FN from any package

#

cc @winter basalt this is very likely the issue. Two different clients basically

winter basalt
#

Ah okay, yeah that would definitely explain it, good find. A secret from one session is getting referenced in a different one and thus ends up not found

crystal forge
#

Oh lol. Yes that's exactly what was happening -.-
I should have used config.Dag().
Okay FINE, I'll finally refactor it 😄
(I wanted to for a long time lol)

Sorry for the headscratcher lol