Repository: code-ready/crc
Pull request #1666 (2020-11-12 13:52:54)

Move shell package from libmachine to crc
This is the only location where this package is used.


openshift-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/code-ready/crc/pull/1666#" title="Author self-approved">guillaumerose</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=code-ready%2Fcrc).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/code-ready/crc/blob/master/OWNERS)~~ [guillaumerose]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
openshift-merge-robot: @guillaumerose: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/e2e-crc | ffa990143b238493ab985abf9b1b2428ed7822e1 | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/code-ready_crc/1666/pull-ci-code-ready-crc-master-e2e-crc/1326899983315636224) | `/test e2e-crc`

[Full PR test history](https://prow.ci.openshift.org/pr-history?org=code-ready&repo=crc&pr=1666). [Your PR dashboard](https://prow.ci.openshift.org/pr?query=is:pr+state:open+author:guillaumerose).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
guillaumerose: I added the error from AppVeyor. I guess it's an error due to cygwin or it is launched (cmd instead of powershell?).
openshift-merge-robot: @guillaumerose: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/e2e-crc | 2c96d66b1aa9fbb45dc95a7e86c51ea4bb65215e | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/code-ready_crc/1666/pull-ci-code-ready-crc-master-e2e-crc/1329741131423944704) | `/test e2e-crc`

[Full PR test history](https://prow.ci.openshift.org/pr-history?org=code-ready&repo=crc&pr=1666). [Your PR dashboard](https://prow.ci.openshift.org/pr?query=is:pr+state:open+author:guillaumerose).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
guillaumerose: /retest
openshift-merge-robot: @guillaumerose: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/e2e-crc | 7e464ac3dd1940fd1a7e8e7cf753e5078db3e609 | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/code-ready_crc/1666/pull-ci-code-ready-crc-master-e2e-crc/1331595460682452992) | `/test e2e-crc`

[Full PR test history](https://prow.ci.openshift.org/pr-history?org=code-ready&repo=crc&pr=1666). [Your PR dashboard](https://prow.ci.openshift.org/pr?query=is:pr+state:open+author:guillaumerose).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
guillaumerose: Funny, someone pinged me to merge this https://github.com/docker/machine/pull/4788#issuecomment-734809216

I guess we should include it :)

Patch:
diff --git a/docs/source/topics/assembly_accessing-the-openshift-cluster.adoc b/docs/source/topics/assembly_accessing-the-openshift-cluster.adoc
index 33cc32a49..51fd418b7 100644
--- a/docs/source/topics/assembly_accessing-the-openshift-cluster.adoc
+++ b/docs/source/topics/assembly_accessing-the-openshift-cluster.adoc
@@ -6,3 +6,5 @@ Access the OpenShift cluster running in the {prod} virtual machine through the O
 include::proc_accessing-the-openshift-web-console.adoc[leveloffset=+1]
 
 include::proc_accessing-the-openshift-cluster-with-oc.adoc[leveloffset=+1]
