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