mirror of https://github.com/docker/cli.git
Merge pull request #429 from RenaudWasTaken/generic-resource
Integrated Generic resource in service create
This commit is contained in:
commit
97b148b440
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
cliopts "github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -58,6 +59,9 @@ func newCreateCommand(dockerCli command.Cli) *cobra.Command {
|
|||
flags.Var(&opts.hosts, flagHost, "Set one or more custom host-to-IP mappings (host:ip)")
|
||||
flags.SetAnnotation(flagHost, "version", []string{"1.25"})
|
||||
|
||||
flags.Var(cliopts.NewListOptsRef(&opts.resources.resGenericResources, ValidateSingleGenericResource), "generic-resource", "User defined resources")
|
||||
flags.SetAnnotation(flagHostAdd, "version", []string{"1.32"})
|
||||
|
||||
flags.SetInterspersed(false)
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
swarmapi "github.com/docker/swarmkit/api"
|
||||
"github.com/docker/swarmkit/api/genericresource"
|
||||
)
|
||||
|
||||
// GenericResource is a concept that a user can use to advertise user-defined
|
||||
// resources on a node and thus better place services based on these resources.
|
||||
// E.g: NVIDIA GPUs, Intel FPGAs, ...
|
||||
// See https://github.com/docker/swarmkit/blob/master/design/generic_resources.md
|
||||
|
||||
// ValidateSingleGenericResource validates that a single entry in the
|
||||
// generic resource list is valid.
|
||||
// i.e 'GPU=UID1' is valid however 'GPU:UID1' or 'UID1' isn't
|
||||
func ValidateSingleGenericResource(val string) (string, error) {
|
||||
if strings.Count(val, "=") < 1 {
|
||||
return "", fmt.Errorf("invalid generic-resource format `%s` expected `name=value`", val)
|
||||
}
|
||||
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// ParseGenericResources parses an array of Generic resourceResources
|
||||
// Requesting Named Generic Resources for a service is not supported this
|
||||
// is filtered here.
|
||||
func ParseGenericResources(value []string) ([]swarm.GenericResource, error) {
|
||||
if len(value) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
resources, err := genericresource.Parse(value)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "invalid generic resource specification")
|
||||
}
|
||||
|
||||
swarmResources := genericResourcesFromGRPC(resources)
|
||||
for _, res := range swarmResources {
|
||||
if res.NamedResourceSpec != nil {
|
||||
return nil, fmt.Errorf("invalid generic-resource request `%s=%s`, Named Generic Resources is not supported for service create or update", res.NamedResourceSpec.Kind, res.NamedResourceSpec.Value)
|
||||
}
|
||||
}
|
||||
|
||||
return swarmResources, nil
|
||||
}
|
||||
|
||||
// genericResourcesFromGRPC converts a GRPC GenericResource to a GenericResource
|
||||
func genericResourcesFromGRPC(genericRes []*swarmapi.GenericResource) []swarm.GenericResource {
|
||||
var generic []swarm.GenericResource
|
||||
for _, res := range genericRes {
|
||||
var current swarm.GenericResource
|
||||
|
||||
switch r := res.Resource.(type) {
|
||||
case *swarmapi.GenericResource_DiscreteResourceSpec:
|
||||
current.DiscreteResourceSpec = &swarm.DiscreteGenericResource{
|
||||
Kind: r.DiscreteResourceSpec.Kind,
|
||||
Value: r.DiscreteResourceSpec.Value,
|
||||
}
|
||||
case *swarmapi.GenericResource_NamedResourceSpec:
|
||||
current.NamedResourceSpec = &swarm.NamedGenericResource{
|
||||
Kind: r.NamedResourceSpec.Kind,
|
||||
Value: r.NamedResourceSpec.Value,
|
||||
}
|
||||
}
|
||||
|
||||
generic = append(generic, current)
|
||||
}
|
||||
|
||||
return generic
|
||||
}
|
||||
|
||||
func buildGenericResourceMap(genericRes []swarm.GenericResource) (map[string]swarm.GenericResource, error) {
|
||||
m := make(map[string]swarm.GenericResource)
|
||||
|
||||
for _, res := range genericRes {
|
||||
if res.DiscreteResourceSpec == nil {
|
||||
return nil, fmt.Errorf("invalid generic-resource `%+v` for service task", res)
|
||||
}
|
||||
|
||||
_, ok := m[res.DiscreteResourceSpec.Kind]
|
||||
if ok {
|
||||
return nil, fmt.Errorf("duplicate generic-resource `%+v` for service task", res.DiscreteResourceSpec.Kind)
|
||||
}
|
||||
|
||||
m[res.DiscreteResourceSpec.Kind] = res
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func buildGenericResourceList(genericRes map[string]swarm.GenericResource) []swarm.GenericResource {
|
||||
var l []swarm.GenericResource
|
||||
|
||||
for _, res := range genericRes {
|
||||
l = append(l, res)
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestValidateSingleGenericResource(t *testing.T) {
|
||||
incorrect := []string{"foo", "fooo-bar"}
|
||||
correct := []string{"foo=bar", "bar=1", "foo=barbar"}
|
||||
|
||||
for _, v := range incorrect {
|
||||
_, err := ValidateSingleGenericResource(v)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
for _, v := range correct {
|
||||
_, err := ValidateSingleGenericResource(v)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
}
|
|
@ -226,9 +226,15 @@ type resourceOptions struct {
|
|||
limitMemBytes opts.MemBytes
|
||||
resCPU opts.NanoCPUs
|
||||
resMemBytes opts.MemBytes
|
||||
resGenericResources []string
|
||||
}
|
||||
|
||||
func (r *resourceOptions) ToResourceRequirements() *swarm.ResourceRequirements {
|
||||
func (r *resourceOptions) ToResourceRequirements() (*swarm.ResourceRequirements, error) {
|
||||
generic, err := ParseGenericResources(r.resGenericResources)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &swarm.ResourceRequirements{
|
||||
Limits: &swarm.Resources{
|
||||
NanoCPUs: r.limitCPU.Value(),
|
||||
|
@ -237,8 +243,9 @@ func (r *resourceOptions) ToResourceRequirements() *swarm.ResourceRequirements {
|
|||
Reservations: &swarm.Resources{
|
||||
NanoCPUs: r.resCPU.Value(),
|
||||
MemoryBytes: r.resMemBytes.Value(),
|
||||
GenericResources: generic,
|
||||
},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
type restartPolicyOptions struct {
|
||||
|
@ -588,6 +595,11 @@ func (options *serviceOptions) ToService(ctx context.Context, apiClient client.N
|
|||
return service, err
|
||||
}
|
||||
|
||||
resources, err := options.resources.ToResourceRequirements()
|
||||
if err != nil {
|
||||
return service, err
|
||||
}
|
||||
|
||||
service = swarm.ServiceSpec{
|
||||
Annotations: swarm.Annotations{
|
||||
Name: options.name,
|
||||
|
@ -619,7 +631,7 @@ func (options *serviceOptions) ToService(ctx context.Context, apiClient client.N
|
|||
Isolation: container.Isolation(options.isolation),
|
||||
},
|
||||
Networks: networks,
|
||||
Resources: options.resources.ToResourceRequirements(),
|
||||
Resources: resources,
|
||||
RestartPolicy: options.restartPolicy.ToRestartPolicy(flags),
|
||||
Placement: &swarm.Placement{
|
||||
Constraints: options.constraints.GetAll(),
|
||||
|
@ -818,6 +830,8 @@ const (
|
|||
flagEnvFile = "env-file"
|
||||
flagEnvRemove = "env-rm"
|
||||
flagEnvAdd = "env-add"
|
||||
flagGenericResourcesRemove = "generic-resource-rm"
|
||||
flagGenericResourcesAdd = "generic-resource-add"
|
||||
flagGroup = "group"
|
||||
flagGroupAdd = "group-add"
|
||||
flagGroupRemove = "group-rm"
|
||||
|
|
|
@ -85,3 +85,41 @@ func TestHealthCheckOptionsToHealthConfigConflict(t *testing.T) {
|
|||
_, err := opt.toHealthConfig()
|
||||
assert.EqualError(t, err, "--no-healthcheck conflicts with --health-* options")
|
||||
}
|
||||
|
||||
func TestResourceOptionsToResourceRequirements(t *testing.T) {
|
||||
incorrectOptions := []resourceOptions{
|
||||
{
|
||||
resGenericResources: []string{"foo=bar", "foo=1"},
|
||||
},
|
||||
{
|
||||
resGenericResources: []string{"foo=bar", "foo=baz"},
|
||||
},
|
||||
{
|
||||
resGenericResources: []string{"foo=bar"},
|
||||
},
|
||||
{
|
||||
resGenericResources: []string{"foo=1", "foo=2"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, opt := range incorrectOptions {
|
||||
_, err := opt.ToResourceRequirements()
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
correctOptions := []resourceOptions{
|
||||
{
|
||||
resGenericResources: []string{"foo=1"},
|
||||
},
|
||||
{
|
||||
resGenericResources: []string{"foo=1", "bar=2"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, opt := range correctOptions {
|
||||
r, err := opt.ToResourceRequirements()
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, r.Reservations.GenericResources, len(opt.resGenericResources))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -95,6 +95,12 @@ func newUpdateCommand(dockerCli command.Cli) *cobra.Command {
|
|||
flags.Var(&options.hosts, flagHostAdd, "Add a custom host-to-IP mapping (host:ip)")
|
||||
flags.SetAnnotation(flagHostAdd, "version", []string{"1.25"})
|
||||
|
||||
// Add needs parsing, Remove only needs the key
|
||||
flags.Var(newListOptsVar(), flagGenericResourcesRemove, "Remove a Generic resource")
|
||||
flags.SetAnnotation(flagHostAdd, "version", []string{"1.32"})
|
||||
flags.Var(newListOptsVarWithValidator(ValidateSingleGenericResource), flagGenericResourcesAdd, "Add a Generic resource")
|
||||
flags.SetAnnotation(flagHostAdd, "version", []string{"1.32"})
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
@ -102,6 +108,10 @@ func newListOptsVar() *opts.ListOpts {
|
|||
return opts.NewListOptsRef(&[]string{}, nil)
|
||||
}
|
||||
|
||||
func newListOptsVarWithValidator(validator opts.ValidatorFctType) *opts.ListOpts {
|
||||
return opts.NewListOptsRef(&[]string{}, validator)
|
||||
}
|
||||
|
||||
// nolint: gocyclo
|
||||
func runUpdate(dockerCli command.Cli, flags *pflag.FlagSet, options *serviceOptions, serviceID string) error {
|
||||
apiClient := dockerCli.Client()
|
||||
|
@ -314,6 +324,14 @@ func updateService(ctx context.Context, apiClient client.NetworkAPIClient, flags
|
|||
updateInt64Value(flagReserveMemory, &task.Resources.Reservations.MemoryBytes)
|
||||
}
|
||||
|
||||
if err := addGenericResources(flags, task); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := removeGenericResources(flags, task); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updateDurationOpt(flagStopGracePeriod, &cspec.StopGracePeriod)
|
||||
|
||||
if anyChanged(flags, flagRestartCondition, flagRestartDelay, flagRestartMaxAttempts, flagRestartWindow) {
|
||||
|
@ -470,6 +488,72 @@ func anyChanged(flags *pflag.FlagSet, fields ...string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func addGenericResources(flags *pflag.FlagSet, spec *swarm.TaskSpec) error {
|
||||
if !flags.Changed(flagGenericResourcesAdd) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if spec.Resources == nil {
|
||||
spec.Resources = &swarm.ResourceRequirements{}
|
||||
}
|
||||
|
||||
if spec.Resources.Reservations == nil {
|
||||
spec.Resources.Reservations = &swarm.Resources{}
|
||||
}
|
||||
|
||||
values := flags.Lookup(flagGenericResourcesAdd).Value.(*opts.ListOpts).GetAll()
|
||||
generic, err := ParseGenericResources(values)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m, err := buildGenericResourceMap(spec.Resources.Reservations.GenericResources)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, toAddRes := range generic {
|
||||
m[toAddRes.DiscreteResourceSpec.Kind] = toAddRes
|
||||
}
|
||||
|
||||
spec.Resources.Reservations.GenericResources = buildGenericResourceList(m)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeGenericResources(flags *pflag.FlagSet, spec *swarm.TaskSpec) error {
|
||||
// Can only be Discrete Resources
|
||||
if !flags.Changed(flagGenericResourcesRemove) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if spec.Resources == nil {
|
||||
spec.Resources = &swarm.ResourceRequirements{}
|
||||
}
|
||||
|
||||
if spec.Resources.Reservations == nil {
|
||||
spec.Resources.Reservations = &swarm.Resources{}
|
||||
}
|
||||
|
||||
values := flags.Lookup(flagGenericResourcesRemove).Value.(*opts.ListOpts).GetAll()
|
||||
|
||||
m, err := buildGenericResourceMap(spec.Resources.Reservations.GenericResources)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, toRemoveRes := range values {
|
||||
if _, ok := m[toRemoveRes]; !ok {
|
||||
return fmt.Errorf("could not find generic-resource `%s` to remove it", toRemoveRes)
|
||||
}
|
||||
|
||||
delete(m, toRemoveRes)
|
||||
}
|
||||
|
||||
spec.Resources.Reservations.GenericResources = buildGenericResourceList(m)
|
||||
return nil
|
||||
}
|
||||
|
||||
func updatePlacementConstraints(flags *pflag.FlagSet, placement *swarm.Placement) {
|
||||
if flags.Changed(flagConstraintAdd) {
|
||||
values := flags.Lookup(flagConstraintAdd).Value.(*opts.ListOpts).GetAll()
|
||||
|
|
|
@ -547,3 +547,42 @@ func TestUpdateIsolationInvalid(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
assert.Equal(t, container.Isolation("test"), spec.TaskTemplate.ContainerSpec.Isolation)
|
||||
}
|
||||
|
||||
func TestAddGenericResources(t *testing.T) {
|
||||
task := &swarm.TaskSpec{}
|
||||
flags := newUpdateCommand(nil).Flags()
|
||||
|
||||
assert.Nil(t, addGenericResources(flags, task))
|
||||
|
||||
flags.Set(flagGenericResourcesAdd, "foo=1")
|
||||
assert.NoError(t, addGenericResources(flags, task))
|
||||
assert.Len(t, task.Resources.Reservations.GenericResources, 1)
|
||||
|
||||
// Checks that foo isn't added a 2nd time
|
||||
flags = newUpdateCommand(nil).Flags()
|
||||
flags.Set(flagGenericResourcesAdd, "bar=1")
|
||||
assert.NoError(t, addGenericResources(flags, task))
|
||||
assert.Len(t, task.Resources.Reservations.GenericResources, 2)
|
||||
}
|
||||
|
||||
func TestRemoveGenericResources(t *testing.T) {
|
||||
task := &swarm.TaskSpec{}
|
||||
flags := newUpdateCommand(nil).Flags()
|
||||
|
||||
assert.Nil(t, removeGenericResources(flags, task))
|
||||
|
||||
flags.Set(flagGenericResourcesRemove, "foo")
|
||||
assert.Error(t, removeGenericResources(flags, task))
|
||||
|
||||
flags = newUpdateCommand(nil).Flags()
|
||||
flags.Set(flagGenericResourcesAdd, "foo=1")
|
||||
addGenericResources(flags, task)
|
||||
flags = newUpdateCommand(nil).Flags()
|
||||
flags.Set(flagGenericResourcesAdd, "bar=1")
|
||||
addGenericResources(flags, task)
|
||||
|
||||
flags = newUpdateCommand(nil).Flags()
|
||||
flags.Set(flagGenericResourcesRemove, "foo")
|
||||
assert.NoError(t, removeGenericResources(flags, task))
|
||||
assert.Len(t, task.Resources.Reservations.GenericResources, 1)
|
||||
}
|
||||
|
|
|
@ -510,9 +510,25 @@ func convertResources(source composetypes.Resources) (*swarm.ResourceRequirement
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var generic []swarm.GenericResource
|
||||
for _, res := range source.Reservations.GenericResources {
|
||||
var r swarm.GenericResource
|
||||
|
||||
if res.DiscreteResourceSpec != nil {
|
||||
r.DiscreteResourceSpec = &swarm.DiscreteGenericResource{
|
||||
Kind: res.DiscreteResourceSpec.Kind,
|
||||
Value: res.DiscreteResourceSpec.Value,
|
||||
}
|
||||
}
|
||||
|
||||
generic = append(generic, r)
|
||||
}
|
||||
|
||||
resources.Reservations = &swarm.Resources{
|
||||
NanoCPUs: cpus,
|
||||
MemoryBytes: int64(source.Reservations.MemoryBytes),
|
||||
GenericResources: generic,
|
||||
}
|
||||
}
|
||||
return resources, nil
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
version: "3.4"
|
||||
version: "3.5"
|
||||
|
||||
services:
|
||||
foo:
|
||||
|
@ -16,7 +16,6 @@ services:
|
|||
labels: [FOO=BAR]
|
||||
|
||||
|
||||
|
||||
cap_add:
|
||||
- ALL
|
||||
|
||||
|
@ -54,6 +53,13 @@ services:
|
|||
reservations:
|
||||
cpus: '0.0001'
|
||||
memory: 20M
|
||||
generic_resources:
|
||||
- discrete_resource_spec:
|
||||
kind: 'gpu'
|
||||
value: 2
|
||||
- discrete_resource_spec:
|
||||
kind: 'ssd'
|
||||
value: 1
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
delay: 5s
|
||||
|
|
|
@ -879,6 +879,20 @@ func TestFullExample(t *testing.T) {
|
|||
Reservations: &types.Resource{
|
||||
NanoCPUs: "0.0001",
|
||||
MemoryBytes: 20 * 1024 * 1024,
|
||||
GenericResources: []types.GenericResource{
|
||||
{
|
||||
DiscreteResourceSpec: &types.DiscreteGenericResource{
|
||||
Kind: "gpu",
|
||||
Value: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
DiscreteResourceSpec: &types.DiscreteGenericResource{
|
||||
Kind: "ssd",
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: &types.RestartPolicy{
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -354,8 +354,23 @@
|
|||
"resources": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"limits": {"$ref": "#/definitions/resource"},
|
||||
"reservations": {"$ref": "#/definitions/resource"}
|
||||
"limits": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cpus": {"type": "string"},
|
||||
"memory": {"type": "string"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"reservations": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cpus": {"type": "string"},
|
||||
"memory": {"type": "string"},
|
||||
"generic_resources": {"$ref": "#/definitions/generic_resources"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
|
@ -390,14 +405,23 @@
|
|||
"additionalProperties": false
|
||||
},
|
||||
|
||||
"resource": {
|
||||
"id": "#/definitions/resource",
|
||||
"generic_resources": {
|
||||
"id": "#/definitions/generic_resources",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cpus": {"type": "string"},
|
||||
"memory": {"type": "string"}
|
||||
"discrete_resource_spec": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": {"type": "string"},
|
||||
"value": {"type": "number"}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
|
||||
"network": {
|
||||
|
|
|
@ -219,6 +219,22 @@ type Resource struct {
|
|||
// TODO: types to convert from units and ratios
|
||||
NanoCPUs string `mapstructure:"cpus"`
|
||||
MemoryBytes UnitBytes `mapstructure:"memory"`
|
||||
GenericResources []GenericResource `mapstructure:"generic_resources"`
|
||||
}
|
||||
|
||||
// GenericResource represents a "user defined" resource which can
|
||||
// only be an integer (e.g: SSD=3) for a service
|
||||
type GenericResource struct {
|
||||
DiscreteResourceSpec *DiscreteGenericResource `mapstructure:"discrete_resource_spec"`
|
||||
}
|
||||
|
||||
// DiscreteGenericResource represents a "user defined" resource which is defined
|
||||
// as an integer
|
||||
// "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...)
|
||||
// Value is used to count the resource (SSD=5, HDD=3, ...)
|
||||
type DiscreteGenericResource struct {
|
||||
Kind string
|
||||
Value int64
|
||||
}
|
||||
|
||||
// UnitBytes is the bytes type
|
||||
|
|
|
@ -72,6 +72,7 @@ Options:
|
|||
--max-concurrent-uploads int Set the max concurrent uploads for each push (default 5)
|
||||
--metrics-addr string Set default address and port to serve the metrics api on
|
||||
--mtu int Set the containers network MTU
|
||||
--node-generic-resources list Advertise user-defined resource
|
||||
--no-new-privileges Set no-new-privileges by default for new containers
|
||||
--oom-score-adjust int Set the oom_score_adj for the daemon (default -500)
|
||||
-p, --pidfile string Path to use for daemon PID file (default "/var/run/docker.pid")
|
||||
|
@ -1237,6 +1238,23 @@ Please note that this feature is still marked as experimental as metrics and met
|
|||
names could change while this feature is still in experimental. Please provide
|
||||
feedback on what you would like to see collected in the API.
|
||||
|
||||
#### Node Generic Resources
|
||||
|
||||
The `--node-generic-resources` option takes a list of key-value
|
||||
pair (`key=value`) that allows you to advertise user defined resources
|
||||
in a swarm cluster.
|
||||
|
||||
The current expected use case is to advertise NVIDIA GPUs so that services
|
||||
requesting `NVIDIA-GPU=[0-16]` can land on a node that has enough GPUs for
|
||||
the task to run.
|
||||
|
||||
Example of usage:
|
||||
```json
|
||||
{
|
||||
"node-generic-resources": ["NVIDIA-GPU=UUID1", "NVIDIA-GPU=UUID2"]
|
||||
}
|
||||
```
|
||||
|
||||
### Daemon configuration file
|
||||
|
||||
The `--config-file` option allows you to set any configuration option
|
||||
|
@ -1325,6 +1343,7 @@ This is a full example of the allowed configuration options on Linux:
|
|||
"no-new-privileges": false,
|
||||
"default-runtime": "runc",
|
||||
"oom-score-adjust": -500,
|
||||
"node-generic-resources": ["NVIDIA-GPU=UUID1", "NVIDIA-GPU=UUID2"],
|
||||
"runtimes": {
|
||||
"cc-runtime": {
|
||||
"path": "/usr/bin/cc-runtime"
|
||||
|
|
|
@ -33,6 +33,7 @@ Options:
|
|||
--entrypoint command Overwrite the default ENTRYPOINT of the image
|
||||
-e, --env list Set environment variables
|
||||
--env-file list Read in a file of environment variables
|
||||
--generic-resource list User defined resources request
|
||||
--group list Set one or more supplementary user groups for the container
|
||||
--health-cmd string Command to run to check health
|
||||
--health-interval duration Time between running the check (ms|s|m|h)
|
||||
|
@ -915,6 +916,17 @@ Supported isolation modes on Windows are:
|
|||
- `process`: use process isolation (Windows server only)
|
||||
- `hyperv`: use Hyper-V isolation
|
||||
|
||||
### Create services requesting Generic Resources
|
||||
|
||||
You can narrow the kind of nodes your task can land on through the using the
|
||||
`--generic-resource` flag (if the nodes advertise these resources):
|
||||
|
||||
```bash
|
||||
$ docker service create --name cuda \
|
||||
--generic-resource "NVIDIA-GPU=2" \
|
||||
--generic-resource "SSD=1" \
|
||||
nvidia/cuda
|
||||
```
|
||||
|
||||
## Related commands
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@ Options:
|
|||
--env-add list Add or update an environment variable
|
||||
--env-rm list Remove an environment variable
|
||||
--force Force update even if no changes require it
|
||||
--generic-resource-add list Add an additional generic resource to the service's resources requirements
|
||||
--generic-resource-rm list Remove a previously added generic resource to the service's resources requirements
|
||||
--group-add list Add an additional supplementary user group to the container
|
||||
--group-rm list Remove a previously added supplementary user group from the container
|
||||
--health-cmd string Command to run to check health
|
||||
|
|
|
@ -56,6 +56,7 @@ dockerd - Enable daemon mode
|
|||
[**--mtu**[=*0*]]
|
||||
[**--max-concurrent-downloads**[=*3*]]
|
||||
[**--max-concurrent-uploads**[=*5*]]
|
||||
[**--node-generic-resources**[=*[]*]]
|
||||
[**-p**|**--pidfile**[=*/var/run/docker.pid*]]
|
||||
[**--raw-logs**]
|
||||
[**--registry-mirror**[=*[]*]]
|
||||
|
@ -326,6 +327,15 @@ unix://[/path/to/socket] to use.
|
|||
**--max-concurrent-uploads**=*5*
|
||||
Set the max concurrent uploads for each push. Default is `5`.
|
||||
|
||||
**--node-generic-resources**=*[]*
|
||||
Advertise user-defined resource. Default is `[]`.
|
||||
Use this if your swarm cluster has some nodes with custom
|
||||
resources (e.g: NVIDIA GPU, SSD, ...) and you need your services to land on
|
||||
nodes advertising these resources.
|
||||
Usage example: `--node-generic-resources "NVIDIA-GPU=UUID1"
|
||||
--node-generic-resources "NVIDIA-GPU=UUID2"`
|
||||
|
||||
|
||||
**-p**, **--pidfile**=""
|
||||
Path to use for daemon PID file. Default is `/var/run/docker.pid`
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ github.com/docker/go d30aec9fd63c35133f8f79c3412ad91a3b08be06
|
|||
github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d
|
||||
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
||||
github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
|
||||
github.com/docker/swarmkit 28f91d87bd3f75fd039dbb9be49bfd2381019261
|
||||
github.com/docker/swarmkit de950a7ed842c7b7e47e9451cde9bf8f96031894
|
||||
github.com/flynn-archive/go-shlex 3f9db97f856818214da2e1057f8ad84803971cff
|
||||
github.com/gogo/protobuf v0.4
|
||||
github.com/golang/protobuf 7a211bcf3bce0e3f1d74f9894916e6f116ae83b4
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
package genericresource
|
||||
|
||||
import (
|
||||
"github.com/docker/swarmkit/api"
|
||||
)
|
||||
|
||||
// NewSet creates a set object
|
||||
func NewSet(key string, vals ...string) []*api.GenericResource {
|
||||
rs := make([]*api.GenericResource, 0, len(vals))
|
||||
|
||||
for _, v := range vals {
|
||||
rs = append(rs, NewString(key, v))
|
||||
}
|
||||
|
||||
return rs
|
||||
}
|
||||
|
||||
// NewString creates a String resource
|
||||
func NewString(key, val string) *api.GenericResource {
|
||||
return &api.GenericResource{
|
||||
Resource: &api.GenericResource_NamedResourceSpec{
|
||||
NamedResourceSpec: &api.NamedGenericResource{
|
||||
Kind: key,
|
||||
Value: val,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NewDiscrete creates a Discrete resource
|
||||
func NewDiscrete(key string, val int64) *api.GenericResource {
|
||||
return &api.GenericResource{
|
||||
Resource: &api.GenericResource_DiscreteResourceSpec{
|
||||
DiscreteResourceSpec: &api.DiscreteGenericResource{
|
||||
Kind: key,
|
||||
Value: val,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// GetResource returns resources from the "resources" parameter matching the kind key
|
||||
func GetResource(kind string, resources []*api.GenericResource) []*api.GenericResource {
|
||||
var res []*api.GenericResource
|
||||
|
||||
for _, r := range resources {
|
||||
if Kind(r) != kind {
|
||||
continue
|
||||
}
|
||||
|
||||
res = append(res, r)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// ConsumeNodeResources removes "res" from nodeAvailableResources
|
||||
func ConsumeNodeResources(nodeAvailableResources *[]*api.GenericResource, res []*api.GenericResource) {
|
||||
if nodeAvailableResources == nil {
|
||||
return
|
||||
}
|
||||
|
||||
w := 0
|
||||
|
||||
loop:
|
||||
for _, na := range *nodeAvailableResources {
|
||||
for _, r := range res {
|
||||
if Kind(na) != Kind(r) {
|
||||
continue
|
||||
}
|
||||
|
||||
if remove(na, r) {
|
||||
continue loop
|
||||
}
|
||||
// If this wasn't the right element then
|
||||
// we need to continue
|
||||
}
|
||||
|
||||
(*nodeAvailableResources)[w] = na
|
||||
w++
|
||||
}
|
||||
|
||||
*nodeAvailableResources = (*nodeAvailableResources)[:w]
|
||||
}
|
||||
|
||||
// Returns true if the element is to be removed from the list
|
||||
func remove(na, r *api.GenericResource) bool {
|
||||
switch tr := r.Resource.(type) {
|
||||
case *api.GenericResource_DiscreteResourceSpec:
|
||||
if na.GetDiscreteResourceSpec() == nil {
|
||||
return false // Type change, ignore
|
||||
}
|
||||
|
||||
na.GetDiscreteResourceSpec().Value -= tr.DiscreteResourceSpec.Value
|
||||
if na.GetDiscreteResourceSpec().Value <= 0 {
|
||||
return true
|
||||
}
|
||||
case *api.GenericResource_NamedResourceSpec:
|
||||
if na.GetNamedResourceSpec() == nil {
|
||||
return false // Type change, ignore
|
||||
}
|
||||
|
||||
if tr.NamedResourceSpec.Value != na.GetNamedResourceSpec().Value {
|
||||
return false // not the right item, ignore
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
package genericresource
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/swarmkit/api"
|
||||
)
|
||||
|
||||
func newParseError(format string, args ...interface{}) error {
|
||||
return fmt.Errorf("could not parse GenericResource: "+format, args...)
|
||||
}
|
||||
|
||||
// discreteResourceVal returns an int64 if the string is a discreteResource
|
||||
// and an error if it isn't
|
||||
func discreteResourceVal(res string) (int64, error) {
|
||||
return strconv.ParseInt(res, 10, 64)
|
||||
}
|
||||
|
||||
// allNamedResources returns true if the array of resources are all namedResources
|
||||
// e.g: res = [red, orange, green]
|
||||
func allNamedResources(res []string) bool {
|
||||
for _, v := range res {
|
||||
if _, err := discreteResourceVal(v); err == nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// ParseCmd parses the Generic Resource command line argument
|
||||
// and returns a list of *api.GenericResource
|
||||
func ParseCmd(cmd string) ([]*api.GenericResource, error) {
|
||||
if strings.Contains(cmd, "\n") {
|
||||
return nil, newParseError("unexpected '\\n' character")
|
||||
}
|
||||
|
||||
r := csv.NewReader(strings.NewReader(cmd))
|
||||
records, err := r.ReadAll()
|
||||
|
||||
if err != nil {
|
||||
return nil, newParseError("%v", err)
|
||||
}
|
||||
|
||||
if len(records) != 1 {
|
||||
return nil, newParseError("found multiple records while parsing cmd %v", records)
|
||||
}
|
||||
|
||||
return Parse(records[0])
|
||||
}
|
||||
|
||||
// Parse parses a table of GenericResource resources
|
||||
func Parse(cmds []string) ([]*api.GenericResource, error) {
|
||||
tokens := make(map[string][]string)
|
||||
|
||||
for _, term := range cmds {
|
||||
kva := strings.Split(term, "=")
|
||||
if len(kva) != 2 {
|
||||
return nil, newParseError("incorrect term %s, missing"+
|
||||
" '=' or malformed expression", term)
|
||||
}
|
||||
|
||||
key := strings.TrimSpace(kva[0])
|
||||
val := strings.TrimSpace(kva[1])
|
||||
|
||||
tokens[key] = append(tokens[key], val)
|
||||
}
|
||||
|
||||
var rs []*api.GenericResource
|
||||
for k, v := range tokens {
|
||||
if u, ok := isDiscreteResource(v); ok {
|
||||
if u < 0 {
|
||||
return nil, newParseError("cannot ask for"+
|
||||
" negative resource %s", k)
|
||||
}
|
||||
|
||||
rs = append(rs, NewDiscrete(k, u))
|
||||
continue
|
||||
}
|
||||
|
||||
if allNamedResources(v) {
|
||||
rs = append(rs, NewSet(k, v...)...)
|
||||
continue
|
||||
}
|
||||
|
||||
return nil, newParseError("mixed discrete and named resources"+
|
||||
" in expression '%s=%s'", k, v)
|
||||
}
|
||||
|
||||
return rs, nil
|
||||
}
|
||||
|
||||
// isDiscreteResource returns true if the array of resources is a
|
||||
// Discrete Resource.
|
||||
// e.g: res = [1]
|
||||
func isDiscreteResource(values []string) (int64, bool) {
|
||||
if len(values) != 1 {
|
||||
return int64(0), false
|
||||
}
|
||||
|
||||
u, err := discreteResourceVal(values[0])
|
||||
if err != nil {
|
||||
return int64(0), false
|
||||
}
|
||||
|
||||
return u, true
|
||||
|
||||
}
|
202
vendor/github.com/docker/swarmkit/api/genericresource/resource_management.go
generated
vendored
Normal file
202
vendor/github.com/docker/swarmkit/api/genericresource/resource_management.go
generated
vendored
Normal file
|
@ -0,0 +1,202 @@
|
|||
package genericresource
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/docker/swarmkit/api"
|
||||
)
|
||||
|
||||
// Claim assigns GenericResources to a task by taking them from the
|
||||
// node's GenericResource list and storing them in the task's available list
|
||||
func Claim(nodeAvailableResources, taskAssigned *[]*api.GenericResource,
|
||||
taskReservations []*api.GenericResource) error {
|
||||
var resSelected []*api.GenericResource
|
||||
|
||||
for _, res := range taskReservations {
|
||||
tr := res.GetDiscreteResourceSpec()
|
||||
if tr == nil {
|
||||
return fmt.Errorf("task should only hold Discrete type")
|
||||
}
|
||||
|
||||
// Select the resources
|
||||
nrs, err := selectNodeResources(*nodeAvailableResources, tr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resSelected = append(resSelected, nrs...)
|
||||
}
|
||||
|
||||
ClaimResources(nodeAvailableResources, taskAssigned, resSelected)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClaimResources adds the specified resources to the task's list
|
||||
// and removes them from the node's generic resource list
|
||||
func ClaimResources(nodeAvailableResources, taskAssigned *[]*api.GenericResource,
|
||||
resSelected []*api.GenericResource) {
|
||||
*taskAssigned = append(*taskAssigned, resSelected...)
|
||||
ConsumeNodeResources(nodeAvailableResources, resSelected)
|
||||
}
|
||||
|
||||
func selectNodeResources(nodeRes []*api.GenericResource,
|
||||
tr *api.DiscreteGenericResource) ([]*api.GenericResource, error) {
|
||||
var nrs []*api.GenericResource
|
||||
|
||||
for _, res := range nodeRes {
|
||||
if Kind(res) != tr.Kind {
|
||||
continue
|
||||
}
|
||||
|
||||
switch nr := res.Resource.(type) {
|
||||
case *api.GenericResource_DiscreteResourceSpec:
|
||||
if nr.DiscreteResourceSpec.Value >= tr.Value && tr.Value != 0 {
|
||||
nrs = append(nrs, NewDiscrete(tr.Kind, tr.Value))
|
||||
}
|
||||
|
||||
return nrs, nil
|
||||
case *api.GenericResource_NamedResourceSpec:
|
||||
nrs = append(nrs, res.Copy())
|
||||
|
||||
if int64(len(nrs)) == tr.Value {
|
||||
return nrs, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(nrs) == 0 {
|
||||
return nil, fmt.Errorf("not enough resources available for task reservations: %+v", tr)
|
||||
}
|
||||
|
||||
return nrs, nil
|
||||
}
|
||||
|
||||
// Reclaim adds the resources taken by the task to the node's store
|
||||
func Reclaim(nodeAvailableResources *[]*api.GenericResource, taskAssigned, nodeRes []*api.GenericResource) error {
|
||||
err := reclaimResources(nodeAvailableResources, taskAssigned)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sanitize(nodeRes, nodeAvailableResources)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func reclaimResources(nodeAvailableResources *[]*api.GenericResource, taskAssigned []*api.GenericResource) error {
|
||||
// The node could have been updated
|
||||
if nodeAvailableResources == nil {
|
||||
return fmt.Errorf("node no longer has any resources")
|
||||
}
|
||||
|
||||
for _, res := range taskAssigned {
|
||||
switch tr := res.Resource.(type) {
|
||||
case *api.GenericResource_DiscreteResourceSpec:
|
||||
nrs := GetResource(tr.DiscreteResourceSpec.Kind, *nodeAvailableResources)
|
||||
|
||||
// If the resource went down to 0 it's no longer in the
|
||||
// available list
|
||||
if len(nrs) == 0 {
|
||||
*nodeAvailableResources = append(*nodeAvailableResources, res.Copy())
|
||||
}
|
||||
|
||||
if len(nrs) != 1 {
|
||||
continue // Type change
|
||||
}
|
||||
|
||||
nr := nrs[0].GetDiscreteResourceSpec()
|
||||
if nr == nil {
|
||||
continue // Type change
|
||||
}
|
||||
|
||||
nr.Value += tr.DiscreteResourceSpec.Value
|
||||
case *api.GenericResource_NamedResourceSpec:
|
||||
*nodeAvailableResources = append(*nodeAvailableResources, res.Copy())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// sanitize checks that nodeAvailableResources does not add resources unknown
|
||||
// to the nodeSpec (nodeRes) or goes over the integer bound specified
|
||||
// by the spec.
|
||||
// Note this is because the user is able to update a node's resources
|
||||
func sanitize(nodeRes []*api.GenericResource, nodeAvailableResources *[]*api.GenericResource) {
|
||||
// - We add the sanitized resources at the end, after
|
||||
// having removed the elements from the list
|
||||
|
||||
// - When a set changes to a Discrete we also need
|
||||
// to make sure that we don't add the Discrete multiple
|
||||
// time hence, the need of a map to remember that
|
||||
var sanitized []*api.GenericResource
|
||||
kindSanitized := make(map[string]struct{})
|
||||
w := 0
|
||||
|
||||
for _, na := range *nodeAvailableResources {
|
||||
ok, nrs := sanitizeResource(nodeRes, na)
|
||||
if !ok {
|
||||
if _, ok = kindSanitized[Kind(na)]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
kindSanitized[Kind(na)] = struct{}{}
|
||||
sanitized = append(sanitized, nrs...)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
(*nodeAvailableResources)[w] = na
|
||||
w++
|
||||
}
|
||||
|
||||
*nodeAvailableResources = (*nodeAvailableResources)[:w]
|
||||
*nodeAvailableResources = append(*nodeAvailableResources, sanitized...)
|
||||
}
|
||||
|
||||
// Returns true if the element is in nodeRes and "sane"
|
||||
// Returns false if the element isn't in nodeRes and "sane" and the element(s) that should be replacing it
|
||||
func sanitizeResource(nodeRes []*api.GenericResource, res *api.GenericResource) (ok bool, nrs []*api.GenericResource) {
|
||||
switch na := res.Resource.(type) {
|
||||
case *api.GenericResource_DiscreteResourceSpec:
|
||||
nrs := GetResource(na.DiscreteResourceSpec.Kind, nodeRes)
|
||||
|
||||
// Type change or removed: reset
|
||||
if len(nrs) != 1 {
|
||||
return false, nrs
|
||||
}
|
||||
|
||||
// Type change: reset
|
||||
nr := nrs[0].GetDiscreteResourceSpec()
|
||||
if nr == nil {
|
||||
return false, nrs
|
||||
}
|
||||
|
||||
// Amount change: reset
|
||||
if na.DiscreteResourceSpec.Value > nr.Value {
|
||||
return false, nrs
|
||||
}
|
||||
case *api.GenericResource_NamedResourceSpec:
|
||||
nrs := GetResource(na.NamedResourceSpec.Kind, nodeRes)
|
||||
|
||||
// Type change
|
||||
if len(nrs) == 0 {
|
||||
return false, nrs
|
||||
}
|
||||
|
||||
for _, nr := range nrs {
|
||||
// Type change: reset
|
||||
if nr.GetDiscreteResourceSpec() != nil {
|
||||
return false, nrs
|
||||
}
|
||||
|
||||
if na.NamedResourceSpec.Value == nr.GetNamedResourceSpec().Value {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Removed
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package genericresource
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/swarmkit/api"
|
||||
)
|
||||
|
||||
func discreteToString(d *api.GenericResource_DiscreteResourceSpec) string {
|
||||
return strconv.FormatInt(d.DiscreteResourceSpec.Value, 10)
|
||||
}
|
||||
|
||||
// Kind returns the kind key as a string
|
||||
func Kind(res *api.GenericResource) string {
|
||||
switch r := res.Resource.(type) {
|
||||
case *api.GenericResource_DiscreteResourceSpec:
|
||||
return r.DiscreteResourceSpec.Kind
|
||||
case *api.GenericResource_NamedResourceSpec:
|
||||
return r.NamedResourceSpec.Kind
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// Value returns the value key as a string
|
||||
func Value(res *api.GenericResource) string {
|
||||
switch res := res.Resource.(type) {
|
||||
case *api.GenericResource_DiscreteResourceSpec:
|
||||
return discreteToString(res)
|
||||
case *api.GenericResource_NamedResourceSpec:
|
||||
return res.NamedResourceSpec.Value
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// EnvFormat returns the environment string version of the resource
|
||||
func EnvFormat(res []*api.GenericResource, prefix string) []string {
|
||||
envs := make(map[string][]string)
|
||||
for _, v := range res {
|
||||
key := Kind(v)
|
||||
val := Value(v)
|
||||
envs[key] = append(envs[key], val)
|
||||
}
|
||||
|
||||
env := make([]string, 0, len(res))
|
||||
for k, v := range envs {
|
||||
k = strings.ToUpper(prefix + "_" + k)
|
||||
env = append(env, k+"="+strings.Join(v, ","))
|
||||
}
|
||||
|
||||
return env
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package genericresource
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/docker/swarmkit/api"
|
||||
)
|
||||
|
||||
// ValidateTask validates that the task only uses integers
|
||||
// for generic resources
|
||||
func ValidateTask(resources *api.Resources) error {
|
||||
for _, v := range resources.Generic {
|
||||
if v.GetDiscreteResourceSpec() != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
return fmt.Errorf("invalid argument for resource %s", Kind(v))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasEnough returns true if node can satisfy the task's GenericResource request
|
||||
func HasEnough(nodeRes []*api.GenericResource, taskRes *api.GenericResource) (bool, error) {
|
||||
t := taskRes.GetDiscreteResourceSpec()
|
||||
if t == nil {
|
||||
return false, fmt.Errorf("task should only hold Discrete type")
|
||||
}
|
||||
|
||||
if nodeRes == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
nrs := GetResource(t.Kind, nodeRes)
|
||||
if len(nrs) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
switch nr := nrs[0].Resource.(type) {
|
||||
case *api.GenericResource_DiscreteResourceSpec:
|
||||
if t.Value > nr.DiscreteResourceSpec.Value {
|
||||
return false, nil
|
||||
}
|
||||
case *api.GenericResource_NamedResourceSpec:
|
||||
if t.Value > int64(len(nrs)) {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// HasResource checks if there is enough "res" in the "resources" argument
|
||||
func HasResource(res *api.GenericResource, resources []*api.GenericResource) bool {
|
||||
for _, r := range resources {
|
||||
if Kind(res) != Kind(r) {
|
||||
continue
|
||||
}
|
||||
|
||||
switch rtype := r.Resource.(type) {
|
||||
case *api.GenericResource_DiscreteResourceSpec:
|
||||
if res.GetDiscreteResourceSpec() == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if res.GetDiscreteResourceSpec().Value < rtype.DiscreteResourceSpec.Value {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
case *api.GenericResource_NamedResourceSpec:
|
||||
if res.GetNamedResourceSpec() == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if res.GetNamedResourceSpec().Value != rtype.NamedResourceSpec.Value {
|
||||
continue
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
|
@ -620,6 +620,9 @@ type ContainerSpec struct {
|
|||
// Isolation defines the isolation level for windows containers (default, process, hyperv).
|
||||
// Runtimes that don't support it ignore that field
|
||||
Isolation ContainerSpec_Isolation `protobuf:"varint,24,opt,name=isolation,proto3,enum=docker.swarmkit.v1.ContainerSpec_Isolation" json:"isolation,omitempty"`
|
||||
// PidsLimit prevents from OS resource damage by applications inside the container
|
||||
// using fork bomb attack.
|
||||
PidsLimit int64 `protobuf:"varint,25,opt,name=pidsLimit,proto3" json:"pidsLimit,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ContainerSpec) Reset() { *m = ContainerSpec{} }
|
||||
|
@ -2055,6 +2058,13 @@ func (m *ContainerSpec) MarshalTo(dAtA []byte) (int, error) {
|
|||
i++
|
||||
i = encodeVarintSpecs(dAtA, i, uint64(m.Isolation))
|
||||
}
|
||||
if m.PidsLimit != 0 {
|
||||
dAtA[i] = 0xc8
|
||||
i++
|
||||
dAtA[i] = 0x1
|
||||
i++
|
||||
i = encodeVarintSpecs(dAtA, i, uint64(m.PidsLimit))
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
|
@ -2787,6 +2797,9 @@ func (m *ContainerSpec) Size() (n int) {
|
|||
if m.Isolation != 0 {
|
||||
n += 2 + sovSpecs(uint64(m.Isolation))
|
||||
}
|
||||
if m.PidsLimit != 0 {
|
||||
n += 2 + sovSpecs(uint64(m.PidsLimit))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
@ -3134,6 +3147,7 @@ func (this *ContainerSpec) String() string {
|
|||
`Privileges:` + strings.Replace(fmt.Sprintf("%v", this.Privileges), "Privileges", "Privileges", 1) + `,`,
|
||||
`Init:` + strings.Replace(fmt.Sprintf("%v", this.Init), "BoolValue", "google_protobuf4.BoolValue", 1) + `,`,
|
||||
`Isolation:` + fmt.Sprintf("%v", this.Isolation) + `,`,
|
||||
`PidsLimit:` + fmt.Sprintf("%v", this.PidsLimit) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
|
@ -5261,6 +5275,25 @@ func (m *ContainerSpec) Unmarshal(dAtA []byte) error {
|
|||
break
|
||||
}
|
||||
}
|
||||
case 25:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field PidsLimit", wireType)
|
||||
}
|
||||
m.PidsLimit = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowSpecs
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.PidsLimit |= (int64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipSpecs(dAtA[iNdEx:])
|
||||
|
@ -6572,138 +6605,139 @@ var (
|
|||
func init() { proto.RegisterFile("github.com/docker/swarmkit/api/specs.proto", fileDescriptorSpecs) }
|
||||
|
||||
var fileDescriptorSpecs = []byte{
|
||||
// 2114 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4f, 0x6f, 0xdb, 0xc8,
|
||||
0x15, 0xb7, 0x6c, 0x59, 0x96, 0x1e, 0xe5, 0x44, 0x9e, 0x4d, 0xb2, 0xb4, 0xb2, 0xb1, 0x15, 0x6d,
|
||||
0x36, 0xf5, 0xee, 0xa2, 0x32, 0xea, 0x2e, 0xb6, 0xd9, 0x4d, 0xb7, 0xad, 0x64, 0x69, 0x1d, 0x35,
|
||||
0x89, 0x2d, 0x8c, 0x1c, 0xb7, 0x01, 0x0a, 0x08, 0x63, 0x72, 0x2c, 0x11, 0xa6, 0x38, 0xec, 0x70,
|
||||
0xe8, 0x40, 0xb7, 0x1e, 0x17, 0xee, 0x67, 0x30, 0x7a, 0x28, 0x7a, 0x6f, 0xbf, 0x42, 0x4f, 0x39,
|
||||
0xf6, 0xd8, 0x5e, 0x8c, 0xae, 0xbf, 0x42, 0x6f, 0xbd, 0xb4, 0x98, 0xe1, 0x90, 0xa2, 0x1c, 0x3a,
|
||||
0x0e, 0xd0, 0x1c, 0x7a, 0x9b, 0x79, 0xfc, 0xfd, 0xde, 0xfc, 0xfb, 0xbd, 0x37, 0x6f, 0x08, 0x9f,
|
||||
0x0d, 0x1d, 0x31, 0x0a, 0x0f, 0x1b, 0x16, 0x1b, 0x6f, 0xda, 0xcc, 0x3a, 0xa6, 0x7c, 0x33, 0x78,
|
||||
0x45, 0xf8, 0xf8, 0xd8, 0x11, 0x9b, 0xc4, 0x77, 0x36, 0x03, 0x9f, 0x5a, 0x41, 0xc3, 0xe7, 0x4c,
|
||||
0x30, 0x84, 0x22, 0x40, 0x23, 0x06, 0x34, 0x4e, 0x7e, 0x54, 0xbd, 0x8e, 0x2f, 0x26, 0x3e, 0xd5,
|
||||
0xfc, 0xea, 0xad, 0x21, 0x1b, 0x32, 0xd5, 0xdc, 0x94, 0x2d, 0x6d, 0x5d, 0x1b, 0x32, 0x36, 0x74,
|
||||
0xe9, 0xa6, 0xea, 0x1d, 0x86, 0x47, 0x9b, 0x76, 0xc8, 0x89, 0x70, 0x98, 0xa7, 0xbf, 0xaf, 0x5e,
|
||||
0xfe, 0x4e, 0xbc, 0xc9, 0x55, 0xd4, 0x57, 0x9c, 0xf8, 0x3e, 0xe5, 0x7a, 0xc0, 0xfa, 0x59, 0x1e,
|
||||
0x8a, 0xbb, 0xcc, 0xa6, 0x7d, 0x9f, 0x5a, 0x68, 0x07, 0x0c, 0xe2, 0x79, 0x4c, 0x28, 0xdf, 0x81,
|
||||
0x99, 0xab, 0xe5, 0x36, 0x8c, 0xad, 0xf5, 0xc6, 0x9b, 0x6b, 0x6a, 0x34, 0xa7, 0xb0, 0x56, 0xfe,
|
||||
0xf5, 0xf9, 0xfa, 0x1c, 0x4e, 0x33, 0xd1, 0xcf, 0xa1, 0x6c, 0xd3, 0xc0, 0xe1, 0xd4, 0x1e, 0x70,
|
||||
0xe6, 0x52, 0x73, 0xbe, 0x96, 0xdb, 0xb8, 0xb1, 0xf5, 0x51, 0x96, 0x27, 0x39, 0x38, 0x66, 0x2e,
|
||||
0xc5, 0x86, 0x66, 0xc8, 0x0e, 0xda, 0x01, 0x18, 0xd3, 0xf1, 0x21, 0xe5, 0xc1, 0xc8, 0xf1, 0xcd,
|
||||
0x05, 0x45, 0xff, 0xc1, 0x55, 0x74, 0x39, 0xf7, 0xc6, 0xf3, 0x04, 0x8e, 0x53, 0x54, 0xf4, 0x1c,
|
||||
0xca, 0xe4, 0x84, 0x38, 0x2e, 0x39, 0x74, 0x5c, 0x47, 0x4c, 0xcc, 0xbc, 0x72, 0xf5, 0xe9, 0x5b,
|
||||
0x5d, 0x35, 0x53, 0x04, 0x3c, 0x43, 0xaf, 0xdb, 0x00, 0xd3, 0x81, 0xd0, 0x43, 0x58, 0xea, 0x75,
|
||||
0x76, 0xdb, 0xdd, 0xdd, 0x9d, 0xca, 0x5c, 0x75, 0xf5, 0xf4, 0xac, 0x76, 0x5b, 0xfa, 0x98, 0x02,
|
||||
0x7a, 0xd4, 0xb3, 0x1d, 0x6f, 0x88, 0x36, 0xa0, 0xd8, 0xdc, 0xde, 0xee, 0xf4, 0xf6, 0x3b, 0xed,
|
||||
0x4a, 0xae, 0x5a, 0x3d, 0x3d, 0xab, 0xdd, 0x99, 0x05, 0x36, 0x2d, 0x8b, 0xfa, 0x82, 0xda, 0xd5,
|
||||
0xfc, 0x77, 0x7f, 0x5c, 0x9b, 0xab, 0x7f, 0x97, 0x83, 0x72, 0x7a, 0x12, 0xe8, 0x21, 0x14, 0x9a,
|
||||
0xdb, 0xfb, 0xdd, 0x83, 0x4e, 0x65, 0x6e, 0x4a, 0x4f, 0x23, 0x9a, 0x96, 0x70, 0x4e, 0x28, 0x7a,
|
||||
0x00, 0x8b, 0xbd, 0xe6, 0x8b, 0x7e, 0xa7, 0x92, 0x9b, 0x4e, 0x27, 0x0d, 0xeb, 0x91, 0x30, 0x50,
|
||||
0xa8, 0x36, 0x6e, 0x76, 0x77, 0x2b, 0xf3, 0xd9, 0xa8, 0x36, 0x27, 0x8e, 0xa7, 0xa7, 0xf2, 0x87,
|
||||
0x3c, 0x18, 0x7d, 0xca, 0x4f, 0x1c, 0xeb, 0x3d, 0x4b, 0xe4, 0x4b, 0xc8, 0x0b, 0x12, 0x1c, 0x2b,
|
||||
0x69, 0x18, 0xd9, 0xd2, 0xd8, 0x27, 0xc1, 0xb1, 0x1c, 0x54, 0xd3, 0x15, 0x5e, 0x2a, 0x83, 0x53,
|
||||
0xdf, 0x75, 0x2c, 0x22, 0xa8, 0xad, 0x94, 0x61, 0x6c, 0x7d, 0x92, 0xc5, 0xc6, 0x09, 0x4a, 0xcf,
|
||||
0xff, 0xc9, 0x1c, 0x4e, 0x51, 0xd1, 0x63, 0x28, 0x0c, 0x5d, 0x76, 0x48, 0x5c, 0xa5, 0x09, 0x63,
|
||||
0xeb, 0x7e, 0x96, 0x93, 0x1d, 0x85, 0x98, 0x3a, 0xd0, 0x14, 0xf4, 0x08, 0x0a, 0xa1, 0x6f, 0x13,
|
||||
0x41, 0xcd, 0x82, 0x22, 0xd7, 0xb2, 0xc8, 0x2f, 0x14, 0x62, 0x9b, 0x79, 0x47, 0xce, 0x10, 0x6b,
|
||||
0x3c, 0x7a, 0x0a, 0x45, 0x8f, 0x8a, 0x57, 0x8c, 0x1f, 0x07, 0xe6, 0x52, 0x6d, 0x61, 0xc3, 0xd8,
|
||||
0xfa, 0x3c, 0x53, 0x8c, 0x11, 0xa6, 0x29, 0x04, 0xb1, 0x46, 0x63, 0xea, 0x89, 0xc8, 0x4d, 0x6b,
|
||||
0xde, 0xcc, 0xe1, 0xc4, 0x01, 0xfa, 0x29, 0x14, 0xa9, 0x67, 0xfb, 0xcc, 0xf1, 0x84, 0x59, 0xbc,
|
||||
0x7a, 0x22, 0x1d, 0x8d, 0x91, 0x9b, 0x89, 0x13, 0x86, 0x64, 0x73, 0xe6, 0xba, 0x87, 0xc4, 0x3a,
|
||||
0x36, 0x4b, 0xef, 0xb8, 0x8c, 0x84, 0xd1, 0x2a, 0x40, 0x7e, 0xcc, 0x6c, 0x5a, 0xdf, 0x84, 0x95,
|
||||
0x37, 0xb6, 0x1a, 0x55, 0xa1, 0xa8, 0xb7, 0x3a, 0xd2, 0x48, 0x1e, 0x27, 0xfd, 0xfa, 0x4d, 0x58,
|
||||
0x9e, 0xd9, 0xd6, 0xfa, 0x9f, 0x17, 0xa1, 0x18, 0x9f, 0x35, 0x6a, 0x42, 0xc9, 0x62, 0x9e, 0x20,
|
||||
0x8e, 0x47, 0xb9, 0x96, 0x57, 0xe6, 0xc9, 0x6c, 0xc7, 0x20, 0xc9, 0x7a, 0x32, 0x87, 0xa7, 0x2c,
|
||||
0xf4, 0x2d, 0x94, 0x38, 0x0d, 0x58, 0xc8, 0x2d, 0x1a, 0x68, 0x7d, 0x6d, 0x64, 0x2b, 0x24, 0x02,
|
||||
0x61, 0xfa, 0xdb, 0xd0, 0xe1, 0x54, 0xee, 0x72, 0x80, 0xa7, 0x54, 0xf4, 0x18, 0x96, 0x38, 0x0d,
|
||||
0x04, 0xe1, 0xe2, 0x6d, 0x12, 0xc1, 0x11, 0xa4, 0xc7, 0x5c, 0xc7, 0x9a, 0xe0, 0x98, 0x81, 0x1e,
|
||||
0x43, 0xc9, 0x77, 0x89, 0xa5, 0xbc, 0x9a, 0x8b, 0x8a, 0x7e, 0x2f, 0x8b, 0xde, 0x8b, 0x41, 0x78,
|
||||
0x8a, 0x47, 0x5f, 0x01, 0xb8, 0x6c, 0x38, 0xb0, 0xb9, 0x73, 0x42, 0xb9, 0x96, 0x58, 0x35, 0x8b,
|
||||
0xdd, 0x56, 0x08, 0x5c, 0x72, 0xd9, 0x30, 0x6a, 0xa2, 0x9d, 0xff, 0x49, 0x5f, 0x29, 0x6d, 0x3d,
|
||||
0x05, 0x20, 0xc9, 0x57, 0xad, 0xae, 0x4f, 0xdf, 0xc9, 0x95, 0x3e, 0x91, 0x14, 0x1d, 0xdd, 0x87,
|
||||
0xf2, 0x11, 0xe3, 0x16, 0x1d, 0xe8, 0xa8, 0x29, 0x29, 0x4d, 0x18, 0xca, 0x16, 0xe9, 0x0b, 0xb5,
|
||||
0x60, 0x69, 0x48, 0x3d, 0xca, 0x1d, 0xcb, 0x04, 0x35, 0xd8, 0xc3, 0xcc, 0x80, 0x8c, 0x20, 0x38,
|
||||
0xf4, 0x84, 0x33, 0xa6, 0x7a, 0xa4, 0x98, 0x88, 0x7e, 0x03, 0x1f, 0xc4, 0xc7, 0x37, 0xe0, 0xf4,
|
||||
0x88, 0x72, 0xea, 0x49, 0x0d, 0x18, 0x6a, 0x1f, 0x3e, 0x79, 0xbb, 0x06, 0x34, 0x5a, 0x27, 0x1b,
|
||||
0xc4, 0x2f, 0x7f, 0x08, 0x5a, 0x25, 0x58, 0xe2, 0xd1, 0xb8, 0xf5, 0xdf, 0xe7, 0xa4, 0xea, 0x2f,
|
||||
0x21, 0xd0, 0x26, 0x18, 0xc9, 0xf0, 0x8e, 0xad, 0xd4, 0x5b, 0x6a, 0xdd, 0xb8, 0x38, 0x5f, 0x87,
|
||||
0x18, 0xdb, 0x6d, 0xcb, 0x1c, 0xa4, 0xdb, 0x36, 0xea, 0xc0, 0x72, 0x42, 0x90, 0x65, 0x80, 0xbe,
|
||||
0x28, 0x6b, 0x6f, 0x9b, 0xe9, 0xfe, 0xc4, 0xa7, 0xb8, 0xcc, 0x53, 0xbd, 0xfa, 0xaf, 0x01, 0xbd,
|
||||
0xb9, 0x2f, 0x08, 0x41, 0xfe, 0xd8, 0xf1, 0xf4, 0x34, 0xb0, 0x6a, 0xa3, 0x06, 0x2c, 0xf9, 0x64,
|
||||
0xe2, 0x32, 0x62, 0xeb, 0xc0, 0xb8, 0xd5, 0x88, 0x0a, 0x84, 0x46, 0x5c, 0x20, 0x34, 0x9a, 0xde,
|
||||
0x04, 0xc7, 0xa0, 0xfa, 0x53, 0xb8, 0x9d, 0x79, 0xbc, 0x68, 0x0b, 0xca, 0x49, 0xc0, 0x4d, 0xd7,
|
||||
0x7a, 0xf3, 0xe2, 0x7c, 0xdd, 0x48, 0x22, 0xb3, 0xdb, 0xc6, 0x46, 0x02, 0xea, 0xda, 0xf5, 0xbf,
|
||||
0x1a, 0xb0, 0x3c, 0x13, 0xb6, 0xe8, 0x16, 0x2c, 0x3a, 0x63, 0x32, 0xa4, 0x7a, 0x8e, 0x51, 0x07,
|
||||
0x75, 0xa0, 0xe0, 0x92, 0x43, 0xea, 0xca, 0xe0, 0x95, 0x07, 0xf7, 0xc3, 0x6b, 0xe3, 0xbf, 0xf1,
|
||||
0x4c, 0xe1, 0x3b, 0x9e, 0xe0, 0x13, 0xac, 0xc9, 0xc8, 0x84, 0x25, 0x8b, 0x8d, 0xc7, 0xc4, 0x93,
|
||||
0xd7, 0xc4, 0xc2, 0x46, 0x09, 0xc7, 0x5d, 0xb9, 0x33, 0x84, 0x0f, 0x03, 0x33, 0xaf, 0xcc, 0xaa,
|
||||
0x8d, 0x2a, 0xb0, 0x40, 0xbd, 0x13, 0x73, 0x51, 0x99, 0x64, 0x53, 0x5a, 0x6c, 0x27, 0x8a, 0xbe,
|
||||
0x12, 0x96, 0x4d, 0xc9, 0x0b, 0x03, 0xca, 0xcd, 0xa5, 0x68, 0x47, 0x65, 0x1b, 0xfd, 0x04, 0x0a,
|
||||
0x63, 0x16, 0x7a, 0x22, 0x30, 0x8b, 0x6a, 0xb2, 0xab, 0x59, 0x93, 0x7d, 0x2e, 0x11, 0x5a, 0x59,
|
||||
0x1a, 0x8e, 0x3a, 0xb0, 0x12, 0x08, 0xe6, 0x0f, 0x86, 0x9c, 0x58, 0x74, 0xe0, 0x53, 0xee, 0x30,
|
||||
0x5b, 0xa7, 0xe1, 0xd5, 0x37, 0x0e, 0xa5, 0xad, 0x0b, 0x3e, 0x7c, 0x53, 0x72, 0x76, 0x24, 0xa5,
|
||||
0xa7, 0x18, 0xa8, 0x07, 0x65, 0x3f, 0x74, 0xdd, 0x01, 0xf3, 0xa3, 0x1b, 0x39, 0x8a, 0x9d, 0x77,
|
||||
0xd8, 0xb2, 0x5e, 0xe8, 0xba, 0x7b, 0x11, 0x09, 0x1b, 0xfe, 0xb4, 0x83, 0xee, 0x40, 0x61, 0xc8,
|
||||
0x59, 0xe8, 0x47, 0x71, 0x53, 0xc2, 0xba, 0x87, 0xbe, 0x81, 0xa5, 0x80, 0x5a, 0x9c, 0x8a, 0xc0,
|
||||
0x2c, 0xab, 0xa5, 0x7e, 0x9c, 0x35, 0x48, 0x5f, 0x41, 0x92, 0x98, 0xc0, 0x31, 0x07, 0xad, 0xc2,
|
||||
0x82, 0x10, 0x13, 0x73, 0xb9, 0x96, 0xdb, 0x28, 0xb6, 0x96, 0x2e, 0xce, 0xd7, 0x17, 0xf6, 0xf7,
|
||||
0x5f, 0x62, 0x69, 0x93, 0xb7, 0xc5, 0x88, 0x05, 0xc2, 0x23, 0x63, 0x6a, 0xde, 0x50, 0x7b, 0x9b,
|
||||
0xf4, 0xd1, 0x4b, 0x00, 0xdb, 0x0b, 0x06, 0x96, 0x4a, 0x4f, 0xe6, 0x4d, 0xb5, 0xba, 0xcf, 0xaf,
|
||||
0x5f, 0x5d, 0x7b, 0xb7, 0xaf, 0x6f, 0xcc, 0xe5, 0x8b, 0xf3, 0xf5, 0x52, 0xd2, 0xc5, 0x25, 0xdb,
|
||||
0x0b, 0xa2, 0x26, 0x6a, 0x81, 0x31, 0xa2, 0xc4, 0x15, 0x23, 0x6b, 0x44, 0xad, 0x63, 0xb3, 0x72,
|
||||
0xf5, 0x15, 0xf8, 0x44, 0xc1, 0xb4, 0x87, 0x34, 0x49, 0x2a, 0x58, 0x4e, 0x35, 0x30, 0x57, 0xd4,
|
||||
0x5e, 0x45, 0x1d, 0x74, 0x0f, 0x80, 0xf9, 0xd4, 0x1b, 0x04, 0xc2, 0x76, 0x3c, 0x13, 0xc9, 0x25,
|
||||
0xe3, 0x92, 0xb4, 0xf4, 0xa5, 0x01, 0xdd, 0x95, 0x17, 0x14, 0xb1, 0x07, 0xcc, 0x73, 0x27, 0xe6,
|
||||
0x07, 0xea, 0x6b, 0x51, 0x1a, 0xf6, 0x3c, 0x77, 0x82, 0xd6, 0xc1, 0x50, 0xba, 0x08, 0x9c, 0xa1,
|
||||
0x47, 0x5c, 0xf3, 0x96, 0xda, 0x0f, 0x90, 0xa6, 0xbe, 0xb2, 0xc8, 0x73, 0x88, 0x76, 0x23, 0x30,
|
||||
0x6f, 0x5f, 0x7d, 0x0e, 0x7a, 0xb2, 0xd3, 0x73, 0xd0, 0x1c, 0xf4, 0x33, 0x00, 0x9f, 0x3b, 0x27,
|
||||
0x8e, 0x4b, 0x87, 0x34, 0x30, 0xef, 0xa8, 0x45, 0xaf, 0x65, 0xde, 0x4c, 0x09, 0x0a, 0xa7, 0x18,
|
||||
0xa8, 0x01, 0x79, 0xc7, 0x73, 0x84, 0xf9, 0xa1, 0xbe, 0x95, 0x2e, 0x4b, 0xb5, 0xc5, 0x98, 0x7b,
|
||||
0x40, 0xdc, 0x90, 0x62, 0x85, 0x43, 0x5d, 0x28, 0x39, 0x01, 0x73, 0x95, 0x7c, 0x4d, 0x53, 0xe5,
|
||||
0xb7, 0x77, 0x38, 0xbf, 0x6e, 0x4c, 0xc1, 0x53, 0x76, 0xf5, 0x2b, 0x30, 0x52, 0x81, 0x2e, 0x03,
|
||||
0xf4, 0x98, 0x4e, 0x74, 0xee, 0x90, 0x4d, 0x79, 0x1a, 0x27, 0x72, 0x68, 0x95, 0xdc, 0x4a, 0x38,
|
||||
0xea, 0x7c, 0x3d, 0xff, 0x28, 0x57, 0xdd, 0x02, 0x23, 0x25, 0x78, 0xf4, 0xb1, 0x4c, 0xbc, 0x43,
|
||||
0x27, 0x10, 0x7c, 0x32, 0x20, 0xa1, 0x18, 0x99, 0xbf, 0x50, 0x84, 0x72, 0x6c, 0x6c, 0x86, 0x62,
|
||||
0x54, 0x1d, 0xc0, 0x54, 0x37, 0xa8, 0x06, 0x86, 0xd4, 0x63, 0x40, 0xf9, 0x09, 0xe5, 0xb2, 0xa8,
|
||||
0x91, 0xc7, 0x9d, 0x36, 0xc9, 0xb8, 0x09, 0x28, 0xe1, 0xd6, 0x48, 0xa5, 0xad, 0x12, 0xd6, 0x3d,
|
||||
0x99, 0x87, 0xe2, 0xe0, 0xd4, 0x79, 0x48, 0x77, 0xeb, 0x7f, 0xc9, 0x41, 0x29, 0x59, 0x28, 0xfa,
|
||||
0x02, 0x56, 0xba, 0xfd, 0xbd, 0x67, 0xcd, 0xfd, 0xee, 0xde, 0xee, 0xa0, 0xdd, 0xf9, 0xb6, 0xf9,
|
||||
0xe2, 0xd9, 0x7e, 0x65, 0xae, 0x7a, 0xef, 0xf4, 0xac, 0xb6, 0x3a, 0xcd, 0xa9, 0x31, 0xbc, 0x4d,
|
||||
0x8f, 0x48, 0xe8, 0x8a, 0x59, 0x56, 0x0f, 0xef, 0x6d, 0x77, 0xfa, 0xfd, 0x4a, 0xee, 0x2a, 0x56,
|
||||
0x8f, 0x33, 0x8b, 0x06, 0x01, 0xda, 0x82, 0xca, 0x94, 0xf5, 0xe4, 0x65, 0xaf, 0x83, 0x0f, 0x2a,
|
||||
0xf3, 0xd5, 0x8f, 0x4e, 0xcf, 0x6a, 0xe6, 0x9b, 0xa4, 0x27, 0x13, 0x9f, 0xf2, 0x03, 0xfd, 0x20,
|
||||
0xf8, 0x57, 0x0e, 0xca, 0xe9, 0x7a, 0x12, 0x6d, 0x47, 0x75, 0xa0, 0x3a, 0x86, 0x1b, 0x5b, 0x9b,
|
||||
0xd7, 0xd5, 0x9f, 0xea, 0x1e, 0x73, 0x43, 0xe9, 0xf7, 0xb9, 0x7c, 0xfa, 0x29, 0x32, 0xfa, 0x02,
|
||||
0x16, 0x7d, 0xc6, 0x45, 0x9c, 0xf1, 0xb3, 0xf5, 0xc8, 0x78, 0x5c, 0xa5, 0x44, 0xe0, 0xfa, 0x08,
|
||||
0x6e, 0xcc, 0x7a, 0x43, 0x0f, 0x60, 0xe1, 0xa0, 0xdb, 0xab, 0xcc, 0x55, 0xef, 0x9e, 0x9e, 0xd5,
|
||||
0x3e, 0x9c, 0xfd, 0x78, 0xe0, 0x70, 0x11, 0x12, 0xb7, 0xdb, 0x43, 0x9f, 0xc1, 0x62, 0x7b, 0xb7,
|
||||
0x8f, 0x71, 0x25, 0x57, 0x5d, 0x3f, 0x3d, 0xab, 0xdd, 0x9d, 0xc5, 0xc9, 0x4f, 0x2c, 0xf4, 0x6c,
|
||||
0xcc, 0x0e, 0x93, 0x67, 0xd0, 0xbf, 0xe7, 0xc1, 0xd0, 0x17, 0xe1, 0xfb, 0x7e, 0x29, 0x2f, 0x47,
|
||||
0x55, 0x5e, 0x9c, 0xe1, 0xe6, 0xaf, 0x2d, 0xf6, 0xca, 0x11, 0x41, 0xeb, 0xf2, 0x3e, 0x94, 0x1d,
|
||||
0xff, 0xe4, 0xcb, 0x01, 0xf5, 0xc8, 0xa1, 0xab, 0x5f, 0x44, 0x45, 0x6c, 0x48, 0x5b, 0x27, 0x32,
|
||||
0xc9, 0xf4, 0xea, 0x78, 0x82, 0x72, 0x4f, 0xbf, 0x75, 0x8a, 0x38, 0xe9, 0xa3, 0x6f, 0x20, 0xef,
|
||||
0xf8, 0x64, 0xac, 0x2b, 0xd4, 0xcc, 0x15, 0x74, 0x7b, 0xcd, 0xe7, 0x3a, 0x6e, 0x5a, 0xc5, 0x8b,
|
||||
0xf3, 0xf5, 0xbc, 0x34, 0x60, 0x45, 0x43, 0x6b, 0x71, 0x91, 0x28, 0x47, 0x52, 0x57, 0x65, 0x11,
|
||||
0xa7, 0x2c, 0x52, 0xfb, 0x8e, 0x37, 0xe4, 0x34, 0x08, 0xd4, 0xa5, 0x59, 0xc4, 0x71, 0x17, 0x55,
|
||||
0x61, 0x49, 0x97, 0x9a, 0xaa, 0xb6, 0x2c, 0xc9, 0x32, 0x4e, 0x1b, 0x5a, 0xcb, 0x60, 0x44, 0xbb,
|
||||
0x31, 0x38, 0xe2, 0x6c, 0x5c, 0xff, 0x4f, 0x1e, 0x8c, 0x6d, 0x37, 0x0c, 0x84, 0xae, 0x1a, 0xde,
|
||||
0xdb, 0xe6, 0xbf, 0x84, 0x15, 0xa2, 0x5e, 0xde, 0xc4, 0x93, 0x57, 0xb0, 0xaa, 0xe0, 0xf5, 0x01,
|
||||
0x3c, 0xc8, 0x74, 0x97, 0x80, 0xa3, 0x6a, 0xbf, 0x55, 0x90, 0x3e, 0xcd, 0x1c, 0xae, 0x90, 0x4b,
|
||||
0x5f, 0x50, 0x1f, 0x96, 0x19, 0xb7, 0x46, 0x34, 0x10, 0xd1, 0xc5, 0xad, 0x5f, 0xaa, 0x99, 0xff,
|
||||
0x30, 0xf6, 0xd2, 0x40, 0x7d, 0x6b, 0x45, 0xb3, 0x9d, 0xf5, 0x81, 0x1e, 0x41, 0x9e, 0x93, 0xa3,
|
||||
0xf8, 0x35, 0x92, 0x19, 0x24, 0x98, 0x1c, 0x89, 0x19, 0x17, 0x8a, 0x81, 0x7e, 0x09, 0x60, 0x3b,
|
||||
0x81, 0x4f, 0x84, 0x35, 0xa2, 0x5c, 0x1f, 0x76, 0xe6, 0x12, 0xdb, 0x09, 0x6a, 0xc6, 0x4b, 0x8a,
|
||||
0x8d, 0x9e, 0x42, 0xc9, 0x22, 0xb1, 0x5c, 0x0b, 0x57, 0x3f, 0xdf, 0xb7, 0x9b, 0xda, 0x45, 0x45,
|
||||
0xba, 0xb8, 0x38, 0x5f, 0x2f, 0xc6, 0x16, 0x5c, 0xb4, 0x88, 0x96, 0xef, 0x53, 0x58, 0x96, 0xcf,
|
||||
0xfa, 0x81, 0x1d, 0xa5, 0xb3, 0x48, 0x26, 0x57, 0xdc, 0xc2, 0xf2, 0x8d, 0xa8, 0xd3, 0x5e, 0x7c,
|
||||
0x9c, 0x65, 0x91, 0xb2, 0xa1, 0x5f, 0xc1, 0x0a, 0xf5, 0x2c, 0x3e, 0x51, 0x62, 0x8d, 0x67, 0x58,
|
||||
0xbc, 0x7a, 0xb1, 0x9d, 0x04, 0x3c, 0xb3, 0xd8, 0x0a, 0xbd, 0x64, 0xaf, 0xff, 0x23, 0x07, 0x10,
|
||||
0x15, 0x36, 0xef, 0x57, 0x80, 0x08, 0xf2, 0x36, 0x11, 0x44, 0x69, 0xae, 0x8c, 0x55, 0x1b, 0x7d,
|
||||
0x0d, 0x20, 0xe8, 0xd8, 0x97, 0xa9, 0xd7, 0x1b, 0x6a, 0xd9, 0xbc, 0x2d, 0x1d, 0xa4, 0xd0, 0x68,
|
||||
0x0b, 0x0a, 0xfa, 0xcd, 0x98, 0xbf, 0x96, 0xa7, 0x91, 0xf5, 0x3f, 0xe5, 0x00, 0xa2, 0x65, 0xfe,
|
||||
0x5f, 0xaf, 0xad, 0x65, 0xbe, 0xfe, 0x7e, 0x6d, 0xee, 0xef, 0xdf, 0xaf, 0xcd, 0xfd, 0xee, 0x62,
|
||||
0x2d, 0xf7, 0xfa, 0x62, 0x2d, 0xf7, 0xb7, 0x8b, 0xb5, 0xdc, 0x3f, 0x2f, 0xd6, 0x72, 0x87, 0x05,
|
||||
0x55, 0x7b, 0xfc, 0xf8, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x1a, 0xbd, 0x13, 0xac, 0xa9, 0x15,
|
||||
0x00, 0x00,
|
||||
// 2131 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4f, 0x6f, 0x1b, 0xc7,
|
||||
0x15, 0x17, 0x25, 0x8a, 0x22, 0xdf, 0x52, 0x36, 0x35, 0x71, 0x9c, 0x15, 0x6d, 0x4b, 0x34, 0xe3,
|
||||
0xb8, 0x4a, 0x82, 0x52, 0xa8, 0x1a, 0xa4, 0x4e, 0xdc, 0xb4, 0x25, 0x45, 0x46, 0x66, 0x6d, 0x4b,
|
||||
0xc4, 0x50, 0x56, 0x6b, 0xa0, 0x00, 0x31, 0xda, 0x1d, 0x91, 0x03, 0x2d, 0x77, 0xb6, 0xb3, 0x43,
|
||||
0x19, 0xbc, 0xf5, 0x18, 0xa8, 0x9f, 0x41, 0xe8, 0xa1, 0xe8, 0xbd, 0xfd, 0x16, 0x3e, 0xf6, 0xd8,
|
||||
0x5e, 0x84, 0x44, 0x5f, 0xa1, 0xb7, 0x5e, 0x5a, 0xcc, 0xec, 0xec, 0x92, 0x94, 0x57, 0x96, 0x81,
|
||||
0xfa, 0xd0, 0xdb, 0xcc, 0xdb, 0xdf, 0xef, 0xcd, 0xbf, 0xdf, 0xbc, 0xf7, 0x66, 0xe1, 0xb3, 0x3e,
|
||||
0x93, 0x83, 0xd1, 0x61, 0xcd, 0xe1, 0xc3, 0x4d, 0x97, 0x3b, 0xc7, 0x54, 0x6c, 0x86, 0xaf, 0x88,
|
||||
0x18, 0x1e, 0x33, 0xb9, 0x49, 0x02, 0xb6, 0x19, 0x06, 0xd4, 0x09, 0x6b, 0x81, 0xe0, 0x92, 0x23,
|
||||
0x14, 0x01, 0x6a, 0x31, 0xa0, 0x76, 0xf2, 0x93, 0xf2, 0x75, 0x7c, 0x39, 0x0e, 0xa8, 0xe1, 0x97,
|
||||
0x6f, 0xf5, 0x79, 0x9f, 0xeb, 0xe6, 0xa6, 0x6a, 0x19, 0xeb, 0x5a, 0x9f, 0xf3, 0xbe, 0x47, 0x37,
|
||||
0x75, 0xef, 0x70, 0x74, 0xb4, 0xe9, 0x8e, 0x04, 0x91, 0x8c, 0xfb, 0xe6, 0xfb, 0xea, 0xe5, 0xef,
|
||||
0xc4, 0x1f, 0x5f, 0x45, 0x7d, 0x25, 0x48, 0x10, 0x50, 0x61, 0x06, 0xac, 0x9e, 0x65, 0x21, 0xbf,
|
||||
0xcb, 0x5d, 0xda, 0x0d, 0xa8, 0x83, 0x76, 0xc0, 0x22, 0xbe, 0xcf, 0xa5, 0xf6, 0x1d, 0xda, 0x99,
|
||||
0x4a, 0x66, 0xc3, 0xda, 0x5a, 0xaf, 0xbd, 0xb9, 0xa6, 0x5a, 0x7d, 0x02, 0x6b, 0x64, 0x5f, 0x9f,
|
||||
0xaf, 0xcf, 0xe1, 0x69, 0x26, 0xfa, 0x25, 0x14, 0x5d, 0x1a, 0x32, 0x41, 0xdd, 0x9e, 0xe0, 0x1e,
|
||||
0xb5, 0xe7, 0x2b, 0x99, 0x8d, 0x1b, 0x5b, 0x77, 0xd3, 0x3c, 0xa9, 0xc1, 0x31, 0xf7, 0x28, 0xb6,
|
||||
0x0c, 0x43, 0x75, 0xd0, 0x0e, 0xc0, 0x90, 0x0e, 0x0f, 0xa9, 0x08, 0x07, 0x2c, 0xb0, 0x17, 0x34,
|
||||
0xfd, 0x47, 0x57, 0xd1, 0xd5, 0xdc, 0x6b, 0xcf, 0x13, 0x38, 0x9e, 0xa2, 0xa2, 0xe7, 0x50, 0x24,
|
||||
0x27, 0x84, 0x79, 0xe4, 0x90, 0x79, 0x4c, 0x8e, 0xed, 0xac, 0x76, 0xf5, 0xe9, 0x5b, 0x5d, 0xd5,
|
||||
0xa7, 0x08, 0x78, 0x86, 0x5e, 0x75, 0x01, 0x26, 0x03, 0xa1, 0x87, 0xb0, 0xd4, 0x69, 0xed, 0x36,
|
||||
0xdb, 0xbb, 0x3b, 0xa5, 0xb9, 0xf2, 0xea, 0xe9, 0x59, 0xe5, 0x43, 0xe5, 0x63, 0x02, 0xe8, 0x50,
|
||||
0xdf, 0x65, 0x7e, 0x1f, 0x6d, 0x40, 0xbe, 0xbe, 0xbd, 0xdd, 0xea, 0xec, 0xb7, 0x9a, 0xa5, 0x4c,
|
||||
0xb9, 0x7c, 0x7a, 0x56, 0xb9, 0x3d, 0x0b, 0xac, 0x3b, 0x0e, 0x0d, 0x24, 0x75, 0xcb, 0xd9, 0xef,
|
||||
0xfe, 0xbc, 0x36, 0x57, 0xfd, 0x2e, 0x03, 0xc5, 0xe9, 0x49, 0xa0, 0x87, 0x90, 0xab, 0x6f, 0xef,
|
||||
0xb7, 0x0f, 0x5a, 0xa5, 0xb9, 0x09, 0x7d, 0x1a, 0x51, 0x77, 0x24, 0x3b, 0xa1, 0xe8, 0x01, 0x2c,
|
||||
0x76, 0xea, 0x2f, 0xba, 0xad, 0x52, 0x66, 0x32, 0x9d, 0x69, 0x58, 0x87, 0x8c, 0x42, 0x8d, 0x6a,
|
||||
0xe2, 0x7a, 0x7b, 0xb7, 0x34, 0x9f, 0x8e, 0x6a, 0x0a, 0xc2, 0x7c, 0x33, 0x95, 0x3f, 0x65, 0xc1,
|
||||
0xea, 0x52, 0x71, 0xc2, 0x9c, 0xf7, 0x2c, 0x91, 0x2f, 0x21, 0x2b, 0x49, 0x78, 0xac, 0xa5, 0x61,
|
||||
0xa5, 0x4b, 0x63, 0x9f, 0x84, 0xc7, 0x6a, 0x50, 0x43, 0xd7, 0x78, 0xa5, 0x0c, 0x41, 0x03, 0x8f,
|
||||
0x39, 0x44, 0x52, 0x57, 0x2b, 0xc3, 0xda, 0xfa, 0x24, 0x8d, 0x8d, 0x13, 0x94, 0x99, 0xff, 0x93,
|
||||
0x39, 0x3c, 0x45, 0x45, 0x8f, 0x21, 0xd7, 0xf7, 0xf8, 0x21, 0xf1, 0xb4, 0x26, 0xac, 0xad, 0xfb,
|
||||
0x69, 0x4e, 0x76, 0x34, 0x62, 0xe2, 0xc0, 0x50, 0xd0, 0x23, 0xc8, 0x8d, 0x02, 0x97, 0x48, 0x6a,
|
||||
0xe7, 0x34, 0xb9, 0x92, 0x46, 0x7e, 0xa1, 0x11, 0xdb, 0xdc, 0x3f, 0x62, 0x7d, 0x6c, 0xf0, 0xe8,
|
||||
0x29, 0xe4, 0x7d, 0x2a, 0x5f, 0x71, 0x71, 0x1c, 0xda, 0x4b, 0x95, 0x85, 0x0d, 0x6b, 0xeb, 0xf3,
|
||||
0x54, 0x31, 0x46, 0x98, 0xba, 0x94, 0xc4, 0x19, 0x0c, 0xa9, 0x2f, 0x23, 0x37, 0x8d, 0x79, 0x3b,
|
||||
0x83, 0x13, 0x07, 0xe8, 0xe7, 0x90, 0xa7, 0xbe, 0x1b, 0x70, 0xe6, 0x4b, 0x3b, 0x7f, 0xf5, 0x44,
|
||||
0x5a, 0x06, 0xa3, 0x36, 0x13, 0x27, 0x0c, 0xc5, 0x16, 0xdc, 0xf3, 0x0e, 0x89, 0x73, 0x6c, 0x17,
|
||||
0xde, 0x71, 0x19, 0x09, 0xa3, 0x91, 0x83, 0xec, 0x90, 0xbb, 0xb4, 0xba, 0x09, 0x2b, 0x6f, 0x6c,
|
||||
0x35, 0x2a, 0x43, 0xde, 0x6c, 0x75, 0xa4, 0x91, 0x2c, 0x4e, 0xfa, 0xd5, 0x9b, 0xb0, 0x3c, 0xb3,
|
||||
0xad, 0xd5, 0xbf, 0x2e, 0x42, 0x3e, 0x3e, 0x6b, 0x54, 0x87, 0x82, 0xc3, 0x7d, 0x49, 0x98, 0x4f,
|
||||
0x85, 0x91, 0x57, 0xea, 0xc9, 0x6c, 0xc7, 0x20, 0xc5, 0x7a, 0x32, 0x87, 0x27, 0x2c, 0xf4, 0x2d,
|
||||
0x14, 0x04, 0x0d, 0xf9, 0x48, 0x38, 0x34, 0x34, 0xfa, 0xda, 0x48, 0x57, 0x48, 0x04, 0xc2, 0xf4,
|
||||
0xf7, 0x23, 0x26, 0xa8, 0xda, 0xe5, 0x10, 0x4f, 0xa8, 0xe8, 0x31, 0x2c, 0x09, 0x1a, 0x4a, 0x22,
|
||||
0xe4, 0xdb, 0x24, 0x82, 0x23, 0x48, 0x87, 0x7b, 0xcc, 0x19, 0xe3, 0x98, 0x81, 0x1e, 0x43, 0x21,
|
||||
0xf0, 0x88, 0xa3, 0xbd, 0xda, 0x8b, 0x9a, 0x7e, 0x2f, 0x8d, 0xde, 0x89, 0x41, 0x78, 0x82, 0x47,
|
||||
0x5f, 0x01, 0x78, 0xbc, 0xdf, 0x73, 0x05, 0x3b, 0xa1, 0xc2, 0x48, 0xac, 0x9c, 0xc6, 0x6e, 0x6a,
|
||||
0x04, 0x2e, 0x78, 0xbc, 0x1f, 0x35, 0xd1, 0xce, 0xff, 0xa4, 0xaf, 0x29, 0x6d, 0x3d, 0x05, 0x20,
|
||||
0xc9, 0x57, 0xa3, 0xae, 0x4f, 0xdf, 0xc9, 0x95, 0x39, 0x91, 0x29, 0x3a, 0xba, 0x0f, 0xc5, 0x23,
|
||||
0x2e, 0x1c, 0xda, 0x33, 0xb7, 0xa6, 0xa0, 0x35, 0x61, 0x69, 0x5b, 0xa4, 0x2f, 0xd4, 0x80, 0xa5,
|
||||
0x3e, 0xf5, 0xa9, 0x60, 0x8e, 0x0d, 0x7a, 0xb0, 0x87, 0xa9, 0x17, 0x32, 0x82, 0xe0, 0x91, 0x2f,
|
||||
0xd9, 0x90, 0x9a, 0x91, 0x62, 0x22, 0xfa, 0x1d, 0x7c, 0x10, 0x1f, 0x5f, 0x4f, 0xd0, 0x23, 0x2a,
|
||||
0xa8, 0xaf, 0x34, 0x60, 0xe9, 0x7d, 0xf8, 0xe4, 0xed, 0x1a, 0x30, 0x68, 0x13, 0x6c, 0x90, 0xb8,
|
||||
0xfc, 0x21, 0x6c, 0x14, 0x60, 0x49, 0x44, 0xe3, 0x56, 0xff, 0x98, 0x51, 0xaa, 0xbf, 0x84, 0x40,
|
||||
0x9b, 0x60, 0x25, 0xc3, 0x33, 0x57, 0xab, 0xb7, 0xd0, 0xb8, 0x71, 0x71, 0xbe, 0x0e, 0x31, 0xb6,
|
||||
0xdd, 0x54, 0x31, 0xc8, 0xb4, 0x5d, 0xd4, 0x82, 0xe5, 0x84, 0xa0, 0xca, 0x00, 0x93, 0x28, 0x2b,
|
||||
0x6f, 0x9b, 0xe9, 0xfe, 0x38, 0xa0, 0xb8, 0x28, 0xa6, 0x7a, 0xd5, 0xdf, 0x02, 0x7a, 0x73, 0x5f,
|
||||
0x10, 0x82, 0xec, 0x31, 0xf3, 0xcd, 0x34, 0xb0, 0x6e, 0xa3, 0x1a, 0x2c, 0x05, 0x64, 0xec, 0x71,
|
||||
0xe2, 0x9a, 0x8b, 0x71, 0xab, 0x16, 0x15, 0x08, 0xb5, 0xb8, 0x40, 0xa8, 0xd5, 0xfd, 0x31, 0x8e,
|
||||
0x41, 0xd5, 0xa7, 0xf0, 0x61, 0xea, 0xf1, 0xa2, 0x2d, 0x28, 0x26, 0x17, 0x6e, 0xb2, 0xd6, 0x9b,
|
||||
0x17, 0xe7, 0xeb, 0x56, 0x72, 0x33, 0xdb, 0x4d, 0x6c, 0x25, 0xa0, 0xb6, 0x5b, 0xfd, 0xde, 0x82,
|
||||
0xe5, 0x99, 0x6b, 0x8b, 0x6e, 0xc1, 0x22, 0x1b, 0x92, 0x3e, 0x35, 0x73, 0x8c, 0x3a, 0xa8, 0x05,
|
||||
0x39, 0x8f, 0x1c, 0x52, 0x4f, 0x5d, 0x5e, 0x75, 0x70, 0x3f, 0xbe, 0xf6, 0xfe, 0xd7, 0x9e, 0x69,
|
||||
0x7c, 0xcb, 0x97, 0x62, 0x8c, 0x0d, 0x19, 0xd9, 0xb0, 0xe4, 0xf0, 0xe1, 0x90, 0xf8, 0x2a, 0x4d,
|
||||
0x2c, 0x6c, 0x14, 0x70, 0xdc, 0x55, 0x3b, 0x43, 0x44, 0x3f, 0xb4, 0xb3, 0xda, 0xac, 0xdb, 0xa8,
|
||||
0x04, 0x0b, 0xd4, 0x3f, 0xb1, 0x17, 0xb5, 0x49, 0x35, 0x95, 0xc5, 0x65, 0xd1, 0xed, 0x2b, 0x60,
|
||||
0xd5, 0x54, 0xbc, 0x51, 0x48, 0x85, 0xbd, 0x14, 0xed, 0xa8, 0x6a, 0xa3, 0x9f, 0x41, 0x6e, 0xc8,
|
||||
0x47, 0xbe, 0x0c, 0xed, 0xbc, 0x9e, 0xec, 0x6a, 0xda, 0x64, 0x9f, 0x2b, 0x84, 0x51, 0x96, 0x81,
|
||||
0xa3, 0x16, 0xac, 0x84, 0x92, 0x07, 0xbd, 0xbe, 0x20, 0x0e, 0xed, 0x05, 0x54, 0x30, 0xee, 0x9a,
|
||||
0x30, 0xbc, 0xfa, 0xc6, 0xa1, 0x34, 0x4d, 0xc1, 0x87, 0x6f, 0x2a, 0xce, 0x8e, 0xa2, 0x74, 0x34,
|
||||
0x03, 0x75, 0xa0, 0x18, 0x8c, 0x3c, 0xaf, 0xc7, 0x83, 0x28, 0x23, 0x47, 0x77, 0xe7, 0x1d, 0xb6,
|
||||
0xac, 0x33, 0xf2, 0xbc, 0xbd, 0x88, 0x84, 0xad, 0x60, 0xd2, 0x41, 0xb7, 0x21, 0xd7, 0x17, 0x7c,
|
||||
0x14, 0x44, 0xf7, 0xa6, 0x80, 0x4d, 0x0f, 0x7d, 0x03, 0x4b, 0x21, 0x75, 0x04, 0x95, 0xa1, 0x5d,
|
||||
0xd4, 0x4b, 0xfd, 0x38, 0x6d, 0x90, 0xae, 0x86, 0x24, 0x77, 0x02, 0xc7, 0x1c, 0xb4, 0x0a, 0x0b,
|
||||
0x52, 0x8e, 0xed, 0xe5, 0x4a, 0x66, 0x23, 0xdf, 0x58, 0xba, 0x38, 0x5f, 0x5f, 0xd8, 0xdf, 0x7f,
|
||||
0x89, 0x95, 0x4d, 0x65, 0x8b, 0x01, 0x0f, 0xa5, 0x4f, 0x86, 0xd4, 0xbe, 0xa1, 0xf7, 0x36, 0xe9,
|
||||
0xa3, 0x97, 0x00, 0xae, 0x1f, 0xf6, 0x1c, 0x1d, 0x9e, 0xec, 0x9b, 0x7a, 0x75, 0x9f, 0x5f, 0xbf,
|
||||
0xba, 0xe6, 0x6e, 0xd7, 0x64, 0xcc, 0xe5, 0x8b, 0xf3, 0xf5, 0x42, 0xd2, 0xc5, 0x05, 0xd7, 0x0f,
|
||||
0xa3, 0x26, 0x6a, 0x80, 0x35, 0xa0, 0xc4, 0x93, 0x03, 0x67, 0x40, 0x9d, 0x63, 0xbb, 0x74, 0x75,
|
||||
0x0a, 0x7c, 0xa2, 0x61, 0xc6, 0xc3, 0x34, 0x49, 0x29, 0x58, 0x4d, 0x35, 0xb4, 0x57, 0xf4, 0x5e,
|
||||
0x45, 0x1d, 0x74, 0x0f, 0x80, 0x07, 0xd4, 0xef, 0x85, 0xd2, 0x65, 0xbe, 0x8d, 0xd4, 0x92, 0x71,
|
||||
0x41, 0x59, 0xba, 0xca, 0x80, 0xee, 0xa8, 0x04, 0x45, 0xdc, 0x1e, 0xf7, 0xbd, 0xb1, 0xfd, 0x81,
|
||||
0xfe, 0x9a, 0x57, 0x86, 0x3d, 0xdf, 0x1b, 0xa3, 0x75, 0xb0, 0xb4, 0x2e, 0x42, 0xd6, 0xf7, 0x89,
|
||||
0x67, 0xdf, 0xd2, 0xfb, 0x01, 0xca, 0xd4, 0xd5, 0x16, 0x75, 0x0e, 0xd1, 0x6e, 0x84, 0xf6, 0x87,
|
||||
0x57, 0x9f, 0x83, 0x99, 0xec, 0xe4, 0x1c, 0x0c, 0x07, 0xfd, 0x02, 0x20, 0x10, 0xec, 0x84, 0x79,
|
||||
0xb4, 0x4f, 0x43, 0xfb, 0xb6, 0x5e, 0xf4, 0x5a, 0x6a, 0x66, 0x4a, 0x50, 0x78, 0x8a, 0x81, 0x6a,
|
||||
0x90, 0x65, 0x3e, 0x93, 0xf6, 0x47, 0x26, 0x2b, 0x5d, 0x96, 0x6a, 0x83, 0x73, 0xef, 0x80, 0x78,
|
||||
0x23, 0x8a, 0x35, 0x0e, 0xb5, 0xa1, 0xc0, 0x42, 0xee, 0x69, 0xf9, 0xda, 0xb6, 0x8e, 0x6f, 0xef,
|
||||
0x70, 0x7e, 0xed, 0x98, 0x82, 0x27, 0x6c, 0x74, 0x17, 0x0a, 0x01, 0x73, 0xc3, 0x67, 0x6c, 0xc8,
|
||||
0xa4, 0xbd, 0x5a, 0xc9, 0x6c, 0x2c, 0xe0, 0x89, 0xa1, 0xfc, 0x15, 0x58, 0x53, 0x61, 0x40, 0x5d,
|
||||
0xdf, 0x63, 0x3a, 0x36, 0x91, 0x45, 0x35, 0xd5, 0x59, 0x9d, 0xa8, 0x89, 0xe9, 0xd0, 0x57, 0xc0,
|
||||
0x51, 0xe7, 0xeb, 0xf9, 0x47, 0x99, 0xf2, 0x16, 0x58, 0x53, 0xd7, 0x01, 0x7d, 0xac, 0xc2, 0x72,
|
||||
0x9f, 0x85, 0x52, 0x8c, 0x7b, 0x64, 0x24, 0x07, 0xf6, 0xaf, 0x34, 0xa1, 0x18, 0x1b, 0xeb, 0x23,
|
||||
0x39, 0x28, 0xf7, 0x60, 0xa2, 0x2a, 0x54, 0x01, 0x4b, 0xa9, 0x35, 0xa4, 0xe2, 0x84, 0x0a, 0x55,
|
||||
0xf2, 0x28, 0x31, 0x4c, 0x9b, 0xd4, 0xad, 0x0a, 0x29, 0x11, 0xce, 0x40, 0x07, 0xb5, 0x02, 0x36,
|
||||
0x3d, 0x15, 0xa5, 0xe2, 0xab, 0x6b, 0xa2, 0x94, 0xe9, 0x56, 0xff, 0x96, 0x81, 0x42, 0xb2, 0x0d,
|
||||
0xe8, 0x0b, 0x58, 0x69, 0x77, 0xf7, 0x9e, 0xd5, 0xf7, 0xdb, 0x7b, 0xbb, 0xbd, 0x66, 0xeb, 0xdb,
|
||||
0xfa, 0x8b, 0x67, 0xfb, 0xa5, 0xb9, 0xf2, 0xbd, 0xd3, 0xb3, 0xca, 0xea, 0x24, 0xe2, 0xc6, 0xf0,
|
||||
0x26, 0x3d, 0x22, 0x23, 0x4f, 0xce, 0xb2, 0x3a, 0x78, 0x6f, 0xbb, 0xd5, 0xed, 0x96, 0x32, 0x57,
|
||||
0xb1, 0x3a, 0x82, 0x3b, 0x34, 0x0c, 0xd1, 0x16, 0x94, 0x26, 0xac, 0x27, 0x2f, 0x3b, 0x2d, 0x7c,
|
||||
0x50, 0x9a, 0x2f, 0xdf, 0x3d, 0x3d, 0xab, 0xd8, 0x6f, 0x92, 0x9e, 0x8c, 0x03, 0x2a, 0x0e, 0xcc,
|
||||
0x73, 0xe1, 0x5f, 0x19, 0x28, 0x4e, 0x57, 0x9b, 0x68, 0x3b, 0xaa, 0x12, 0xf5, 0x31, 0xdc, 0xd8,
|
||||
0xda, 0xbc, 0xae, 0x3a, 0xd5, 0x59, 0xce, 0x1b, 0x29, 0xbf, 0xcf, 0xd5, 0xc3, 0x50, 0x93, 0xd1,
|
||||
0x17, 0xb0, 0x18, 0x70, 0x21, 0xe3, 0x7c, 0x90, 0xae, 0x56, 0x2e, 0xe2, 0x1a, 0x26, 0x02, 0x57,
|
||||
0x07, 0x70, 0x63, 0xd6, 0x1b, 0x7a, 0x00, 0x0b, 0x07, 0xed, 0x4e, 0x69, 0xae, 0x7c, 0xe7, 0xf4,
|
||||
0xac, 0xf2, 0xd1, 0xec, 0xc7, 0x03, 0x26, 0xe4, 0x88, 0x78, 0xed, 0x0e, 0xfa, 0x0c, 0x16, 0x9b,
|
||||
0xbb, 0x5d, 0x8c, 0x4b, 0x99, 0xf2, 0xfa, 0xe9, 0x59, 0xe5, 0xce, 0x2c, 0x4e, 0x7d, 0xe2, 0x23,
|
||||
0xdf, 0xc5, 0xfc, 0x30, 0x79, 0x24, 0xfd, 0x7b, 0x1e, 0x2c, 0x93, 0x26, 0xdf, 0xf7, 0x3b, 0x7a,
|
||||
0x39, 0xaa, 0x01, 0xe3, 0xf8, 0x37, 0x7f, 0x6d, 0x29, 0x58, 0x8c, 0x08, 0x46, 0x97, 0xf7, 0xa1,
|
||||
0xc8, 0x82, 0x93, 0x2f, 0x7b, 0xd4, 0x27, 0x87, 0x9e, 0x79, 0x2f, 0xe5, 0xb1, 0xa5, 0x6c, 0xad,
|
||||
0xc8, 0xa4, 0x82, 0x2f, 0xf3, 0x25, 0x15, 0xbe, 0x79, 0x09, 0xe5, 0x71, 0xd2, 0x47, 0xdf, 0x40,
|
||||
0x96, 0x05, 0x64, 0x68, 0xea, 0xd7, 0xd4, 0x15, 0xb4, 0x3b, 0xf5, 0xe7, 0xe6, 0xde, 0x34, 0xf2,
|
||||
0x17, 0xe7, 0xeb, 0x59, 0x65, 0xc0, 0x9a, 0x86, 0xd6, 0xe2, 0x12, 0x52, 0x8d, 0xa4, 0x13, 0x69,
|
||||
0x1e, 0x4f, 0x59, 0x94, 0xf6, 0x99, 0xdf, 0x17, 0x34, 0x0c, 0x75, 0x4a, 0xcd, 0xe3, 0xb8, 0x8b,
|
||||
0xca, 0xb0, 0x64, 0x0a, 0x51, 0x5d, 0x79, 0x16, 0x54, 0x91, 0x67, 0x0c, 0x8d, 0x65, 0xb0, 0xa2,
|
||||
0xdd, 0xe8, 0x1d, 0x09, 0x3e, 0xac, 0xfe, 0x27, 0x0b, 0xd6, 0xb6, 0x37, 0x0a, 0xa5, 0xa9, 0x29,
|
||||
0xde, 0xdb, 0xe6, 0xbf, 0x84, 0x15, 0xa2, 0xdf, 0xe5, 0xc4, 0x57, 0x09, 0x5a, 0xd7, 0xf7, 0xe6,
|
||||
0x00, 0x1e, 0xa4, 0xba, 0x4b, 0xc0, 0xd1, 0x5b, 0xa0, 0x91, 0x53, 0x3e, 0xed, 0x0c, 0x2e, 0x91,
|
||||
0x4b, 0x5f, 0x50, 0x17, 0x96, 0xb9, 0x70, 0x06, 0x34, 0x94, 0x51, 0x5a, 0x37, 0xef, 0xd8, 0xd4,
|
||||
0x3f, 0x1c, 0x7b, 0xd3, 0x40, 0x93, 0xd3, 0xa2, 0xd9, 0xce, 0xfa, 0x40, 0x8f, 0x20, 0x2b, 0xc8,
|
||||
0x51, 0xfc, 0x56, 0x49, 0xbd, 0x24, 0x98, 0x1c, 0xc9, 0x19, 0x17, 0x9a, 0x81, 0x7e, 0x0d, 0xe0,
|
||||
0xb2, 0x30, 0x20, 0xd2, 0x19, 0x50, 0x61, 0x0e, 0x3b, 0x75, 0x89, 0xcd, 0x04, 0x35, 0xe3, 0x65,
|
||||
0x8a, 0x8d, 0x9e, 0x42, 0xc1, 0x21, 0xb1, 0x5c, 0x73, 0x57, 0x3f, 0xee, 0xb7, 0xeb, 0xc6, 0x45,
|
||||
0x49, 0xb9, 0xb8, 0x38, 0x5f, 0xcf, 0xc7, 0x16, 0x9c, 0x77, 0x88, 0x91, 0xef, 0x53, 0x58, 0x56,
|
||||
0x8f, 0xfe, 0x9e, 0x1b, 0x85, 0xb3, 0x48, 0x26, 0x57, 0xe4, 0x68, 0xf5, 0x82, 0x34, 0x61, 0x2f,
|
||||
0x3e, 0xce, 0xa2, 0x9c, 0xb2, 0xa1, 0xdf, 0xc0, 0x0a, 0xf5, 0x1d, 0x31, 0xd6, 0x62, 0x8d, 0x67,
|
||||
0x98, 0xbf, 0x7a, 0xb1, 0xad, 0x04, 0x3c, 0xb3, 0xd8, 0x12, 0xbd, 0x64, 0xaf, 0xfe, 0x33, 0x03,
|
||||
0x10, 0x95, 0x3d, 0xef, 0x57, 0x80, 0x08, 0xb2, 0x2e, 0x91, 0x44, 0x6b, 0xae, 0x88, 0x75, 0x1b,
|
||||
0x7d, 0x0d, 0x20, 0xe9, 0x30, 0x50, 0xa1, 0xd7, 0xef, 0x1b, 0xd9, 0xbc, 0x2d, 0x1c, 0x4c, 0xa1,
|
||||
0xd1, 0x16, 0xe4, 0xcc, 0x8b, 0x32, 0x7b, 0x2d, 0xcf, 0x20, 0xab, 0x7f, 0xc9, 0x00, 0x44, 0xcb,
|
||||
0xfc, 0xbf, 0x5e, 0x5b, 0xc3, 0x7e, 0xfd, 0xc3, 0xda, 0xdc, 0x3f, 0x7e, 0x58, 0x9b, 0xfb, 0xc3,
|
||||
0xc5, 0x5a, 0xe6, 0xf5, 0xc5, 0x5a, 0xe6, 0xef, 0x17, 0x6b, 0x99, 0xef, 0x2f, 0xd6, 0x32, 0x87,
|
||||
0x39, 0x5d, 0x99, 0xfc, 0xf4, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb8, 0xa3, 0x85, 0xdc, 0xc7,
|
||||
0x15, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -314,6 +314,10 @@ message ContainerSpec {
|
|||
// Isolation defines the isolation level for windows containers (default, process, hyperv).
|
||||
// Runtimes that don't support it ignore that field
|
||||
Isolation isolation = 24;
|
||||
|
||||
// PidsLimit prevents from OS resource damage by applications inside the container
|
||||
// using fork bomb attack.
|
||||
int64 pidsLimit = 25;
|
||||
}
|
||||
|
||||
// EndpointSpec defines the properties that can be configured to
|
||||
|
|
Loading…
Reference in New Issue