Change:
<!-- This form is for bug reports and feature requests ONLY! If you're looking for help check and the . If the matter is security related, please disclose it privately via --Is this a BUG REPORT or FEATURE REQUEST?: /kind feature What happened: What you expected to happen: We need to have a cluster level stub device plugin based e2e test, which has been long pending task slip through several cycles. After we have that, we can configure it to run in different environments, like scale, soak, upgrade, and downgrade. For simplicity, we can create a stubdeviceplugin directory under test/images/ with a simple stub device plugin implementation in a .go file, and simple Makefile, Dockerfile, etc. The stub device plugin can start with defined behavior and just provide simple container runtime setting during Allocate call. For reference, is an example plugin we have used in pluginwatcher test. We can have a similar one for stub device plugin that implements the device plugin API. How to reproduce it (as minimally and precisely as possible): Anything else we need to know?: Environment: Kubernetes version (use ): Cloud provider or hardware configuration: OS (e.g. from /etc/os-release): Kernel (e.g. ): Install tools: Others:
/sig node /cc
As per slack discussion with i will be working on this. /assign
Issues go stale after 90d of inactivity. Mark the issue as fresh with . Stale issues rot after an additional 30d of inactivity and eventually close. If this issue is safe to close now please do so with . Send feedback to sig-testing, kubernetes/test-infra and/or . /lifecycle stale
Stale issues rot after 30d of inactivity. Mark the issue as fresh with . Rotten issues close after an additional 30d of inactivity. If this issue is safe to close now please do so with . Send feedback to sig-testing, kubernetes/test-infra and/or . /lifecycle rotten
Rotten issues close after 30d of inactivity. Reopen the issue with . Mark the issue as fresh with . Send feedback to sig-testing, kubernetes/test-infra and/or . /close
Closing this issue. <detailsIn response to : Rotten issues close after 30d of inactivity. Reopen the issue with . Mark the issue as fresh with . /close Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/reopen /remove-lifecycle rotten
Reopened this issue. <detailsIn response to : /reopen /remove-lifecycle rotten Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/reopen
Reopened this issue. <detailsIn response to : /reopen Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
Issues go stale after 90d of inactivity. Mark the issue as fresh with . Stale issues rot after an additional 30d of inactivity and eventually close. If this issue is safe to close now please do so with . Send feedback to sig-testing, kubernetes/test-infra and/or . /lifecycle stale
/remove-lifecycle stale

Discussion:
"//test/images/porter:all-srcs", "//test/images/resource-consumer:all-srcs", "//test/images/sample-apiserver:all-srcs", <ins> "//test/images/sample-device-plugin:all-srcs", </ins> "//test/images/serve-hostname:all-srcs", "//test/images/test-webserver:all-srcs", "//test/images/webhook:all-srcs",

<ins> amd64=alpine:3.8 arm=arm32v6/alpine:3.8 arm64=arm64v8/alpine:3.8 ppc64le=ppc64le/alpine:3.8 s390x=s390x/alpine:3.8 </ins>

<ins> package(default_visibility = ["//visibility:public"]) load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") go_library( name = "go_default_library", srcs = ["sampledeviceplugin.go"], importpath = "k8s.io/kubernetes/test/images/sample-device-plugin", visibility = ["//visibility:private"], deps = [ "//pkg/kubelet/apis/deviceplugin/v1beta1:go_default_library", "//pkg/kubelet/cm/devicemanager:go_default_library", "//vendor/k8s.io/klog:go_default_library", ], ) go_binary( name = "sample-device-plugin", embed = [":go_default_library"], visibility = ["//visibility:public"], ) filegroup( name = "package-srcs", srcs = glob(["**"]), tags = ["automanaged"], visibility = ["//visibility:private"], ) filegroup( name = "all-srcs", srcs = [":package-srcs"], tags = ["automanaged"], visibility = ["//visibility:public"], ) </ins>

<ins> # Copyright 2018 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 sampledeviceplugin /sampledeviceplugin ENTRYPOINT ["/sampledeviceplugin", "-alsologtostderr"] </ins>

<ins> # Copyright 2018 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=sampledeviceplugin ARCH ?= amd64 TARGET ?= $(CURDIR) GOLANG_VERSION ?= latest SRC_DIR = $(notdir $(shell pwd)) export bin: ../image-util.sh bin $(SRCS) .PHONY: bin </ins>

<ins> /* Copyright 2018 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 main import ( "fmt" "os" "path/filepath" "time" "k8s.io/klog" pluginapi "k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1beta1" dm "k8s.io/kubernetes/pkg/kubelet/cm/devicemanager" ) const ( resourceName = "example.com/resource" ) // stubAllocFunc creates and returns allocation response for the input allocate request func stubAllocFunc(r *pluginapi.AllocateRequest, devs map[string]pluginapi.Device) (*pluginapi.AllocateResponse, error) { var responses pluginapi.AllocateResponse for _, req := range r.ContainerRequests { response := &pluginapi.ContainerAllocateResponse{} for _, requestID := range req.DevicesIDs { dev, ok := devs[requestID] if !ok { return nil, fmt.Errorf("invalid allocation request with non-existing device %s", requestID) } if dev.Health != pluginapi.Healthy { return nil, fmt.Errorf("invalid allocation request with unhealthy device: %s", requestID) } // create fake device file fpath := filepath.Join("/tmp", dev.ID) // clean first if err := os.RemoveAll(fpath); err != nil { return nil, fmt.Errorf("failed to clean fake device file from previous run: %s", err) } f, err := os.Create(fpath) if err != nil && !os.IsExist(err) { return nil, fmt.Errorf("failed to create fake device file: %s", err) } f.Close() response.Mounts = append(response.Mounts, &pluginapi.Mount{ ContainerPath: fpath, HostPath:      fpath, }) } responses.ContainerResponses = append(responses.ContainerResponses, response) } return &responses, nil } func main() { devs := []*pluginapi.Device{ {ID: "Dev-1", Health: pluginapi.Healthy}, {ID: "Dev-2", Health: pluginapi.Healthy}, } pluginSocksDir := os.Getenv("PLUGIN_SOCK_DIR") klog.Infof("pluginSocksDir: %s", pluginSocksDir) if pluginSocksDir == "" { klog.Errorf("Empty pluginSocksDir") return } socketPath := pluginSocksDir + "/dp." + fmt.Sprintf("%d", time.Now().Unix()) dp1 := dm.NewDevicePluginStub(devs, socketPath, resourceName, false) if err := dp1.Start(); err != nil { panic(err) } dp1.SetAllocFunc(stubAllocFunc) if err := dp1.Register(pluginapi.KubeletSocket, resourceName, pluginapi.DevicePluginPath); err != nil { panic(err) } select {} } </ins>