#Exporting from a failed container

1 messages · Page 1 of 1 (latest)

marsh patio
#

I have an action that I am running in a dagger container that generates an error report on failure. I need the report in order to resolve the failure, but I cannot get the report out of the container using Export() because of the failed status code from the shell command.

Is there a way to resolve this?

paper stream
#

i.e:

package main

import (
    "context"
    "fmt"

    "dagger.io/dagger"
)

func main() {
    c, err := dagger.Connect(context.Background())
    if err != nil {
        panic(err)
    }
    defer c.Close()

    ctx := context.Background()
    ok, err := c.Container().From("alpine").
        WithExec([]string{"sh", "-c", "(echo hello > foo.txt && exit 1) || true"}).
        FS().
        Export(ctx, "./out")

    fmt.Println(ok, err)
}
marsh patio
#

I see. I got the export working, but I needed the error to fail the process. I made a workaround by sending the command stderr and the command exit code to a file. I have a function that can inspect the exit code and detect non-zero that will throw an error and read the stderr file to report back to the terminal.

I think this will work for now

#
func WithTrapExec(container *dagger.Container, cmd []string) (*dagger.Container, error) {
    container = container.WithExec(
        []string{"/bin/sh", "-c", fmt.Sprintf("%s > /tmp/stderr 2>&1 || echo $? > /tmp/code", strings.Join(cmd, " "))},
    )
    ctx := context.Background()
    code, err := container.File("/tmp/code").Contents(ctx)
    if err != nil {
        // if the command succeeds /tmp/code will not be created
        if strings.Contains(err.Error(), "no such file or directory") {
            return container, nil
        }
        return container, err
    }
    if code != "0" {
        stderr, err := container.File("/tmp/stderr").Contents(ctx)
        if err != nil {
            return container, err
        }
        return container, errors.New(stderr)
    }
    return container, nil
}