+
+include::proc_accessing-the-internal-openshift-registry.adoc[leveloffset=+1]
diff --git a/docs/source/topics/proc_accessing-the-internal-openshift-registry.adoc b/docs/source/topics/proc_accessing-the-internal-openshift-registry.adoc
new file mode 100644
index 000000000..1353604a8
--- /dev/null
+++ b/docs/source/topics/proc_accessing-the-internal-openshift-registry.adoc
@@ -0,0 +1,88 @@
+[id="accessing-the-internal-openshift-registry_{context}"]
+= Accessing the internal OpenShift registry
+
+The OpenShift cluster running in the {prod} virtual machine includes an internal container image registry by default.
+This internal container image registry can be used as a publication target for locally developed container images.
+To access the internal OpenShift registry, follow these steps.
+
+.Prerequisites
+
+* A running {prod} virtual machine.
+For more information, see link:{crc-gsg-url}#starting-the-virtual-machine_gsg[Starting the virtual machine].
+* A working [command]`oc` command.
+For more information, see link:{crc-gsg-url}#accessing-the-openshift-cluster-with-oc_gsg[Accessing the OpenShift cluster with `oc`].
+* An installation of [command]`podman` or [command]`docker`.
+** For Docker, add `default-route-openshift-image-registry.apps-crc.testing` as an insecure registry.
+For more information, see link:https://docs.docker.com/registry/insecure/[the Docker documentation].
+
+.Procedure
+
+. Check which user is logged in to the cluster:
++
+[subs="+quotes,attributes"]
+----
+$ oc whoami
+----
++
+[NOTE]
+====
+For demonstration purposes, the current user is assumed to be `kube:admin`.
+====
+
+. Log in to the registry as that user with its token:
++
+[subs="+quotes,attributes"]
+----
+$ podman login -u kubeadmin -p $(oc whoami -t) default-route-openshift-image-registry.apps-crc.testing --tls-verify=false
+----
+
+. Create a new project:
++
+[subs="+quotes,attributes"]
+----
+$ oc new-project demo
+----
+
+. Pull an example container image:
++
+[subs="+quotes,attributes"]
+----
+$ podman pull quay.io/libpod/alpine
+----
+
+. Tag the image, including namespace details:
++
+[subs="+quotes,attributes"]
+----
+$ podman tag alpine:latest default-route-openshift-image-registry.apps-crc.testing/demo/alpine:latest
+----
+
+. Push the container image to the internal registry:
++
+[subs="+quotes,attributes"]
+----
+$ podman push default-route-openshift-image-registry.apps-crc.testing/demo/alpine:latest --tls-verify=false
+----
+
+. Get imagestreams and verify that the pushed image is listed:
++
+[subs="+quotes,attributes"]
+----
+$ oc get is
+----
+
+. Enable image lookup for all tags in the imagestream:
++
+[subs="+quotes,attributes"]
+----
+$ oc set image-lookup
+----
++
+This setting allows the imagestream to be the source of images without having to provide the full URL to the internal registry.
+
+. Create a pod using the recently pushed image:
++
+[subs="+quotes,attributes"]
+----
+$ oc run demo --image=alpine --command -- sleep 600s
+----
diff --git a/pkg/crc/preflight/preflight_checks_darwin.go b/pkg/crc/preflight/preflight_checks_darwin.go
index ec11236a6..0626a2034 100644
--- a/pkg/crc/preflight/preflight_checks_darwin.go
+++ b/pkg/crc/preflight/preflight_checks_darwin.go
@@ -1,6 +1,7 @@
 package preflight
 
 import (
+	"errors"
 	"fmt"
 	"os"
 	"os/exec"
@@ -187,13 +188,28 @@ func addFileWritePermissionToUser(filename string) error {
 }
 
 func stopCRCHyperkitProcess() error {
-	path, err := exec.LookPath("pkill")
+	pgrepPath, err := exec.LookPath("pgrep")
+	if err != nil {
+		return fmt.Errorf("Could not find 'pgrep'. %w", err)
+	}
+	if _, _, err := crcos.RunWithDefaultLocale(pgrepPath, "-f", filepath.Join(constants.CrcBinDir, "hyperkit")); err != nil {
+		var exitErr *exec.ExitError
+		if errors.As(err, &exitErr) {
+			/* 1: no processes matched */
+			if exitErr.ExitCode() == 1 {
+				logging.Debugf("No running 'hyperkit' process started by crc")
+				return nil
+			}
+		}
+		logging.Debugf("Failed to find 'hyperkit' process. %v", err)
+		/* Unclear what pgrep failure was, don't return, maybe pkill will be more successful */
+	}
+
+	pkillPath, err := exec.LookPath("pkill")
 	if err != nil {
-		logging.Debugf("Could not find 'pkill'. %v", err)
 		return fmt.Errorf("Could not find 'pkill'. %w", err)
 	}
-	if _, _, err := crcos.RunWithDefaultLocale(path, "-f", filepath.Join(constants.CrcBinDir, "hyperkit")); err != nil {
-		logging.Debugf("Failed to kill 'hyperkit' process. %v", err)
+	if _, _, err := crcos.RunWithDefaultLocale(pkillPath, "-f", filepath.Join(constants.CrcBinDir, "hyperkit")); err != nil {
 		return fmt.Errorf("Failed to kill 'hyperkit' process. %w", err)
 	}
 	return nil
diff --git a/pkg/os/shell/shell.go b/pkg/os/shell/shell.go
index 2f8e94ae9..71142a396 100644
--- a/pkg/os/shell/shell.go
+++ b/pkg/os/shell/shell.go
@@ -3,8 +3,6 @@ package shell
 import (
 	"fmt"
 	"strings"
-
-	"github.com/code-ready/machine/libmachine/shell"
 )
 
 type Config struct {
@@ -21,7 +19,7 @@ func GetShell(userShell string) (string, error) {
 		}
 		return userShell, nil
 	}
-	return shell.Detect()
+	return detect()
 }
 
 func isSupportedShell(userShell string) bool {
diff --git a/vendor/github.com/code-ready/machine/libmachine/shell/shell.go b/pkg/os/shell/shell_unix.go
similarity index 84%
rename from vendor/github.com/code-ready/machine/libmachine/shell/shell.go
rename to pkg/os/shell/shell_unix.go
index d0a271c9a..7934bd912 100644
--- a/vendor/github.com/code-ready/machine/libmachine/shell/shell.go
+++ b/pkg/os/shell/shell_unix.go
@@ -13,8 +13,8 @@ var (
 	ErrUnknownShell = errors.New("Error: Unknown shell")
 )
 
-// Detect detects user's current shell.
-func Detect() (string, error) {
+// detect detects user's current shell.
+func detect() (string, error) {
 	shell := os.Getenv("SHELL")
 
 	if shell == "" {
diff --git a/pkg/os/shell/shell_windows.go b/pkg/os/shell/shell_windows.go
index 9c291bd21..6fb4f2a26 100644
--- a/pkg/os/shell/shell_windows.go
+++ b/pkg/os/shell/shell_windows.go
@@ -1,5 +1,90 @@
 package shell
 
+import (
+	"os"
+	"path/filepath"
+	"strings"
+	"syscall"
+	"unsafe"
+)
+
 var (
 	supportedShell = []string{"cmd", "powershell"}
 )
+
+// re-implementation of private function in https://github.com/golang/go/blob/master/src/syscall/syscall_windows.go
+func getProcessEntry(pid int) (pe *syscall.ProcessEntry32, err error) {
+	snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		_ = syscall.CloseHandle(syscall.Handle(snapshot))
+	}()
+
+	var processEntry syscall.ProcessEntry32
+	processEntry.Size = uint32(unsafe.Sizeof(processEntry))
+	err = syscall.Process32First(snapshot, &processEntry)
+	if err != nil {
+		return nil, err
+	}
+
+	for {
+		if processEntry.ProcessID == uint32(pid) {
+			pe = &processEntry
+			return
+		}
+
+		err = syscall.Process32Next(snapshot, &processEntry)
+		if err != nil {
+			return nil, err
+		}
+	}
+}
+
+// getNameAndItsPpid returns the exe file name its parent process id.
+func getNameAndItsPpid(pid int) (exefile string, parentid int, err error) {
+	pe, err := getProcessEntry(pid)
+	if err != nil {
+		return "", 0, err
+	}
+
+	name := syscall.UTF16ToString(pe.ExeFile[:])
+	return name, int(pe.ParentProcessID), nil
+}
+
+func detect() (string, error) {
+	shell := os.Getenv("SHELL")
+
+	if shell == "" {
+		shell, shellppid, err := getNameAndItsPpid(os.Getppid())
+		if err != nil {
+			return "cmd", err // defaulting to cmd
+		}
+		switch {
+		case strings.Contains(strings.ToLower(shell), "powershell"):
+			return "powershell", nil
+		case strings.Contains(strings.ToLower(shell), "cmd"):
+			return "cmd", nil
+		default:
+			shell, _, err := getNameAndItsPpid(shellppid)
+			if err != nil {
+				return "cmd", err // defaulting to cmd
+			}
+			switch {
+			case strings.Contains(strings.ToLower(shell), "powershell"):
+				return "powershell", nil
+			case strings.Contains(strings.ToLower(shell), "cmd"):
+				return "cmd", nil
+			default:
+				return "cmd", nil // this could be either powershell or cmd, defaulting to cmd
+			}
+		}
+	}
+
+	if os.Getenv("__fish_bin_dir") != "" {
+		return "fish", nil
+	}
+
+	return filepath.Base(shell), nil
+}
diff --git a/vendor/github.com/code-ready/machine/libmachine/shell/shell_windows.go b/vendor/github.com/code-ready/machine/libmachine/shell/shell_windows.go
deleted file mode 100644
index fc5341c2f..000000000
--- a/vendor/github.com/code-ready/machine/libmachine/shell/shell_windows.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package shell
-
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-	"strings"
-	"syscall"
-	"unsafe"
-)
-
-// re-implementation of private function in https://github.com/golang/go/blob/master/src/syscall/syscall_windows.go#L945
-func getProcessEntry(pid int) (pe *syscall.ProcessEntry32, err error) {
-	snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
-	if err != nil {
-		return nil, err
-	}
-	defer func() {
-		_ = syscall.CloseHandle(syscall.Handle(snapshot))
-	}()
-
-	var processEntry syscall.ProcessEntry32
-	processEntry.Size = uint32(unsafe.Sizeof(processEntry))
-	err = syscall.Process32First(snapshot, &processEntry)
-	if err != nil {
-		return nil, err
-	}
-
-	for {
-		if processEntry.ProcessID == uint32(pid) {
-			pe = &processEntry
-			return
-		}
-
-		err = syscall.Process32Next(snapshot, &processEntry)
-		if err != nil {
-			return nil, err
-		}
-	}
-}
-
-// getNameAndItsPpid returns the exe file name its parent process id.
-func getNameAndItsPpid(pid int) (exefile string, parentid int, err error) {
-	pe, err := getProcessEntry(pid)
-	if err != nil {
-		return "", 0, err
-	}
-
-	name := syscall.UTF16ToString(pe.ExeFile[:])
-	return name, int(pe.ParentProcessID), nil
-}
-
-func Detect() (string, error) {
-	shell := os.Getenv("SHELL")
-
-	if shell == "" {
-		shell, shellppid, err := getNameAndItsPpid(os.Getppid())
-		if err != nil {
-			return "cmd", err // defaulting to cmd
-		}
-		switch {
-		case strings.Contains(strings.ToLower(shell), "powershell"):
-			return "powershell", nil
-		case strings.Contains(strings.ToLower(shell), "cmd"):
-			return "cmd", nil
-		default:
-			shell, _, err := getNameAndItsPpid(shellppid)
-			if err != nil {
-				return "cmd", err // defaulting to cmd
-			}
-			switch {
-			case strings.Contains(strings.ToLower(shell), "powershell"):
-				return "powershell", nil
-			case strings.Contains(strings.ToLower(shell), "cmd"):
-				return "cmd", nil
-			default:
-				fmt.Printf("You can further specify your shell with either 'cmd' or 'powershell' with the --shell flag.\n\n")
-				return "cmd", nil // this could be either powershell or cmd, defaulting to cmd
-			}
-		}
-	}
-
-	if os.Getenv("__fish_bin_dir") != "" {
-		return "fish", nil
-	}
-
-	return filepath.Base(shell), nil
-}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 414e3755d..19dae08ea 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -51,7 +51,6 @@ github.com/code-ready/machine/libmachine/mcnerror
 github.com/code-ready/machine/libmachine/mcnflag
 github.com/code-ready/machine/libmachine/mcnutils
 github.com/code-ready/machine/libmachine/persist
-github.com/code-ready/machine/libmachine/shell
 github.com/code-ready/machine/libmachine/state
 github.com/code-ready/machine/libmachine/swarm
 github.com/code-ready/machine/libmachine/version


Test patch:
diff --git a/pkg/os/shell/shell_test.go b/pkg/os/shell/shell_test.go
new file mode 100644
index 000000000..c60567e19
--- /dev/null
+++ b/pkg/os/shell/shell_test.go
@@ -0,0 +1,30 @@
+// +build !windows
+
+package shell
+
+import (
+	"os"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestDetectBash(t *testing.T) {
+	defer func(shell string) { os.Setenv("SHELL", shell) }(os.Getenv("SHELL"))
+	os.Setenv("SHELL", "/bin/bash")
+
+	shell, err := detect()
+
+	assert.Equal(t, "bash", shell)
+	assert.NoError(t, err)
+}
+
+func TestDetectFish(t *testing.T) {
+	defer func(shell string) { os.Setenv("SHELL", shell) }(os.Getenv("SHELL"))
+	os.Setenv("SHELL", "/bin/fish")
+
+	shell, err := detect()
+
+	assert.Equal(t, "fish", shell)
+	assert.NoError(t, err)
+}
diff --git a/pkg/os/shell/shell_unix_test.go b/pkg/os/shell/shell_unix_test.go
new file mode 100644
index 000000000..bfaacda4a
--- /dev/null
+++ b/pkg/os/shell/shell_unix_test.go
@@ -0,0 +1,20 @@
+// +build !windows
+
+package shell
+
+import (
+	"os"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestUnknownShell(t *testing.T) {
+	defer func(shell string) { os.Setenv("SHELL", shell) }(os.Getenv("SHELL"))
+	os.Setenv("SHELL", "")
+
+	shell, err := detect()
+
+	assert.Equal(t, err, ErrUnknownShell)
+	assert.Empty(t, shell)
+}
diff --git a/pkg/os/shell/shell_windows_test.go b/pkg/os/shell/shell_windows_test.go
new file mode 100644
index 000000000..de7bf1a69
--- /dev/null
+++ b/pkg/os/shell/shell_windows_test.go
@@ -0,0 +1,33 @@
+package shell
+
+import (
+	"os"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestDetect(t *testing.T) {
+	defer func(shell string) { os.Setenv("SHELL", shell) }(os.Getenv("SHELL"))
+	os.Setenv("SHELL", "")
+
+	shell, err := detect()
+
+	assert.Contains(t, supportedShell, shell)
+	assert.NoError(t, err)
+}
+
+func TestGetNameAndItsPpidOfCurrent(t *testing.T) {
+	shell, shellppid, err := getNameAndItsPpid(os.Getpid())
+
+	assert.Equal(t, "shell.test.exe", shell)
+	assert.Equal(t, os.Getppid(), shellppid)
+	assert.NoError(t, err)
+}
+
+func TestGetNameAndItsPpidOfParent(t *testing.T) {
+	shell, _, err := getNameAndItsPpid(os.Getppid())
+
+	assert.Equal(t, "go.exe", shell)
+	assert.NoError(t, err)
+}