Build a snap from a private repository

When developing snap applications, you may need to clone sources that are private. While snapcraft.yaml usually lives next to the private code, in some cases it depends on source code that resides in a separate private repository. This is the case covered in this how-to guide.

NOTE: In destructive mode, everything is done on the host, so the steps below aren’t necessary.

By default, snapcraft executes all commands in a container or a VM, so private SSH keys on your host aren’t available by default in this isolated environment.

For this guide, we will clone the ROS snap examples repository with the following SSH URL: git@github.com:ubuntu-robotics/ros-snaps-examples.git.
While the repository is public, the use of an SSH URL requires a valid private key.

If you build a snap using an SSH URL without the appropriate SSH key, snapcraft will fail to pull the source:

Failed to pull source: command ['git', 'clone', '--recursive', 'git@github.com:ubuntu-robotics/ros-snaps-examples.git', '/root/parts/my-part/src']
exited with code 128.
Make sure sources are correctly specified.

Let’s solve this issue.

Using a private SSH key with snapcraft

For snapcraft to access a private repository via SSH, the --bind-ssh flag is used. It mounts the host ~/.ssh/ directory to the isolated environment. This way, you can clone private sources with snapcraft.

NOTE: The ssh-agent is not forwarded, so keys loaded by the agent won’t be seen by snapcraft.

Make sure the remote is known to SSH

First, ensure the host is registered in your ~/.ssh/known_hosts.

In our scenario, the host is github.com:

ssh-keygen -F github.com

If there is no output, you can add the hashes for a hostname or an address:

ssh-keyscan -H github.com >> ~/.ssh/known_hosts

Using the default key pair’s name

With a default private key (~/.ssh/id_rsa), the configuration is minimal:
A valid ~/.ssh/known_hosts and the ~/.ssh/id_rsa itself is everything you need on the host.

IMPORTANT: The private key should not be protected by a passphrase, because you won’t be prompted to enter it.

You can now build the private-source snap:

snapcraft --bind-ssh

Using non-default key pair names

If you use multiple private keys or rename a private key for any reason, additional configuration is needed.

Assume now that the private key to use is named ~/.ssh/github_rsa.

On the host, create an ssh-config file and indicate the key to use with the following entry in ~/.ssh/config:

Host github.com
    User git
    IdentityFile ~/.ssh/github_rsa

The ~/.ssh/config file is located in the ~/.ssh/ directory, so it’s affected by the --bind-ssh flag as well.
Now, build the private-source snap:

snapcraft --bind-ssh

Troubleshooting

In case a problem persists, there are a number of possible ways to approach it:

  • Use the --debug flag with snapcraft to shell into the environment after the error and test your files.
  • On the host, ensure that the private key can access the repository:
    GIT_SSH_COMMAND=‘ssh -i ~/.ssh/github_rsa -o IdentitiesOnly=yes’ \
    git clone git@github.com:ubuntu-robotics/ros-snaps-examples.git