toolbox-0.0.99.2^1.git660b6970e998-1.el9
- Add support for configuration files - Related: #1970747 Signed-off-by: Jindrich Novy <jnovy@redhat.com>
This commit is contained in:
parent
b817729eef
commit
7ebedec3a3
2
sources
2
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
|
||||||
|
@ -1,667 +0,0 @@
|
|||||||
From 62a022428231df50637495673354d4fdd2541c1a Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Ond=C5=99ej=20M=C3=ADchal?= <harrymichal@seznam.cz>
|
|
||||||
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?= <harrymichal@seznam.cz>
|
|
||||||
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?= <harrymichal@seznam.cz>
|
|
||||||
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?= <harrymichal@seznam.cz>
|
|
||||||
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?= <harrymichal@seznam.cz>
|
|
||||||
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 <rishi@fedoraproject.org>
|
|
||||||
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?= <harrymichal@seznam.cz>
|
|
||||||
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
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
|||||||
From d03a5fee80f2f72da6a409f7ebc3b6caf21506e3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Ond=C5=99ej=20M=C3=ADchal?= <harrymichal@seznam.cz>
|
|
||||||
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
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
|||||||
From 6c86cabbe5da6e542b50c5c043b4d213c6279bbc Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Ond=C5=99ej=20M=C3=ADchal?= <harrymichal@seznam.cz>
|
|
||||||
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
|
|
||||||
|
|
20
toolbox.spec
20
toolbox.spec
@ -4,12 +4,12 @@
|
|||||||
%global _find_debuginfo_dwz_opts %{nil}
|
%global _find_debuginfo_dwz_opts %{nil}
|
||||||
|
|
||||||
Name: toolbox
|
Name: toolbox
|
||||||
Version: 0.0.99.2
|
Version: 0.0.99.2^1.git660b6970e998
|
||||||
|
|
||||||
%global goipath github.com/containers/%{name}
|
%global goipath github.com/containers/%{name}
|
||||||
%gometa
|
%gometa
|
||||||
|
|
||||||
Release: 3%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: Unprivileged development environment
|
Summary: Unprivileged development environment
|
||||||
|
|
||||||
License: ASL 2.0
|
License: ASL 2.0
|
||||||
@ -21,15 +21,9 @@ URL: https://github.com/containers/%{name}
|
|||||||
# $ go mod vendor
|
# $ go mod vendor
|
||||||
Source0: %{name}-%{version}-vendored.tar.xz
|
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
|
# RHEL specific
|
||||||
Patch100: toolbox-Make-the-build-flags-match-RHEL-s-gobuild.patch
|
Patch100: toolbox-Make-the-build-flags-match-RHEL-s-gobuild.patch
|
||||||
Patch101: toolbox-Make-the-build-flags-match-RHEL-s-gobuild-for-PPC64.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
|
# https://bugzilla.redhat.com/show_bug.cgi?id=1905383
|
||||||
ExcludeArch: %{ix86}
|
ExcludeArch: %{ix86}
|
||||||
@ -61,17 +55,12 @@ The %{name}-tests package contains system tests for %{name}.
|
|||||||
%prep
|
%prep
|
||||||
%setup -q
|
%setup -q
|
||||||
|
|
||||||
%patch0 -p1
|
|
||||||
%patch1 -p1
|
|
||||||
|
|
||||||
%ifnarch ppc64
|
%ifnarch ppc64
|
||||||
%patch100 -p1
|
%patch100 -p1
|
||||||
%else
|
%else
|
||||||
%patch101 -p1
|
%patch101 -p1
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%patch102 -p1
|
|
||||||
|
|
||||||
# %%gomkdir is absent from RHEL 8.
|
# %%gomkdir is absent from RHEL 8.
|
||||||
GOBUILDDIR="$(pwd)/_build"
|
GOBUILDDIR="$(pwd)/_build"
|
||||||
GOSOURCEDIR="$(pwd)"
|
GOSOURCEDIR="$(pwd)"
|
||||||
@ -108,6 +97,7 @@ ln -s src/vendor vendor
|
|||||||
%{_datadir}/bash-completion
|
%{_datadir}/bash-completion
|
||||||
%{_mandir}/man1/%{name}.1*
|
%{_mandir}/man1/%{name}.1*
|
||||||
%{_mandir}/man1/%{name}-*.1*
|
%{_mandir}/man1/%{name}-*.1*
|
||||||
|
%config(noreplace) %{_sysconfdir}/containers/%{name}.conf
|
||||||
%{_sysconfdir}/profile.d/%{name}.sh
|
%{_sysconfdir}/profile.d/%{name}.sh
|
||||||
%{_tmpfilesdir}/%{name}.conf
|
%{_tmpfilesdir}/%{name}.conf
|
||||||
|
|
||||||
@ -116,6 +106,10 @@ ln -s src/vendor vendor
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Jul 28 2021 Jindrich Novy <jnovy@redhat.com> - 0.0.99.2^1.git660b6970e998-1
|
||||||
|
- Add support for configuration files
|
||||||
|
- Related: #1970747
|
||||||
|
|
||||||
* Sat Jul 10 2021 Jindrich Novy <jnovy@redhat.com> - 0.0.99.2-3
|
* Sat Jul 10 2021 Jindrich Novy <jnovy@redhat.com> - 0.0.99.2-3
|
||||||
- Expose the host's entire / in the container at /run/host
|
- Expose the host's entire / in the container at /run/host
|
||||||
- Resolves: #1977343
|
- Resolves: #1977343
|
||||||
|
Loading…
Reference in New Issue
Block a user