Add inaccel/fpga-operator addon

Signed-off-by: Elias Koromilas <elias.koromilas@gmail.com>
pull/12995/head
Elias Koromilas 2022-05-26 10:07:10 +03:00
parent 89dd1b3c4b
commit 6364518066
10 changed files with 168 additions and 1 deletions

View File

@ -66,7 +66,7 @@ func TestAddonsList(t *testing.T) {
Ambassador *interface{} `json:"ambassador"` Ambassador *interface{} `json:"ambassador"`
} }
b := make([]byte, 544) b := make([]byte, 557)
r, w, err := os.Pipe() r, w, err := os.Pipe()
if err != nil { if err != nil {
t.Fatalf("failed to create pipe: %v", err) t.Fatalf("failed to create pipe: %v", err)

View File

@ -143,4 +143,8 @@ var (
// AliyunMirror assets for aliyun_mirror.json // AliyunMirror assets for aliyun_mirror.json
//go:embed aliyun_mirror.json //go:embed aliyun_mirror.json
AliyunMirror embed.FS AliyunMirror embed.FS
// InAccelAssets assets for inaccel addon
//go:embed inaccel/fpga-operator.yaml.tmpl
InAccelAssets embed.FS
) )

View File

@ -0,0 +1,7 @@
### Documentation
For detailed usage instructions visit: [docs.inaccel.com](https://docs.inaccel.com)
### Support
For more product information contact: info@inaccel.com

View File

@ -0,0 +1,56 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
labels:
addonmanager.kubernetes.io/mode: Reconcile
kubernetes.io/minikube-addons: inaccel
name: inaccel-addon
namespace: kube-system
data:
disable.sh: |
#!/bin/sh -e
exec >/proc/1/fd/1
echo "Disabling InAccel FPGA Operator"
helm uninstall inaccel --namespace kube-system
echo "InAccel is disabled"
enable.sh: |
#!/bin/sh -e
exec >/proc/1/fd/1
echo "Enabling InAccel FPGA Operator"
helm install inaccel fpga-operator --namespace kube-system --repo https://setup.inaccel.com/helm
echo "InAccel is enabled"
---
apiVersion: v1
kind: Pod
metadata:
labels:
addonmanager.kubernetes.io/mode: Reconcile
kubernetes.io/minikube-addons: inaccel
name: inaccel-addon
namespace: kube-system
spec:
containers:
- command:
- sleep
- infinity
image: {{ .CustomRegistries.Helm3 | default .ImageRepository | default .Registries.Helm3 }}{{ .Images.Helm3 }}
lifecycle:
postStart:
exec:
command:
- /inaccel/enable.sh
preStop:
exec:
command:
- /inaccel/disable.sh
name: helm3
volumeMounts:
- mountPath: /inaccel
name: inaccel-addon
readOnly: true
volumes:
- configMap:
defaultMode: 0777
name: inaccel-addon
name: inaccel-addon

View File

@ -197,4 +197,9 @@ var Addons = []*Addon{
set: SetBool, set: SetBool,
callbacks: []setFn{EnableOrDisableAddon}, callbacks: []setFn{EnableOrDisableAddon},
}, },
{
name: "inaccel",
set: SetBool,
callbacks: []setFn{EnableOrDisableAddon},
},
} }

View File

@ -688,6 +688,17 @@ var Addons = map[string]*Addon{
}, false, "portainer", "portainer.io", map[string]string{ }, false, "portainer", "portainer.io", map[string]string{
"Portainer": "portainer/portainer-ce:latest@sha256:4f126c5114b63e9d1bceb4b368944d14323329a9a0d4e7bb7eb53c9b7435d498", "Portainer": "portainer/portainer-ce:latest@sha256:4f126c5114b63e9d1bceb4b368944d14323329a9a0d4e7bb7eb53c9b7435d498",
}, nil), }, nil),
"inaccel": NewAddon([]*BinAsset{
MustBinAsset(addons.InAccelAssets,
"inaccel/fpga-operator.yaml.tmpl",
vmpath.GuestAddonsDir,
"fpga-operator.yaml",
"0640"),
}, false, "inaccel", "InAccel <info@inaccel.com>", map[string]string{
"Helm3": "alpine/helm:3.9.0@sha256:9f4bf4d24241f983910550b1fe8688571cd684046500abe58cef14308f9cb19e",
}, map[string]string{
"Helm3": "docker.io",
}),
} }
// parseMapString creates a map based on `str` which is encoded as <key1>=<value1>,<key2>=<value2>,... // parseMapString creates a map based on `str` which is encoded as <key1>=<value1>,<key2>=<value2>,...

View File

