github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/pkg/bindings/pods/pods.go (about) 1 package pods 2 3 import ( 4 "context" 5 "net/http" 6 "net/url" 7 "strconv" 8 "strings" 9 10 "github.com/containers/libpod/pkg/api/handlers" 11 "github.com/containers/libpod/pkg/bindings" 12 "github.com/containers/libpod/pkg/domain/entities" 13 "github.com/containers/libpod/pkg/specgen" 14 jsoniter "github.com/json-iterator/go" 15 ) 16 17 func CreatePodFromSpec(ctx context.Context, s *specgen.PodSpecGenerator) (*entities.PodCreateReport, error) { 18 var ( 19 pcr entities.PodCreateReport 20 ) 21 conn, err := bindings.GetClient(ctx) 22 if err != nil { 23 return nil, err 24 } 25 specgenString, err := jsoniter.MarshalToString(s) 26 if err != nil { 27 return nil, err 28 } 29 stringReader := strings.NewReader(specgenString) 30 response, err := conn.DoRequest(stringReader, http.MethodPost, "/pods/create", nil) 31 if err != nil { 32 return nil, err 33 } 34 return &pcr, response.Process(&pcr) 35 } 36 37 // Exists is a lightweight method to determine if a pod exists in local storage 38 func Exists(ctx context.Context, nameOrID string) (bool, error) { 39 conn, err := bindings.GetClient(ctx) 40 if err != nil { 41 return false, err 42 } 43 response, err := conn.DoRequest(nil, http.MethodGet, "/pods/%s/exists", nil, nameOrID) 44 if err != nil { 45 return false, err 46 } 47 return response.IsSuccess(), nil 48 } 49 50 // Inspect returns low-level information about the given pod. 51 func Inspect(ctx context.Context, nameOrID string) (*entities.PodInspectReport, error) { 52 var ( 53 report entities.PodInspectReport 54 ) 55 conn, err := bindings.GetClient(ctx) 56 if err != nil { 57 return nil, err 58 } 59 response, err := conn.DoRequest(nil, http.MethodGet, "/pods/%s/json", nil, nameOrID) 60 if err != nil { 61 return nil, err 62 } 63 return &report, response.Process(&report) 64 } 65 66 // Kill sends a SIGTERM to all the containers in a pod. The optional signal parameter 67 // can be used to override SIGTERM. 68 func Kill(ctx context.Context, nameOrID string, signal *string) (*entities.PodKillReport, error) { 69 var ( 70 report entities.PodKillReport 71 ) 72 conn, err := bindings.GetClient(ctx) 73 if err != nil { 74 return nil, err 75 } 76 params := url.Values{} 77 if signal != nil { 78 params.Set("signal", *signal) 79 } 80 response, err := conn.DoRequest(nil, http.MethodPost, "/pods/%s/kill", params, nameOrID) 81 if err != nil { 82 return nil, err 83 } 84 return &report, response.Process(&report) 85 } 86 87 // Pause pauses all running containers in a given pod. 88 func Pause(ctx context.Context, nameOrID string) (*entities.PodPauseReport, error) { 89 var report entities.PodPauseReport 90 conn, err := bindings.GetClient(ctx) 91 if err != nil { 92 return nil, err 93 } 94 response, err := conn.DoRequest(nil, http.MethodPost, "/pods/%s/pause", nil, nameOrID) 95 if err != nil { 96 return nil, err 97 } 98 return &report, response.Process(&report) 99 } 100 101 // Prune removes all non-running pods in local storage. 102 func Prune(ctx context.Context) error { 103 conn, err := bindings.GetClient(ctx) 104 if err != nil { 105 return err 106 } 107 response, err := conn.DoRequest(nil, http.MethodPost, "/pods/prune", nil) 108 if err != nil { 109 return err 110 } 111 return response.Process(nil) 112 } 113 114 // List returns all pods in local storage. The optional filters parameter can 115 // be used to refine which pods should be listed. 116 func List(ctx context.Context, filters map[string][]string) ([]*entities.ListPodsReport, error) { 117 var ( 118 podsReports []*entities.ListPodsReport 119 ) 120 conn, err := bindings.GetClient(ctx) 121 if err != nil { 122 return nil, err 123 } 124 params := url.Values{} 125 if filters != nil { 126 stringFilter, err := bindings.FiltersToString(filters) 127 if err != nil { 128 return nil, err 129 } 130 params.Set("filters", stringFilter) 131 } 132 response, err := conn.DoRequest(nil, http.MethodGet, "/pods/json", params) 133 if err != nil { 134 return podsReports, err 135 } 136 return podsReports, response.Process(&podsReports) 137 } 138 139 // Restart restarts all containers in a pod. 140 func Restart(ctx context.Context, nameOrID string) (*entities.PodRestartReport, error) { 141 var report entities.PodRestartReport 142 conn, err := bindings.GetClient(ctx) 143 if err != nil { 144 return nil, err 145 } 146 response, err := conn.DoRequest(nil, http.MethodPost, "/pods/%s/restart", nil, nameOrID) 147 if err != nil { 148 return nil, err 149 } 150 return &report, response.Process(&report) 151 } 152 153 // Remove deletes a Pod from from local storage. The optional force parameter denotes 154 // that the Pod can be removed even if in a running state. 155 func Remove(ctx context.Context, nameOrID string, force *bool) (*entities.PodRmReport, error) { 156 var report entities.PodRmReport 157 conn, err := bindings.GetClient(ctx) 158 if err != nil { 159 return nil, err 160 } 161 params := url.Values{} 162 if force != nil { 163 params.Set("force", strconv.FormatBool(*force)) 164 } 165 response, err := conn.DoRequest(nil, http.MethodDelete, "/pods/%s", params, nameOrID) 166 if err != nil { 167 return nil, err 168 } 169 return &report, response.Process(&report) 170 } 171 172 // Start starts all containers in a pod. 173 func Start(ctx context.Context, nameOrID string) (*entities.PodStartReport, error) { 174 var report entities.PodStartReport 175 conn, err := bindings.GetClient(ctx) 176 if err != nil { 177 return nil, err 178 } 179 response, err := conn.DoRequest(nil, http.MethodPost, "/pods/%s/start", nil, nameOrID) 180 if err != nil { 181 return nil, err 182 } 183 if response.StatusCode == http.StatusNotModified { 184 report.Id = nameOrID 185 return &report, nil 186 } 187 return &report, response.Process(&report) 188 } 189 190 func Stats() error { 191 // TODO 192 return bindings.ErrNotImplemented 193 } 194 195 // Stop stops all containers in a Pod. The optional timeout parameter can be 196 // used to override the timeout before the container is killed. 197 func Stop(ctx context.Context, nameOrID string, timeout *int) (*entities.PodStopReport, error) { 198 var report entities.PodStopReport 199 conn, err := bindings.GetClient(ctx) 200 if err != nil { 201 return nil, err 202 } 203 params := url.Values{} 204 if timeout != nil { 205 params.Set("t", strconv.Itoa(*timeout)) 206 } 207 response, err := conn.DoRequest(nil, http.MethodPost, "/pods/%s/stop", params, nameOrID) 208 if err != nil { 209 return nil, err 210 } 211 if response.StatusCode == http.StatusNotModified { 212 report.Id = nameOrID 213 return &report, nil 214 } 215 return &report, response.Process(&report) 216 } 217 218 // Top gathers statistics about the running processes in a pod. The nameOrID can be a pod name 219 // or a partial/full ID. The descriptors allow for specifying which data to collect from each process. 220 func Top(ctx context.Context, nameOrID string, descriptors []string) ([]string, error) { 221 conn, err := bindings.GetClient(ctx) 222 if err != nil { 223 return nil, err 224 } 225 params := url.Values{} 226 227 if len(descriptors) > 0 { 228 // flatten the slice into one string 229 params.Set("ps_args", strings.Join(descriptors, ",")) 230 } 231 response, err := conn.DoRequest(nil, http.MethodGet, "/pods/%s/top", params, nameOrID) 232 if err != nil { 233 return nil, err 234 } 235 236 body := handlers.PodTopOKBody{} 237 if err = response.Process(&body); err != nil { 238 return nil, err 239 } 240 241 // handlers.PodTopOKBody{} returns a slice of slices where each cell in the top table is an item. 242 // In libpod land, we're just using a slice with cells being split by tabs, which allows for an idiomatic 243 // usage of the tabwriter. 244 topOutput := []string{strings.Join(body.Titles, "\t")} 245 for _, out := range body.Processes { 246 topOutput = append(topOutput, strings.Join(out, "\t")) 247 } 248 249 return topOutput, err 250 } 251 252 // Unpause unpauses all paused containers in a Pod. 253 func Unpause(ctx context.Context, nameOrID string) (*entities.PodUnpauseReport, error) { 254 var report entities.PodUnpauseReport 255 conn, err := bindings.GetClient(ctx) 256 if err != nil { 257 return nil, err 258 } 259 response, err := conn.DoRequest(nil, http.MethodPost, "/pods/%s/unpause", nil, nameOrID) 260 if err != nil { 261 return nil, err 262 } 263 return &report, response.Process(&report) 264 }