Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 0 additions & 24 deletions .devcontainer/Dockerfile

This file was deleted.

7 changes: 0 additions & 7 deletions .devcontainer/devcontainer.json

This file was deleted.

18 changes: 18 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Release Dev Container feature
on:
workflow_dispatch:
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Publish Features
uses: devcontainers/action@v1
with:
publish-features: "true"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
permissions:
contents: read
packages: write
33 changes: 23 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
# Codespace with Tailscale connectivity
This repository contains a simple [codespace devcontainer](https://github.com/features/codespaces)
which can connect the running VM to a [Tailscale network](https://tailscale.com). To use it
you need to be a member of a GitHub Organization which has Codespaces enabled. When you
click on the Code button you should see a second tab with an option to start up
a new codespace.
# Codespace feature for Tailscale connectivity

This repository contains a feature for [GitHub Codespaces](https://github.com/features/codespaces)
to connect the running VM to a [Tailscale network](https://tailscale.com).

![Start a new codespace](codespace.jpg)

You need to create a [Reusable Authkey](https://login.tailscale.com/admin/settings/authkeys)
for your Tailnet and add it as a [Codespaces Secret](https://github.com/settings/codespaces)
named `TAILSCALE_AUTHKEY`.
To get started, add the following [feature](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/adding-features-to-a-devcontainer-file)
to your `devcontainer.json`:

```json
"runArgs": ["--device=/dev/net/tun"],
"features": {
// ...
"ghcr.io/tailscale/codespace/tailscale": {}
// ...
}
```

Then launch your Codespace. After it starts up, run [`tailscale up`](https://tailscale.com/kb/1080/cli/#up):

```shell
sudo tailscale up --accept-routes
```

Then launch your codespace!
You'll only need to run `tailscale up` once per Codespace.
The Tailscale state will be saved between rebuilds.
16 changes: 16 additions & 0 deletions tailscale/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "Tailscale",
"id": "tailscale",
"description": "Connect to your tailnet in your development container",
"documentationURL": "https://tailscale.com/kb/1160/github-codespaces/",
"licenseURL": "https://github.com/tailscale/codespace/blob/main/LICENSE",
"entrypoint": "/usr/local/sbin/tailscaled-entrypoint",
"capAdd": ["NET_ADMIN", "NET_RAW"],
"options": {
"version": {
"type": "string",
"default": "1.34.0",
"description": "Version of Tailscale to download"
}
}
}
42 changes: 42 additions & 0 deletions tailscale/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

set -euo pipefail

tailscale_url="https://pkgs.tailscale.com/stable/tailscale_${VERSION}_amd64.tgz"

download() {
if command -v curl >& /dev/null; then
curl -fsSL "$1"
elif command -v wget >& /dev/null; then
wget -qO - "$1"
else
echo "Must install curl or wget to download $1" 1>&2
return 1
fi
}

script_dir="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
scratch_dir="/tmp/tailscale"
mkdir -p "$scratch_dir"
trap 'rm -rf "$scratch_dir"' EXIT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this line: it seems like it deletes the /tmp/tailscale directory which the previous line should have just created.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trap ... EXIT can be thought of like a defer in Go. It runs a command once the shell exits. More docs here: https://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html


download "$tailscale_url" |
tar -xzf - --strip-components=1 -C "$scratch_dir"
install "$scratch_dir/tailscale" /usr/local/bin/tailscale
install "$scratch_dir/tailscaled" /usr/local/sbin/tailscaled
install "$script_dir/tailscaled-entrypoint.sh" /usr/local/sbin/tailscaled-entrypoint

mkdir -p /var/lib/tailscale /var/run/tailscale

if ! command -v iptables >& /dev/null; then
if command -v apt-get >& /dev/null; then
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends iptables
rm -rf /var/lib/apt/lists/*
else
echo "WARNING: iptables not installed. tailscaled might fail."
fi
fi
24 changes: 24 additions & 0 deletions tailscale/tailscaled-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash
# Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

set -euxo pipefail

if [[ "$(id -u)" -eq 0 ]]; then
mkdir -p /workspaces/.tailscale || true
/usr/local/sbin/tailscaled \
--statedir=/workspaces/.tailscale/ \
--socket=/var/run/tailscale/tailscaled.sock \
--port=41641 \
>& /dev/null &
elif command -v sudo >& /dev/null; then
sudo --non-interactive sh -c 'mkdir -p /workspaces/.tailscale ; /usr/local/sbin/tailscaled \
--statedir=/workspaces/.tailscale/ \
--socket=/var/run/tailscale/tailscaled.sock \
--port=41641 >& /dev/null' &
else
echo "tailscaled could not start as root." 1>&2
fi

exec "$@"
59 changes: 0 additions & 59 deletions tailscaled

This file was deleted.