github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/cmd/podman/varlink.go (about) 1 // +build varlink,!remoteclient 2 3 package main 4 5 import ( 6 "fmt" 7 "os" 8 "path/filepath" 9 "time" 10 11 "github.com/containers/libpod/cmd/podman/cliconfig" 12 "github.com/containers/libpod/cmd/podman/libpodruntime" 13 "github.com/containers/libpod/pkg/adapter" 14 "github.com/containers/libpod/pkg/rootless" 15 "github.com/containers/libpod/pkg/util" 16 iopodman "github.com/containers/libpod/pkg/varlink" 17 "github.com/containers/libpod/pkg/varlinkapi" 18 "github.com/containers/libpod/version" 19 "github.com/pkg/errors" 20 "github.com/sirupsen/logrus" 21 "github.com/spf13/cobra" 22 "github.com/varlink/go/varlink" 23 ) 24 25 var ( 26 varlinkCommand cliconfig.VarlinkValues 27 varlinkDescription = `Run varlink interface. Podman varlink listens on the specified unix domain socket for incoming connects. 28 29 Tools speaking varlink protocol can remotely manage pods, containers and images. 30 ` 31 _varlinkCommand = &cobra.Command{ 32 Use: "varlink [flags] [URI]", 33 Short: "Run varlink interface", 34 Long: varlinkDescription, 35 RunE: func(cmd *cobra.Command, args []string) error { 36 varlinkCommand.InputArgs = args 37 varlinkCommand.GlobalFlags = MainGlobalOpts 38 return varlinkCmd(&varlinkCommand) 39 }, 40 Example: `podman varlink unix:/run/podman/io.podman 41 podman varlink --timeout 5000 unix:/run/podman/io.podman`, 42 } 43 ) 44 45 func init() { 46 varlinkCommand.Command = _varlinkCommand 47 varlinkCommand.SetHelpTemplate(HelpTemplate()) 48 varlinkCommand.SetUsageTemplate(UsageTemplate()) 49 flags := varlinkCommand.Flags() 50 flags.Int64VarP(&varlinkCommand.Timeout, "timeout", "t", 1000, "Time until the varlink session expires in milliseconds. Use 0 to disable the timeout") 51 } 52 53 func varlinkCmd(c *cliconfig.VarlinkValues) error { 54 varlinkURI := adapter.DefaultVarlinkAddress 55 if rootless.IsRootless() { 56 xdg, err := util.GetRuntimeDir() 57 if err != nil { 58 return err 59 } 60 socketDir := filepath.Join(xdg, "podman/io.podman") 61 if _, err := os.Stat(filepath.Dir(socketDir)); os.IsNotExist(err) { 62 if err := os.Mkdir(filepath.Dir(socketDir), 0755); err != nil { 63 return err 64 } 65 } 66 varlinkURI = fmt.Sprintf("unix:%s", socketDir) 67 } 68 args := c.InputArgs 69 70 if len(args) > 1 { 71 return errors.Errorf("too many arguments. You may optionally provide 1") 72 } 73 74 if len(args) > 0 { 75 varlinkURI = args[0] 76 } 77 78 logrus.Debugf("Using varlink socket: %s", varlinkURI) 79 timeout := time.Duration(c.Timeout) * time.Millisecond 80 81 // Create a single runtime for varlink 82 runtime, err := libpodruntime.GetRuntimeDisableFDs(getContext(), &c.PodmanCommand) 83 if err != nil { 84 return errors.Wrapf(err, "error creating libpod runtime") 85 } 86 defer runtime.DeferredShutdown(false) 87 88 var varlinkInterfaces = []*iopodman.VarlinkInterface{varlinkapi.New(c.PodmanCommand.Command, runtime)} 89 // Register varlink service. The metadata can be retrieved with: 90 // $ varlink info [varlink address URI] 91 service, err := varlink.NewService( 92 "Atomic", 93 "podman", 94 version.Version, 95 "https://github.com/containers/libpod", 96 ) 97 if err != nil { 98 return errors.Wrapf(err, "unable to create new varlink service") 99 } 100 101 for _, i := range varlinkInterfaces { 102 if err := service.RegisterInterface(i); err != nil { 103 return errors.Errorf("unable to register varlink interface %v", i) 104 } 105 } 106 107 // Run the varlink server at the given address 108 if err = service.Listen(varlinkURI, timeout); err != nil { 109 switch err.(type) { 110 case varlink.ServiceTimeoutError: 111 logrus.Infof("varlink service expired (use --timeout to increase session time beyond %d ms, 0 means never timeout)", c.Int64("timeout")) 112 return nil 113 default: 114 return errors.Wrapf(err, "unable to start varlink service") 115 } 116 } 117 118 return nil 119 }