github.com/khulnasoft/cli@v0.0.0-20240402070845-01bcad7beefa/cli/compose/loader/full-struct_test.go (about) 1 // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: 2 //go:build go1.19 3 4 package loader 5 6 import ( 7 "time" 8 9 "github.com/khulnasoft/cli/cli/compose/types" 10 ) 11 12 func fullExampleConfig(workingDir, homeDir string) *types.Config { 13 return &types.Config{ 14 Version: "3.12", 15 Services: services(workingDir, homeDir), 16 Networks: networks(), 17 Volumes: volumes(), 18 Configs: configs(workingDir), 19 Secrets: secrets(workingDir), 20 Extras: map[string]any{ 21 "x-foo": "bar", 22 "x-bar": "baz", 23 "x-nested": map[string]any{ 24 "foo": "bar", 25 "bar": "baz", 26 }, 27 }, 28 } 29 } 30 31 func services(workingDir, homeDir string) []types.ServiceConfig { 32 return []types.ServiceConfig{ 33 { 34 Name: "foo", 35 36 Build: types.BuildConfig{ 37 Context: "./dir", 38 Dockerfile: "Dockerfile", 39 Args: map[string]*string{"foo": strPtr("bar")}, 40 Target: "foo", 41 Network: "foo", 42 CacheFrom: []string{"foo", "bar"}, 43 ExtraHosts: types.HostsList{ 44 "ipv4.example.com:127.0.0.1", 45 "ipv6.example.com:::1", 46 }, 47 Labels: map[string]string{"FOO": "BAR"}, 48 }, 49 CapAdd: []string{"ALL"}, 50 CapDrop: []string{"NET_ADMIN", "SYS_ADMIN"}, 51 CgroupParent: "m-executor-abcd", 52 Command: []string{"bundle", "exec", "thin", "-p", "3000"}, 53 Configs: []types.ServiceConfigObjConfig{ 54 { 55 Source: "config1", 56 }, 57 { 58 Source: "config2", 59 Target: "/my_config", 60 UID: "103", 61 GID: "103", 62 Mode: uint32Ptr(0o440), 63 }, 64 }, 65 ContainerName: "my-web-container", 66 DependsOn: []string{"db", "redis"}, 67 Deploy: types.DeployConfig{ 68 Mode: "replicated", 69 Replicas: uint64Ptr(6), 70 Labels: map[string]string{"FOO": "BAR"}, 71 RollbackConfig: &types.UpdateConfig{ 72 Parallelism: uint64Ptr(3), 73 Delay: types.Duration(10 * time.Second), 74 FailureAction: "continue", 75 Monitor: types.Duration(60 * time.Second), 76 MaxFailureRatio: 0.3, 77 Order: "start-first", 78 }, 79 UpdateConfig: &types.UpdateConfig{ 80 Parallelism: uint64Ptr(3), 81 Delay: types.Duration(10 * time.Second), 82 FailureAction: "continue", 83 Monitor: types.Duration(60 * time.Second), 84 MaxFailureRatio: 0.3, 85 Order: "start-first", 86 }, 87 Resources: types.Resources{ 88 Limits: &types.ResourceLimit{ 89 NanoCPUs: "0.001", 90 MemoryBytes: 50 * 1024 * 1024, 91 Pids: 100, 92 }, 93 Reservations: &types.Resource{ 94 NanoCPUs: "0.0001", 95 MemoryBytes: 20 * 1024 * 1024, 96 GenericResources: []types.GenericResource{ 97 { 98 DiscreteResourceSpec: &types.DiscreteGenericResource{ 99 Kind: "gpu", 100 Value: 2, 101 }, 102 }, 103 { 104 DiscreteResourceSpec: &types.DiscreteGenericResource{ 105 Kind: "ssd", 106 Value: 1, 107 }, 108 }, 109 }, 110 }, 111 }, 112 RestartPolicy: &types.RestartPolicy{ 113 Condition: "on-failure", 114 Delay: durationPtr(5 * time.Second), 115 MaxAttempts: uint64Ptr(3), 116 Window: durationPtr(2 * time.Minute), 117 }, 118 Placement: types.Placement{ 119 Constraints: []string{"node=foo"}, 120 MaxReplicas: uint64(5), 121 Preferences: []types.PlacementPreferences{ 122 { 123 Spread: "node.labels.az", 124 }, 125 }, 126 }, 127 EndpointMode: "dnsrr", 128 }, 129 Devices: []string{"/dev/ttyUSB0:/dev/ttyUSB0"}, 130 DNS: []string{"8.8.8.8", "9.9.9.9"}, 131 DNSSearch: []string{"dc1.example.com", "dc2.example.com"}, 132 DomainName: "foo.com", 133 Entrypoint: []string{"/code/entrypoint.sh", "-p", "3000"}, 134 Environment: map[string]*string{ 135 "FOO": strPtr("foo_from_env_file"), 136 "BAR": strPtr("bar_from_env_file_2"), 137 "BAZ": strPtr("baz_from_service_def"), 138 "QUX": strPtr("qux_from_environment"), 139 }, 140 EnvFile: []string{ 141 "./example1.env", 142 "./example2.env", 143 }, 144 Expose: []string{"3000", "8000"}, 145 ExternalLinks: []string{ 146 "redis_1", 147 "project_db_1:mysql", 148 "project_db_1:postgresql", 149 }, 150 ExtraHosts: []string{ 151 "somehost:162.242.195.82", 152 "otherhost:50.31.209.229", 153 "host.docker.internal:host-gateway", 154 }, 155 Extras: map[string]any{ 156 "x-bar": "baz", 157 "x-foo": "bar", 158 }, 159 HealthCheck: &types.HealthCheckConfig{ 160 Test: types.HealthCheckTest([]string{"CMD-SHELL", "echo \"hello world\""}), 161 Interval: durationPtr(10 * time.Second), 162 Timeout: durationPtr(1 * time.Second), 163 Retries: uint64Ptr(5), 164 StartPeriod: durationPtr(15 * time.Second), 165 StartInterval: durationPtr(1 * time.Second), 166 }, 167 Hostname: "foo", 168 Image: "redis", 169 Ipc: "host", 170 Labels: map[string]string{ 171 "com.example.description": "Accounting webapp", 172 "com.example.number": "42", 173 "com.example.empty-label": "", 174 }, 175 Links: []string{ 176 "db", 177 "db:database", 178 "redis", 179 }, 180 Logging: &types.LoggingConfig{ 181 Driver: "syslog", 182 Options: map[string]string{ 183 "syslog-address": "tcp://192.168.0.42:123", 184 }, 185 }, 186 MacAddress: "02:42:ac:11:65:43", 187 NetworkMode: "container:0cfeab0f748b9a743dc3da582046357c6ef497631c1a016d28d2bf9b4f899f7b", 188 Networks: map[string]*types.ServiceNetworkConfig{ 189 "some-network": { 190 Aliases: []string{"alias1", "alias3"}, 191 Ipv4Address: "", 192 Ipv6Address: "", 193 }, 194 "other-network": { 195 Ipv4Address: "172.16.238.10", 196 Ipv6Address: "2001:3984:3989::10", 197 }, 198 "other-other-network": nil, 199 }, 200 Pid: "host", 201 Ports: []types.ServicePortConfig{ 202 // "3000", 203 { 204 Mode: "ingress", 205 Target: 3000, 206 Protocol: "tcp", 207 }, 208 { 209 Mode: "ingress", 210 Target: 3001, 211 Protocol: "tcp", 212 }, 213 { 214 Mode: "ingress", 215 Target: 3002, 216 Protocol: "tcp", 217 }, 218 { 219 Mode: "ingress", 220 Target: 3003, 221 Protocol: "tcp", 222 }, 223 { 224 Mode: "ingress", 225 Target: 3004, 226 Protocol: "tcp", 227 }, 228 { 229 Mode: "ingress", 230 Target: 3005, 231 Protocol: "tcp", 232 }, 233 // "8000:8000", 234 { 235 Mode: "ingress", 236 Target: 8000, 237 Published: 8000, 238 Protocol: "tcp", 239 }, 240 // "9090-9091:8080-8081", 241 { 242 Mode: "ingress", 243 Target: 8080, 244 Published: 9090, 245 Protocol: "tcp", 246 }, 247 { 248 Mode: "ingress", 249 Target: 8081, 250 Published: 9091, 251 Protocol: "tcp", 252 }, 253 // "49100:22", 254 { 255 Mode: "ingress", 256 Target: 22, 257 Published: 49100, 258 Protocol: "tcp", 259 }, 260 // "127.0.0.1:8001:8001", 261 { 262 Mode: "ingress", 263 Target: 8001, 264 Published: 8001, 265 Protocol: "tcp", 266 }, 267 // "127.0.0.1:5000-5010:5000-5010", 268 { 269 Mode: "ingress", 270 Target: 5000, 271 Published: 5000, 272 Protocol: "tcp", 273 }, 274 { 275 Mode: "ingress", 276 Target: 5001, 277 Published: 5001, 278 Protocol: "tcp", 279 }, 280 { 281 Mode: "ingress", 282 Target: 5002, 283 Published: 5002, 284 Protocol: "tcp", 285 }, 286 { 287 Mode: "ingress", 288 Target: 5003, 289 Published: 5003, 290 Protocol: "tcp", 291 }, 292 { 293 Mode: "ingress", 294 Target: 5004, 295 Published: 5004, 296 Protocol: "tcp", 297 }, 298 { 299 Mode: "ingress", 300 Target: 5005, 301 Published: 5005, 302 Protocol: "tcp", 303 }, 304 { 305 Mode: "ingress", 306 Target: 5006, 307 Published: 5006, 308 Protocol: "tcp", 309 }, 310 { 311 Mode: "ingress", 312 Target: 5007, 313 Published: 5007, 314 Protocol: "tcp", 315 }, 316 { 317 Mode: "ingress", 318 Target: 5008, 319 Published: 5008, 320 Protocol: "tcp", 321 }, 322 { 323 Mode: "ingress", 324 Target: 5009, 325 Published: 5009, 326 Protocol: "tcp", 327 }, 328 { 329 Mode: "ingress", 330 Target: 5010, 331 Published: 5010, 332 Protocol: "tcp", 333 }, 334 }, 335 Privileged: true, 336 ReadOnly: true, 337 Restart: "always", 338 Secrets: []types.ServiceSecretConfig{ 339 { 340 Source: "secret1", 341 }, 342 { 343 Source: "secret2", 344 Target: "my_secret", 345 UID: "103", 346 GID: "103", 347 Mode: uint32Ptr(0o440), 348 }, 349 }, 350 SecurityOpt: []string{ 351 "label=level:s0:c100,c200", 352 "label=type:svirt_apache_t", 353 }, 354 StdinOpen: true, 355 StopSignal: "SIGUSR1", 356 StopGracePeriod: durationPtr(20 * time.Second), 357 Sysctls: map[string]string{ 358 "net.core.somaxconn": "1024", 359 "net.ipv4.tcp_syncookies": "0", 360 }, 361 Tmpfs: []string{"/run", "/tmp"}, 362 Tty: true, 363 Ulimits: map[string]*types.UlimitsConfig{ 364 "nproc": { 365 Single: 65535, 366 }, 367 "nofile": { 368 Soft: 20000, 369 Hard: 40000, 370 }, 371 }, 372 User: "someone", 373 Volumes: []types.ServiceVolumeConfig{ 374 {Target: "/var/lib/mysql", Type: "volume"}, 375 {Source: "/opt/data", Target: "/var/lib/mysql", Type: "bind"}, 376 {Source: workingDir, Target: "/code", Type: "bind"}, 377 {Source: workingDir + "/static", Target: "/var/www/html", Type: "bind"}, 378 {Source: homeDir + "/configs", Target: "/etc/configs/", Type: "bind", ReadOnly: true}, 379 {Source: "datavolume", Target: "/var/lib/mysql", Type: "volume"}, 380 {Source: workingDir + "/opt", Target: "/opt", Consistency: "cached", Type: "bind"}, 381 {Target: "/opt", Type: "tmpfs", Tmpfs: &types.ServiceVolumeTmpfs{ 382 Size: int64(10000), 383 }}, 384 {Source: "group:mygroup", Target: "/srv", Type: "cluster"}, 385 }, 386 WorkingDir: "/code", 387 }, 388 } 389 } 390 391 func networks() map[string]types.NetworkConfig { 392 return map[string]types.NetworkConfig{ 393 "some-network": {}, 394 395 "other-network": { 396 Driver: "overlay", 397 DriverOpts: map[string]string{ 398 "foo": "bar", 399 "baz": "1", 400 }, 401 Ipam: types.IPAMConfig{ 402 Driver: "overlay", 403 Config: []*types.IPAMPool{ 404 {Subnet: "172.16.238.0/24"}, 405 {Subnet: "2001:3984:3989::/64"}, 406 }, 407 }, 408 Labels: map[string]string{ 409 "foo": "bar", 410 }, 411 }, 412 413 "external-network": { 414 Name: "external-network", 415 External: types.External{External: true}, 416 }, 417 418 "other-external-network": { 419 Name: "my-cool-network", 420 External: types.External{External: true}, 421 Extras: map[string]any{ 422 "x-bar": "baz", 423 "x-foo": "bar", 424 }, 425 }, 426 } 427 } 428 429 func volumes() map[string]types.VolumeConfig { 430 return map[string]types.VolumeConfig{ 431 "some-volume": {}, 432 "other-volume": { 433 Driver: "flocker", 434 DriverOpts: map[string]string{ 435 "foo": "bar", 436 "baz": "1", 437 }, 438 Labels: map[string]string{ 439 "foo": "bar", 440 }, 441 }, 442 "another-volume": { 443 Name: "user_specified_name", 444 Driver: "vsphere", 445 DriverOpts: map[string]string{ 446 "foo": "bar", 447 "baz": "1", 448 }, 449 }, 450 "external-volume": { 451 Name: "external-volume", 452 External: types.External{External: true}, 453 }, 454 "other-external-volume": { 455 Name: "my-cool-volume", 456 External: types.External{External: true}, 457 }, 458 "external-volume3": { 459 Name: "this-is-volume3", 460 External: types.External{External: true}, 461 Extras: map[string]any{ 462 "x-bar": "baz", 463 "x-foo": "bar", 464 }, 465 }, 466 "cluster-volume": { 467 Driver: "my-csi-driver", 468 Spec: &types.ClusterVolumeSpec{ 469 Group: "mygroup", 470 AccessMode: &types.AccessMode{ 471 Scope: "single", 472 Sharing: "none", 473 BlockVolume: &types.BlockVolume{}, 474 }, 475 AccessibilityRequirements: &types.TopologyRequirement{ 476 Requisite: []types.Topology{ 477 { 478 Segments: types.Mapping{"region": "R1", "zone": "Z1"}, 479 }, 480 { 481 Segments: types.Mapping{"region": "R1", "zone": "Z2"}, 482 }, 483 }, 484 Preferred: []types.Topology{ 485 { 486 Segments: types.Mapping{"region": "R1", "zone": "Z1"}, 487 }, 488 }, 489 }, 490 CapacityRange: &types.CapacityRange{ 491 RequiredBytes: types.UnitBytes(1 * 1024 * 1024 * 1024), 492 LimitBytes: types.UnitBytes(8 * 1024 * 1024 * 1024), 493 }, 494 Secrets: []types.VolumeSecret{ 495 {Key: "mycsisecret", Secret: "secret1"}, 496 {Key: "mycsisecret2", Secret: "secret4"}, 497 }, 498 Availability: "active", 499 }, 500 }, 501 } 502 } 503 504 func configs(workingDir string) map[string]types.ConfigObjConfig { 505 return map[string]types.ConfigObjConfig{ 506 "config1": { 507 File: workingDir + "/config_data", 508 Labels: map[string]string{ 509 "foo": "bar", 510 }, 511 }, 512 "config2": { 513 Name: "my_config", 514 External: types.External{External: true}, 515 }, 516 "config3": { 517 Name: "config3", 518 External: types.External{External: true}, 519 }, 520 "config4": { 521 Name: "foo", 522 File: workingDir, 523 Extras: map[string]any{ 524 "x-bar": "baz", 525 "x-foo": "bar", 526 }, 527 }, 528 } 529 } 530 531 func secrets(workingDir string) map[string]types.SecretConfig { 532 return map[string]types.SecretConfig{ 533 "secret1": { 534 File: workingDir + "/secret_data", 535 Labels: map[string]string{ 536 "foo": "bar", 537 }, 538 }, 539 "secret2": { 540 Name: "my_secret", 541 External: types.External{External: true}, 542 }, 543 "secret3": { 544 Name: "secret3", 545 External: types.External{External: true}, 546 }, 547 "secret4": { 548 Name: "bar", 549 File: workingDir, 550 Extras: map[string]any{ 551 "x-bar": "baz", 552 "x-foo": "bar", 553 }, 554 }, 555 } 556 }