package deployer import ( "fmt" "strconv" "strings" ) type ImageConfig struct { Port int ProxyEnable bool ProxyKind string Limits struct { Memory int64 CPU int64 } Security struct { ReadOnlyFS bool SecurityOpt []string CapAdd []string CapDrop []string } } func defaultImageConfig() ImageConfig { cfg := ImageConfig{ Port: 0, ProxyEnable: true, ProxyKind: "http", } cfg.Limits.Memory = 1024 * 1024 * 1024 cfg.Limits.CPU = 1000000000 cfg.Security.ReadOnlyFS = true cfg.Security.SecurityOpt = []string{"no-new-privileges"} cfg.Security.CapAdd = []string{} cfg.Security.CapDrop = []string{"ALL"} return cfg } func extractImageConfig(imageLabels map[string]string) (ImageConfig, error) { var prefix = Namespace + "." cfg := defaultImageConfig() for k, v := range imageLabels { if !strings.HasPrefix(k, prefix) { continue } key := strings.TrimPrefix(k, prefix) switch key { case "port": p, err := strconv.Atoi(v) if err != nil { return cfg, fmt.Errorf("invalid port: %q", v) } cfg.Port = p case "proxy.enable": cfg.ProxyEnable = v == "true" case "proxy.kind": if v != "http" && v != "tcp" { return cfg, fmt.Errorf("invalid proxy.kind: %q", v) } cfg.ProxyKind = v case "limits.memory": cfg.Limits.Memory = parseMemory(v) case "limits.cpu": cfg.Limits.CPU = parseCPU(v) case "security.read-only-fs": cfg.Security.ReadOnlyFS = v == "true" case "security.security-opt": cfg.Security.SecurityOpt = strings.Split(v, ",") case "security.cap-add": cfg.Security.CapAdd = strings.Split(v, ",") case "security.cap-drop": cfg.Security.CapDrop = strings.Split(v, ",") } } if cfg.Port == 0 { return cfg, fmt.Errorf("no port given") } return cfg, nil } func parseMemory(mem string) int64 { mem = strings.ToUpper(mem) switch { case strings.HasSuffix(mem, "G"): v, _ := strconv.ParseInt(strings.TrimSuffix(mem, "G"), 10, 64) return v * 1024 * 1024 * 1024 case strings.HasSuffix(mem, "M"): v, _ := strconv.ParseInt(strings.TrimSuffix(mem, "M"), 10, 64) return v * 1024 * 1024 default: v, _ := strconv.ParseInt(mem, 10, 64) return v } } func parseCPU(cpu string) int64 { f, err := strconv.ParseFloat(cpu, 64) if err != nil { return 1000000000 } return int64(f * 1000000000) }