diff --git a/test/images/BUILD b/test/images/BUILD index 47ea674f016e..2f887f0b6443 100644 --- a/test/images/BUILD +++ b/test/images/BUILD @@ -15,15 +15,12 @@ filegroup( "//test/images/apparmor-loader:all-srcs", "//test/images/echoserver:all-srcs", "//test/images/metadata-concealment:all-srcs", - "//test/images/mounttest:all-srcs", "//test/images/nonewprivs:all-srcs", "//test/images/pets/peer-finder:all-srcs", "//test/images/regression-issue-74839:all-srcs", "//test/images/resource-consumer:all-srcs", - "//test/images/resource-consumer-controller:all-srcs", "//test/images/sample-apiserver:all-srcs", "//test/images/sample-device-plugin:all-srcs", - "//test/images/test-webserver:all-srcs", ], tags = ["automanaged"], ) diff --git a/test/images/agnhost/BUILD b/test/images/agnhost/BUILD index d8fd2c4dc72d..95559ea5e23a 100644 --- a/test/images/agnhost/BUILD +++ b/test/images/agnhost/BUILD @@ -26,6 +26,7 @@ go_library( "//test/images/agnhost/inclusterclient:go_default_library", "//test/images/agnhost/liveness:go_default_library", "//test/images/agnhost/logs-generator:go_default_library", + "//test/images/agnhost/mounttest:go_default_library", "//test/images/agnhost/net:go_default_library", "//test/images/agnhost/netexec:go_default_library", "//test/images/agnhost/nettest:go_default_library", @@ -34,7 +35,9 @@ go_library( "//test/images/agnhost/pause:go_default_library", "//test/images/agnhost/port-forward-tester:go_default_library", "//test/images/agnhost/porter:go_default_library", + "//test/images/agnhost/resource-consumer-controller:go_default_library", "//test/images/agnhost/serve-hostname:go_default_library", + "//test/images/agnhost/test-webserver:go_default_library", "//test/images/agnhost/webhook:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library", "//vendor/k8s.io/klog:go_default_library", @@ -62,6 +65,7 @@ filegroup( "//test/images/agnhost/inclusterclient:all-srcs", "//test/images/agnhost/liveness:all-srcs", "//test/images/agnhost/logs-generator:all-srcs", + "//test/images/agnhost/mounttest:all-srcs", "//test/images/agnhost/net:all-srcs", "//test/images/agnhost/netexec:all-srcs", "//test/images/agnhost/nettest:all-srcs", @@ -70,7 +74,9 @@ filegroup( "//test/images/agnhost/pause:all-srcs", "//test/images/agnhost/port-forward-tester:all-srcs", "//test/images/agnhost/porter:all-srcs", + "//test/images/agnhost/resource-consumer-controller:all-srcs", "//test/images/agnhost/serve-hostname:all-srcs", + "//test/images/agnhost/test-webserver:all-srcs", "//test/images/agnhost/webhook:all-srcs", ], tags = ["automanaged"], diff --git a/test/images/agnhost/Dockerfile b/test/images/agnhost/Dockerfile index d4c9d967f01a..c551802c7928 100644 --- a/test/images/agnhost/Dockerfile +++ b/test/images/agnhost/Dockerfile @@ -16,6 +16,10 @@ FROM BASEIMAGE CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/ +# from dnsutils image +# install necessary packages: +# - bind-tools: contains dig, which can used in DNS tests. +# - CoreDNS: used in some DNS tests. # from hostexec image # install necessary packages: # - curl, nc: used by a lot of e2e tests @@ -26,10 +30,14 @@ RUN apk --update add bind-tools curl netcat-openbsd iproute2 iperf bash && rm -r && ln -s /usr/bin/iperf /usr/local/bin/iperf \ && ls -altrh /usr/local/bin/iperf -# PORT 8080 needed by: netexec, nettest +ADD https://github.com/coredns/coredns/releases/download/v1.6.2/coredns_1.6.2_linux_BASEARCH.tgz /coredns.tgz +RUN tar -xzvf /coredns.tgz && rm -f /coredns.tgz + +# PORT 80 needed by: test-webserver +# PORT 8080 needed by: netexec, nettest, resource-consumer, resource-consumer-controller # PORT 8081 needed by: netexec # PORT 9376 needed by: serve-hostname -EXPOSE 8080 8081 9376 +EXPOSE 80 8080 8081 9376 # from netexec RUN mkdir /uploads diff --git a/test/images/agnhost/README.md b/test/images/agnhost/README.md index 29687939fe19..aa89ec59c303 100644 --- a/test/images/agnhost/README.md +++ b/test/images/agnhost/README.md @@ -40,7 +40,7 @@ For example, let's consider the following `pod.yaml` file: containers: - args: - dns-suffix - image: gcr.io/kubernetes-e2e-test-images/agnhost:2.8 + image: gcr.io/kubernetes-e2e-test-images/agnhost:2.9 name: agnhost dnsConfig: nameservers: @@ -290,14 +290,14 @@ Examples: ```console docker run -i \ - gcr.io/kubernetes-e2e-test-images/agnhost:2.8 \ + gcr.io/kubernetes-e2e-test-images/agnhost:2.9 \ logs-generator --log-lines-total 10 --run-duration 1s ``` ```console kubectl run logs-generator \ --generator=run-pod/v1 \ - --image=gcr.io/kubernetes-e2e-test-images/agnhost:2.8 \ + --image=gcr.io/kubernetes-e2e-test-images/agnhost:2.9 \ --restart=Never \ -- logs-generator -t 10 -d 1s ``` @@ -305,6 +305,37 @@ kubectl run logs-generator \ [![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/test/images/logs-generator/README.md?pixel)]() +### mounttest + +The `mounttest` subcommand can be used to create files with various permissions, read files, +and output file system type, mode, owner, and permissions for any given file. + +The subcommand can accept the following flags: + +- `fs_type`: Path to print the FS type for. +- `file_mode`: Path to print the mode bits of. +- `file_perm`: Path to print the perms of. +- `file_owner`: Path to print the owning UID and GID of. +- `new_file_0644`: Path to write to and read from with perm 0644. +- `new_file_0666`: Path to write to and read from with perm 0666. +- `new_file_0660`: Path to write to and read from with perm 0660. +- `new_file_0777`: Path to write to and read from with perm 0777. +- `file_content`: Path to read the file content from. +- `file_content_in_loop`: Path to read the file content in loop from. +- `retry_time` (default: 180): Retry time during the loop. +- `break_on_expected_content` (default: true): Break out of loop on expected content (use with `--file_content_in_loop` flag only). + +Usage: + +```console + kubectl exec test-agnhost -- /agnhost mounttest \ + [--fs_type ] [--file_mode ] [--file_perm ] [--file_owner ] \ + [--new_file_0644 ] [--new_file_0666 ] [--new_file_0660 ] [--new_file_0777 ] \ + [--file_content ] [--file_content_in_loop ] \ + [--retry_time ] [--break_on_expected_content ] +``` + + ### net The goal of this Go project is to consolidate all low-level @@ -424,7 +455,7 @@ Usage: ```console kubectl run test-agnhost \ --generator=run-pod/v1 \ - --image=gcr.io/kubernetes-e2e-test-images/agnhost:2.8 \ + --image=gcr.io/kubernetes-e2e-test-images/agnhost:2.9 \ --restart=Never \ --env "POD_IP=" \ --env "NODE_IP=" \ @@ -479,7 +510,7 @@ Usage: ```console kubectl run test-agnhost \ --generator=run-pod/v1 \ - --image=gcr.io/kubernetes-e2e-test-images/agnhost:2.8 \ + --image=gcr.io/kubernetes-e2e-test-images/agnhost:2.9 \ --restart=Never \ --env "BIND_ADDRESS=localhost" \ --env "BIND_PORT=8080" \ @@ -517,6 +548,25 @@ Usage: [![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/test/images/porter/README.md?pixel)]() +### resource-consumer-controller + +This subcommand starts an HTTP server that spreads requests around resource consumers. The HTTP server has the same endpoints and usage as the one spawned by the ``resource-consumer`` subcommand. + +The subcommand can accept the following flags: + +- `port` (default: 8080): The port number to listen to. +- `consumer-port` (default: 8080): Port number of consumers. +- `consumer-service-name` (default: `resource-consumer`): Name of service containing resource consumers. +- `consumer-service-namespace` (default: `default`): Namespace of service containing resource consumers. + +Usage: + +```console + kubectl exec test-agnhost -- /agnhost resource-consumer-controller \ + [--port ] [--consumer-port ] [--consumer-service-name ] [--consumer-service-namespace ] +``` + + ### serve-hostname This is a small util app to serve your hostname on TCP and/or UDP. Useful for testing. @@ -542,6 +592,21 @@ Usage: [![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/test/images/serve_hostname/README.md?pixel)]() +### test-webserver + +Starts a simple HTTP fileserver which serves any file specified in the URL path, if it exists. + +The subcommand can accept the following flags: + +- `port` (default: `80`): The port number to listen to. + +Usage: + +```console + kubectl exec test-agnhost -- /agnhost test-webserver [--port ] +``` + + ### webhook (Kubernetes External Admission Webhook) The subcommand tests MutatingAdmissionWebhook and ValidatingAdmissionWebhook. After deploying @@ -561,11 +626,11 @@ Usage: ## Other tools -The image contains `iperf`. +The image contains `iperf`, `curl`, `dns-tools` (including `dig`), CoreDNS. ## Image -The image can be found at `gcr.io/kubernetes-e2e-test-images/agnhost:2.8` for Linux +The image can be found at `gcr.io/kubernetes-e2e-test-images/agnhost:2.9` for Linux containers, and `e2eteam/agnhost:2.8` for Windows containers. In the future, the same repository can be used for both OSes. diff --git a/test/images/agnhost/VERSION b/test/images/agnhost/VERSION index a4412fa745d3..8c2691509e79 100644 --- a/test/images/agnhost/VERSION +++ b/test/images/agnhost/VERSION @@ -1 +1 @@ -2.8 +2.9 diff --git a/test/images/agnhost/agnhost.go b/test/images/agnhost/agnhost.go index edd80a2e52e6..2c862a833224 100644 --- a/test/images/agnhost/agnhost.go +++ b/test/images/agnhost/agnhost.go @@ -32,6 +32,7 @@ import ( "k8s.io/kubernetes/test/images/agnhost/inclusterclient" "k8s.io/kubernetes/test/images/agnhost/liveness" "k8s.io/kubernetes/test/images/agnhost/logs-generator" + "k8s.io/kubernetes/test/images/agnhost/mounttest" "k8s.io/kubernetes/test/images/agnhost/net" "k8s.io/kubernetes/test/images/agnhost/netexec" "k8s.io/kubernetes/test/images/agnhost/nettest" @@ -40,12 +41,14 @@ import ( "k8s.io/kubernetes/test/images/agnhost/pause" "k8s.io/kubernetes/test/images/agnhost/port-forward-tester" "k8s.io/kubernetes/test/images/agnhost/porter" + "k8s.io/kubernetes/test/images/agnhost/resource-consumer-controller" "k8s.io/kubernetes/test/images/agnhost/serve-hostname" + "k8s.io/kubernetes/test/images/agnhost/test-webserver" "k8s.io/kubernetes/test/images/agnhost/webhook" ) func main() { - rootCmd := &cobra.Command{Use: "app", Version: "2.8"} + rootCmd := &cobra.Command{Use: "app", Version: "2.9"} rootCmd.AddCommand(auditproxy.CmdAuditProxy) rootCmd.AddCommand(connect.CmdConnect) @@ -59,6 +62,7 @@ func main() { rootCmd.AddCommand(inclusterclient.CmdInClusterClient) rootCmd.AddCommand(liveness.CmdLiveness) rootCmd.AddCommand(logsgen.CmdLogsGenerator) + rootCmd.AddCommand(mounttest.CmdMounttest) rootCmd.AddCommand(net.CmdNet) rootCmd.AddCommand(netexec.CmdNetexec) rootCmd.AddCommand(nettest.CmdNettest) @@ -67,7 +71,9 @@ func main() { rootCmd.AddCommand(pause.CmdPause) rootCmd.AddCommand(porter.CmdPorter) rootCmd.AddCommand(portforwardtester.CmdPortForwardTester) + rootCmd.AddCommand(resconsumerctrl.CmdResourceConsumerController) rootCmd.AddCommand(servehostname.CmdServeHostname) + rootCmd.AddCommand(testwebserver.CmdTestWebserver) rootCmd.AddCommand(webhook.CmdWebhook) // NOTE(claudiub): Some tests are passing logging related flags, so we need to be able to diff --git a/test/images/mounttest/BUILD b/test/images/agnhost/mounttest/BUILD similarity index 63% rename from test/images/mounttest/BUILD rename to test/images/agnhost/mounttest/BUILD index 27dceeba20f9..1de6c8b60de3 100644 --- a/test/images/mounttest/BUILD +++ b/test/images/agnhost/mounttest/BUILD @@ -2,14 +2,18 @@ package(default_visibility = ["//visibility:public"]) load( "@io_bazel_rules_go//go:def.bzl", - "go_binary", "go_library", ) go_library( name = "go_default_library", - srcs = ["mt.go"], - importpath = "k8s.io/kubernetes/test/images/mounttest", + srcs = [ + "mt.go", + "mt_utils.go", + "mt_utils_windows.go", + ], + importpath = "k8s.io/kubernetes/test/images/agnhost/mounttest", + deps = ["//vendor/github.com/spf13/cobra:go_default_library"], ) filegroup( @@ -24,8 +28,3 @@ filegroup( srcs = [":package-srcs"], tags = ["automanaged"], ) - -go_binary( - name = "mounttest", - embed = [":go_default_library"], -) diff --git a/test/images/agnhost/mounttest/filePermissions.ps1 b/test/images/agnhost/mounttest/filePermissions.ps1 new file mode 100644 index 000000000000..57ef50aa9217 --- /dev/null +++ b/test/images/agnhost/mounttest/filePermissions.ps1 @@ -0,0 +1,97 @@ +# Copyright 2019 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Param( + [string]$FileName = $(throw "-FileName is required.") + ) + + +# read = read data | read attributes +$READ_PERMISSIONS = 0x0001 -bor 0x0080 + +# write = write data | append data | write attributes | write EA +$WRITE_PERMISSIONS = 0x0002 -bor 0x0004 -bor 0x0100 -bor 0x0010 + +# execute = read data | file execute +$EXECUTE_PERMISSIONS = 0x0001 -bor 0x0020 + + +function GetFilePermissions($path) { + $objPath = "Win32_LogicalFileSecuritySetting='$path'" + $output = Invoke-WmiMethod -Namespace root/cimv2 -Path $objPath -Name GetSecurityDescriptor + + if ($output.ReturnValue -ne 0) { + $retVal = $output.ReturnValue + Write-Error "GetSecurityDescriptor invocation failed with code: $retVal" + exit 1 + } + + $fileSD = $output.Descriptor + $fileOwnerGroup = $fileSD.Group + $fileOwner = $fileSD.Owner + + if ($fileOwnerGroup.Name -eq $null -and $fileOwnerGroup.Domain -eq $null) { + # the file owner's group is not recognized. Check if the Owner itself is + # a group, and if so, default the group to it. + net user $fileOwner.Name > $null 2> $null + if (-not $?) { + $fileOwnerGroup = $fileOwner + } + + } + + $userMask = 0 + $groupMask = 0 + $otherMask = 0 + + foreach ($ace in $fileSD.DACL) { + $mask = 0 + if ($ace.AceType -ne 0) { + # not an Allow ACE, skip. + continue + } + + # convert mask. + if ( ($ace.AccessMask -band $READ_PERMISSIONS) -eq $READ_PERMISSIONS ) { + $mask = $mask -bor 4 + } + if ( ($ace.AccessMask -band $WRITE_PERMISSIONS) -eq $WRITE_PERMISSIONS ) { + $mask = $mask -bor 2 + } + if ( ($ace.AccessMask -band $EXECUTE_PERMISSIONS) -eq $EXECUTE_PERMISSIONS ) { + $mask = $mask -bor 1 + } + + # detect mask type. + if ($ace.Trustee.Equals($fileOwner)) { + $userMask = $mask + } + if ($ace.Trustee.Equals($fileOwnerGroup)) { + $groupMask = $mask + } + if ($ace.Trustee.Name.ToLower() -eq "users") { + $otherMask = $mask + } + } + + return "$userMask$groupMask$otherMask" +} + +$mask = GetFilePermissions($FileName) +if (-not $?) { + exit 1 +} + +# print the permission mask Linux-style. +echo "0$mask" diff --git a/test/images/mounttest/mt.go b/test/images/agnhost/mounttest/mt.go similarity index 60% rename from test/images/mounttest/mt.go rename to test/images/agnhost/mounttest/mt.go index 6bd92161ff0c..d5e15908fdc0 100644 --- a/test/images/mounttest/mt.go +++ b/test/images/agnhost/mounttest/mt.go @@ -1,5 +1,3 @@ -// +build linux - /* Copyright 2015 The Kubernetes Authors. @@ -16,17 +14,26 @@ See the License for the specific language governing permissions and limitations under the License. */ -package main +package mounttest import ( - "flag" "fmt" "io/ioutil" "os" - "syscall" "time" + + "github.com/spf13/cobra" ) +// CmdMounttest is used by agnhost Cobra. +var CmdMounttest = &cobra.Command{ + Use: "mounttest", + Short: "Creates files with given permissions and outputs FS type, owner, mode, permissions, contents of files", + Long: "Creates files with specific file permissions, and outputs the filesystem type, owner, mode, permissions, content of the given files, if they exist.", + Args: cobra.MaximumNArgs(0), + Run: main, +} + var ( fsTypePath = "" fileModePath = "" @@ -43,32 +50,30 @@ var ( ) func init() { - flag.StringVar(&fsTypePath, "fs_type", "", "Path to print the fs type for") - flag.StringVar(&fileModePath, "file_mode", "", "Path to print the mode bits of") - flag.StringVar(&filePermPath, "file_perm", "", "Path to print the perms of") - flag.StringVar(&fileOwnerPath, "file_owner", "", "Path to print the owning UID and GID of") - flag.StringVar(&newFilePath0644, "new_file_0644", "", "Path to write to and read from with perm 0644") - flag.StringVar(&newFilePath0666, "new_file_0666", "", "Path to write to and read from with perm 0666") - flag.StringVar(&newFilePath0660, "new_file_0660", "", "Path to write to and read from with perm 0660") - flag.StringVar(&newFilePath0777, "new_file_0777", "", "Path to write to and read from with perm 0777") - flag.StringVar(&readFileContentPath, "file_content", "", "Path to read the file content from") - flag.StringVar(&readFileContentInLoopPath, "file_content_in_loop", "", "Path to read the file content in loop from") - flag.IntVar(&retryDuration, "retry_time", 180, "Retry time during the loop") - flag.BoolVar(&breakOnExpectedContent, "break_on_expected_content", true, "Break out of loop on expected content, (use with --file_content_in_loop flag only)") + CmdMounttest.Flags().StringVar(&fsTypePath, "fs_type", "", "Path to print the fs type for") + CmdMounttest.Flags().StringVar(&fileModePath, "file_mode", "", "Path to print the mode bits of") + CmdMounttest.Flags().StringVar(&filePermPath, "file_perm", "", "Path to print the perms of") + CmdMounttest.Flags().StringVar(&fileOwnerPath, "file_owner", "", "Path to print the owning UID and GID of") + CmdMounttest.Flags().StringVar(&newFilePath0644, "new_file_0644", "", "Path to write to and read from with perm 0644") + CmdMounttest.Flags().StringVar(&newFilePath0666, "new_file_0666", "", "Path to write to and read from with perm 0666") + CmdMounttest.Flags().StringVar(&newFilePath0660, "new_file_0660", "", "Path to write to and read from with perm 0660") + CmdMounttest.Flags().StringVar(&newFilePath0777, "new_file_0777", "", "Path to write to and read from with perm 0777") + CmdMounttest.Flags().StringVar(&readFileContentPath, "file_content", "", "Path to read the file content from") + CmdMounttest.Flags().StringVar(&readFileContentInLoopPath, "file_content_in_loop", "", "Path to read the file content in loop from") + CmdMounttest.Flags().IntVar(&retryDuration, "retry_time", 180, "Retry time during the loop") + CmdMounttest.Flags().BoolVar(&breakOnExpectedContent, "break_on_expected_content", true, "Break out of loop on expected content, (use with --file_content_in_loop flag only)") } // This program performs some tests on the filesystem as dictated by the // flags passed by the user. -func main() { - flag.Parse() - +func main(cmd *cobra.Command, args []string) { var ( err error errs = []error{} ) // Clear the umask so we can set any mode bits we want. - syscall.Umask(0000) + umask(0000) // NOTE: the ordering of execution of the various command line // flags is intentional and allows a single command to: @@ -136,75 +141,6 @@ func main() { os.Exit(0) } -// Defined by Linux (sys/statfs.h) - the type number for tmpfs mounts. -const linuxTmpfsMagic = 0x01021994 - -func fsType(path string) error { - if path == "" { - return nil - } - - buf := syscall.Statfs_t{} - if err := syscall.Statfs(path, &buf); err != nil { - fmt.Printf("error from statfs(%q): %v\n", path, err) - return err - } - - if buf.Type == linuxTmpfsMagic { - fmt.Printf("mount type of %q: tmpfs\n", path) - } else { - fmt.Printf("mount type of %q: %v\n", path, buf.Type) - } - - return nil -} - -func fileMode(path string) error { - if path == "" { - return nil - } - - fileinfo, err := os.Stat(path) - if err != nil { - fmt.Printf("error from Stat(%q): %v\n", path, err) - return err - } - - fmt.Printf("mode of file %q: %v\n", path, fileinfo.Mode()) - return nil -} - -func filePerm(path string) error { - if path == "" { - return nil - } - - fileinfo, err := os.Stat(path) - if err != nil { - fmt.Printf("error from Stat(%q): %v\n", path, err) - return err - } - - fmt.Printf("perms of file %q: %v\n", path, fileinfo.Mode().Perm()) - return nil -} - -func fileOwner(path string) error { - if path == "" { - return nil - } - - buf := syscall.Stat_t{} - if err := syscall.Stat(path, &buf); err != nil { - fmt.Printf("error from stat(%q): %v\n", path, err) - return err - } - - fmt.Printf("owner UID of %q: %v\n", path, buf.Uid) - fmt.Printf("owner GID of %q: %v\n", path, buf.Gid) - return nil -} - func readFileContent(path string) error { if path == "" { return nil diff --git a/test/images/agnhost/mounttest/mt_utils.go b/test/images/agnhost/mounttest/mt_utils.go new file mode 100644 index 000000000000..37db9f901b58 --- /dev/null +++ b/test/images/agnhost/mounttest/mt_utils.go @@ -0,0 +1,98 @@ +// +build !windows + +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package mounttest + +import ( + "fmt" + "os" + "syscall" +) + +func umask(mask int) int { + return syscall.Umask(mask) +} + +// Defined by Linux (sys/statfs.h) - the type number for tmpfs mounts. +const linuxTmpfsMagic = 0x01021994 + +func fsType(path string) error { + if path == "" { + return nil + } + + buf := syscall.Statfs_t{} + if err := syscall.Statfs(path, &buf); err != nil { + fmt.Printf("error from statfs(%q): %v\n", path, err) + return err + } + + if buf.Type == linuxTmpfsMagic { + fmt.Printf("mount type of %q: tmpfs\n", path) + } else { + fmt.Printf("mount type of %q: %v\n", path, buf.Type) + } + + return nil +} + +func fileMode(path string) error { + if path == "" { + return nil + } + + fileinfo, err := os.Stat(path) + if err != nil { + fmt.Printf("error from Stat(%q): %v\n", path, err) + return err + } + + fmt.Printf("mode of file %q: %v\n", path, fileinfo.Mode()) + return nil +} + +func filePerm(path string) error { + if path == "" { + return nil + } + + fileinfo, err := os.Stat(path) + if err != nil { + fmt.Printf("error from Stat(%q): %v\n", path, err) + return err + } + + fmt.Printf("perms of file %q: %v\n", path, fileinfo.Mode().Perm()) + return nil +} + +func fileOwner(path string) error { + if path == "" { + return nil + } + + buf := syscall.Stat_t{} + if err := syscall.Stat(path, &buf); err != nil { + fmt.Printf("error from stat(%q): %v\n", path, err) + return err + } + + fmt.Printf("owner UID of %q: %v\n", path, buf.Uid) + fmt.Printf("owner GID of %q: %v\n", path, buf.Gid) + return nil +} diff --git a/test/images/agnhost/mounttest/mt_utils_windows.go b/test/images/agnhost/mounttest/mt_utils_windows.go new file mode 100644 index 000000000000..245053c8e91e --- /dev/null +++ b/test/images/agnhost/mounttest/mt_utils_windows.go @@ -0,0 +1,99 @@ +// +build windows + +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package mounttest + +import ( + "bytes" + "fmt" + "os" + "os/exec" + "strconv" + "strings" +) + +func umask(mask int) int { + // noop for Windows. + return 0 +} + +func fileOwner(path string) error { + // Windows does not have owner UID / GID. However, it has owner SID. + // not currently implemented in Kubernetes, so noop. + return nil +} + +func fileMode(path string) error { + if path == "" { + return nil + } + + permissions, err := getFilePerm(path) + if err != nil { + return err + } + + fmt.Printf("mode of Windows file %q: %v\n", path, permissions) + return nil +} + +func filePerm(path string) error { + if path == "" { + return nil + } + + permissions, err := getFilePerm(path) + if err != nil { + return err + } + + fmt.Printf("perms of Windows file %q: %v\n", path, permissions) + return nil +} + +func getFilePerm(path string) (os.FileMode, error) { + var ( + out bytes.Buffer + errOut bytes.Buffer + ) + + cmd := exec.Command("powershell.exe", "-NonInteractive", "./filePermissions.ps1", + "-FileName", path) + cmd.Stdout = &out + cmd.Stderr = &errOut + err := cmd.Run() + + if err != nil { + fmt.Printf("error from PowerShell Script: %v, %v\n", err, errOut.String()) + return 0, err + } + + output := strings.TrimSpace(out.String()) + val, err := strconv.ParseInt(output, 8, 32) + if err != nil { + fmt.Printf("error parsing string '%s' as int: %v\n", output, err) + return 0, err + } + + return os.FileMode(val), nil +} + +func fsType(path string) error { + // only NTFS is supported at the moment. + return nil +} diff --git a/test/images/resource-consumer-controller/BUILD b/test/images/agnhost/resource-consumer-controller/BUILD similarity index 63% rename from test/images/resource-consumer-controller/BUILD rename to test/images/agnhost/resource-consumer-controller/BUILD index 2bb311ceaf4b..a87e0488e7bb 100644 --- a/test/images/resource-consumer-controller/BUILD +++ b/test/images/agnhost/resource-consumer-controller/BUILD @@ -2,20 +2,17 @@ package(default_visibility = ["//visibility:public"]) load( "@io_bazel_rules_go//go:def.bzl", - "go_binary", "go_library", ) -go_binary( - name = "controller", - embed = [":go_default_library"], -) - go_library( name = "go_default_library", srcs = ["controller.go"], - importpath = "k8s.io/kubernetes/test/images/resource-consumer-controller", - deps = ["//test/images/resource-consumer/common:go_default_library"], + importpath = "k8s.io/kubernetes/test/images/agnhost/resource-consumer-controller", + deps = [ + "//test/images/resource-consumer/common:go_default_library", + "//vendor/github.com/spf13/cobra:go_default_library", + ], ) filegroup( diff --git a/test/images/resource-consumer-controller/controller.go b/test/images/agnhost/resource-consumer-controller/controller.go similarity index 85% rename from test/images/resource-consumer-controller/controller.go rename to test/images/agnhost/resource-consumer-controller/controller.go index 32f9763f7f6c..20b6a52ce583 100644 --- a/test/images/resource-consumer-controller/controller.go +++ b/test/images/agnhost/resource-consumer-controller/controller.go @@ -14,10 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ -package main +package resconsumerctrl import ( - "flag" "fmt" "log" "net/http" @@ -25,18 +24,37 @@ import ( "strconv" "sync" + "github.com/spf13/cobra" + "k8s.io/kubernetes/test/images/resource-consumer/common" ) -var port = flag.Int("port", 8080, "Port number.") -var consumerPort = flag.Int("consumer-port", 8080, "Port number of consumers.") -var consumerServiceName = flag.String("consumer-service-name", "resource-consumer", "Name of service containing resource consumers.") -var consumerServiceNamespace = flag.String("consumer-service-namespace", "default", "Namespace of service containing resource consumers.") +// CmdResourceConsumerController is used by agnhost Cobra. +var CmdResourceConsumerController = &cobra.Command{ + Use: "resource-consumer-controller", + Short: "Starts a HTTP server that spreads requests around resource consumers", + Long: "Starts a HTTP server that spreads requests around resource consumers. The HTTP server has the same endpoints and usage as the one spawned by the \"resource-consumer\" subcommand.", + Args: cobra.MaximumNArgs(0), + Run: main, +} + +var ( + port int + consumerPort int + consumerServiceName string + consumerServiceNamespace string +) + +func init() { + CmdResourceConsumerController.Flags().IntVar(&port, "port", 8080, "Port number.") + CmdResourceConsumerController.Flags().IntVar(&consumerPort, "consumer-port", 8080, "Port number of consumers.") + CmdResourceConsumerController.Flags().StringVar(&consumerServiceName, "consumer-service-name", "resource-consumer", "Name of service containing resource consumers.") + CmdResourceConsumerController.Flags().StringVar(&consumerServiceNamespace, "consumer-service-namespace", "default", "Namespace of service containing resource consumers.") +} -func main() { - flag.Parse() +func main(cmd *cobra.Command, args []string) { mgr := newController() - log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), mgr)) + log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), mgr)) } type controller struct { @@ -196,7 +214,7 @@ func (c *controller) sendConsumeCustomMetric(w http.ResponseWriter, metric strin } func createConsumerURL(suffix string) string { - return fmt.Sprintf("http://%s.%s.svc.cluster.local:%d%s", *consumerServiceName, *consumerServiceNamespace, *consumerPort, suffix) + return fmt.Sprintf("http://%s.%s.svc.cluster.local:%d%s", consumerServiceName, consumerServiceNamespace, consumerPort, suffix) } // sendOneConsumeCPURequest sends POST request for cpu consumption diff --git a/test/images/test-webserver/BUILD b/test/images/agnhost/test-webserver/BUILD similarity index 72% rename from test/images/test-webserver/BUILD rename to test/images/agnhost/test-webserver/BUILD index f8234f74e667..4737c13486f7 100644 --- a/test/images/test-webserver/BUILD +++ b/test/images/agnhost/test-webserver/BUILD @@ -2,19 +2,14 @@ package(default_visibility = ["//visibility:public"]) load( "@io_bazel_rules_go//go:def.bzl", - "go_binary", "go_library", ) -go_binary( - name = "test-webserver", - embed = [":go_default_library"], -) - go_library( name = "go_default_library", srcs = ["test-webserver.go"], - importpath = "k8s.io/kubernetes/test/images/test-webserver", + importpath = "k8s.io/kubernetes/test/images/agnhost/test-webserver", + deps = ["//vendor/github.com/spf13/cobra:go_default_library"], ) filegroup( diff --git a/test/images/test-webserver/test-webserver.go b/test/images/agnhost/test-webserver/test-webserver.go similarity index 66% rename from test/images/test-webserver/test-webserver.go rename to test/images/agnhost/test-webserver/test-webserver.go index ee496b0b5b0c..c9daa2c0a2de 100644 --- a/test/images/test-webserver/test-webserver.go +++ b/test/images/agnhost/test-webserver/test-webserver.go @@ -14,23 +14,35 @@ See the License for the specific language governing permissions and limitations under the License. */ -// A tiny web server that serves a static file. -package main +// Package testwebserver offers a tiny web server that serves a static file. +package testwebserver import ( - "flag" "fmt" "log" "net/http" + + "github.com/spf13/cobra" ) +// CmdTestWebserver is used by agnhost Cobra. +var CmdTestWebserver = &cobra.Command{ + Use: "test-webserver", + Short: "Starts a simple HTTP fileserver", + Long: "Starts a simple HTTP fileserver on the given --port, which serves any file specified in the URL path, if it exists.", + Args: cobra.MaximumNArgs(0), + Run: main, +} + var ( - port = flag.Int("port", 80, "Port number.") + port int ) -func main() { - flag.Parse() +func init() { + CmdTestWebserver.Flags().IntVar(&port, "port", 80, "Port number.") +} +func main(cmd *cobra.Command, args []string) { fs := http.StripPrefix("/", http.FileServer(http.Dir("/"))) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { @@ -45,7 +57,7 @@ func main() { fs.ServeHTTP(w, r) }) - go log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil)) + go log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil)) select {} } diff --git a/test/images/dnsutils/BASEIMAGE b/test/images/dnsutils/BASEIMAGE deleted file mode 100644 index 7bad7a6d3a2d..000000000000 --- a/test/images/dnsutils/BASEIMAGE +++ /dev/null @@ -1,5 +0,0 @@ -amd64=alpine:3.6 -arm=arm32v6/alpine:3.6 -arm64=arm64v8/alpine:3.6 -ppc64le=ppc64le/alpine:3.6 -s390x=s390x/alpine:3.6 diff --git a/test/images/dnsutils/Dockerfile b/test/images/dnsutils/Dockerfile deleted file mode 100644 index 30eb78569603..000000000000 --- a/test/images/dnsutils/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2016 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FROM BASEIMAGE - -CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/ - -RUN apk add --no-cache bind-tools dnsmasq - -ADD https://github.com/coredns/coredns/releases/download/v1.5.0/coredns_1.5.0_linux_BASEARCH.tgz /coredns.tgz -RUN tar -xzvf /coredns.tgz && rm -f /coredns.tgz diff --git a/test/images/dnsutils/Dockerfile_windows b/test/images/dnsutils/Dockerfile_windows deleted file mode 100644 index 29b7a8e37ace..000000000000 --- a/test/images/dnsutils/Dockerfile_windows +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2019 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FROM BASEIMAGE - -USER ContainerAdministrator -ENV chocolateyUseWindowsCompression false -RUN powershell -Command \ - iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')); \ - choco feature disable --name showDownloadProgress; \ - powershell -Command choco install bind-toolsonly --version 9.10.3 -y -RUN powershell -Command "\ - wget -uri 'https://github.com/coredns/coredns/releases/download/v1.5.0/coredns_1.5.0_windows_amd64.tgz' -OutFile 'C:\coredns.tgz';\ - tar -xzvf 'C:\coredns.tgz';\ - Remove-Item 'C:\coredns.tgz'" -ADD hostname /bin/hostname.exe diff --git a/test/images/dnsutils/VERSION b/test/images/dnsutils/VERSION deleted file mode 100644 index 5625e59da887..000000000000 --- a/test/images/dnsutils/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.2 diff --git a/test/images/kitten/BASEIMAGE b/test/images/kitten/BASEIMAGE index 1d2837d2ff46..20b2972e552b 100644 --- a/test/images/kitten/BASEIMAGE +++ b/test/images/kitten/BASEIMAGE @@ -1,5 +1,5 @@ -amd64=gcr.io/kubernetes-e2e-test-images/test-webserver-amd64:1.0 -arm=gcr.io/kubernetes-e2e-test-images/test-webserver-arm:1.0 -arm64=gcr.io/kubernetes-e2e-test-images/test-webserver-arm64:1.0 -ppc64le=gcr.io/kubernetes-e2e-test-images/test-webserver-ppc64le:1.0 -s390x=gcr.io/kubernetes-e2e-test-images/test-webserver-s390x:1.0 +amd64=gcr.io/kubernetes-e2e-test-images/agnhost-amd64:2.7 +arm=gcr.io/kubernetes-e2e-test-images/agnhost-arm:2.7 +arm64=gcr.io/kubernetes-e2e-test-images/agnhost-arm64:2.7 +ppc64le=gcr.io/kubernetes-e2e-test-images/agnhost-ppc64le:2.7 +s390x=gcr.io/kubernetes-e2e-test-images/agnhost-s390x:2.7 diff --git a/test/images/kitten/VERSION b/test/images/kitten/VERSION index d3827e75a5ca..9459d4ba2a0d 100644 --- a/test/images/kitten/VERSION +++ b/test/images/kitten/VERSION @@ -1 +1 @@ -1.0 +1.1 diff --git a/test/images/mounttest/Dockerfile b/test/images/mounttest/Dockerfile deleted file mode 100644 index 91c034155f0b..000000000000 --- a/test/images/mounttest/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2016 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FROM scratch -COPY mounttest / -ENTRYPOINT ["/mounttest"] diff --git a/test/images/mounttest/Makefile b/test/images/mounttest/Makefile deleted file mode 100644 index 969e8080d101..000000000000 --- a/test/images/mounttest/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2016 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -SRCS=mounttest -ARCH ?= amd64 -TARGET ?= $(CURDIR) -GOLANG_VERSION ?= latest -SRC_DIR = $(notdir $(shell pwd)) -export - -bin: - ../image-util.sh bin $(SRCS) - -.PHONY: bin diff --git a/test/images/mounttest/VERSION b/test/images/mounttest/VERSION deleted file mode 100644 index d3827e75a5ca..000000000000 --- a/test/images/mounttest/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.0 diff --git a/test/images/nautilus/BASEIMAGE b/test/images/nautilus/BASEIMAGE index 1d2837d2ff46..20b2972e552b 100644 --- a/test/images/nautilus/BASEIMAGE +++ b/test/images/nautilus/BASEIMAGE @@ -1,5 +1,5 @@ -amd64=gcr.io/kubernetes-e2e-test-images/test-webserver-amd64:1.0 -arm=gcr.io/kubernetes-e2e-test-images/test-webserver-arm:1.0 -arm64=gcr.io/kubernetes-e2e-test-images/test-webserver-arm64:1.0 -ppc64le=gcr.io/kubernetes-e2e-test-images/test-webserver-ppc64le:1.0 -s390x=gcr.io/kubernetes-e2e-test-images/test-webserver-s390x:1.0 +amd64=gcr.io/kubernetes-e2e-test-images/agnhost-amd64:2.7 +arm=gcr.io/kubernetes-e2e-test-images/agnhost-arm:2.7 +arm64=gcr.io/kubernetes-e2e-test-images/agnhost-arm64:2.7 +ppc64le=gcr.io/kubernetes-e2e-test-images/agnhost-ppc64le:2.7 +s390x=gcr.io/kubernetes-e2e-test-images/agnhost-s390x:2.7 diff --git a/test/images/nautilus/VERSION b/test/images/nautilus/VERSION index d3827e75a5ca..9459d4ba2a0d 100644 --- a/test/images/nautilus/VERSION +++ b/test/images/nautilus/VERSION @@ -1 +1 @@ -1.0 +1.1 diff --git a/test/images/resource-consumer-controller/BASEIMAGE b/test/images/resource-consumer-controller/BASEIMAGE deleted file mode 100644 index 44329aaa5b15..000000000000 --- a/test/images/resource-consumer-controller/BASEIMAGE +++ /dev/null @@ -1,5 +0,0 @@ -amd64=busybox -arm=arm32v6/busybox -arm64=arm64v8/busybox -ppc64le=ppc64le/busybox -s390x=s390x/busybox diff --git a/test/images/resource-consumer-controller/Dockerfile b/test/images/resource-consumer-controller/Dockerfile deleted file mode 100644 index c725284cbbf1..000000000000 --- a/test/images/resource-consumer-controller/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2016 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FROM BASEIMAGE -ADD controller /controller -EXPOSE 8080 -ENTRYPOINT ["/controller"] diff --git a/test/images/resource-consumer-controller/Makefile b/test/images/resource-consumer-controller/Makefile deleted file mode 100644 index f12895305092..000000000000 --- a/test/images/resource-consumer-controller/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -SRCS=controller -ARCH ?= amd64 -TARGET ?= $(CURDIR) -GOLANG_VERSION ?= latest -SRC_DIR = $(notdir $(shell pwd)) -export - -bin: - ../image-util.sh bin $(SRCS) - -.PHONY: bin diff --git a/test/images/resource-consumer-controller/VERSION b/test/images/resource-consumer-controller/VERSION deleted file mode 100644 index d3827e75a5ca..000000000000 --- a/test/images/resource-consumer-controller/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.0 diff --git a/test/images/test-webserver/Dockerfile b/test/images/test-webserver/Dockerfile deleted file mode 100644 index e14595f08e9a..000000000000 --- a/test/images/test-webserver/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2014 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FROM scratch - -COPY test-webserver / -EXPOSE 80 -ENTRYPOINT ["/test-webserver"] diff --git a/test/images/test-webserver/Makefile b/test/images/test-webserver/Makefile deleted file mode 100644 index 712f55b009f0..000000000000 --- a/test/images/test-webserver/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -SRCS = test-webserver -ARCH ?= amd64 -TARGET ?= $(CURDIR) -GOLANG_VERSION ?= latest -SRC_DIR = $(notdir $(shell pwd)) -export - -bin: - ../image-util.sh bin $(SRCS) - -.PHONY: bin diff --git a/test/images/test-webserver/VERSION b/test/images/test-webserver/VERSION deleted file mode 100644 index d3827e75a5ca..000000000000 --- a/test/images/test-webserver/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.0