diff --git a/sources b/sources index d230e8e..605595e 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (toolbox-0.0.99.2-vendored.tar.xz) = 44eab6eb98fc8e52e03fc753e1c26e5d2d8a91e5ba84817bbf76f7dc6601581b5922115c140637951074ab8d741f443b3217a07639ea4d7bdf81d5faf836e3b2 +SHA512 (toolbox-0.0.99.2^1.git660b6970e998-vendored.tar.xz) = edc035b19e8330c55669ad318da1553a700c6e064ba602fe2e7da83f6db23ff1a13297f91fb816b6cc58cbccf1676125923f1c889df86edde60374fdec1d8f6f diff --git a/toolbox-Support-logging-into-a-registry-if-necessary.patch b/toolbox-Support-logging-into-a-registry-if-necessary.patch deleted file mode 100644 index d1f9dd0..0000000 --- a/toolbox-Support-logging-into-a-registry-if-necessary.patch +++ /dev/null @@ -1,667 +0,0 @@ -From 62a022428231df50637495673354d4fdd2541c1a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ond=C5=99ej=20M=C3=ADchal?= -Date: Mon, 7 Jun 2021 14:11:27 +0200 -Subject: [PATCH 1/7] pkg/podman: Support parsing 'podman pull' spew into a Go - error - -This is meant to get a better understanding of a failed 'podman pull' -invocation to understand whether pulling an image requires logging into -the registry or not. Currently, 'podman pull' doesn't have a dedicated -exit code to denote authorization errors, so this is meant to be a -temporary workaround for that. - -Parsing the error stream is inherently fragile and tricky because -there's no guarantee that the structure of the messages won't change, -and there's no clear definition of how the messages are laid out. -Therefore, this approach can't be treated as a generic solution for -getting detailed information about failed Podman invocations. - -The error stream is used not only for dumping error messages, but also -for showing progress bars. Therefore, all lines are skipped until one -that starts with "Error: " is found. This is a heuristic based on how -Go programs written using the Cobra [1] library tend to report errors. - -All subsequent lines are taken together and split around the ": " -sub-string, on the assumption that the ": " sub-string is used when a -new error message is prefixed to an inner error. Each sub-string -created from the split is treated as a potential member of the chain of -errors reported within Podman. - -Some real world examples of the 'podman pull' error stream in the case -of authorization errors are: - - * With Docker Hub (https://hub.docker.com/): - Trying to pull docker.io/library/foobar:latest... - Error: Error initializing source docker://foobar:latest: Error reading manifest latest in docker.io/library/foobar: errors: - denied: requested access to the resource is denied - unauthorized: authentication required - - * With registry.redhat.io: - Trying to pull registry.redhat.io/foobar:latest... - Error: Error initializing source docker://registry.redhat.io/foobar:latest: unable to retrieve auth token: invalid username/password: unauthorized: Please login to the Red Hat Registry using your Customer Portal credentials. Further instructions can be found here: https://access.redhat.com/RegistryAuthentication - -[1] https://github.com/spf13/cobra/ - https://pkg.go.dev/github.com/spf13/cobra - -https://github.com/containers/toolbox/pull/786 -https://github.com/containers/toolbox/pull/787 ---- - src/pkg/podman/error.go | 109 +++++++++++++++++++++++++ - src/pkg/podman/error_test.go | 152 +++++++++++++++++++++++++++++++++++ - 2 files changed, 261 insertions(+) - create mode 100644 src/pkg/podman/error.go - create mode 100644 src/pkg/podman/error_test.go - -diff --git a/src/pkg/podman/error.go b/src/pkg/podman/error.go -new file mode 100644 -index 000000000000..ea35de8d7ed8 ---- /dev/null -+++ b/src/pkg/podman/error.go -@@ -0,0 +1,109 @@ -+/* -+ * Copyright © 2021 Red Hat Inc. -+ * -+ * 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 podman -+ -+import ( -+ "bufio" -+ "bytes" -+ "strings" -+) -+ -+// internalError serves for representing errors printed by Podman to stderr -+type internalError struct { -+ errors []string -+} -+ -+func (e *internalError) Error() string { -+ if e.errors == nil || len(e.errors) == 0 { -+ return "" -+ } -+ -+ var builder strings.Builder -+ -+ for i, part := range e.errors { -+ if i != 0 { -+ builder.WriteString(": ") -+ } -+ -+ builder.WriteString(part) -+ } -+ -+ return builder.String() -+} -+ -+// Is lexically compares errors -+// -+// The comparison is done for every part in the error chain not across. -+func (e *internalError) Is(target error) bool { -+ if target == nil { -+ return false -+ } -+ -+ if e.errors == nil || len(e.errors) == 0 { -+ return false -+ } -+ -+ for _, part := range e.errors { -+ if part == target.Error() { -+ return true -+ } -+ } -+ -+ return false -+} -+ -+func (e *internalError) Unwrap() error { -+ if e.errors == nil || len(e.errors) <= 1 { -+ return nil -+ } -+ -+ return &internalError{e.errors[1:]} -+} -+ -+// parseErrorMsg serves for converting error output of Podman into an error -+// that can be further used in Go -+func parseErrorMsg(stderr *bytes.Buffer) error { -+ // Stderr is not used only for error messages but also for things like -+ // progress bars. We're only interested in the error messages. -+ -+ var errMsgFound bool -+ var errMsgParts []string -+ -+ scanner := bufio.NewScanner(stderr) -+ for scanner.Scan() { -+ line := scanner.Text() -+ -+ if strings.HasPrefix(line, "Error: ") { -+ line = strings.TrimPrefix(line, "Error: ") -+ errMsgFound = true -+ } -+ -+ if errMsgFound { -+ line = strings.TrimSpace(line) -+ line = strings.Trim(line, ":") -+ -+ parts := strings.Split(line, ": ") -+ errMsgParts = append(errMsgParts, parts...) -+ } -+ } -+ -+ if !errMsgFound { -+ return nil -+ } -+ -+ return &internalError{errMsgParts} -+} -diff --git a/src/pkg/podman/error_test.go b/src/pkg/podman/error_test.go -new file mode 100644 -index 000000000000..11652c709bdd ---- /dev/null -+++ b/src/pkg/podman/error_test.go -@@ -0,0 +1,152 @@ -+/* -+ * Copyright © 2021 Red Hat Inc. -+ * -+ * 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 podman -+ -+import ( -+ "bytes" -+ "errors" -+ "testing" -+ -+ "github.com/stretchr/testify/assert" -+) -+ -+func TestInternalError(t *testing.T) { -+ type expect struct { -+ IsNil bool -+ Error string -+ Search string -+ Wrap []string -+ } -+ -+ testCases := []struct { -+ name string -+ input string -+ expect expect -+ }{ -+ { -+ name: "Empty", -+ input: "", -+ expect: expect{ -+ IsNil: true, -+ Error: "", -+ }, -+ }, -+ { -+ name: "Text with only a prolog and no error message", -+ input: "There is only a prolog and no error message", -+ expect: expect{ -+ IsNil: true, -+ Error: "", -+ }, -+ }, -+ { -+ name: "Text with only a prolog and no error message", -+ input: "There is only a prolog Error: not an error message", -+ expect: expect{ -+ IsNil: true, -+ Error: "", -+ }, -+ }, -+ { -+ name: "Text with a prolog before the error message", -+ input: `There is a prolog -+Error: an error message`, -+ expect: expect{ -+ Error: "an error message", -+ Search: "an error message", -+ }, -+ }, -+ { -+ name: "Error message with several wrapped errors", -+ input: "Error: level 1: level 2: level 3: level 4", -+ expect: expect{ -+ Error: "level 1: level 2: level 3: level 4", -+ Search: "level 4", -+ Wrap: []string{"level 1", "level 2", "level 3", "level 4"}, -+ }, -+ }, -+ { -+ name: "Error message with a bullet list", -+ input: `Error: an error message: -+ err1 -+ err2 -+ err3`, -+ expect: expect{ -+ Error: "an error message: err1: err2: err3", -+ Search: "err2", -+ Wrap: []string{"an error message", "err1", "err2", "err3"}, -+ }, -+ }, -+ { -+ name: "Error message from 'podman pull' - unauthorized (Docker Hub)", -+ input: `Trying to pull docker.io/library/foobar:latest... -+Error: Error initializing source docker://foobar:latest: Error reading manifest latest in docker.io/library/foobar: errors: -+denied: requested access to the resource is denied -+unauthorized: authentication required`, -+ expect: expect{ -+ Error: "Error initializing source docker://foobar:latest: Error reading manifest latest in docker.io/library/foobar: errors: denied: requested access to the resource is denied: unauthorized: authentication required", -+ }, -+ }, -+ { -+ name: "Error message from 'podman pull' - unauthorized (Red Hat Registry)", -+ input: `Trying to pull registry.redhat.io/foobar:latest... -+Error: Error initializing source docker://registry.redhat.io/foobar:latest: unable to retrieve auth token: invalid username/password: unauthorized: Please login to the Red Hat Registry using your Customer Portal credentials. Further instructions can be found here: https://access.redhat.com/RegistryAuthentication -+`, -+ expect: expect{ -+ Error: "Error initializing source docker://registry.redhat.io/foobar:latest: unable to retrieve auth token: invalid username/password: unauthorized: Please login to the Red Hat Registry using your Customer Portal credentials. Further instructions can be found here: https://access.redhat.com/RegistryAuthentication", -+ }, -+ }, -+ } -+ -+ for _, tc := range testCases { -+ t.Run(tc.name, func(t *testing.T) { -+ err := parseErrorMsg(bytes.NewBufferString(tc.input)) -+ -+ if tc.expect.IsNil { -+ assert.Nil(t, err) -+ return -+ } else { -+ assert.NotNil(t, err) -+ } -+ -+ errInternal := err.(*internalError) -+ assert.Equal(t, tc.expect.Error, errInternal.Error()) -+ -+ if tc.expect.Search != "" { -+ assert.True(t, errInternal.Is(errors.New(tc.expect.Search))) -+ } -+ -+ if len(tc.expect.Wrap) != 0 { -+ for { -+ assert.Equal(t, len(tc.expect.Wrap), len(errInternal.errors)) -+ -+ for i, part := range tc.expect.Wrap { -+ assert.Equal(t, part, errInternal.errors[i]) -+ } -+ -+ err = errInternal.Unwrap() -+ if err == nil { -+ assert.Equal(t, len(tc.expect.Wrap), 1) -+ break -+ } -+ errInternal = err.(*internalError) -+ tc.expect.Wrap = tc.expect.Wrap[1:] -+ } -+ } -+ }) -+ } -+} --- -2.31.1 - - -From 146c93b431941d21b3c686734a7b83a737072004 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ond=C5=99ej=20M=C3=ADchal?= -Date: Sat, 3 Jul 2021 22:06:30 +0200 -Subject: [PATCH 2/7] pkg/shell: Allow extracting the stderr even when it's - shown to the user - -This way the standard error stream of the spawned binaries can be -inspected to get a better understanding of the failure, while still -being shown to the user when run with the '--verbose' flag. - -Unfortunately, this breaks the progress bar in 'podman pull' because -the standard error stream is no longer connected to a file descriptor -that's a terminal device. - -https://github.com/containers/toolbox/pull/787 -https://github.com/containers/toolbox/pull/823 ---- - src/pkg/shell/shell.go | 22 +++++++++++++++++----- - 1 file changed, 17 insertions(+), 5 deletions(-) - -diff --git a/src/pkg/shell/shell.go b/src/pkg/shell/shell.go -index 272dcc9ca693..c63b85bc8745 100644 ---- a/src/pkg/shell/shell.go -+++ b/src/pkg/shell/shell.go -@@ -40,15 +40,12 @@ func Run(name string, stdin io.Reader, stdout, stderr io.Writer, arg ...string) - } - - func RunWithExitCode(name string, stdin io.Reader, stdout, stderr io.Writer, arg ...string) (int, error) { -- logLevel := logrus.GetLevel() -- if stderr == nil && logLevel >= logrus.DebugLevel { -- stderr = os.Stderr -- } -+ stderrWrapper := getStderrWrapper(stderr) - - cmd := exec.Command(name, arg...) - cmd.Stdin = stdin - cmd.Stdout = stdout -- cmd.Stderr = stderr -+ cmd.Stderr = stderrWrapper - - if err := cmd.Run(); err != nil { - if errors.Is(err, exec.ErrNotFound) { -@@ -66,3 +63,18 @@ func RunWithExitCode(name string, stdin io.Reader, stdout, stderr io.Writer, arg - - return 0, nil - } -+ -+func getStderrWrapper(buffer io.Writer) io.Writer { -+ var stderr io.Writer -+ -+ logLevel := logrus.GetLevel() -+ if logLevel < logrus.DebugLevel { -+ stderr = buffer -+ } else if buffer == nil { -+ stderr = os.Stderr -+ } else { -+ stderr = io.MultiWriter(buffer, os.Stderr) -+ } -+ -+ return stderr -+} --- -2.31.1 - - -From 5c3249033224c6f107a2d39ab84e519303d74072 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ond=C5=99ej=20M=C3=ADchal?= -Date: Sun, 4 Jul 2021 18:15:16 +0200 -Subject: [PATCH 3/7] pkg/podman: Try to parse the error from 'podman pull' - into a Go error - -https://github.com/containers/toolbox/pull/787 ---- - src/pkg/podman/podman.go | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/pkg/podman/podman.go b/src/pkg/podman/podman.go -index 9099df1eaf2a..8e7d5068fb97 100644 ---- a/src/pkg/podman/podman.go -+++ b/src/pkg/podman/podman.go -@@ -228,10 +228,13 @@ func IsToolboxImage(image string) (bool, error) { - - // Pull pulls an image - func Pull(imageName string) error { -+ var stderr bytes.Buffer -+ - logLevelString := LogLevel.String() - args := []string{"--log-level", logLevelString, "pull", imageName} - -- if err := shell.Run("podman", nil, nil, nil, args...); err != nil { -+ if err := shell.Run("podman", nil, nil, &stderr, args...); err != nil { -+ err := parseErrorMsg(&stderr) - return err - } - --- -2.31.1 - - -From 4b8b007201cd019909829d73afdcf919753943a3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ond=C5=99ej=20M=C3=ADchal?= -Date: Sun, 4 Jul 2021 18:16:12 +0200 -Subject: [PATCH 4/7] pkg/podman: Add error for 'podman pull' failing due to no - authorization - -https://github.com/containers/toolbox/pull/787 ---- - src/pkg/podman/podman.go | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/pkg/podman/podman.go b/src/pkg/podman/podman.go -index 8e7d5068fb97..521538c9abfb 100644 ---- a/src/pkg/podman/podman.go -+++ b/src/pkg/podman/podman.go -@@ -19,6 +19,7 @@ package podman - import ( - "bytes" - "encoding/json" -+ "errors" - "fmt" - "io" - -@@ -32,7 +33,8 @@ var ( - ) - - var ( -- LogLevel = logrus.ErrorLevel -+ ErrUnauthorized = errors.New("unauthorized") -+ LogLevel = logrus.ErrorLevel - ) - - // CheckVersion compares provided version with the version of Podman. --- -2.31.1 - - -From ef3bebac89cd833a663dc63fffba8b04ca944dde Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ond=C5=99ej=20M=C3=ADchal?= -Date: Sat, 3 Jul 2021 02:25:49 +0200 -Subject: [PATCH 5/7] pkg/podman: Wrap 'podman login' - -https://github.com/containers/toolbox/pull/787 ---- - src/pkg/podman/podman.go | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/src/pkg/podman/podman.go b/src/pkg/podman/podman.go -index 521538c9abfb..8538bd7c617a 100644 ---- a/src/pkg/podman/podman.go -+++ b/src/pkg/podman/podman.go -@@ -228,6 +228,18 @@ func IsToolboxImage(image string) (bool, error) { - return true, nil - } - -+func Login(registry, username, password string) error { -+ logLevelString := LogLevel.String() -+ args := []string{"--log-level", logLevelString, "login", registry, "--password-stdin", "--username", username} -+ stdin := bytes.NewBufferString(password) -+ -+ if err := shell.Run("podman", stdin, nil, nil, args...); err != nil { -+ return err -+ } -+ -+ return nil -+} -+ - // Pull pulls an image - func Pull(imageName string) error { - var stderr bytes.Buffer --- -2.31.1 - - -From 49cd3c48c26d37c85aba5dbdcf04a995593ae673 Mon Sep 17 00:00:00 2001 -From: Debarshi Ray -Date: Sun, 4 Jul 2021 18:11:04 +0200 -Subject: [PATCH 6/7] cmd/create: Split out the spinner around 'podman pull' - -A subsequent commit will use this when retrying the 'podman pull' -after logging the user into the registry for images that require -authorization. - -https://github.com/containers/toolbox/pull/787 ---- - src/cmd/create.go | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/src/cmd/create.go b/src/cmd/create.go -index e3245b4c5ae3..6a3005f06041 100644 ---- a/src/cmd/create.go -+++ b/src/cmd/create.go -@@ -731,6 +731,14 @@ func pullImage(image, release string) (bool, error) { - return false, nil - } - -+ if _, err := pullImageWithSpinner(imageFull); err != nil { -+ return false, fmt.Errorf("failed to pull image %s", imageFull) -+ } -+ -+ return true, nil -+} -+ -+func pullImageWithSpinner(imageFull string) (bool, error) { - logrus.Debugf("Pulling image %s", imageFull) - - stdoutFd := os.Stdout.Fd() -@@ -744,7 +752,7 @@ func pullImage(image, release string) (bool, error) { - } - - if err := podman.Pull(imageFull); err != nil { -- return false, fmt.Errorf("failed to pull image %s", imageFull) -+ return false, err - } - - return true, nil --- -2.31.1 - - -From 19bb0f08118536c32ff2d2f571d92758dff00dcb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ond=C5=99ej=20M=C3=ADchal?= -Date: Sun, 4 Jul 2021 18:11:28 +0200 -Subject: [PATCH 7/7] cmd/create: Support logging into a registry if necessary - -Some registries contain private repositories of images and require the -user to log in first to gain access. With this Toolbox tries to -recognize errors when pulling images and offers the user the means to -log in. - -Some changes by Debarshi Ray. - -https://github.com/containers/toolbox/pull/787 ---- - src/cmd/create.go | 72 ++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 71 insertions(+), 1 deletion(-) - -diff --git a/src/cmd/create.go b/src/cmd/create.go -index 6a3005f06041..7cf03e8a4cd2 100644 ---- a/src/cmd/create.go -+++ b/src/cmd/create.go -@@ -17,6 +17,7 @@ - package cmd - - import ( -+ "bufio" - "errors" - "fmt" - "os" -@@ -668,6 +669,65 @@ func isPathReadWrite(path string) (bool, error) { - return false, nil - } - -+func logIntoRegistry(imageFull, registry string) (bool, error) { -+ fmt.Printf("Image %s requires log-in.\n", imageFull) -+ -+ scanner := bufio.NewScanner(os.Stdin) -+ -+ stdinFd := os.Stdin.Fd() -+ stdinFdInt := int(stdinFd) -+ -+ if terminal.IsTerminal(stdinFdInt) { -+ fmt.Printf("Username: ") -+ } -+ -+ if !scanner.Scan() { -+ if err := scanner.Err(); err != nil { -+ logrus.Debugf("Logging into registry: failed to read username: %s", err) -+ } -+ -+ return false, errors.New("failed to read username") -+ } -+ -+ username := scanner.Text() -+ -+ var password string -+ -+ if terminal.IsTerminal(stdinFdInt) { -+ logrus.Debug("Reading password from a terminal input") -+ -+ fmt.Printf("Password: ") -+ -+ passwordBytes, err := terminal.ReadPassword(stdinFdInt) -+ if err != nil { -+ logrus.Debugf("Logging into registry: failed to read password: %s", err) -+ return false, errors.New("failed to read password") -+ } -+ -+ password = string(passwordBytes) -+ fmt.Println("") -+ } else { -+ logrus.Debug("Reading password from a non-terminal input") -+ -+ if !scanner.Scan() { -+ if err := scanner.Err(); err != nil { -+ logrus.Debugf("Logging into registry: failed to read password: %s", err) -+ } -+ -+ return false, errors.New("failed to read password") -+ } -+ -+ password = scanner.Text() -+ } -+ -+ if err := podman.Login(registry, username, password); err != nil { -+ logrus.Debugf("Logging into registry %s failed: %s", registry, err) -+ return false, fmt.Errorf("failed to log into registry %s", registry) -+ } -+ -+ return true, nil -+} -+ - func pullImage(image, release string) (bool, error) { - if _, err := utils.ImageReferenceCanBeID(image); err == nil { - logrus.Debugf("Looking for image %s", image) -@@ -732,7 +792,17 @@ func pullImage(image, release string) (bool, error) { - } - - if _, err := pullImageWithSpinner(imageFull); err != nil { -- return false, fmt.Errorf("failed to pull image %s", imageFull) -+ if !errors.Is(err, podman.ErrUnauthorized) { -+ return false, fmt.Errorf("failed to pull image %s", imageFull) -+ } -+ -+ if _, err := logIntoRegistry(imageFull, domain); err != nil { -+ return false, err -+ } -+ -+ if _, err := pullImageWithSpinner(imageFull); err != nil { -+ return false, fmt.Errorf("failed to pull image %s", imageFull) -+ } - } - - return true, nil --- -2.31.1 - diff --git a/toolbox-cmd-create-Expose-the-host-s-entire-in-the-container.patch b/toolbox-cmd-create-Expose-the-host-s-entire-in-the-container.patch deleted file mode 100644 index 3b18c30..0000000 --- a/toolbox-cmd-create-Expose-the-host-s-entire-in-the-container.patch +++ /dev/null @@ -1,76 +0,0 @@ -From d03a5fee80f2f72da6a409f7ebc3b6caf21506e3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ond=C5=99ej=20M=C3=ADchal?= -Date: Sat, 3 Jul 2021 20:39:49 +0200 -Subject: [PATCH] cmd/create: Expose the host's entire / in the container at - /run/host - -Having the entire host file system hierarchy mounted inside a toolbox -container gives the containers a more complete environment that's -resilient against future changes in the layout of the file system -hierarchy and the need for giving access to new paths to support new -use-cases. Otherwise, one would have to create a new container to get -access to any path that lies outside the /boot, /etc, /run, /tmp, /usr -and /var directories. - -As a nice side-effect, this also simplifies the bind mount handling -code. - -https://github.com/containers/toolbox/pull/827 ---- - src/cmd/create.go | 29 +---------------------------- - 1 file changed, 1 insertion(+), 28 deletions(-) - -diff --git a/src/cmd/create.go b/src/cmd/create.go -index ff533c26db98..297b336f6382 100644 ---- a/src/cmd/create.go -+++ b/src/cmd/create.go -@@ -265,28 +265,6 @@ func createContainer(container, image, release string, showCommandToEnter bool) - logrus.Debugf("%s canonicalized to %s", currentUser.HomeDir, homeDirEvaled) - homeDirMountArg := homeDirEvaled + ":" + homeDirEvaled + ":rslave" - -- bootMountFlags := "ro" -- isBootReadWrite, err := isPathReadWrite("/boot") -- if err != nil { -- return err -- } -- if isBootReadWrite { -- bootMountFlags = "rw" -- } -- -- bootMountArg := "/boot:/run/host/boot:" + bootMountFlags + ",rslave" -- -- usrMountFlags := "ro" -- isUsrReadWrite, err := isPathReadWrite("/usr") -- if err != nil { -- return err -- } -- if isUsrReadWrite { -- usrMountFlags = "rw" -- } -- -- usrMountArg := "/usr:/run/host/usr:" + usrMountFlags + ",rslave" -- - var avahiSocketMount []string - - avahiSocket, err := getServiceSocket("Avahi", "avahi-daemon.socket") -@@ -423,16 +401,11 @@ func createContainer(container, image, release string, showCommandToEnter bool) - createArgs = append(createArgs, []string{ - "--userns", usernsArg, - "--user", "root:root", -- "--volume", "/etc:/run/host/etc", -+ "--volume", "/:/run/host:rslave", - "--volume", "/dev:/dev:rslave", -- "--volume", "/run:/run/host/run:rslave", -- "--volume", "/tmp:/run/host/tmp:rslave", -- "--volume", "/var:/run/host/var:rslave", -- "--volume", bootMountArg, - "--volume", dbusSystemSocketMountArg, - "--volume", homeDirMountArg, - "--volume", toolboxPathMountArg, -- "--volume", usrMountArg, - "--volume", runtimeDirectoryMountArg, - }...) - --- -2.31.1 - diff --git a/toolbox-cmd-root-Make-toolbox-create-or-fall-back-to-a-conta.patch b/toolbox-cmd-root-Make-toolbox-create-or-fall-back-to-a-conta.patch deleted file mode 100644 index 412db46..0000000 --- a/toolbox-cmd-root-Make-toolbox-create-or-fall-back-to-a-conta.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 6c86cabbe5da6e542b50c5c043b4d213c6279bbc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ond=C5=99ej=20M=C3=ADchal?= -Date: Fri, 25 Jun 2021 16:04:52 +0200 -Subject: [PATCH] cmd/root: Make 'toolbox' create or fall back to a container - if possible - -This makes 'toolbox', without any commands specified, behave a lot like -'toolbox enter'. When there aren't any toolbox containers, it will -offer to create a new container matching the same parameters passed to -the command. If there's just one toolbox container available, then it -will fall back to it. - -This makes the command line interface a lot similar to that of -github.com/coreos/toolbox, which makes things easier for those -switching over from it. - -Some changes by Debarshi Ray. - -https://github.com/containers/toolbox/pull/811 ---- - src/cmd/root.go | 65 +++++++++++++++++++++++++++++++++------ - test/system/002-help.bats | 8 ----- - 2 files changed, 55 insertions(+), 18 deletions(-) - -diff --git a/src/cmd/root.go b/src/cmd/root.go -index d50135b9e963..7c4aef61eee8 100644 ---- a/src/cmd/root.go -+++ b/src/cmd/root.go -@@ -177,17 +177,62 @@ func rootHelp(cmd *cobra.Command, args []string) { - } - - func rootRun(cmd *cobra.Command, args []string) error { -- var builder strings.Builder -- fmt.Fprintf(&builder, "missing command\n") -- fmt.Fprintf(&builder, "\n") -- fmt.Fprintf(&builder, "create Create a new toolbox container\n") -- fmt.Fprintf(&builder, "enter Enter an existing toolbox container\n") -- fmt.Fprintf(&builder, "list List all existing toolbox containers and images\n") -- fmt.Fprintf(&builder, "\n") -- fmt.Fprintf(&builder, "Run '%s --help' for usage.", executableBase) -+ if len(args) != 0 { -+ panic("unexpected argument: commands known or unknown shouldn't reach here") -+ } - -- errMsg := builder.String() -- return errors.New(errMsg) -+ if utils.IsInsideContainer() { -+ if !utils.IsInsideToolboxContainer() { -+ return errors.New("this is not a toolbox container") -+ } -+ -+ if _, err := utils.ForwardToHost(); err != nil { -+ return err -+ } -+ -+ return nil -+ } -+ -+ container, image, release, err := utils.ResolveContainerAndImageNames("", "", "", "") -+ if err != nil { -+ return err -+ } -+ -+ userShell := os.Getenv("SHELL") -+ if userShell == "" { -+ return errors.New("failed to get the current user's default shell") -+ } -+ -+ command := []string{userShell, "-l"} -+ -+ hostID, err := utils.GetHostID() -+ if err != nil { -+ return fmt.Errorf("failed to get the host ID: %w", err) -+ } -+ -+ hostVariantID, err := utils.GetHostVariantID() -+ if err != nil { -+ return errors.New("failed to get the host VARIANT_ID") -+ } -+ -+ var emitEscapeSequence bool -+ -+ if hostID == "fedora" && (hostVariantID == "silverblue" || hostVariantID == "workstation") { -+ emitEscapeSequence = true -+ } -+ -+ if err := runCommand(container, -+ true, -+ image, -+ release, -+ command, -+ emitEscapeSequence, -+ true, -+ false); err != nil { -+ return err -+ } -+ -+ return nil - } - - func rootUsage(cmd *cobra.Command) error { -diff --git a/test/system/002-help.bats b/test/system/002-help.bats -index 8a057ddb3818..4ff02c6215e7 100644 ---- a/test/system/002-help.bats -+++ b/test/system/002-help.bats -@@ -4,14 +4,6 @@ load 'libs/bats-support/load' - load 'libs/bats-assert/load' - load 'libs/helpers.bash' - --@test "help: Try to run toolbox with no command (shows usage screen)" { -- run $TOOLBOX -- -- assert_failure -- assert_line --index 0 "Error: missing command" -- assert_output --partial "Run 'toolbox --help' for usage." --} -- - @test "help: Run command 'help'" { - run $TOOLBOX help - --- -2.31.1 - diff --git a/toolbox.spec b/toolbox.spec index 64a0e6c..7a954cf 100644 --- a/toolbox.spec +++ b/toolbox.spec @@ -4,12 +4,12 @@ %global _find_debuginfo_dwz_opts %{nil} Name: toolbox -Version: 0.0.99.2 +Version: 0.0.99.2^1.git660b6970e998 %global goipath github.com/containers/%{name} %gometa -Release: 3%{?dist} +Release: 1%{?dist} Summary: Unprivileged development environment License: ASL 2.0 @@ -21,15 +21,9 @@ URL: https://github.com/containers/%{name} # $ go mod vendor Source0: %{name}-%{version}-vendored.tar.xz -# Upstream -Patch0: toolbox-cmd-root-Make-toolbox-create-or-fall-back-to-a-conta.patch -Patch1: toolbox-cmd-create-Expose-the-host-s-entire-in-the-container.patch - # RHEL specific Patch100: toolbox-Make-the-build-flags-match-RHEL-s-gobuild.patch Patch101: toolbox-Make-the-build-flags-match-RHEL-s-gobuild-for-PPC64.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1940054 -Patch102: toolbox-Support-logging-into-a-registry-if-necessary.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1905383 ExcludeArch: %{ix86} @@ -61,17 +55,12 @@ The %{name}-tests package contains system tests for %{name}. %prep %setup -q -%patch0 -p1 -%patch1 -p1 - %ifnarch ppc64 %patch100 -p1 %else %patch101 -p1 %endif -%patch102 -p1 - # %%gomkdir is absent from RHEL 8. GOBUILDDIR="$(pwd)/_build" GOSOURCEDIR="$(pwd)" @@ -108,6 +97,7 @@ ln -s src/vendor vendor %{_datadir}/bash-completion %{_mandir}/man1/%{name}.1* %{_mandir}/man1/%{name}-*.1* +%config(noreplace) %{_sysconfdir}/containers/%{name}.conf %{_sysconfdir}/profile.d/%{name}.sh %{_tmpfilesdir}/%{name}.conf @@ -116,6 +106,10 @@ ln -s src/vendor vendor %changelog +* Wed Jul 28 2021 Jindrich Novy - 0.0.99.2^1.git660b6970e998-1 +- Add support for configuration files +- Related: #1970747 + * Sat Jul 10 2021 Jindrich Novy - 0.0.99.2-3 - Expose the host's entire / in the container at /run/host - Resolves: #1977343