|
|
@ -33,6 +33,7 @@ import (
|
|
|
|
"golang.org/x/sys/unix"
|
|
|
|
"golang.org/x/sys/unix"
|
|
|
|
"tailscale.com/ipn/ipnstate"
|
|
|
|
"tailscale.com/ipn/ipnstate"
|
|
|
|
"tailscale.com/tailcfg"
|
|
|
|
"tailscale.com/tailcfg"
|
|
|
|
|
|
|
|
"tailscale.com/tstest"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
func TestContainerBoot(t *testing.T) {
|
|
|
|
func TestContainerBoot(t *testing.T) {
|
|
|
@ -97,31 +98,44 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
// step. Right now all of containerboot's modes either converge
|
|
|
|
// step. Right now all of containerboot's modes either converge
|
|
|
|
// with no further interaction needed, or with one extra step
|
|
|
|
// with no further interaction needed, or with one extra step
|
|
|
|
// only.
|
|
|
|
// only.
|
|
|
|
tests := []struct {
|
|
|
|
type phase struct {
|
|
|
|
Name string
|
|
|
|
// Make LocalAPI report this status, then wait for the Wants below to be
|
|
|
|
Env map[string]string
|
|
|
|
// satisfied. A zero Status is a valid state for a just-started
|
|
|
|
KubeSecret map[string]string
|
|
|
|
// tailscaled.
|
|
|
|
WantArgs1 []string // Wait for containerboot to run these commands...
|
|
|
|
Status ipnstate.Status
|
|
|
|
Status1 ipnstate.Status // ... then report this status in LocalAPI.
|
|
|
|
|
|
|
|
WantArgs2 []string // If non-nil, wait for containerboot to run these additional commands...
|
|
|
|
// WantCmds is the commands that containerboot should run in this phase.
|
|
|
|
Status2 ipnstate.Status // ... then report this status in LocalAPI.
|
|
|
|
WantCmds []string
|
|
|
|
|
|
|
|
// WantKubeSecret is the secret keys/values that should exist in the
|
|
|
|
|
|
|
|
// kube secret.
|
|
|
|
WantKubeSecret map[string]string
|
|
|
|
WantKubeSecret map[string]string
|
|
|
|
WantFiles map[string]string
|
|
|
|
// WantFiles files that should exist in the container and their
|
|
|
|
|
|
|
|
// contents.
|
|
|
|
|
|
|
|
WantFiles map[string]string
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
|
|
|
Name string
|
|
|
|
|
|
|
|
Env map[string]string
|
|
|
|
|
|
|
|
KubeSecret map[string]string
|
|
|
|
|
|
|
|
Phases []phase
|
|
|
|
}{
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Out of the box default: runs in userspace mode, ephemeral storage, interactive login.
|
|
|
|
// Out of the box default: runs in userspace mode, ephemeral storage, interactive login.
|
|
|
|
Name: "no_args",
|
|
|
|
Name: "no_args",
|
|
|
|
Env: nil,
|
|
|
|
Env: nil,
|
|
|
|
WantArgs1: []string{
|
|
|
|
Phases: []phase{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp --tun=userspace-networking",
|
|
|
|
{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false",
|
|
|
|
WantCmds: []string{
|
|
|
|
},
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp --tun=userspace-networking",
|
|
|
|
// The tailscale up call blocks until auth is complete, so
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false",
|
|
|
|
// by the time it returns the next converged state is
|
|
|
|
},
|
|
|
|
// Running.
|
|
|
|
},
|
|
|
|
Status1: ipnstate.Status{
|
|
|
|
{
|
|
|
|
BackendState: "Running",
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
BackendState: "Running",
|
|
|
|
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -130,13 +144,19 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
Env: map[string]string{
|
|
|
|
Env: map[string]string{
|
|
|
|
"TS_AUTH_KEY": "tskey-key",
|
|
|
|
"TS_AUTH_KEY": "tskey-key",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantArgs1: []string{
|
|
|
|
Phases: []phase{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp --tun=userspace-networking",
|
|
|
|
{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key",
|
|
|
|
WantCmds: []string{
|
|
|
|
},
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp --tun=userspace-networking",
|
|
|
|
Status1: ipnstate.Status{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key",
|
|
|
|
BackendState: "Running",
|
|
|
|
},
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
|
|
|
|
BackendState: "Running",
|
|
|
|
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -145,13 +165,19 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
"TS_AUTH_KEY": "tskey-key",
|
|
|
|
"TS_AUTH_KEY": "tskey-key",
|
|
|
|
"TS_STATE_DIR": filepath.Join(d, "tmp"),
|
|
|
|
"TS_STATE_DIR": filepath.Join(d, "tmp"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantArgs1: []string{
|
|
|
|
Phases: []phase{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --statedir=/tmp --tun=userspace-networking",
|
|
|
|
{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key",
|
|
|
|
WantCmds: []string{
|
|
|
|
},
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --statedir=/tmp --tun=userspace-networking",
|
|
|
|
Status1: ipnstate.Status{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key",
|
|
|
|
BackendState: "Running",
|
|
|
|
},
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
|
|
|
|
BackendState: "Running",
|
|
|
|
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -160,17 +186,23 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
"TS_AUTH_KEY": "tskey-key",
|
|
|
|
"TS_AUTH_KEY": "tskey-key",
|
|
|
|
"TS_ROUTES": "1.2.3.0/24,10.20.30.0/24",
|
|
|
|
"TS_ROUTES": "1.2.3.0/24,10.20.30.0/24",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantArgs1: []string{
|
|
|
|
Phases: []phase{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp --tun=userspace-networking",
|
|
|
|
{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key --advertise-routes=1.2.3.0/24,10.20.30.0/24",
|
|
|
|
WantCmds: []string{
|
|
|
|
},
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp --tun=userspace-networking",
|
|
|
|
Status1: ipnstate.Status{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key --advertise-routes=1.2.3.0/24,10.20.30.0/24",
|
|
|
|
BackendState: "Running",
|
|
|
|
},
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
WantFiles: map[string]string{
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
"proc/sys/net/ipv4/ip_forward": "0",
|
|
|
|
BackendState: "Running",
|
|
|
|
"proc/sys/net/ipv6/conf/all/forwarding": "0",
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
WantFiles: map[string]string{
|
|
|
|
|
|
|
|
"proc/sys/net/ipv4/ip_forward": "0",
|
|
|
|
|
|
|
|
"proc/sys/net/ipv6/conf/all/forwarding": "0",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -180,17 +212,23 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
"TS_ROUTES": "1.2.3.0/24,10.20.30.0/24",
|
|
|
|
"TS_ROUTES": "1.2.3.0/24,10.20.30.0/24",
|
|
|
|
"TS_USERSPACE": "false",
|
|
|
|
"TS_USERSPACE": "false",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantArgs1: []string{
|
|
|
|
Phases: []phase{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp",
|
|
|
|
{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key --advertise-routes=1.2.3.0/24,10.20.30.0/24",
|
|
|
|
WantCmds: []string{
|
|
|
|
},
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp",
|
|
|
|
Status1: ipnstate.Status{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key --advertise-routes=1.2.3.0/24,10.20.30.0/24",
|
|
|
|
BackendState: "Running",
|
|
|
|
},
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
WantFiles: map[string]string{
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
"proc/sys/net/ipv4/ip_forward": "1",
|
|
|
|
BackendState: "Running",
|
|
|
|
"proc/sys/net/ipv6/conf/all/forwarding": "0",
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
WantFiles: map[string]string{
|
|
|
|
|
|
|
|
"proc/sys/net/ipv4/ip_forward": "1",
|
|
|
|
|
|
|
|
"proc/sys/net/ipv6/conf/all/forwarding": "0",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -200,17 +238,23 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
"TS_ROUTES": "::/64,1::/64",
|
|
|
|
"TS_ROUTES": "::/64,1::/64",
|
|
|
|
"TS_USERSPACE": "false",
|
|
|
|
"TS_USERSPACE": "false",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantArgs1: []string{
|
|
|
|
Phases: []phase{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp",
|
|
|
|
{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key --advertise-routes=::/64,1::/64",
|
|
|
|
WantCmds: []string{
|
|
|
|
},
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp",
|
|
|
|
Status1: ipnstate.Status{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key --advertise-routes=::/64,1::/64",
|
|
|
|
BackendState: "Running",
|
|
|
|
},
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
WantFiles: map[string]string{
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
"proc/sys/net/ipv4/ip_forward": "0",
|
|
|
|
BackendState: "Running",
|
|
|
|
"proc/sys/net/ipv6/conf/all/forwarding": "1",
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
WantFiles: map[string]string{
|
|
|
|
|
|
|
|
"proc/sys/net/ipv4/ip_forward": "0",
|
|
|
|
|
|
|
|
"proc/sys/net/ipv6/conf/all/forwarding": "1",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -220,17 +264,23 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
"TS_ROUTES": "::/64,1.2.3.0/24",
|
|
|
|
"TS_ROUTES": "::/64,1.2.3.0/24",
|
|
|
|
"TS_USERSPACE": "false",
|
|
|
|
"TS_USERSPACE": "false",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantArgs1: []string{
|
|
|
|
Phases: []phase{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp",
|
|
|
|
{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key --advertise-routes=::/64,1.2.3.0/24",
|
|
|
|
WantCmds: []string{
|
|
|
|
},
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp",
|
|
|
|
Status1: ipnstate.Status{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key --advertise-routes=::/64,1.2.3.0/24",
|
|
|
|
BackendState: "Running",
|
|
|
|
},
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
WantFiles: map[string]string{
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
"proc/sys/net/ipv4/ip_forward": "1",
|
|
|
|
BackendState: "Running",
|
|
|
|
"proc/sys/net/ipv6/conf/all/forwarding": "1",
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
WantFiles: map[string]string{
|
|
|
|
|
|
|
|
"proc/sys/net/ipv4/ip_forward": "1",
|
|
|
|
|
|
|
|
"proc/sys/net/ipv6/conf/all/forwarding": "1",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -240,20 +290,22 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
"TS_DEST_IP": "1.2.3.4",
|
|
|
|
"TS_DEST_IP": "1.2.3.4",
|
|
|
|
"TS_USERSPACE": "false",
|
|
|
|
"TS_USERSPACE": "false",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantArgs1: []string{
|
|
|
|
Phases: []phase{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp",
|
|
|
|
{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key",
|
|
|
|
WantCmds: []string{
|
|
|
|
},
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp",
|
|
|
|
Status1: ipnstate.Status{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key",
|
|
|
|
BackendState: "Running",
|
|
|
|
},
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
WantArgs2: []string{
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
"/usr/bin/iptables -t nat -I PREROUTING 1 -d 100.64.0.1 -j DNAT --to-destination 1.2.3.4",
|
|
|
|
BackendState: "Running",
|
|
|
|
},
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
Status2: ipnstate.Status{
|
|
|
|
},
|
|
|
|
BackendState: "Running",
|
|
|
|
WantCmds: []string{
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
"/usr/bin/iptables -t nat -I PREROUTING 1 -d 100.64.0.1 -j DNAT --to-destination 1.2.3.4",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -262,18 +314,26 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
"TS_AUTH_KEY": "tskey-key",
|
|
|
|
"TS_AUTH_KEY": "tskey-key",
|
|
|
|
"TS_AUTH_ONCE": "true",
|
|
|
|
"TS_AUTH_ONCE": "true",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantArgs1: []string{
|
|
|
|
Phases: []phase{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp --tun=userspace-networking",
|
|
|
|
{
|
|
|
|
},
|
|
|
|
WantCmds: []string{
|
|
|
|
Status1: ipnstate.Status{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp --tun=userspace-networking",
|
|
|
|
BackendState: "NeedsLogin",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantArgs2: []string{
|
|
|
|
{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key",
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
},
|
|
|
|
BackendState: "NeedsLogin",
|
|
|
|
Status2: ipnstate.Status{
|
|
|
|
},
|
|
|
|
BackendState: "Running",
|
|
|
|
WantCmds: []string{
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
|
|
|
|
BackendState: "Running",
|
|
|
|
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -285,20 +345,29 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
KubeSecret: map[string]string{
|
|
|
|
KubeSecret: map[string]string{
|
|
|
|
"authkey": "tskey-key",
|
|
|
|
"authkey": "tskey-key",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantArgs1: []string{
|
|
|
|
Phases: []phase{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=kube:tailscale --statedir=/tmp --tun=userspace-networking",
|
|
|
|
{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key",
|
|
|
|
WantCmds: []string{
|
|
|
|
},
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=kube:tailscale --statedir=/tmp --tun=userspace-networking",
|
|
|
|
Status1: ipnstate.Status{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key",
|
|
|
|
BackendState: "Running",
|
|
|
|
},
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
WantKubeSecret: map[string]string{
|
|
|
|
Self: &ipnstate.PeerStatus{
|
|
|
|
"authkey": "tskey-key",
|
|
|
|
ID: tailcfg.StableNodeID("myID"),
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
|
|
|
|
BackendState: "Running",
|
|
|
|
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
|
|
|
|
Self: &ipnstate.PeerStatus{
|
|
|
|
|
|
|
|
ID: tailcfg.StableNodeID("myID"),
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
WantKubeSecret: map[string]string{
|
|
|
|
|
|
|
|
"authkey": "tskey-key",
|
|
|
|
|
|
|
|
"device_id": "myID",
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
WantKubeSecret: map[string]string{
|
|
|
|
|
|
|
|
"authkey": "tskey-key",
|
|
|
|
|
|
|
|
"device_id": "myID",
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -312,24 +381,38 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
KubeSecret: map[string]string{
|
|
|
|
KubeSecret: map[string]string{
|
|
|
|
"authkey": "tskey-key",
|
|
|
|
"authkey": "tskey-key",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantArgs1: []string{
|
|
|
|
Phases: []phase{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=kube:tailscale --statedir=/tmp --tun=userspace-networking",
|
|
|
|
{
|
|
|
|
},
|
|
|
|
WantCmds: []string{
|
|
|
|
Status1: ipnstate.Status{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=kube:tailscale --statedir=/tmp --tun=userspace-networking",
|
|
|
|
BackendState: "NeedsLogin",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantKubeSecret: map[string]string{
|
|
|
|
WantArgs2: []string{
|
|
|
|
"authkey": "tskey-key",
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Status2: ipnstate.Status{
|
|
|
|
{
|
|
|
|
BackendState: "Running",
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
BackendState: "NeedsLogin",
|
|
|
|
Self: &ipnstate.PeerStatus{
|
|
|
|
},
|
|
|
|
ID: tailcfg.StableNodeID("myID"),
|
|
|
|
WantCmds: []string{
|
|
|
|
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
WantKubeSecret: map[string]string{
|
|
|
|
|
|
|
|
"authkey": "tskey-key",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
|
|
|
|
BackendState: "Running",
|
|
|
|
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
|
|
|
|
Self: &ipnstate.PeerStatus{
|
|
|
|
|
|
|
|
ID: tailcfg.StableNodeID("myID"),
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
WantKubeSecret: map[string]string{
|
|
|
|
|
|
|
|
"device_id": "myID",
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
WantKubeSecret: map[string]string{
|
|
|
|
|
|
|
|
"device_id": "myID",
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -338,16 +421,22 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
"TS_SOCKS5_SERVER": "localhost:1080",
|
|
|
|
"TS_SOCKS5_SERVER": "localhost:1080",
|
|
|
|
"TS_OUTBOUND_HTTP_PROXY_LISTEN": "localhost:8080",
|
|
|
|
"TS_OUTBOUND_HTTP_PROXY_LISTEN": "localhost:8080",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantArgs1: []string{
|
|
|
|
Phases: []phase{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp --tun=userspace-networking --socks5-server=localhost:1080 --outbound-http-proxy-listen=localhost:8080",
|
|
|
|
{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false",
|
|
|
|
WantCmds: []string{
|
|
|
|
},
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp --tun=userspace-networking --socks5-server=localhost:1080 --outbound-http-proxy-listen=localhost:8080",
|
|
|
|
// The tailscale up call blocks until auth is complete, so
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false",
|
|
|
|
// by the time it returns the next converged state is
|
|
|
|
},
|
|
|
|
// Running.
|
|
|
|
},
|
|
|
|
Status1: ipnstate.Status{
|
|
|
|
{
|
|
|
|
BackendState: "Running",
|
|
|
|
// The tailscale up call blocks until auth is complete, so
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
// by the time it returns the next converged state is
|
|
|
|
|
|
|
|
// Running.
|
|
|
|
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
|
|
|
|
BackendState: "Running",
|
|
|
|
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -355,13 +444,19 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
Env: map[string]string{
|
|
|
|
Env: map[string]string{
|
|
|
|
"TS_ACCEPT_DNS": "true",
|
|
|
|
"TS_ACCEPT_DNS": "true",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantArgs1: []string{
|
|
|
|
Phases: []phase{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp --tun=userspace-networking",
|
|
|
|
{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=true",
|
|
|
|
WantCmds: []string{
|
|
|
|
},
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp --tun=userspace-networking",
|
|
|
|
Status1: ipnstate.Status{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=true",
|
|
|
|
BackendState: "Running",
|
|
|
|
},
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
|
|
|
|
BackendState: "Running",
|
|
|
|
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -370,13 +465,18 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
"TS_EXTRA_ARGS": "--widget=rotated",
|
|
|
|
"TS_EXTRA_ARGS": "--widget=rotated",
|
|
|
|
"TS_TAILSCALED_EXTRA_ARGS": "--experiments=widgets",
|
|
|
|
"TS_TAILSCALED_EXTRA_ARGS": "--experiments=widgets",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
WantArgs1: []string{
|
|
|
|
Phases: []phase{
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp --tun=userspace-networking --experiments=widgets",
|
|
|
|
{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --widget=rotated",
|
|
|
|
WantCmds: []string{
|
|
|
|
},
|
|
|
|
"/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --state=mem: --statedir=/tmp --tun=userspace-networking --experiments=widgets",
|
|
|
|
Status1: ipnstate.Status{
|
|
|
|
"/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --widget=rotated",
|
|
|
|
BackendState: "Running",
|
|
|
|
},
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
}, {
|
|
|
|
|
|
|
|
Status: ipnstate.Status{
|
|
|
|
|
|
|
|
BackendState: "Running",
|
|
|
|
|
|
|
|
TailscaleIPs: tsIPs,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -419,35 +519,45 @@ func TestContainerBoot(t *testing.T) {
|
|
|
|
cmd.Process.Wait()
|
|
|
|
cmd.Process.Wait()
|
|
|
|
}()
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
|
|
waitArgs(t, 2*time.Second, d, argFile, strings.Join(test.WantArgs1, "\n"))
|
|
|
|
var wantCmds []string
|
|
|
|
lapi.SetStatus(test.Status1)
|
|
|
|
for _, p := range test.Phases {
|
|
|
|
if test.WantArgs2 != nil {
|
|
|
|
lapi.SetStatus(p.Status)
|
|
|
|
waitArgs(t, 2*time.Second, d, argFile, strings.Join(append(test.WantArgs1, test.WantArgs2...), "\n"))
|
|
|
|
wantCmds = append(wantCmds, p.WantCmds...)
|
|
|
|
lapi.SetStatus(test.Status2)
|
|
|
|
waitArgs(t, 2*time.Second, d, argFile, strings.Join(wantCmds, "\n"))
|
|
|
|
}
|
|
|
|
err := tstest.WaitFor(2*time.Second, func() error {
|
|
|
|
waitLogLine(t, 2*time.Second, cbOut, "Startup complete, waiting for shutdown signal")
|
|
|
|
if p.WantKubeSecret != nil {
|
|
|
|
|
|
|
|
got := kube.Secret()
|
|
|
|
if test.WantKubeSecret != nil {
|
|
|
|
if diff := cmp.Diff(got, p.WantKubeSecret); diff != "" {
|
|
|
|
got := kube.Secret()
|
|
|
|
return fmt.Errorf("unexpected kube secret data (-got+want):\n%s", diff)
|
|
|
|
if diff := cmp.Diff(got, test.WantKubeSecret); diff != "" {
|
|
|
|
}
|
|
|
|
t.Fatalf("unexpected kube secret data (-got+want):\n%s", diff)
|
|
|
|
} else {
|
|
|
|
}
|
|
|
|
got := kube.Secret()
|
|
|
|
} else {
|
|
|
|
if len(got) > 0 {
|
|
|
|
got := kube.Secret()
|
|
|
|
return fmt.Errorf("kube secret unexpectedly not empty, got %#v", got)
|
|
|
|
if len(got) != 0 {
|
|
|
|
}
|
|
|
|
t.Fatalf("kube secret unexpectedly not empty, got %#v", got)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
for path, want := range test.WantFiles {
|
|
|
|
|
|
|
|
gotBs, err := os.ReadFile(filepath.Join(d, path))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("reading wanted file %q: %v", path, err)
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if got := strings.TrimSpace(string(gotBs)); got != want {
|
|
|
|
err = tstest.WaitFor(2*time.Second, func() error {
|
|
|
|
t.Errorf("wrong file contents for %q, got %q want %q", path, got, want)
|
|
|
|
for path, want := range p.WantFiles {
|
|
|
|
|
|
|
|
gotBs, err := os.ReadFile(filepath.Join(d, path))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return fmt.Errorf("reading wanted file %q: %v", path, err)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if got := strings.TrimSpace(string(gotBs)); got != want {
|
|
|
|
|
|
|
|
return fmt.Errorf("wrong file contents for %q, got %q want %q", path, got, want)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
waitLogLine(t, 2*time.Second, cbOut, "Startup complete, waiting for shutdown signal")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|