github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/pkg/domain/infra/tunnel/containers.go (about) 1 package tunnel 2 3 import ( 4 "context" 5 "io" 6 "os" 7 8 "github.com/containers/common/pkg/config" 9 "github.com/containers/image/v5/docker/reference" 10 "github.com/containers/libpod/libpod/define" 11 "github.com/containers/libpod/pkg/bindings/containers" 12 "github.com/containers/libpod/pkg/domain/entities" 13 "github.com/containers/libpod/pkg/specgen" 14 "github.com/pkg/errors" 15 ) 16 17 func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrId string) (*entities.BoolReport, error) { 18 exists, err := containers.Exists(ic.ClientCxt, nameOrId) 19 return &entities.BoolReport{Value: exists}, err 20 } 21 22 func (ic *ContainerEngine) ContainerWait(ctx context.Context, namesOrIds []string, options entities.WaitOptions) ([]entities.WaitReport, error) { 23 var ( 24 responses []entities.WaitReport 25 ) 26 cons, err := getContainersByContext(ic.ClientCxt, false, namesOrIds) 27 if err != nil { 28 return nil, err 29 } 30 for _, c := range cons { 31 response := entities.WaitReport{Id: c.ID} 32 exitCode, err := containers.Wait(ic.ClientCxt, c.ID, &options.Condition) 33 if err != nil { 34 response.Error = err 35 } else { 36 response.ExitCode = exitCode 37 } 38 responses = append(responses, response) 39 } 40 return responses, nil 41 } 42 43 func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) { 44 var ( 45 reports []*entities.PauseUnpauseReport 46 ) 47 ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds) 48 if err != nil { 49 return nil, err 50 } 51 for _, c := range ctrs { 52 err := containers.Pause(ic.ClientCxt, c.ID) 53 reports = append(reports, &entities.PauseUnpauseReport{Id: c.ID, Err: err}) 54 } 55 return reports, nil 56 } 57 58 func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) { 59 var ( 60 reports []*entities.PauseUnpauseReport 61 ) 62 ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds) 63 if err != nil { 64 return nil, err 65 } 66 for _, c := range ctrs { 67 err := containers.Unpause(ic.ClientCxt, c.ID) 68 reports = append(reports, &entities.PauseUnpauseReport{Id: c.ID, Err: err}) 69 } 70 return reports, nil 71 } 72 73 func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []string, options entities.StopOptions) ([]*entities.StopReport, error) { 74 var ( 75 reports []*entities.StopReport 76 ) 77 ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds) 78 if err != nil { 79 return nil, err 80 } 81 for _, c := range ctrs { 82 report := entities.StopReport{Id: c.ID} 83 report.Err = containers.Stop(ic.ClientCxt, c.ID, &options.Timeout) 84 // TODO we need to associate errors returned by http with common 85 // define.errors so that we can equity tests. this will allow output 86 // to be the same as the native client 87 reports = append(reports, &report) 88 } 89 return reports, nil 90 } 91 92 func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []string, options entities.KillOptions) ([]*entities.KillReport, error) { 93 var ( 94 reports []*entities.KillReport 95 ) 96 ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds) 97 if err != nil { 98 return nil, err 99 } 100 for _, c := range ctrs { 101 reports = append(reports, &entities.KillReport{ 102 Id: c.ID, 103 Err: containers.Kill(ic.ClientCxt, c.ID, options.Signal), 104 }) 105 } 106 return reports, nil 107 } 108 109 func (ic *ContainerEngine) ContainerRestart(ctx context.Context, namesOrIds []string, options entities.RestartOptions) ([]*entities.RestartReport, error) { 110 var ( 111 reports []*entities.RestartReport 112 timeout *int 113 ) 114 if options.Timeout != nil { 115 t := int(*options.Timeout) 116 timeout = &t 117 } 118 ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds) 119 if err != nil { 120 return nil, err 121 } 122 for _, c := range ctrs { 123 reports = append(reports, &entities.RestartReport{ 124 Id: c.ID, 125 Err: containers.Restart(ic.ClientCxt, c.ID, timeout), 126 }) 127 } 128 return reports, nil 129 } 130 131 func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, options entities.RmOptions) ([]*entities.RmReport, error) { 132 var ( 133 reports []*entities.RmReport 134 ) 135 ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds) 136 if err != nil { 137 return nil, err 138 } 139 // TODO there is no endpoint for container eviction. Need to discuss 140 for _, c := range ctrs { 141 reports = append(reports, &entities.RmReport{ 142 Id: c.ID, 143 Err: containers.Remove(ic.ClientCxt, c.ID, &options.Force, &options.Volumes), 144 }) 145 } 146 return reports, nil 147 } 148 149 func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]*entities.ContainerInspectReport, error) { 150 var ( 151 reports []*entities.ContainerInspectReport 152 ) 153 ctrs, err := getContainersByContext(ic.ClientCxt, false, namesOrIds) 154 if err != nil { 155 return nil, err 156 } 157 for _, con := range ctrs { 158 data, err := containers.Inspect(ic.ClientCxt, con.ID, &options.Size) 159 if err != nil { 160 return nil, err 161 } 162 reports = append(reports, &entities.ContainerInspectReport{InspectContainerData: data}) 163 } 164 return reports, nil 165 } 166 167 func (ic *ContainerEngine) ContainerTop(ctx context.Context, options entities.TopOptions) (*entities.StringSliceReport, error) { 168 switch { 169 case options.Latest: 170 return nil, errors.New("latest is not supported") 171 case options.NameOrID == "": 172 return nil, errors.New("NameOrID must be specified") 173 } 174 175 topOutput, err := containers.Top(ic.ClientCxt, options.NameOrID, options.Descriptors) 176 if err != nil { 177 return nil, err 178 } 179 return &entities.StringSliceReport{Value: topOutput}, nil 180 } 181 182 func (ic *ContainerEngine) ContainerCommit(ctx context.Context, nameOrId string, options entities.CommitOptions) (*entities.CommitReport, error) { 183 var ( 184 repo string 185 tag string = "latest" 186 ) 187 if len(options.ImageName) > 0 { 188 ref, err := reference.Parse(options.ImageName) 189 if err != nil { 190 return nil, err 191 } 192 if t, ok := ref.(reference.Tagged); ok { 193 tag = t.Tag() 194 } 195 if r, ok := ref.(reference.Named); ok { 196 repo = r.Name() 197 } 198 if len(repo) < 1 { 199 return nil, errors.Errorf("invalid image name %q", options.ImageName) 200 } 201 } 202 commitOpts := containers.CommitOptions{ 203 Author: &options.Author, 204 Changes: options.Changes, 205 Comment: &options.Message, 206 Format: &options.Format, 207 Pause: &options.Pause, 208 Repo: &repo, 209 Tag: &tag, 210 } 211 response, err := containers.Commit(ic.ClientCxt, nameOrId, commitOpts) 212 if err != nil { 213 return nil, err 214 } 215 return &entities.CommitReport{Id: response.ID}, nil 216 } 217 218 func (ic *ContainerEngine) ContainerExport(ctx context.Context, nameOrId string, options entities.ContainerExportOptions) error { 219 var ( 220 err error 221 w io.Writer 222 ) 223 if len(options.Output) > 0 { 224 w, err = os.Create(options.Output) 225 if err != nil { 226 return err 227 } 228 } 229 return containers.Export(ic.ClientCxt, nameOrId, w) 230 } 231 232 func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds []string, options entities.CheckpointOptions) ([]*entities.CheckpointReport, error) { 233 var ( 234 reports []*entities.CheckpointReport 235 err error 236 ctrs []entities.ListContainer 237 ) 238 239 if options.All { 240 allCtrs, err := getContainersByContext(ic.ClientCxt, true, []string{}) 241 if err != nil { 242 return nil, err 243 } 244 // narrow the list to running only 245 for _, c := range allCtrs { 246 if c.State == define.ContainerStateRunning.String() { 247 ctrs = append(ctrs, c) 248 } 249 } 250 251 } else { 252 ctrs, err = getContainersByContext(ic.ClientCxt, false, namesOrIds) 253 if err != nil { 254 return nil, err 255 } 256 } 257 for _, c := range ctrs { 258 report, err := containers.Checkpoint(ic.ClientCxt, c.ID, &options.Keep, &options.LeaveRuninng, &options.TCPEstablished, &options.IgnoreRootFS, &options.Export) 259 if err != nil { 260 reports = append(reports, &entities.CheckpointReport{Id: c.ID, Err: err}) 261 } 262 reports = append(reports, report) 263 } 264 return reports, nil 265 } 266 267 func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []string, options entities.RestoreOptions) ([]*entities.RestoreReport, error) { 268 var ( 269 reports []*entities.RestoreReport 270 err error 271 ctrs []entities.ListContainer 272 ) 273 if options.All { 274 allCtrs, err := getContainersByContext(ic.ClientCxt, true, []string{}) 275 if err != nil { 276 return nil, err 277 } 278 // narrow the list to exited only 279 for _, c := range allCtrs { 280 if c.State == define.ContainerStateExited.String() { 281 ctrs = append(ctrs, c) 282 } 283 } 284 285 } else { 286 ctrs, err = getContainersByContext(ic.ClientCxt, false, namesOrIds) 287 if err != nil { 288 return nil, err 289 } 290 } 291 for _, c := range ctrs { 292 report, err := containers.Restore(ic.ClientCxt, c.ID, &options.Keep, &options.TCPEstablished, &options.IgnoreRootFS, &options.IgnoreStaticIP, &options.IgnoreStaticMAC, &options.Name, &options.Import) 293 if err != nil { 294 reports = append(reports, &entities.RestoreReport{Id: c.ID, Err: err}) 295 } 296 reports = append(reports, report) 297 } 298 return reports, nil 299 } 300 301 func (ic *ContainerEngine) ContainerCreate(ctx context.Context, s *specgen.SpecGenerator) (*entities.ContainerCreateReport, error) { 302 response, err := containers.CreateWithSpec(ic.ClientCxt, s) 303 if err != nil { 304 return nil, err 305 } 306 return &entities.ContainerCreateReport{Id: response.ID}, nil 307 } 308 309 func (ic *ContainerEngine) ContainerLogs(ctx context.Context, containers []string, options entities.ContainerLogsOptions) error { 310 // The endpoint is not ready yet and requires some more work. 311 return errors.New("not implemented yet") 312 } 313 314 func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrId string, options entities.AttachOptions) error { 315 return errors.New("not implemented") 316 } 317 318 func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, options entities.ExecOptions) (int, error) { 319 return 125, errors.New("not implemented") 320 } 321 322 func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) { 323 return nil, errors.New("not implemented") 324 } 325 326 func (ic *ContainerEngine) ContainerList(ctx context.Context, options entities.ContainerListOptions) ([]entities.ListContainer, error) { 327 return containers.List(ic.ClientCxt, options.Filters, &options.All, &options.Last, &options.Pod, &options.Size, &options.Sync) 328 } 329 330 func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.ContainerRunOptions) (*entities.ContainerRunReport, error) { 331 return nil, errors.New("not implemented") 332 } 333 334 func (ic *ContainerEngine) ContainerDiff(ctx context.Context, nameOrId string, _ entities.DiffOptions) (*entities.DiffReport, error) { 335 changes, err := containers.Diff(ic.ClientCxt, nameOrId) 336 return &entities.DiffReport{Changes: changes}, err 337 } 338 339 func (ic *ContainerEngine) ContainerCleanup(ctx context.Context, namesOrIds []string, options entities.ContainerCleanupOptions) ([]*entities.ContainerCleanupReport, error) { 340 return nil, errors.New("not implemented") 341 } 342 343 func (ic *ContainerEngine) ContainerInit(ctx context.Context, namesOrIds []string, options entities.ContainerInitOptions) ([]*entities.ContainerInitReport, error) { 344 var reports []*entities.ContainerInitReport 345 ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds) 346 if err != nil { 347 return nil, err 348 } 349 for _, ctr := range ctrs { 350 err := containers.ContainerInit(ic.ClientCxt, ctr.ID) 351 reports = append(reports, &entities.ContainerInitReport{ 352 Err: err, 353 Id: ctr.ID, 354 }) 355 } 356 return reports, nil 357 } 358 359 func (ic *ContainerEngine) ContainerMount(ctx context.Context, nameOrIds []string, options entities.ContainerMountOptions) ([]*entities.ContainerMountReport, error) { 360 return nil, errors.New("mounting containers is not supported for remote clients") 361 } 362 363 func (ic *ContainerEngine) ContainerUnmount(ctx context.Context, nameOrIds []string, options entities.ContainerUnmountOptions) ([]*entities.ContainerUnmountReport, error) { 364 return nil, errors.New("unmounting containers is not supported for remote clients") 365 } 366 367 func (ic *ContainerEngine) Config(_ context.Context) (*config.Config, error) { 368 return config.Default() 369 }