github.com/apptainer/singularity@v3.1.1+incompatible/cmd/internal/cli/run_help_linux.go (about) 1 // Copyright (c) 2018-2019, Sylabs Inc. All rights reserved. 2 // This software is licensed under a 3-clause BSD license. Please consult the 3 // LICENSE.md file distributed with the sources of this project regarding your 4 // rights to use or distribute this software. 5 6 package cli 7 8 import ( 9 "encoding/json" 10 "fmt" 11 "os" 12 "path/filepath" 13 14 "github.com/opencontainers/runtime-tools/generate" 15 "github.com/spf13/cobra" 16 "github.com/sylabs/singularity/docs" 17 "github.com/sylabs/singularity/internal/pkg/buildcfg" 18 "github.com/sylabs/singularity/internal/pkg/runtime/engines/config" 19 "github.com/sylabs/singularity/internal/pkg/runtime/engines/config/oci" 20 singularityConfig "github.com/sylabs/singularity/internal/pkg/runtime/engines/singularity/config" 21 "github.com/sylabs/singularity/internal/pkg/sylog" 22 "github.com/sylabs/singularity/internal/pkg/util/exec" 23 ) 24 25 const ( 26 standardHelpPath = "/.singularity.d/runscript.help" 27 appHelpPath = "/scif/apps/%s/scif/runscript.help" 28 runHelpCommand = "if [ ! -f \"%s\" ]\nthen\n echo \"No help sections were defined for this image\"\nelse\n /bin/cat %s\nfi" 29 ) 30 31 func init() { 32 RunHelpCmd.Flags().SetInterspersed(false) 33 34 RunHelpCmd.Flags().StringVar(&AppName, "app", "", "Show the help for an app") 35 RunHelpCmd.Flags().SetAnnotation("app", "envkey", []string{"APP"}) 36 37 SingularityCmd.AddCommand(RunHelpCmd) 38 } 39 40 // RunHelpCmd singularity run-help <image> 41 var RunHelpCmd = &cobra.Command{ 42 DisableFlagsInUseLine: true, 43 PreRun: sylabsToken, 44 Args: cobra.ExactArgs(1), 45 Run: func(cmd *cobra.Command, args []string) { 46 // Sanity check 47 if _, err := os.Stat(args[0]); err != nil { 48 sylog.Fatalf("container not found: %s", err) 49 } 50 51 // Help prints (if set) the sourced %help section on the definition file 52 abspath, err := filepath.Abs(args[0]) 53 if err != nil { 54 sylog.Fatalf("While getting absolute path: %s", err) 55 } 56 name := filepath.Base(abspath) 57 58 a := []string{"/bin/sh", "-c", getCommand(getHelpPath(cmd))} 59 starter := buildcfg.LIBEXECDIR + "/singularity/bin/starter-suid" 60 procname := "Singularity help" 61 Env := []string{sylog.GetEnvVar()} 62 63 engineConfig := singularityConfig.NewConfig() 64 ociConfig := &oci.Config{} 65 generator := generate.Generator{Config: &ociConfig.Spec} 66 engineConfig.OciConfig = ociConfig 67 68 generator.SetProcessArgs(a) 69 generator.SetProcessCwd("/") 70 engineConfig.SetImage(abspath) 71 72 cfg := &config.Common{ 73 EngineName: singularityConfig.Name, 74 ContainerID: name, 75 EngineConfig: engineConfig, 76 } 77 78 configData, err := json.Marshal(cfg) 79 if err != nil { 80 sylog.Fatalf("CLI Failed to marshal CommonEngineConfig: %s\n", err) 81 } 82 83 if err := exec.Pipe(starter, []string{procname}, Env, configData); err != nil { 84 sylog.Fatalf("%s", err) 85 } 86 }, 87 88 Use: docs.RunHelpUse, 89 Short: docs.RunHelpShort, 90 Long: docs.RunHelpLong, 91 Example: docs.RunHelpExample, 92 } 93 94 func getCommand(helpFile string) string { 95 return fmt.Sprintf(runHelpCommand, helpFile, helpFile) 96 } 97 98 func getHelpPath(cmd *cobra.Command) string { 99 if cmd.Flags().Changed("app") { 100 sylog.Debugf("App specified. Looking for help section of %s", AppName) 101 return fmt.Sprintf(appHelpPath, AppName) 102 } 103 104 return standardHelpPath 105 }