/* * Default private-net * --- * Host launches http server on all interfaces in the host netns * Container must be able to connect via any IP address of the host in the * default network, which is NATed */ func TestPrivateNetDefaultConnectivity(t *testing.T) { httpServeAddr := "0.0.0.0:54321" httpServeTimeout := 30 ifaces, err := net.Interfaces() if err != nil { t.Fatalf("Cannot get network host's interfaces: %v", err) } var httpGetAddr string for _, iface := range ifaces[1:] { name := iface.Name ifaceIPsv4, err := test_netutils.GetIPsv4(name) if err != nil { t.Fatalf("Cannot get IPV4 address for interface %v: %v", name, err) } if len(ifaceIPsv4) > 0 { httpGetAddr = fmt.Sprintf("http://%v:54321", ifaceIPsv4[0]) t.Log("Telling the child to connect via", httpGetAddr) break } } if httpGetAddr == "" { t.Skipf("Can not find any NAT'able IPv4 on the host, skipping..") } testImageArgs := []string{fmt.Sprintf("--exec=/inspect --get-http=%v", httpGetAddr)} testImage := patchTestACI("rkt-inspect-networking.aci", testImageArgs...) defer os.Remove(testImage) ctx := newRktRunCtx() defer ctx.cleanup() defer ctx.reset() var wg sync.WaitGroup // Host opens the server wg.Add(1) go func() { defer wg.Done() err := test_netutils.HttpServe(httpServeAddr, httpServeTimeout) if err != nil { t.Fatalf("Error during HttpServe: %v", err) } }() // Child connects to host wg.Add(1) hostname, err := os.Hostname() go func() { defer wg.Done() cmd := fmt.Sprintf("%s --debug --insecure-skip-verify run --private-net=default --mds-register=false %s", ctx.cmd(), testImage) t.Logf("Command: %v", cmd) child, err := gexpect.Spawn(cmd) if err != nil { t.Fatalf("Cannot exec rkt: %v", err) } expectedRegex := `HTTP-Get received: (.*)\r` result, _ := child.ExpectRegexFind(expectedRegex) if len(result) == 0 { t.Fatalf("Expected %q but not found", expectedRegex) } if result[1] != hostname { t.Fatalf("Hostname received by client `%v` doesn't match `%v`", result[1], hostname) } err = child.Wait() if err != nil { t.Fatalf("rkt didn't terminate correctly: %v", err) } }() wg.Wait() }
func main() { globalFlagset.Parse(os.Args[1:]) args := globalFlagset.Args() if len(args) > 0 { fmt.Fprintln(os.Stderr, "Wrong parameters") os.Exit(1) } if globalFlags.PreSleep >= 0 { time.Sleep(time.Duration(globalFlags.PreSleep) * time.Second) } if globalFlags.ReadStdin { reader := bufio.NewReader(os.Stdin) fmt.Printf("Enter text:\n") text, _ := reader.ReadString('\n') fmt.Printf("Received text: %s\n", text) } if globalFlags.CheckTty { fd := int(os.Stdin.Fd()) var termios syscall.Termios _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TCGETS, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) if err == 0 { fmt.Printf("stdin is a terminal\n") } else { fmt.Printf("stdin is not a terminal\n") } } if globalFlags.PrintMsg != "" { fmt.Fprintf(os.Stdout, "%s\n", globalFlags.PrintMsg) messageLoopStr := os.Getenv("MESSAGE_LOOP") messageLoop, err := strconv.Atoi(messageLoopStr) if err == nil { for i := 0; i < messageLoop; i++ { time.Sleep(time.Second) fmt.Fprintf(os.Stdout, "%s\n", globalFlags.PrintMsg) } } } if globalFlags.PrintEnv != "" { fmt.Fprintf(os.Stdout, "%s=%s\n", globalFlags.PrintEnv, os.Getenv(globalFlags.PrintEnv)) } if globalFlags.PrintCapsPid >= 0 { caps, err := capability.NewPid(globalFlags.PrintCapsPid) if err != nil { fmt.Fprintf(os.Stderr, "Cannot get caps: %v\n", err) os.Exit(1) return } fmt.Printf("Capability set: effective: %s\n", caps.StringCap(capability.EFFECTIVE)) fmt.Printf("Capability set: permitted: %s\n", caps.StringCap(capability.PERMITTED)) fmt.Printf("Capability set: inheritable: %s\n", caps.StringCap(capability.INHERITABLE)) fmt.Printf("Capability set: bounding: %s\n", caps.StringCap(capability.BOUNDING)) if capStr := os.Getenv("CAPABILITY"); capStr != "" { capInt, err := strconv.Atoi(capStr) if err != nil { fmt.Fprintf(os.Stderr, "Environment variable $CAPABILITY is not a valid capability number: %v\n", err) os.Exit(1) return } c := capability.Cap(capInt) if caps.Get(capability.BOUNDING, c) { fmt.Printf("%v=enabled\n", c.String()) } else { fmt.Printf("%v=disabled\n", c.String()) } } } if globalFlags.PrintUser { fmt.Printf("User: uid=%d euid=%d gid=%d egid=%d\n", os.Getuid(), os.Geteuid(), os.Getgid(), os.Getegid()) } if globalFlags.WriteFile { fileName := os.Getenv("FILE") if globalFlags.FileName != "" { fileName = globalFlags.FileName } content := os.Getenv("CONTENT") if globalFlags.Content != "" { content = globalFlags.Content } err := ioutil.WriteFile(fileName, []byte(content), 0600) if err != nil { fmt.Fprintf(os.Stderr, "Cannot write to file %q: %v\n", fileName, err) os.Exit(1) return } } if globalFlags.ReadFile { fileName := os.Getenv("FILE") if globalFlags.FileName != "" { fileName = globalFlags.FileName } dat, err := ioutil.ReadFile(fileName) if err != nil { fmt.Fprintf(os.Stderr, "Cannot read file %q: %v\n", fileName, err) os.Exit(1) return } fmt.Print("<<<") fmt.Print(string(dat)) fmt.Print(">>>\n") } if globalFlags.CheckCwd != "" { wd, err := os.Getwd() if err != nil { fmt.Fprintf(os.Stderr, "Cannot get working directory: %v\n", err) os.Exit(1) } if wd != globalFlags.CheckCwd { fmt.Fprintf(os.Stderr, "Working directory: %q. Expected: %q.\n", wd, globalFlags.CheckCwd) os.Exit(1) } } if globalFlags.Sleep >= 0 { time.Sleep(time.Duration(globalFlags.Sleep) * time.Second) } if globalFlags.PrintMemoryLimit { memCgroupPath, err := cgroup.GetOwnCgroupPath("memory") if err != nil { fmt.Fprintf(os.Stderr, "Error getting own memory cgroup path: %v\n", err) os.Exit(1) } // we use /proc/1/root to escape the chroot we're in and read our // memory limit limitPath := filepath.Join("/proc/1/root/sys/fs/cgroup/memory", memCgroupPath, "memory.limit_in_bytes") limit, err := ioutil.ReadFile(limitPath) if err != nil { fmt.Fprintf(os.Stderr, "Can't read memory.limit_in_bytes\n") os.Exit(1) } fmt.Printf("Memory Limit: %s\n", string(limit)) } if globalFlags.PrintCPUQuota { cpuCgroupPath, err := cgroup.GetOwnCgroupPath("cpu") if err != nil { fmt.Fprintf(os.Stderr, "Error getting own cpu cgroup path: %v\n", err) os.Exit(1) } // we use /proc/1/root to escape the chroot we're in and read our // cpu quota periodPath := filepath.Join("/proc/1/root/sys/fs/cgroup/cpu", cpuCgroupPath, "cpu.cfs_period_us") periodBytes, err := ioutil.ReadFile(periodPath) if err != nil { fmt.Fprintf(os.Stderr, "Can't read cpu.cpu_period_us\n") os.Exit(1) } quotaPath := filepath.Join("/proc/1/root/sys/fs/cgroup/cpu", cpuCgroupPath, "cpu.cfs_quota_us") quotaBytes, err := ioutil.ReadFile(quotaPath) if err != nil { fmt.Fprintf(os.Stderr, "Can't read cpu.cpu_quota_us\n") os.Exit(1) } period, err := strconv.Atoi(strings.Trim(string(periodBytes), "\n")) if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } quota, err := strconv.Atoi(strings.Trim(string(quotaBytes), "\n")) if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } quotaMilliCores := quota * 1000 / period fmt.Printf("CPU Quota: %s\n", strconv.Itoa(quotaMilliCores)) } if globalFlags.CheckCgroupMounts { rootCgroupPath := "/proc/1/root/sys/fs/cgroup" testPaths := []string{rootCgroupPath} // test a couple of controllers if they're available if cgroup.IsIsolatorSupported("memory") { testPaths = append(testPaths, filepath.Join(rootCgroupPath, "memory")) } if cgroup.IsIsolatorSupported("cpu") { testPaths = append(testPaths, filepath.Join(rootCgroupPath, "cpu")) } for _, p := range testPaths { if err := syscall.Mkdir(filepath.Join(p, "test"), 0600); err == nil || err != syscall.EROFS { fmt.Println("check-cgroups: FAIL") os.Exit(1) } } fmt.Println("check-cgroups: SUCCESS") } if globalFlags.PrintNetNS { ns, err := os.Readlink("/proc/self/ns/net") if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } fmt.Printf("NetNS: %s\n", ns) } if globalFlags.PrintIPv4 != "" { iface := globalFlags.PrintIPv4 ips, err := test_netutils.GetIPsv4(iface) if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } fmt.Printf("%v IPv4: %s\n", iface, ips[0]) } if globalFlags.PrintDefaultGWv4 { gw, err := test_netutils.GetDefaultGWv4() if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } fmt.Printf("DefaultGWv4: %s\n", gw) } if globalFlags.PrintDefaultGWv6 { gw, err := test_netutils.GetDefaultGWv6() if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } fmt.Printf("DefaultGWv6: %s\n", gw) } if globalFlags.PrintGWv4 != "" { // TODO: GetGW not implemented yet iface := globalFlags.PrintGWv4 gw, err := test_netutils.GetGWv4(iface) if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } fmt.Printf("%v GWv4: %s\n", iface, gw) } if globalFlags.PrintIPv6 != "" { // TODO } if globalFlags.PrintGWv6 != "" { // TODO } if globalFlags.ServeHttp != "" { err := test_netutils.HttpServe(globalFlags.ServeHttp, globalFlags.ServeHttpTimeout) if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } } if globalFlags.GetHttp != "" { body, err := test_netutils.HttpGet(globalFlags.GetHttp) if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } fmt.Printf("HTTP-Get received: %s\n", body) } os.Exit(globalFlags.ExitCode) }