#[SOLVED] Accessing to my self-hosted gitlab server from inside my Dagger container

1 messages · Page 1 of 1 (latest)

tawdry halo
#

Hi all,

I'm running Dagger from a self-made Docker image.

Docker container : By starting an interactive shell session in my Docker container, I can do things like git clone git@my_server:myrepo.git i.e. I can clone my private repo from my Docker container. SSH is well working in the container.

Dagger container: When running a Dagger function, let's say dagger call php-lint, Dagger is then running a new container. I've added in my code a await container.terminal() command so I jump in a shell session. From there, I can't access to my repo which sounds normal because my ~/.ssh/id_ed25519 key (and ~/.ssh/known_hosts file) is not present in my Dagger container. (in fact, I need to run composer install or yarn install to download private dependencies).

What should I do please to enable Dagger to reuse my SSH configuration?

Thanks a lot

severe bear
#

there is multiple ways to do it. What you ask can be possible by passing SSH socket to dagger. You can take a look https://docs.dagger.io/api/arguments/#unix-sockets or:

  • you can clone outside pass directory to container
  • you can clone it using dag.Git() and pass the directory to container

Dagger Functions, just like regular functions, can accept arguments. In addition to basic types (string, boolean, integer, arrays...), Dagger also defines powerful core types which Dagger Functions can use for their arguments, such as Directory, Container, Service, Secret, and many more.

tawdry halo
#

Thanks awaris; I'm trying to read / understand docs / discord forum posts since hours now.

By running, from inside my Docker container, commands like dagger --help or dagger call --help I don't see any flag called --sock (as we can see on the page you're referring).

On top, the example is showing the Docker socket (not SSH one if there is one) (-sock=/var/run/docker.sock) while I've already shared that one (when running Docker from my host).

I don't really see, on the URL you've provided, how to "reuse" the SSH keys I've mounted in my Docker container inside my Dagger one.

you can clone outside pass directory to container
you can clone it using dag.Git() and pass the directory to container

No, in my use case, I can't. My Dagger container should works whatever the project I'm using. The project can have or not dependencies to my self-hosted Gitlab server. I don't know this in advance.

Correctly configuring SSH inside the Dagger container would solve my current issue; but don't yet found how...

severe bear
#

On top, the example is showing the Docker socket (not SSH one if there is one) (-sock=/var/run/docker.sock) while I've already shared that one (when running Docker from my host).

that's the same idea, you pass the your ssh sock and configure your ssh agent to use sock in container.

No, in my use case, I can't. My Dagger container should works whatever the project I'm using. The project can have or not dependencies to my self-hosted Gitlab server. I don't know this in advance.

I didn't understand your use case. dag.Git() idea, i mean you need to clone and container call in two different parts. You can change clone part based on projects or anything and pass the directory to container / functions etc.

Are you trying to write a common module to used in different projects or dagger module to access multiple projects and run tasks?

tawdry halo
#

Are you trying to write a common module to used in different projects or dagger module
to access multiple projects and run tasks?

Yes, common module (think to a static code quality tool like phan for PHP or to run unit tests like phpunit or yarn test).

In my use case, I need to be able to run f.i. (PHP) composer require phan which is a static quality tool for PHP. By running composer , the system should be able to download dependencies from my private self-hosted Gitlab.

Same thing for yarn install (JS ).

I can't use dag.git() since I should stay reusable.

Thanks for the help; still trying to make things working ...

tawdry halo
#

I've fired a terminal with await container.terminal(). In my Dagger terminal, I've manually created my SSH key (using ssh-keygen -t ed25519 -C "my_email" and make all actions to register my newly key in GitLab) then fired ssh -T git@my_server and it's works. Then also fired git clone git@my_server:myrepo.git and it works too. So, my Dagger container can access to my private repos and soon as my SSH key is present.

I exit my terminal, loose thus my manually-created key and it didn't works anymore.

My problem is, so far I correctly understand, I should share my SSH key (socket?) between my Docker container and my Dagger module... Not yet found how...

severe bear
#

added quick example using dagger cli how to use ssh socket with continers

➜  ~ dagger core container from --address "alpine/git" with-unix-socket --path="/root/.ssh/socket" --source="${SSH_AUTH_SOCK}" \
    with-env-variable --name="SSH_AUTH_SOCK" --value /root/.ssh/socket \
    with-mounted-file --path /root/.ssh/id_rsa --source /Users/<username>/.ssh/<your-private-key> terminal
