github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/bindings/containers/exec.go (about) 1 package containers 2 3 import ( 4 "bytes" 5 "context" 6 "net/http" 7 "strings" 8 9 "github.com/hanks177/podman/v4/libpod/define" 10 "github.com/hanks177/podman/v4/pkg/api/handlers" 11 "github.com/hanks177/podman/v4/pkg/bindings" 12 "github.com/hanks177/podman/v4/pkg/domain/entities" 13 jsoniter "github.com/json-iterator/go" 14 "github.com/pkg/errors" 15 "github.com/sirupsen/logrus" 16 ) 17 18 var json = jsoniter.ConfigCompatibleWithStandardLibrary 19 20 // ExecCreate creates a new exec session in an existing container. 21 // The exec session will not be started; that is done with ExecStart. 22 // Returns ID of new exec session, or an error if one occurred. 23 func ExecCreate(ctx context.Context, nameOrID string, config *handlers.ExecCreateConfig) (string, error) { 24 conn, err := bindings.GetClient(ctx) 25 if err != nil { 26 return "", err 27 } 28 29 if config == nil { 30 return "", errors.Errorf("must provide a configuration for exec session") 31 } 32 33 requestJSON, err := json.Marshal(config) 34 if err != nil { 35 return "", errors.Wrapf(err, "error marshalling exec config to JSON") 36 } 37 jsonReader := strings.NewReader(string(requestJSON)) 38 39 resp, err := conn.DoRequest(ctx, jsonReader, http.MethodPost, "/containers/%s/exec", nil, nil, nameOrID) 40 if err != nil { 41 return "", err 42 } 43 defer resp.Body.Close() 44 45 respStruct := new(entities.IDResponse) 46 if err := resp.Process(respStruct); err != nil { 47 return "", err 48 } 49 50 return respStruct.ID, nil 51 } 52 53 // ExecInspect inspects an existing exec session, returning detailed information 54 // about it. 55 func ExecInspect(ctx context.Context, sessionID string, options *ExecInspectOptions) (*define.InspectExecSession, error) { 56 if options == nil { 57 options = new(ExecInspectOptions) 58 } 59 _ = options 60 conn, err := bindings.GetClient(ctx) 61 if err != nil { 62 return nil, err 63 } 64 65 logrus.Debugf("Inspecting session ID %q", sessionID) 66 67 resp, err := conn.DoRequest(ctx, nil, http.MethodGet, "/exec/%s/json", nil, nil, sessionID) 68 if err != nil { 69 return nil, err 70 } 71 defer resp.Body.Close() 72 73 respStruct := new(define.InspectExecSession) 74 if err := resp.Process(respStruct); err != nil { 75 return nil, err 76 } 77 78 return respStruct, nil 79 } 80 81 // ExecStart starts (but does not attach to) a given exec session. 82 func ExecStart(ctx context.Context, sessionID string, options *ExecStartOptions) error { 83 if options == nil { 84 options = new(ExecStartOptions) 85 } 86 _ = options 87 conn, err := bindings.GetClient(ctx) 88 if err != nil { 89 return err 90 } 91 92 logrus.Debugf("Starting exec session ID %q", sessionID) 93 94 // We force Detach to true 95 body := struct { 96 Detach bool `json:"Detach"` 97 }{ 98 Detach: true, 99 } 100 bodyJSON, err := json.Marshal(body) 101 if err != nil { 102 return err 103 } 104 105 resp, err := conn.DoRequest(ctx, bytes.NewReader(bodyJSON), http.MethodPost, "/exec/%s/start", nil, nil, sessionID) 106 if err != nil { 107 return err 108 } 109 defer resp.Body.Close() 110 111 return resp.Process(nil) 112 }