fix: more friendly error output when running rootless mode (#2287)

* fix: more friendly error output when running rootless mode without required uidmap/fuse-overlayfs

Signed-off-by: fengxsong <fengxsong@outlook.com>

* fix: add cert to unrelated command names

Signed-off-by: fengxsong <fengxsong@outlook.com>

* fix: string slice is just fine

Signed-off-by: fengxsong <fengxsong@outlook.com>

Signed-off-by: fengxsong <fengxsong@outlook.com>
This commit is contained in:
fengxsong
2022-12-23 13:04:37 +08:00
committed by GitHub
parent 1dee9233c3
commit 3581779e8f
21 changed files with 75 additions and 59 deletions
+3
View File
@@ -18,6 +18,7 @@ import (
"fmt"
"os"
"github.com/labring/sealos/pkg/buildah"
"github.com/labring/sealos/pkg/constants"
"github.com/labring/sealos/pkg/utils/file"
"github.com/labring/sealos/pkg/utils/logger"
@@ -57,6 +58,8 @@ func init() {
_ = fs.MarkHidden("cluster-root")
fs.StringVar(&runtimeRootDir, "sealos-root", constants.DefaultRuntimeRootDir, "root directory for sealos actions")
_ = fs.MarkHidden("sealos-root")
// add unrelated command names that don't required buildah sdk.
buildah.AddUnrelatedCommandNames("cert", "docs", "exec", "gen", "scp", "version")
}
func onBootOnDie() {
+1 -1
View File
@@ -62,7 +62,7 @@ func newBuildCommand() *cobra.Command {
Args: cobra.MaximumNArgs(1),
Example: fmt.Sprintf(`%[1]s build
%[1]s bud -f Kubefile.simple .
%[1]s bud -f Kubefile.simple -f Kubefile.notsosimple .`, rootCmdName),
%[1]s bud -f Kubefile.simple -f Kubefile.notsosimple .`, rootCmd.CommandPath()),
}
buildCommand.SetUsageTemplate(UsageTemplate())
+26 -30
View File
@@ -107,7 +107,7 @@ func RegisterGlobalFlags(fs *pflag.FlagSet) error {
var (
globalFlagResults globalFlags
rootCmd *cobra.Command
rootCmdName string
unrelatedCommands = []string{"version"}
postRunHooks []func() error
)
@@ -147,7 +147,6 @@ func subCommands() []*cobra.Command {
func RegisterRootCommand(cmd *cobra.Command) {
os.Setenv("TMPDIR", parse.GetTempDir())
rootCmd = cmd
rootCmdName = getFullCmdName(rootCmd) // incase it's registered to a sub command.
cmd.SilenceUsage = true
err := RegisterGlobalFlags(cmd.PersistentFlags())
bailOnError(err, "failed to register global flags")
@@ -156,15 +155,6 @@ func RegisterRootCommand(cmd *cobra.Command) {
cmd.AddCommand(subCommands()...)
}
func getFullCmdName(cmd *cobra.Command) string {
name := cmd.Name()
for cmd.Parent() != nil {
name = fmt.Sprintf("%s %s", cmd.Parent().Name(), name)
cmd = cmd.Parent()
}
return name
}
func RegisterPostRun(fn func() error) {
if rootCmd == nil {
logger.Fatal("Must not register post run function before RegisterRootCommand")
@@ -172,33 +162,45 @@ func RegisterPostRun(fn func() error) {
postRunHooks = append(postRunHooks, fn)
}
func wrapPrePersistentRun(cmd *cobra.Command) {
switch cmd.Use {
case "", "version":
return
func AddUnrelatedCommandNames(names ...string) {
unrelatedCommands = append(unrelatedCommands, names...)
}
func skipUnrelatedCommandRun(cmd *cobra.Command) bool {
for _, name := range unrelatedCommands {
if name == cmd.Name() {
return true
}
}
return false
}
func wrapPrePersistentRun(cmd *cobra.Command) {
switch {
case cmd.PersistentPreRun != nil:
run := cmd.PersistentPreRun
cmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
if err := TrySetupWithDefaults(defaultSetters...); err != nil {
logger.Fatal(err)
if skipUnrelatedCommandRun(cmd) {
return
}
bailOnError(TrySetupWithDefaults(defaultSetters...), "unable to setup")
run(cmd, args)
}
case cmd.PersistentPreRunE != nil:
runE := cmd.PersistentPreRunE
cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
if err := TrySetupWithDefaults(defaultSetters...); err != nil {
return err
if skipUnrelatedCommandRun(cmd) {
return nil
}
bailOnError(TrySetupWithDefaults(defaultSetters...), "unable to setup")
return runE(cmd, args)
}
default:
cmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
if err := TrySetupWithDefaults(defaultSetters...); err != nil {
logger.Fatal(err)
if skipUnrelatedCommandRun(cmd) {
return
}
bailOnError(TrySetupWithDefaults(defaultSetters...), "unable to setup")
}
}
}
@@ -209,24 +211,18 @@ func wrapPostPersistentRun(cmd *cobra.Command) {
case cmd.PersistentPostRun != nil:
run := cmd.PersistentPostRun
cmd.PersistentPostRun = func(cmd *cobra.Command, args []string) {
if err := after(cmd); err != nil {
logger.Fatal(err)
}
bailOnError(after(cmd), "")
run(cmd, args)
}
case cmd.PersistentPostRunE != nil:
runE := cmd.PersistentPostRunE
cmd.PersistentPostRunE = func(cmd *cobra.Command, args []string) error {
if err := after(cmd); err != nil {
return err
}
bailOnError(after(cmd), "")
return runE(cmd, args)
}
default:
cmd.PersistentPostRun = func(cmd *cobra.Command, args []string) {
if err := after(cmd); err != nil {
logger.Fatal(err)
}
bailOnError(after(cmd), "")
}
}
}
+2 -2
View File
@@ -110,7 +110,7 @@ func newContainersCommand() *cobra.Command {
},
Example: fmt.Sprintf(`%[1]s containers
%[1]s containers --format "{{.ContainerID}} {{.ContainerName}}"
%[1]s containers -q --noheading --notruncate`, rootCmdName),
%[1]s containers -q --noheading --notruncate`, rootCmd.CommandPath()),
}
containersCommand.SetUsageTemplate(UsageTemplate())
@@ -120,7 +120,7 @@ func newContainersCommand() *cobra.Command {
func containersCmd(c *cobra.Command, args []string, iopts *containersResults) error {
if len(args) > 0 {
return fmt.Errorf("'%s containers' does not accept arguments", rootCmdName)
return fmt.Errorf("'%s' does not accept arguments", c.CommandPath())
}
store, err := getStore(c)
if err != nil {
+1 -1
View File
@@ -128,7 +128,7 @@ func newFromCommand() *cobra.Command {
},
Example: fmt.Sprintf(`%[1]s from --pull imagename
%[1]s from docker-daemon:imagename:imagetag
%[1]s from --name "myimagename" myregistry/myrepository/imagename:imagetag`, rootCmdName),
%[1]s from --name "myimagename" myregistry/myrepository/imagename:imagetag`, rootCmd.CommandPath()),
}
fromCommand.SetUsageTemplate(UsageTemplate())
opts.RegisterFlags(fromCommand.Flags())
+2 -2
View File
@@ -122,7 +122,7 @@ func newImagesCommand() *cobra.Command {
},
Example: fmt.Sprintf(`%[1]s images --all
%[1]s images [imageName]
%[1]s images --format '{{.ID}} {{.Name}} {{.Size}} {{.CreatedAtRaw}}'`, rootCmdName),
%[1]s images --format '{{.ID}} {{.Name}} {{.Size}} {{.CreatedAtRaw}}'`, rootCmd.CommandPath()),
}
imagesCommand.SetUsageTemplate(UsageTemplate())
@@ -140,7 +140,7 @@ func imagesCmd(c *cobra.Command, args []string, iopts *imageResults) error {
return err
}
if len(args) > 1 {
return fmt.Errorf("'%s images' requires at most 1 argument", rootCmdName)
return fmt.Errorf("'%s' requires at most 1 argument", c.CommandPath())
}
}
if iopts.quiet && iopts.format != "" {
+1 -1
View File
@@ -70,7 +70,7 @@ func newInspectCommand() *cobra.Command {
},
Example: fmt.Sprintf(`%[1]s inspect containerID
%[1]s inspect --type image imageID
%[1]s inspect --format '{{.OCIv1.Config.Env}}' alpine`, rootCmdName),
%[1]s inspect --format '{{.OCIv1.Config.Env}}' alpine`, rootCmd.CommandPath()),
}
inspectCommand.SetUsageTemplate(UsageTemplate())
opts.RegisterFlags(inspectCommand.Flags())
+1 -1
View File
@@ -34,7 +34,7 @@ func newLoadCommand() *cobra.Command {
RunE: func(cmd *cobra.Command, _ []string) error {
return pullCmd(cmd, []string{fmt.Sprintf("%s:%s", DockerArchive, archiveName)}, opts)
},
Example: fmt.Sprintf(`%[1]s load -i kubernetes.tar`, rootCmdName),
Example: fmt.Sprintf(`%[1]s load -i kubernetes.tar`, rootCmd.CommandPath()),
}
loadCommand.SetUsageTemplate(UsageTemplate())
fs := loadCommand.Flags()
+1 -1
View File
@@ -109,7 +109,7 @@ func newLoginCommand() *cobra.Command {
}
return nil
},
Example: fmt.Sprintf(`%s login quay.io`, rootCmdName),
Example: fmt.Sprintf(`%s login quay.io`, rootCmd.CommandPath()),
}
loginCommand.SetUsageTemplate(UsageTemplate())
opts.RegisterFlags(loginCommand.Flags())
+1 -1
View File
@@ -39,7 +39,7 @@ func newLogoutCommand() *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
return logoutCmd(cmd, args, &opts)
},
Example: fmt.Sprintf(`%s logout quay.io`, rootCmdName),
Example: fmt.Sprintf(`%s logout quay.io`, rootCmd.CommandPath()),
}
logoutCommand.SetUsageTemplate(UsageTemplate())
+9 -9
View File
@@ -134,7 +134,7 @@ func newManifestCommand() *cobra.Command {
%[1]s manifest inspect localhost/list
%[1]s manifest push localhost/list transport:destination
%[1]s manifest remove localhost/list sha256:entryManifestDigest
%[1]s manifest rm localhost/list`, rootCmdName),
%[1]s manifest rm localhost/list`, rootCmd.CommandPath()),
}
manifestCommand.SetUsageTemplate(UsageTemplate())
@@ -147,7 +147,7 @@ func newManifestCommand() *cobra.Command {
},
Example: fmt.Sprintf(`%[1]s manifest create mylist:v1.11
%[1]s manifest create mylist:v1.11 arch-specific-image-to-add
%[1]s manifest create --all mylist:v1.11 transport:tagged-image-to-add`, rootCmdName),
%[1]s manifest create --all mylist:v1.11 transport:tagged-image-to-add`, rootCmd.CommandPath()),
Args: cobra.MinimumNArgs(1),
}
manifestCreateCommand.SetUsageTemplate(UsageTemplate())
@@ -163,7 +163,7 @@ func newManifestCommand() *cobra.Command {
return manifestAddCmd(cmd, args, manifestAddOpts)
},
Example: fmt.Sprintf(`%[1]s manifest add mylist:v1.11 image:v1.11-amd64
%[1]s manifest add mylist:v1.11 transport:imageName`, rootCmdName),
%[1]s manifest add mylist:v1.11 transport:imageName`, rootCmd.CommandPath()),
Args: cobra.MinimumNArgs(2),
}
manifestAddCommand.SetUsageTemplate(UsageTemplate())
@@ -178,7 +178,7 @@ func newManifestCommand() *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
return manifestRemoveCmd(cmd, args, manifestRemoveOpts)
},
Example: fmt.Sprintf(`%s manifest remove mylist:v1.11 sha256:15352d97781ffdf357bf3459c037be3efac4133dc9070c2dce7eca7c05c3e736`, rootCmdName),
Example: fmt.Sprintf(`%s manifest remove mylist:v1.11 sha256:15352d97781ffdf357bf3459c037be3efac4133dc9070c2dce7eca7c05c3e736`, rootCmd.CommandPath()),
Args: cobra.MinimumNArgs(2),
}
manifestRemoveCommand.SetUsageTemplate(UsageTemplate())
@@ -192,7 +192,7 @@ func newManifestCommand() *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
return manifestExistsCmd(cmd, args)
},
Example: fmt.Sprintf(`%s manifest exists mylist`, rootCmdName),
Example: fmt.Sprintf(`%s manifest exists mylist`, rootCmd.CommandPath()),
}
manifestExistsCommand.SetUsageTemplate(UsageTemplate())
manifestCommand.AddCommand(manifestExistsCommand)
@@ -204,7 +204,7 @@ func newManifestCommand() *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
return manifestAnnotateCmd(cmd, args, manifestAnnotateOpts)
},
Example: fmt.Sprintf(`%s manifest annotate --annotation left=right mylist:v1.11 image:v1.11-amd64`, rootCmdName),
Example: fmt.Sprintf(`%s manifest annotate --annotation left=right mylist:v1.11 image:v1.11-amd64`, rootCmd.CommandPath()),
Args: cobra.MinimumNArgs(2),
}
manifestAnnotateCommand.SetUsageTemplate(UsageTemplate())
@@ -219,7 +219,7 @@ func newManifestCommand() *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
return manifestInspectCmd(cmd, args, manifestInspectOpts)
},
Example: fmt.Sprintf(`%s manifest inspect mylist:v1.11`, rootCmdName),
Example: fmt.Sprintf(`%s manifest inspect mylist:v1.11`, rootCmd.CommandPath()),
Args: cobra.MinimumNArgs(1),
}
manifestInspectCommand.SetUsageTemplate(UsageTemplate())
@@ -232,7 +232,7 @@ func newManifestCommand() *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
return manifestPushCmd(cmd, args, manifestPushOpts)
},
Example: fmt.Sprintf(`%s manifest push mylist:v1.11 transport:imageName`, rootCmdName),
Example: fmt.Sprintf(`%s manifest push mylist:v1.11 transport:imageName`, rootCmd.CommandPath()),
Args: cobra.MinimumNArgs(2),
}
manifestPushCommand.SetUsageTemplate(UsageTemplate())
@@ -261,7 +261,7 @@ func newManifestCommand() *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
return manifestRmCmd(cmd, args)
},
Example: fmt.Sprintf(`%s manifest rm mylist:v1.11`, rootCmdName),
Example: fmt.Sprintf(`%s manifest rm mylist:v1.11`, rootCmd.CommandPath()),
Args: cobra.MinimumNArgs(1),
}
manifestRmCommand.SetUsageTemplate(UsageTemplate())
+2 -2
View File
@@ -37,7 +37,7 @@ func newMountCommand() *cobra.Command {
var (
mountDescription = fmt.Sprintf(`%[1]s mount
mounts a working container's root filesystem for manipulation.
`, rootCmdName)
`, rootCmd.CommandPath())
opts mountOptions
noTruncate bool
)
@@ -52,7 +52,7 @@ func newMountCommand() *cobra.Command {
Example: fmt.Sprintf(`%[1]s mount
%[1]s mount containerID
%[1]s mount containerID1 containerID2
`, rootCmdName),
`, rootCmd.CommandPath()),
}
mountCommand.SetUsageTemplate(UsageTemplate())
+1 -1
View File
@@ -112,7 +112,7 @@ func newPullCommand() *cobra.Command {
},
Example: fmt.Sprintf(`%[1]s pull imagename
%[1]s pull docker-daemon:imagename:imagetag
%[1]s pull myregistry/myrepository/imagename:imagetag`, rootCmdName),
%[1]s pull myregistry/myrepository/imagename:imagetag`, rootCmd.CommandPath()),
}
pullCommand.SetUsageTemplate(UsageTemplate())
+1 -1
View File
@@ -119,7 +119,7 @@ func newPushCommand() *cobra.Command {
},
Example: fmt.Sprintf(`%[1]s push imageID docker://registry.example.com/repository:tag
%[1]s push imageID docker-daemon:image:tagi
%[1]s push imageID oci:/path/to/layout:image:tag`, rootCmdName),
%[1]s push imageID oci:/path/to/layout:image:tag`, rootCmd.CommandPath()),
}
pushCommand.SetUsageTemplate(UsageTemplate())
err := opts.RegisterFlags(pushCommand.Flags())
+1 -1
View File
@@ -43,7 +43,7 @@ func newRMCommand() *cobra.Command {
},
Example: fmt.Sprintf(`%[1]s rm containerID
%[1]s rm containerID1 containerID2 containerID3
%[1]s rm --all`, rootCmdName),
%[1]s rm --all`, rootCmd.CommandPath()),
}
rmCommand.SetUsageTemplate(UsageTemplate())
+1 -1
View File
@@ -47,7 +47,7 @@ func newRMICommand() *cobra.Command {
},
Example: fmt.Sprintf(`%[1]s rmi imageID
%[1]s rmi --all --force
%[1]s rmi imageID1 imageID2 imageID3`, rootCmdName),
%[1]s rmi imageID1 imageID2 imageID3`, rootCmd.CommandPath()),
}
rmiCommand.SetUsageTemplate(UsageTemplate())
+1 -1
View File
@@ -35,7 +35,7 @@ func newSaveCommand() *cobra.Command {
fmt.Sprintf("%s:%s:%s", DockerArchive, archiveName, args[0]),
}, opts)
},
Example: fmt.Sprintf(`%[1]s save -o kubernetes.tar labring/kubernetes:latest`, rootCmdName),
Example: fmt.Sprintf(`%[1]s save -o kubernetes.tar labring/kubernetes:latest`, rootCmd.CommandPath()),
}
saveCommand.SetUsageTemplate(UsageTemplate())
+17
View File
@@ -17,6 +17,7 @@ package buildah
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"github.com/containers/common/pkg/config"
@@ -106,6 +107,21 @@ func writeFileIfNotExists(filename string, data []byte) error {
return err
}
func DetermineIfRootlessPackagePresent() error {
if !IsRootless() {
return nil
}
deps := map[string][]string{"uidmap": {"newuidmap", "newgidmap"}, "fuse-overlayfs": {"fuse-overlayfs"}}
for pkg, executables := range deps {
for i := range executables {
if _, err := exec.LookPath(executables[i]); err != nil {
return fmt.Errorf("executable file '%s' not found in $PATH, consider run in root mode or install package '%s' first", executables[i], pkg)
}
}
}
return nil
}
func MaybeReexecUsingUserNamespace() error {
if !IsRootless() {
return nil
@@ -124,6 +140,7 @@ func MaybeReexecUsingUserNamespace() error {
type Setter func() error
var defaultSetters = []Setter{
DetermineIfRootlessPackagePresent,
MaybeReexecUsingUserNamespace,
SetupContainerPolicy,
SetupRegistriesFile,
+1 -1
View File
@@ -33,7 +33,7 @@ func newTagCommand() *cobra.Command {
RunE: tagCmd,
Example: fmt.Sprintf(`%[1]s tag imageName firstNewName
%[1]s tag imageName firstNewName SecondNewName`, rootCmdName),
%[1]s tag imageName firstNewName SecondNewName`, rootCmd.CommandPath()),
Args: cobra.MinimumNArgs(2),
}
tagCommand.SetUsageTemplate(UsageTemplate())
+1 -1
View File
@@ -34,7 +34,7 @@ func newUmountCommand() *cobra.Command {
RunE: umountCmd,
Example: fmt.Sprintf(`%[1]s umount containerID
%[1]s umount containerID1 containerID2 containerID3
%[1]s umount --all`, rootCmdName),
%[1]s umount --all`, rootCmd.CommandPath()),
}
umountCommand.SetUsageTemplate(UsageTemplate())
+1 -1
View File
@@ -41,7 +41,7 @@ func newUnshareCommand() *cobra.Command {
RunE: unshareCmd,
Example: fmt.Sprintf(`%[1]s unshare id
%[1]s unshare cat /proc/self/uid_map
%[1]s unshare buildah-script.sh`, rootCmdName),
%[1]s unshare buildah-script.sh`, rootCmd.CommandPath()),
}
unshareMounts []string
)