1syntax = "proto3"; 2 3package docker.swarmkit.v1; 4 5import "google/protobuf/timestamp.proto"; 6import "google/protobuf/duration.proto"; 7import "gogoproto/gogo.proto"; 8 9// This file contains types that are common to objects and spec or that are not 10// considered first-class within the cluster object-model. 11 12// Version tracks the last time an object in the store was updated. 13message Version { 14 uint64 index = 1; 15} 16 17message IndexEntry { 18 string key = 1; 19 string val = 2; 20} 21 22// Annotations provide useful information to identify API objects. They are 23// common to all API specs. 24message Annotations { 25 string name = 1; 26 map<string, string> labels = 2; 27 28 // Indices provides keys and values for indexing this object. 29 // A single key may have multiple values. 30 repeated IndexEntry indices = 4 [(gogoproto.nullable) = false]; 31} 32 33// NamedGenericResource represents a "user defined" resource which is defined 34// as a string. 35// "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...) 36// Value is used to identify the resource (GPU="UUID-1", FPGA="/dev/sdb5", ...) 37message NamedGenericResource { 38 string kind = 1; 39 string value = 2; 40} 41 42// DiscreteGenericResource represents a "user defined" resource which is defined 43// as an integer 44// "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...) 45// Value is used to count the resource (SSD=5, HDD=3, ...) 46message DiscreteGenericResource { 47 string kind = 1; 48 int64 value = 2; 49} 50 51// GenericResource represents a "user defined" resource which can 52// be either an integer (e.g: SSD=3) or a string (e.g: SSD=sda1) 53message GenericResource { 54 oneof resource { 55 NamedGenericResource named_resource_spec = 1; 56 DiscreteGenericResource discrete_resource_spec = 2; 57 } 58} 59 60enum ResourceType { 61 TASK = 0; 62 SECRET = 1; 63 CONFIG = 2; 64} 65 66message Resources { 67 // Amount of CPUs (e.g. 2000000000 = 2 CPU cores) 68 int64 nano_cpus = 1 [(gogoproto.customname) = "NanoCPUs"]; 69 70 // Amount of memory in bytes. 71 int64 memory_bytes = 2; 72 73 // User specified resource (e.g: bananas=2;apple={red,yellow,green}) 74 repeated GenericResource generic = 3; 75} 76 77message ResourceRequirements { 78 Resources limits = 1; 79 Resources reservations = 2; 80} 81 82message Platform { 83 // Architecture (e.g. x86_64) 84 string architecture = 1; 85 86 // Operating System (e.g. linux) 87 string os = 2 [(gogoproto.customname) = "OS"]; 88} 89 90// PluginDescription describes an engine plugin. 91message PluginDescription { 92 // Type of plugin. Canonical values for existing types are 93 // Volume, Network, and Authorization. More types could be 94 // supported in the future. 95 string type = 1; 96 97 // Name of the plugin 98 string name = 2; 99} 100 101message EngineDescription { 102 // Docker daemon version running on the node. 103 string engine_version = 1; 104 105 // Labels attached to the engine. 106 map<string, string> labels = 2; 107 108 // Volume, Network, and Auth plugins 109 repeated PluginDescription plugins = 3 [(gogoproto.nullable) = false]; 110} 111 112message NodeDescription { 113 // Hostname of the node as reported by the agent. 114 // This is different from spec.meta.name which is user-defined. 115 string hostname = 1; 116 117 // Platform of the node. 118 Platform platform = 2; 119 120 // Total resources on the node. 121 Resources resources = 3; 122 123 // Information about the Docker Engine on the node. 124 EngineDescription engine = 4; 125 126 // Information on the node's TLS setup 127 NodeTLSInfo tls_info = 5 [(gogoproto.customname) = "TLSInfo"]; 128 129 // FIPS indicates whether the node has FIPS-enabled 130 bool fips = 6 [(gogoproto.customname) = "FIPS"]; 131} 132 133message NodeTLSInfo { 134 // Information about which root certs the node trusts 135 bytes trust_root = 1; 136 137 // Information about the node's current TLS certificate 138 bytes cert_issuer_subject = 2; 139 bytes cert_issuer_public_key = 3; 140} 141 142message RaftMemberStatus { 143 bool leader = 1; 144 145 enum Reachability { 146 // Unknown indicates that the manager state cannot be resolved 147 UNKNOWN = 0; 148 149 // Unreachable indicates that the node cannot be contacted by other 150 // raft cluster members. 151 UNREACHABLE = 1; 152 153 // Reachable indicates that the node is healthy and reachable 154 // by other members. 155 REACHABLE = 2; 156 } 157 158 Reachability reachability = 2; 159 string message = 3; 160} 161 162message NodeStatus { 163 // TODO(aluzzardi) These should be using `gogoproto.enumvalue_customname`. 164 enum State { 165 // Unknown indicates the node state cannot be resolved. 166 UNKNOWN = 0; 167 168 // Down indicates the node is down. 169 DOWN = 1; 170 171 // Ready indicates the node is ready to accept tasks. 172 READY = 2; 173 174 // Disconnected indicates the node is currently trying to find new manager. 175 DISCONNECTED = 3; 176 } 177 178 State state = 1; 179 string message = 2; 180 // Addr is the node's IP address as observed by the manager 181 string addr = 3; 182} 183 184message Image { 185 // reference is a docker image reference. This can include a rpository, tag 186 // or be fully qualified witha digest. The format is specified in the 187 // distribution/reference package. 188 string reference = 1; 189} 190 191// Mount describes volume mounts for a container. 192// 193// The Mount type follows the structure of the mount syscall, including a type, 194// source, target. Top-level flags, such as writable, are common to all kinds 195// of mounts, where we also provide options that are specific to a type of 196// mount. This corresponds to flags and data, respectively, in the syscall. 197message Mount { 198 enum Type { 199 option (gogoproto.goproto_enum_prefix) = false; 200 option (gogoproto.enum_customname) = "MountType"; 201 202 BIND = 0 [(gogoproto.enumvalue_customname) = "MountTypeBind"]; // Bind mount host dir 203 VOLUME = 1 [(gogoproto.enumvalue_customname) = "MountTypeVolume"]; // Remote storage volumes 204 TMPFS = 2 [(gogoproto.enumvalue_customname) = "MountTypeTmpfs"]; // Mount a tmpfs 205 } 206 207 // Type defines the nature of the mount. 208 Type type = 1; 209 210 // Source specifies the name of the mount. Depending on mount type, this 211 // may be a volume name or a host path, or even ignored. 212 string source = 2; 213 214 // Target path in container 215 string target = 3; 216 217 // ReadOnly should be set to true if the mount should not be writable. 218 bool readonly = 4 [(gogoproto.customname) = "ReadOnly"]; 219 220 // Consistency indicates the tolerable level of file system consistency 221 enum Consistency { 222 option (gogoproto.goproto_enum_prefix) = false; 223 option (gogoproto.enum_customname) = "MountConsistency"; 224 225 DEFAULT = 0 [(gogoproto.enumvalue_customname) = "MountConsistencyDefault"]; 226 CONSISTENT = 1 [(gogoproto.enumvalue_customname) = "MountConsistencyFull"]; 227 CACHED = 2 [(gogoproto.enumvalue_customname) = "MountConsistencyCached"]; 228 DELEGATED = 3 [(gogoproto.enumvalue_customname) = "MountConsistencyDelegated"]; 229 } 230 Consistency consistency = 8; 231 232 // BindOptions specifies options that are specific to a bind mount. 233 message BindOptions { 234 enum Propagation { 235 option (gogoproto.goproto_enum_prefix) = false; 236 option (gogoproto.enum_customname) = "MountPropagation"; 237 238 RPRIVATE = 0 [(gogoproto.enumvalue_customname) = "MountPropagationRPrivate"]; 239 PRIVATE = 1 [(gogoproto.enumvalue_customname) = "MountPropagationPrivate"]; 240 RSHARED = 2 [(gogoproto.enumvalue_customname) = "MountPropagationRShared"]; 241 SHARED = 3 [(gogoproto.enumvalue_customname) = "MountPropagationShared"]; 242 RSLAVE = 4 [(gogoproto.enumvalue_customname) = "MountPropagationRSlave"]; 243 SLAVE = 5 [(gogoproto.enumvalue_customname) = "MountPropagationSlave"]; 244 } 245 246 // Propagation mode of mount. 247 Propagation propagation = 1; 248 } 249 250 // VolumeOptions contains parameters for mounting the volume. 251 message VolumeOptions { 252 // nocopy prevents automatic copying of data to the volume with data from target 253 bool nocopy = 1 [(gogoproto.customname) = "NoCopy"]; 254 255 // labels to apply to the volume if creating 256 map<string, string> labels = 2; 257 258 // DriverConfig specifies the options that may be passed to the driver 259 // if the volume is created. 260 // 261 // If this is empty, no volume will be created if the volume is missing. 262 Driver driver_config = 3; 263 } 264 265 message TmpfsOptions { 266 // Size sets the size of the tmpfs, in bytes. 267 // 268 // This will be converted to an operating system specific value 269 // depending on the host. For example, on linux, it will be convered to 270 // use a 'k', 'm' or 'g' syntax. BSD, though not widely supported with 271 // docker, uses a straight byte value. 272 // 273 // Percentages are not supported. 274 int64 size_bytes = 1; 275 276 // Mode of the tmpfs upon creation 277 uint32 mode = 2 [(gogoproto.customtype) = "os.FileMode", (gogoproto.nullable) = false]; 278 279 // TODO(stevvooe): There are several more tmpfs flags, specified in the 280 // daemon, that are accepted. Only the most basic are added for now. 281 // 282 // From docker/docker/pkg/mount/flags.go: 283 // 284 // var validFlags = map[string]bool{ 285 // "": true, 286 // "size": true, X 287 // "mode": true, X 288 // "uid": true, 289 // "gid": true, 290 // "nr_inodes": true, 291 // "nr_blocks": true, 292 // "mpol": true, 293 // } 294 // 295 // Some of these may be straightforward to add, but others, such as 296 // uid/gid have implications in a clustered system. 297 } 298 299 // Depending on type, one of bind_options or volumes_options will be set. 300 301 // BindOptions configures properties of a bind mount type. 302 // 303 // For mounts of type bind, the source must be an absolute host path. 304 BindOptions bind_options = 5; 305 306 // VolumeOptions configures the properties specific to a volume mount type. 307 // 308 // For mounts of type volume, the source will be used as the volume name. 309 VolumeOptions volume_options = 6; 310 311 // TmpfsOptions allows one to set options for mounting a temporary 312 // filesystem. 313 // 314 // The source field will be ignored when using mounts of type tmpfs. 315 TmpfsOptions tmpfs_options = 7; 316 317 // TODO(stevvooe): It be better to use a oneof field above, although the 318 // type is enough to make the decision, while being primary to the 319 // datastructure. 320} 321 322message RestartPolicy { 323 enum RestartCondition { 324 option (gogoproto.goproto_enum_prefix) = false; 325 option (gogoproto.enum_customname) = "RestartCondition"; 326 NONE = 0 [(gogoproto.enumvalue_customname) = "RestartOnNone"]; 327 ON_FAILURE = 1 [(gogoproto.enumvalue_customname) = "RestartOnFailure"]; 328 ANY = 2 [(gogoproto.enumvalue_customname) = "RestartOnAny"]; 329 } 330 331 RestartCondition condition = 1; 332 333 // Delay between restart attempts 334 // Note: can't use stdduration because this field needs to be nullable. 335 google.protobuf.Duration delay = 2; 336 337 // MaxAttempts is the maximum number of restarts to attempt on an 338 // instance before giving up. Ignored if 0. 339 uint64 max_attempts = 3; 340 341 // Window is the time window used to evaluate the restart policy. 342 // The time window is unbounded if this is 0. 343 // Note: can't use stdduration because this field needs to be nullable. 344 google.protobuf.Duration window = 4; 345} 346 347// UpdateConfig specifies the rate and policy of updates. 348// TODO(aluzzardi): Consider making this a oneof with RollingStrategy and LockstepStrategy. 349message UpdateConfig { 350 // Maximum number of tasks to be updated in one iteration. 351 // 0 means unlimited parallelism. 352 uint64 parallelism = 1; 353 354 // Amount of time between updates. 355 google.protobuf.Duration delay = 2 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false]; 356 357 enum FailureAction { 358 PAUSE = 0; 359 CONTINUE = 1; 360 ROLLBACK = 2; 361 } 362 363 // FailureAction is the action to take when an update failures. 364 FailureAction failure_action = 3; 365 366 // Monitor indicates how long to monitor a task for failure after it is 367 // created. If the task fails by ending up in one of the states 368 // REJECTED, COMPLETED, or FAILED, within Monitor from its creation, 369 // this counts as a failure. If it fails after Monitor, it does not 370 // count as a failure. If Monitor is unspecified, a default value will 371 // be used. 372 // Note: can't use stdduration because this field needs to be nullable. 373 google.protobuf.Duration monitor = 4; 374 375 // MaxFailureRatio is the fraction of tasks that may fail during 376 // an update before the failure action is invoked. Any task created by 377 // the current update which ends up in one of the states REJECTED, 378 // COMPLETED or FAILED within Monitor from its creation counts as a 379 // failure. The number of failures is divided by the number of tasks 380 // being updated, and if this fraction is greater than 381 // MaxFailureRatio, the failure action is invoked. 382 // 383 // If the failure action is CONTINUE, there is no effect. 384 // If the failure action is PAUSE, no more tasks will be updated until 385 // another update is started. 386 // If the failure action is ROLLBACK, the orchestrator will attempt to 387 // roll back to the previous service spec. If the MaxFailureRatio 388 // threshold is hit during the rollback, the rollback will pause. 389 float max_failure_ratio = 5; 390 391 // UpdateOrder controls the order of operations when rolling out an 392 // updated task. Either the old task is shut down before the new task 393 // is started, or the new task is started before the old task is shut 394 // down. 395 enum UpdateOrder { 396 STOP_FIRST = 0; 397 START_FIRST = 1; 398 } 399 400 UpdateOrder order = 6; 401} 402 403// UpdateStatus is the status of an update in progress. 404message UpdateStatus { 405 enum UpdateState { 406 UNKNOWN = 0; 407 UPDATING = 1; 408 PAUSED = 2; 409 COMPLETED = 3; 410 ROLLBACK_STARTED = 4; 411 ROLLBACK_PAUSED = 5; // if a rollback fails 412 ROLLBACK_COMPLETED = 6; 413 } 414 415 // State is the state of this update. It indicates whether the 416 // update is in progress, completed, paused, rolling back, or 417 // finished rolling back. 418 UpdateState state = 1; 419 420 // StartedAt is the time at which the update was started. 421 // Note: can't use stdtime because this field is nullable. 422 google.protobuf.Timestamp started_at = 2; 423 424 // CompletedAt is the time at which the update completed successfully, 425 // paused, or finished rolling back. 426 // Note: can't use stdtime because this field is nullable. 427 google.protobuf.Timestamp completed_at = 3; 428 429 // TODO(aaronl): Consider adding a timestamp showing when the most 430 // recent task update took place. Currently, this is nontrivial 431 // because each service update kicks off a replacement update, so 432 // updating the service object with a timestamp at every step along 433 // the rolling update would cause the rolling update to be constantly 434 // restarted. 435 436 // Message explains how the update got into its current state. For 437 // example, if the update is paused, it will explain what is preventing 438 // the update from proceeding (typically the failure of a task to start up 439 // when OnFailure is PAUSE). 440 string message = 4; 441} 442 443// TaskState enumerates the states that a task progresses through within an 444// agent. States are designed to be monotonically increasing, such that if two 445// states are seen by a task, the greater of the new represents the true state. 446 447// Only the manager create a NEW task, and move the task to PENDING and ASSIGNED. 448// Afterward, the manager must rely on the agent to update the task status 449// (pre-run: preparing, ready, starting; 450// running; 451// end-state: complete, shutdown, failed, rejected) 452enum TaskState { 453 // TODO(aluzzardi): Move it back into `TaskStatus` because of the naming 454 // collisions of enums. 455 456 option (gogoproto.goproto_enum_prefix) = false; 457 option (gogoproto.enum_customname) = "TaskState"; 458 NEW = 0 [(gogoproto.enumvalue_customname)="TaskStateNew"]; 459 PENDING = 64 [(gogoproto.enumvalue_customname)="TaskStatePending"]; // waiting for scheduling decision 460 ASSIGNED = 192 [(gogoproto.enumvalue_customname)="TaskStateAssigned"]; 461 ACCEPTED = 256 [(gogoproto.enumvalue_customname)="TaskStateAccepted"]; // task has been accepted by an agent. 462 PREPARING = 320 [(gogoproto.enumvalue_customname)="TaskStatePreparing"]; 463 READY = 384 [(gogoproto.enumvalue_customname)="TaskStateReady"]; 464 STARTING = 448 [(gogoproto.enumvalue_customname)="TaskStateStarting"]; 465 RUNNING = 512 [(gogoproto.enumvalue_customname)="TaskStateRunning"]; 466 COMPLETE = 576 [(gogoproto.enumvalue_customname)="TaskStateCompleted"]; // successful completion of task (not error code, just ran) 467 SHUTDOWN = 640 [(gogoproto.enumvalue_customname)="TaskStateShutdown"]; // orchestrator requested shutdown 468 FAILED = 704 [(gogoproto.enumvalue_customname)="TaskStateFailed"]; // task execution failed with error 469 // TaskStateRejected means a task never ran, for instance if something about 470 // the environment failed (e.g. setting up a port on that node failed). 471 REJECTED = 768 [(gogoproto.enumvalue_customname)="TaskStateRejected"]; // task could not be executed here. 472 // TaskStateRemove is used to correctly handle service deletions and scale 473 // downs. This allows us to keep track of tasks that have been marked for 474 // deletion, but can't yet be removed because the agent is in the process of 475 // shutting them down. Once the agent has shut down tasks with desired state 476 // REMOVE, the task reaper is responsible for removing them. 477 REMOVE = 800 [(gogoproto.enumvalue_customname)="TaskStateRemove"]; 478 // TaskStateOrphaned is used to free up resources associated with service 479 // tasks on unresponsive nodes without having to delete those tasks. This 480 // state is directly assigned to the task by the orchestrator. 481 ORPHANED = 832 [(gogoproto.enumvalue_customname)="TaskStateOrphaned"]; 482 483 // NOTE(stevvooe): The state of a task is actually a lamport clock, in that 484 // given two observations, the greater of the two can be considered 485 // correct. To enforce this, we only allow tasks to proceed to a greater 486 // state. 487 // 488 // A byproduct of this design decision is that we must also maintain this 489 // invariant in the protobuf enum values, such that when comparing two 490 // values, the one with the greater value is also the greater state. 491 // 492 // Because we may want to add intervening states a later date, we've left 493 // 64 spaces between each one. This should allow us to make 5 or 6 494 // insertions between each state if we find that we made a mistake and need 495 // another state. 496 // 497 // Remove this message when the states are deemed perfect. 498} 499 500// Container specific status. 501message ContainerStatus { 502 string container_id = 1; 503 504 int32 pid = 2 [(gogoproto.customname) = "PID"]; 505 int32 exit_code = 3; 506} 507 508// PortStatus specifies the actual allocated runtime state of a list 509// of port configs. 510message PortStatus { 511 repeated PortConfig ports = 1; 512} 513 514message TaskStatus { 515 // Note: can't use stdtime because this field is nullable. 516 google.protobuf.Timestamp timestamp = 1; 517 518 // State expresses the current state of the task. 519 TaskState state = 2; 520 521 // Message reports a message for the task status. This should provide a 522 // human readable message that can point to how the task actually arrived 523 // at a current state. 524 // 525 // As a convention, we place the a small message here that led to the 526 // current state. For example, if the task is in ready, because it was 527 // prepared, we'd place "prepared" in this field. If we skipped preparation 528 // because the task is prepared, we would put "already prepared" in this 529 // field. 530 string message = 3; 531 532 // Err is set if the task is in an error state, or is unable to 533 // progress from an earlier state because a precondition is 534 // unsatisfied. 535 // 536 // The following states should report a companion error: 537 // 538 // FAILED, REJECTED 539 // 540 // In general, messages that should be surfaced to users belong in the 541 // Err field, and notes on routine state transitions belong in Message. 542 // 543 // TODO(stevvooe) Integrate this field with the error interface. 544 string err = 4; 545 546 // Container status contains container specific status information. 547 oneof runtime_status { 548 ContainerStatus container = 5; 549 } 550 551 // HostPorts provides a list of ports allocated at the host 552 // level. 553 PortStatus port_status = 6; 554 555 // AppliedBy gives the node ID of the manager that applied this task 556 // status update to the Task object. 557 string applied_by = 7; 558 559 // AppliedAt gives a timestamp of when this status update was applied to 560 // the Task object. 561 // Note: can't use stdtime because this field is nullable. 562 google.protobuf.Timestamp applied_at = 8; 563} 564 565// NetworkAttachmentConfig specifies how a service should be attached to a particular network. 566// 567// For now, this is a simple struct, but this can include future information 568// instructing Swarm on how this service should work on the particular 569// network. 570message NetworkAttachmentConfig { 571 // Target specifies the target network for attachment. This value must be a 572 // network ID. 573 string target = 1; 574 // Aliases specifies a list of discoverable alternate names for the service on this Target. 575 repeated string aliases = 2; 576 // Addresses specifies a list of ipv4 and ipv6 addresses 577 // preferred. If these addresses are not available then the 578 // attachment might fail. 579 repeated string addresses = 3; 580 // DriverAttachmentOpts is a map of driver attachment options for the network target 581 map<string, string> driver_attachment_opts = 4; 582} 583 584// IPAMConfig specifies parameters for IP Address Management. 585message IPAMConfig { 586 // TODO(stevvooe): It may make more sense to manage IPAM and network 587 // definitions separately. This will allow multiple networks to share IPAM 588 // instances. For now, we will follow the conventions of libnetwork and 589 // specify this as part of the network specification. 590 591 // AddressFamily specifies the network address family that 592 // this IPAMConfig belongs to. 593 enum AddressFamily { 594 UNKNOWN = 0; // satisfy proto3 595 IPV4 = 4; 596 IPV6 = 6; 597 } 598 599 AddressFamily family = 1; 600 601 // Subnet defines a network as a CIDR address (ie network and mask 602 // 192.168.0.1/24). 603 string subnet = 2; 604 605 // Range defines the portion of the subnet to allocate to tasks. This is 606 // defined as a subnet within the primary subnet. 607 string range = 3; 608 609 // Gateway address within the subnet. 610 string gateway = 4; 611 612 // Reserved is a list of address from the master pool that should *not* be 613 // allocated. These addresses may have already been allocated or may be 614 // reserved for another allocation manager. 615 map<string, string> reserved = 5; 616} 617 618// PortConfig specifies an exposed port which can be 619// addressed using the given name. This can be later queried 620// using a service discovery api or a DNS SRV query. The node 621// port specifies a port that can be used to address this 622// service external to the cluster by sending a connection 623// request to this port to any node on the cluster. 624message PortConfig { 625 enum Protocol { 626 option (gogoproto.goproto_enum_prefix) = false; 627 628 TCP = 0 [(gogoproto.enumvalue_customname) = "ProtocolTCP"]; 629 UDP = 1 [(gogoproto.enumvalue_customname) = "ProtocolUDP"]; 630 SCTP = 2 [(gogoproto.enumvalue_customname) = "ProtocolSCTP"]; 631 } 632 633 // PublishMode controls how ports are published on the swarm. 634 enum PublishMode { 635 option (gogoproto.enum_customname) = "PublishMode"; 636 option (gogoproto.goproto_enum_prefix) = false; 637 638 // PublishModeIngress exposes the port across the cluster on all nodes. 639 INGRESS = 0 [(gogoproto.enumvalue_customname) = "PublishModeIngress"]; 640 641 // PublishModeHost exposes the port on just the target host. If the 642 // published port is undefined, an ephemeral port will be allocated. If 643 // the published port is defined, the node will attempt to allocate it, 644 // erroring the task if it fails. 645 HOST = 1 [(gogoproto.enumvalue_customname) = "PublishModeHost"]; 646 } 647 648 // Name for the port. If provided the port information can 649 // be queried using the name as in a DNS SRV query. 650 string name = 1; 651 652 // Protocol for the port which is exposed. 653 Protocol protocol = 2; 654 655 // The port which the application is exposing and is bound to. 656 uint32 target_port = 3; 657 658 // PublishedPort specifies the port on which the service is exposed. If 659 // specified, the port must be within the available range. If not specified 660 // (value is zero), an available port is automatically assigned. 661 uint32 published_port = 4; 662 663 // PublishMode controls how the port is published. 664 PublishMode publish_mode = 5; 665} 666 667// Driver is a generic driver type to be used throughout the API. For now, a 668// driver is simply a name and set of options. The field contents depend on the 669// target use case and driver application. For example, a network driver may 670// have different rules than a volume driver. 671message Driver { 672 string name = 1; 673 map <string, string> options = 2; 674} 675 676message IPAMOptions { 677 Driver driver = 1; 678 repeated IPAMConfig configs = 3; 679} 680 681// Peer should be used anywhere where we are describing a remote peer. 682message Peer { 683 string node_id = 1; 684 string addr = 2; 685} 686 687// WeightedPeer should be used anywhere where we are describing a remote peer 688// with a weight. 689message WeightedPeer { 690 Peer peer = 1; 691 int64 weight = 2; 692} 693 694 695message IssuanceStatus { 696 enum State { 697 option (gogoproto.goproto_enum_prefix) = false; 698 699 UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "IssuanceStateUnknown"]; 700 // A new certificate should be issued 701 RENEW = 1 [(gogoproto.enumvalue_customname)="IssuanceStateRenew"]; 702 // Certificate is pending acceptance 703 PENDING = 2 [(gogoproto.enumvalue_customname)="IssuanceStatePending"]; 704 // successful completion certificate issuance 705 ISSUED = 3 [(gogoproto.enumvalue_customname)="IssuanceStateIssued"]; 706 // Certificate issuance failed 707 FAILED = 4 [(gogoproto.enumvalue_customname)="IssuanceStateFailed"]; 708 // Signals workers to renew their certificate. From the CA's perspective 709 // this is equivalent to IssuanceStateIssued: a noop. 710 ROTATE = 5 [(gogoproto.enumvalue_customname)="IssuanceStateRotate"]; 711 } 712 State state = 1; 713 714 // Err is set if the Certificate Issuance is in an error state. 715 // The following states should report a companion error: 716 // FAILED 717 string err = 2; 718} 719 720message AcceptancePolicy { 721 message RoleAdmissionPolicy { 722 message Secret { 723 // The actual content (possibly hashed) 724 bytes data = 1; 725 // The type of hash we are using, or "plaintext" 726 string alg = 2; 727 } 728 729 NodeRole role = 1; 730 // Autoaccept controls which roles' certificates are automatically 731 // issued without administrator intervention. 732 bool autoaccept = 2; 733 // Secret represents a user-provided string that is necessary for new 734 // nodes to join the cluster 735 Secret secret = 3; 736 } 737 738 repeated RoleAdmissionPolicy policies = 1; 739} 740 741message ExternalCA { 742 enum CAProtocol { 743 CFSSL = 0 [(gogoproto.enumvalue_customname) = "CAProtocolCFSSL"]; 744 } 745 746 // Protocol is the protocol used by this external CA. 747 CAProtocol protocol = 1; 748 749 // URL is the URL where the external CA can be reached. 750 string url = 2 [(gogoproto.customname) = "URL"]; 751 752 // Options is a set of additional key/value pairs whose interpretation 753 // depends on the specified CA type. 754 map<string, string> options = 3; 755 756 // CACert specifies which root CA is used by this external CA 757 bytes ca_cert = 4 [(gogoproto.customname) = "CACert"]; 758} 759 760message CAConfig { 761 // NodeCertExpiry is the duration certificates should be issued for 762 // Note: can't use stdduration because this field needs to be nullable. 763 google.protobuf.Duration node_cert_expiry = 1; 764 765 // ExternalCAs is a list of CAs to which a manager node will make 766 // certificate signing requests for node certificates. 767 repeated ExternalCA external_cas = 2 [(gogoproto.customname) = "ExternalCAs"]; 768 769 // SigningCACert is the desired CA certificate to be used as the root and 770 // signing CA for the swarm. If not provided, indicates that we are either happy 771 // with the current configuration, or (together with a bump in the ForceRotate value) 772 // that we want a certificate and key generated for us. 773 bytes signing_ca_cert = 3 [(gogoproto.customname) = "SigningCACert"]; 774 775 // SigningCAKey is the desired private key, matching the signing CA cert, to be used 776 // to sign certificates for the swarm 777 bytes signing_ca_key = 4 [(gogoproto.customname) = "SigningCAKey"]; 778 779 // ForceRotate is a counter that triggers a root CA rotation even if no relevant 780 // parameters have been in the spec. This will force the manager to generate a new 781 // certificate and key, if none have been provided. 782 uint64 force_rotate = 5; 783} 784 785// OrchestrationConfig defines cluster-level orchestration settings. 786message OrchestrationConfig { 787 // TaskHistoryRetentionLimit is the number of historic tasks to keep per instance or 788 // node. If negative, never remove completed or failed tasks. 789 int64 task_history_retention_limit = 1; 790 791} 792 793// TaskDefaults specifies default values for task creation. 794message TaskDefaults { 795 // LogDriver specifies the log driver to use for the cluster if not 796 // specified for each task. 797 // 798 // If this is changed, only new tasks will pick up the new log driver. 799 // Existing tasks will continue to use the previous default until rescheduled. 800 Driver log_driver = 1; 801} 802 803// DispatcherConfig defines cluster-level dispatcher settings. 804message DispatcherConfig { 805 // HeartbeatPeriod defines how often agent should send heartbeats to 806 // dispatcher. 807 // Note: can't use stdduration because this field needs to be nullable. 808 google.protobuf.Duration heartbeat_period = 1; 809} 810 811// RaftConfig defines raft settings for the cluster. 812message RaftConfig { 813 // SnapshotInterval is the number of log entries between snapshots. 814 uint64 snapshot_interval = 1; 815 // KeepOldSnapshots is the number of snapshots to keep beyond the 816 // current snapshot. 817 uint64 keep_old_snapshots = 2; 818 // LogEntriesForSlowFollowers is the number of log entries to keep 819 // around to sync up slow followers after a snapshot is created. 820 uint64 log_entries_for_slow_followers = 3; 821 // HeartbeatTick defines the amount of ticks (in seconds) between 822 // each heartbeat message sent to other members for health-check. 823 uint32 heartbeat_tick = 4; 824 // ElectionTick defines the amount of ticks (in seconds) needed 825 // without a leader to trigger a new election. 826 uint32 election_tick = 5; 827} 828 829message EncryptionConfig { 830 // AutoLockManagers specifies whether or not managers TLS keys and raft data 831 // should be encrypted at rest in such a way that they must be unlocked 832 // before the manager node starts up again. 833 bool auto_lock_managers = 1; 834} 835 836message SpreadOver { 837 string spread_descriptor = 1; // label descriptor, such as engine.labels.az 838 // TODO: support node information beyond engine and node labels 839 840 // TODO: in the future, add a map that provides weights for weighted 841 // spreading. 842} 843 844message PlacementPreference { 845 oneof Preference { 846 SpreadOver spread = 1; 847 } 848} 849 850// Placement specifies task distribution constraints. 851message Placement { 852 // Constraints specifies a set of requirements a node should meet for a task. 853 repeated string constraints = 1; 854 855 // Preferences provide a way to make the scheduler aware of factors 856 // such as topology. They are provided in order from highest to lowest 857 // precedence. 858 repeated PlacementPreference preferences = 2; 859 860 // Platforms stores all the platforms that the image can run on. 861 // This field is used in the platform filter for scheduling. If empty, 862 // then the platform filter is off, meaning there are no scheduling restrictions. 863 repeated Platform platforms = 3; 864} 865 866// JoinToken contains the join tokens for workers and managers. 867message JoinTokens { 868 // Worker is the join token workers may use to join the swarm. 869 string worker = 1; 870 871 // Manager is the join token workers may use to join the swarm. 872 string manager = 2; 873} 874 875message RootCA { 876 // CAKey is the root CA private key. 877 bytes ca_key = 1 [(gogoproto.customname) = "CAKey"]; 878 879 // CACert is the root CA certificate. 880 bytes ca_cert = 2 [(gogoproto.customname) = "CACert"]; 881 882 // CACertHash is the digest of the CA Certificate. 883 string ca_cert_hash = 3 [(gogoproto.customname) = "CACertHash"]; 884 885 // JoinTokens contains the join tokens for workers and managers. 886 JoinTokens join_tokens = 4 [(gogoproto.nullable) = false]; 887 888 // RootRotation contains the new root cert and key we want to rotate to - if this is nil, we are not in the 889 // middle of a root rotation 890 RootRotation root_rotation = 5; 891 892 // LastForcedRotation matches the Cluster Spec's CAConfig's ForceRotation counter. 893 // It indicates when the current CA cert and key were generated (or updated). 894 uint64 last_forced_rotation = 6; 895} 896 897 898enum NodeRole { 899 option (gogoproto.enum_customname) = "NodeRole"; 900 option (gogoproto.goproto_enum_prefix) = false; 901 902 WORKER = 0 [(gogoproto.enumvalue_customname) = "NodeRoleWorker"]; 903 MANAGER = 1 [(gogoproto.enumvalue_customname) = "NodeRoleManager"]; 904} 905 906message Certificate { 907 NodeRole role = 1; 908 909 bytes csr = 2 [(gogoproto.customname) = "CSR"]; 910 911 IssuanceStatus status = 3 [(gogoproto.nullable) = false]; 912 913 bytes certificate = 4; 914 915 // CN represents the node ID. 916 string cn = 5 [(gogoproto.customname) = "CN"]; 917} 918 919 920// Symmetric keys to encrypt inter-agent communication. 921message EncryptionKey { 922 // Agent subsystem the key is intended for. Example: 923 // networking:gossip 924 string subsystem = 1; 925 926 // Encryption algorithm that can implemented using this key 927 enum Algorithm { 928 option (gogoproto.goproto_enum_prefix) = false; 929 930 AES_128_GCM = 0; 931 } 932 933 Algorithm algorithm = 2; 934 935 bytes key = 3; 936 937 // Time stamp from the lamport clock of the key allocator to 938 // identify the relative age of the key. 939 uint64 lamport_time = 4; 940} 941 942// ManagerStatus provides informations about the state of a manager in the cluster. 943message ManagerStatus { 944 // RaftID specifies the internal ID used by the manager in a raft context, it can never be modified 945 // and is used only for information purposes 946 uint64 raft_id = 1; 947 948 // Addr is the address advertised to raft. 949 string addr = 2; 950 951 // Leader is set to true if this node is the raft leader. 952 bool leader = 3; 953 954 // Reachability specifies whether this node is reachable. 955 RaftMemberStatus.Reachability reachability = 4; 956} 957 958// FileTarget represents a specific target that is backed by a file 959message FileTarget { 960 // Name represents the final filename in the filesystem 961 string name = 1; 962 963 // UID represents the file UID 964 string uid = 2 [(gogoproto.customname) = "UID"]; 965 966 // GID represents the file GID 967 string gid = 3 [(gogoproto.customname) = "GID"]; 968 969 // Mode represents the FileMode of the file 970 uint32 mode = 4 [(gogoproto.customtype) = "os.FileMode", (gogoproto.nullable) = false]; 971} 972 973// SecretReference is the linkage between a service and a secret that it uses. 974message SecretReference { 975 // SecretID represents the ID of the specific Secret that we're 976 // referencing. This identifier exists so that SecretReferences don't leak 977 // any information about the secret contents. 978 string secret_id = 1; 979 980 // SecretName is the name of the secret that this references, but this is just provided for 981 // lookup/display purposes. The secret in the reference will be identified by its ID. 982 string secret_name = 2; 983 984 // Target specifies how this secret should be exposed to the task. 985 oneof target { 986 FileTarget file = 3; 987 } 988} 989 990// ConfigReference is the linkage between a service and a config that it uses. 991message ConfigReference { 992 // ConfigID represents the ID of the specific Config that we're 993 // referencing. 994 string config_id = 1; 995 996 // ConfigName is the name of the config that this references, but this is just provided for 997 // lookup/display purposes. The config in the reference will be identified by its ID. 998 string config_name = 2; 999 1000 // Target specifies how this secret should be exposed to the task. 1001 oneof target { 1002 FileTarget file = 3; 1003 } 1004} 1005 1006// BlacklistedCertificate is a record for a blacklisted certificate. It does not 1007// contain the certificate's CN, because these records are indexed by CN. 1008message BlacklistedCertificate { 1009 // Expiry is the latest known expiration time of a certificate that 1010 // was issued for the given CN. 1011 // Note: can't use stdtime because this field is nullable. 1012 google.protobuf.Timestamp expiry = 1; 1013} 1014 1015// HealthConfig holds configuration settings for the HEALTHCHECK feature. 1016message HealthConfig { 1017 // Test is the test to perform to check that the container is healthy. 1018 // An empty slice means to inherit the default. 1019 // The options are: 1020 // {} : inherit healthcheck 1021 // {"NONE"} : disable healthcheck 1022 // {"CMD", args...} : exec arguments directly 1023 // {"CMD-SHELL", command} : run command with system's default shell 1024 repeated string test = 1; 1025 1026 // Interval is the time to wait between checks. Zero means inherit. 1027 // Note: can't use stdduration because this field needs to be nullable. 1028 google.protobuf.Duration interval = 2; 1029 1030 // Timeout is the time to wait before considering the check to have hung. 1031 // Zero means inherit. 1032 // Note: can't use stdduration because this field needs to be nullable. 1033 google.protobuf.Duration timeout = 3; 1034 1035 // Retries is the number of consecutive failures needed to consider a 1036 // container as unhealthy. Zero means inherit. 1037 int32 retries = 4; 1038 1039 // Start period is the period for container initialization during 1040 // which health check failures will note count towards the maximum 1041 // number of retries. 1042 google.protobuf.Duration start_period = 5; 1043} 1044 1045message MaybeEncryptedRecord { 1046 enum Algorithm { 1047 NONE = 0 [(gogoproto.enumvalue_customname) = "NotEncrypted"]; 1048 SECRETBOX_SALSA20_POLY1305 = 1 [(gogoproto.enumvalue_customname) = "NACLSecretboxSalsa20Poly1305"]; 1049 FERNET_AES_128_CBC = 2 [(gogoproto.enumvalue_customname) = "FernetAES128CBC"]; 1050 } 1051 1052 Algorithm algorithm = 1; 1053 bytes data = 2; 1054 bytes nonce = 3; 1055} 1056 1057 1058message RootRotation { 1059 bytes ca_cert = 1 [(gogoproto.customname) = "CACert"]; 1060 bytes ca_key = 2 [(gogoproto.customname) = "CAKey"]; 1061 // cross-signed CA cert is the CACert that has been cross-signed by the previous root 1062 bytes cross_signed_ca_cert = 3 [(gogoproto.customname) = "CrossSignedCACert"]; 1063} 1064 1065// Privileges specifies security configuration/permissions. 1066message Privileges { 1067 // CredentialSpec for managed service account (Windows only). 1068 message CredentialSpec { 1069 oneof source { 1070 string file = 1; 1071 string registry = 2; 1072 } 1073 } 1074 CredentialSpec credential_spec = 1; 1075 1076 // SELinuxContext contains the SELinux labels for the container. 1077 message SELinuxContext { 1078 bool disable = 1; 1079 1080 string user = 2; 1081 string role = 3; 1082 string type = 4; 1083 string level = 5; 1084 } 1085 SELinuxContext selinux_context = 2 [(gogoproto.customname) = "SELinuxContext"]; 1086} 1087