github.com/AliyunContainerService/cli@v0.0.0-20181009023821-814ced4b30d0/cli/compose/types/types.go (about) 1 package types 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "time" 7 ) 8 9 // UnsupportedProperties not yet supported by this implementation of the compose file 10 var UnsupportedProperties = []string{ 11 "build", 12 "cap_add", 13 "cap_drop", 14 "cgroup_parent", 15 "devices", 16 "domainname", 17 "external_links", 18 "ipc", 19 "links", 20 "mac_address", 21 "network_mode", 22 "pid", 23 "privileged", 24 "restart", 25 "security_opt", 26 "shm_size", 27 "sysctls", 28 "ulimits", 29 "userns_mode", 30 } 31 32 // DeprecatedProperties that were removed from the v3 format, but their 33 // use should not impact the behaviour of the application. 34 var DeprecatedProperties = map[string]string{ 35 "container_name": "Setting the container name is not supported.", 36 "expose": "Exposing ports is unnecessary - services on the same network can access each other's containers on any port.", 37 } 38 39 // ForbiddenProperties that are not supported in this implementation of the 40 // compose file. 41 var ForbiddenProperties = map[string]string{ 42 "extends": "Support for `extends` is not implemented yet.", 43 "volume_driver": "Instead of setting the volume driver on the service, define a volume using the top-level `volumes` option and specify the driver there.", 44 "volumes_from": "To share a volume between services, define it using the top-level `volumes` option and reference it from each service that shares it using the service-level `volumes` option.", 45 "cpu_quota": "Set resource limits using deploy.resources", 46 "cpu_shares": "Set resource limits using deploy.resources", 47 "cpuset": "Set resource limits using deploy.resources", 48 "mem_limit": "Set resource limits using deploy.resources", 49 "memswap_limit": "Set resource limits using deploy.resources", 50 } 51 52 // ConfigFile is a filename and the contents of the file as a Dict 53 type ConfigFile struct { 54 Filename string 55 Config map[string]interface{} 56 } 57 58 // ConfigDetails are the details about a group of ConfigFiles 59 type ConfigDetails struct { 60 Version string 61 WorkingDir string 62 ConfigFiles []ConfigFile 63 Environment map[string]string 64 } 65 66 // Duration is a thin wrapper around time.Duration with improved JSON marshalling 67 type Duration time.Duration 68 69 func (d Duration) String() string { 70 return time.Duration(d).String() 71 } 72 73 // ConvertDurationPtr converts a typedefined Duration pointer to a time.Duration pointer with the same value. 74 func ConvertDurationPtr(d *Duration) *time.Duration { 75 if d == nil { 76 return nil 77 } 78 res := time.Duration(*d) 79 return &res 80 } 81 82 // MarshalJSON makes Duration implement json.Marshaler 83 func (d Duration) MarshalJSON() ([]byte, error) { 84 return json.Marshal(d.String()) 85 } 86 87 // MarshalYAML makes Duration implement yaml.Marshaler 88 func (d Duration) MarshalYAML() (interface{}, error) { 89 return d.String(), nil 90 } 91 92 // LookupEnv provides a lookup function for environment variables 93 func (cd ConfigDetails) LookupEnv(key string) (string, bool) { 94 v, ok := cd.Environment[key] 95 return v, ok 96 } 97 98 // Config is a full compose file configuration 99 type Config struct { 100 Filename string `yaml:"-" json:"-"` 101 Version string `json:"version"` 102 Services Services `json:"services"` 103 Networks map[string]NetworkConfig `yaml:",omitempty" json:"networks,omitempty"` 104 Volumes map[string]VolumeConfig `yaml:",omitempty" json:"volumes,omitempty"` 105 Secrets map[string]SecretConfig `yaml:",omitempty" json:"secrets,omitempty"` 106 Configs map[string]ConfigObjConfig `yaml:",omitempty" json:"configs,omitempty"` 107 Extras map[string]interface{} `yaml:",inline", json:"-"` 108 } 109 110 // MarshalJSON makes Config implement json.Marshaler 111 func (c Config) MarshalJSON() ([]byte, error) { 112 m := map[string]interface{}{ 113 "version": c.Version, 114 "services": c.Services, 115 } 116 117 if len(c.Networks) > 0 { 118 m["networks"] = c.Networks 119 } 120 if len(c.Volumes) > 0 { 121 m["volumes"] = c.Volumes 122 } 123 if len(c.Secrets) > 0 { 124 m["secrets"] = c.Secrets 125 } 126 if len(c.Configs) > 0 { 127 m["configs"] = c.Configs 128 } 129 for k, v := range c.Extras { 130 m[k] = v 131 } 132 return json.Marshal(m) 133 } 134 135 // Services is a list of ServiceConfig 136 type Services []ServiceConfig 137 138 // MarshalYAML makes Services implement yaml.Marshaller 139 func (s Services) MarshalYAML() (interface{}, error) { 140 services := map[string]ServiceConfig{} 141 for _, service := range s { 142 services[service.Name] = service 143 } 144 return services, nil 145 } 146 147 // MarshalJSON makes Services implement json.Marshaler 148 func (s Services) MarshalJSON() ([]byte, error) { 149 data, err := s.MarshalYAML() 150 if err != nil { 151 return nil, err 152 } 153 return json.MarshalIndent(data, "", " ") 154 } 155 156 // ServiceConfig is the configuration of one service 157 type ServiceConfig struct { 158 Name string `yaml:"-" json:"-"` 159 160 Build BuildConfig `yaml:",omitempty" json:"build,omitempty"` 161 CapAdd []string `mapstructure:"cap_add" yaml:"cap_add,omitempty" json:"cap_add,omitempty"` 162 CapDrop []string `mapstructure:"cap_drop" yaml:"cap_drop,omitempty" json:"cap_drop,omitempty"` 163 CgroupParent string `mapstructure:"cgroup_parent" yaml:"cgroup_parent,omitempty" json:"cgroup_parent,omitempty"` 164 Command ShellCommand `yaml:",omitempty" json:"command,omitempty"` 165 Configs []ServiceConfigObjConfig `yaml:",omitempty" json:"configs,omitempty"` 166 ContainerName string `mapstructure:"container_name" yaml:"container_name,omitempty" json:"container_name,omitempty"` 167 CredentialSpec CredentialSpecConfig `mapstructure:"credential_spec" yaml:"credential_spec,omitempty" json:"credential_spec,omitempty"` 168 DependsOn []string `mapstructure:"depends_on" yaml:"depends_on,omitempty" json:"depends_on,omitempty"` 169 Deploy DeployConfig `yaml:",omitempty" json:"deploy,omitempty"` 170 Devices []string `yaml:",omitempty" json:"devices,omitempty"` 171 DNS StringList `yaml:",omitempty" json:"dns,omitempty"` 172 DNSSearch StringList `mapstructure:"dns_search" yaml:"dns_search,omitempty" json:"dns_search,omitempty"` 173 DomainName string `mapstructure:"domainname" yaml:"domainname,omitempty" json:"domainname,omitempty"` 174 Entrypoint ShellCommand `yaml:",omitempty" json:"entrypoint,omitempty"` 175 Environment MappingWithEquals `yaml:",omitempty" json:"environment,omitempty"` 176 EnvFile StringList `mapstructure:"env_file" yaml:"env_file,omitempty" json:"env_file,omitempty"` 177 Expose StringOrNumberList `yaml:",omitempty" json:"expose,omitempty"` 178 ExternalLinks []string `mapstructure:"external_links" yaml:"external_links,omitempty" json:"external_links,omitempty"` 179 ExtraHosts HostsList `mapstructure:"extra_hosts" yaml:"extra_hosts,omitempty" json:"extra_hosts,omitempty"` 180 Hostname string `yaml:",omitempty" json:"hostname,omitempty"` 181 HealthCheck *HealthCheckConfig `yaml:",omitempty" json:"healthcheck,omitempty"` 182 Image string `yaml:",omitempty" json:"image,omitempty"` 183 Init *bool `yaml:",omitempty" json:"init,omitempty"` 184 Ipc string `yaml:",omitempty" json:"ipc,omitempty"` 185 Isolation string `mapstructure:"isolation" yaml:"isolation,omitempty" json:"isolation,omitempty"` 186 Labels Labels `yaml:",omitempty" json:"labels,omitempty"` 187 Links []string `yaml:",omitempty" json:"links,omitempty"` 188 Logging *LoggingConfig `yaml:",omitempty" json:"logging,omitempty"` 189 MacAddress string `mapstructure:"mac_address" yaml:"mac_address,omitempty" json:"mac_address,omitempty"` 190 NetworkMode string `mapstructure:"network_mode" yaml:"network_mode,omitempty" json:"network_mode,omitempty"` 191 Networks map[string]*ServiceNetworkConfig `yaml:",omitempty" json:"networks,omitempty"` 192 Pid string `yaml:",omitempty" json:"pid,omitempty"` 193 Ports []ServicePortConfig `yaml:",omitempty" json:"ports,omitempty"` 194 Privileged bool `yaml:",omitempty" json:"privileged,omitempty"` 195 ReadOnly bool `mapstructure:"read_only" yaml:"read_only,omitempty" json:"read_only,omitempty"` 196 Restart string `yaml:",omitempty" json:"restart,omitempty"` 197 Secrets []ServiceSecretConfig `yaml:",omitempty" json:"secrets,omitempty"` 198 SecurityOpt []string `mapstructure:"security_opt" yaml:"security_opt,omitempty" json:"security_opt,omitempty"` 199 ShmSize string `mapstructure:"shm_size" yaml:"shm_size,omitempty" json:"shm_size,omitempty"` 200 StdinOpen bool `mapstructure:"stdin_open" yaml:"stdin_open,omitempty" json:"stdin_open,omitempty"` 201 StopGracePeriod *Duration `mapstructure:"stop_grace_period" yaml:"stop_grace_period,omitempty" json:"stop_grace_period,omitempty"` 202 StopSignal string `mapstructure:"stop_signal" yaml:"stop_signal,omitempty" json:"stop_signal,omitempty"` 203 Sysctls StringList `yaml:",omitempty" json:"sysctls,omitempty"` 204 Tmpfs StringList `yaml:",omitempty" json:"tmpfs,omitempty"` 205 Tty bool `mapstructure:"tty" yaml:"tty,omitempty" json:"tty,omitempty"` 206 Ulimits map[string]*UlimitsConfig `yaml:",omitempty" json:"ulimits,omitempty"` 207 User string `yaml:",omitempty" json:"user,omitempty"` 208 UserNSMode string `mapstructure:"userns_mode" yaml:"userns_mode,omitempty" json:"userns_mode,omitempty"` 209 Volumes []ServiceVolumeConfig `yaml:",omitempty" json:"volumes,omitempty"` 210 WorkingDir string `mapstructure:"working_dir" yaml:"working_dir,omitempty" json:"working_dir,omitempty"` 211 212 Extras map[string]interface{} `yaml:",inline" json:"-"` 213 } 214 215 // BuildConfig is a type for build 216 // using the same format at libcompose: https://github.com/docker/libcompose/blob/master/yaml/build.go#L12 217 type BuildConfig struct { 218 Context string `yaml:",omitempty" json:"context,omitempty"` 219 Dockerfile string `yaml:",omitempty" json:"dockerfile,omitempty"` 220 Args MappingWithEquals `yaml:",omitempty" json:"args,omitempty"` 221 Labels Labels `yaml:",omitempty" json:"labels,omitempty"` 222 CacheFrom StringList `mapstructure:"cache_from" yaml:"cache_from,omitempty" json:"cache_from,omitempty"` 223 Network string `yaml:",omitempty" json:"network,omitempty"` 224 Target string `yaml:",omitempty" json:"target,omitempty"` 225 } 226 227 // ShellCommand is a string or list of string args 228 type ShellCommand []string 229 230 // StringList is a type for fields that can be a string or list of strings 231 type StringList []string 232 233 // StringOrNumberList is a type for fields that can be a list of strings or 234 // numbers 235 type StringOrNumberList []string 236 237 // MappingWithEquals is a mapping type that can be converted from a list of 238 // key[=value] strings. 239 // For the key with an empty value (`key=`), the mapped value is set to a pointer to `""`. 240 // For the key without value (`key`), the mapped value is set to nil. 241 type MappingWithEquals map[string]*string 242 243 // Labels is a mapping type for labels 244 type Labels map[string]string 245 246 // MappingWithColon is a mapping type that can be converted from a list of 247 // 'key: value' strings 248 type MappingWithColon map[string]string 249 250 // HostsList is a list of colon-separated host-ip mappings 251 type HostsList []string 252 253 // LoggingConfig the logging configuration for a service 254 type LoggingConfig struct { 255 Driver string `yaml:",omitempty" json:"driver,omitempty"` 256 Options map[string]string `yaml:",omitempty" json:"options,omitempty"` 257 } 258 259 // DeployConfig the deployment configuration for a service 260 type DeployConfig struct { 261 Mode string `yaml:",omitempty" json:"mode,omitempty"` 262 Replicas *uint64 `yaml:",omitempty" json:"replicas,omitempty"` 263 Labels Labels `yaml:",omitempty" json:"labels,omitempty"` 264 UpdateConfig *UpdateConfig `mapstructure:"update_config" yaml:"update_config,omitempty" json:"update_config,omitempty"` 265 RollbackConfig *UpdateConfig `mapstructure:"rollback_config" yaml:"rollback_config,omitempty" json:"rollback_config,omitempty"` 266 Resources Resources `yaml:",omitempty" json:"resources,omitempty"` 267 RestartPolicy *RestartPolicy `mapstructure:"restart_policy" yaml:"restart_policy,omitempty" json:"restart_policy,omitempty"` 268 Placement Placement `yaml:",omitempty" json:"placement,omitempty"` 269 EndpointMode string `mapstructure:"endpoint_mode" yaml:"endpoint_mode,omitempty" json:"endpoint_mode,omitempty"` 270 } 271 272 // HealthCheckConfig the healthcheck configuration for a service 273 type HealthCheckConfig struct { 274 Test HealthCheckTest `yaml:",omitempty" json:"test,omitempty"` 275 Timeout *Duration `yaml:",omitempty" json:"timeout,omitempty"` 276 Interval *Duration `yaml:",omitempty" json:"interval,omitempty"` 277 Retries *uint64 `yaml:",omitempty" json:"retries,omitempty"` 278 StartPeriod *Duration `mapstructure:"start_period" yaml:"start_period,omitempty" json:"start_period,omitempty"` 279 Disable bool `yaml:",omitempty" json:"disable,omitempty"` 280 } 281 282 // HealthCheckTest is the command run to test the health of a service 283 type HealthCheckTest []string 284 285 // UpdateConfig the service update configuration 286 type UpdateConfig struct { 287 Parallelism *uint64 `yaml:",omitempty" json:"parallelism,omitempty"` 288 Delay Duration `yaml:",omitempty" json:"delay,omitempty"` 289 FailureAction string `mapstructure:"failure_action" yaml:"failure_action,omitempty" json:"failure_action,omitempty"` 290 Monitor Duration `yaml:",omitempty" json:"monitor,omitempty"` 291 MaxFailureRatio float32 `mapstructure:"max_failure_ratio" yaml:"max_failure_ratio,omitempty" json:"max_failure_ratio,omitempty"` 292 Order string `yaml:",omitempty" json:"order,omitempty"` 293 } 294 295 // Resources the resource limits and reservations 296 type Resources struct { 297 Limits *Resource `yaml:",omitempty" json:"limits,omitempty"` 298 Reservations *Resource `yaml:",omitempty" json:"reservations,omitempty"` 299 } 300 301 // Resource is a resource to be limited or reserved 302 type Resource struct { 303 // TODO: types to convert from units and ratios 304 NanoCPUs string `mapstructure:"cpus" yaml:"cpus,omitempty" json:"cpus,omitempty"` 305 MemoryBytes UnitBytes `mapstructure:"memory" yaml:"memory,omitempty" json:"memory,omitempty"` 306 GenericResources []GenericResource `mapstructure:"generic_resources" yaml:"generic_resources,omitempty" json:"generic_resources,omitempty"` 307 } 308 309 // GenericResource represents a "user defined" resource which can 310 // only be an integer (e.g: SSD=3) for a service 311 type GenericResource struct { 312 DiscreteResourceSpec *DiscreteGenericResource `mapstructure:"discrete_resource_spec" yaml:"discrete_resource_spec,omitempty" json:"discrete_resource_spec,omitempty"` 313 } 314 315 // DiscreteGenericResource represents a "user defined" resource which is defined 316 // as an integer 317 // "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...) 318 // Value is used to count the resource (SSD=5, HDD=3, ...) 319 type DiscreteGenericResource struct { 320 Kind string `json:"kind"` 321 Value int64 `json:"value"` 322 } 323 324 // UnitBytes is the bytes type 325 type UnitBytes int64 326 327 // MarshalYAML makes UnitBytes implement yaml.Marshaller 328 func (u UnitBytes) MarshalYAML() (interface{}, error) { 329 return fmt.Sprintf("%d", u), nil 330 } 331 332 // MarshalJSON makes UnitBytes implement json.Marshaler 333 func (u UnitBytes) MarshalJSON() ([]byte, error) { 334 return []byte(fmt.Sprintf(`"%d"`, u)), nil 335 } 336 337 // RestartPolicy the service restart policy 338 type RestartPolicy struct { 339 Condition string `yaml:",omitempty" json:"condition,omitempty"` 340 Delay *Duration `yaml:",omitempty" json:"delay,omitempty"` 341 MaxAttempts *uint64 `mapstructure:"max_attempts" yaml:"max_attempts,omitempty" json:"max_attempts,omitempty"` 342 Window *Duration `yaml:",omitempty" json:"window,omitempty"` 343 } 344 345 // Placement constraints for the service 346 type Placement struct { 347 Constraints []string `yaml:",omitempty" json:"constraints,omitempty"` 348 Preferences []PlacementPreferences `yaml:",omitempty" json:"preferences,omitempty"` 349 } 350 351 // PlacementPreferences is the preferences for a service placement 352 type PlacementPreferences struct { 353 Spread string `yaml:",omitempty" json:"spread,omitempty"` 354 } 355 356 // ServiceNetworkConfig is the network configuration for a service 357 type ServiceNetworkConfig struct { 358 Aliases []string `yaml:",omitempty" json:"aliases,omitempty"` 359 Ipv4Address string `mapstructure:"ipv4_address" yaml:"ipv4_address,omitempty" json:"ipv4_address,omitempty"` 360 Ipv6Address string `mapstructure:"ipv6_address" yaml:"ipv6_address,omitempty" json:"ipv6_address,omitempty"` 361 } 362 363 // ServicePortConfig is the port configuration for a service 364 type ServicePortConfig struct { 365 Mode string `yaml:",omitempty" json:"mode,omitempty"` 366 Target uint32 `yaml:",omitempty" json:"target,omitempty"` 367 Published uint32 `yaml:",omitempty" json:"published,omitempty"` 368 Protocol string `yaml:",omitempty" json:"protocol,omitempty"` 369 } 370 371 // ServiceVolumeConfig are references to a volume used by a service 372 type ServiceVolumeConfig struct { 373 Type string `yaml:",omitempty" json:"type,omitempty"` 374 Source string `yaml:",omitempty" json:"source,omitempty"` 375 Target string `yaml:",omitempty" json:"target,omitempty"` 376 ReadOnly bool `mapstructure:"read_only" yaml:"read_only,omitempty" json:"read_only,omitempty"` 377 Consistency string `yaml:",omitempty" json:"consistency,omitempty"` 378 Bind *ServiceVolumeBind `yaml:",omitempty" json:"bind,omitempty"` 379 Volume *ServiceVolumeVolume `yaml:",omitempty" json:"volume,omitempty"` 380 Tmpfs *ServiceVolumeTmpfs `yaml:",omitempty" json:"tmpfs,omitempty"` 381 } 382 383 // ServiceVolumeBind are options for a service volume of type bind 384 type ServiceVolumeBind struct { 385 Propagation string `yaml:",omitempty" json:"propagation,omitempty"` 386 } 387 388 // ServiceVolumeVolume are options for a service volume of type volume 389 type ServiceVolumeVolume struct { 390 NoCopy bool `mapstructure:"nocopy" yaml:"nocopy,omitempty" json:"nocopy,omitempty"` 391 } 392 393 // ServiceVolumeTmpfs are options for a service volume of type tmpfs 394 type ServiceVolumeTmpfs struct { 395 Size int64 `yaml:",omitempty" json:"size,omitempty"` 396 } 397 398 // FileReferenceConfig for a reference to a swarm file object 399 type FileReferenceConfig struct { 400 Source string `yaml:",omitempty" json:"source,omitempty"` 401 Target string `yaml:",omitempty" json:"target,omitempty"` 402 UID string `yaml:",omitempty" json:"uid,omitempty"` 403 GID string `yaml:",omitempty" json:"gid,omitempty"` 404 Mode *uint32 `yaml:",omitempty" json:"mode,omitempty"` 405 } 406 407 // ServiceConfigObjConfig is the config obj configuration for a service 408 type ServiceConfigObjConfig FileReferenceConfig 409 410 // ServiceSecretConfig is the secret configuration for a service 411 type ServiceSecretConfig FileReferenceConfig 412 413 // UlimitsConfig the ulimit configuration 414 type UlimitsConfig struct { 415 Single int `yaml:",omitempty" json:"single,omitempty"` 416 Soft int `yaml:",omitempty" json:"soft,omitempty"` 417 Hard int `yaml:",omitempty" json:"hard,omitempty"` 418 } 419 420 // MarshalYAML makes UlimitsConfig implement yaml.Marshaller 421 func (u *UlimitsConfig) MarshalYAML() (interface{}, error) { 422 if u.Single != 0 { 423 return u.Single, nil 424 } 425 return u, nil 426 } 427 428 // MarshalJSON makes UlimitsConfig implement json.Marshaller 429 func (u *UlimitsConfig) MarshalJSON() ([]byte, error) { 430 if u.Single != 0 { 431 return json.Marshal(u.Single) 432 } 433 // Pass as a value to avoid re-entering this method and use the default implementation 434 return json.Marshal(*u) 435 } 436 437 // NetworkConfig for a network 438 type NetworkConfig struct { 439 Name string `yaml:",omitempty" json:"name,omitempty"` 440 Driver string `yaml:",omitempty" json:"driver,omitempty"` 441 DriverOpts map[string]string `mapstructure:"driver_opts" yaml:"driver_opts,omitempty" json:"driver_opts,omitempty"` 442 Ipam IPAMConfig `yaml:",omitempty" json:"ipam,omitempty"` 443 External External `yaml:",omitempty" json:"external,omitempty"` 444 Internal bool `yaml:",omitempty" json:"internal,omitempty"` 445 Attachable bool `yaml:",omitempty" json:"attachable,omitempty"` 446 Labels Labels `yaml:",omitempty" json:"labels,omitempty"` 447 Extras map[string]interface{} `yaml:",inline" json:"-"` 448 } 449 450 // IPAMConfig for a network 451 type IPAMConfig struct { 452 Driver string `yaml:",omitempty" json:"driver,omitempty"` 453 Config []*IPAMPool `yaml:",omitempty" json:"config,omitempty"` 454 } 455 456 // IPAMPool for a network 457 type IPAMPool struct { 458 Subnet string `yaml:",omitempty" json:"subnet,omitempty"` 459 } 460 461 // VolumeConfig for a volume 462 type VolumeConfig struct { 463 Name string `yaml:",omitempty" json:"name,omitempty"` 464 Driver string `yaml:",omitempty" json:"driver,omitempty"` 465 DriverOpts map[string]string `mapstructure:"driver_opts" yaml:"driver_opts,omitempty" json:"driver_opts,omitempty"` 466 External External `yaml:",omitempty" json:"external,omitempty"` 467 Labels Labels `yaml:",omitempty" json:"labels,omitempty"` 468 Extras map[string]interface{} `yaml:",inline" json:"-"` 469 } 470 471 // External identifies a Volume or Network as a reference to a resource that is 472 // not managed, and should already exist. 473 // External.name is deprecated and replaced by Volume.name 474 type External struct { 475 Name string `yaml:",omitempty" json:"name,omitempty"` 476 External bool `yaml:",omitempty" json:"external,omitempty"` 477 } 478 479 // MarshalYAML makes External implement yaml.Marshaller 480 func (e External) MarshalYAML() (interface{}, error) { 481 if e.Name == "" { 482 return e.External, nil 483 } 484 return External{Name: e.Name}, nil 485 } 486 487 // MarshalJSON makes External implement json.Marshaller 488 func (e External) MarshalJSON() ([]byte, error) { 489 if e.Name == "" { 490 return []byte(fmt.Sprintf("%v", e.External)), nil 491 } 492 return []byte(fmt.Sprintf(`{"name": %q}`, e.Name)), nil 493 } 494 495 // CredentialSpecConfig for credential spec on Windows 496 type CredentialSpecConfig struct { 497 File string `yaml:",omitempty" json:"file,omitempty"` 498 Registry string `yaml:",omitempty" json:"registry,omitempty"` 499 } 500 501 // FileObjectConfig is a config type for a file used by a service 502 type FileObjectConfig struct { 503 Name string `yaml:",omitempty" json:"name,omitempty"` 504 File string `yaml:",omitempty" json:"file,omitempty"` 505 External External `yaml:",omitempty" json:"external,omitempty"` 506 Labels Labels `yaml:",omitempty" json:"labels,omitempty"` 507 Extras map[string]interface{} `yaml:",inline" json:"-"` 508 } 509 510 // SecretConfig for a secret 511 type SecretConfig FileObjectConfig 512 513 // ConfigObjConfig is the config for the swarm "Config" object 514 type ConfigObjConfig FileObjectConfig