summaryrefslogtreecommitdiff
path: root/go/internal/executable
diff options
context:
space:
mode:
Diffstat (limited to 'go/internal/executable')
-rw-r--r--go/internal/executable/executable.go58
-rw-r--r--go/internal/executable/executable_test.go104
2 files changed, 162 insertions, 0 deletions
diff --git a/go/internal/executable/executable.go b/go/internal/executable/executable.go
new file mode 100644
index 0000000..63f4c90
--- /dev/null
+++ b/go/internal/executable/executable.go
@@ -0,0 +1,58 @@
+package executable
+
+import (
+ "os"
+ "path/filepath"
+)
+
+const (
+ GitlabShell = "gitlab-shell"
+ AuthorizedKeysCheck = "gitlab-shell-authorized-keys-check"
+ AuthorizedPrincipalsCheck = "gitlab-shell-authorized-principals-check"
+)
+
+type Executable struct {
+ Name string
+ RootDir string
+}
+
+var (
+ // osExecutable is overridden in tests
+ osExecutable = os.Executable
+)
+
+func New() (*Executable, error) {
+ path, err := osExecutable()
+ if err != nil {
+ return nil, err
+ }
+
+ rootDir, err := findRootDir(path)
+ if err != nil {
+ return nil, err
+ }
+
+ executable := &Executable{
+ Name: filepath.Base(path),
+ RootDir: rootDir,
+ }
+
+ return executable, nil
+}
+
+func findRootDir(path string) (string, error) {
+ // Start: /opt/.../gitlab-shell/bin/gitlab-shell
+ // Ends: /opt/.../gitlab-shell
+ rootDir := filepath.Dir(filepath.Dir(path))
+ pathFromEnv := os.Getenv("GITLAB_SHELL_DIR")
+
+ if pathFromEnv != "" {
+ if _, err := os.Stat(pathFromEnv); os.IsNotExist(err) {
+ return "", err
+ }
+
+ rootDir = pathFromEnv
+ }
+
+ return rootDir, nil
+}
diff --git a/go/internal/executable/executable_test.go b/go/internal/executable/executable_test.go
new file mode 100644
index 0000000..4d2174b
--- /dev/null
+++ b/go/internal/executable/executable_test.go
@@ -0,0 +1,104 @@
+package executable
+
+import (
+ "errors"
+ "testing"
+
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/testhelper"
+
+ "github.com/stretchr/testify/require"
+)
+
+type fakeOs struct {
+ OldExecutable func() (string, error)
+ Path string
+ Error error
+}
+
+func (f *fakeOs) Executable() (string, error) {
+ return f.Path, f.Error
+}
+
+func (f *fakeOs) Setup() {
+ f.OldExecutable = osExecutable
+ osExecutable = f.Executable
+}
+
+func (f *fakeOs) Cleanup() {
+ osExecutable = f.OldExecutable
+}
+
+func TestNewSuccess(t *testing.T) {
+ testCases := []struct {
+ desc string
+ fakeOs *fakeOs
+ environment map[string]string
+ expectedRootDir string
+ }{
+ {
+ desc: "GITLAB_SHELL_DIR env var is not defined",
+ fakeOs: &fakeOs{Path: "/tmp/bin/gitlab-shell"},
+ expectedRootDir: "/tmp",
+ },
+ {
+ desc: "GITLAB_SHELL_DIR env var is defined",
+ fakeOs: &fakeOs{Path: "/opt/bin/gitlab-shell"},
+ environment: map[string]string{
+ "GITLAB_SHELL_DIR": "/tmp",
+ },
+ expectedRootDir: "/tmp",
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.desc, func(t *testing.T) {
+ restoreEnv := testhelper.TempEnv(tc.environment)
+ defer restoreEnv()
+
+ fake := tc.fakeOs
+ fake.Setup()
+ defer fake.Cleanup()
+
+ result, err := New()
+
+ require.NoError(t, err)
+ require.Equal(t, result.Name, "gitlab-shell")
+ require.Equal(t, result.RootDir, tc.expectedRootDir)
+ })
+ }
+}
+
+func TestNewFailure(t *testing.T) {
+ testCases := []struct {
+ desc string
+ fakeOs *fakeOs
+ environment map[string]string
+ }{
+ {
+ desc: "failed to determine executable",
+ fakeOs: &fakeOs{Path: "", Error: errors.New("error")},
+ },
+ {
+ desc: "GITLAB_SHELL_DIR doesn't exist",
+ fakeOs: &fakeOs{Path: "/tmp/bin/gitlab-shell"},
+ environment: map[string]string{
+ "GITLAB_SHELL_DIR": "/tmp/non/existing/directory",
+ },
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.desc, func(t *testing.T) {
+ restoreEnv := testhelper.TempEnv(tc.environment)
+ defer restoreEnv()
+
+ fake := tc.fakeOs
+ fake.Setup()
+ defer fake.Cleanup()
+
+ _, err := New()
+
+ require.Error(t, err)
+ })
+ }
+}