Repository: code-ready/crc
Pull request #1858 (2021-01-20 15:32:15)

Unpack the tray in the macOS pkg directly
Notarization forces us to untar everything in the package. For an app,
it's slightly more complicated: the plist needs to be changed otherwise
the app is not installed at all.
    
Reference: https://scriptingosx.com/2017/05/relocatable-package-installers-and-quickpkg-update/

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

This pull-request has been approved by: *<a href="https://github.com/code-ready/crc/pull/1858#" 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":[]} -->
cfergeau: Do you have a reference for 'Notarization forces us to untar everything in the package' as well? I was initially confused as I thought the link talked about that, but I could not find it.
guillaumerose: When we try to notarize the application, Apple answers this error for the tarball:

```
{

    "severity": "warning",
    "code": null,
    "path": "crc-installer-macos-1.21.0-amd64.zip/crc-installer.pkg/crc.pkg Contents/Payload/Library/CodeReady Containers/1.21.0/crc-tray-macos.tar.gz",
    "message": "b'gunzip: /tmp/tmpxrahqkuu/crc-tray-macos.tar.gz.unpacked_00/crc-tray-macos.tar.gz: trailing garbage ignored\\n'",
    "docUrl": null,
    "architecture": null

},
```

Patch:
diff --git a/Makefile b/Makefile
index 16a5b83c9..ce3f09ad2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 SHELL := /bin/bash
 
-BUNDLE_VERSION = 4.6.9
+BUNDLE_VERSION = 4.6.12
 BUNDLE_EXTENSION = crcbundle
 CRC_VERSION = 1.21.0
 COMMIT_SHA=$(shell git rev-parse --short HEAD)
@@ -233,12 +233,20 @@ package: clean check_bundledir $(BUILD_DIR)/macos-amd64/crc $(HOST_BUILD_DIR)/cr
 	chmod 755 packaging/darwin/scripts/postinstall
 	mkdir -p packaging/root/"$(MACOS_INSTALL_PATH)"/$(CRC_VERSION)/
 	$(HOST_BUILD_DIR)/crc-embedder download packaging/root/"$(MACOS_INSTALL_PATH)"/$(CRC_VERSION)/
+
+	tar -C packaging/root/"$(MACOS_INSTALL_PATH)"/$(CRC_VERSION)/ -xvzf packaging/root/"$(MACOS_INSTALL_PATH)"/$(CRC_VERSION)/crc-tray-macos.tar.gz
+	rm packaging/root/"$(MACOS_INSTALL_PATH)"/$(CRC_VERSION)/crc-tray-macos.tar.gz
+
 	cp $(HYPERKIT_BUNDLENAME) packaging/root/"$(MACOS_INSTALL_PATH)"/$(CRC_VERSION)/
 	cp $(BUILD_DIR)/macos-amd64/crc packaging/root/"$(MACOS_INSTALL_PATH)"/$(CRC_VERSION)/
 	cp LICENSE packaging/darwin/Resources/LICENSE.txt
+	pkgbuild --analyze --root packaging/root packaging/components.plist
+	plutil -replace BundleIsRelocatable -bool NO packaging/components.plist
 	pkgbuild --identifier com.redhat.crc.$(CRC_VERSION) --version $(CRC_VERSION) \
 		--scripts packaging/darwin/scripts \
 		--root packaging/root \
+		--install-location / \
+		--component-plist packaging/components.plist \
 		$(BUILD_DIR)/macos-amd64/crc.pkg
 	productbuild --distribution packaging/darwin/Distribution \
 		--resources packaging/darwin/Resources \
diff --git a/centos_ci.sh b/centos_ci.sh
index 469aebe22..f223021ec 100644
--- a/centos_ci.sh
+++ b/centos_ci.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 # bundle location
-BUNDLE_VERSION=4.6.9
+BUNDLE_VERSION=4.6.12
 BUNDLE=crc_libvirt_$BUNDLE_VERSION.crcbundle
 GO_VERSION=1.14.13
 
