#shared mount not available on container when i exec into it

1 messages · Page 1 of 1 (latest)

wooden fjord
#

I'm running a pipeline that's running into an error. I'd like to exec into it to investigate.

I'm using the -i interactive mode of dagger. It drops me into the shell, but then there's no shared mount on the container anymore.

eternal matrix
#

Tried simple case here, which works...is it possible that you hit the error before the directory is mounted? I'll try your repro with -i and an error as well:

~ ➤ cd /tmp
/tmp ➤ mkdir shared
/tmp ➤ cd shared
shared ➤ echo "Hello from shared" > hello
shared ➤ cd ..
/tmp ➤ dagger core container from --address alpine with-mounted-directory --path="/shared" --source=./shared terminal
● Attaching terminal:
    container: Container!
    Container.from(address: "alpine"): Container!
    Container.withMountedDirectory(
        path: "/shared"
        source: blob(digest: "sha256:0de44ea83f118111a72ad99b9ddcf7d13bcc0a4fc157aede8eb68656524fc50c", mediaType: "application/vnd.oci.image.layer.v1.tar+zstd", size: 106, uncompressed: "sha256:de0445bf8b9c63d19b0a64c0f299cacfe7bd0e805b57eab5c4f63cab80bd7625"): Directory!
      ): Container!

dagger / $ ls shared
hello
dagger / $ cat shared/hello
Hello from shared
#
/tmp ➤ dagger -i core container from --address alpine with-mounted-directory --path="/shared" --source=./shared with-exec --args="foo"
✘ Exec failed, attaching terminal:
    container: Container!
    Container.from(address: "alpine"): Container!
    Container.withMountedDirectory(
        path: "/shared"
        source: blob(digest: "sha256:0de44ea83f118111a72ad99b9ddcf7d13bcc0a4fc157aede8eb68656524fc50c", mediaType: "application/vnd.oci.image.layer.v1.tar+zstd", size: 106, uncompressed: "sha256:de0445bf8b9c63d19b0a64c0f299cacfe7bd0e805b57eab5c4f63cab80bd7625"): Directory!
      ): Container!
    Container.withExec(args: ["foo"]): Container!

! process "foo" did not complete successfully: exit code: 2
/ # ls
bin     etc     lib     mnt     proc    run     shared  sys     usr
dev     home    media   opt     root    sbin    srv     tmp     var
/ # cat shared/hello
Hello from shared
/ #
#

happy to try repro with your code 🙏

wooden fjord
#

ah thanks for trying, i'll try to share something reproducible

wooden fjord
#

hey i finally got around to reproducing this. I think it's because I'm using a cache mount that is doesn't show up in the interactive terminal after failing?

func (m *Treasury) TestSharedMount(ctx context.Context) (*dagger.Container, error) {
    devContainer := dag.Container().
        From("alpine")

    // mount a shared dir
    devContainer = devContainer.WithMountedCache("/shared", dag.CacheVolume(fmt.Sprintf("shared-%s", time.Now())))

    // run a working command
    devContainer = devContainer.WithExec([]string{"sh", "-c", "echo hello > /shared/greeting"})
    _, err := devContainer.Stdout(ctx)
    if err != nil {
        return devContainer, err
    }

    // run a failing command
    devContainer = devContainer.WithExec([]string{"sh", "-c", "exit 127"})
    _, err = devContainer.Stdout(ctx)
    if err != nil {
        return devContainer, err
    }

    return devContainer, nil
}
/ # ls /shared
ls: /shared: No such file or directory
#

confirmed it works if i don't use a cache mount.

#

i don't know how i missed the normal directory mount haha.

#

thanks!

#

@eternal matrix Do you know if it's possible to get this to work with the cache mounts?

I ask because I need mounts to be shared between multiple containers at the same time, and I think only cache mounts work for that.

eternal matrix
#

@wooden fjord in my testing, you need to ensure the step that is reading from the cache volume is not itself cached. Here I use a cache buster env variable to do that.

Without the cache buster, once I get something in my cache (goes in cache volume), and read it once (result now in layer cache for first dictionary item A), I just get that one first read result back.

package main

import (
    "context"
    "time"
    //"dagger/simulcast/internal/dagger"
)

type Simulcast struct{}

// Read from cache
func (m *Simulcast) Read(ctx context.Context) (string, error) {
    return dag.Container().
        From("alpine:latest").
        WithMountedCache("/mnt", dag.CacheVolume("data")).
        WithWorkdir("/mnt").
        WithEnvVariable("CACHE_BUST", time.Now().String()).
        WithExec([]string{"sh", "-c", "cat data.txt"}).
        Stdout(ctx)
}

// Write to cache
func (m *Simulcast) Write(ctx context.Context, data string) (string, error) {
    return dag.Container().
        From("alpine:latest").
        WithMountedCache("/mnt", dag.CacheVolume("data")).
        WithWorkdir("/mnt").
        WithExec([]string{"sh", "-c", "echo " + data + " >> data.txt"}).
        Stdout(ctx)
}
#!/bin/bash

dagger -s call read
for w in `cat /usr/share/dict/words`; do
  dagger call -s write --data $w
  dagger -s call read
done
#

cc @pure hull seem right?

pure hull
#

Looking to see if it's something obvious to fix quick. If not will open an issue

#

Okay yeah it's just a bug, fixed it locally. What Jeremy mentioned about cache busting being necessary is relevant to get the contents in the cache mount, but due to the bug the cache mounts just didn't show up in the interactive debug container at all.

#

Just need to add an integ test, will send out a fix in a few. Will be in the next release

wooden fjord
#

Wow amazing, thanks!