copy/pasted from https://github.com/docker/cli/blob/9de1b162f/cli/command/container/opts.go#L673-L697 + RelativePath TODO find so way to share this code with docker/cli
(p *types.Project, securityOpts []string)
| 462 | // copy/pasted from https://github.com/docker/cli/blob/9de1b162f/cli/command/container/opts.go#L673-L697 + RelativePath |
| 463 | // TODO find so way to share this code with docker/cli |
| 464 | func parseSecurityOpts(p *types.Project, securityOpts []string) ([]string, bool, error) { |
| 465 | var ( |
| 466 | unconfined bool |
| 467 | parsed []string |
| 468 | ) |
| 469 | for _, opt := range securityOpts { |
| 470 | if opt == "systempaths=unconfined" { |
| 471 | unconfined = true |
| 472 | continue |
| 473 | } |
| 474 | con := strings.SplitN(opt, "=", 2) |
| 475 | if len(con) == 1 && con[0] != "no-new-privileges" { |
| 476 | if strings.Contains(opt, ":") { |
| 477 | con = strings.SplitN(opt, ":", 2) |
| 478 | } else { |
| 479 | return securityOpts, false, fmt.Errorf("invalid security-opt: %q", opt) |
| 480 | } |
| 481 | } |
| 482 | if con[0] == "seccomp" && con[1] != "unconfined" && con[1] != "builtin" { |
| 483 | f, err := os.ReadFile(p.RelativePath(con[1])) |
| 484 | if err != nil { |
| 485 | return securityOpts, false, fmt.Errorf("opening seccomp profile (%s) failed: %w", con[1], err) |
| 486 | } |
| 487 | b := bytes.NewBuffer(nil) |
| 488 | if err := json.Compact(b, f); err != nil { |
| 489 | return securityOpts, false, fmt.Errorf("compacting json for seccomp profile (%s) failed: %w", con[1], err) |
| 490 | } |
| 491 | parsed = append(parsed, fmt.Sprintf("seccomp=%s", b.Bytes())) |
| 492 | } else { |
| 493 | parsed = append(parsed, opt) |
| 494 | } |
| 495 | } |
| 496 | |
| 497 | return parsed, unconfined, nil |
| 498 | } |
| 499 | |
| 500 | func (s *composeService) prepareLabels(labels types.Labels, service types.ServiceConfig, number int) (map[string]string, error) { |
| 501 | hash, err := ServiceHash(service) |
no test coverage detected