@ -17,6 +17,7 @@ limitations under the License.
package detect package detect
import ( import (
"io"
"net/http" "net/http"
"os" "os"
"os/exec" "os/exec"
@ -67,6 +68,27 @@ func IsOnGCE() bool {
return resp.Header.Get("Metadata-Flavor") == "Google" return resp.Header.Get("Metadata-Flavor") == "Google"
} }
// IsOnAmazonEC2 determines whether minikube is currently running on Amazon EC2
// and, if yes, on which instance type.
func IsOnAmazonEC2() (bool, string) {
resp, err := http.Get("http://instance-data.ec2.internal/latest/meta-data/instance-type")
if err != nil {
return false, ""
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return true, ""
}
instanceType, err := io.ReadAll(resp.Body)
if err != nil {
return true, ""
}
return true, string(instanceType)
}
// IsCloudShell determines whether minikube is running inside CloudShell // IsCloudShell determines whether minikube is running inside CloudShell
func IsCloudShell() bool { func IsCloudShell() bool {
e := os.Getenv("CLOUD_SHELL") e := os.Getenv("CLOUD_SHELL")

View File

@ -42,6 +42,9 @@ tests the csi hostpath driver by creating a persistent volume, snapshotting it a
#### validateGCPAuthAddon #### validateGCPAuthAddon
tests the GCP Auth addon with either phony or real credentials and makes sure the files are mounted into pods correctly tests the GCP Auth addon with either phony or real credentials and makes sure the files are mounted into pods correctly
#### validateInAccelAddon
tests the InAccel addon by trying a vadd
## TestCertOptions ## TestCertOptions
makes sure minikube certs respect the --apiserver-ips and --apiserver-names parameters makes sure minikube certs respect the --apiserver-ips and --apiserver-names parameters

View File

@ -68,6 +68,8 @@ func TestAddons(t *testing.T) {
args := append([]string{"start", "-p", profile, "--wait=true", "--memory=4000", "--alsologtostderr", "--addons=registry", "--addons=metrics-server", "--addons=volumesnapshots", "--addons=csi-hostpath-driver", "--addons=gcp-auth"}, StartArgs()...) args := append([]string{"start", "-p", profile, "--wait=true", "--memory=4000", "--alsologtostderr", "--addons=registry", "--addons=metrics-server", "--addons=volumesnapshots", "--addons=csi-hostpath-driver", "--addons=gcp-auth"}, StartArgs()...)
if !NoneDriver() { // none driver does not support ingress if !NoneDriver() { // none driver does not support ingress
args = append(args, "--addons=ingress", "--addons=ingress-dns") args = append(args, "--addons=ingress", "--addons=ingress-dns")
} else if isOnAmazonEC2, instanceType := detect.IsOnAmazonEC2(); isOnAmazonEC2 && strings.HasPrefix(instanceType, "f1.") {
args = append(args, "--addons=inaccel") // inaccel supports only none driver
} }
if !arm64Platform() { if !arm64Platform() {
args = append(args, "--addons=helm-tiller") args = append(args, "--addons=helm-tiller")
@ -95,6 +97,7 @@ func TestAddons(t *testing.T) {
{"HelmTiller", validateHelmTillerAddon}, {"HelmTiller", validateHelmTillerAddon},
{"Olm", validateOlmAddon}, {"Olm", validateOlmAddon},
{"CSI", validateCSIDriverAndSnapshots}, {"CSI", validateCSIDriverAndSnapshots},
{"InAccel", validateInAccelAddon},
} }
for _, tc := range tests { for _, tc := range tests {
tc := tc tc := tc
@ -708,3 +711,40 @@ func validateGCPAuthAddon(ctx context.Context, t *testing.T, profile string) {
} }
} }
} }
// validateInAccelAddon tests the inaccel addon by trying a vadd
func validateInAccelAddon(ctx context.Context, t *testing.T, profile string) {
defer PostMortemLogs(t, profile)
if !NoneDriver() {
t.Skipf("skipping: inaccel not supported")
}
if isOnAmazonEC2, instanceType := detect.IsOnAmazonEC2(); !(isOnAmazonEC2 && strings.HasPrefix(instanceType, "f1.")) {
t.Skipf("skipping: not running on an Amazon EC2 f1 instance")
}
// create sample pod
rr, err := Run(t, exec.CommandContext(ctx, "kubectl", "--context", profile, "create", "--filename", filepath.Join(*testdataDir, "inaccel.yaml")))
if err != nil {
t.Fatalf("creating pod with %s failed: %v", rr.Command(), err)
}
if _, err = Run(t, exec.CommandContext(ctx, "kubectl", "--context", profile, "wait", "--for", "condition=ready", "--timeout", "-1s", "pod/inaccel-vadd")); err != nil {
t.Fatalf("failed waiting for inaccel-vadd pod: %v", err)
}
rr, err = Run(t, exec.CommandContext(ctx, "kubectl", "--context", profile, "logs", "--follow", "pod/inaccel-vadd"))
if err != nil {
t.Fatalf("%q failed: %v", rr.Command(), err)
}
if !strings.Contains(rr.Stdout.String(), "Test PASSED") {
t.Fatalf("expected inaccel-vadd logs to include: %q but got: %s", "Test PASSED", rr.Output())
}
// delete pod
rr, err = Run(t, exec.CommandContext(ctx, "kubectl", "--context", profile, "delete", "pod/inaccel-vadd"))
if err != nil {
t.Fatalf("deleting pod with %s failed: %v", rr.Command(), err)
}
}

19
test/integration/testdata/inaccel.yaml vendored Normal file
View File

@ -0,0 +1,19 @@
apiVersion: v1
kind: Pod
metadata:
annotations:
inaccel/cli: |
bitstream install https://store.inaccel.com/artifactory/bitstreams/xilinx/aws-vu9p-f1/dynamic-shell/aws/vector/1/1addition
labels:
inaccel/fpga: enabled
name: inaccel-vadd
spec:
containers:
- image: inaccel/vadd
name: inaccel-vadd
resources:
limits:
xilinx/aws-vu9p-f1: 1
nodeSelector:
xilinx/aws-vu9p-f1: dynamic-shell
restartPolicy: Never