<a id="how-share-content-between-sdks"></a>

# How to share content between SDKs

<!-- @tests in tests/docs-how-to/share-content-between-sdks/task.yaml -->
<!-- @artefact mount interface -->
<!-- @artefact interface plug -->
<!-- @artefact interface slot -->

Two SDKs in the same workshop can share a directory
through the mount interface,
without routing the content through the host.
Three pieces make up the flow:
the providing SDK declares a mount slot,
the consuming SDK declares a mount plug,
and the workshop definition pairs the two
with an explicit `connections:` entry.

Where the SDKs already declare the slot and the plug,
only the pairing is left to graft on
from the workshop definition,
and [How to add mounts to a workshop](https://ubuntu.com/workshop/docs//how-to/customize-workshops/add-mounts.md#how-add-mounts) covers that
with the shipped `uv` and `jupyter` pair.
Building the slot and the plug into SDKs you author
is the subject here.
The examples use two synthesized SDKs:
`cachekit`, which publishes a directory,
and `builder-sdk`, which reads it.

## Prerequisites

Before starting, ensure you have these requirements satisfied:

- A working **SDKcraft** installation.
- An `sdkcraft.yaml` you can edit
  for each side of the pair.
  If you don’t have one yet,
  [Craft SDKs with SDKcraft](https://ubuntu.com/workshop/docs//tutorial/part-4-craft-sdks.md#tut-craft-sdks) walks through scaffolding an SDK with
  **sdkcraft init**.
- A workshop you can launch and refresh
  on a host with **Workshop** installed.

## Declare the mount slot

The providing SDK exposes a directory with a mount slot.
`cachekit` publishes the directory it fills
so that other SDKs can read it:

```yaml
# ...

slots:
  shared:
    interface: mount
    workshop-source: /home/workshop/cachekit-share
```

`workshop-source` is the only attribute a mount slot accepts,
and [How to declare plugs and slots](https://ubuntu.com/workshop/docs//how-to/develop-sdks/declare-plugs-slots.md#how-declare-plugs-slots) covers its form.
In particular, a slot cannot mark itself read-only:
`read-only` is a plug attribute,
so each consumer decides for itself
whether it mounts the shared directory read-only.

The slot publishes the directory but never creates it.
Make sure the SDK does,
in a `setup-base` or `setup-project` hook,
or through the parts that build it.

## Declare the mount plug

The consuming SDK declares a mount plug
naming the path where the shared directory appears.
`builder-sdk` reads what `cachekit` publishes
through a plug of its own:

```yaml
# ...

plugs:
  cache:
    interface: mount
    workshop-target: /home/workshop/builder-sdk-cache
```

Neither declaration names the other SDK,
and the plug and the slot don’t have to share a name:
`builder-sdk` calls its plug `cache`
while `cachekit` calls its slot `shared`.
Nothing pairs them until the workshop definition does.

## Connect the SDKs

Listing both SDKs in a workshop is not enough to pair them.
Left to the SDKs’ own rules,
a mount plug auto-connects only to the slot the `system` SDK provides,
so `builder-sdk:cache` connects to `system:mount`
and receives a directory that **Workshop** allocates on the host,
while `cachekit:shared` stays listed but unconsumed.

To pair them, name the plug and the slot
in a top-level `connections:` entry:

```yaml
name: dev
base: ubuntu@24.04
sdks:
  - name: cachekit
  - name: builder-sdk
connections:
  - plug: builder-sdk:cache
    slot: cachekit:shared
```

Both sides use the `<SDK-NAME>:<NAME>` form.
While the pair is still unpublished,
list the SDKs under `sdks:`
with the `try-` or `project-` prefix
that matches how you’re testing them.
The prefix belongs in `sdks:` only:
`connections:` always names the bare SDK,
and a prefixed name there fails the launch as a reserved name.

Apply the change with **workshop launch**,
or **workshop refresh** for a workshop that is already running:

```console
$ workshop refresh
```

#### NOTE
A plug named in `connections:` is claimed by that entry.
It no longer falls back to `system:mount`,
so the host directory it used to receive is no longer mounted.
Removing the entry and refreshing again returns the plug to that default.

## Verify the connection

Confirm the pairing with **workshop connections**:

```console
$ workshop connections dev

  INTERFACE  PLUG                   SLOT                 NOTES
  mount      dev/builder-sdk:cache  dev/cachekit:shared  -
  mount      dev/builder-sdk:state  dev/system:mount     -
```

On the first row,
the `SLOT` column names `dev/cachekit:shared`
rather than `dev/system:mount`,
which confirms that `builder-sdk` reads from `cachekit`
instead of from a host directory.

The second row shows the default the `connections:` entry overrides.
`builder-sdk:state` is not named in the workshop definition,
so it auto-connects to `system:mount`
and receives a host directory.
A dash in the `PLUG` column marks a slot that nothing consumes,
which is what `dev/cachekit:shared` would show
if the `connections:` entry were missing.

## See also

Explanation:

- [SDK dependencies](https://ubuntu.com/workshop/docs//explanation/sdks/best-practices.md#exp-best-dependencies)
- [Mount interface](https://ubuntu.com/workshop/docs//explanation/interfaces/mount-interface.md#exp-mount-interface)
- [Plugs and slots](https://ubuntu.com/workshop/docs//explanation/interfaces/plugs-and-slots.md#exp-plugs-slots)
- [System SDK](https://ubuntu.com/workshop/docs//explanation/sdks/concepts.md#exp-system-sdk)
- [Plugs, slots, connections](https://ubuntu.com/workshop/docs//explanation/workshops/concepts.md#exp-workshop-definition-connections)

How-to guides:

- [How to add mounts to a workshop](https://ubuntu.com/workshop/docs//how-to/customize-workshops/add-mounts.md#how-add-mounts)
- [How to declare plugs and slots](https://ubuntu.com/workshop/docs//how-to/develop-sdks/declare-plugs-slots.md#how-declare-plugs-slots)
- [How to fix plug conflicts with binding](https://ubuntu.com/workshop/docs//how-to/fix-workshops/resolve-plug-conflicts.md#how-resolve-plug-conflicts)

Reference:

- [workshop connections](https://ubuntu.com/workshop/docs//reference/cli/workshop.md#ref-workshop-connections)
- [Workshop definition](https://ubuntu.com/workshop/docs//reference/definition-files/workshop-definition.md#ref-workshop-definition)

Tutorial:

- [Craft SDKs with SDKcraft](https://ubuntu.com/workshop/docs//tutorial/part-4-craft-sdks.md#tut-craft-sdks)
