#Issues with 'with_mounted_cache' causing an empty directory

1 messages Β· Page 1 of 1 (latest)

lusty ginkgo
#

I have a pipeline which installs sdkman, java and maven. I had it working and decided to implement cache for the installation of sdkman and its candidates but now the directory that I am trying to cache (/root/.sdkman) its empty after using the with_cache_mounted function. This is what my pipeline looks like:

In the following pipeline:

import sys

import anyio
import dagger


async def main():
    config = dagger.Config(log_output=sys.stdout)

    async with dagger.Connection(config) as client:
        container = client.container().from_("ubuntu:22.04")

        sdkman_cache = client.cache_volume("sdkman-cache")

        # install sdkman and its dependencies
        container = (
            container
            .with_exec("apt-get update".split())
            .with_exec("apt-get install -y zip unzip wget curl".split())
            .with_exec("curl -s https://get.sdkman.io -o sdkman.sh".split())
            .with_exec("bash sdkman.sh".split())
            .with_mounted_cache("/root/.sdkman", sdkman_cache)
        )

        # install required java and maven versions
        container = (
            container
            .with_exec(["/bin/bash", "-c", "source /root/.sdkman/bin/sdkman-init.sh && sdk install java 11.0.18-zulu"])
            .with_exec(["/bin/bash", "-c", "source /root/.sdkman/bin/sdkman-init.sh && sdk install maven 3.6.3"])
            .with_env_variable(name="PATH", value="$PATH:/root/.sdkman/candidates/maven/current/bin", expand=True)
            .with_env_variable(name="PATH", value="$PATH:/root/.sdkman/candidates/java/current/bin", expand=True)
            .with_env_variable(name="JAVA_HOME", value="/root/.sdkman/candidates/java/current")
        )

        container = container.with_exec(["java", "--version"])
        await container


anyio.run(main)
#

I get errors when I try to run the /bin/bash -c source etc lines as the file that I am trying to source does not exists and, in fact, if I try to execute a ls -l /root/.sdkman I get nothing.

brisk drift
#

πŸ‘‹ I'm getting an error when running the above snippet:

#3                                                                                                         
#3 0.174 /bin/bash: line 1: /root/.sdkman/bin/sdkman-init.sh: No such file or directory
#3 ERROR: process "/bin/bash -c source /root/.sdkman/bin/sdkman-init.sh && sdk install java 11.0.18-zulu" d
id not complete successfully: exit code: 1                                                                 
------             
 > :                                                                                                       
0.174 /bin/bash: line 1: /root/.sdkman/bin/sdkman-init.sh: No such file or directory
low solar
#

I'll give it a try.

lusty ginkgo
#

yeah, that is the main point. If you remove the line .with_mounted_cache("/root/.sdkman", sdkman_cache) it does work, but if you use it, the directory its empty

low solar
#

got same behavior. what should be in that cache normally?

lusty ginkgo
#

Source code and binaries for sdkman, and the installation of the candidates (maven, java, gradle, etc).

#

I wanted to cache it to avoid future installations of both sdkman and candidates. I am not saying that this is the best approach and there are alternatives like just caching java and maven installations and proceeding with sdkman installation only if those versions does not exists, but I was wondering what may be the reason for the cache directory getting empty.

brisk drift
#
import sys

import anyio
import dagger


async def main():
    config = dagger.Config(log_output=sys.stdout)

    async with dagger.Connection(config) as client:
        container = client.container().from_("ubuntu:22.04")

        sdkman_cache = client.cache_volume("sdkman-cache")

        # install sdkman and its dependencies
        container = (
            container
            .with_exec("apt-get update".split())
            .with_exec("apt-get install -y zip unzip wget curl".split())
            .with_exec("curl -s https://get.sdkman.io -o sdkman.sh".split())
            .with_mounted_cache("/root/.sdkman", sdkman_cache)
            .with_env_variable("SDKMAN_DIR", "/root/.sdkman/sdkman")
            .with_exec("bash sdkman.sh".split())
        )

        # install required java and maven versions
        container = (
            container
            .with_exec(["/bin/bash", "-c", "source /root/.sdkman/sdkman/bin/sdkman-init.sh && sdk install java 11.0.18-zulu"])
            .with_exec(["/bin/bash", "-c", "source /root/.sdkman/sdkman/bin/sdkman-init.sh && sdk install maven 3.6.3"])
            .with_env_variable(name="PATH", value="$PATH:/root/.sdkman/sdkman/candidates/maven/current/bin", expand=True)
            .with_env_variable(name="PATH", value="$PATH:/root/.sdkman/sdkman/candidates/java/current/bin", expand=True)
            .with_env_variable(name="JAVA_HOME", value="/root/.sdkman/sdkman/candidates/java/current")
        )

        container = container.with_exec(["java", "--version"])
        await container


anyio.run(main)
#

seems like the issue is that sdkman doesn't handle .sdkman existing very well

#

and it assumes that sdkman is installed when it's not

#

so I just hacked it using SDKMAN_DIR env variable

lusty ginkgo
#

Thank you! So if I understood this well, the error comes when sdkman is installed in the root directory of a mounted cache directory but works fine when installed in a child directory of a mounted cache directory. I do not really know how buildkit "mounts" the cache directories but I guess it has an explanation.

brisk drift
#

edit: just updated the snippet

lusty ginkgo
#

I was going to publish the fixed script but you got me πŸ˜‰

brisk drift
#

when you use WithMountedCache dir in Dagger, Dagger creates an empty directory in the containers so you can put stuff in there

lusty ginkgo
#

ohhh

brisk drift
#

SDKMAN install script checks if SDKMAN is installed and assumes it's installed just because that folder exists

#

which is incorrect

lusty ginkgo
#

yeah, that has sense. Thank you! I will probably raise an issue in SDKMAN with this information. Thank you again.

brisk drift
#

I'd think there should be an issue for this already. Seems like a very basic and annoying thing to check

lusty ginkgo
#

Also, another question, is there a more "dagger" way of sourcing a file?

brisk drift
brisk drift
low solar
#

@brisk drift I wonder why your script has lots of things lower cased when Python or the Dagger Python SDK want upper cased like true vs True, config, connection, env vars, etc

#

In that form, it doesn't run for me. Do you have some magic in place?

brisk drift
#

just updated it @low solar

brisk drift