diff --git a/internal/oci/runtime_exec.go b/internal/oci/runtime_exec.go deleted file mode 100644 index 98415747..00000000 --- a/internal/oci/runtime_exec.go +++ /dev/null @@ -1,79 +0,0 @@ -/* -# Copyright (c) 2021, 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 oci - -import ( - "fmt" - "os" - "syscall" - - log "github.com/sirupsen/logrus" -) - -// SyscallExecRuntime wraps the path that a binary and defines the semanitcs for how to exec into it. -// This can be used to wrap an OCI-compliant low-level runtime binary, allowing it to be used through the -// Runtime internface. -type SyscallExecRuntime struct { - logger *log.Logger - path string - // exec is used for testing. This defaults to syscall.Exec - exec func(argv0 string, argv []string, envv []string) error -} - -var _ Runtime = (*SyscallExecRuntime)(nil) - -// NewSyscallExecRuntime creates a SyscallExecRuntime for the specified path with the standard logger -func NewSyscallExecRuntime(path string) (Runtime, error) { - return NewSyscallExecRuntimeWithLogger(log.StandardLogger(), path) -} - -// NewSyscallExecRuntimeWithLogger creates a SyscallExecRuntime for the specified logger and path -func NewSyscallExecRuntimeWithLogger(logger *log.Logger, path string) (Runtime, error) { - info, err := os.Stat(path) - if err != nil { - return nil, fmt.Errorf("invalid path '%v': %v", path, err) - } - if info.IsDir() || info.Mode()&0111 == 0 { - return nil, fmt.Errorf("specified path '%v' is not an executable file", path) - } - - shim := SyscallExecRuntime{ - logger: logger, - path: path, - exec: syscall.Exec, - } - - return &shim, nil -} - -// Exec exces into the binary at the path from the SyscallExecRuntime struct, passing it the supplied arguments -// after ensuring that the first argument is the path of the target binary. -func (s SyscallExecRuntime) Exec(args []string) error { - runtimeArgs := []string{s.path} - if len(args) > 1 { - runtimeArgs = append(runtimeArgs, args[1:]...) - } - - err := s.exec(s.path, runtimeArgs, os.Environ()) - if err != nil { - return fmt.Errorf("could not exec '%v': %v", s.path, err) - } - - // syscall.Exec is not expected to return. This is an error state regardless of whether - // err is nil or not. - return fmt.Errorf("unexpected return from exec '%v'", s.path) -} diff --git a/internal/oci/runtime_exec_test.go b/internal/oci/runtime_exec_test.go deleted file mode 100644 index 83ac64a2..00000000 --- a/internal/oci/runtime_exec_test.go +++ /dev/null @@ -1,100 +0,0 @@ -/* -# Copyright (c) 2021, 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 oci - -import ( - "fmt" - "strings" - "testing" - - testlog "github.com/sirupsen/logrus/hooks/test" - "github.com/stretchr/testify/require" -) - -func TestSyscallExecConstructor(t *testing.T) { - r, err := NewSyscallExecRuntime("////an/invalid/path") - require.Error(t, err) - require.Nil(t, r) - - r, err = NewSyscallExecRuntime("/tmp") - require.Error(t, err) - require.Nil(t, r) - - r, err = NewSyscallExecRuntime("/dev/null") - require.Error(t, err) - require.Nil(t, r) - - r, err = NewSyscallExecRuntime("/bin/sh") - require.NoError(t, err) - - f, ok := r.(*SyscallExecRuntime) - require.True(t, ok) - - require.Equal(t, "/bin/sh", f.path) -} - -func TestSyscallExecForwardsArgs(t *testing.T) { - logger, _ := testlog.NewNullLogger() - f := SyscallExecRuntime{ - logger: logger, - path: "runtime", - } - - testCases := []struct { - returnError error - args []string - errorPrefix string - }{ - { - returnError: nil, - errorPrefix: "unexpected return from exec", - }, - { - returnError: fmt.Errorf("error from exec"), - errorPrefix: "could not exec", - }, - { - returnError: nil, - args: []string{"otherargv0"}, - errorPrefix: "unexpected return from exec", - }, - { - returnError: nil, - args: []string{"otherargv0", "arg1", "arg2", "arg3"}, - errorPrefix: "unexpected return from exec", - }, - } - - for i, tc := range testCases { - execMock := WithMockExec(f, tc.returnError) - - err := execMock.Exec(tc.args) - - require.Errorf(t, err, "%d: %v", i, tc) - require.Truef(t, strings.HasPrefix(err.Error(), tc.errorPrefix), "%d: %v", i, tc) - if tc.returnError != nil { - require.Truef(t, strings.HasSuffix(err.Error(), tc.returnError.Error()), "%d: %v", i, tc) - } - - require.Equalf(t, f.path, execMock.argv0, "%d: %v", i, tc) - require.Equalf(t, f.path, execMock.argv[0], "%d: %v", i, tc) - - require.LessOrEqualf(t, len(tc.args), len(execMock.argv), "%d: %v", i, tc) - if len(tc.args) > 1 { - require.Equalf(t, tc.args[1:], execMock.argv[1:], "%d: %v", i, tc) - } - } -}