● Attaching terminal:
    container: Container!
    Container.from(address: "docker.io/alpine/git:latest@sha256:<image-sha256>"): Container!
    Container.withUnixSocket(
    │ │ path: "/root/.ssh/socket"
    │ │ source: Host.__internalSocket(accessor: "<internal-accessor>"): Socket!
    │ ): Container!
    Container.withEnvVariable(name: "SSH_AUTH_SOCK", value: "/root/.ssh/socket"): Container!
    Container.withMountedFile(
    │ │ path: "/root/.ssh/id_rsa"
    │ │ source: Directory.file(path: "<your-private-key>"): File!
    │ ): Container!

dagger /git $ ssh-add -l
256 SHA256:<ssh-key-fingerprint> <username>@<domain> (ED25519)
dagger /git $ git clone git@gitlab.com:<organization>/<repository>.git
Cloning into '<repository-name>'...
....

basically you need to pass path to your ssh auth sock and a private key to use as part of the authentication

#

you can convert to your module language form cli commands

tawdry halo
#

I really appreciate your help; thanks.

I'm using dagger call to run my function and I don't see anywhere the existence of a with-unix-socket or --sock or --with-unix-socket flag.

(I've actually created more than 60 functions and I call them with dagger call and my required CLI arguments)

tawdry halo
#

Your provided example works fine dagger core container from --address "alpine/git" with-unix-socket --path="/root/.ssh/id_ed25519" --source="${SSH_AUTH_SOCK}" with-env-variable --name="SSH_AUTH_SOCK" --value /root/.ssh/id_ed25519 terminal. I can then run ssh -T git@my-server and see my name and also do a git clone. Just I should understand how to make the same thing with a dagger call command...

severe bear
#

core extends core functionality, call is calls your module function. You need to add socket *dagger.Socket and key *dagger.Secret in your functon adn pass to container you're creating with fucntion you seen in your module

#

Syntax could be wrong, just wrote it quickly but this is more or less how it would look in golang. You can convert this example in your langugage

// runs linter on the component with given parameters
func (m *CI) Lint(
    ctx context.Context,
    socket *dagger.Socket,
    sshKey *dagger.Secret,
) *dagger.Container {
    return dag.Container().From("alpine/git:latest).WithUnixSocket("/root/.ssh/id_ed25519", socket).WithEnvVariable("SSH_AUTH_SOCK", "/root/.ssh/id_ed25519").WithMountedFile("/root/.ssh/id_rsa", sshKey)
tawdry halo
#

It took me all day and I couldn't have done it without your help; thank you @severe bear !

Here is a working Python code for those who'll retrieve this question.

@function
async def ssh(self, socket: dagger.Socket) -> str:
    """Check SSH connection to private repositories

    # Create the SSH socket (i.e. create and initialize the SSH_AUTH_SOCK variable)
    eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_ed25519

    # Then call
    clear ; dagger call ssh --socket ${SSH_AUTH_SOCK}

    Args:
        socket (dagger.Socket): the SSH socket to use

    Returns:
        str: a welcome message if everything is working fine
    """
    async with dagger.Connection() as client:
        container: Container = (
            client.container()
            .from_("alpine/git:latest")
            # Use the SSH socket from the host
            .with_unix_socket("/root/.ssh/id_ed25519", socket)
            # Set secure permissions
            .with_exec(["sh", "-c", "chmod 600 /root/.ssh/id_ed25519"])
            # Add host to known_hosts
            .with_exec(["sh", "-c", "ssh-keyscan my_server_domain >> /root/.ssh/known_hosts"]) 
            .with_exec(["sh", "-c", "ssh -T git@my_server"])
            .terminal()
        )

        # Execute a command that uses SSH (e.g., cloning a private Git repository)
        return await container.stdout()

To be able to call it, first we need to run eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_ed25519.

That command will initialize the SSH_AUTH_SOCK variable i.e. the ssh socket (didn't know until today)
(we can check it's done by running echo "${SSH_AUTH_SOCK}" to see its content; will be something like this /tmp/ssh-RRdMRlgQXZ1I/agent.174 )

And, the dagger call command will be in my sample: dagger call ssh --socket ${SSH_AUTH_SOCK}

THANKS aweris.