diff --git a/cmd/crc/cmd/setup.go b/cmd/crc/cmd/setup.go
index e0e3946d1..e2d2951ee 100644
--- a/cmd/crc/cmd/setup.go
+++ b/cmd/crc/cmd/setup.go
@@ -33,8 +33,9 @@ var setupCmd = &cobra.Command{
 
 func runSetup(arguments []string) error {
 	if config.Get(cmdConfig.ConsentTelemetry).AsString() == "" {
-		fmt.Println("CodeReady Containers is constantly improving and we would like to know more about usage!")
-		if input.PromptUserForYesOrNo("Would you like to contribute anonymous usage statistics (more details at https://developers.redhat.com/article/tool-data-collection)", false) {
+		fmt.Println("CodeReady Containers is constantly improving and we would like to know more about usage (more details at https://developers.redhat.com/article/tool-data-collection)")
+		fmt.Println("Your preference can be changed manually if desired using 'crc config set consent-telemetry <yes/no>'")
+		if input.PromptUserForYesOrNo("Would you like to contribute anonymous usage statistics", false) {
 			if _, err := config.Set(cmdConfig.ConsentTelemetry, "yes"); err != nil {
 				return err
 			}
diff --git a/images/dnsmasq/Dockerfile b/images/dnsmasq/Dockerfile
index fd46f43f1..a5b679892 100644
--- a/images/dnsmasq/Dockerfile
+++ b/images/dnsmasq/Dockerfile
@@ -1,4 +1,4 @@
-FROM registry.redhat.io/ubi8/ubi
+FROM registry.access.redhat.com/ubi8/ubi
 MAINTAINER CodeReady Container <devtools-cdk@redhat.com>
 
 RUN yum -y install dnsmasq && \
diff --git a/images/docs-builder/Dockerfile b/images/docs-builder/Dockerfile
index 6a466ece7..c0b9a09b0 100644
--- a/images/docs-builder/Dockerfile
+++ b/images/docs-builder/Dockerfile
@@ -1,4 +1,4 @@
-FROM registry.redhat.io/ubi8
+FROM registry.access.redhat.com/ubi8/ubi
 MAINTAINER CodeReady Containers <devtools-cdk@redhat.com>
 
 RUN yum update -y && \
diff --git a/packaging/.gitignore b/packaging/.gitignore
index cfbfa1fdd..ff7927c1d 100644
--- a/packaging/.gitignore
+++ b/packaging/.gitignore
@@ -1,1 +1,6 @@
 root/
+/components.plist
+/darwin/Distribution
+/darwin/Resources/LICENSE.txt
+/darwin/Resources/welcome.html
+/darwin/scripts/postinstall
diff --git a/pkg/crc/constants/constants_darwin.go b/pkg/crc/constants/constants_darwin.go
index c018bb767..81337d8aa 100644
--- a/pkg/crc/constants/constants_darwin.go
+++ b/pkg/crc/constants/constants_darwin.go
@@ -1,6 +1,11 @@
 package constants
 
-import "path/filepath"
+import (
+	"os"
+	"path/filepath"
+
+	"github.com/code-ready/crc/pkg/crc/version"
+)
 
 const (
 	OcExecutableName          = "oc"
@@ -10,6 +15,16 @@ const (
 )
 
 var (
-	TrayAppBundlePath  = filepath.Join(CrcBinDir, TrayExecutableName)
+	TrayAppBundlePath  = trayAppBundlePath()
 	TrayExecutablePath = filepath.Join(TrayAppBundlePath, "Contents", "MacOS", "CodeReady Containers")
 )
+
+func trayAppBundlePath() string {
+	if version.IsMacosInstallPathSet() {
+		path := filepath.Join(version.GetMacosInstallPath(), version.GetCRCVersion(), TrayExecutableName)
+		if _, err := os.Stat(path); err == nil {
+			return path
+		}
+	}
+	return filepath.Join(CrcBinDir, TrayExecutableName)
+}
diff --git a/pkg/crc/machine/bundle/repository.go b/pkg/crc/machine/bundle/repository.go
index 059c8b61e..60d4cb990 100644
--- a/pkg/crc/machine/bundle/repository.go
+++ b/pkg/crc/machine/bundle/repository.go
@@ -83,6 +83,14 @@ func (repo *Repository) Use(bundleName string) (*CrcBundleInfo, error) {
 func (bundle *CrcBundleInfo) createSymlinkOrCopyOpenShiftClient(ocBinDir string) error {
 	ocInBundle := bundle.resolvePath(constants.OcExecutableName)
 	ocInBinDir := filepath.Join(ocBinDir, constants.OcExecutableName)
+
+	// this is needed when upgrading from crc versions anterior to commit 1.11.0~5
+	if info, err := os.Stat(ocBinDir); err == nil && !info.IsDir() {
+		if err := os.Remove(ocBinDir); err != nil {
+			return err
+		}
+	}
+
 	if err := os.MkdirAll(ocBinDir, 0750); err != nil {
 		return err
 	}
diff --git a/pkg/crc/preflight/preflight_checks_linux.go b/pkg/crc/preflight/preflight_checks_linux.go
index 41b03a9a3..4015797f4 100644
--- a/pkg/crc/preflight/preflight_checks_linux.go
+++ b/pkg/crc/preflight/preflight_checks_linux.go
@@ -219,7 +219,7 @@ func fixUserPartOfLibvirtGroup(distro *linux.OsRelease) func() error {
 		logging.Debug("Current user is in the libvirt group")
 
 		if distroIsLike(distro, linux.Ubuntu) {
-			return fmt.Errorf("Current user added to libvirt group. Please logout and login again")
+			return fmt.Errorf("Current user added to libvirt group. Please logout, login again, and run crc setup again")
 		}
 		return err
 	}
diff --git a/pkg/crc/preflight/preflight_checks_network_linux.go b/pkg/crc/preflight/preflight_checks_network_linux.go
index ca22b3ea9..725d78da8 100644
--- a/pkg/crc/preflight/preflight_checks_network_linux.go
+++ b/pkg/crc/preflight/preflight_checks_network_linux.go
@@ -19,7 +19,7 @@ var nmPreflightChecks = [...]Check{
 		configKeySuffix:  "check-systemd-networkd-running",
 		checkDescription: "Checking if systemd-networkd is running",
 		check:            checkSystemdNetworkdIsNotRunning,
-		fixDescription:   "network configuration with systemd-networkd is not supported",
+		fixDescription:   "Network configuration with systemd-networkd is not supported. Perhaps you can try this new network mode: https://github.com/code-ready/crc/wiki/VPN-support--with-an--userland-network-stack",
 		flags:            NoFix,
 	},
 	{
diff --git a/pkg/crc/preflight/preflight_linux.go b/pkg/crc/preflight/preflight_linux.go
index d7f817574..86e21c4f8 100644
--- a/pkg/crc/preflight/preflight_linux.go
+++ b/pkg/crc/preflight/preflight_linux.go
@@ -121,7 +121,7 @@ func checkVsock() error {
 	if err != nil {
 		return err
 	}
-	if !strings.Contains(string(getcap), "cap_net_bind_service+eip") {
+	if !strings.Contains(getcap, "cap_net_bind_service+eip") {
 		return fmt.Errorf("capabilities are not correct for %s", executable)
 	}
 	info, err := os.Stat("/dev/vsock")
diff --git a/pkg/crc/segment/segment.go b/pkg/crc/segment/segment.go
index dc0b7ce39..723efd6bd 100644
--- a/pkg/crc/segment/segment.go
+++ b/pkg/crc/segment/segment.go
@@ -2,6 +2,7 @@ package segment
 
 import (
 	"io/ioutil"
+	"net"
 	"os"
 	"path/filepath"
 	"strings"
@@ -34,6 +35,9 @@ func newCustomClient(config *crcConfig.Config, telemetryFilePath, segmentEndpoin
 	client, err := analytics.NewWithConfig(WriteKey, analytics.Config{
 		Endpoint: segmentEndpoint,
 		Logger:   &loggingAdapter{},
+		DefaultContext: &analytics.Context{
+			IP: net.IPv4(0, 0, 0, 0),
+		},
 	})
 	if err != nil {
 		return nil, err
diff --git a/pkg/crc/services/dns/dns_windows.go b/pkg/crc/services/dns/dns_windows.go
index a17c4beaa..57f327103 100644
--- a/pkg/crc/services/dns/dns_windows.go
+++ b/pkg/crc/services/dns/dns_windows.go
@@ -31,7 +31,7 @@ func runPostStartForOS(serviceConfig services.ServicePostStartConfig) error {
 	time.Sleep(2 * time.Second)
 
 	if !contains(getInterfaceNameserverValues(networkInterface), serviceConfig.IP) {
-		return fmt.Errorf("Nameserver %s not successfully set on interface %s", serviceConfig.IP, networkInterface)
+		return fmt.Errorf("Nameserver %s not successfully set on interface %s. Perhaps you can try this new network mode: https://github.com/code-ready/crc/wiki/VPN-support--with-an--userland-network-stack", serviceConfig.IP, networkInterface)
 	}
 	return nil
 }


Test patch:
diff --git a/pkg/crc/machine/bundle/repository_test.go b/pkg/crc/machine/bundle/repository_test.go
index 72f642f2d..13cc9acf8 100644
--- a/pkg/crc/machine/bundle/repository_test.go
+++ b/pkg/crc/machine/bundle/repository_test.go
@@ -21,9 +21,7 @@ func TestUse(t *testing.T) {
 	assert.NoError(t, err)
 	defer os.RemoveAll(ocBinDir)
 
-	assert.NoError(t, os.Mkdir(filepath.Join(dir, "crc_libvirt_4.6.1"), 0755))
-	writeMetadata(t, filepath.Join(dir, "crc_libvirt_4.6.1"), reference)
-	assert.NoError(t, ioutil.WriteFile(filepath.Join(dir, "crc_libvirt_4.6.1", constants.OcExecutableName), []byte("openshift-client"), 0600))
+	addBundle(t, dir, "crc_libvirt_4.6.1")
 
 	repo := &Repository{
 		CacheDir: dir,
@@ -39,6 +37,27 @@ func TestUse(t *testing.T) {
 	assert.Equal(t, "openshift-client", string(bin))
 }
 
+func TestUseWithOCFile(t *testing.T) {
+	dir, err := ioutil.TempDir("", "repo")
+	assert.NoError(t, err)
+	defer os.RemoveAll(dir)
+
+	fd, err := ioutil.TempFile("", "oc-bin-dir")
+	assert.NoError(t, err)
+	fd.Close()
+	defer os.RemoveAll(fd.Name())
+
+	addBundle(t, dir, "crc_libvirt_4.6.1")
+
+	repo := &Repository{
+		CacheDir: dir,
+		OcBinDir: fd.Name(),
+	}
+
+	_, err = repo.Use("crc_libvirt_4.6.1.crcbundle")
+	assert.NoError(t, err)
+}
+
 func TestExtract(t *testing.T) {
 	dir, err := ioutil.TempDir("", "repo")
 	assert.NoError(t, err)
@@ -105,3 +124,9 @@ func TestVersionCheck(t *testing.T) {
 func writeMetadata(t *testing.T, dir string, s string) bool {
 	return assert.NoError(t, ioutil.WriteFile(filepath.Join(dir, metadataFilename), []byte(s), 0600))
 }
+
+func addBundle(t *testing.T, dir, name string) {
+	assert.NoError(t, os.Mkdir(filepath.Join(dir, name), 0755))
+	writeMetadata(t, filepath.Join(dir, name), reference)
+	assert.NoError(t, ioutil.WriteFile(filepath.Join(dir, name, constants.OcExecutableName), []byte("openshift-client"), 0600))
+}
diff --git a/test/integration/crcsuite/crcsuite.go b/test/integration/crcsuite/crcsuite.go
index 5f6404dcf..afd5b80fb 100644
--- a/test/integration/crcsuite/crcsuite.go
+++ b/test/integration/crcsuite/crcsuite.go
@@ -137,9 +137,13 @@ func FeatureContext(s *godog.Suite) {
 
 	s.BeforeScenario(func(pickle *messages.Pickle) {
 		// copy data/config files to test dir
-		err := CopyFilesToTestDir()
-		if err != nil {
-			os.Exit(1)
+		for _, tag := range pickle.GetTags() {
+			if tag.Name == "@testdata" {
+				err := CopyFilesToTestDir()
+				if err != nil {
+					os.Exit(1)
+				}
+			}
 		}
 	})
 
diff --git a/test/integration/features/story_marketplace.feature b/test/integration/features/story_marketplace.feature
index ef05ffe2d..b79416283 100644
--- a/test/integration/features/story_marketplace.feature
+++ b/test/integration/features/story_marketplace.feature
@@ -22,13 +22,13 @@ Feature: Operator from marketplace
         When checking that CRC is running
         Then login to the oc cluster succeeds
 
-    @darwin @linux @windows
+    @darwin @linux @windows @testdata
     Scenario: Install new operator
         When executing "oc apply -f etcdop-sub.yaml" succeeds
         # check if cluster operator is running
         Then with up to "20" retries with wait period of "30s" command "oc get csv" output matches ".*etcdoperator\.(.*)Succeeded$"
         
-    @darwin @linux @windows
+    @darwin @linux @windows @testdata
     Scenario: Scale up
         # start cluster with 3 pods
         When executing "oc apply -f etcd-cluster3.yaml" succeeds
@@ -63,7 +63,7 @@ Feature: Operator from marketplace
         But executing "oc get pods $Env:POD" fails
         And stderr matches "(.*)pods (.*) not found$"
 
-    @darwin @linux @windows
+    @darwin @linux @windows @testdata
     Scenario: Scale down
         # scale back down to 3 pods
         When executing "oc apply -f etcd-cluster3.yaml" succeeds
diff --git a/test/integration/features/story_registry.feature b/test/integration/features/story_registry.feature
index 40f8d5119..421569363 100644
--- a/test/integration/features/story_registry.feature
+++ b/test/integration/features/story_registry.feature
@@ -14,15 +14,16 @@ Feature: Local image to image-registry
         And login to the oc cluster succeeds
 
     Scenario: Create local image
-        Given executing "podman build -t hello:test -f Dockerfile" succeeds
+        Given executing "podman pull quay.io/bitnami/nginx" succeeds
         When executing "podman images" succeeds
-        Then stdout should contain "localhost/hello"
+        Then stdout should contain "quay.io/bitnami/nginx"
         
     Scenario: Push local image to OpenShift image registry
         Given executing "oc new-project testproj-img" succeeds
         When executing "podman login -u kubeadmin -p $(oc whoami -t) default-route-openshift-image-registry.apps-crc.testing --tls-verify=false" succeeds
         Then stdout should contain "Login Succeeded!"
-        When executing "podman push hello:test default-route-openshift-image-registry.apps-crc.testing/testproj-img/hello:test --tls-verify=false" succeeds
+         And executing "podman tag quay.io/bitnami/nginx:latest default-route-openshift-image-registry.apps-crc.testing/testproj-img/hello:test" succeeds
+        When executing "podman push default-route-openshift-image-registry.apps-crc.testing/testproj-img/hello:test --tls-verify=false" succeeds
 
     Scenario: Deploy the image
         Given executing "oc new-app testproj-img/hello:test" succeeds
@@ -31,12 +32,12 @@ Feature: Local image to image-registry
         When executing "oc get pods" succeeds
         Then stdout should contain "Running"
         When executing "oc logs deployment/hello" succeeds
-        Then stdout should contain "Hello, it works!"
+        Then stdout should contain "Starting NGINX"
 
     Scenario: Clean up
         Given executing "podman images" succeeds
-        When stdout contains "localhost/hello"
-        Then executing "podman image rm localhost/hello:test" succeeds
+        When stdout contains "quay.io/bitnami/nginx"
+        Then executing "podman image rm quay.io/bitnami/nginx" succeeds
         And executing "oc delete project testproj-img" succeeds
         And executing "crc delete -f" succeeds
         Then stdout should contain "Deleted the OpenShift cluster"
diff --git a/test/testdata/Dockerfile b/test/testdata/Dockerfile
deleted file mode 100644
index b384783b3..000000000
--- a/test/testdata/Dockerfile
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM registry.centos.org/centos/centos:latest
-
-RUN groupadd -r crcek -g 1234 && useradd -u 1234 -r -g crcek -m -d /crcek -s /sbin/nologin -c "CRC user" crcek && chmod 755 /crcek
-
-WORKDIR /crcek
-
-USER crcek
-
-ENTRYPOINT ["/bin/bash", "-c", "echo Hello, it works! && echo Sleeping for 10min && sleep 10m && echo Done."]