diff --git a/internal/discover/discover.go b/internal/discover/discover.go new file mode 100644 index 00000000..4858b282 --- /dev/null +++ b/internal/discover/discover.go @@ -0,0 +1,30 @@ +/* +# Copyright (c) 2021-2022, NVIDIA CORPORATION. All rights reserved. +# +# 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 discover + +// Hook represents a discovered hook. +type Hook struct { + Lifecycle string + Path string + Args []string +} + +//go:generate moq -stub -out discover_mock.go . Discover +// Discover defines an interface for discovering the devices, mounts, and hooks available on a system +type Discover interface { + Hooks() ([]Hook, error) +} diff --git a/internal/discover/discover_mock.go b/internal/discover/discover_mock.go new file mode 100644 index 00000000..0a0f211f --- /dev/null +++ b/internal/discover/discover_mock.go @@ -0,0 +1,70 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package discover + +import ( + "sync" +) + +// Ensure, that DiscoverMock does implement Discover. +// If this is not the case, regenerate this file with moq. +var _ Discover = &DiscoverMock{} + +// DiscoverMock is a mock implementation of Discover. +// +// func TestSomethingThatUsesDiscover(t *testing.T) { +// +// // make and configure a mocked Discover +// mockedDiscover := &DiscoverMock{ +// HooksFunc: func() ([]Hook, error) { +// panic("mock out the Hooks method") +// }, +// } +// +// // use mockedDiscover in code that requires Discover +// // and then make assertions. +// +// } +type DiscoverMock struct { + // HooksFunc mocks the Hooks method. + HooksFunc func() ([]Hook, error) + + // calls tracks calls to the methods. + calls struct { + // Hooks holds details about calls to the Hooks method. + Hooks []struct { + } + } + lockHooks sync.RWMutex +} + +// Hooks calls HooksFunc. +func (mock *DiscoverMock) Hooks() ([]Hook, error) { + callInfo := struct { + }{} + mock.lockHooks.Lock() + mock.calls.Hooks = append(mock.calls.Hooks, callInfo) + mock.lockHooks.Unlock() + if mock.HooksFunc == nil { + var ( + hooksOut []Hook + errOut error + ) + return hooksOut, errOut + } + return mock.HooksFunc() +} + +// HooksCalls gets all the calls that were made to Hooks. +// Check the length with: +// len(mockedDiscover.HooksCalls()) +func (mock *DiscoverMock) HooksCalls() []struct { +} { + var calls []struct { + } + mock.lockHooks.RLock() + calls = mock.calls.Hooks + mock.lockHooks.RUnlock() + return calls +} diff --git a/internal/discover/stable.go b/internal/discover/stable.go new file mode 100644 index 00000000..d5273002 --- /dev/null +++ b/internal/discover/stable.go @@ -0,0 +1,71 @@ +/** +# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. +# +# 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 discover + +import ( + "github.com/NVIDIA/nvidia-container-toolkit/internal/lookup" + "github.com/container-orchestrated-devices/container-device-interface/pkg/cdi" + "github.com/sirupsen/logrus" +) + +type stable struct { + logger *logrus.Logger + lookup lookup.Locator +} + +const ( + nvidiaContainerRuntimeHookExecuable = "nvidia-container-runtime-hook" + hookDefaultFilePath = "/usr/bin/nvidia-container-runtime-hook" +) + +var _ Discover = (*stable)(nil) + +// NewStableDiscoverer creates a discoverer for the stable runtime +func NewStableDiscoverer(logger *logrus.Logger, root string) (Discover, error) { + d := stable{ + logger: logger, + lookup: lookup.NewPathLocator(logger, root), + } + + return &d, nil +} + +// Hooks returns the "stable" NVIDIA Container Runtime hook +func (d stable) Hooks() ([]Hook, error) { + var hooks []Hook + + hookPath := hookDefaultFilePath + targets, err := d.lookup.Locate(nvidiaContainerRuntimeHookExecuable) + if err != nil { + d.logger.Warnf("Failed to locate %v: %v", nvidiaContainerRuntimeHookExecuable, err) + } else if len(targets) == 0 { + d.logger.Warnf("%v not found", nvidiaContainerRuntimeHookExecuable) + } else { + d.logger.Debugf("Found %v candidates: %v", nvidiaContainerRuntimeHookExecuable, targets) + hookPath = targets[0] + } + d.logger.Debugf("Using NVIDIA Container Runtime Hook path %v", hookPath) + + args := []string{hookPath, "prestart"} + legacyHook := Hook{ + Lifecycle: cdi.PrestartHook, + Path: hookPath, + Args: args, + } + hooks = append(hooks, legacyHook) + return hooks, nil +}