diff --git a/bcs-common/pkg/discovery/app.go b/bcs-common/pkg/discovery/app.go deleted file mode 100644 index 095d8b1969..0000000000 --- a/bcs-common/pkg/discovery/app.go +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Blueking Container Service available. - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * Licensed under the MIT License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package discovery - -const ( - //BcsDiscoveryVersion definition for version parameter in container ENV - BcsDiscoveryVersion = "BCS_DISCOVERY_VERSION" -) - -//AppSvcRequest base info for request -type AppSvcRequest struct { - Meta `json:",inline"` -} - -//AppSvc service definition for bcs-discovery -type AppSvc struct { - Meta `json:",inline"` - Frontend []string `json:"frontend,omitempty"` //frontend, come from BcsService.ClusterIP - Master string `json:"master,omitempty"` //reserved - SvcPorts []*SvcPort `json:"ports,omitempty"` //BcsService.Ports - Nodes map[string]*AppNode `json:"nodes,omitempty"` //TaskGroup/Pod info -} - -//SvcPort port definition from BcsService -type SvcPort struct { - Name string `json:"name"` - Protocol string `json:"protocol"` - Domain string `json:"domain,omitempty"` - Path string `json:"path,omitempty"` - ServicePort int `json:"serviceport"` - NodePort int `json:"nodeport,omitempty"` -} - -//SvcPortList list for sorting -type SvcPortList []*SvcPort - -//Len is the number of elements in the collection. -func (list SvcPortList) Len() int { - return len(list) -} - -//Less reports whether the element with -// index i should sort before the element with index j. -func (list SvcPortList) Less(i, j int) bool { - return list[i].ServicePort < list[j].ServicePort -} - -//Swap swaps the elements with indexes i and j. -func (list SvcPortList) Swap(i, j int) { - list[i], list[j] = list[j], list[i] -} - -//AppNode node info from Taskgroup/Pod -type AppNode struct { - Meta `json:",inline"` - Index string `json:"index"` //node key, pod instance name / taskgroup name - Version string `json:"version,omitempty"` //node version, like v1, v1.1, v12.01.1, come from env[BCS_DISCOVERY_VERSION] - Network string `json:"network"` //app node network mode - ContainerIP string `json:"containerIP"` //node container ip address - NodeIP string `json:"nodeIP"` //container deployed host ip address - Ports PortList `json:"ports,omitempty"` //port info for container -} - -//Key AppNode key func -func (node *AppNode) Key() string { - return node.Cluster + "." + node.Namespace + "." + node.Name + "." + node.Index -} - -//NodePort port info for container -type NodePort struct { - Name string `json:"name"` - Protocol string `json:"protocol"` - ContainerPort int `json:"containerport"` - NodePort int `json:"nodeport,omitempty"` -} - -//PortList list for ports -type PortList []*NodePort - -//Len is the number of elements in the collection. -func (list PortList) Len() int { - return len(list) -} - -//Less reports whether the element with -// index i should sort before the element with index j. -func (list PortList) Less(i, j int) bool { - return list[i].ContainerPort < list[j].ContainerPort -} - -//Swap swaps the elements with indexes i and j. -func (list PortList) Swap(i, j int) { - list[i], list[j] = list[j], list[i] -} diff --git a/bcs-common/pkg/discovery/application.go b/bcs-common/pkg/discovery/application.go new file mode 100644 index 0000000000..6e093434d2 --- /dev/null +++ b/bcs-common/pkg/discovery/application.go @@ -0,0 +1,146 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package discovery + +import ( + "fmt" + "path" + "time" + + "bk-bcs/bcs-common/common/blog" + "bk-bcs/bcs-common/pkg/meta" + "bk-bcs/bcs-common/pkg/reflector" + schedypes "bk-bcs/bcs-common/pkg/scheduler/types" + "bk-bcs/bcs-common/pkg/storage" + "bk-bcs/bcs-common/pkg/storage/zookeeper" + "bk-bcs/bcs-common/pkg/watch" + + "golang.org/x/net/context" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + k8scache "k8s.io/client-go/tools/cache" +) + +// ApplicationController controller for Application +type ApplicationController interface { + // List list all application datas + List(selector labels.Selector) (ret []*schedypes.Application, err error) + // NamespaceList list specified applications by namespace + // ns = namespace + NamespaceList(ns string, selector labels.Selector) (ret []*schedypes.Application, err error) + // Get application by the specified namespace, application name + // ns = namespace + // name = application name + GetByName(ns, name string) (*schedypes.Application, error) +} + +//applicationController for dataType resource +type applicationController struct { + cxt context.Context + stopFn context.CancelFunc + eventStorage storage.Storage //remote event storage + indexer k8scache.Indexer //indexer + reflector *reflector.Reflector //reflector list/watch all datas to local memory cache +} + +// List list all application datas +func (s *applicationController) List(selector labels.Selector) (ret []*schedypes.Application, err error) { + err = ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*schedypes.Application)) + }) + return ret, err +} + +// NamespaceList get specified application by namespace +func (s *applicationController) NamespaceList(ns string, selector labels.Selector) (ret []*schedypes.Application, err error) { + err = ListAllByNamespace(s.indexer, ns, selector, func(m interface{}) { + ret = append(ret, m.(*schedypes.Application)) + }) + return ret, err +} + +func (s *applicationController) GetByName(ns, name string) (*schedypes.Application, error) { + obj, exists, err := s.indexer.GetByKey(path.Join(ns, name)) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("Application"), fmt.Sprintf("%s.%s", ns, name)) + } + return obj.(*schedypes.Application), nil +} + +func NewApplicationController(hosts []string, eventHandler reflector.EventInterface) (ApplicationController, error) { + indexers := k8scache.Indexers{ + meta.NamespaceIndex: meta.NamespaceIndexFunc, + } + + ts := k8scache.NewIndexer(ApplicationObjectKeyFn, indexers) + //create namespace client for zookeeper + zkConfig := &zookeeper.ZkConfig{ + Hosts: hosts, + PrefixPath: "/blueking/application", + Name: "application", + Codec: &meta.JsonCodec{}, + ObjectNewFunc: ApplicationObjectNewFn, + } + svcclient, err := zookeeper.NewNSClient(zkConfig) + if err != nil { + blog.Errorf("bk-bcs mesos discovery create application pod client failed, %s", err) + return nil, err + } + //create listwatcher + listwatcher := &reflector.ListWatch{ + ListFn: func() ([]meta.Object, error) { + return svcclient.List(context.Background(), "", nil) + }, + WatchFn: func() (watch.Interface, error) { + return svcclient.Watch(context.Background(), "", "", nil) + }, + } + cxt, stopfn := context.WithCancel(context.Background()) + ctl := &applicationController{ + cxt: cxt, + stopFn: stopfn, + eventStorage: svcclient, + indexer: ts, + } + + //create reflector + ctl.reflector = reflector.NewReflector(fmt.Sprintf("Reflector-%s", zkConfig.Name), ts, listwatcher, time.Second*600, eventHandler) + //sync all data object from remote event storage + err = ctl.reflector.ListAllData() + if err != nil { + return nil, err + } + //run reflector controller + go ctl.reflector.Run() + + return ctl, nil +} + +//ApplicationObjectKeyFn create key for application +func ApplicationObjectKeyFn(obj interface{}) (string, error) { + application, ok := obj.(*schedypes.Application) + if !ok { + return "", fmt.Errorf("error object type") + } + return path.Join(application.GetNamespace(), application.GetName()), nil +} + +//ApplicationObjectNewFn create new Application Object +func ApplicationObjectNewFn() meta.Object { + return new(schedypes.Application) +} diff --git a/bcs-common/pkg/discovery/lister.go b/bcs-common/pkg/discovery/lister.go new file mode 100644 index 0000000000..e11d616872 --- /dev/null +++ b/bcs-common/pkg/discovery/lister.go @@ -0,0 +1,154 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package discovery + +import ( + "fmt" + + "bk-bcs/bcs-common/common/blog" + "bk-bcs/bcs-common/pkg/meta" + + "k8s.io/apimachinery/pkg/labels" + k8scache "k8s.io/client-go/tools/cache" +) + +// AppendFunc is used to add a matching item to whatever list the caller is using +type AppendFunc func(interface{}) + +func ListAll(store k8scache.Indexer, selector labels.Selector, appendFn AppendFunc) error { + selectAll := selector.Empty() + for _, m := range store.List() { + if selectAll { + // Avoid computing labels of the objects to speed up common flows + // of listing all objects. + appendFn(m) + continue + } + metadata, err := meta.Accessor(m) + if err != nil { + return err + } + if selector.Matches(labels.Set(metadata.GetLabels())) { + appendFn(m) + } + } + return nil +} + +func ListAllByNamespace(indexer k8scache.Indexer, namespace string, selector labels.Selector, appendFn AppendFunc) error { + selectAll := selector.Empty() + if namespace == meta.NamespaceAll { + for _, m := range indexer.List() { + if selectAll { + // Avoid computing labels of the objects to speed up common flows + // of listing all objects. + appendFn(m) + continue + } + metadata, err := meta.Accessor(m) + if err != nil { + return err + } + if selector.Matches(labels.Set(metadata.GetLabels())) { + appendFn(m) + } + } + return nil + } + + items, err := indexer.Index(meta.NamespaceIndex, &meta.ObjectMeta{Namespace: namespace}) + if err != nil { + // Ignore error; do slow search without index. + blog.Warn("can not retrieve list of objects using index : %v", err) + for _, m := range indexer.List() { + metadata, err := meta.Accessor(m) + if err != nil { + return err + } + if metadata.GetNamespace() == namespace && selector.Matches(labels.Set(metadata.GetLabels())) { + appendFn(m) + } + + } + return nil + } + for _, m := range items { + if selectAll { + // Avoid computing labels of the objects to speed up common flows + // of listing all objects. + appendFn(m) + continue + } + metadata, err := meta.Accessor(m) + if err != nil { + return err + } + if selector.Matches(labels.Set(metadata.GetLabels())) { + appendFn(m) + } + } + + return nil +} + +//only taskgroup has the application index +func ListAllByApplication(indexer k8scache.Indexer, ns, appname string, selector labels.Selector, appendFn AppendFunc) error { + selectAll := selector.Empty() + if ns == meta.NamespaceAll { + for _, m := range indexer.List() { + if selectAll { + // Avoid computing labels of the objects to speed up common flows + // of listing all objects. + appendFn(m) + continue + } + metadata, err := meta.Accessor(m) + if err != nil { + return err + } + if selector.Matches(labels.Set(metadata.GetLabels())) { + appendFn(m) + } + } + return nil + } + + items, err := indexer.ByIndex(meta.ApplicationIndex, fmt.Sprintf("%s.%s", appname, ns)) + if err != nil { + // Ignore error; do slow search without index. + blog.Warn("can not retrieve list of objects using index : %v", err) + return fmt.Errorf("can not retrieve list of objects using index: %s", err.Error()) + } + for _, m := range items { + if selectAll { + // Avoid computing labels of the objects to speed up common flows + // of listing all objects. + appendFn(m) + continue + } + metadata, err := meta.Accessor(m) + if err != nil { + return err + } + if selector.Matches(labels.Set(metadata.GetLabels())) { + appendFn(m) + } + } + + return nil +} + +func EverythingSelector() labels.Selector { + return labels.Everything() +} diff --git a/bcs-common/pkg/discovery/meta.go b/bcs-common/pkg/discovery/meta.go deleted file mode 100644 index 87157ca590..0000000000 --- a/bcs-common/pkg/discovery/meta.go +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Blueking Container Service available. - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * Licensed under the MIT License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package discovery - -import "errors" - -//IMeta meta interface -type IMeta interface { - Key() string -} - -var errLostKey = errors.New("object lost key") - -//MetaKeyFunc key func for node cache -func MetaKeyFunc(obj interface{}) (string, error) { - m, ok := obj.(IMeta) - if !ok { - return "", errLostKey - } - return m.Key(), nil -} - -//Meta for location -type Meta struct { - Cluster string `json:"cluster"` - Namespace string `json:"namespace"` - Name string `json:"name"` -} - -//Key get key of meta data -func (m *Meta) Key() string { - return m.Cluster + "." + m.Namespace + "." + m.Name -} - -//IsValid check meta is valid -func (m *Meta) IsValid() bool { - if len(m.Cluster) == 0 { - return false - } - if len(m.Namespace) == 0 { - return false - } - if len(m.Name) == 0 { - return false - } - return true -} - -//IsEqual check two Meta is equal -func (m *Meta) IsEqual(other *Meta) bool { - if m.Namespace != other.Namespace { - return false - } - if m.Name != other.Name { - return false - } - if m.Cluster != other.Cluster { - return false - } - return true -} - -//GetName return meta name -func (m *Meta) GetName() string { - return m.Name -} - -//GetNamespace return meta namespace -func (m *Meta) GetNamespace() string { - return m.Namespace -} - -//GetCluster return meta cluster -func (m *Meta) GetCluster() string { - return m.Cluster -} diff --git a/bcs-common/pkg/discovery/node.go b/bcs-common/pkg/discovery/node.go new file mode 100644 index 0000000000..3e304f0b76 --- /dev/null +++ b/bcs-common/pkg/discovery/node.go @@ -0,0 +1,130 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package discovery + +import ( + "fmt" + "time" + + "bk-bcs/bcs-common/common/blog" + "bk-bcs/bcs-common/pkg/meta" + "bk-bcs/bcs-common/pkg/reflector" + schedypes "bk-bcs/bcs-common/pkg/scheduler/types" + "bk-bcs/bcs-common/pkg/storage" + "bk-bcs/bcs-common/pkg/storage/zookeeper" + "bk-bcs/bcs-common/pkg/watch" + + "golang.org/x/net/context" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + k8scache "k8s.io/client-go/tools/cache" +) + +// NodeController controller for Node +type NodeController interface { + // List list all node datas + List(selector labels.Selector) (ret []*schedypes.Agent, err error) + // Get node by the specified hostname + GetByHostname(hostname string) (*schedypes.Agent, error) +} + +//nodeController for dataType resource +type nodeController struct { + cxt context.Context + stopFn context.CancelFunc + eventStorage storage.Storage //remote event storage + indexer k8scache.Indexer //indexer + reflector *reflector.Reflector //reflector list/watch all datas to local memory cache +} + +// List list all node datas +func (s *nodeController) List(selector labels.Selector) (ret []*schedypes.Agent, err error) { + err = ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*schedypes.Agent)) + }) + return ret, err +} + +func (s *nodeController) GetByHostname(hostname string) (*schedypes.Agent, error) { + obj, exists, err := s.indexer.GetByKey(hostname) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("Node"), hostname) + } + return obj.(*schedypes.Agent), nil +} + +func NewNodeController(hosts []string, eventHandler reflector.EventInterface) (NodeController, error) { + indexers := k8scache.Indexers{} + + ts := k8scache.NewIndexer(NodeObjectKeyFn, indexers) + //create namespace client for zookeeper + zkConfig := &zookeeper.ZkConfig{ + Hosts: hosts, + PrefixPath: "/blueking", + Name: "node", + Codec: &meta.JsonCodec{}, + ObjectNewFunc: NodeObjectNewFn, + } + nodeclient, err := zookeeper.NewNSClient(zkConfig) + if err != nil { + blog.Errorf("bk-bcs mesos discovery create node pod client failed, %s", err) + return nil, err + } + //create listwatcher + listwatcher := &reflector.ListWatch{ + ListFn: func() ([]meta.Object, error) { + return nodeclient.List(context.Background(), "/agent", nil) + }, + WatchFn: func() (watch.Interface, error) { + return nodeclient.Watch(context.Background(), "/agent", "", nil) + }, + } + cxt, stopfn := context.WithCancel(context.Background()) + ctl := &nodeController{ + cxt: cxt, + stopFn: stopfn, + eventStorage: nodeclient, + indexer: ts, + } + + //create reflector + ctl.reflector = reflector.NewReflector(fmt.Sprintf("Reflector-%s", zkConfig.Name), ts, listwatcher, time.Second*600, eventHandler) + //sync all data object from remote event storage + err = ctl.reflector.ListAllData() + if err != nil { + return nil, err + } + //run reflector controller + go ctl.reflector.Run() + + return ctl, nil +} + +//NodeObjectKeyFn create key for node +func NodeObjectKeyFn(obj interface{}) (string, error) { + node, ok := obj.(*schedypes.Agent) + if !ok { + return "", fmt.Errorf("error object type") + } + return node.Key, nil +} + +//NodeObjectNewFn create new Node Object +func NodeObjectNewFn() meta.Object { + return new(schedypes.Agent) +} diff --git a/bcs-common/pkg/discovery/service.go b/bcs-common/pkg/discovery/service.go new file mode 100644 index 0000000000..d926744417 --- /dev/null +++ b/bcs-common/pkg/discovery/service.go @@ -0,0 +1,146 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package discovery + +import ( + "fmt" + "path" + "time" + + "bk-bcs/bcs-common/common/blog" + commtypes "bk-bcs/bcs-common/common/types" + "bk-bcs/bcs-common/pkg/meta" + "bk-bcs/bcs-common/pkg/reflector" + "bk-bcs/bcs-common/pkg/storage" + "bk-bcs/bcs-common/pkg/storage/zookeeper" + "bk-bcs/bcs-common/pkg/watch" + + "golang.org/x/net/context" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + k8scache "k8s.io/client-go/tools/cache" +) + +// ServiceController controller for Service +type ServiceController interface { + // List list all service datas + List(selector labels.Selector) (ret []*commtypes.BcsService, err error) + // NamespaceList list specified services by namespace + // ns = namespace + NamespaceList(ns string, selector labels.Selector) (ret []*commtypes.BcsService, err error) + // Get service by the specified namespace, service name + // ns = namespace + // name = service name + GetByName(ns, name string) (*commtypes.BcsService, error) +} + +//serviceController for dataType resource +type serviceController struct { + cxt context.Context + stopFn context.CancelFunc + eventStorage storage.Storage //remote event storage + indexer k8scache.Indexer //indexer + reflector *reflector.Reflector //reflector list/watch all datas to local memory cache +} + +// List list all service datas +func (s *serviceController) List(selector labels.Selector) (ret []*commtypes.BcsService, err error) { + err = ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*commtypes.BcsService)) + }) + return ret, err +} + +// NamespaceList get specified service by namespace +func (s *serviceController) NamespaceList(ns string, selector labels.Selector) (ret []*commtypes.BcsService, err error) { + err = ListAllByNamespace(s.indexer, ns, selector, func(m interface{}) { + ret = append(ret, m.(*commtypes.BcsService)) + }) + return ret, err +} + +func (s *serviceController) GetByName(ns, name string) (*commtypes.BcsService, error) { + obj, exists, err := s.indexer.GetByKey(path.Join(ns, name)) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("Service"), fmt.Sprintf("%s.%s", ns, name)) + } + return obj.(*commtypes.BcsService), nil +} + +func NewServiceController(hosts []string, eventHandler reflector.EventInterface) (ServiceController, error) { + indexers := k8scache.Indexers{ + meta.NamespaceIndex: meta.NamespaceIndexFunc, + } + + ts := k8scache.NewIndexer(ServiceObjectKeyFn, indexers) + //create namespace client for zookeeper + zkConfig := &zookeeper.ZkConfig{ + Hosts: hosts, + PrefixPath: "/blueking/service", + Name: "service", + Codec: &meta.JsonCodec{}, + ObjectNewFunc: ServiceObjectNewFn, + } + svcclient, err := zookeeper.NewNSClient(zkConfig) + if err != nil { + blog.Errorf("bk-bcs mesos discovery create service pod client failed, %s", err) + return nil, err + } + //create listwatcher + listwatcher := &reflector.ListWatch{ + ListFn: func() ([]meta.Object, error) { + return svcclient.List(context.Background(), "", nil) + }, + WatchFn: func() (watch.Interface, error) { + return svcclient.Watch(context.Background(), "", "", nil) + }, + } + cxt, stopfn := context.WithCancel(context.Background()) + ctl := &serviceController{ + cxt: cxt, + stopFn: stopfn, + eventStorage: svcclient, + indexer: ts, + } + + //create reflector + ctl.reflector = reflector.NewReflector(fmt.Sprintf("Reflector-%s", zkConfig.Name), ts, listwatcher, time.Second*600, eventHandler) + //sync all data object from remote event storage + err = ctl.reflector.ListAllData() + if err != nil { + return nil, err + } + //run reflector controller + go ctl.reflector.Run() + + return ctl, nil +} + +//ServiceObjectKeyFn create key for service +func ServiceObjectKeyFn(obj interface{}) (string, error) { + service, ok := obj.(*commtypes.BcsService) + if !ok { + return "", fmt.Errorf("error object type") + } + return path.Join(service.GetNamespace(), service.GetName()), nil +} + +//ServiceObjectNewFn create new Service Object +func ServiceObjectNewFn() meta.Object { + return new(commtypes.BcsService) +} diff --git a/bcs-common/pkg/discovery/taskgroup.go b/bcs-common/pkg/discovery/taskgroup.go new file mode 100644 index 0000000000..47038c65cd --- /dev/null +++ b/bcs-common/pkg/discovery/taskgroup.go @@ -0,0 +1,181 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package discovery + +import ( + "fmt" + "path" + "strings" + "time" + + "bk-bcs/bcs-common/common/blog" + "bk-bcs/bcs-common/pkg/meta" + "bk-bcs/bcs-common/pkg/reflector" + schedtypes "bk-bcs/bcs-common/pkg/scheduler/types" + "bk-bcs/bcs-common/pkg/storage" + "bk-bcs/bcs-common/pkg/storage/zookeeper" + "bk-bcs/bcs-common/pkg/watch" + + "golang.org/x/net/context" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + k8scache "k8s.io/client-go/tools/cache" +) + +// TaskgroupController controller for Taskgroup +type TaskgroupController interface { + // List list all taskgroup datas + List(selector labels.Selector) (ret []*schedtypes.TaskGroup, err error) + // NamespaceList list specified taskgroups by namespace + // ns = namespace + NamespaceList(ns string, selector labels.Selector) (ret []*schedtypes.TaskGroup, err error) + // ApplicationList list specified taskgroups by application name.namespace + // ns = namespace + // appname = application name + ApplicationList(ns, appname string, selector labels.Selector) (ret []*schedtypes.TaskGroup, err error) + // Get taskgroup by the specified taskgroupID + // taskgroupID, for examples: 0.test-app.defaultGroup.10001.1564385547430065980 + GetById(taskgroupId string) (*schedtypes.TaskGroup, error) + // Get taskgroup by the specified namespace, taskgroup name + // ns = namespace + // name = taskgroup name, appname-index, for examples: test-app-0 + GetByName(ns, name string) (*schedtypes.TaskGroup, error) +} + +//taskgroupController for dataType resource +type taskgroupController struct { + cxt context.Context + stopFn context.CancelFunc + eventStorage storage.Storage //remote event storage + indexer k8scache.Indexer //indexer + reflector *reflector.Reflector //reflector list/watch all datas to local memory cache +} + +// List list all taskgroup datas +func (s *taskgroupController) List(selector labels.Selector) (ret []*schedtypes.TaskGroup, err error) { + err = ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*schedtypes.TaskGroup)) + }) + return ret, err +} + +// NamespaceList get specified taskgroup by namespace +func (s *taskgroupController) NamespaceList(ns string, selector labels.Selector) (ret []*schedtypes.TaskGroup, err error) { + err = ListAllByNamespace(s.indexer, ns, selector, func(m interface{}) { + ret = append(ret, m.(*schedtypes.TaskGroup)) + }) + return ret, err +} + +func (s *taskgroupController) ApplicationList(ns, appname string, + selector labels.Selector) (ret []*schedtypes.TaskGroup, err error) { + + err = ListAllByApplication(s.indexer, ns, appname, selector, func(m interface{}) { + ret = append(ret, m.(*schedtypes.TaskGroup)) + }) + return ret, err +} + +func (s *taskgroupController) GetById(taskgroupId string) (*schedtypes.TaskGroup, error) { + //taskgroupId example: 0.appname.namespace.10001.1505188438633098965 + arr := strings.Split(taskgroupId, ".") + if len(arr) != 5 { + return nil, fmt.Errorf("taskgroupId %s is invalid", taskgroupId) + } + + obj, exists, err := s.indexer.GetByKey(path.Join(arr[2], arr[1])) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("Taskgroup"), taskgroupId) + } + return obj.(*schedtypes.TaskGroup), nil +} + +func (s *taskgroupController) GetByName(ns, name string) (*schedtypes.TaskGroup, error) { + obj, exists, err := s.indexer.GetByKey(path.Join(ns, name)) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("Taskgroup"), fmt.Sprintf("%s.%s", ns, name)) + } + return obj.(*schedtypes.TaskGroup), nil +} + +func NewTaskgroupController(hosts []string, eventHandler reflector.EventInterface) (TaskgroupController, error) { + indexers := k8scache.Indexers{ + meta.NamespaceIndex: meta.NamespaceIndexFunc, + meta.ApplicationIndex: meta.ApplicationIndexFunc, + } + + ts := k8scache.NewIndexer(TaskGroupObjectKeyFn, indexers) + //create namespace client for zookeeper + zkConfig := &zookeeper.ZkConfig{ + Hosts: hosts, + PrefixPath: "/blueking/application", + Name: "taskgroup", + Codec: &meta.JsonCodec{}, + ObjectNewFunc: TaskGroupObjectNewFn, + } + podclient, err := zookeeper.NewPodClient(zkConfig) + if err != nil { + blog.Errorf("bk-bcs mesos discovery create taskgroup pod client failed, %s", err) + return nil, err + } + //create listwatcher + listwatcher := &reflector.ListWatch{ + ListFn: func() ([]meta.Object, error) { + return podclient.List(context.Background(), "", nil) + }, + WatchFn: func() (watch.Interface, error) { + return podclient.Watch(context.Background(), "", "", nil) + }, + } + cxt, stopfn := context.WithCancel(context.Background()) + ctl := &taskgroupController{ + cxt: cxt, + stopFn: stopfn, + eventStorage: podclient, + indexer: ts, + } + + //create reflector + ctl.reflector = reflector.NewReflector(fmt.Sprintf("Reflector-%s", zkConfig.Name), ts, listwatcher, time.Second*600, eventHandler) + //sync all data object from remote event storage + err = ctl.reflector.ListAllData() + if err != nil { + return nil, err + } + //run reflector controller + go ctl.reflector.Run() + + return ctl, nil +} + +//TaskGroupObjectKeyFn create key for taskgroup +func TaskGroupObjectKeyFn(obj interface{}) (string, error) { + task, ok := obj.(*schedtypes.TaskGroup) + if !ok { + return "", fmt.Errorf("error object type") + } + return path.Join(task.GetNamespace(), task.GetName()), nil +} + +//TaskGroupObjectNewFn create new Service Object +func TaskGroupObjectNewFn() meta.Object { + return new(schedtypes.TaskGroup) +} diff --git a/bcs-common/pkg/meta/codec.go b/bcs-common/pkg/meta/codec.go new file mode 100644 index 0000000000..6d0b9ab099 --- /dev/null +++ b/bcs-common/pkg/meta/codec.go @@ -0,0 +1,57 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package meta + +import ( + "encoding/json" + "fmt" +) + +//Encoder define data object encode +type Encoder interface { + Encode(obj Object) ([]byte, error) +} + +//Decoder decode bytes to object +type Decoder interface { + Decode(data []byte, obj Object) error +} + +//Codec combine Encoder & Decoder +type Codec interface { + Encoder + Decoder +} + +//JsonCodec decode & encode with json +type JsonCodec struct{} + +//Encode implements Encoder +func (jc *JsonCodec) Encode(obj Object) ([]byte, error) { + if obj == nil { + return nil, fmt.Errorf("nil object") + } + return json.Marshal(obj) +} + +//Decode implements Decoder +func (jc *JsonCodec) Decode(data []byte, obj Object) error { + if obj == nil { + return fmt.Errorf("nil object") + } + if len(data) == 0 { + return fmt.Errorf("empty decode data") + } + return json.Unmarshal(data, obj) +} diff --git a/bcs-common/pkg/meta/labels.go b/bcs-common/pkg/meta/labels.go new file mode 100644 index 0000000000..0d58b41918 --- /dev/null +++ b/bcs-common/pkg/meta/labels.go @@ -0,0 +1,114 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package meta + +import ( + "sort" + "strings" +) + +//Labels label definition +type Labels map[string]string + +//String implement string interface +func (lb Labels) String() string { + s := make([]string, 0, len(lb)) + for k, v := range lb { + s = append(s, k+"="+v) + } + sort.StringSlice(s).Sort() + return strings.Join(s, ",") +} + +//Has check key existence +func (lb Labels) Has(key string) bool { + _, ok := lb[key] + return ok +} + +//Get get key value +func (lb Labels) Get(key string) string { + return lb[key] +} + +//LabelsMerge merge two Labels into one +//if keys are conflict, keys in y will be reserved +func LabelsMerge(x, y Labels) Labels { + z := Labels{} + for k, v := range x { + z[k] = v + } + for k, v := range y { + z[k] = v + } + return z +} + +//LabelsConflict means two labels have some key but different value +func LabelsConflict(x, y Labels) bool { + small := x + big := y + if len(x) > len(y) { + small = y + big = x + } + for k, v := range small { + if other, ok := big[k]; ok { + if other != v { + return true + } + } + } + return false +} + +//LabelsAllMatch check key/value in Labels X are totally matched +// in Y, **please pay more attention**: function return +//true even if x is nil or empty +func LabelsAllMatch(x, y Labels) bool { + if len(x) == 0 { + return true + } + for k, v := range x { + other, ok := y[k] + if !ok { + return false + } + if v != other { + return false + } + } + return true +} + +//StringToLabels converts string to Labels +//string formate likes a=vlaue,b=value2, no space inside +func StringToLabels(s string) Labels { + kvs := strings.Split(s, ",") + if len(kvs) == 0 { + return nil + } + m := make(map[string]string) + for _, raw := range kvs { + kv := strings.Split(raw, "=") + if len(kv) != 2 { + continue + } + m[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1]) + } + if len(m) == 0 { + return nil + } + return Labels(m) +} diff --git a/bcs-common/pkg/meta/meta.go b/bcs-common/pkg/meta/meta.go new file mode 100644 index 0000000000..556e906ab1 --- /dev/null +++ b/bcs-common/pkg/meta/meta.go @@ -0,0 +1,124 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package meta + +import ( + "time" +) + +const ( + // NamespaceAll is the default argument to specify on a context when you want to list or filter resources across all namespaces + NamespaceAll string = "" +) + +//TypeMeta define version & type +type TypeMeta struct { + APIVersion string `json:"apiVersion,omitempty"` + Kind string `json:"kind,omitempty"` +} + +//ObjectMeta common meta info for all Object +type ObjectMeta struct { + Name string `json:"name"` + Namespace string `json:"namespace,omitempty"` + CreationTimestamp time.Time `json:"creationTimestamp,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` + ClusterName string `json:"clusterName,omitempty"` +} + +//GetName get object name +func (obj *ObjectMeta) GetName() string { + return obj.Name +} + +//SetName set object name +func (obj *ObjectMeta) SetName(name string) { + obj.Name = name +} + +//GetNamespace get object namespace +func (obj *ObjectMeta) GetNamespace() string { + return obj.Namespace +} + +//SetNamespace set object namespace +func (obj *ObjectMeta) SetNamespace(ns string) { + obj.Namespace = ns +} + +//GetCreationTimestamp get create timestamp +func (obj *ObjectMeta) GetCreationTimestamp() time.Time { + return obj.CreationTimestamp +} + +//SetCreationTimestamp set creat timestamp +func (obj *ObjectMeta) SetCreationTimestamp(timestamp time.Time) { + obj.CreationTimestamp = timestamp +} + +//GetLabels get object labels +func (obj *ObjectMeta) GetLabels() map[string]string { + return obj.Labels +} + +//SetLabels set objec labels +func (obj *ObjectMeta) SetLabels(labels map[string]string) { + obj.Labels = labels +} + +//GetAnnotations get object annotation +func (obj *ObjectMeta) GetAnnotations() map[string]string { + return obj.Annotations +} + +//SetAnnotations get annotation name +func (obj *ObjectMeta) SetAnnotations(annotation map[string]string) { + obj.Annotations = annotation +} + +//GetClusterName get cluster name +func (obj *ObjectMeta) GetClusterName() string { + return obj.ClusterName +} + +//SetClusterName set cluster name +func (obj *ObjectMeta) SetClusterName(clusterName string) { + obj.ClusterName = clusterName +} + +//Objects define list for object +type Objects struct { + ObjectMeta `json:"meta"` + Items []Object `json:"items"` +} + +//GetItems implements List interface +func (objs *Objects) GetItems() []Object { + return objs.Items +} + +//SetItems implements List interface +func (objs *Objects) SetItems(list []Object) { + objs.Items = list +} + +func Accessor(obj interface{}) (Object, error) { + switch t := obj.(type) { + case Object: + return t, nil + default: + return nil, errNotObject + } +} diff --git a/bcs-common/pkg/meta/object.go b/bcs-common/pkg/meta/object.go new file mode 100644 index 0000000000..084217c72d --- /dev/null +++ b/bcs-common/pkg/meta/object.go @@ -0,0 +1,86 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package meta + +import ( + "fmt" + "strings" + "time" +) + +//ObjectNewFn return target data object pointer +type ObjectNewFn func() Object + +//ObjectListNewFn creat Object List +type ObjectListNewFn func(raw []byte) ([]Object, error) + +//Object offer common interface to access all data objects +type Object interface { + GetName() string + SetName(name string) + GetNamespace() string + SetNamespace(ns string) + GetCreationTimestamp() time.Time + SetCreationTimestamp(timestamp time.Time) + GetLabels() map[string]string + SetLabels(lables map[string]string) + GetAnnotations() map[string]string + SetAnnotations(annotation map[string]string) + GetClusterName() string + SetClusterName(clusterName string) +} + +//List list for objects +type List interface { + GetItems() []Object + SetItems([]Object) +} + +const ( + NamespaceIndex string = "namespace" + //only taskgroup has the application index + ApplicationIndex string = "application" +) + +var errNotObject = fmt.Errorf("object does not implement the Object interfaces") + +// NamespaceIndexFunc is a default index function that indexes based on an object's namespace +func NamespaceIndexFunc(obj interface{}) ([]string, error) { + switch t := obj.(type) { + case Object: + return []string{t.GetNamespace()}, nil + + default: + return nil, errNotObject + } +} + +// ApplicationIndexFunc is a default index function that indexes based on an object's application name +// only taskgroup has this index +func ApplicationIndexFunc(obj interface{}) ([]string, error) { + switch t := obj.(type) { + case Object: + //name: mars-test-lb-0 and mars-test-lb is appname + //application is appname.namespace + index := strings.LastIndex(t.GetName(), "-") + if index == -1 { + return nil, fmt.Errorf("Taskgroup(%s:%s) is invalid", t.GetNamespace(), t.GetName()) + } + + return []string{fmt.Sprintf("%s.%s", t.GetName()[:index], t.GetNamespace())}, nil + + default: + return nil, errNotObject + } +} diff --git a/bcs-common/pkg/discovery/mesh.go b/bcs-common/pkg/queue/event.go similarity index 78% rename from bcs-common/pkg/discovery/mesh.go rename to bcs-common/pkg/queue/event.go index 060309c41e..6913b3ba32 100644 --- a/bcs-common/pkg/discovery/mesh.go +++ b/bcs-common/pkg/queue/event.go @@ -11,10 +11,12 @@ * */ -package discovery +package queue -//Mesh shoue -type Mesh struct { - Source string `json:"source"` //definition request source - Destination string `json:"destination"` //definition request destination +import "bk-bcs/bcs-common/pkg/watch" + +//Event holding event info for data object +type Event struct { + Type watch.EventType + Data interface{} } diff --git a/bcs-common/pkg/queue/queue.go b/bcs-common/pkg/queue/queue.go new file mode 100644 index 0000000000..67b4bdc958 --- /dev/null +++ b/bcs-common/pkg/queue/queue.go @@ -0,0 +1,87 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package queue + +import ( + "bk-bcs/bcs-common/pkg/watch" + "fmt" +) + +// Queue integrates all data events to one seqential queue +type Queue interface { + // Push specified event to local queue + Push(e *Event) + // Get event from queue, blocked + Get() (*Event, error) + // AGet async get event from queue, not blocked + AGet() (*Event, error) + // GetChannel event reading queue + GetChannel() (<-chan *Event, error) + // Close close Queue + Close() +} + +// NewQueue create default Queue for local usage +func NewQueue() Queue { + return &channelQueue{ + localQ: make(chan *Event, watch.DefaultChannelBuffer), + } +} + +// channelQueue default queue using channel +type channelQueue struct { + localQ chan *Event +} + +// Push specified event to local queue +func (cq *channelQueue) Push(e *Event) { + if e != nil { + cq.localQ <- e + } +} + +// Get event from queue +func (cq *channelQueue) Get() (*Event, error) { + e, ok := <-cq.localQ + if ok { + return e, nil + } + return nil, fmt.Errorf("Queue closed") +} + +// AGet async get event from queue, not blocked +func (cq *channelQueue) AGet() (*Event, error) { + select { + case e, ok := <-cq.localQ: + if ok { + return e, nil + } + return nil, fmt.Errorf("Queue closed") + default: + return nil, nil + } +} + +// GetChannel event reading queue +func (cq *channelQueue) GetChannel() (<-chan *Event, error) { + if cq.localQ == nil { + return nil, fmt.Errorf("lost event queue") + } + return cq.localQ, nil +} + +// Close event queue +func (cq *channelQueue) Close() { + close(cq.localQ) +} diff --git a/bcs-common/pkg/reflector/listerwatcher.go b/bcs-common/pkg/reflector/listerwatcher.go new file mode 100644 index 0000000000..65841e35be --- /dev/null +++ b/bcs-common/pkg/reflector/listerwatcher.go @@ -0,0 +1,57 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package reflector + +import ( + "bk-bcs/bcs-common/pkg/meta" + "bk-bcs/bcs-common/pkg/watch" + "fmt" +) + +// ListerWatcher is interface perform list all objects and start a watch +type ListerWatcher interface { + // List should return a list type object + List() ([]meta.Object, error) + // Watch should begin a watch from remote storage + Watch() (watch.Interface, error) +} + +//ListFunc define list function for ListerWatcher +type ListFunc func() ([]meta.Object, error) + +//WatchFunc define watch function for ListerWatcher +type WatchFunc func() (watch.Interface, error) + +//ListWatch implements ListerWatcher interface +//protect ListFunc or WatchFunc is nil +type ListWatch struct { + ListFn ListFunc + WatchFn WatchFunc +} + +// List should return a list type object +func (lw *ListWatch) List() ([]meta.Object, error) { + if lw.ListFn == nil { + return nil, nil + } + return lw.ListFn() +} + +// Watch should begin a watch from remote storage +func (lw *ListWatch) Watch() (watch.Interface, error) { + if lw.WatchFn == nil { + return nil, fmt.Errorf("Lost watcher function") + } + return lw.WatchFn() +} diff --git a/bcs-common/pkg/reflector/reflector.go b/bcs-common/pkg/reflector/reflector.go new file mode 100644 index 0000000000..5d45fb9fa6 --- /dev/null +++ b/bcs-common/pkg/reflector/reflector.go @@ -0,0 +1,220 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package reflector + +import ( + "time" + + "bk-bcs/bcs-common/common/blog" + "bk-bcs/bcs-common/pkg/watch" + + "golang.org/x/net/context" + k8scache "k8s.io/client-go/tools/cache" +) + +//NewReflector create new reflector +func NewReflector(name string, store k8scache.Indexer, lw ListerWatcher, fullSyncPeriod time.Duration, handler EventInterface) *Reflector { + cxt, stopfn := context.WithCancel(context.Background()) + return &Reflector{ + name: name, + cxt: cxt, + stopFn: stopfn, + listWatch: lw, + syncPeriod: fullSyncPeriod, + store: store, + handler: handler, + underWatch: false, + } +} + +//Reflector offers lister & watcher mechanism to sync event-storage data +//to local memory store, and meanwhile push data event to predifine event handler +type Reflector struct { + name string //reflector name + cxt context.Context + stopFn context.CancelFunc + listWatch ListerWatcher //lister & watcher for object data + syncPeriod time.Duration //period for resync all data + store k8scache.Indexer //memory store for all data object + handler EventInterface //event callback when processing store data + underWatch bool //flag for watch handler +} + +//Run running reflector, list all data in period and create stable watcher for +//all data events +func (r *Reflector) Run() { + blog.V(3).Infof("%s ready to start, begin to cache data", r.name) + //sync all data object from remote event storage + //r.listAllData() + watchCxt, _ := context.WithCancel(r.cxt) + go r.handleWatch(watchCxt) + blog.V(3).Infof("%s first resynchronization & watch success, register all ticker", r.name) + //create ticker for data object resync + syncTick := time.NewTicker(r.syncPeriod) + //create ticker check stable watcher + watchTick := time.NewTicker(time.Second * 2) + for { + select { + case <-r.cxt.Done(): + blog.Warnf("%s running exit, lister & watcher stopped", r.name) + return + case <-syncTick.C: + //fully resync all datas in period + blog.Infof("%s trigger all data synchronization", r.name) + r.ListAllData() + case <-watchTick.C: + //check watch is running + if r.underWatch { + continue + } + //watch is out, recovery watch loop + blog.Warnf("%s long watch is out, start watch loop to recovery.", r.name) + go r.handleWatch(watchCxt) + } + } +} + +//Stop stop reflector +func (r *Reflector) Stop() { + blog.V(3).Infof("%s is asked to stop", r.name) + r.stopFn() +} + +func (r *Reflector) ListAllData() error { + blog.V(3).Infof("%s begins to list all data...", r.name) + objs, err := r.listWatch.List() + if err != nil { + //some err response, wait for next resync ticker + blog.Errorf("%s List all data failed, %s", r.name, err) + return err + } + blog.V(3).Infof("%s list all data success, objects number %d", r.name, len(objs)) + for _, obj := range objs { + oldObj, exist, err := r.store.Get(obj) + if err != nil { + blog.Errorf("%s gets local store err under List, %s, discard data", r.name, err) + continue + } + if exist { + r.store.Update(obj) + if r.handler != nil { + r.handler.OnUpdate(oldObj, obj) + } + blog.V(5).Infof("%s update %s/%s notify succes in Lister.", r.name, obj.GetNamespace(), obj.GetName()) + } else { + r.store.Add(obj) + if r.handler != nil { + r.handler.OnAdd(obj) + } + blog.V(5).Infof("%s add %s/%s notify succes in Lister.", r.name, obj.GetNamespace(), obj.GetName()) + } + } + + return nil +} + +func (r *Reflector) handleWatch(cxt context.Context) { + if r.underWatch { + return + } + r.underWatch = true + watcher, err := r.listWatch.Watch() + if err != nil { + blog.Errorf("Reflector %s create watch by ListerWatcher failed, %s", r.name, err) + r.underWatch = false + return + } + defer func() { + r.underWatch = false + watcher.Stop() + blog.Infof("Reflector %s watch loop exit", r.name) + }() + blog.V(3).Infof("%s enter storage watch loop, waiting for event trigger", r.name) + channel := watcher.WatchEvent() + for { + select { + case <-cxt.Done(): + blog.Infof("reflector %s is asked to exit.", r.name) + return + case event, ok := <-channel: + if !ok { + blog.Errorf("%s reads watch.Event from channel failed. channel closed", r.name) + return + } + switch event.Type { + case watch.EventSync, watch.EventAdded, watch.EventUpdated: + r.processAddUpdate(&event) + case watch.EventDeleted: + r.processDeletion(&event) + case watch.EventErr: + //some unexpected err occured, but channel & watach is still work + blog.V(3).Infof("Reflector %s catch some data err in watch.Event channel, keep watch running", r.name) + } + } + } +} + +func (r *Reflector) processAddUpdate(event *watch.Event) { + oldObj, exist, err := r.store.Get(event.Data) + if err != nil { + blog.V(3).Infof("Reflector %s gets local store err, %s", r.name, err) + return + } + if exist { + r.store.Update(event.Data) + if r.handler != nil { + r.handler.OnUpdate(oldObj, event.Data) + } + } else { + r.store.Add(event.Data) + if r.handler != nil { + r.handler.OnAdd(event.Data) + } + } +} + +func (r *Reflector) processDeletion(event *watch.Event) { + //fix(DeveloperJim): 2018-06-26 16:42:10 + //when deletion happens in zookeeper, no Object dispatchs, so we + //need to get object from local cache + oldObj, exist, err := r.store.Get(event.Data) + if err != nil { + blog.V(3).Infof("Reflector %s gets local store err in DeleteEvent, %s", r.name, err) + return + } + if exist { + r.store.Delete(event.Data) + if event.Data.GetAnnotations() != nil && event.Data.GetAnnotations()["bk-bcs-inner-storage"] == "bkbcs-zookeeper" { + //tricky here, zookeeper can't get creation time when deletion + if r.handler != nil { + r.handler.OnDelete(oldObj) + } + blog.V(5).Infof("reflector %s invoke Delete tricky callback func for %s/%s.", r.name, event.Data.GetNamespace(), event.Data.GetName()) + } else { + if r.handler != nil { + r.handler.OnDelete(event.Data) + } + blog.V(5).Infof("reflector %s invoke Delete callback for %s/%s.", r.name, event.Data.GetNamespace(), event.Data.GetName()) + } + } + //local cache do not exist, nothing happens + blog.V(3).Infof("reflector %s lost local cache for %s/%s", r.name, event.Data.GetNamespace(), event.Data.GetName()) +} + +//EventInterface register interface for event notification +type EventInterface interface { + OnAdd(obj interface{}) + OnUpdate(old, cur interface{}) + OnDelete(obj interface{}) +} diff --git a/bcs-common/pkg/scheduler/mesosproto/json/call.go b/bcs-common/pkg/scheduler/mesosproto/json/call.go new file mode 100644 index 0000000000..ae0971230c --- /dev/null +++ b/bcs-common/pkg/scheduler/mesosproto/json/call.go @@ -0,0 +1,18 @@ +package json + +type Call struct { + Type string `json:"type"` + Subscribe *Subscribe `json:"subscribe"` +} +type Subscribe struct { + FrameworkInfo *FrameworkInfo `json:"framework_info"` +} +type FrameworkInfo struct { + User string `json:"user"` + Name string `json:"name"` + HostName string `json:"hostname"` + *FrameworkID `json:"framework_id"` +} +type FrameworkID struct { + Value string `json:"value"` +} diff --git a/bcs-common/pkg/scheduler/mesosproto/mesos/allocator/allocator.pb.go b/bcs-common/pkg/scheduler/mesosproto/mesos/allocator/allocator.pb.go new file mode 100644 index 0000000000..f1093b1bc1 --- /dev/null +++ b/bcs-common/pkg/scheduler/mesosproto/mesos/allocator/allocator.pb.go @@ -0,0 +1,141 @@ +// Code generated by protoc-gen-go. +// source: allocator.proto +// DO NOT EDIT! + +/* +Package mesos_allocator is a generated protocol buffer package. + +It is generated from these files: + allocator.proto + +It has these top-level messages: + InverseOfferStatus +*/ +package mesos_allocator + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import mesos "bk-bcs/bcs-common/pkg/scheduler/mesosproto/mesos" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type InverseOfferStatus_Status int32 + +const ( + // We have not received a response yet. This is the default state before + // receiving a response. + InverseOfferStatus_UNKNOWN InverseOfferStatus_Status = 1 + // The framework is ok with the inverse offer. This means it will not + // violate any SLAs and will attempt to evacuate any tasks running on the + // agent. If the tasks are not evacuated by the framework, the operator can + // manually shut down the slave knowing that the framework will not have + // violated its SLAs. + InverseOfferStatus_ACCEPT InverseOfferStatus_Status = 2 + // The framework wants to block the maintenance operation from happening. An + // example would be that it cannot meet its SLA by losing resources. + InverseOfferStatus_DECLINE InverseOfferStatus_Status = 3 +) + +var InverseOfferStatus_Status_name = map[int32]string{ + 1: "UNKNOWN", + 2: "ACCEPT", + 3: "DECLINE", +} +var InverseOfferStatus_Status_value = map[string]int32{ + "UNKNOWN": 1, + "ACCEPT": 2, + "DECLINE": 3, +} + +func (x InverseOfferStatus_Status) Enum() *InverseOfferStatus_Status { + p := new(InverseOfferStatus_Status) + *p = x + return p +} +func (x InverseOfferStatus_Status) String() string { + return proto.EnumName(InverseOfferStatus_Status_name, int32(x)) +} +func (x *InverseOfferStatus_Status) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(InverseOfferStatus_Status_value, data, "InverseOfferStatus_Status") + if err != nil { + return err + } + *x = InverseOfferStatus_Status(value) + return nil +} +func (InverseOfferStatus_Status) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} } + +// * +// Describes the status of an inverse offer. +// +// This is a protobuf so as to be able to share the status to inverse offers +// through endpoints such as the maintenance status endpoint. +type InverseOfferStatus struct { + Status *InverseOfferStatus_Status `protobuf:"varint,1,req,name=status,enum=mesos.v1.allocator.InverseOfferStatus_Status" json:"status,omitempty"` + FrameworkId *mesos.FrameworkID `protobuf:"bytes,2,req,name=framework_id,json=frameworkId" json:"framework_id,omitempty"` + // Time, since the epoch, when this status was last updated. + Timestamp *mesos.TimeInfo `protobuf:"bytes,3,req,name=timestamp" json:"timestamp,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *InverseOfferStatus) Reset() { *m = InverseOfferStatus{} } +func (m *InverseOfferStatus) String() string { return proto.CompactTextString(m) } +func (*InverseOfferStatus) ProtoMessage() {} +func (*InverseOfferStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *InverseOfferStatus) GetStatus() InverseOfferStatus_Status { + if m != nil && m.Status != nil { + return *m.Status + } + return InverseOfferStatus_UNKNOWN +} + +func (m *InverseOfferStatus) GetFrameworkId() *mesos.FrameworkID { + if m != nil { + return m.FrameworkId + } + return nil +} + +func (m *InverseOfferStatus) GetTimestamp() *mesos.TimeInfo { + if m != nil { + return m.Timestamp + } + return nil +} + +func init() { + proto.RegisterType((*InverseOfferStatus)(nil), "mesos.v1.allocator.InverseOfferStatus") + proto.RegisterEnum("mesos.v1.allocator.InverseOfferStatus_Status", InverseOfferStatus_Status_name, InverseOfferStatus_Status_value) +} + +func init() { proto.RegisterFile("allocator.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 225 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x4f, 0xcc, 0xc9, 0xc9, + 0x4f, 0x4e, 0x2c, 0xc9, 0x2f, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0xca, 0x4d, 0x2d, + 0xce, 0x2f, 0xd6, 0x2b, 0x33, 0xd4, 0x83, 0xcb, 0x48, 0x89, 0x80, 0xc5, 0xf4, 0xcb, 0x0c, 0xf5, + 0x21, 0x92, 0x60, 0x95, 0x4a, 0xdf, 0x19, 0xb9, 0x84, 0x3c, 0xf3, 0xca, 0x52, 0x8b, 0x8a, 0x53, + 0xfd, 0xd3, 0xd2, 0x52, 0x8b, 0x82, 0x4b, 0x12, 0x4b, 0x4a, 0x8b, 0x85, 0x5c, 0xb9, 0xd8, 0x8a, + 0xc1, 0x2c, 0x09, 0x46, 0x05, 0x26, 0x0d, 0x3e, 0x23, 0x5d, 0x3d, 0x4c, 0x13, 0xf5, 0x30, 0xf5, + 0xe9, 0x41, 0xa8, 0x20, 0xa8, 0x66, 0x21, 0x0b, 0x2e, 0x9e, 0xb4, 0xa2, 0xc4, 0xdc, 0xd4, 0xf2, + 0xfc, 0xa2, 0xec, 0xf8, 0xcc, 0x14, 0x09, 0x26, 0x05, 0x26, 0x0d, 0x6e, 0x23, 0x51, 0x84, 0x61, + 0x6e, 0x30, 0x59, 0x4f, 0x97, 0x20, 0x6e, 0xb8, 0x52, 0xcf, 0x14, 0x21, 0x03, 0x2e, 0xce, 0x92, + 0xcc, 0xdc, 0xd4, 0xe2, 0x92, 0xc4, 0xdc, 0x02, 0x09, 0x66, 0xb0, 0x36, 0x21, 0x84, 0xb6, 0x90, + 0xcc, 0xdc, 0x54, 0xcf, 0xbc, 0xb4, 0xfc, 0x20, 0x84, 0x22, 0x25, 0x3d, 0x2e, 0x36, 0xa8, 0xe3, + 0xb9, 0xb9, 0xd8, 0x43, 0xfd, 0xbc, 0xfd, 0xfc, 0xc3, 0xfd, 0x04, 0x18, 0x85, 0xb8, 0xb8, 0xd8, + 0x1c, 0x9d, 0x9d, 0x5d, 0x03, 0x42, 0x04, 0x98, 0x40, 0x12, 0x2e, 0xae, 0xce, 0x3e, 0x9e, 0x7e, + 0xae, 0x02, 0xcc, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1a, 0x50, 0x74, 0xd9, 0x35, 0x01, 0x00, + 0x00, +} diff --git a/bcs-common/pkg/scheduler/mesosproto/mesos/maintenance/maintenance.pb.go b/bcs-common/pkg/scheduler/mesosproto/mesos/maintenance/maintenance.pb.go new file mode 100644 index 0000000000..fcc9923719 --- /dev/null +++ b/bcs-common/pkg/scheduler/mesosproto/mesos/maintenance/maintenance.pb.go @@ -0,0 +1,174 @@ +// Code generated by protoc-gen-go. +// source: maintenance.proto +// DO NOT EDIT! + +/* +Package mesos_maintenance is a generated protocol buffer package. + +It is generated from these files: + maintenance.proto + +It has these top-level messages: + Window + Schedule + ClusterStatus +*/ +package mesos_maintenance + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import mesos "bk-bcs/bcs-common/pkg/scheduler/mesosproto/mesos" +import mesos_allocator "bk-bcs/bcs-common/pkg/scheduler/mesosproto/mesos/allocator" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// * +// A set of machines scheduled to go into maintenance +// in the same `unavailability`. +type Window struct { + // Machines affected by this maintenance window. + MachineIds []*mesos.MachineID `protobuf:"bytes,1,rep,name=machine_ids,json=machineIds" json:"machine_ids,omitempty"` + // Interval during which this set of machines is expected to be down. + Unavailability *mesos.Unavailability `protobuf:"bytes,2,req,name=unavailability" json:"unavailability,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Window) Reset() { *m = Window{} } +func (m *Window) String() string { return proto.CompactTextString(m) } +func (*Window) ProtoMessage() {} +func (*Window) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *Window) GetMachineIds() []*mesos.MachineID { + if m != nil { + return m.MachineIds + } + return nil +} + +func (m *Window) GetUnavailability() *mesos.Unavailability { + if m != nil { + return m.Unavailability + } + return nil +} + +// * +// A list of maintenance windows. +// For example, this may represent a rolling restart of agents. +type Schedule struct { + Windows []*Window `protobuf:"bytes,1,rep,name=windows" json:"windows,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Schedule) Reset() { *m = Schedule{} } +func (m *Schedule) String() string { return proto.CompactTextString(m) } +func (*Schedule) ProtoMessage() {} +func (*Schedule) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *Schedule) GetWindows() []*Window { + if m != nil { + return m.Windows + } + return nil +} + +// * +// Represents the maintenance status of each machine in the cluster. +// The lists correspond to the `MachineInfo.Mode` enumeration. +type ClusterStatus struct { + DrainingMachines []*ClusterStatus_DrainingMachine `protobuf:"bytes,1,rep,name=draining_machines,json=drainingMachines" json:"draining_machines,omitempty"` + DownMachines []*mesos.MachineID `protobuf:"bytes,2,rep,name=down_machines,json=downMachines" json:"down_machines,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ClusterStatus) Reset() { *m = ClusterStatus{} } +func (m *ClusterStatus) String() string { return proto.CompactTextString(m) } +func (*ClusterStatus) ProtoMessage() {} +func (*ClusterStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *ClusterStatus) GetDrainingMachines() []*ClusterStatus_DrainingMachine { + if m != nil { + return m.DrainingMachines + } + return nil +} + +func (m *ClusterStatus) GetDownMachines() []*mesos.MachineID { + if m != nil { + return m.DownMachines + } + return nil +} + +type ClusterStatus_DrainingMachine struct { + Id *mesos.MachineID `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` + // A list of the most recent responses to inverse offers from frameworks + // running on this draining machine. + Statuses []*mesos_allocator.InverseOfferStatus `protobuf:"bytes,2,rep,name=statuses" json:"statuses,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ClusterStatus_DrainingMachine) Reset() { *m = ClusterStatus_DrainingMachine{} } +func (m *ClusterStatus_DrainingMachine) String() string { return proto.CompactTextString(m) } +func (*ClusterStatus_DrainingMachine) ProtoMessage() {} +func (*ClusterStatus_DrainingMachine) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{2, 0} +} + +func (m *ClusterStatus_DrainingMachine) GetId() *mesos.MachineID { + if m != nil { + return m.Id + } + return nil +} + +func (m *ClusterStatus_DrainingMachine) GetStatuses() []*mesos_allocator.InverseOfferStatus { + if m != nil { + return m.Statuses + } + return nil +} + +func init() { + proto.RegisterType((*Window)(nil), "mesos.v1.maintenance.Window") + proto.RegisterType((*Schedule)(nil), "mesos.v1.maintenance.Schedule") + proto.RegisterType((*ClusterStatus)(nil), "mesos.v1.maintenance.ClusterStatus") + proto.RegisterType((*ClusterStatus_DrainingMachine)(nil), "mesos.v1.maintenance.ClusterStatus.DrainingMachine") +} + +func init() { proto.RegisterFile("maintenance.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 334 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x92, 0x4f, 0x4b, 0xf3, 0x40, + 0x10, 0xc6, 0x69, 0x5e, 0xe8, 0x5b, 0xa6, 0x56, 0xed, 0xea, 0x21, 0x14, 0xc1, 0x12, 0x41, 0xea, + 0x65, 0x4b, 0xab, 0x88, 0x47, 0x89, 0xbd, 0xf4, 0x20, 0x4a, 0x8a, 0x78, 0xac, 0x63, 0x76, 0xdb, + 0x2e, 0xa4, 0xbb, 0x25, 0xbb, 0x49, 0xd1, 0x93, 0xdf, 0xc6, 0xaf, 0x29, 0xcd, 0x5f, 0x53, 0xe2, + 0x2d, 0xcc, 0xfc, 0x9e, 0x67, 0x9e, 0x99, 0x2c, 0x74, 0xd7, 0x28, 0xa4, 0xe1, 0x12, 0xa5, 0xcf, + 0xe9, 0x26, 0x54, 0x46, 0x91, 0xd3, 0x35, 0xd7, 0x4a, 0xd3, 0x78, 0x44, 0x7f, 0xf5, 0x7a, 0x69, + 0x75, 0x18, 0x8f, 0x86, 0x69, 0x3b, 0x61, 0x7b, 0x4e, 0x51, 0xc5, 0x20, 0x50, 0x3e, 0x1a, 0x15, + 0x96, 0x5f, 0x29, 0xe3, 0x7c, 0x35, 0xa0, 0xf9, 0x2a, 0x24, 0x53, 0x5b, 0x72, 0x03, 0xed, 0x35, + 0xfa, 0x2b, 0x21, 0xf9, 0x5c, 0x30, 0x6d, 0x37, 0xfa, 0xff, 0x06, 0xed, 0xf1, 0x09, 0x2d, 0x06, + 0x3e, 0xa6, 0xcd, 0xe9, 0xc4, 0x83, 0x8c, 0x9b, 0x32, 0x4d, 0xee, 0xe1, 0x30, 0x92, 0x18, 0xa3, + 0x08, 0xf0, 0x5d, 0x04, 0xc2, 0x7c, 0xd8, 0x56, 0xdf, 0x1a, 0xb4, 0xc7, 0x76, 0x29, 0x7c, 0xa9, + 0xf4, 0xbd, 0x3d, 0xde, 0x71, 0xa1, 0x35, 0xf3, 0x57, 0x9c, 0x45, 0x01, 0x27, 0xb7, 0xf0, 0x7f, + 0x9b, 0xa4, 0xc9, 0xe7, 0x9f, 0xd1, 0xba, 0x85, 0x69, 0x1a, 0xd9, 0xcb, 0x61, 0xe7, 0xdb, 0x82, + 0xce, 0x43, 0x10, 0x69, 0xc3, 0xc3, 0x99, 0x41, 0x13, 0x69, 0xf2, 0x06, 0x5d, 0x16, 0xa2, 0x90, + 0x42, 0x2e, 0xe7, 0x59, 0xdc, 0xdc, 0xf3, 0xba, 0xde, 0xb3, 0xa2, 0xa7, 0x93, 0x4c, 0x9c, 0x6d, + 0xed, 0x1d, 0xb3, 0x6a, 0x41, 0x93, 0x3b, 0xe8, 0x30, 0xb5, 0x95, 0xa5, 0xbb, 0xf5, 0xf7, 0xc5, + 0x0e, 0x76, 0x64, 0xae, 0xec, 0x7d, 0xc2, 0xd1, 0x9e, 0x3d, 0xb9, 0x00, 0x4b, 0x30, 0xbb, 0x91, + 0x9c, 0xae, 0xd6, 0xc1, 0x12, 0x8c, 0xb8, 0xd0, 0xd2, 0x49, 0xba, 0x62, 0xd8, 0x65, 0x89, 0x96, + 0x7f, 0x76, 0x2a, 0x63, 0x1e, 0x6a, 0xfe, 0xb4, 0x58, 0xe4, 0xdb, 0x78, 0x85, 0xce, 0xbd, 0x82, + 0x73, 0x15, 0x2e, 0x29, 0x6e, 0xd0, 0x5f, 0xf1, 0xda, 0x43, 0xb8, 0xcd, 0xe7, 0xdd, 0xd3, 0xd0, + 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x49, 0x49, 0xfb, 0x4b, 0x7f, 0x02, 0x00, 0x00, +} diff --git a/bcs-common/pkg/scheduler/mesosproto/mesos/master/master.pb.go b/bcs-common/pkg/scheduler/mesosproto/mesos/master/master.pb.go new file mode 100644 index 0000000000..d16b6ef053 --- /dev/null +++ b/bcs-common/pkg/scheduler/mesosproto/mesos/master/master.pb.go @@ -0,0 +1,1960 @@ +// Code generated by protoc-gen-go. +// source: master.proto +// DO NOT EDIT! + +/* +Package mesos_master is a generated protocol buffer package. + +It is generated from these files: + master.proto + +It has these top-level messages: + Call + Response + Event +*/ +package mesos_master + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import mesos "bk-bcs/bcs-common/pkg/scheduler/mesosproto/mesos" +import mesos_maintenance "bk-bcs/bcs-common/pkg/scheduler/mesosproto/mesos/maintenance" +import mesos_quota "bk-bcs/bcs-common/pkg/scheduler/mesosproto/mesos/quota" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type Call_Type int32 + +const ( + // If a call of type `Call::FOO` requires additional parameters they can be + // included in the corresponding `Call::Foo` message. Similarly, if a call + // receives a synchronous response it will be returned as a `Response` + // message of type `Response::FOO`. Currently all calls except + // `Call::SUBSCRIBE` receive synchronous responses; `Call::SUBSCRIBE` returns + // a streaming response of `Event`. + Call_UNKNOWN Call_Type = 0 + Call_GET_HEALTH Call_Type = 1 + Call_GET_FLAGS Call_Type = 2 + Call_GET_VERSION Call_Type = 3 + Call_GET_METRICS Call_Type = 4 + Call_GET_LOGGING_LEVEL Call_Type = 5 + Call_SET_LOGGING_LEVEL Call_Type = 6 + Call_LIST_FILES Call_Type = 7 + Call_READ_FILE Call_Type = 8 + Call_GET_STATE Call_Type = 9 + Call_GET_AGENTS Call_Type = 10 + Call_GET_FRAMEWORKS Call_Type = 11 + Call_GET_EXECUTORS Call_Type = 12 + Call_GET_TASKS Call_Type = 13 + Call_GET_ROLES Call_Type = 14 + Call_GET_WEIGHTS Call_Type = 15 + Call_UPDATE_WEIGHTS Call_Type = 16 + Call_GET_MASTER Call_Type = 17 + Call_SUBSCRIBE Call_Type = 18 + Call_RESERVE_RESOURCES Call_Type = 19 + Call_UNRESERVE_RESOURCES Call_Type = 20 + Call_CREATE_VOLUMES Call_Type = 21 + Call_DESTROY_VOLUMES Call_Type = 22 + // Retrieves the cluster's maintenance status. + Call_GET_MAINTENANCE_STATUS Call_Type = 23 + // Retrieves the cluster's maintenance schedule. + Call_GET_MAINTENANCE_SCHEDULE Call_Type = 24 + Call_UPDATE_MAINTENANCE_SCHEDULE Call_Type = 25 + Call_START_MAINTENANCE Call_Type = 26 + Call_STOP_MAINTENANCE Call_Type = 27 + Call_GET_QUOTA Call_Type = 28 + Call_SET_QUOTA Call_Type = 29 + Call_REMOVE_QUOTA Call_Type = 30 +) + +var Call_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "GET_HEALTH", + 2: "GET_FLAGS", + 3: "GET_VERSION", + 4: "GET_METRICS", + 5: "GET_LOGGING_LEVEL", + 6: "SET_LOGGING_LEVEL", + 7: "LIST_FILES", + 8: "READ_FILE", + 9: "GET_STATE", + 10: "GET_AGENTS", + 11: "GET_FRAMEWORKS", + 12: "GET_EXECUTORS", + 13: "GET_TASKS", + 14: "GET_ROLES", + 15: "GET_WEIGHTS", + 16: "UPDATE_WEIGHTS", + 17: "GET_MASTER", + 18: "SUBSCRIBE", + 19: "RESERVE_RESOURCES", + 20: "UNRESERVE_RESOURCES", + 21: "CREATE_VOLUMES", + 22: "DESTROY_VOLUMES", + 23: "GET_MAINTENANCE_STATUS", + 24: "GET_MAINTENANCE_SCHEDULE", + 25: "UPDATE_MAINTENANCE_SCHEDULE", + 26: "START_MAINTENANCE", + 27: "STOP_MAINTENANCE", + 28: "GET_QUOTA", + 29: "SET_QUOTA", + 30: "REMOVE_QUOTA", +} +var Call_Type_value = map[string]int32{ + "UNKNOWN": 0, + "GET_HEALTH": 1, + "GET_FLAGS": 2, + "GET_VERSION": 3, + "GET_METRICS": 4, + "GET_LOGGING_LEVEL": 5, + "SET_LOGGING_LEVEL": 6, + "LIST_FILES": 7, + "READ_FILE": 8, + "GET_STATE": 9, + "GET_AGENTS": 10, + "GET_FRAMEWORKS": 11, + "GET_EXECUTORS": 12, + "GET_TASKS": 13, + "GET_ROLES": 14, + "GET_WEIGHTS": 15, + "UPDATE_WEIGHTS": 16, + "GET_MASTER": 17, + "SUBSCRIBE": 18, + "RESERVE_RESOURCES": 19, + "UNRESERVE_RESOURCES": 20, + "CREATE_VOLUMES": 21, + "DESTROY_VOLUMES": 22, + "GET_MAINTENANCE_STATUS": 23, + "GET_MAINTENANCE_SCHEDULE": 24, + "UPDATE_MAINTENANCE_SCHEDULE": 25, + "START_MAINTENANCE": 26, + "STOP_MAINTENANCE": 27, + "GET_QUOTA": 28, + "SET_QUOTA": 29, + "REMOVE_QUOTA": 30, +} + +func (x Call_Type) Enum() *Call_Type { + p := new(Call_Type) + *p = x + return p +} +func (x Call_Type) String() string { + return proto.EnumName(Call_Type_name, int32(x)) +} +func (x *Call_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Call_Type_value, data, "Call_Type") + if err != nil { + return err + } + *x = Call_Type(value) + return nil +} +func (Call_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} } + +// Each of the responses of type `FOO` corresponds to `Foo` message below. +type Response_Type int32 + +const ( + Response_UNKNOWN Response_Type = 0 + Response_GET_HEALTH Response_Type = 1 + Response_GET_FLAGS Response_Type = 2 + Response_GET_VERSION Response_Type = 3 + Response_GET_METRICS Response_Type = 4 + Response_GET_LOGGING_LEVEL Response_Type = 5 + Response_LIST_FILES Response_Type = 6 + Response_READ_FILE Response_Type = 7 + Response_GET_STATE Response_Type = 8 + Response_GET_AGENTS Response_Type = 9 + Response_GET_FRAMEWORKS Response_Type = 10 + Response_GET_EXECUTORS Response_Type = 11 + Response_GET_TASKS Response_Type = 12 + Response_GET_ROLES Response_Type = 13 + Response_GET_WEIGHTS Response_Type = 14 + Response_GET_MASTER Response_Type = 15 + Response_GET_MAINTENANCE_STATUS Response_Type = 16 + Response_GET_MAINTENANCE_SCHEDULE Response_Type = 17 + Response_GET_QUOTA Response_Type = 18 +) + +var Response_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "GET_HEALTH", + 2: "GET_FLAGS", + 3: "GET_VERSION", + 4: "GET_METRICS", + 5: "GET_LOGGING_LEVEL", + 6: "LIST_FILES", + 7: "READ_FILE", + 8: "GET_STATE", + 9: "GET_AGENTS", + 10: "GET_FRAMEWORKS", + 11: "GET_EXECUTORS", + 12: "GET_TASKS", + 13: "GET_ROLES", + 14: "GET_WEIGHTS", + 15: "GET_MASTER", + 16: "GET_MAINTENANCE_STATUS", + 17: "GET_MAINTENANCE_SCHEDULE", + 18: "GET_QUOTA", +} +var Response_Type_value = map[string]int32{ + "UNKNOWN": 0, + "GET_HEALTH": 1, + "GET_FLAGS": 2, + "GET_VERSION": 3, + "GET_METRICS": 4, + "GET_LOGGING_LEVEL": 5, + "LIST_FILES": 6, + "READ_FILE": 7, + "GET_STATE": 8, + "GET_AGENTS": 9, + "GET_FRAMEWORKS": 10, + "GET_EXECUTORS": 11, + "GET_TASKS": 12, + "GET_ROLES": 13, + "GET_WEIGHTS": 14, + "GET_MASTER": 15, + "GET_MAINTENANCE_STATUS": 16, + "GET_MAINTENANCE_SCHEDULE": 17, + "GET_QUOTA": 18, +} + +func (x Response_Type) Enum() *Response_Type { + p := new(Response_Type) + *p = x + return p +} +func (x Response_Type) String() string { + return proto.EnumName(Response_Type_name, int32(x)) +} +func (x *Response_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Response_Type_value, data, "Response_Type") + if err != nil { + return err + } + *x = Response_Type(value) + return nil +} +func (Response_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 0} } + +type Event_Type int32 + +const ( + Event_UNKNOWN Event_Type = 0 + Event_SUBSCRIBED Event_Type = 1 + Event_TASK_ADDED Event_Type = 2 + Event_TASK_UPDATED Event_Type = 3 + Event_AGENT_ADDED Event_Type = 4 + Event_AGENT_REMOVED Event_Type = 5 +) + +var Event_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "SUBSCRIBED", + 2: "TASK_ADDED", + 3: "TASK_UPDATED", + 4: "AGENT_ADDED", + 5: "AGENT_REMOVED", +} +var Event_Type_value = map[string]int32{ + "UNKNOWN": 0, + "SUBSCRIBED": 1, + "TASK_ADDED": 2, + "TASK_UPDATED": 3, + "AGENT_ADDED": 4, + "AGENT_REMOVED": 5, +} + +func (x Event_Type) Enum() *Event_Type { + p := new(Event_Type) + *p = x + return p +} +func (x Event_Type) String() string { + return proto.EnumName(Event_Type_name, int32(x)) +} +func (x *Event_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Event_Type_value, data, "Event_Type") + if err != nil { + return err + } + *x = Event_Type(value) + return nil +} +func (Event_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 0} } + +// * +// Calls that can be sent to the v1 master API. +// +// A call is described using the standard protocol buffer "union" +// trick, see +// https://developers.google.com/protocol-buffers/docs/techniques#union. +type Call struct { + Type *Call_Type `protobuf:"varint,1,opt,name=type,enum=mesos.v1.master.Call_Type" json:"type,omitempty"` + GetMetrics *Call_GetMetrics `protobuf:"bytes,2,opt,name=get_metrics,json=getMetrics" json:"get_metrics,omitempty"` + SetLoggingLevel *Call_SetLoggingLevel `protobuf:"bytes,3,opt,name=set_logging_level,json=setLoggingLevel" json:"set_logging_level,omitempty"` + ListFiles *Call_ListFiles `protobuf:"bytes,4,opt,name=list_files,json=listFiles" json:"list_files,omitempty"` + ReadFile *Call_ReadFile `protobuf:"bytes,5,opt,name=read_file,json=readFile" json:"read_file,omitempty"` + UpdateWeights *Call_UpdateWeights `protobuf:"bytes,6,opt,name=update_weights,json=updateWeights" json:"update_weights,omitempty"` + ReserveResources *Call_ReserveResources `protobuf:"bytes,7,opt,name=reserve_resources,json=reserveResources" json:"reserve_resources,omitempty"` + UnreserveResources *Call_UnreserveResources `protobuf:"bytes,8,opt,name=unreserve_resources,json=unreserveResources" json:"unreserve_resources,omitempty"` + CreateVolumes *Call_CreateVolumes `protobuf:"bytes,9,opt,name=create_volumes,json=createVolumes" json:"create_volumes,omitempty"` + DestroyVolumes *Call_DestroyVolumes `protobuf:"bytes,10,opt,name=destroy_volumes,json=destroyVolumes" json:"destroy_volumes,omitempty"` + UpdateMaintenanceSchedule *Call_UpdateMaintenanceSchedule `protobuf:"bytes,11,opt,name=update_maintenance_schedule,json=updateMaintenanceSchedule" json:"update_maintenance_schedule,omitempty"` + StartMaintenance *Call_StartMaintenance `protobuf:"bytes,12,opt,name=start_maintenance,json=startMaintenance" json:"start_maintenance,omitempty"` + StopMaintenance *Call_StopMaintenance `protobuf:"bytes,13,opt,name=stop_maintenance,json=stopMaintenance" json:"stop_maintenance,omitempty"` + SetQuota *Call_SetQuota `protobuf:"bytes,14,opt,name=set_quota,json=setQuota" json:"set_quota,omitempty"` + RemoveQuota *Call_RemoveQuota `protobuf:"bytes,15,opt,name=remove_quota,json=removeQuota" json:"remove_quota,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call) Reset() { *m = Call{} } +func (m *Call) String() string { return proto.CompactTextString(m) } +func (*Call) ProtoMessage() {} +func (*Call) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *Call) GetType() Call_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return Call_UNKNOWN +} + +func (m *Call) GetGetMetrics() *Call_GetMetrics { + if m != nil { + return m.GetMetrics + } + return nil +} + +func (m *Call) GetSetLoggingLevel() *Call_SetLoggingLevel { + if m != nil { + return m.SetLoggingLevel + } + return nil +} + +func (m *Call) GetListFiles() *Call_ListFiles { + if m != nil { + return m.ListFiles + } + return nil +} + +func (m *Call) GetReadFile() *Call_ReadFile { + if m != nil { + return m.ReadFile + } + return nil +} + +func (m *Call) GetUpdateWeights() *Call_UpdateWeights { + if m != nil { + return m.UpdateWeights + } + return nil +} + +func (m *Call) GetReserveResources() *Call_ReserveResources { + if m != nil { + return m.ReserveResources + } + return nil +} + +func (m *Call) GetUnreserveResources() *Call_UnreserveResources { + if m != nil { + return m.UnreserveResources + } + return nil +} + +func (m *Call) GetCreateVolumes() *Call_CreateVolumes { + if m != nil { + return m.CreateVolumes + } + return nil +} + +func (m *Call) GetDestroyVolumes() *Call_DestroyVolumes { + if m != nil { + return m.DestroyVolumes + } + return nil +} + +func (m *Call) GetUpdateMaintenanceSchedule() *Call_UpdateMaintenanceSchedule { + if m != nil { + return m.UpdateMaintenanceSchedule + } + return nil +} + +func (m *Call) GetStartMaintenance() *Call_StartMaintenance { + if m != nil { + return m.StartMaintenance + } + return nil +} + +func (m *Call) GetStopMaintenance() *Call_StopMaintenance { + if m != nil { + return m.StopMaintenance + } + return nil +} + +func (m *Call) GetSetQuota() *Call_SetQuota { + if m != nil { + return m.SetQuota + } + return nil +} + +func (m *Call) GetRemoveQuota() *Call_RemoveQuota { + if m != nil { + return m.RemoveQuota + } + return nil +} + +// Provides a snapshot of the current metrics tracked by the master. +type Call_GetMetrics struct { + // If set, `timeout` would be used to determines the maximum amount of time + // the API will take to respond. If the timeout is exceeded, some metrics + // may not be included in the response. + Timeout *mesos.DurationInfo `protobuf:"bytes,1,opt,name=timeout" json:"timeout,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_GetMetrics) Reset() { *m = Call_GetMetrics{} } +func (m *Call_GetMetrics) String() string { return proto.CompactTextString(m) } +func (*Call_GetMetrics) ProtoMessage() {} +func (*Call_GetMetrics) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} } + +func (m *Call_GetMetrics) GetTimeout() *mesos.DurationInfo { + if m != nil { + return m.Timeout + } + return nil +} + +// Sets the logging verbosity level for a specified duration. Mesos uses +// [glog](https://github.com/google/glog) for logging. The library only uses +// verbose logging which means nothing will be output unless the verbosity +// level is set (by default it's 0, libprocess uses levels 1, 2, and 3). +type Call_SetLoggingLevel struct { + // The verbosity level. + Level *uint32 `protobuf:"varint,1,req,name=level" json:"level,omitempty"` + // The duration to keep verbosity level toggled. After this duration, the + // verbosity level of log would revert to the original level. + Duration *mesos.DurationInfo `protobuf:"bytes,2,req,name=duration" json:"duration,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_SetLoggingLevel) Reset() { *m = Call_SetLoggingLevel{} } +func (m *Call_SetLoggingLevel) String() string { return proto.CompactTextString(m) } +func (*Call_SetLoggingLevel) ProtoMessage() {} +func (*Call_SetLoggingLevel) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 1} } + +func (m *Call_SetLoggingLevel) GetLevel() uint32 { + if m != nil && m.Level != nil { + return *m.Level + } + return 0 +} + +func (m *Call_SetLoggingLevel) GetDuration() *mesos.DurationInfo { + if m != nil { + return m.Duration + } + return nil +} + +// Provides the file listing for a directory. +type Call_ListFiles struct { + Path *string `protobuf:"bytes,1,req,name=path" json:"path,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_ListFiles) Reset() { *m = Call_ListFiles{} } +func (m *Call_ListFiles) String() string { return proto.CompactTextString(m) } +func (*Call_ListFiles) ProtoMessage() {} +func (*Call_ListFiles) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 2} } + +func (m *Call_ListFiles) GetPath() string { + if m != nil && m.Path != nil { + return *m.Path + } + return "" +} + +// Reads data from a file. +type Call_ReadFile struct { + // The path of file. + Path *string `protobuf:"bytes,1,req,name=path" json:"path,omitempty"` + // Initial offset in file to start reading from. + Offset *uint64 `protobuf:"varint,2,req,name=offset" json:"offset,omitempty"` + // The maximum number of bytes to read. The read length is capped at 16 + // memory pages. + Length *uint64 `protobuf:"varint,3,opt,name=length" json:"length,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_ReadFile) Reset() { *m = Call_ReadFile{} } +func (m *Call_ReadFile) String() string { return proto.CompactTextString(m) } +func (*Call_ReadFile) ProtoMessage() {} +func (*Call_ReadFile) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 3} } + +func (m *Call_ReadFile) GetPath() string { + if m != nil && m.Path != nil { + return *m.Path + } + return "" +} + +func (m *Call_ReadFile) GetOffset() uint64 { + if m != nil && m.Offset != nil { + return *m.Offset + } + return 0 +} + +func (m *Call_ReadFile) GetLength() uint64 { + if m != nil && m.Length != nil { + return *m.Length + } + return 0 +} + +type Call_UpdateWeights struct { + WeightInfos []*mesos.WeightInfo `protobuf:"bytes,1,rep,name=weight_infos,json=weightInfos" json:"weight_infos,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_UpdateWeights) Reset() { *m = Call_UpdateWeights{} } +func (m *Call_UpdateWeights) String() string { return proto.CompactTextString(m) } +func (*Call_UpdateWeights) ProtoMessage() {} +func (*Call_UpdateWeights) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 4} } + +func (m *Call_UpdateWeights) GetWeightInfos() []*mesos.WeightInfo { + if m != nil { + return m.WeightInfos + } + return nil +} + +// Reserve resources dynamically on a specific agent. +type Call_ReserveResources struct { + AgentId *mesos.AgentID `protobuf:"bytes,1,req,name=agent_id,json=agentId" json:"agent_id,omitempty"` + Resources []*mesos.Resource `protobuf:"bytes,2,rep,name=resources" json:"resources,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_ReserveResources) Reset() { *m = Call_ReserveResources{} } +func (m *Call_ReserveResources) String() string { return proto.CompactTextString(m) } +func (*Call_ReserveResources) ProtoMessage() {} +func (*Call_ReserveResources) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 5} } + +func (m *Call_ReserveResources) GetAgentId() *mesos.AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *Call_ReserveResources) GetResources() []*mesos.Resource { + if m != nil { + return m.Resources + } + return nil +} + +// Unreserve resources dynamically on a specific agent. +type Call_UnreserveResources struct { + AgentId *mesos.AgentID `protobuf:"bytes,1,req,name=agent_id,json=agentId" json:"agent_id,omitempty"` + Resources []*mesos.Resource `protobuf:"bytes,2,rep,name=resources" json:"resources,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_UnreserveResources) Reset() { *m = Call_UnreserveResources{} } +func (m *Call_UnreserveResources) String() string { return proto.CompactTextString(m) } +func (*Call_UnreserveResources) ProtoMessage() {} +func (*Call_UnreserveResources) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 6} } + +func (m *Call_UnreserveResources) GetAgentId() *mesos.AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *Call_UnreserveResources) GetResources() []*mesos.Resource { + if m != nil { + return m.Resources + } + return nil +} + +// Create persistent volumes on reserved resources. The request is forwarded +// asynchronously to the Mesos agent where the reserved resources are located. +// That asynchronous message may not be delivered or creating the volumes at +// the agent might fail. Volume creation can be verified by sending a +// `GET_VOLUMES` call. +type Call_CreateVolumes struct { + AgentId *mesos.AgentID `protobuf:"bytes,1,req,name=agent_id,json=agentId" json:"agent_id,omitempty"` + Volumes []*mesos.Resource `protobuf:"bytes,2,rep,name=volumes" json:"volumes,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_CreateVolumes) Reset() { *m = Call_CreateVolumes{} } +func (m *Call_CreateVolumes) String() string { return proto.CompactTextString(m) } +func (*Call_CreateVolumes) ProtoMessage() {} +func (*Call_CreateVolumes) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 7} } + +func (m *Call_CreateVolumes) GetAgentId() *mesos.AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *Call_CreateVolumes) GetVolumes() []*mesos.Resource { + if m != nil { + return m.Volumes + } + return nil +} + +// Destroy persistent volumes. The request is forwarded asynchronously to the +// Mesos agent where the reserved resources are located. That asynchronous +// message may not be delivered or destroying the volumes at the agent might +// fail. Volume deletion can be verified by sending a `GET_VOLUMES` call. +type Call_DestroyVolumes struct { + AgentId *mesos.AgentID `protobuf:"bytes,1,req,name=agent_id,json=agentId" json:"agent_id,omitempty"` + Volumes []*mesos.Resource `protobuf:"bytes,2,rep,name=volumes" json:"volumes,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_DestroyVolumes) Reset() { *m = Call_DestroyVolumes{} } +func (m *Call_DestroyVolumes) String() string { return proto.CompactTextString(m) } +func (*Call_DestroyVolumes) ProtoMessage() {} +func (*Call_DestroyVolumes) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 8} } + +func (m *Call_DestroyVolumes) GetAgentId() *mesos.AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *Call_DestroyVolumes) GetVolumes() []*mesos.Resource { + if m != nil { + return m.Volumes + } + return nil +} + +// Updates the cluster's maintenance schedule. +type Call_UpdateMaintenanceSchedule struct { + Schedule *mesos_maintenance.Schedule `protobuf:"bytes,1,req,name=schedule" json:"schedule,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_UpdateMaintenanceSchedule) Reset() { *m = Call_UpdateMaintenanceSchedule{} } +func (m *Call_UpdateMaintenanceSchedule) String() string { return proto.CompactTextString(m) } +func (*Call_UpdateMaintenanceSchedule) ProtoMessage() {} +func (*Call_UpdateMaintenanceSchedule) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{0, 9} +} + +func (m *Call_UpdateMaintenanceSchedule) GetSchedule() *mesos_maintenance.Schedule { + if m != nil { + return m.Schedule + } + return nil +} + +// Starts the maintenance of the cluster, this would bring a set of machines +// down. +type Call_StartMaintenance struct { + Machines []*mesos.MachineID `protobuf:"bytes,1,rep,name=machines" json:"machines,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_StartMaintenance) Reset() { *m = Call_StartMaintenance{} } +func (m *Call_StartMaintenance) String() string { return proto.CompactTextString(m) } +func (*Call_StartMaintenance) ProtoMessage() {} +func (*Call_StartMaintenance) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 10} } + +func (m *Call_StartMaintenance) GetMachines() []*mesos.MachineID { + if m != nil { + return m.Machines + } + return nil +} + +// Stops the maintenance of the cluster, this would bring a set of machines +// back up. +type Call_StopMaintenance struct { + Machines []*mesos.MachineID `protobuf:"bytes,1,rep,name=machines" json:"machines,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_StopMaintenance) Reset() { *m = Call_StopMaintenance{} } +func (m *Call_StopMaintenance) String() string { return proto.CompactTextString(m) } +func (*Call_StopMaintenance) ProtoMessage() {} +func (*Call_StopMaintenance) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 11} } + +func (m *Call_StopMaintenance) GetMachines() []*mesos.MachineID { + if m != nil { + return m.Machines + } + return nil +} + +// Sets the quota for resources to be used by a particular role. +type Call_SetQuota struct { + QuotaRequest *mesos_quota.QuotaRequest `protobuf:"bytes,1,req,name=quota_request,json=quotaRequest" json:"quota_request,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_SetQuota) Reset() { *m = Call_SetQuota{} } +func (m *Call_SetQuota) String() string { return proto.CompactTextString(m) } +func (*Call_SetQuota) ProtoMessage() {} +func (*Call_SetQuota) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 12} } + +func (m *Call_SetQuota) GetQuotaRequest() *mesos_quota.QuotaRequest { + if m != nil { + return m.QuotaRequest + } + return nil +} + +type Call_RemoveQuota struct { + Role *string `protobuf:"bytes,1,req,name=role" json:"role,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_RemoveQuota) Reset() { *m = Call_RemoveQuota{} } +func (m *Call_RemoveQuota) String() string { return proto.CompactTextString(m) } +func (*Call_RemoveQuota) ProtoMessage() {} +func (*Call_RemoveQuota) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 13} } + +func (m *Call_RemoveQuota) GetRole() string { + if m != nil && m.Role != nil { + return *m.Role + } + return "" +} + +// * +// Synchronous responses for all calls (except Call::SUBSCRIBE) made to +// the v1 master API. +type Response struct { + Type *Response_Type `protobuf:"varint,1,opt,name=type,enum=mesos.v1.master.Response_Type" json:"type,omitempty"` + GetHealth *Response_GetHealth `protobuf:"bytes,2,opt,name=get_health,json=getHealth" json:"get_health,omitempty"` + GetFlags *Response_GetFlags `protobuf:"bytes,3,opt,name=get_flags,json=getFlags" json:"get_flags,omitempty"` + GetVersion *Response_GetVersion `protobuf:"bytes,4,opt,name=get_version,json=getVersion" json:"get_version,omitempty"` + GetMetrics *Response_GetMetrics `protobuf:"bytes,5,opt,name=get_metrics,json=getMetrics" json:"get_metrics,omitempty"` + GetLoggingLevel *Response_GetLoggingLevel `protobuf:"bytes,6,opt,name=get_logging_level,json=getLoggingLevel" json:"get_logging_level,omitempty"` + ListFiles *Response_ListFiles `protobuf:"bytes,7,opt,name=list_files,json=listFiles" json:"list_files,omitempty"` + ReadFile *Response_ReadFile `protobuf:"bytes,8,opt,name=read_file,json=readFile" json:"read_file,omitempty"` + GetState *Response_GetState `protobuf:"bytes,9,opt,name=get_state,json=getState" json:"get_state,omitempty"` + GetAgents *Response_GetAgents `protobuf:"bytes,10,opt,name=get_agents,json=getAgents" json:"get_agents,omitempty"` + GetFrameworks *Response_GetFrameworks `protobuf:"bytes,11,opt,name=get_frameworks,json=getFrameworks" json:"get_frameworks,omitempty"` + GetExecutors *Response_GetExecutors `protobuf:"bytes,12,opt,name=get_executors,json=getExecutors" json:"get_executors,omitempty"` + GetTasks *Response_GetTasks `protobuf:"bytes,13,opt,name=get_tasks,json=getTasks" json:"get_tasks,omitempty"` + GetRoles *Response_GetRoles `protobuf:"bytes,14,opt,name=get_roles,json=getRoles" json:"get_roles,omitempty"` + GetWeights *Response_GetWeights `protobuf:"bytes,15,opt,name=get_weights,json=getWeights" json:"get_weights,omitempty"` + GetMaster *Response_GetMaster `protobuf:"bytes,16,opt,name=get_master,json=getMaster" json:"get_master,omitempty"` + GetMaintenanceStatus *Response_GetMaintenanceStatus `protobuf:"bytes,17,opt,name=get_maintenance_status,json=getMaintenanceStatus" json:"get_maintenance_status,omitempty"` + GetMaintenanceSchedule *Response_GetMaintenanceSchedule `protobuf:"bytes,18,opt,name=get_maintenance_schedule,json=getMaintenanceSchedule" json:"get_maintenance_schedule,omitempty"` + GetQuota *Response_GetQuota `protobuf:"bytes,19,opt,name=get_quota,json=getQuota" json:"get_quota,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response) Reset() { *m = Response{} } +func (m *Response) String() string { return proto.CompactTextString(m) } +func (*Response) ProtoMessage() {} +func (*Response) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *Response) GetType() Response_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return Response_UNKNOWN +} + +func (m *Response) GetGetHealth() *Response_GetHealth { + if m != nil { + return m.GetHealth + } + return nil +} + +func (m *Response) GetGetFlags() *Response_GetFlags { + if m != nil { + return m.GetFlags + } + return nil +} + +func (m *Response) GetGetVersion() *Response_GetVersion { + if m != nil { + return m.GetVersion + } + return nil +} + +func (m *Response) GetGetMetrics() *Response_GetMetrics { + if m != nil { + return m.GetMetrics + } + return nil +} + +func (m *Response) GetGetLoggingLevel() *Response_GetLoggingLevel { + if m != nil { + return m.GetLoggingLevel + } + return nil +} + +func (m *Response) GetListFiles() *Response_ListFiles { + if m != nil { + return m.ListFiles + } + return nil +} + +func (m *Response) GetReadFile() *Response_ReadFile { + if m != nil { + return m.ReadFile + } + return nil +} + +func (m *Response) GetGetState() *Response_GetState { + if m != nil { + return m.GetState + } + return nil +} + +func (m *Response) GetGetAgents() *Response_GetAgents { + if m != nil { + return m.GetAgents + } + return nil +} + +func (m *Response) GetGetFrameworks() *Response_GetFrameworks { + if m != nil { + return m.GetFrameworks + } + return nil +} + +func (m *Response) GetGetExecutors() *Response_GetExecutors { + if m != nil { + return m.GetExecutors + } + return nil +} + +func (m *Response) GetGetTasks() *Response_GetTasks { + if m != nil { + return m.GetTasks + } + return nil +} + +func (m *Response) GetGetRoles() *Response_GetRoles { + if m != nil { + return m.GetRoles + } + return nil +} + +func (m *Response) GetGetWeights() *Response_GetWeights { + if m != nil { + return m.GetWeights + } + return nil +} + +func (m *Response) GetGetMaster() *Response_GetMaster { + if m != nil { + return m.GetMaster + } + return nil +} + +func (m *Response) GetGetMaintenanceStatus() *Response_GetMaintenanceStatus { + if m != nil { + return m.GetMaintenanceStatus + } + return nil +} + +func (m *Response) GetGetMaintenanceSchedule() *Response_GetMaintenanceSchedule { + if m != nil { + return m.GetMaintenanceSchedule + } + return nil +} + +func (m *Response) GetGetQuota() *Response_GetQuota { + if m != nil { + return m.GetQuota + } + return nil +} + +// `healthy` would be true if the master is healthy. Delayed responses are +// also indicative of the poor health of the master. +type Response_GetHealth struct { + Healthy *bool `protobuf:"varint,1,req,name=healthy" json:"healthy,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetHealth) Reset() { *m = Response_GetHealth{} } +func (m *Response_GetHealth) String() string { return proto.CompactTextString(m) } +func (*Response_GetHealth) ProtoMessage() {} +func (*Response_GetHealth) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 0} } + +func (m *Response_GetHealth) GetHealthy() bool { + if m != nil && m.Healthy != nil { + return *m.Healthy + } + return false +} + +// Contains the flag configuration of the master. +type Response_GetFlags struct { + Flags []*mesos.Flag `protobuf:"bytes,1,rep,name=flags" json:"flags,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetFlags) Reset() { *m = Response_GetFlags{} } +func (m *Response_GetFlags) String() string { return proto.CompactTextString(m) } +func (*Response_GetFlags) ProtoMessage() {} +func (*Response_GetFlags) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 1} } + +func (m *Response_GetFlags) GetFlags() []*mesos.Flag { + if m != nil { + return m.Flags + } + return nil +} + +// Contains the version information of the master. +type Response_GetVersion struct { + VersionInfo *mesos.VersionInfo `protobuf:"bytes,1,req,name=version_info,json=versionInfo" json:"version_info,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetVersion) Reset() { *m = Response_GetVersion{} } +func (m *Response_GetVersion) String() string { return proto.CompactTextString(m) } +func (*Response_GetVersion) ProtoMessage() {} +func (*Response_GetVersion) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 2} } + +func (m *Response_GetVersion) GetVersionInfo() *mesos.VersionInfo { + if m != nil { + return m.VersionInfo + } + return nil +} + +// Contains a snapshot of the current metrics. +type Response_GetMetrics struct { + Metrics []*mesos.Metric `protobuf:"bytes,1,rep,name=metrics" json:"metrics,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetMetrics) Reset() { *m = Response_GetMetrics{} } +func (m *Response_GetMetrics) String() string { return proto.CompactTextString(m) } +func (*Response_GetMetrics) ProtoMessage() {} +func (*Response_GetMetrics) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 3} } + +func (m *Response_GetMetrics) GetMetrics() []*mesos.Metric { + if m != nil { + return m.Metrics + } + return nil +} + +// Contains the logging level of the master. +type Response_GetLoggingLevel struct { + Level *uint32 `protobuf:"varint,1,req,name=level" json:"level,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetLoggingLevel) Reset() { *m = Response_GetLoggingLevel{} } +func (m *Response_GetLoggingLevel) String() string { return proto.CompactTextString(m) } +func (*Response_GetLoggingLevel) ProtoMessage() {} +func (*Response_GetLoggingLevel) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 4} } + +func (m *Response_GetLoggingLevel) GetLevel() uint32 { + if m != nil && m.Level != nil { + return *m.Level + } + return 0 +} + +// Contains the file listing(similar to `ls -l`) for a directory. +type Response_ListFiles struct { + FileInfos []*mesos.FileInfo `protobuf:"bytes,1,rep,name=file_infos,json=fileInfos" json:"file_infos,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_ListFiles) Reset() { *m = Response_ListFiles{} } +func (m *Response_ListFiles) String() string { return proto.CompactTextString(m) } +func (*Response_ListFiles) ProtoMessage() {} +func (*Response_ListFiles) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 5} } + +func (m *Response_ListFiles) GetFileInfos() []*mesos.FileInfo { + if m != nil { + return m.FileInfos + } + return nil +} + +// Contains the file data. +type Response_ReadFile struct { + // The size of file (in bytes). + Size *uint64 `protobuf:"varint,1,req,name=size" json:"size,omitempty"` + Data []byte `protobuf:"bytes,2,req,name=data" json:"data,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_ReadFile) Reset() { *m = Response_ReadFile{} } +func (m *Response_ReadFile) String() string { return proto.CompactTextString(m) } +func (*Response_ReadFile) ProtoMessage() {} +func (*Response_ReadFile) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 6} } + +func (m *Response_ReadFile) GetSize() uint64 { + if m != nil && m.Size != nil { + return *m.Size + } + return 0 +} + +func (m *Response_ReadFile) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +// Contains full state of the master i.e. information about the tasks, +// agents, frameworks and executors running in the cluster. +type Response_GetState struct { + GetTasks *Response_GetTasks `protobuf:"bytes,1,opt,name=get_tasks,json=getTasks" json:"get_tasks,omitempty"` + GetExecutors *Response_GetExecutors `protobuf:"bytes,2,opt,name=get_executors,json=getExecutors" json:"get_executors,omitempty"` + GetFrameworks *Response_GetFrameworks `protobuf:"bytes,3,opt,name=get_frameworks,json=getFrameworks" json:"get_frameworks,omitempty"` + GetAgents *Response_GetAgents `protobuf:"bytes,4,opt,name=get_agents,json=getAgents" json:"get_agents,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetState) Reset() { *m = Response_GetState{} } +func (m *Response_GetState) String() string { return proto.CompactTextString(m) } +func (*Response_GetState) ProtoMessage() {} +func (*Response_GetState) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 7} } + +func (m *Response_GetState) GetGetTasks() *Response_GetTasks { + if m != nil { + return m.GetTasks + } + return nil +} + +func (m *Response_GetState) GetGetExecutors() *Response_GetExecutors { + if m != nil { + return m.GetExecutors + } + return nil +} + +func (m *Response_GetState) GetGetFrameworks() *Response_GetFrameworks { + if m != nil { + return m.GetFrameworks + } + return nil +} + +func (m *Response_GetState) GetGetAgents() *Response_GetAgents { + if m != nil { + return m.GetAgents + } + return nil +} + +type Response_GetAgents struct { + // Registered agents. + Agents []*Response_GetAgents_Agent `protobuf:"bytes,1,rep,name=agents" json:"agents,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetAgents) Reset() { *m = Response_GetAgents{} } +func (m *Response_GetAgents) String() string { return proto.CompactTextString(m) } +func (*Response_GetAgents) ProtoMessage() {} +func (*Response_GetAgents) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 8} } + +func (m *Response_GetAgents) GetAgents() []*Response_GetAgents_Agent { + if m != nil { + return m.Agents + } + return nil +} + +type Response_GetAgents_Agent struct { + AgentInfo *mesos.AgentInfo `protobuf:"bytes,1,req,name=agent_info,json=agentInfo" json:"agent_info,omitempty"` + Active *bool `protobuf:"varint,2,req,name=active" json:"active,omitempty"` + Version *string `protobuf:"bytes,3,req,name=version" json:"version,omitempty"` + Pid *string `protobuf:"bytes,4,opt,name=pid" json:"pid,omitempty"` + RegisteredTime *mesos.TimeInfo `protobuf:"bytes,5,opt,name=registered_time,json=registeredTime" json:"registered_time,omitempty"` + ReregisteredTime *mesos.TimeInfo `protobuf:"bytes,6,opt,name=reregistered_time,json=reregisteredTime" json:"reregistered_time,omitempty"` + // Total resources (including oversubscribed resources) the agent + // provides. + TotalResources []*mesos.Resource `protobuf:"bytes,7,rep,name=total_resources,json=totalResources" json:"total_resources,omitempty"` + AllocatedResources []*mesos.Resource `protobuf:"bytes,8,rep,name=allocated_resources,json=allocatedResources" json:"allocated_resources,omitempty"` + OfferedResources []*mesos.Resource `protobuf:"bytes,9,rep,name=offered_resources,json=offeredResources" json:"offered_resources,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetAgents_Agent) Reset() { *m = Response_GetAgents_Agent{} } +func (m *Response_GetAgents_Agent) String() string { return proto.CompactTextString(m) } +func (*Response_GetAgents_Agent) ProtoMessage() {} +func (*Response_GetAgents_Agent) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 8, 0} } + +func (m *Response_GetAgents_Agent) GetAgentInfo() *mesos.AgentInfo { + if m != nil { + return m.AgentInfo + } + return nil +} + +func (m *Response_GetAgents_Agent) GetActive() bool { + if m != nil && m.Active != nil { + return *m.Active + } + return false +} + +func (m *Response_GetAgents_Agent) GetVersion() string { + if m != nil && m.Version != nil { + return *m.Version + } + return "" +} + +func (m *Response_GetAgents_Agent) GetPid() string { + if m != nil && m.Pid != nil { + return *m.Pid + } + return "" +} + +func (m *Response_GetAgents_Agent) GetRegisteredTime() *mesos.TimeInfo { + if m != nil { + return m.RegisteredTime + } + return nil +} + +func (m *Response_GetAgents_Agent) GetReregisteredTime() *mesos.TimeInfo { + if m != nil { + return m.ReregisteredTime + } + return nil +} + +func (m *Response_GetAgents_Agent) GetTotalResources() []*mesos.Resource { + if m != nil { + return m.TotalResources + } + return nil +} + +func (m *Response_GetAgents_Agent) GetAllocatedResources() []*mesos.Resource { + if m != nil { + return m.AllocatedResources + } + return nil +} + +func (m *Response_GetAgents_Agent) GetOfferedResources() []*mesos.Resource { + if m != nil { + return m.OfferedResources + } + return nil +} + +// Information about all the frameworks known to the master at the current +// time. Note that there might be frameworks unknown to the master running +// on partitioned or unsubscribed agents. +type Response_GetFrameworks struct { + // Frameworks that have subscribed with the master. Note that this includes + // frameworks that are disconnected and in the process of re-subscribing. + Frameworks []*Response_GetFrameworks_Framework `protobuf:"bytes,1,rep,name=frameworks" json:"frameworks,omitempty"` + // Frameworks that have been teared down. + CompletedFrameworks []*Response_GetFrameworks_Framework `protobuf:"bytes,2,rep,name=completed_frameworks,json=completedFrameworks" json:"completed_frameworks,omitempty"` + // Frameworks that have previously subscribed but haven't yet subscribed + // after a master failover. + RecoveredFrameworks []*mesos.FrameworkInfo `protobuf:"bytes,3,rep,name=recovered_frameworks,json=recoveredFrameworks" json:"recovered_frameworks,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetFrameworks) Reset() { *m = Response_GetFrameworks{} } +func (m *Response_GetFrameworks) String() string { return proto.CompactTextString(m) } +func (*Response_GetFrameworks) ProtoMessage() {} +func (*Response_GetFrameworks) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 9} } + +func (m *Response_GetFrameworks) GetFrameworks() []*Response_GetFrameworks_Framework { + if m != nil { + return m.Frameworks + } + return nil +} + +func (m *Response_GetFrameworks) GetCompletedFrameworks() []*Response_GetFrameworks_Framework { + if m != nil { + return m.CompletedFrameworks + } + return nil +} + +func (m *Response_GetFrameworks) GetRecoveredFrameworks() []*mesos.FrameworkInfo { + if m != nil { + return m.RecoveredFrameworks + } + return nil +} + +type Response_GetFrameworks_Framework struct { + FrameworkInfo *mesos.FrameworkInfo `protobuf:"bytes,1,req,name=framework_info,json=frameworkInfo" json:"framework_info,omitempty"` + Active *bool `protobuf:"varint,2,req,name=active" json:"active,omitempty"` + Connected *bool `protobuf:"varint,3,req,name=connected" json:"connected,omitempty"` + RegisteredTime *mesos.TimeInfo `protobuf:"bytes,4,opt,name=registered_time,json=registeredTime" json:"registered_time,omitempty"` + ReregisteredTime *mesos.TimeInfo `protobuf:"bytes,5,opt,name=reregistered_time,json=reregisteredTime" json:"reregistered_time,omitempty"` + UnregisteredTime *mesos.TimeInfo `protobuf:"bytes,6,opt,name=unregistered_time,json=unregisteredTime" json:"unregistered_time,omitempty"` + Offers []*mesos.Offer `protobuf:"bytes,7,rep,name=offers" json:"offers,omitempty"` + InverseOffers []*mesos.InverseOffer `protobuf:"bytes,8,rep,name=inverse_offers,json=inverseOffers" json:"inverse_offers,omitempty"` + AllocatedResources []*mesos.Resource `protobuf:"bytes,9,rep,name=allocated_resources,json=allocatedResources" json:"allocated_resources,omitempty"` + OfferedResources []*mesos.Resource `protobuf:"bytes,10,rep,name=offered_resources,json=offeredResources" json:"offered_resources,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetFrameworks_Framework) Reset() { *m = Response_GetFrameworks_Framework{} } +func (m *Response_GetFrameworks_Framework) String() string { return proto.CompactTextString(m) } +func (*Response_GetFrameworks_Framework) ProtoMessage() {} +func (*Response_GetFrameworks_Framework) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{1, 9, 0} +} + +func (m *Response_GetFrameworks_Framework) GetFrameworkInfo() *mesos.FrameworkInfo { + if m != nil { + return m.FrameworkInfo + } + return nil +} + +func (m *Response_GetFrameworks_Framework) GetActive() bool { + if m != nil && m.Active != nil { + return *m.Active + } + return false +} + +func (m *Response_GetFrameworks_Framework) GetConnected() bool { + if m != nil && m.Connected != nil { + return *m.Connected + } + return false +} + +func (m *Response_GetFrameworks_Framework) GetRegisteredTime() *mesos.TimeInfo { + if m != nil { + return m.RegisteredTime + } + return nil +} + +func (m *Response_GetFrameworks_Framework) GetReregisteredTime() *mesos.TimeInfo { + if m != nil { + return m.ReregisteredTime + } + return nil +} + +func (m *Response_GetFrameworks_Framework) GetUnregisteredTime() *mesos.TimeInfo { + if m != nil { + return m.UnregisteredTime + } + return nil +} + +func (m *Response_GetFrameworks_Framework) GetOffers() []*mesos.Offer { + if m != nil { + return m.Offers + } + return nil +} + +func (m *Response_GetFrameworks_Framework) GetInverseOffers() []*mesos.InverseOffer { + if m != nil { + return m.InverseOffers + } + return nil +} + +func (m *Response_GetFrameworks_Framework) GetAllocatedResources() []*mesos.Resource { + if m != nil { + return m.AllocatedResources + } + return nil +} + +func (m *Response_GetFrameworks_Framework) GetOfferedResources() []*mesos.Resource { + if m != nil { + return m.OfferedResources + } + return nil +} + +// Lists information about all the executors known to the master at the +// current time. Note that there might be executors unknown to the master +// running on partitioned or unsubscribed agents. +type Response_GetExecutors struct { + Executors []*Response_GetExecutors_Executor `protobuf:"bytes,1,rep,name=executors" json:"executors,omitempty"` + OrphanExecutors []*Response_GetExecutors_Executor `protobuf:"bytes,2,rep,name=orphan_executors,json=orphanExecutors" json:"orphan_executors,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetExecutors) Reset() { *m = Response_GetExecutors{} } +func (m *Response_GetExecutors) String() string { return proto.CompactTextString(m) } +func (*Response_GetExecutors) ProtoMessage() {} +func (*Response_GetExecutors) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 10} } + +func (m *Response_GetExecutors) GetExecutors() []*Response_GetExecutors_Executor { + if m != nil { + return m.Executors + } + return nil +} + +func (m *Response_GetExecutors) GetOrphanExecutors() []*Response_GetExecutors_Executor { + if m != nil { + return m.OrphanExecutors + } + return nil +} + +type Response_GetExecutors_Executor struct { + ExecutorInfo *mesos.ExecutorInfo `protobuf:"bytes,1,req,name=executor_info,json=executorInfo" json:"executor_info,omitempty"` + AgentId *mesos.AgentID `protobuf:"bytes,2,req,name=agent_id,json=agentId" json:"agent_id,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetExecutors_Executor) Reset() { *m = Response_GetExecutors_Executor{} } +func (m *Response_GetExecutors_Executor) String() string { return proto.CompactTextString(m) } +func (*Response_GetExecutors_Executor) ProtoMessage() {} +func (*Response_GetExecutors_Executor) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{1, 10, 0} +} + +func (m *Response_GetExecutors_Executor) GetExecutorInfo() *mesos.ExecutorInfo { + if m != nil { + return m.ExecutorInfo + } + return nil +} + +func (m *Response_GetExecutors_Executor) GetAgentId() *mesos.AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +// Lists information about all the tasks known to the master at the current +// time. Note that there might be tasks unknown to the master running on +// partitioned or unsubscribed agents. +type Response_GetTasks struct { + // Tasks that are an enqueued on the master waiting (e.g., authorizing) + // to be launched. + PendingTasks []*mesos.Task `protobuf:"bytes,1,rep,name=pending_tasks,json=pendingTasks" json:"pending_tasks,omitempty"` + // Tasks that have been forwarded to the agent for launch. This includes + // tasks that are running and reached terminal state. + Tasks []*mesos.Task `protobuf:"bytes,2,rep,name=tasks" json:"tasks,omitempty"` + // Tasks that have reached terminal state and have all their updates + // acknowledged by the scheduler. + CompletedTasks []*mesos.Task `protobuf:"bytes,3,rep,name=completed_tasks,json=completedTasks" json:"completed_tasks,omitempty"` + // Tasks belonging to frameworks that have not yet re-subscribed with + // master (e.g., immediately after master failover). + OrphanTasks []*mesos.Task `protobuf:"bytes,4,rep,name=orphan_tasks,json=orphanTasks" json:"orphan_tasks,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetTasks) Reset() { *m = Response_GetTasks{} } +func (m *Response_GetTasks) String() string { return proto.CompactTextString(m) } +func (*Response_GetTasks) ProtoMessage() {} +func (*Response_GetTasks) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 11} } + +func (m *Response_GetTasks) GetPendingTasks() []*mesos.Task { + if m != nil { + return m.PendingTasks + } + return nil +} + +func (m *Response_GetTasks) GetTasks() []*mesos.Task { + if m != nil { + return m.Tasks + } + return nil +} + +func (m *Response_GetTasks) GetCompletedTasks() []*mesos.Task { + if m != nil { + return m.CompletedTasks + } + return nil +} + +func (m *Response_GetTasks) GetOrphanTasks() []*mesos.Task { + if m != nil { + return m.OrphanTasks + } + return nil +} + +// Provides information about every role that is on the role whitelist (if +// enabled), has one or more registered frameworks or has a non-default weight +// or quota. +type Response_GetRoles struct { + Roles []*mesos.Role `protobuf:"bytes,1,rep,name=roles" json:"roles,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetRoles) Reset() { *m = Response_GetRoles{} } +func (m *Response_GetRoles) String() string { return proto.CompactTextString(m) } +func (*Response_GetRoles) ProtoMessage() {} +func (*Response_GetRoles) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 12} } + +func (m *Response_GetRoles) GetRoles() []*mesos.Role { + if m != nil { + return m.Roles + } + return nil +} + +// Provides the weight information about every role. +type Response_GetWeights struct { + WeightInfos []*mesos.WeightInfo `protobuf:"bytes,1,rep,name=weight_infos,json=weightInfos" json:"weight_infos,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetWeights) Reset() { *m = Response_GetWeights{} } +func (m *Response_GetWeights) String() string { return proto.CompactTextString(m) } +func (*Response_GetWeights) ProtoMessage() {} +func (*Response_GetWeights) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 13} } + +func (m *Response_GetWeights) GetWeightInfos() []*mesos.WeightInfo { + if m != nil { + return m.WeightInfos + } + return nil +} + +// Contains the master's information. +type Response_GetMaster struct { + MasterInfo *mesos.MasterInfo `protobuf:"bytes,1,opt,name=master_info,json=masterInfo" json:"master_info,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetMaster) Reset() { *m = Response_GetMaster{} } +func (m *Response_GetMaster) String() string { return proto.CompactTextString(m) } +func (*Response_GetMaster) ProtoMessage() {} +func (*Response_GetMaster) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 14} } + +func (m *Response_GetMaster) GetMasterInfo() *mesos.MasterInfo { + if m != nil { + return m.MasterInfo + } + return nil +} + +// Contains the cluster's maintenance status. +type Response_GetMaintenanceStatus struct { + Status *mesos_maintenance.ClusterStatus `protobuf:"bytes,1,req,name=status" json:"status,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetMaintenanceStatus) Reset() { *m = Response_GetMaintenanceStatus{} } +func (m *Response_GetMaintenanceStatus) String() string { return proto.CompactTextString(m) } +func (*Response_GetMaintenanceStatus) ProtoMessage() {} +func (*Response_GetMaintenanceStatus) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{1, 15} +} + +func (m *Response_GetMaintenanceStatus) GetStatus() *mesos_maintenance.ClusterStatus { + if m != nil { + return m.Status + } + return nil +} + +// Contains the cluster's maintenance schedule. +type Response_GetMaintenanceSchedule struct { + Schedule *mesos_maintenance.Schedule `protobuf:"bytes,1,req,name=schedule" json:"schedule,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetMaintenanceSchedule) Reset() { *m = Response_GetMaintenanceSchedule{} } +func (m *Response_GetMaintenanceSchedule) String() string { return proto.CompactTextString(m) } +func (*Response_GetMaintenanceSchedule) ProtoMessage() {} +func (*Response_GetMaintenanceSchedule) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{1, 16} +} + +func (m *Response_GetMaintenanceSchedule) GetSchedule() *mesos_maintenance.Schedule { + if m != nil { + return m.Schedule + } + return nil +} + +// Contains the cluster's configured quotas. +type Response_GetQuota struct { + Status *mesos_quota.QuotaStatus `protobuf:"bytes,1,req,name=status" json:"status,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Response_GetQuota) Reset() { *m = Response_GetQuota{} } +func (m *Response_GetQuota) String() string { return proto.CompactTextString(m) } +func (*Response_GetQuota) ProtoMessage() {} +func (*Response_GetQuota) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 17} } + +func (m *Response_GetQuota) GetStatus() *mesos_quota.QuotaStatus { + if m != nil { + return m.Status + } + return nil +} + +// * +// Streaming response to `Call::SUBSCRIBE` made to the master. +type Event struct { + Type *Event_Type `protobuf:"varint,1,opt,name=type,enum=mesos.v1.master.Event_Type" json:"type,omitempty"` + Subscribed *Event_Subscribed `protobuf:"bytes,2,opt,name=subscribed" json:"subscribed,omitempty"` + TaskAdded *Event_TaskAdded `protobuf:"bytes,3,opt,name=task_added,json=taskAdded" json:"task_added,omitempty"` + TaskUpdated *Event_TaskUpdated `protobuf:"bytes,4,opt,name=task_updated,json=taskUpdated" json:"task_updated,omitempty"` + AgentAdded *Event_AgentAdded `protobuf:"bytes,5,opt,name=agent_added,json=agentAdded" json:"agent_added,omitempty"` + AgentRemoved *Event_AgentRemoved `protobuf:"bytes,6,opt,name=agent_removed,json=agentRemoved" json:"agent_removed,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event) Reset() { *m = Event{} } +func (m *Event) String() string { return proto.CompactTextString(m) } +func (*Event) ProtoMessage() {} +func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *Event) GetType() Event_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return Event_UNKNOWN +} + +func (m *Event) GetSubscribed() *Event_Subscribed { + if m != nil { + return m.Subscribed + } + return nil +} + +func (m *Event) GetTaskAdded() *Event_TaskAdded { + if m != nil { + return m.TaskAdded + } + return nil +} + +func (m *Event) GetTaskUpdated() *Event_TaskUpdated { + if m != nil { + return m.TaskUpdated + } + return nil +} + +func (m *Event) GetAgentAdded() *Event_AgentAdded { + if m != nil { + return m.AgentAdded + } + return nil +} + +func (m *Event) GetAgentRemoved() *Event_AgentRemoved { + if m != nil { + return m.AgentRemoved + } + return nil +} + +// First event received when a client subscribes. +type Event_Subscribed struct { + // Snapshot of the entire cluster state. Further updates to the + // cluster state are sent as separate events on the stream. + GetState *Response_GetState `protobuf:"bytes,1,opt,name=get_state,json=getState" json:"get_state,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event_Subscribed) Reset() { *m = Event_Subscribed{} } +func (m *Event_Subscribed) String() string { return proto.CompactTextString(m) } +func (*Event_Subscribed) ProtoMessage() {} +func (*Event_Subscribed) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 0} } + +func (m *Event_Subscribed) GetGetState() *Response_GetState { + if m != nil { + return m.GetState + } + return nil +} + +// Forwarded by the master when a task becomes known to it. This can happen +// when a new task is launched by the scheduler or when the task becomes +// known to the master upon an agent (re-)registration after a failover. +type Event_TaskAdded struct { + Task *mesos.Task `protobuf:"bytes,1,req,name=task" json:"task,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event_TaskAdded) Reset() { *m = Event_TaskAdded{} } +func (m *Event_TaskAdded) String() string { return proto.CompactTextString(m) } +func (*Event_TaskAdded) ProtoMessage() {} +func (*Event_TaskAdded) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 1} } + +func (m *Event_TaskAdded) GetTask() *mesos.Task { + if m != nil { + return m.Task + } + return nil +} + +// Forwarded by the master when an existing task transitions to a new state. +type Event_TaskUpdated struct { + FrameworkId *mesos.FrameworkID `protobuf:"bytes,1,req,name=framework_id,json=frameworkId" json:"framework_id,omitempty"` + // This is the status of the task corresponding to the last + // status update acknowledged by the scheduler. + Status *mesos.TaskStatus `protobuf:"bytes,2,req,name=status" json:"status,omitempty"` + // This is the latest state of the task according to the agent. + State *mesos.TaskState `protobuf:"varint,3,req,name=state,enum=mesos.v1.TaskState" json:"state,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event_TaskUpdated) Reset() { *m = Event_TaskUpdated{} } +func (m *Event_TaskUpdated) String() string { return proto.CompactTextString(m) } +func (*Event_TaskUpdated) ProtoMessage() {} +func (*Event_TaskUpdated) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 2} } + +func (m *Event_TaskUpdated) GetFrameworkId() *mesos.FrameworkID { + if m != nil { + return m.FrameworkId + } + return nil +} + +func (m *Event_TaskUpdated) GetStatus() *mesos.TaskStatus { + if m != nil { + return m.Status + } + return nil +} + +func (m *Event_TaskUpdated) GetState() mesos.TaskState { + if m != nil && m.State != nil { + return *m.State + } + return mesos.TaskState_TASK_STAGING +} + +// Forwarded by the master when an agent becomes known to it. +// This can happen when an agent registered for the first +// time, or reregistered after a master failover. +type Event_AgentAdded struct { + Agent *Response_GetAgents_Agent `protobuf:"bytes,1,req,name=agent" json:"agent,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event_AgentAdded) Reset() { *m = Event_AgentAdded{} } +func (m *Event_AgentAdded) String() string { return proto.CompactTextString(m) } +func (*Event_AgentAdded) ProtoMessage() {} +func (*Event_AgentAdded) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 3} } + +func (m *Event_AgentAdded) GetAgent() *Response_GetAgents_Agent { + if m != nil { + return m.Agent + } + return nil +} + +// Forwarded by the master when an agent is removed. +// This can happen when an agent does not re-register +// within `--agent_reregister_timeout` upon a master failover, +// or when the agent is scheduled for maintenance. +// +// NOTE: It's possible that an agent might become +// active once it has been removed, i.e. if the master +// has gc'ed its list of known "dead" agents. +// See MESOS-5965 for context. +type Event_AgentRemoved struct { + AgentId *mesos.AgentID `protobuf:"bytes,1,req,name=agent_id,json=agentId" json:"agent_id,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event_AgentRemoved) Reset() { *m = Event_AgentRemoved{} } +func (m *Event_AgentRemoved) String() string { return proto.CompactTextString(m) } +func (*Event_AgentRemoved) ProtoMessage() {} +func (*Event_AgentRemoved) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 4} } + +func (m *Event_AgentRemoved) GetAgentId() *mesos.AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func init() { + proto.RegisterType((*Call)(nil), "mesos.v1.master.Call") + proto.RegisterType((*Call_GetMetrics)(nil), "mesos.v1.master.Call.GetMetrics") + proto.RegisterType((*Call_SetLoggingLevel)(nil), "mesos.v1.master.Call.SetLoggingLevel") + proto.RegisterType((*Call_ListFiles)(nil), "mesos.v1.master.Call.ListFiles") + proto.RegisterType((*Call_ReadFile)(nil), "mesos.v1.master.Call.ReadFile") + proto.RegisterType((*Call_UpdateWeights)(nil), "mesos.v1.master.Call.UpdateWeights") + proto.RegisterType((*Call_ReserveResources)(nil), "mesos.v1.master.Call.ReserveResources") + proto.RegisterType((*Call_UnreserveResources)(nil), "mesos.v1.master.Call.UnreserveResources") + proto.RegisterType((*Call_CreateVolumes)(nil), "mesos.v1.master.Call.CreateVolumes") + proto.RegisterType((*Call_DestroyVolumes)(nil), "mesos.v1.master.Call.DestroyVolumes") + proto.RegisterType((*Call_UpdateMaintenanceSchedule)(nil), "mesos.v1.master.Call.UpdateMaintenanceSchedule") + proto.RegisterType((*Call_StartMaintenance)(nil), "mesos.v1.master.Call.StartMaintenance") + proto.RegisterType((*Call_StopMaintenance)(nil), "mesos.v1.master.Call.StopMaintenance") + proto.RegisterType((*Call_SetQuota)(nil), "mesos.v1.master.Call.SetQuota") + proto.RegisterType((*Call_RemoveQuota)(nil), "mesos.v1.master.Call.RemoveQuota") + proto.RegisterType((*Response)(nil), "mesos.v1.master.Response") + proto.RegisterType((*Response_GetHealth)(nil), "mesos.v1.master.Response.GetHealth") + proto.RegisterType((*Response_GetFlags)(nil), "mesos.v1.master.Response.GetFlags") + proto.RegisterType((*Response_GetVersion)(nil), "mesos.v1.master.Response.GetVersion") + proto.RegisterType((*Response_GetMetrics)(nil), "mesos.v1.master.Response.GetMetrics") + proto.RegisterType((*Response_GetLoggingLevel)(nil), "mesos.v1.master.Response.GetLoggingLevel") + proto.RegisterType((*Response_ListFiles)(nil), "mesos.v1.master.Response.ListFiles") + proto.RegisterType((*Response_ReadFile)(nil), "mesos.v1.master.Response.ReadFile") + proto.RegisterType((*Response_GetState)(nil), "mesos.v1.master.Response.GetState") + proto.RegisterType((*Response_GetAgents)(nil), "mesos.v1.master.Response.GetAgents") + proto.RegisterType((*Response_GetAgents_Agent)(nil), "mesos.v1.master.Response.GetAgents.Agent") + proto.RegisterType((*Response_GetFrameworks)(nil), "mesos.v1.master.Response.GetFrameworks") + proto.RegisterType((*Response_GetFrameworks_Framework)(nil), "mesos.v1.master.Response.GetFrameworks.Framework") + proto.RegisterType((*Response_GetExecutors)(nil), "mesos.v1.master.Response.GetExecutors") + proto.RegisterType((*Response_GetExecutors_Executor)(nil), "mesos.v1.master.Response.GetExecutors.Executor") + proto.RegisterType((*Response_GetTasks)(nil), "mesos.v1.master.Response.GetTasks") + proto.RegisterType((*Response_GetRoles)(nil), "mesos.v1.master.Response.GetRoles") + proto.RegisterType((*Response_GetWeights)(nil), "mesos.v1.master.Response.GetWeights") + proto.RegisterType((*Response_GetMaster)(nil), "mesos.v1.master.Response.GetMaster") + proto.RegisterType((*Response_GetMaintenanceStatus)(nil), "mesos.v1.master.Response.GetMaintenanceStatus") + proto.RegisterType((*Response_GetMaintenanceSchedule)(nil), "mesos.v1.master.Response.GetMaintenanceSchedule") + proto.RegisterType((*Response_GetQuota)(nil), "mesos.v1.master.Response.GetQuota") + proto.RegisterType((*Event)(nil), "mesos.v1.master.Event") + proto.RegisterType((*Event_Subscribed)(nil), "mesos.v1.master.Event.Subscribed") + proto.RegisterType((*Event_TaskAdded)(nil), "mesos.v1.master.Event.TaskAdded") + proto.RegisterType((*Event_TaskUpdated)(nil), "mesos.v1.master.Event.TaskUpdated") + proto.RegisterType((*Event_AgentAdded)(nil), "mesos.v1.master.Event.AgentAdded") + proto.RegisterType((*Event_AgentRemoved)(nil), "mesos.v1.master.Event.AgentRemoved") + proto.RegisterEnum("mesos.v1.master.Call_Type", Call_Type_name, Call_Type_value) + proto.RegisterEnum("mesos.v1.master.Response_Type", Response_Type_name, Response_Type_value) + proto.RegisterEnum("mesos.v1.master.Event_Type", Event_Type_name, Event_Type_value) +} + +func init() { proto.RegisterFile("master.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 2642 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x59, 0xdd, 0x6e, 0x1b, 0xc7, + 0x15, 0x2e, 0x29, 0x52, 0x22, 0x0f, 0xff, 0x96, 0x23, 0x45, 0x61, 0xd6, 0x6e, 0xa2, 0x28, 0x4a, + 0x6c, 0x17, 0x86, 0x64, 0x2b, 0x28, 0x12, 0xd4, 0xad, 0x05, 0x8a, 0x5c, 0x4b, 0x8c, 0xf9, 0x63, + 0xcf, 0x92, 0x72, 0xd3, 0x5e, 0x10, 0x1b, 0xee, 0x88, 0x62, 0x4d, 0x71, 0xe9, 0xdd, 0xa1, 0x5c, + 0xf7, 0x2d, 0xfa, 0x06, 0x7d, 0x80, 0xa0, 0xe8, 0x23, 0xf4, 0xa6, 0x17, 0xbd, 0xec, 0x5d, 0xd1, + 0x77, 0x29, 0x50, 0xcc, 0xdf, 0xfe, 0x90, 0x4b, 0x5a, 0xb2, 0x90, 0xde, 0x10, 0x73, 0xce, 0x7c, + 0xf3, 0xcd, 0xec, 0xcc, 0x99, 0x33, 0xe7, 0x1c, 0x42, 0xfe, 0xd2, 0xf2, 0x28, 0x71, 0xf7, 0xa7, + 0xae, 0x43, 0x1d, 0x54, 0xba, 0x24, 0x9e, 0xe3, 0xed, 0x5f, 0x3d, 0xde, 0x17, 0x6a, 0x7d, 0x8b, + 0x2b, 0x0e, 0xae, 0x1e, 0x1f, 0x88, 0x1e, 0x0e, 0xd3, 0xbf, 0x0a, 0xb4, 0xd6, 0x68, 0x42, 0xc9, + 0xc4, 0x9a, 0x0c, 0x48, 0xb8, 0x2d, 0x71, 0xba, 0x8f, 0x7b, 0x33, 0x73, 0xa8, 0x25, 0x7e, 0x45, + 0xdf, 0xee, 0x3f, 0xb7, 0x21, 0x55, 0xb3, 0xc6, 0x63, 0xb4, 0x0f, 0x29, 0xfa, 0x6e, 0x4a, 0x2a, + 0x89, 0x9d, 0xc4, 0xfd, 0xe2, 0xa1, 0xbe, 0x3f, 0xb7, 0x84, 0x7d, 0x06, 0xda, 0xef, 0xbe, 0x9b, + 0x12, 0xcc, 0x71, 0xa8, 0x0a, 0xb9, 0x21, 0xa1, 0xfd, 0x4b, 0x42, 0xdd, 0xd1, 0xc0, 0xab, 0x24, + 0x77, 0x12, 0xf7, 0x73, 0x87, 0x3b, 0xf1, 0xc3, 0x4e, 0x08, 0x6d, 0x09, 0x1c, 0x86, 0xa1, 0xdf, + 0x46, 0x2f, 0xa1, 0xec, 0x11, 0xda, 0x1f, 0x3b, 0xc3, 0xe1, 0x68, 0x32, 0xec, 0x8f, 0xc9, 0x15, + 0x19, 0x57, 0xd6, 0x38, 0xd1, 0x97, 0xf1, 0x44, 0x26, 0xa1, 0x4d, 0x81, 0x6e, 0x32, 0x30, 0x2e, + 0x79, 0x51, 0x05, 0x7a, 0x0a, 0x30, 0x1e, 0x79, 0xb4, 0x7f, 0x3e, 0x1a, 0x13, 0xaf, 0x92, 0xe2, + 0x5c, 0x9f, 0xc5, 0x73, 0x35, 0x47, 0x1e, 0x7d, 0xc6, 0x60, 0x38, 0x3b, 0x56, 0x4d, 0xf4, 0x04, + 0xb2, 0x2e, 0xb1, 0x6c, 0x3e, 0xbe, 0x92, 0xe6, 0xc3, 0x3f, 0x8d, 0x1f, 0x8e, 0x89, 0x65, 0xb3, + 0x31, 0x38, 0xe3, 0xca, 0x16, 0xfa, 0x0e, 0x8a, 0xb3, 0xa9, 0x6d, 0x51, 0xd2, 0x7f, 0x4b, 0x46, + 0xc3, 0x0b, 0xea, 0x55, 0xd6, 0x39, 0xc3, 0x17, 0xf1, 0x0c, 0x3d, 0x8e, 0x7d, 0x25, 0xa0, 0xb8, + 0x30, 0x0b, 0x8b, 0xc8, 0x84, 0xb2, 0x4b, 0x3c, 0xe2, 0x5e, 0x91, 0xbe, 0x4b, 0x3c, 0x67, 0xe6, + 0x0e, 0x88, 0x57, 0xd9, 0xe0, 0x74, 0x5f, 0x2d, 0x5b, 0x10, 0x87, 0x63, 0x85, 0xc6, 0x9a, 0x3b, + 0xa7, 0x41, 0xdf, 0xc3, 0xe6, 0x6c, 0xb2, 0x48, 0x9b, 0xe1, 0xb4, 0xf7, 0x97, 0xac, 0x72, 0x32, + 0x4f, 0x83, 0xd1, 0x6c, 0x41, 0xc7, 0xbe, 0x7d, 0xe0, 0x12, 0xf6, 0xed, 0x57, 0xce, 0x78, 0x76, + 0x49, 0xbc, 0x4a, 0x76, 0xd5, 0xb7, 0xd7, 0x38, 0xf6, 0x4c, 0x40, 0x71, 0x61, 0x10, 0x16, 0x51, + 0x0b, 0x4a, 0x36, 0xf1, 0xa8, 0xeb, 0xbc, 0xf3, 0xc9, 0x80, 0x93, 0xed, 0xc5, 0x93, 0xd5, 0x05, + 0x58, 0xb1, 0x15, 0xed, 0x88, 0x8c, 0x1c, 0xb8, 0x23, 0x8f, 0x25, 0x74, 0x35, 0xfa, 0xde, 0xe0, + 0x82, 0xd8, 0xb3, 0x31, 0xa9, 0xe4, 0x38, 0xf5, 0xc1, 0xaa, 0x33, 0x6a, 0x05, 0xe3, 0x4c, 0x39, + 0x0c, 0x7f, 0x32, 0x5b, 0xd6, 0xc5, 0xce, 0xce, 0xa3, 0x96, 0x4b, 0xc3, 0xf3, 0x55, 0xf2, 0xab, + 0xce, 0xce, 0x64, 0xf0, 0x10, 0x15, 0xd6, 0xbc, 0x39, 0x0d, 0x7a, 0x01, 0x9a, 0x47, 0x9d, 0x69, + 0x84, 0xb3, 0xb0, 0xf2, 0xae, 0x50, 0x67, 0x1a, 0xa6, 0x2c, 0x79, 0x51, 0x05, 0xb3, 0x75, 0x76, + 0xfd, 0xb8, 0x37, 0xa8, 0x14, 0x57, 0xd9, 0xba, 0x49, 0xe8, 0x4b, 0x86, 0xc2, 0x19, 0x4f, 0xb6, + 0x50, 0x1d, 0xf2, 0x2e, 0xb9, 0x74, 0xae, 0x88, 0x1c, 0x5f, 0xe2, 0xe3, 0x3f, 0x5f, 0x66, 0x9a, + 0x0c, 0x29, 0x28, 0x72, 0x6e, 0x20, 0xe8, 0x4f, 0x01, 0x02, 0xdf, 0x80, 0x1e, 0xc1, 0x06, 0x1d, + 0x5d, 0x12, 0x67, 0x46, 0xb9, 0x17, 0xca, 0x1d, 0x6e, 0x07, 0x74, 0xf5, 0x99, 0x6b, 0xd1, 0x91, + 0x33, 0x69, 0x4c, 0xce, 0x1d, 0xac, 0x60, 0xfa, 0xef, 0xa1, 0x34, 0xe7, 0x12, 0xd0, 0x16, 0xa4, + 0x85, 0x23, 0x49, 0xec, 0x24, 0xef, 0x17, 0xb0, 0x10, 0xd0, 0x21, 0x64, 0x6c, 0xc9, 0x50, 0x49, + 0xee, 0x24, 0x57, 0x70, 0xfb, 0x38, 0xfd, 0x33, 0xc8, 0xfa, 0x3e, 0x02, 0x21, 0x48, 0x4d, 0x2d, + 0x7a, 0xc1, 0x59, 0xb3, 0x98, 0xb7, 0xf5, 0x36, 0x64, 0x94, 0x17, 0x88, 0xeb, 0x47, 0xdb, 0xb0, + 0xee, 0x9c, 0x9f, 0x7b, 0x84, 0xf2, 0x29, 0x53, 0x58, 0x4a, 0x4c, 0x3f, 0x26, 0x93, 0x21, 0xbd, + 0xe0, 0xce, 0x2e, 0x85, 0xa5, 0xa4, 0x9f, 0x42, 0x21, 0xe2, 0x13, 0xd0, 0x37, 0x90, 0x17, 0x9e, + 0xa4, 0x3f, 0x9a, 0x9c, 0x3b, 0x5e, 0x25, 0xb1, 0xb3, 0x76, 0x3f, 0x77, 0xb8, 0x15, 0xac, 0x5c, + 0x00, 0xf9, 0xba, 0x73, 0x6f, 0xfd, 0xb6, 0xa7, 0xbb, 0xa0, 0xcd, 0xbb, 0x03, 0xf4, 0x10, 0x32, + 0xd6, 0x90, 0x4c, 0x68, 0x7f, 0x64, 0xf3, 0x55, 0xe6, 0x0e, 0xcb, 0x01, 0x51, 0x95, 0xf5, 0x34, + 0xea, 0x78, 0x83, 0x43, 0x1a, 0x36, 0x7a, 0xc4, 0x1c, 0xa1, 0x72, 0x10, 0x49, 0x3e, 0x2f, 0x0a, + 0xe0, 0x8a, 0x15, 0x07, 0x20, 0x9d, 0x02, 0x5a, 0xf4, 0x15, 0x3f, 0xf9, 0xac, 0xaf, 0xa1, 0x10, + 0xf1, 0x25, 0x37, 0x9c, 0xf0, 0x21, 0x6c, 0x28, 0x17, 0xb3, 0x7c, 0x3a, 0x05, 0xd1, 0xc7, 0x50, + 0x8c, 0xfa, 0x9a, 0x9f, 0x74, 0xb6, 0x57, 0xf0, 0xc9, 0x52, 0xf7, 0x83, 0x7e, 0x05, 0x19, 0xdf, + 0x83, 0x89, 0x89, 0x23, 0x77, 0x37, 0x08, 0x01, 0x7c, 0x87, 0xe5, 0xe3, 0xf5, 0x1a, 0x68, 0xf3, + 0x0e, 0x07, 0x1d, 0x40, 0xe6, 0xd2, 0x1a, 0x5c, 0x8c, 0x26, 0x44, 0x99, 0xd9, 0x66, 0xc0, 0xd7, + 0x12, 0x3d, 0x8d, 0x3a, 0xf6, 0x41, 0xfa, 0x31, 0x94, 0xe6, 0x3c, 0xcc, 0xcd, 0x39, 0x5a, 0x90, + 0x51, 0xae, 0x05, 0x55, 0xa1, 0xc0, 0x3d, 0x49, 0xdf, 0x25, 0x6f, 0x66, 0xc4, 0xa3, 0xf2, 0xab, + 0xee, 0x06, 0x0c, 0x22, 0x6c, 0x11, 0x5e, 0x44, 0x60, 0x70, 0xfe, 0x4d, 0x48, 0xd2, 0x3f, 0x87, + 0x5c, 0xc8, 0xd3, 0xb0, 0x2b, 0xe9, 0x3a, 0x72, 0x7b, 0xb2, 0x98, 0xb7, 0x77, 0xff, 0x93, 0x82, + 0x14, 0x0b, 0x62, 0x50, 0x0e, 0x36, 0x7a, 0xed, 0xe7, 0xed, 0xce, 0xab, 0xb6, 0xf6, 0x33, 0x54, + 0x04, 0x38, 0x31, 0xba, 0xfd, 0x53, 0xa3, 0xda, 0xec, 0x9e, 0x6a, 0x09, 0x54, 0x80, 0x2c, 0x93, + 0x9f, 0x35, 0xab, 0x27, 0xa6, 0x96, 0x44, 0x25, 0xc8, 0x31, 0xf1, 0xcc, 0xc0, 0x66, 0xa3, 0xd3, + 0xd6, 0xd6, 0x94, 0xa2, 0x65, 0x74, 0x71, 0xa3, 0x66, 0x6a, 0x29, 0xf4, 0x11, 0x94, 0x99, 0xa2, + 0xd9, 0x39, 0x39, 0x69, 0xb4, 0x4f, 0xfa, 0x4d, 0xe3, 0xcc, 0x68, 0x6a, 0x69, 0xa6, 0x36, 0x17, + 0xd4, 0xeb, 0x6c, 0xba, 0x66, 0xc3, 0xec, 0xf6, 0x9f, 0x35, 0x9a, 0x86, 0xa9, 0x6d, 0xb0, 0xe9, + 0xb0, 0x51, 0xad, 0x73, 0x59, 0xcb, 0xa8, 0xd9, 0xcd, 0x6e, 0xb5, 0x6b, 0x68, 0x59, 0xb5, 0xb8, + 0xea, 0x89, 0xd1, 0xee, 0x9a, 0x1a, 0x20, 0x04, 0x45, 0xbe, 0x38, 0x5c, 0x6d, 0x19, 0xaf, 0x3a, + 0xf8, 0xb9, 0xa9, 0xe5, 0x50, 0x19, 0x0a, 0x4c, 0x67, 0xfc, 0xd6, 0xa8, 0xf5, 0xba, 0x1d, 0x6c, + 0x6a, 0x79, 0xc5, 0xd2, 0xad, 0x9a, 0xcf, 0x4d, 0xad, 0xa0, 0x44, 0xdc, 0x61, 0x53, 0x16, 0xd5, + 0x17, 0xbc, 0x32, 0x1a, 0x27, 0xa7, 0x5d, 0x53, 0x2b, 0x31, 0xd6, 0xde, 0x8b, 0x7a, 0xb5, 0x6b, + 0xf8, 0x3a, 0x4d, 0xcd, 0xdc, 0xaa, 0x9a, 0x5d, 0x03, 0x6b, 0x65, 0xc6, 0x61, 0xf6, 0x8e, 0xcd, + 0x1a, 0x6e, 0x1c, 0x1b, 0x1a, 0x62, 0x5f, 0x87, 0x0d, 0xd3, 0xc0, 0x67, 0x46, 0x1f, 0x1b, 0x66, + 0xa7, 0x87, 0x6b, 0x86, 0xa9, 0x6d, 0xa2, 0x8f, 0x61, 0xb3, 0xd7, 0x5e, 0xec, 0xd8, 0x62, 0x53, + 0xd4, 0xb0, 0xc1, 0xa6, 0x38, 0xeb, 0x34, 0x7b, 0x2d, 0xc3, 0xd4, 0x3e, 0x42, 0x9b, 0x50, 0xaa, + 0x1b, 0x66, 0x17, 0x77, 0xbe, 0xf7, 0x95, 0xdb, 0x48, 0x87, 0x6d, 0x31, 0x6f, 0xa3, 0xdd, 0x35, + 0xda, 0xd5, 0x76, 0xcd, 0xe0, 0x9b, 0xd1, 0x33, 0xb5, 0x8f, 0xd1, 0x5d, 0xa8, 0x2c, 0xf4, 0xd5, + 0x4e, 0x8d, 0x7a, 0xaf, 0x69, 0x68, 0x15, 0xf4, 0x19, 0xdc, 0x91, 0x5f, 0x11, 0x0b, 0xf8, 0x84, + 0x9f, 0x48, 0xb7, 0x8a, 0x23, 0x04, 0x9a, 0x8e, 0xb6, 0x40, 0x33, 0xbb, 0x9d, 0x17, 0x11, 0xed, + 0x1d, 0xb5, 0x67, 0x2f, 0x7b, 0x9d, 0x6e, 0x55, 0xbb, 0xcb, 0x3f, 0xdf, 0x17, 0x7f, 0x8e, 0x34, + 0xc8, 0x63, 0xa3, 0xd5, 0x39, 0x33, 0xa4, 0xe6, 0xd3, 0xdd, 0xff, 0xee, 0xb1, 0x07, 0xc1, 0x9b, + 0x3a, 0x13, 0x8f, 0xa0, 0xc3, 0x48, 0x3c, 0xbd, 0xf8, 0xb0, 0x2a, 0x60, 0x38, 0xa6, 0x3e, 0x06, + 0x16, 0x1e, 0xf7, 0x2f, 0x88, 0x35, 0xa6, 0x17, 0x32, 0xa4, 0xfe, 0x62, 0xf9, 0xc8, 0x13, 0x42, + 0x4f, 0x39, 0x14, 0x67, 0x87, 0xaa, 0x89, 0x8e, 0x80, 0x09, 0xfd, 0xf3, 0xb1, 0x35, 0xf4, 0x64, + 0x30, 0xbd, 0xbb, 0x92, 0xe2, 0x19, 0x43, 0xe2, 0xcc, 0x50, 0xb6, 0x90, 0x21, 0x02, 0xfb, 0x2b, + 0xe2, 0x7a, 0xec, 0xb5, 0x4c, 0x2d, 0x89, 0xbc, 0xc2, 0x14, 0x67, 0x02, 0xcb, 0x83, 0x7b, 0xd9, + 0x56, 0x34, 0x2a, 0x3f, 0x48, 0x5f, 0x83, 0x26, 0x2e, 0x47, 0xe8, 0x41, 0x79, 0xb8, 0x90, 0x23, + 0x88, 0xb0, 0xfa, 0xc1, 0x4a, 0xb2, 0x68, 0x9e, 0x30, 0x9c, 0x8b, 0x12, 0x8e, 0x23, 0x79, 0xc2, + 0xc6, 0xfb, 0x76, 0x3a, 0x36, 0x57, 0x38, 0x0a, 0xe7, 0x0a, 0x99, 0xf7, 0xed, 0x74, 0x4c, 0xbe, + 0x20, 0x8f, 0xca, 0xa3, 0x16, 0x25, 0x32, 0x5c, 0x5e, 0x7d, 0x54, 0x26, 0x43, 0xf2, 0xa3, 0xe2, + 0x2d, 0x65, 0x2f, 0xfc, 0x79, 0x51, 0x31, 0xf2, 0x6a, 0x7b, 0xe1, 0x4f, 0x92, 0xc7, 0xed, 0x45, + 0x34, 0x51, 0x1b, 0x8a, 0xdc, 0x5e, 0x5c, 0xeb, 0x92, 0xbc, 0x75, 0xdc, 0xd7, 0x9e, 0x0c, 0x88, + 0xef, 0xad, 0x36, 0x1a, 0x1f, 0x8e, 0x0b, 0xc3, 0xb0, 0x88, 0x9e, 0x03, 0x53, 0xf4, 0xc9, 0x1f, + 0xc9, 0x60, 0x46, 0x1d, 0xd7, 0x5b, 0x1a, 0xf8, 0x86, 0xe9, 0x0c, 0x85, 0xc6, 0xf9, 0x61, 0x48, + 0x52, 0x3b, 0x44, 0x2d, 0xef, 0xb5, 0x27, 0xa3, 0xdd, 0xd5, 0x3b, 0xd4, 0x65, 0x48, 0xbe, 0x43, + 0xbc, 0xa5, 0x08, 0x98, 0xef, 0xf7, 0x64, 0x8c, 0xbb, 0x9a, 0x00, 0x33, 0x24, 0x27, 0xe0, 0x2d, + 0x65, 0xc6, 0x2a, 0xa1, 0x2b, 0x5d, 0xc3, 0x8c, 0x55, 0x46, 0xc7, 0xce, 0x46, 0x45, 0x72, 0xf2, + 0xa4, 0x04, 0xba, 0xa2, 0x5d, 0xe3, 0xa4, 0x5a, 0x5c, 0xc5, 0x4f, 0x4a, 0x34, 0x91, 0x0d, 0xdb, + 0x82, 0x23, 0x94, 0xc4, 0x50, 0x8b, 0xce, 0xbc, 0x4a, 0x99, 0xf3, 0xed, 0xbf, 0x87, 0x2f, 0x08, + 0x22, 0xf8, 0x28, 0xbc, 0x35, 0x8c, 0xd1, 0xa2, 0x3f, 0x40, 0x65, 0x61, 0x16, 0x15, 0x68, 0x20, + 0x3e, 0xcf, 0xa3, 0x6b, 0xcf, 0xa3, 0x42, 0x8f, 0xed, 0x61, 0xac, 0x5e, 0x9d, 0x8e, 0xc8, 0x20, + 0x36, 0xaf, 0x71, 0x3a, 0x32, 0x0b, 0x19, 0xca, 0x96, 0xfe, 0x25, 0x64, 0x7d, 0x27, 0x88, 0x2a, + 0xb0, 0x21, 0x3c, 0xe7, 0x3b, 0xfe, 0xe4, 0x67, 0xb0, 0x12, 0xf5, 0x47, 0x90, 0x51, 0x8e, 0x0e, + 0xed, 0x41, 0x5a, 0xf8, 0x46, 0x11, 0xa1, 0x14, 0x83, 0xf9, 0x58, 0x3f, 0x16, 0x9d, 0xfa, 0x33, + 0x9e, 0x98, 0x28, 0x5f, 0xf6, 0x2d, 0xe4, 0xa5, 0x3b, 0xe4, 0x81, 0xb8, 0x0c, 0x4d, 0x3e, 0x0a, + 0x86, 0x4a, 0xa0, 0x08, 0xc4, 0xaf, 0x02, 0x41, 0xff, 0x36, 0x92, 0xe0, 0xfc, 0x02, 0x36, 0x94, + 0x3f, 0x14, 0xb3, 0x6b, 0xa1, 0xf8, 0x88, 0x77, 0x60, 0x05, 0xd0, 0xef, 0x41, 0xe9, 0xe4, 0x3a, + 0xa9, 0x8d, 0xfe, 0x34, 0x9c, 0xa6, 0x3c, 0x06, 0x60, 0xee, 0x28, 0x92, 0x2f, 0x84, 0x82, 0x4c, + 0x06, 0xe2, 0x8b, 0xcc, 0x9e, 0xcb, 0x96, 0xa7, 0x1f, 0x46, 0xb3, 0x18, 0x6f, 0xf4, 0x27, 0x11, + 0x32, 0xa5, 0x30, 0x6f, 0x33, 0x9d, 0x6d, 0x51, 0x8b, 0xe7, 0x30, 0x79, 0xcc, 0xdb, 0xfa, 0x8f, + 0x49, 0xbe, 0xa3, 0xc2, 0x0b, 0x45, 0x2e, 0x69, 0xe2, 0x03, 0x2e, 0xe9, 0x82, 0xcb, 0x48, 0xde, + 0xc2, 0x65, 0x2c, 0xfa, 0xb3, 0xb5, 0x5b, 0xf9, 0xb3, 0xa8, 0x8f, 0x4d, 0x7d, 0x88, 0x8f, 0xd5, + 0xff, 0x9c, 0xe2, 0x76, 0x2a, 0x3d, 0x6e, 0x15, 0xd6, 0x25, 0x9b, 0x38, 0x9f, 0x07, 0xd7, 0x60, + 0x13, 0xb9, 0x04, 0x96, 0x03, 0xf5, 0xbf, 0xaf, 0x41, 0x9a, 0x6b, 0xd0, 0x21, 0x80, 0x4c, 0x40, + 0x02, 0xc3, 0xdc, 0x9c, 0x4f, 0x41, 0xf8, 0x89, 0x5b, 0xaa, 0xc9, 0xf2, 0x4f, 0x6b, 0x40, 0x47, + 0x57, 0x84, 0x9f, 0x69, 0x06, 0x4b, 0x89, 0x5d, 0x20, 0xf5, 0xea, 0xaf, 0xf1, 0x98, 0x59, 0x89, + 0x48, 0x83, 0xb5, 0xe9, 0xc8, 0xe6, 0x5f, 0x9f, 0xc5, 0xac, 0x89, 0x9e, 0x40, 0xc9, 0x25, 0xc3, + 0x11, 0x5b, 0x2e, 0xb1, 0xfb, 0x2c, 0x1f, 0x97, 0x4f, 0x7c, 0xc8, 0xda, 0xba, 0xa3, 0x4b, 0x61, + 0x6d, 0xc5, 0x00, 0xca, 0x74, 0xe8, 0x08, 0xca, 0x2e, 0x99, 0x1f, 0xbe, 0xbe, 0x74, 0xb8, 0x16, + 0x06, 0x73, 0x82, 0x27, 0x50, 0xa2, 0x0e, 0xb5, 0xc6, 0x91, 0xda, 0xd8, 0xb2, 0x84, 0xaa, 0xc8, + 0xa1, 0x41, 0x4a, 0x5a, 0x83, 0x4d, 0x6b, 0x3c, 0x76, 0x06, 0x16, 0x25, 0x76, 0xa4, 0x0a, 0xb6, + 0x8c, 0x00, 0xf9, 0xf0, 0x80, 0xe4, 0x08, 0xca, 0xce, 0xf9, 0x39, 0x5f, 0x7d, 0x40, 0x91, 0x5d, + 0x4a, 0xa1, 0x49, 0xb0, 0x4f, 0xa0, 0xff, 0x63, 0x1d, 0x0a, 0x11, 0xc3, 0x43, 0x2f, 0x01, 0x42, + 0x56, 0x2b, 0x6c, 0xe3, 0xf1, 0x35, 0xad, 0x76, 0xdf, 0x6f, 0xe2, 0x10, 0x09, 0xb2, 0x61, 0x6b, + 0xe0, 0x5c, 0x4e, 0xc7, 0x84, 0x7d, 0x6a, 0x88, 0x3c, 0xf9, 0xa1, 0xe4, 0x9b, 0x3e, 0x5d, 0x68, + 0xe1, 0xdf, 0xc1, 0x96, 0x4b, 0x06, 0xce, 0x15, 0xdf, 0x8d, 0xc8, 0xc5, 0x63, 0xb3, 0x7c, 0x1c, + 0x72, 0x3f, 0xaa, 0x8f, 0x1f, 0xeb, 0xa6, 0x3f, 0x28, 0xe0, 0xd2, 0xff, 0x9a, 0x82, 0xac, 0x2f, + 0xa2, 0xa7, 0x50, 0xf4, 0xf9, 0xc2, 0x16, 0xbe, 0x94, 0xb3, 0x70, 0x1e, 0x16, 0x97, 0x5a, 0xfa, + 0x5d, 0xc8, 0x0e, 0x9c, 0xc9, 0x84, 0x0c, 0x28, 0xb1, 0xb9, 0xad, 0x67, 0x70, 0xa0, 0x88, 0xb3, + 0xed, 0xd4, 0xed, 0x6c, 0x3b, 0x7d, 0x03, 0xdb, 0x3e, 0x82, 0xf2, 0x6c, 0x72, 0x83, 0xcb, 0x11, + 0x06, 0x73, 0x82, 0x7b, 0xbc, 0xec, 0x44, 0x5c, 0x75, 0x27, 0x4a, 0xc1, 0xa8, 0x0e, 0xd3, 0x63, + 0xd9, 0x8d, 0x7e, 0x03, 0xc5, 0xd1, 0x84, 0x5d, 0x71, 0xd2, 0x97, 0x03, 0xc4, 0x1d, 0x08, 0x95, + 0xc6, 0x1a, 0xa2, 0x5f, 0x8c, 0x2b, 0x8c, 0x42, 0xd2, 0xd2, 0x7b, 0x94, 0xbd, 0xfd, 0x3d, 0x82, + 0x1b, 0xdc, 0xa3, 0xbf, 0x25, 0x21, 0x1f, 0x7e, 0x0e, 0x50, 0x0b, 0xb2, 0xc1, 0x4b, 0x22, 0x6e, + 0xd1, 0xc1, 0xf5, 0x5e, 0x92, 0x7d, 0xd5, 0xc2, 0x01, 0x03, 0xfa, 0x1d, 0x68, 0x8e, 0x3b, 0xbd, + 0xb0, 0x26, 0x91, 0xf7, 0xe9, 0x83, 0x58, 0x4b, 0x82, 0xc8, 0xef, 0xd1, 0x67, 0x90, 0x51, 0x02, + 0x7a, 0x02, 0x05, 0x35, 0x41, 0xd8, 0xd2, 0x43, 0x67, 0xa1, 0xa0, 0xfc, 0xd8, 0xf3, 0x24, 0x24, + 0x45, 0xca, 0x50, 0xc9, 0xf7, 0x95, 0xa1, 0xf4, 0x7f, 0x25, 0xf8, 0xeb, 0x2d, 0x1e, 0xdf, 0xaf, + 0xa1, 0x30, 0x25, 0x13, 0x9b, 0x25, 0x57, 0xea, 0x05, 0x9f, 0x8b, 0x8b, 0x18, 0x0e, 0xe7, 0x25, + 0x48, 0x0c, 0xda, 0x83, 0xb4, 0x00, 0x27, 0x63, 0xc1, 0xa2, 0x13, 0x7d, 0x03, 0xa5, 0xc0, 0xfb, + 0x08, 0xfc, 0x5a, 0x2c, 0xbe, 0xe8, 0xc3, 0x04, 0xfd, 0x63, 0xc8, 0xcb, 0x3d, 0x17, 0xa3, 0x52, + 0xb1, 0xa3, 0x72, 0x02, 0xc3, 0x87, 0xc8, 0x10, 0x4f, 0xc4, 0xec, 0x7b, 0x90, 0x16, 0x01, 0xff, + 0xc2, 0xa7, 0xb0, 0x7e, 0x2c, 0x3a, 0x75, 0x83, 0x87, 0x66, 0xb7, 0x2e, 0xb5, 0x1e, 0xf3, 0xa7, + 0x5d, 0x86, 0xe8, 0xbf, 0x84, 0x9c, 0x30, 0x05, 0x75, 0x84, 0x89, 0x28, 0x89, 0x80, 0x71, 0x12, + 0xb8, 0xf4, 0xdb, 0xba, 0x09, 0x5b, 0x71, 0x11, 0x3a, 0x7a, 0x02, 0xeb, 0x32, 0xc2, 0x17, 0xc6, + 0xf0, 0x45, 0x7c, 0x89, 0xaf, 0x36, 0x9e, 0x31, 0x2a, 0x19, 0xd6, 0xcb, 0x21, 0x7a, 0x17, 0xb6, + 0xe3, 0xc3, 0xf1, 0x5b, 0xd5, 0x0e, 0x8f, 0xf8, 0x3e, 0x8b, 0x02, 0xdb, 0xd7, 0x73, 0xcb, 0xbb, + 0x13, 0x5b, 0xab, 0x8b, 0x2e, 0x6b, 0xf7, 0xdf, 0xc9, 0xff, 0x67, 0x05, 0x2e, 0x5a, 0x6a, 0x5b, + 0x8f, 0x96, 0xda, 0x36, 0xa2, 0xa5, 0xb6, 0xcc, 0x5c, 0xa9, 0x2d, 0x1b, 0x53, 0x6a, 0x83, 0xc5, + 0x52, 0x5b, 0x2e, 0x5a, 0x6a, 0xcb, 0x47, 0x4b, 0x6d, 0x85, 0xf9, 0x52, 0x5b, 0x71, 0xae, 0xac, + 0x56, 0x5a, 0x51, 0xee, 0xd2, 0x56, 0x96, 0xbb, 0xca, 0xd1, 0x02, 0x15, 0xda, 0xfd, 0x71, 0x03, + 0xd2, 0xc6, 0x15, 0x8b, 0x0a, 0x0f, 0x22, 0xc5, 0xa7, 0x3b, 0x0b, 0x8e, 0x8a, 0xa3, 0xa2, 0xff, + 0xe6, 0x82, 0x37, 0xfb, 0xc1, 0x1b, 0xb8, 0xa3, 0x1f, 0x88, 0x2d, 0xe3, 0xef, 0xcf, 0x97, 0x0c, + 0x33, 0x7d, 0x20, 0x0e, 0x0d, 0x42, 0x47, 0x00, 0xec, 0xb6, 0xf6, 0x2d, 0xdb, 0xe6, 0x8f, 0x6a, + 0xfc, 0xff, 0xc1, 0x72, 0x66, 0xcb, 0x7b, 0x5d, 0x65, 0x38, 0x9c, 0xa5, 0xaa, 0x89, 0x0c, 0xc8, + 0x73, 0x02, 0xf1, 0xc7, 0x9a, 0x2d, 0xdf, 0xdc, 0xdd, 0x15, 0x14, 0xa2, 0x3c, 0x6e, 0xe3, 0x1c, + 0x0d, 0x04, 0x74, 0x0c, 0x39, 0xe1, 0x0b, 0xc5, 0x42, 0xd2, 0x2b, 0xbf, 0x85, 0xfb, 0x46, 0xb1, + 0x12, 0x11, 0x47, 0x8b, 0xa5, 0x9c, 0x42, 0x41, 0x70, 0x88, 0x3f, 0xab, 0xec, 0xa5, 0x7f, 0xe4, + 0x86, 0x58, 0x44, 0xe9, 0xd9, 0xc6, 0x79, 0x2b, 0x24, 0xe9, 0x2d, 0x00, 0x33, 0xbc, 0x47, 0xa1, + 0x8a, 0x4f, 0xe2, 0xe6, 0x15, 0x1f, 0xfd, 0x00, 0xb2, 0xfe, 0xde, 0xa1, 0x5d, 0x48, 0xb1, 0x0f, + 0x97, 0xb7, 0x6f, 0xde, 0x3d, 0xf2, 0x3e, 0xfd, 0x2f, 0x09, 0xc8, 0x85, 0xb6, 0x8a, 0xa5, 0xb2, + 0xa1, 0x88, 0xca, 0x5e, 0x4c, 0x65, 0x83, 0x78, 0xaa, 0x8e, 0x73, 0x41, 0x34, 0x65, 0xa3, 0x87, + 0xfe, 0x6d, 0x17, 0x2f, 0xcc, 0x56, 0x74, 0xbe, 0xe8, 0x35, 0x47, 0x0f, 0x20, 0x2d, 0xbe, 0x92, + 0x45, 0x57, 0xc5, 0x70, 0x4a, 0xa2, 0xc0, 0x04, 0x0b, 0x04, 0xdb, 0xa2, 0xe0, 0x18, 0xd0, 0x11, + 0xa4, 0xf9, 0x06, 0xca, 0x95, 0xdd, 0x20, 0x39, 0x12, 0xe3, 0xf4, 0x5f, 0x43, 0x3e, 0x7c, 0x1e, + 0x37, 0xfb, 0x8b, 0x66, 0x77, 0xb4, 0xc4, 0x3b, 0xf9, 0x85, 0xef, 0xba, 0x96, 0x60, 0x32, 0xbb, + 0xec, 0xfd, 0x6a, 0xbd, 0x6e, 0xd4, 0xb5, 0x24, 0xd2, 0x20, 0xcf, 0x65, 0x51, 0x7b, 0xae, 0x0b, + 0xff, 0xc4, 0xbd, 0x88, 0x84, 0xa4, 0x98, 0xdb, 0x10, 0x0a, 0x51, 0x33, 0xae, 0x6b, 0xe9, 0xe3, + 0x3d, 0xd0, 0x1d, 0x77, 0xb8, 0x6f, 0x4d, 0xad, 0xc1, 0x05, 0x99, 0xff, 0xcc, 0xe3, 0xf5, 0x17, + 0xae, 0x43, 0x1d, 0xef, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x26, 0x07, 0xe4, 0xe8, 0x1a, 0x22, + 0x00, 0x00, +} diff --git a/bcs-common/pkg/scheduler/mesosproto/mesos/mesos.pb.go b/bcs-common/pkg/scheduler/mesosproto/mesos/mesos.pb.go new file mode 100644 index 0000000000..d0cb420107 --- /dev/null +++ b/bcs-common/pkg/scheduler/mesosproto/mesos/mesos.pb.go @@ -0,0 +1,7660 @@ +// Code generated by protoc-gen-go. +// source: mesos.proto +// DO NOT EDIT! + +/* +Package mesos is a generated protocol buffer package. + +It is generated from these files: + mesos.proto + +It has these top-level messages: + FrameworkID + OfferID + AgentID + TaskID + ExecutorID + ContainerID + TimeInfo + DurationInfo + Address + URL + Unavailability + MachineID + MachineInfo + FrameworkInfo + HealthCheck + KillPolicy + CommandInfo + ExecutorInfo + MasterInfo + AgentInfo + Value + Attribute + Resource + TrafficControlStatistics + IpStatistics + IcmpStatistics + TcpStatistics + UdpStatistics + SNMPStatistics + ResourceStatistics + ResourceUsage + PerfStatistics + Request + Offer + InverseOffer + TaskInfo + TaskGroupInfo + Task + TaskStatus + Filters + Environment + Parameter + Parameters + Credential + Credentials + RateLimit + RateLimits + Image + Volume + NetworkInfo + CapabilityInfo + LinuxInfo + ContainerInfo + ContainerStatus + CgroupInfo + Labels + Label + Port + Ports + DiscoveryInfo + WeightInfo + VersionInfo + Flag + Role + Metric + FileInfo +*/ +package mesos + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// * +// Status is used to indicate the state of the scheduler and executor +// driver after function calls. +type Status int32 + +const ( + Status_DRIVER_NOT_STARTED Status = 1 + Status_DRIVER_RUNNING Status = 2 + Status_DRIVER_ABORTED Status = 3 + Status_DRIVER_STOPPED Status = 4 +) + +var Status_name = map[int32]string{ + 1: "DRIVER_NOT_STARTED", + 2: "DRIVER_RUNNING", + 3: "DRIVER_ABORTED", + 4: "DRIVER_STOPPED", +} +var Status_value = map[string]int32{ + "DRIVER_NOT_STARTED": 1, + "DRIVER_RUNNING": 2, + "DRIVER_ABORTED": 3, + "DRIVER_STOPPED": 4, +} + +func (x Status) Enum() *Status { + p := new(Status) + *p = x + return p +} +func (x Status) String() string { + return proto.EnumName(Status_name, int32(x)) +} +func (x *Status) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Status_value, data, "Status") + if err != nil { + return err + } + *x = Status(value) + return nil +} +func (Status) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +// * +// Describes possible task states. IMPORTANT: Mesos assumes tasks that +// enter terminal states (see below) imply the task is no longer +// running and thus clean up any thing associated with the task +// (ultimately offering any resources being consumed by that task to +// another task). +type TaskState int32 + +const ( + TaskState_TASK_STAGING TaskState = 6 + TaskState_TASK_STARTING TaskState = 0 + TaskState_TASK_RUNNING TaskState = 1 + // NOTE: This should only be sent when the framework has + // the TASK_KILLING_STATE capability. + TaskState_TASK_KILLING TaskState = 8 + TaskState_TASK_FINISHED TaskState = 2 + TaskState_TASK_FAILED TaskState = 3 + TaskState_TASK_KILLED TaskState = 4 + TaskState_TASK_ERROR TaskState = 7 + // In Mesos 1.2, this will only be sent when the framework does NOT + // opt-in to the PARTITION_AWARE capability. + TaskState_TASK_LOST TaskState = 5 + // The task failed to launch because of a transient error. The + // task's executor never started running. Unlike TASK_ERROR, the + // task description is valid -- attempting to launch the task again + // may be successful. + TaskState_TASK_DROPPED TaskState = 9 + // The task was running on an agent that has lost contact with the + // master, typically due to a network failure or partition. The task + // may or may not still be running. + TaskState_TASK_UNREACHABLE TaskState = 10 + // The task was running on an agent that has been shutdown (e.g., + // the agent become partitioned, rebooted, and then reconnected to + // the master; any tasks running before the reboot will transition + // from UNREACHABLE to GONE). The task is no longer running. + TaskState_TASK_GONE TaskState = 11 + // The task was running on an agent that the master cannot contact; + // the operator has asserted that the agent has been shutdown, but + // this has not been directly confirmed by the master. If the + // operator is correct, the task is not running and this is a + // terminal state; if the operator is mistaken, the task may still + // be running and might return to RUNNING in the future. + TaskState_TASK_GONE_BY_OPERATOR TaskState = 12 + // The master has no knowledge of the task. This is typically + // because either (a) the master never had knowledge of the task, or + // (b) the master forgot about the task because it garbage collected + // its metadata about the task. The task may or may not still be + // running. + TaskState_TASK_UNKNOWN TaskState = 13 +) + +var TaskState_name = map[int32]string{ + 6: "TASK_STAGING", + 0: "TASK_STARTING", + 1: "TASK_RUNNING", + 8: "TASK_KILLING", + 2: "TASK_FINISHED", + 3: "TASK_FAILED", + 4: "TASK_KILLED", + 7: "TASK_ERROR", + 5: "TASK_LOST", + 9: "TASK_DROPPED", + 10: "TASK_UNREACHABLE", + 11: "TASK_GONE", + 12: "TASK_GONE_BY_OPERATOR", + 13: "TASK_UNKNOWN", +} +var TaskState_value = map[string]int32{ + "TASK_STAGING": 6, + "TASK_STARTING": 0, + "TASK_RUNNING": 1, + "TASK_KILLING": 8, + "TASK_FINISHED": 2, + "TASK_FAILED": 3, + "TASK_KILLED": 4, + "TASK_ERROR": 7, + "TASK_LOST": 5, + "TASK_DROPPED": 9, + "TASK_UNREACHABLE": 10, + "TASK_GONE": 11, + "TASK_GONE_BY_OPERATOR": 12, + "TASK_UNKNOWN": 13, +} + +func (x TaskState) Enum() *TaskState { + p := new(TaskState) + *p = x + return p +} +func (x TaskState) String() string { + return proto.EnumName(TaskState_name, int32(x)) +} +func (x *TaskState) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(TaskState_value, data, "TaskState") + if err != nil { + return err + } + *x = TaskState(value) + return nil +} +func (TaskState) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +// Describes the several states that a machine can be in. A `Mode` +// applies to a machine and to all associated agents on the machine. +type MachineInfo_Mode int32 + +const ( + // In this mode, a machine is behaving normally; + // offering resources, executing tasks, etc. + MachineInfo_UP MachineInfo_Mode = 1 + // In this mode, all agents on the machine are expected to cooperate with + // frameworks to drain resources. In general, draining is done ahead of + // a pending `unavailability`. The resources should be drained so as to + // maximize utilization prior to the maintenance but without knowingly + // violating the frameworks' requirements. + MachineInfo_DRAINING MachineInfo_Mode = 2 + // In this mode, a machine is not running any tasks and will not offer + // any of its resources. Agents on the machine will not be allowed to + // register with the master. + MachineInfo_DOWN MachineInfo_Mode = 3 +) + +var MachineInfo_Mode_name = map[int32]string{ + 1: "UP", + 2: "DRAINING", + 3: "DOWN", +} +var MachineInfo_Mode_value = map[string]int32{ + "UP": 1, + "DRAINING": 2, + "DOWN": 3, +} + +func (x MachineInfo_Mode) Enum() *MachineInfo_Mode { + p := new(MachineInfo_Mode) + *p = x + return p +} +func (x MachineInfo_Mode) String() string { + return proto.EnumName(MachineInfo_Mode_name, int32(x)) +} +func (x *MachineInfo_Mode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(MachineInfo_Mode_value, data, "MachineInfo_Mode") + if err != nil { + return err + } + *x = MachineInfo_Mode(value) + return nil +} +func (MachineInfo_Mode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{12, 0} } + +type FrameworkInfo_Capability_Type int32 + +const ( + // This must be the first enum value in this list, to + // ensure that if 'type' is not set, the default value + // is UNKNOWN. This enables enum values to be added + // in a backwards-compatible way. See: MESOS-4997. + FrameworkInfo_Capability_UNKNOWN FrameworkInfo_Capability_Type = 0 + // Receive offers with revocable resources. See 'Resource' + // message for details. + FrameworkInfo_Capability_REVOCABLE_RESOURCES FrameworkInfo_Capability_Type = 1 + // Receive the TASK_KILLING TaskState when a task is being + // killed by an executor. The executor will examine this + // capability to determine whether it can send TASK_KILLING. + FrameworkInfo_Capability_TASK_KILLING_STATE FrameworkInfo_Capability_Type = 2 + // Indicates whether the framework is aware of GPU resources. + // Frameworks that are aware of GPU resources are expected to + // avoid placing non-GPU workloads on GPU agents, in order + // to avoid occupying a GPU agent and preventing GPU workloads + // from running! Currently, if a framework is unaware of GPU + // resources, it will not be offered *any* of the resources on + // an agent with GPUs. This restriction is in place because we + // do not have a revocation mechanism that ensures GPU workloads + // can evict GPU agent occupants if necessary. + // + // TODO(bmahler): As we add revocation we can relax the + // restriction here. See MESOS-5634 for more information. + FrameworkInfo_Capability_GPU_RESOURCES FrameworkInfo_Capability_Type = 3 + // Receive offers with resources that are shared. + FrameworkInfo_Capability_SHARED_RESOURCES FrameworkInfo_Capability_Type = 4 + // Indicates that (1) the framework is prepared to handle the + // following TaskStates: TASK_UNREACHABLE, TASK_DROPPED, + // TASK_GONE, TASK_GONE_BY_OPERATOR, and TASK_UNKNOWN, and (2) + // the framework will assume responsibility for managing + // partitioned tasks that reregister with the master. + // + // Frameworks that enable this capability can define how they + // would like to handle partitioned tasks. Frameworks will + // receive TASK_UNREACHABLE for tasks on agents that are + // partitioned from the master. If/when a partitioned agent + // reregisters, tasks on the agent that were started by + // PARTITION_AWARE frameworks will not killed. + // + // Without this capability, frameworks will receive TASK_LOST + // for tasks on partitioned agents; such tasks will be killed by + // Mesos when the agent reregisters (unless the master has + // failed over). + FrameworkInfo_Capability_PARTITION_AWARE FrameworkInfo_Capability_Type = 5 +) + +var FrameworkInfo_Capability_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "REVOCABLE_RESOURCES", + 2: "TASK_KILLING_STATE", + 3: "GPU_RESOURCES", + 4: "SHARED_RESOURCES", + 5: "PARTITION_AWARE", +} +var FrameworkInfo_Capability_Type_value = map[string]int32{ + "UNKNOWN": 0, + "REVOCABLE_RESOURCES": 1, + "TASK_KILLING_STATE": 2, + "GPU_RESOURCES": 3, + "SHARED_RESOURCES": 4, + "PARTITION_AWARE": 5, +} + +func (x FrameworkInfo_Capability_Type) Enum() *FrameworkInfo_Capability_Type { + p := new(FrameworkInfo_Capability_Type) + *p = x + return p +} +func (x FrameworkInfo_Capability_Type) String() string { + return proto.EnumName(FrameworkInfo_Capability_Type_name, int32(x)) +} +func (x *FrameworkInfo_Capability_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FrameworkInfo_Capability_Type_value, data, "FrameworkInfo_Capability_Type") + if err != nil { + return err + } + *x = FrameworkInfo_Capability_Type(value) + return nil +} +func (FrameworkInfo_Capability_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor0, []int{13, 0, 0} +} + +type HealthCheck_Type int32 + +const ( + HealthCheck_UNKNOWN HealthCheck_Type = 0 + HealthCheck_COMMAND HealthCheck_Type = 1 + HealthCheck_HTTP HealthCheck_Type = 2 + HealthCheck_TCP HealthCheck_Type = 3 +) + +var HealthCheck_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "COMMAND", + 2: "HTTP", + 3: "TCP", +} +var HealthCheck_Type_value = map[string]int32{ + "UNKNOWN": 0, + "COMMAND": 1, + "HTTP": 2, + "TCP": 3, +} + +func (x HealthCheck_Type) Enum() *HealthCheck_Type { + p := new(HealthCheck_Type) + *p = x + return p +} +func (x HealthCheck_Type) String() string { + return proto.EnumName(HealthCheck_Type_name, int32(x)) +} +func (x *HealthCheck_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(HealthCheck_Type_value, data, "HealthCheck_Type") + if err != nil { + return err + } + *x = HealthCheck_Type(value) + return nil +} +func (HealthCheck_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{14, 0} } + +type ExecutorInfo_Type int32 + +const ( + ExecutorInfo_UNKNOWN ExecutorInfo_Type = 0 + // Mesos provides a simple built-in default executor that frameworks can + // leverage to run shell commands and containers. + // + // NOTES: + // + // 1) `command` must not be set when using a default executor. + // + // 2) Default executor only accepts a *single* `LAUNCH` or `LAUNCH_GROUP` + // offer operation. + ExecutorInfo_DEFAULT ExecutorInfo_Type = 1 + // For frameworks that need custom functionality to run tasks, a `CUSTOM` + // executor can be used. Note that `command` must be set when using a + // `CUSTOM` executor. + ExecutorInfo_CUSTOM ExecutorInfo_Type = 2 +) + +var ExecutorInfo_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "DEFAULT", + 2: "CUSTOM", +} +var ExecutorInfo_Type_value = map[string]int32{ + "UNKNOWN": 0, + "DEFAULT": 1, + "CUSTOM": 2, +} + +func (x ExecutorInfo_Type) Enum() *ExecutorInfo_Type { + p := new(ExecutorInfo_Type) + *p = x + return p +} +func (x ExecutorInfo_Type) String() string { + return proto.EnumName(ExecutorInfo_Type_name, int32(x)) +} +func (x *ExecutorInfo_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(ExecutorInfo_Type_value, data, "ExecutorInfo_Type") + if err != nil { + return err + } + *x = ExecutorInfo_Type(value) + return nil +} +func (ExecutorInfo_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{17, 0} } + +type Value_Type int32 + +const ( + Value_SCALAR Value_Type = 0 + Value_RANGES Value_Type = 1 + Value_SET Value_Type = 2 + Value_TEXT Value_Type = 3 +) + +var Value_Type_name = map[int32]string{ + 0: "SCALAR", + 1: "RANGES", + 2: "SET", + 3: "TEXT", +} +var Value_Type_value = map[string]int32{ + "SCALAR": 0, + "RANGES": 1, + "SET": 2, + "TEXT": 3, +} + +func (x Value_Type) Enum() *Value_Type { + p := new(Value_Type) + *p = x + return p +} +func (x Value_Type) String() string { + return proto.EnumName(Value_Type_name, int32(x)) +} +func (x *Value_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Value_Type_value, data, "Value_Type") + if err != nil { + return err + } + *x = Value_Type(value) + return nil +} +func (Value_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{20, 0} } + +type Resource_DiskInfo_Source_Type int32 + +const ( + Resource_DiskInfo_Source_PATH Resource_DiskInfo_Source_Type = 1 + Resource_DiskInfo_Source_MOUNT Resource_DiskInfo_Source_Type = 2 +) + +var Resource_DiskInfo_Source_Type_name = map[int32]string{ + 1: "PATH", + 2: "MOUNT", +} +var Resource_DiskInfo_Source_Type_value = map[string]int32{ + "PATH": 1, + "MOUNT": 2, +} + +func (x Resource_DiskInfo_Source_Type) Enum() *Resource_DiskInfo_Source_Type { + p := new(Resource_DiskInfo_Source_Type) + *p = x + return p +} +func (x Resource_DiskInfo_Source_Type) String() string { + return proto.EnumName(Resource_DiskInfo_Source_Type_name, int32(x)) +} +func (x *Resource_DiskInfo_Source_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Resource_DiskInfo_Source_Type_value, data, "Resource_DiskInfo_Source_Type") + if err != nil { + return err + } + *x = Resource_DiskInfo_Source_Type(value) + return nil +} +func (Resource_DiskInfo_Source_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor0, []int{22, 1, 1, 0} +} + +type Offer_Operation_Type int32 + +const ( + Offer_Operation_UNKNOWN Offer_Operation_Type = 0 + Offer_Operation_LAUNCH Offer_Operation_Type = 1 + Offer_Operation_LAUNCH_GROUP Offer_Operation_Type = 6 + Offer_Operation_RESERVE Offer_Operation_Type = 2 + Offer_Operation_UNRESERVE Offer_Operation_Type = 3 + Offer_Operation_CREATE Offer_Operation_Type = 4 + Offer_Operation_DESTROY Offer_Operation_Type = 5 +) + +var Offer_Operation_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "LAUNCH", + 6: "LAUNCH_GROUP", + 2: "RESERVE", + 3: "UNRESERVE", + 4: "CREATE", + 5: "DESTROY", +} +var Offer_Operation_Type_value = map[string]int32{ + "UNKNOWN": 0, + "LAUNCH": 1, + "LAUNCH_GROUP": 6, + "RESERVE": 2, + "UNRESERVE": 3, + "CREATE": 4, + "DESTROY": 5, +} + +func (x Offer_Operation_Type) Enum() *Offer_Operation_Type { + p := new(Offer_Operation_Type) + *p = x + return p +} +func (x Offer_Operation_Type) String() string { + return proto.EnumName(Offer_Operation_Type_name, int32(x)) +} +func (x *Offer_Operation_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Offer_Operation_Type_value, data, "Offer_Operation_Type") + if err != nil { + return err + } + *x = Offer_Operation_Type(value) + return nil +} +func (Offer_Operation_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{33, 0, 0} } + +// Describes the source of the task status update. +type TaskStatus_Source int32 + +const ( + TaskStatus_SOURCE_MASTER TaskStatus_Source = 0 + TaskStatus_SOURCE_AGENT TaskStatus_Source = 1 + TaskStatus_SOURCE_EXECUTOR TaskStatus_Source = 2 +) + +var TaskStatus_Source_name = map[int32]string{ + 0: "SOURCE_MASTER", + 1: "SOURCE_AGENT", + 2: "SOURCE_EXECUTOR", +} +var TaskStatus_Source_value = map[string]int32{ + "SOURCE_MASTER": 0, + "SOURCE_AGENT": 1, + "SOURCE_EXECUTOR": 2, +} + +func (x TaskStatus_Source) Enum() *TaskStatus_Source { + p := new(TaskStatus_Source) + *p = x + return p +} +func (x TaskStatus_Source) String() string { + return proto.EnumName(TaskStatus_Source_name, int32(x)) +} +func (x *TaskStatus_Source) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(TaskStatus_Source_value, data, "TaskStatus_Source") + if err != nil { + return err + } + *x = TaskStatus_Source(value) + return nil +} +func (TaskStatus_Source) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{38, 0} } + +// Detailed reason for the task status update. +// +// TODO(bmahler): Differentiate between agent removal reasons +// (e.g. unhealthy vs. unregistered for maintenance). +type TaskStatus_Reason int32 + +const ( + // TODO(jieyu): The default value when a caller doesn't check for + // presence is 0 and so ideally the 0 reason is not a valid one. + // Since this is not used anywhere, consider removing this reason. + TaskStatus_REASON_COMMAND_EXECUTOR_FAILED TaskStatus_Reason = 0 + TaskStatus_REASON_CONTAINER_LAUNCH_FAILED TaskStatus_Reason = 21 + TaskStatus_REASON_CONTAINER_LIMITATION TaskStatus_Reason = 19 + TaskStatus_REASON_CONTAINER_LIMITATION_DISK TaskStatus_Reason = 20 + TaskStatus_REASON_CONTAINER_LIMITATION_MEMORY TaskStatus_Reason = 8 + TaskStatus_REASON_CONTAINER_PREEMPTED TaskStatus_Reason = 17 + TaskStatus_REASON_CONTAINER_UPDATE_FAILED TaskStatus_Reason = 22 + TaskStatus_REASON_EXECUTOR_REGISTRATION_TIMEOUT TaskStatus_Reason = 23 + TaskStatus_REASON_EXECUTOR_REREGISTRATION_TIMEOUT TaskStatus_Reason = 24 + TaskStatus_REASON_EXECUTOR_TERMINATED TaskStatus_Reason = 1 + TaskStatus_REASON_EXECUTOR_UNREGISTERED TaskStatus_Reason = 2 + TaskStatus_REASON_FRAMEWORK_REMOVED TaskStatus_Reason = 3 + TaskStatus_REASON_GC_ERROR TaskStatus_Reason = 4 + TaskStatus_REASON_INVALID_FRAMEWORKID TaskStatus_Reason = 5 + TaskStatus_REASON_INVALID_OFFERS TaskStatus_Reason = 6 + TaskStatus_REASON_MASTER_DISCONNECTED TaskStatus_Reason = 7 + TaskStatus_REASON_RECONCILIATION TaskStatus_Reason = 9 + TaskStatus_REASON_RESOURCES_UNKNOWN TaskStatus_Reason = 18 + TaskStatus_REASON_AGENT_DISCONNECTED TaskStatus_Reason = 10 + TaskStatus_REASON_AGENT_REMOVED TaskStatus_Reason = 11 + TaskStatus_REASON_AGENT_RESTARTED TaskStatus_Reason = 12 + TaskStatus_REASON_AGENT_UNKNOWN TaskStatus_Reason = 13 + TaskStatus_REASON_TASK_GROUP_INVALID TaskStatus_Reason = 25 + TaskStatus_REASON_TASK_GROUP_UNAUTHORIZED TaskStatus_Reason = 26 + TaskStatus_REASON_TASK_INVALID TaskStatus_Reason = 14 + TaskStatus_REASON_TASK_UNAUTHORIZED TaskStatus_Reason = 15 + TaskStatus_REASON_TASK_UNKNOWN TaskStatus_Reason = 16 +) + +var TaskStatus_Reason_name = map[int32]string{ + 0: "REASON_COMMAND_EXECUTOR_FAILED", + 21: "REASON_CONTAINER_LAUNCH_FAILED", + 19: "REASON_CONTAINER_LIMITATION", + 20: "REASON_CONTAINER_LIMITATION_DISK", + 8: "REASON_CONTAINER_LIMITATION_MEMORY", + 17: "REASON_CONTAINER_PREEMPTED", + 22: "REASON_CONTAINER_UPDATE_FAILED", + 23: "REASON_EXECUTOR_REGISTRATION_TIMEOUT", + 24: "REASON_EXECUTOR_REREGISTRATION_TIMEOUT", + 1: "REASON_EXECUTOR_TERMINATED", + 2: "REASON_EXECUTOR_UNREGISTERED", + 3: "REASON_FRAMEWORK_REMOVED", + 4: "REASON_GC_ERROR", + 5: "REASON_INVALID_FRAMEWORKID", + 6: "REASON_INVALID_OFFERS", + 7: "REASON_MASTER_DISCONNECTED", + 9: "REASON_RECONCILIATION", + 18: "REASON_RESOURCES_UNKNOWN", + 10: "REASON_AGENT_DISCONNECTED", + 11: "REASON_AGENT_REMOVED", + 12: "REASON_AGENT_RESTARTED", + 13: "REASON_AGENT_UNKNOWN", + 25: "REASON_TASK_GROUP_INVALID", + 26: "REASON_TASK_GROUP_UNAUTHORIZED", + 14: "REASON_TASK_INVALID", + 15: "REASON_TASK_UNAUTHORIZED", + 16: "REASON_TASK_UNKNOWN", +} +var TaskStatus_Reason_value = map[string]int32{ + "REASON_COMMAND_EXECUTOR_FAILED": 0, + "REASON_CONTAINER_LAUNCH_FAILED": 21, + "REASON_CONTAINER_LIMITATION": 19, + "REASON_CONTAINER_LIMITATION_DISK": 20, + "REASON_CONTAINER_LIMITATION_MEMORY": 8, + "REASON_CONTAINER_PREEMPTED": 17, + "REASON_CONTAINER_UPDATE_FAILED": 22, + "REASON_EXECUTOR_REGISTRATION_TIMEOUT": 23, + "REASON_EXECUTOR_REREGISTRATION_TIMEOUT": 24, + "REASON_EXECUTOR_TERMINATED": 1, + "REASON_EXECUTOR_UNREGISTERED": 2, + "REASON_FRAMEWORK_REMOVED": 3, + "REASON_GC_ERROR": 4, + "REASON_INVALID_FRAMEWORKID": 5, + "REASON_INVALID_OFFERS": 6, + "REASON_MASTER_DISCONNECTED": 7, + "REASON_RECONCILIATION": 9, + "REASON_RESOURCES_UNKNOWN": 18, + "REASON_AGENT_DISCONNECTED": 10, + "REASON_AGENT_REMOVED": 11, + "REASON_AGENT_RESTARTED": 12, + "REASON_AGENT_UNKNOWN": 13, + "REASON_TASK_GROUP_INVALID": 25, + "REASON_TASK_GROUP_UNAUTHORIZED": 26, + "REASON_TASK_INVALID": 14, + "REASON_TASK_UNAUTHORIZED": 15, + "REASON_TASK_UNKNOWN": 16, +} + +func (x TaskStatus_Reason) Enum() *TaskStatus_Reason { + p := new(TaskStatus_Reason) + *p = x + return p +} +func (x TaskStatus_Reason) String() string { + return proto.EnumName(TaskStatus_Reason_name, int32(x)) +} +func (x *TaskStatus_Reason) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(TaskStatus_Reason_value, data, "TaskStatus_Reason") + if err != nil { + return err + } + *x = TaskStatus_Reason(value) + return nil +} +func (TaskStatus_Reason) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{38, 1} } + +type Image_Type int32 + +const ( + Image_APPC Image_Type = 1 + Image_DOCKER Image_Type = 2 +) + +var Image_Type_name = map[int32]string{ + 1: "APPC", + 2: "DOCKER", +} +var Image_Type_value = map[string]int32{ + "APPC": 1, + "DOCKER": 2, +} + +func (x Image_Type) Enum() *Image_Type { + p := new(Image_Type) + *p = x + return p +} +func (x Image_Type) String() string { + return proto.EnumName(Image_Type_name, int32(x)) +} +func (x *Image_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Image_Type_value, data, "Image_Type") + if err != nil { + return err + } + *x = Image_Type(value) + return nil +} +func (Image_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{47, 0} } + +type Volume_Mode int32 + +const ( + Volume_RW Volume_Mode = 1 + Volume_RO Volume_Mode = 2 +) + +var Volume_Mode_name = map[int32]string{ + 1: "RW", + 2: "RO", +} +var Volume_Mode_value = map[string]int32{ + "RW": 1, + "RO": 2, +} + +func (x Volume_Mode) Enum() *Volume_Mode { + p := new(Volume_Mode) + *p = x + return p +} +func (x Volume_Mode) String() string { + return proto.EnumName(Volume_Mode_name, int32(x)) +} +func (x *Volume_Mode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Volume_Mode_value, data, "Volume_Mode") + if err != nil { + return err + } + *x = Volume_Mode(value) + return nil +} +func (Volume_Mode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{48, 0} } + +type Volume_Source_Type int32 + +const ( + // This must be the first enum value in this list, to + // ensure that if 'type' is not set, the default value + // is UNKNOWN. This enables enum values to be added + // in a backwards-compatible way. See: MESOS-4997. + Volume_Source_UNKNOWN Volume_Source_Type = 0 + // TODO(gyliu513): Add HOST_PATH and IMAGE as volume source type. + Volume_Source_DOCKER_VOLUME Volume_Source_Type = 1 + Volume_Source_SANDBOX_PATH Volume_Source_Type = 2 +) + +var Volume_Source_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "DOCKER_VOLUME", + 2: "SANDBOX_PATH", +} +var Volume_Source_Type_value = map[string]int32{ + "UNKNOWN": 0, + "DOCKER_VOLUME": 1, + "SANDBOX_PATH": 2, +} + +func (x Volume_Source_Type) Enum() *Volume_Source_Type { + p := new(Volume_Source_Type) + *p = x + return p +} +func (x Volume_Source_Type) String() string { + return proto.EnumName(Volume_Source_Type_name, int32(x)) +} +func (x *Volume_Source_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Volume_Source_Type_value, data, "Volume_Source_Type") + if err != nil { + return err + } + *x = Volume_Source_Type(value) + return nil +} +func (Volume_Source_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{48, 0, 0} } + +type Volume_Source_SandboxPath_Type int32 + +const ( + Volume_Source_SandboxPath_UNKNOWN Volume_Source_SandboxPath_Type = 0 + Volume_Source_SandboxPath_SELF Volume_Source_SandboxPath_Type = 1 + Volume_Source_SandboxPath_PARENT Volume_Source_SandboxPath_Type = 2 +) + +var Volume_Source_SandboxPath_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "SELF", + 2: "PARENT", +} +var Volume_Source_SandboxPath_Type_value = map[string]int32{ + "UNKNOWN": 0, + "SELF": 1, + "PARENT": 2, +} + +func (x Volume_Source_SandboxPath_Type) Enum() *Volume_Source_SandboxPath_Type { + p := new(Volume_Source_SandboxPath_Type) + *p = x + return p +} +func (x Volume_Source_SandboxPath_Type) String() string { + return proto.EnumName(Volume_Source_SandboxPath_Type_name, int32(x)) +} +func (x *Volume_Source_SandboxPath_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Volume_Source_SandboxPath_Type_value, data, "Volume_Source_SandboxPath_Type") + if err != nil { + return err + } + *x = Volume_Source_SandboxPath_Type(value) + return nil +} +func (Volume_Source_SandboxPath_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor0, []int{48, 0, 1, 0} +} + +type NetworkInfo_Protocol int32 + +const ( + NetworkInfo_IPv4 NetworkInfo_Protocol = 1 + NetworkInfo_IPv6 NetworkInfo_Protocol = 2 +) + +var NetworkInfo_Protocol_name = map[int32]string{ + 1: "IPv4", + 2: "IPv6", +} +var NetworkInfo_Protocol_value = map[string]int32{ + "IPv4": 1, + "IPv6": 2, +} + +func (x NetworkInfo_Protocol) Enum() *NetworkInfo_Protocol { + p := new(NetworkInfo_Protocol) + *p = x + return p +} +func (x NetworkInfo_Protocol) String() string { + return proto.EnumName(NetworkInfo_Protocol_name, int32(x)) +} +func (x *NetworkInfo_Protocol) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(NetworkInfo_Protocol_value, data, "NetworkInfo_Protocol") + if err != nil { + return err + } + *x = NetworkInfo_Protocol(value) + return nil +} +func (NetworkInfo_Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{49, 0} } + +// We start the actual values at an offset(1000) because Protobuf 2 +// uses the first value as the default one. Separating the default +// value from the real first value helps to disambiguate them. This +// is especially valuable for backward compatibility. +// See: MESOS-4997. +type CapabilityInfo_Capability int32 + +const ( + CapabilityInfo_UNKNOWN CapabilityInfo_Capability = 0 + CapabilityInfo_CHOWN CapabilityInfo_Capability = 1000 + CapabilityInfo_DAC_OVERRIDE CapabilityInfo_Capability = 1001 + CapabilityInfo_DAC_READ_SEARCH CapabilityInfo_Capability = 1002 + CapabilityInfo_FOWNER CapabilityInfo_Capability = 1003 + CapabilityInfo_FSETID CapabilityInfo_Capability = 1004 + CapabilityInfo_KILL CapabilityInfo_Capability = 1005 + CapabilityInfo_SETGID CapabilityInfo_Capability = 1006 + CapabilityInfo_SETUID CapabilityInfo_Capability = 1007 + CapabilityInfo_SETPCAP CapabilityInfo_Capability = 1008 + CapabilityInfo_LINUX_IMMUTABLE CapabilityInfo_Capability = 1009 + CapabilityInfo_NET_BIND_SERVICE CapabilityInfo_Capability = 1010 + CapabilityInfo_NET_BROADCAST CapabilityInfo_Capability = 1011 + CapabilityInfo_NET_ADMIN CapabilityInfo_Capability = 1012 + CapabilityInfo_NET_RAW CapabilityInfo_Capability = 1013 + CapabilityInfo_IPC_LOCK CapabilityInfo_Capability = 1014 + CapabilityInfo_IPC_OWNER CapabilityInfo_Capability = 1015 + CapabilityInfo_SYS_MODULE CapabilityInfo_Capability = 1016 + CapabilityInfo_SYS_RAWIO CapabilityInfo_Capability = 1017 + CapabilityInfo_SYS_CHROOT CapabilityInfo_Capability = 1018 + CapabilityInfo_SYS_PTRACE CapabilityInfo_Capability = 1019 + CapabilityInfo_SYS_PACCT CapabilityInfo_Capability = 1020 + CapabilityInfo_SYS_ADMIN CapabilityInfo_Capability = 1021 + CapabilityInfo_SYS_BOOT CapabilityInfo_Capability = 1022 + CapabilityInfo_SYS_NICE CapabilityInfo_Capability = 1023 + CapabilityInfo_SYS_RESOURCE CapabilityInfo_Capability = 1024 + CapabilityInfo_SYS_TIME CapabilityInfo_Capability = 1025 + CapabilityInfo_SYS_TTY_CONFIG CapabilityInfo_Capability = 1026 + CapabilityInfo_MKNOD CapabilityInfo_Capability = 1027 + CapabilityInfo_LEASE CapabilityInfo_Capability = 1028 + CapabilityInfo_AUDIT_WRITE CapabilityInfo_Capability = 1029 + CapabilityInfo_AUDIT_CONTROL CapabilityInfo_Capability = 1030 + CapabilityInfo_SETFCAP CapabilityInfo_Capability = 1031 + CapabilityInfo_MAC_OVERRIDE CapabilityInfo_Capability = 1032 + CapabilityInfo_MAC_ADMIN CapabilityInfo_Capability = 1033 + CapabilityInfo_SYSLOG CapabilityInfo_Capability = 1034 + CapabilityInfo_WAKE_ALARM CapabilityInfo_Capability = 1035 + CapabilityInfo_BLOCK_SUSPEND CapabilityInfo_Capability = 1036 + CapabilityInfo_AUDIT_READ CapabilityInfo_Capability = 1037 +) + +var CapabilityInfo_Capability_name = map[int32]string{ + 0: "UNKNOWN", + 1000: "CHOWN", + 1001: "DAC_OVERRIDE", + 1002: "DAC_READ_SEARCH", + 1003: "FOWNER", + 1004: "FSETID", + 1005: "KILL", + 1006: "SETGID", + 1007: "SETUID", + 1008: "SETPCAP", + 1009: "LINUX_IMMUTABLE", + 1010: "NET_BIND_SERVICE", + 1011: "NET_BROADCAST", + 1012: "NET_ADMIN", + 1013: "NET_RAW", + 1014: "IPC_LOCK", + 1015: "IPC_OWNER", + 1016: "SYS_MODULE", + 1017: "SYS_RAWIO", + 1018: "SYS_CHROOT", + 1019: "SYS_PTRACE", + 1020: "SYS_PACCT", + 1021: "SYS_ADMIN", + 1022: "SYS_BOOT", + 1023: "SYS_NICE", + 1024: "SYS_RESOURCE", + 1025: "SYS_TIME", + 1026: "SYS_TTY_CONFIG", + 1027: "MKNOD", + 1028: "LEASE", + 1029: "AUDIT_WRITE", + 1030: "AUDIT_CONTROL", + 1031: "SETFCAP", + 1032: "MAC_OVERRIDE", + 1033: "MAC_ADMIN", + 1034: "SYSLOG", + 1035: "WAKE_ALARM", + 1036: "BLOCK_SUSPEND", + 1037: "AUDIT_READ", +} +var CapabilityInfo_Capability_value = map[string]int32{ + "UNKNOWN": 0, + "CHOWN": 1000, + "DAC_OVERRIDE": 1001, + "DAC_READ_SEARCH": 1002, + "FOWNER": 1003, + "FSETID": 1004, + "KILL": 1005, + "SETGID": 1006, + "SETUID": 1007, + "SETPCAP": 1008, + "LINUX_IMMUTABLE": 1009, + "NET_BIND_SERVICE": 1010, + "NET_BROADCAST": 1011, + "NET_ADMIN": 1012, + "NET_RAW": 1013, + "IPC_LOCK": 1014, + "IPC_OWNER": 1015, + "SYS_MODULE": 1016, + "SYS_RAWIO": 1017, + "SYS_CHROOT": 1018, + "SYS_PTRACE": 1019, + "SYS_PACCT": 1020, + "SYS_ADMIN": 1021, + "SYS_BOOT": 1022, + "SYS_NICE": 1023, + "SYS_RESOURCE": 1024, + "SYS_TIME": 1025, + "SYS_TTY_CONFIG": 1026, + "MKNOD": 1027, + "LEASE": 1028, + "AUDIT_WRITE": 1029, + "AUDIT_CONTROL": 1030, + "SETFCAP": 1031, + "MAC_OVERRIDE": 1032, + "MAC_ADMIN": 1033, + "SYSLOG": 1034, + "WAKE_ALARM": 1035, + "BLOCK_SUSPEND": 1036, + "AUDIT_READ": 1037, +} + +func (x CapabilityInfo_Capability) Enum() *CapabilityInfo_Capability { + p := new(CapabilityInfo_Capability) + *p = x + return p +} +func (x CapabilityInfo_Capability) String() string { + return proto.EnumName(CapabilityInfo_Capability_name, int32(x)) +} +func (x *CapabilityInfo_Capability) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(CapabilityInfo_Capability_value, data, "CapabilityInfo_Capability") + if err != nil { + return err + } + *x = CapabilityInfo_Capability(value) + return nil +} +func (CapabilityInfo_Capability) EnumDescriptor() ([]byte, []int) { + return fileDescriptor0, []int{50, 0} +} + +// All container implementation types. +type ContainerInfo_Type int32 + +const ( + ContainerInfo_DOCKER ContainerInfo_Type = 1 + ContainerInfo_MESOS ContainerInfo_Type = 2 +) + +var ContainerInfo_Type_name = map[int32]string{ + 1: "DOCKER", + 2: "MESOS", +} +var ContainerInfo_Type_value = map[string]int32{ + "DOCKER": 1, + "MESOS": 2, +} + +func (x ContainerInfo_Type) Enum() *ContainerInfo_Type { + p := new(ContainerInfo_Type) + *p = x + return p +} +func (x ContainerInfo_Type) String() string { + return proto.EnumName(ContainerInfo_Type_name, int32(x)) +} +func (x *ContainerInfo_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(ContainerInfo_Type_value, data, "ContainerInfo_Type") + if err != nil { + return err + } + *x = ContainerInfo_Type(value) + return nil +} +func (ContainerInfo_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{52, 0} } + +// Network options. +type ContainerInfo_DockerInfo_Network int32 + +const ( + ContainerInfo_DockerInfo_HOST ContainerInfo_DockerInfo_Network = 1 + ContainerInfo_DockerInfo_BRIDGE ContainerInfo_DockerInfo_Network = 2 + ContainerInfo_DockerInfo_NONE ContainerInfo_DockerInfo_Network = 3 + ContainerInfo_DockerInfo_USER ContainerInfo_DockerInfo_Network = 4 +) + +var ContainerInfo_DockerInfo_Network_name = map[int32]string{ + 1: "HOST", + 2: "BRIDGE", + 3: "NONE", + 4: "USER", +} +var ContainerInfo_DockerInfo_Network_value = map[string]int32{ + "HOST": 1, + "BRIDGE": 2, + "NONE": 3, + "USER": 4, +} + +func (x ContainerInfo_DockerInfo_Network) Enum() *ContainerInfo_DockerInfo_Network { + p := new(ContainerInfo_DockerInfo_Network) + *p = x + return p +} +func (x ContainerInfo_DockerInfo_Network) String() string { + return proto.EnumName(ContainerInfo_DockerInfo_Network_name, int32(x)) +} +func (x *ContainerInfo_DockerInfo_Network) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(ContainerInfo_DockerInfo_Network_value, data, "ContainerInfo_DockerInfo_Network") + if err != nil { + return err + } + *x = ContainerInfo_DockerInfo_Network(value) + return nil +} +func (ContainerInfo_DockerInfo_Network) EnumDescriptor() ([]byte, []int) { + return fileDescriptor0, []int{52, 0, 0} +} + +type DiscoveryInfo_Visibility int32 + +const ( + DiscoveryInfo_FRAMEWORK DiscoveryInfo_Visibility = 0 + DiscoveryInfo_CLUSTER DiscoveryInfo_Visibility = 1 + DiscoveryInfo_EXTERNAL DiscoveryInfo_Visibility = 2 +) + +var DiscoveryInfo_Visibility_name = map[int32]string{ + 0: "FRAMEWORK", + 1: "CLUSTER", + 2: "EXTERNAL", +} +var DiscoveryInfo_Visibility_value = map[string]int32{ + "FRAMEWORK": 0, + "CLUSTER": 1, + "EXTERNAL": 2, +} + +func (x DiscoveryInfo_Visibility) Enum() *DiscoveryInfo_Visibility { + p := new(DiscoveryInfo_Visibility) + *p = x + return p +} +func (x DiscoveryInfo_Visibility) String() string { + return proto.EnumName(DiscoveryInfo_Visibility_name, int32(x)) +} +func (x *DiscoveryInfo_Visibility) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(DiscoveryInfo_Visibility_value, data, "DiscoveryInfo_Visibility") + if err != nil { + return err + } + *x = DiscoveryInfo_Visibility(value) + return nil +} +func (DiscoveryInfo_Visibility) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{59, 0} } + +// * +// A unique ID assigned to a framework. A framework can reuse this ID +// in order to do failover (see MesosSchedulerDriver). +type FrameworkID struct { + Value *string `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *FrameworkID) Reset() { *m = FrameworkID{} } +func (m *FrameworkID) String() string { return proto.CompactTextString(m) } +func (*FrameworkID) ProtoMessage() {} +func (*FrameworkID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *FrameworkID) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +// * +// A unique ID assigned to an offer. +type OfferID struct { + Value *string `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OfferID) Reset() { *m = OfferID{} } +func (m *OfferID) String() string { return proto.CompactTextString(m) } +func (*OfferID) ProtoMessage() {} +func (*OfferID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *OfferID) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +// * +// A unique ID assigned to an agent. Currently, an agent gets a new ID +// whenever it (re)registers with Mesos. Framework writers shouldn't +// assume any binding between an agent ID and and a hostname. +type AgentID struct { + Value *string `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *AgentID) Reset() { *m = AgentID{} } +func (m *AgentID) String() string { return proto.CompactTextString(m) } +func (*AgentID) ProtoMessage() {} +func (*AgentID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *AgentID) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +// * +// A framework-generated ID to distinguish a task. The ID must remain +// unique while the task is active. A framework can reuse an ID _only_ +// if the previous task with the same ID has reached a terminal state +// (e.g., TASK_FINISHED, TASK_LOST, TASK_KILLED, etc.). However, +// reusing task IDs is strongly discouraged (MESOS-2198). +type TaskID struct { + Value *string `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *TaskID) Reset() { *m = TaskID{} } +func (m *TaskID) String() string { return proto.CompactTextString(m) } +func (*TaskID) ProtoMessage() {} +func (*TaskID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +func (m *TaskID) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +// * +// A framework-generated ID to distinguish an executor. Only one +// executor with the same ID can be active on the same agent at a +// time. However, reusing executor IDs is discouraged. +type ExecutorID struct { + Value *string `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ExecutorID) Reset() { *m = ExecutorID{} } +func (m *ExecutorID) String() string { return proto.CompactTextString(m) } +func (*ExecutorID) ProtoMessage() {} +func (*ExecutorID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } + +func (m *ExecutorID) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +// * +// ID used to uniquely identify a container. If the `parent` is not +// specified, the ID is a UUID generated by the agent to uniquely +// identify the container of an executor run. If the `parent` field is +// specified, it represents a nested container. +type ContainerID struct { + Value *string `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` + Parent *ContainerID `protobuf:"bytes,2,opt,name=parent" json:"parent,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ContainerID) Reset() { *m = ContainerID{} } +func (m *ContainerID) String() string { return proto.CompactTextString(m) } +func (*ContainerID) ProtoMessage() {} +func (*ContainerID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } + +func (m *ContainerID) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +func (m *ContainerID) GetParent() *ContainerID { + if m != nil { + return m.Parent + } + return nil +} + +// * +// Represents time since the epoch, in nanoseconds. +type TimeInfo struct { + Nanoseconds *int64 `protobuf:"varint,1,req,name=nanoseconds" json:"nanoseconds,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *TimeInfo) Reset() { *m = TimeInfo{} } +func (m *TimeInfo) String() string { return proto.CompactTextString(m) } +func (*TimeInfo) ProtoMessage() {} +func (*TimeInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } + +func (m *TimeInfo) GetNanoseconds() int64 { + if m != nil && m.Nanoseconds != nil { + return *m.Nanoseconds + } + return 0 +} + +// * +// Represents duration in nanoseconds. +type DurationInfo struct { + Nanoseconds *int64 `protobuf:"varint,1,req,name=nanoseconds" json:"nanoseconds,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *DurationInfo) Reset() { *m = DurationInfo{} } +func (m *DurationInfo) String() string { return proto.CompactTextString(m) } +func (*DurationInfo) ProtoMessage() {} +func (*DurationInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } + +func (m *DurationInfo) GetNanoseconds() int64 { + if m != nil && m.Nanoseconds != nil { + return *m.Nanoseconds + } + return 0 +} + +// * +// A network address. +// +// TODO(bmahler): Use this more widely. +type Address struct { + // May contain a hostname, IP address, or both. + Hostname *string `protobuf:"bytes,1,opt,name=hostname" json:"hostname,omitempty"` + Ip *string `protobuf:"bytes,2,opt,name=ip" json:"ip,omitempty"` + Port *int32 `protobuf:"varint,3,req,name=port" json:"port,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Address) Reset() { *m = Address{} } +func (m *Address) String() string { return proto.CompactTextString(m) } +func (*Address) ProtoMessage() {} +func (*Address) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } + +func (m *Address) GetHostname() string { + if m != nil && m.Hostname != nil { + return *m.Hostname + } + return "" +} + +func (m *Address) GetIp() string { + if m != nil && m.Ip != nil { + return *m.Ip + } + return "" +} + +func (m *Address) GetPort() int32 { + if m != nil && m.Port != nil { + return *m.Port + } + return 0 +} + +// * +// Represents a URL. +type URL struct { + Scheme *string `protobuf:"bytes,1,req,name=scheme" json:"scheme,omitempty"` + Address *Address `protobuf:"bytes,2,req,name=address" json:"address,omitempty"` + Path *string `protobuf:"bytes,3,opt,name=path" json:"path,omitempty"` + Query []*Parameter `protobuf:"bytes,4,rep,name=query" json:"query,omitempty"` + Fragment *string `protobuf:"bytes,5,opt,name=fragment" json:"fragment,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *URL) Reset() { *m = URL{} } +func (m *URL) String() string { return proto.CompactTextString(m) } +func (*URL) ProtoMessage() {} +func (*URL) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } + +func (m *URL) GetScheme() string { + if m != nil && m.Scheme != nil { + return *m.Scheme + } + return "" +} + +func (m *URL) GetAddress() *Address { + if m != nil { + return m.Address + } + return nil +} + +func (m *URL) GetPath() string { + if m != nil && m.Path != nil { + return *m.Path + } + return "" +} + +func (m *URL) GetQuery() []*Parameter { + if m != nil { + return m.Query + } + return nil +} + +func (m *URL) GetFragment() string { + if m != nil && m.Fragment != nil { + return *m.Fragment + } + return "" +} + +// * +// Represents an interval, from a given start time over a given duration. +// This interval pertains to an unavailability event, such as maintenance, +// and is not a generic interval. +type Unavailability struct { + Start *TimeInfo `protobuf:"bytes,1,req,name=start" json:"start,omitempty"` + // When added to `start`, this represents the end of the interval. + // If unspecified, the duration is assumed to be infinite. + Duration *DurationInfo `protobuf:"bytes,2,opt,name=duration" json:"duration,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Unavailability) Reset() { *m = Unavailability{} } +func (m *Unavailability) String() string { return proto.CompactTextString(m) } +func (*Unavailability) ProtoMessage() {} +func (*Unavailability) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } + +func (m *Unavailability) GetStart() *TimeInfo { + if m != nil { + return m.Start + } + return nil +} + +func (m *Unavailability) GetDuration() *DurationInfo { + if m != nil { + return m.Duration + } + return nil +} + +// * +// Represents a single machine, which may hold one or more agents. +// +// NOTE: In order to match an agent to a machine, both the `hostname` and +// `ip` must match the values advertised by the agent to the master. +// Hostname is not case-sensitive. +type MachineID struct { + Hostname *string `protobuf:"bytes,1,opt,name=hostname" json:"hostname,omitempty"` + Ip *string `protobuf:"bytes,2,opt,name=ip" json:"ip,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MachineID) Reset() { *m = MachineID{} } +func (m *MachineID) String() string { return proto.CompactTextString(m) } +func (*MachineID) ProtoMessage() {} +func (*MachineID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } + +func (m *MachineID) GetHostname() string { + if m != nil && m.Hostname != nil { + return *m.Hostname + } + return "" +} + +func (m *MachineID) GetIp() string { + if m != nil && m.Ip != nil { + return *m.Ip + } + return "" +} + +// * +// Holds information about a single machine, its `mode`, and any other +// relevant information which may affect the behavior of the machine. +type MachineInfo struct { + Id *MachineID `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` + Mode *MachineInfo_Mode `protobuf:"varint,2,opt,name=mode,enum=mesos.v1.MachineInfo_Mode" json:"mode,omitempty"` + // Signifies that the machine may be unavailable during the given interval. + // See comments in `Unavailability` and for the `unavailability` fields + // in `Offer` and `InverseOffer` for more information. + Unavailability *Unavailability `protobuf:"bytes,3,opt,name=unavailability" json:"unavailability,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MachineInfo) Reset() { *m = MachineInfo{} } +func (m *MachineInfo) String() string { return proto.CompactTextString(m) } +func (*MachineInfo) ProtoMessage() {} +func (*MachineInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } + +func (m *MachineInfo) GetId() *MachineID { + if m != nil { + return m.Id + } + return nil +} + +func (m *MachineInfo) GetMode() MachineInfo_Mode { + if m != nil && m.Mode != nil { + return *m.Mode + } + return MachineInfo_UP +} + +func (m *MachineInfo) GetUnavailability() *Unavailability { + if m != nil { + return m.Unavailability + } + return nil +} + +// * +// Describes a framework. +type FrameworkInfo struct { + // Used to determine the Unix user that an executor or task should be + // launched as. + // + // When using the MesosSchedulerDriver, if the field is set to an + // empty string, it will automagically set it to the current user. + // + // When using the HTTP Scheduler API, the user has to be set + // explicitly. + User *string `protobuf:"bytes,1,req,name=user" json:"user,omitempty"` + // Name of the framework that shows up in the Mesos Web UI. + Name *string `protobuf:"bytes,2,req,name=name" json:"name,omitempty"` + // Note that 'id' is only available after a framework has + // registered, however, it is included here in order to facilitate + // scheduler failover (i.e., if it is set then the + // MesosSchedulerDriver expects the scheduler is performing + // failover). + Id *FrameworkID `protobuf:"bytes,3,opt,name=id" json:"id,omitempty"` + // The amount of time (in seconds) that the master will wait for the + // scheduler to failover before it tears down the framework by + // killing all its tasks/executors. This should be non-zero if a + // framework expects to reconnect after a failure and not lose its + // tasks/executors. + // + // NOTE: To avoid accidental destruction of tasks, production + // frameworks typically set this to a large value (e.g., 1 week). + FailoverTimeout *float64 `protobuf:"fixed64,4,opt,name=failover_timeout,json=failoverTimeout,def=0" json:"failover_timeout,omitempty"` + // If set, agents running tasks started by this framework will write + // the framework pid, executor pids and status updates to disk. If + // the agent exits (e.g., due to a crash or as part of upgrading + // Mesos), this checkpointed data allows the restarted agent to + // reconnect to executors that were started by the old instance of + // the agent. Enabling checkpointing improves fault tolerance, at + // the cost of a (usually small) increase in disk I/O. + Checkpoint *bool `protobuf:"varint,5,opt,name=checkpoint,def=0" json:"checkpoint,omitempty"` + // Used to group frameworks for allocation decisions, depending on + // the allocation policy being used. + Role *string `protobuf:"bytes,6,opt,name=role,def=*" json:"role,omitempty"` + // Used to indicate the current host from which the scheduler is + // registered in the Mesos Web UI. If set to an empty string Mesos + // will automagically set it to the current hostname if one is + // available. + Hostname *string `protobuf:"bytes,7,opt,name=hostname" json:"hostname,omitempty"` + // This field should match the credential's principal the framework + // uses for authentication. This field is used for framework API + // rate limiting and dynamic reservations. It should be set even + // if authentication is not enabled if these features are desired. + Principal *string `protobuf:"bytes,8,opt,name=principal" json:"principal,omitempty"` + // This field allows a framework to advertise its web UI, so that + // the Mesos web UI can link to it. It is expected to be a full URL, + // for example http://my-scheduler.example.com:8080/. + WebuiUrl *string `protobuf:"bytes,9,opt,name=webui_url,json=webuiUrl" json:"webui_url,omitempty"` + // This field allows a framework to advertise its set of + // capabilities (e.g., ability to receive offers for revocable + // resources). + Capabilities []*FrameworkInfo_Capability `protobuf:"bytes,10,rep,name=capabilities" json:"capabilities,omitempty"` + // Labels are free-form key value pairs supplied by the framework + // scheduler (e.g., to describe additional functionality offered by + // the framework). These labels are not interpreted by Mesos itself. + // Labels should not contain duplicate key-value pairs. + Labels *Labels `protobuf:"bytes,11,opt,name=labels" json:"labels,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *FrameworkInfo) Reset() { *m = FrameworkInfo{} } +func (m *FrameworkInfo) String() string { return proto.CompactTextString(m) } +func (*FrameworkInfo) ProtoMessage() {} +func (*FrameworkInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } + +const Default_FrameworkInfo_FailoverTimeout float64 = 0 +const Default_FrameworkInfo_Checkpoint bool = false +const Default_FrameworkInfo_Role string = "*" + +func (m *FrameworkInfo) GetUser() string { + if m != nil && m.User != nil { + return *m.User + } + return "" +} + +func (m *FrameworkInfo) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *FrameworkInfo) GetId() *FrameworkID { + if m != nil { + return m.Id + } + return nil +} + +func (m *FrameworkInfo) GetFailoverTimeout() float64 { + if m != nil && m.FailoverTimeout != nil { + return *m.FailoverTimeout + } + return Default_FrameworkInfo_FailoverTimeout +} + +func (m *FrameworkInfo) GetCheckpoint() bool { + if m != nil && m.Checkpoint != nil { + return *m.Checkpoint + } + return Default_FrameworkInfo_Checkpoint +} + +func (m *FrameworkInfo) GetRole() string { + if m != nil && m.Role != nil { + return *m.Role + } + return Default_FrameworkInfo_Role +} + +func (m *FrameworkInfo) GetHostname() string { + if m != nil && m.Hostname != nil { + return *m.Hostname + } + return "" +} + +func (m *FrameworkInfo) GetPrincipal() string { + if m != nil && m.Principal != nil { + return *m.Principal + } + return "" +} + +func (m *FrameworkInfo) GetWebuiUrl() string { + if m != nil && m.WebuiUrl != nil { + return *m.WebuiUrl + } + return "" +} + +func (m *FrameworkInfo) GetCapabilities() []*FrameworkInfo_Capability { + if m != nil { + return m.Capabilities + } + return nil +} + +func (m *FrameworkInfo) GetLabels() *Labels { + if m != nil { + return m.Labels + } + return nil +} + +type FrameworkInfo_Capability struct { + // Enum fields should be optional, see: MESOS-4997. + Type *FrameworkInfo_Capability_Type `protobuf:"varint,1,opt,name=type,enum=mesos.v1.FrameworkInfo_Capability_Type" json:"type,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *FrameworkInfo_Capability) Reset() { *m = FrameworkInfo_Capability{} } +func (m *FrameworkInfo_Capability) String() string { return proto.CompactTextString(m) } +func (*FrameworkInfo_Capability) ProtoMessage() {} +func (*FrameworkInfo_Capability) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13, 0} } + +func (m *FrameworkInfo_Capability) GetType() FrameworkInfo_Capability_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return FrameworkInfo_Capability_UNKNOWN +} + +// * +// Describes a health check for a task or executor (or any arbitrary +// process/command). A type is picked by specifying one of the +// optional fields. Specifying more than one type is an error. +type HealthCheck struct { + // Amount of time to wait until starting the health checks. + DelaySeconds *float64 `protobuf:"fixed64,2,opt,name=delay_seconds,json=delaySeconds,def=15" json:"delay_seconds,omitempty"` + // Interval between health checks. + IntervalSeconds *float64 `protobuf:"fixed64,3,opt,name=interval_seconds,json=intervalSeconds,def=10" json:"interval_seconds,omitempty"` + // Amount of time to wait for the health check to complete. + TimeoutSeconds *float64 `protobuf:"fixed64,4,opt,name=timeout_seconds,json=timeoutSeconds,def=20" json:"timeout_seconds,omitempty"` + // Number of consecutive failures until signaling kill task. + ConsecutiveFailures *uint32 `protobuf:"varint,5,opt,name=consecutive_failures,json=consecutiveFailures,def=3" json:"consecutive_failures,omitempty"` + // Amount of time to allow failed health checks since launch. + GracePeriodSeconds *float64 `protobuf:"fixed64,6,opt,name=grace_period_seconds,json=gracePeriodSeconds,def=10" json:"grace_period_seconds,omitempty"` + // The type of health check. + Type *HealthCheck_Type `protobuf:"varint,8,opt,name=type,enum=mesos.v1.HealthCheck_Type" json:"type,omitempty"` + // Command health check. + Command *CommandInfo `protobuf:"bytes,7,opt,name=command" json:"command,omitempty"` + // HTTP health check. + Http *HealthCheck_HTTPCheckInfo `protobuf:"bytes,1,opt,name=http" json:"http,omitempty"` + // TCP health check. + Tcp *HealthCheck_TCPCheckInfo `protobuf:"bytes,9,opt,name=tcp" json:"tcp,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *HealthCheck) Reset() { *m = HealthCheck{} } +func (m *HealthCheck) String() string { return proto.CompactTextString(m) } +func (*HealthCheck) ProtoMessage() {} +func (*HealthCheck) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } + +const Default_HealthCheck_DelaySeconds float64 = 15 +const Default_HealthCheck_IntervalSeconds float64 = 10 +const Default_HealthCheck_TimeoutSeconds float64 = 20 +const Default_HealthCheck_ConsecutiveFailures uint32 = 3 +const Default_HealthCheck_GracePeriodSeconds float64 = 10 + +func (m *HealthCheck) GetDelaySeconds() float64 { + if m != nil && m.DelaySeconds != nil { + return *m.DelaySeconds + } + return Default_HealthCheck_DelaySeconds +} + +func (m *HealthCheck) GetIntervalSeconds() float64 { + if m != nil && m.IntervalSeconds != nil { + return *m.IntervalSeconds + } + return Default_HealthCheck_IntervalSeconds +} + +func (m *HealthCheck) GetTimeoutSeconds() float64 { + if m != nil && m.TimeoutSeconds != nil { + return *m.TimeoutSeconds + } + return Default_HealthCheck_TimeoutSeconds +} + +func (m *HealthCheck) GetConsecutiveFailures() uint32 { + if m != nil && m.ConsecutiveFailures != nil { + return *m.ConsecutiveFailures + } + return Default_HealthCheck_ConsecutiveFailures +} + +func (m *HealthCheck) GetGracePeriodSeconds() float64 { + if m != nil && m.GracePeriodSeconds != nil { + return *m.GracePeriodSeconds + } + return Default_HealthCheck_GracePeriodSeconds +} + +func (m *HealthCheck) GetType() HealthCheck_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return HealthCheck_UNKNOWN +} + +func (m *HealthCheck) GetCommand() *CommandInfo { + if m != nil { + return m.Command + } + return nil +} + +func (m *HealthCheck) GetHttp() *HealthCheck_HTTPCheckInfo { + if m != nil { + return m.Http + } + return nil +} + +func (m *HealthCheck) GetTcp() *HealthCheck_TCPCheckInfo { + if m != nil { + return m.Tcp + } + return nil +} + +// Describes an HTTP health check. Sends a GET request to +// scheme://:port/path. Note that is not configurable and is +// resolved automatically, in most cases to 127.0.0.1. Default executors +// treat return codes between 200 and 399 as success; custom executors +// may employ a different strategy, e.g. leveraging the `statuses` field. +type HealthCheck_HTTPCheckInfo struct { + // Currently "http" and "https" are supported. + Scheme *string `protobuf:"bytes,3,opt,name=scheme" json:"scheme,omitempty"` + // Port to send the HTTP request. + Port *uint32 `protobuf:"varint,1,req,name=port" json:"port,omitempty"` + // HTTP request path. + Path *string `protobuf:"bytes,2,opt,name=path" json:"path,omitempty"` + // NOTE: It is up to the custom executor to interpret and act on this + // field. Setting this field has no effect on the default executors. + // + // TODO(haosdent): Deprecate this field when we add better support for + // success and possibly failure statuses, e.g. ranges of success and + // failure statuses. + Statuses []uint32 `protobuf:"varint,4,rep,name=statuses" json:"statuses,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *HealthCheck_HTTPCheckInfo) Reset() { *m = HealthCheck_HTTPCheckInfo{} } +func (m *HealthCheck_HTTPCheckInfo) String() string { return proto.CompactTextString(m) } +func (*HealthCheck_HTTPCheckInfo) ProtoMessage() {} +func (*HealthCheck_HTTPCheckInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14, 0} } + +func (m *HealthCheck_HTTPCheckInfo) GetScheme() string { + if m != nil && m.Scheme != nil { + return *m.Scheme + } + return "" +} + +func (m *HealthCheck_HTTPCheckInfo) GetPort() uint32 { + if m != nil && m.Port != nil { + return *m.Port + } + return 0 +} + +func (m *HealthCheck_HTTPCheckInfo) GetPath() string { + if m != nil && m.Path != nil { + return *m.Path + } + return "" +} + +func (m *HealthCheck_HTTPCheckInfo) GetStatuses() []uint32 { + if m != nil { + return m.Statuses + } + return nil +} + +// Describes a TCP health check, i.e. based on establishing +// a TCP connection to the specified port. +type HealthCheck_TCPCheckInfo struct { + // Port expected to be open. + Port *uint32 `protobuf:"varint,1,req,name=port" json:"port,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *HealthCheck_TCPCheckInfo) Reset() { *m = HealthCheck_TCPCheckInfo{} } +func (m *HealthCheck_TCPCheckInfo) String() string { return proto.CompactTextString(m) } +func (*HealthCheck_TCPCheckInfo) ProtoMessage() {} +func (*HealthCheck_TCPCheckInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14, 1} } + +func (m *HealthCheck_TCPCheckInfo) GetPort() uint32 { + if m != nil && m.Port != nil { + return *m.Port + } + return 0 +} + +// * +// Describes a kill policy for a task. Currently does not express +// different policies (e.g. hitting HTTP endpoints), only controls +// how long to wait between graceful and forcible task kill: +// +// graceful kill --------------> forcible kill +// grace_period +// +// Kill policies are best-effort, because machine failures / forcible +// terminations may occur. +// +// NOTE: For executor-less command-based tasks, the kill is performed +// via sending a signal to the task process: SIGTERM for the graceful +// kill and SIGKILL for the forcible kill. For the docker executor-less +// tasks the grace period is passed to 'docker stop --time'. +type KillPolicy struct { + // The grace period specifies how long to wait before forcibly + // killing the task. It is recommended to attempt to gracefully + // kill the task (and send TASK_KILLING) to indicate that the + // graceful kill is in progress. Once the grace period elapses, + // if the task has not terminated, a forcible kill should occur. + // The task should not assume that it will always be allotted + // the full grace period. For example, the executor may be + // shutdown more quickly by the agent, or failures / forcible + // terminations may occur. + GracePeriod *DurationInfo `protobuf:"bytes,1,opt,name=grace_period,json=gracePeriod" json:"grace_period,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *KillPolicy) Reset() { *m = KillPolicy{} } +func (m *KillPolicy) String() string { return proto.CompactTextString(m) } +func (*KillPolicy) ProtoMessage() {} +func (*KillPolicy) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } + +func (m *KillPolicy) GetGracePeriod() *DurationInfo { + if m != nil { + return m.GracePeriod + } + return nil +} + +// * +// Describes a command, executed via: '/bin/sh -c value'. Any URIs specified +// are fetched before executing the command. If the executable field for an +// uri is set, executable file permission is set on the downloaded file. +// Otherwise, if the downloaded file has a recognized archive extension +// (currently [compressed] tar and zip) it is extracted into the executor's +// working directory. This extraction can be disabled by setting `extract` to +// false. In addition, any environment variables are set before executing +// the command (so they can be used to "parameterize" your command). +type CommandInfo struct { + Uris []*CommandInfo_URI `protobuf:"bytes,1,rep,name=uris" json:"uris,omitempty"` + Environment *Environment `protobuf:"bytes,2,opt,name=environment" json:"environment,omitempty"` + // There are two ways to specify the command: + // 1) If 'shell == true', the command will be launched via shell + // (i.e., /bin/sh -c 'value'). The 'value' specified will be + // treated as the shell command. The 'arguments' will be ignored. + // 2) If 'shell == false', the command will be launched by passing + // arguments to an executable. The 'value' specified will be + // treated as the filename of the executable. The 'arguments' + // will be treated as the arguments to the executable. This is + // similar to how POSIX exec families launch processes (i.e., + // execlp(value, arguments(0), arguments(1), ...)). + // NOTE: The field 'value' is changed from 'required' to 'optional' + // in 0.20.0. It will only cause issues if a new framework is + // connecting to an old master. + Shell *bool `protobuf:"varint,6,opt,name=shell,def=1" json:"shell,omitempty"` + Value *string `protobuf:"bytes,3,opt,name=value" json:"value,omitempty"` + Arguments []string `protobuf:"bytes,7,rep,name=arguments" json:"arguments,omitempty"` + // Enables executor and tasks to run as a specific user. If the user + // field is present both in FrameworkInfo and here, the CommandInfo + // user value takes precedence. + User *string `protobuf:"bytes,5,opt,name=user" json:"user,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *CommandInfo) Reset() { *m = CommandInfo{} } +func (m *CommandInfo) String() string { return proto.CompactTextString(m) } +func (*CommandInfo) ProtoMessage() {} +func (*CommandInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } + +const Default_CommandInfo_Shell bool = true + +func (m *CommandInfo) GetUris() []*CommandInfo_URI { + if m != nil { + return m.Uris + } + return nil +} + +func (m *CommandInfo) GetEnvironment() *Environment { + if m != nil { + return m.Environment + } + return nil +} + +func (m *CommandInfo) GetShell() bool { + if m != nil && m.Shell != nil { + return *m.Shell + } + return Default_CommandInfo_Shell +} + +func (m *CommandInfo) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +func (m *CommandInfo) GetArguments() []string { + if m != nil { + return m.Arguments + } + return nil +} + +func (m *CommandInfo) GetUser() string { + if m != nil && m.User != nil { + return *m.User + } + return "" +} + +type CommandInfo_URI struct { + Value *string `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` + Executable *bool `protobuf:"varint,2,opt,name=executable" json:"executable,omitempty"` + // In case the fetched file is recognized as an archive, extract + // its contents into the sandbox. Note that a cached archive is + // not copied from the cache to the sandbox in case extraction + // originates from an archive in the cache. + Extract *bool `protobuf:"varint,3,opt,name=extract,def=1" json:"extract,omitempty"` + // If this field is "true", the fetcher cache will be used. If not, + // fetching bypasses the cache and downloads directly into the + // sandbox directory, no matter whether a suitable cache file is + // available or not. The former directs the fetcher to download to + // the file cache, then copy from there to the sandbox. Subsequent + // fetch attempts with the same URI will omit downloading and copy + // from the cache as long as the file is resident there. Cache files + // may get evicted at any time, which then leads to renewed + // downloading. See also "docs/fetcher.md" and + // "docs/fetcher-cache-internals.md". + Cache *bool `protobuf:"varint,4,opt,name=cache" json:"cache,omitempty"` + // The fetcher's default behavior is to use the URI string's basename to + // name the local copy. If this field is provided, the local copy will be + // named with its value instead. If there is a directory component (which + // must be a relative path), the local copy will be stored in that + // subdirectory inside the sandbox. + OutputFile *string `protobuf:"bytes,5,opt,name=output_file,json=outputFile" json:"output_file,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *CommandInfo_URI) Reset() { *m = CommandInfo_URI{} } +func (m *CommandInfo_URI) String() string { return proto.CompactTextString(m) } +func (*CommandInfo_URI) ProtoMessage() {} +func (*CommandInfo_URI) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16, 0} } + +const Default_CommandInfo_URI_Extract bool = true + +func (m *CommandInfo_URI) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +func (m *CommandInfo_URI) GetExecutable() bool { + if m != nil && m.Executable != nil { + return *m.Executable + } + return false +} + +func (m *CommandInfo_URI) GetExtract() bool { + if m != nil && m.Extract != nil { + return *m.Extract + } + return Default_CommandInfo_URI_Extract +} + +func (m *CommandInfo_URI) GetCache() bool { + if m != nil && m.Cache != nil { + return *m.Cache + } + return false +} + +func (m *CommandInfo_URI) GetOutputFile() string { + if m != nil && m.OutputFile != nil { + return *m.OutputFile + } + return "" +} + +// * +// Describes information about an executor. +type ExecutorInfo struct { + // For backwards compatibility, if this field is not set when using `LAUNCH` + // offer operation, Mesos will infer the type by checking if `command` is + // set (`CUSTOM`) or unset (`DEFAULT`). `type` must be set when using + // `LAUNCH_GROUP` offer operation. + // + // TODO(vinod): Add support for explicitly setting `type` to `DEFAULT ` + // in `LAUNCH` offer operation. + Type *ExecutorInfo_Type `protobuf:"varint,15,opt,name=type,enum=mesos.v1.ExecutorInfo_Type" json:"type,omitempty"` + ExecutorId *ExecutorID `protobuf:"bytes,1,req,name=executor_id,json=executorId" json:"executor_id,omitempty"` + FrameworkId *FrameworkID `protobuf:"bytes,8,opt,name=framework_id,json=frameworkId" json:"framework_id,omitempty"` + Command *CommandInfo `protobuf:"bytes,7,opt,name=command" json:"command,omitempty"` + // Executor provided with a container will launch the container + // with the executor's CommandInfo and we expect the container to + // act as a Mesos executor. + Container *ContainerInfo `protobuf:"bytes,11,opt,name=container" json:"container,omitempty"` + Resources []*Resource `protobuf:"bytes,5,rep,name=resources" json:"resources,omitempty"` + Name *string `protobuf:"bytes,9,opt,name=name" json:"name,omitempty"` + // 'source' is an identifier style string used by frameworks to + // track the source of an executor. This is useful when it's + // possible for different executor ids to be related semantically. + // + // NOTE: 'source' is exposed alongside the resource usage of the + // executor via JSON on the agent. This allows users to import usage + // information into a time series database for monitoring. + // + // This field is deprecated since 1.0. Please use labels for + // free-form metadata instead. + Source *string `protobuf:"bytes,10,opt,name=source" json:"source,omitempty"` + // This field can be used to pass arbitrary bytes to an executor. + Data []byte `protobuf:"bytes,4,opt,name=data" json:"data,omitempty"` + // Service discovery information for the executor. It is not + // interpreted or acted upon by Mesos. It is up to a service + // discovery system to use this information as needed and to handle + // executors without service discovery information. + Discovery *DiscoveryInfo `protobuf:"bytes,12,opt,name=discovery" json:"discovery,omitempty"` + // When shutting down an executor the agent will wait in a + // best-effort manner for the grace period specified here + // before forcibly destroying the container. The executor + // must not assume that it will always be allotted the full + // grace period, as the agent may decide to allot a shorter + // period and failures / forcible terminations may occur. + ShutdownGracePeriod *DurationInfo `protobuf:"bytes,13,opt,name=shutdown_grace_period,json=shutdownGracePeriod" json:"shutdown_grace_period,omitempty"` + // Labels are free-form key value pairs which are exposed through + // master and agent endpoints. Labels will not be interpreted or + // acted upon by Mesos itself. As opposed to the data field, labels + // will be kept in memory on master and agent processes. Therefore, + // labels should be used to tag executors with lightweight metadata. + // Labels should not contain duplicate key-value pairs. + Labels *Labels `protobuf:"bytes,14,opt,name=labels" json:"labels,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ExecutorInfo) Reset() { *m = ExecutorInfo{} } +func (m *ExecutorInfo) String() string { return proto.CompactTextString(m) } +func (*ExecutorInfo) ProtoMessage() {} +func (*ExecutorInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } + +func (m *ExecutorInfo) GetType() ExecutorInfo_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return ExecutorInfo_UNKNOWN +} + +func (m *ExecutorInfo) GetExecutorId() *ExecutorID { + if m != nil { + return m.ExecutorId + } + return nil +} + +func (m *ExecutorInfo) GetFrameworkId() *FrameworkID { + if m != nil { + return m.FrameworkId + } + return nil +} + +func (m *ExecutorInfo) GetCommand() *CommandInfo { + if m != nil { + return m.Command + } + return nil +} + +func (m *ExecutorInfo) GetContainer() *ContainerInfo { + if m != nil { + return m.Container + } + return nil +} + +func (m *ExecutorInfo) GetResources() []*Resource { + if m != nil { + return m.Resources + } + return nil +} + +func (m *ExecutorInfo) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *ExecutorInfo) GetSource() string { + if m != nil && m.Source != nil { + return *m.Source + } + return "" +} + +func (m *ExecutorInfo) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *ExecutorInfo) GetDiscovery() *DiscoveryInfo { + if m != nil { + return m.Discovery + } + return nil +} + +func (m *ExecutorInfo) GetShutdownGracePeriod() *DurationInfo { + if m != nil { + return m.ShutdownGracePeriod + } + return nil +} + +func (m *ExecutorInfo) GetLabels() *Labels { + if m != nil { + return m.Labels + } + return nil +} + +// * +// Describes a master. This will probably have more fields in the +// future which might be used, for example, to link a framework webui +// to a master webui. +type MasterInfo struct { + Id *string `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` + // The IP address (only IPv4) as a packed 4-bytes integer, + // stored in network order. Deprecated, use `address.ip` instead. + Ip *uint32 `protobuf:"varint,2,req,name=ip" json:"ip,omitempty"` + // The TCP port the Master is listening on for incoming + // HTTP requests; deprecated, use `address.port` instead. + Port *uint32 `protobuf:"varint,3,req,name=port,def=5050" json:"port,omitempty"` + // In the default implementation, this will contain information + // about both the IP address, port and Master name; it should really + // not be relied upon by external tooling/frameworks and be + // considered an "internal" implementation field. + Pid *string `protobuf:"bytes,4,opt,name=pid" json:"pid,omitempty"` + // The server's hostname, if available; it may be unreliable + // in environments where the DNS configuration does not resolve + // internal hostnames (eg, some public cloud providers). + // Deprecated, use `address.hostname` instead. + Hostname *string `protobuf:"bytes,5,opt,name=hostname" json:"hostname,omitempty"` + // The running Master version, as a string; taken from the + // generated "master/version.hpp". + Version *string `protobuf:"bytes,6,opt,name=version" json:"version,omitempty"` + // The full IP address (supports both IPv4 and IPv6 formats) + // and supersedes the use of `ip`, `port` and `hostname`. + // Since Mesos 0.24. + Address *Address `protobuf:"bytes,7,opt,name=address" json:"address,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MasterInfo) Reset() { *m = MasterInfo{} } +func (m *MasterInfo) String() string { return proto.CompactTextString(m) } +func (*MasterInfo) ProtoMessage() {} +func (*MasterInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } + +const Default_MasterInfo_Port uint32 = 5050 + +func (m *MasterInfo) GetId() string { + if m != nil && m.Id != nil { + return *m.Id + } + return "" +} + +func (m *MasterInfo) GetIp() uint32 { + if m != nil && m.Ip != nil { + return *m.Ip + } + return 0 +} + +func (m *MasterInfo) GetPort() uint32 { + if m != nil && m.Port != nil { + return *m.Port + } + return Default_MasterInfo_Port +} + +func (m *MasterInfo) GetPid() string { + if m != nil && m.Pid != nil { + return *m.Pid + } + return "" +} + +func (m *MasterInfo) GetHostname() string { + if m != nil && m.Hostname != nil { + return *m.Hostname + } + return "" +} + +func (m *MasterInfo) GetVersion() string { + if m != nil && m.Version != nil { + return *m.Version + } + return "" +} + +func (m *MasterInfo) GetAddress() *Address { + if m != nil { + return m.Address + } + return nil +} + +// * +// Describes an agent. Note that the 'id' field is only available +// after an agent is registered with the master, and is made available +// here to facilitate re-registration. +type AgentInfo struct { + Hostname *string `protobuf:"bytes,1,req,name=hostname" json:"hostname,omitempty"` + Port *int32 `protobuf:"varint,8,opt,name=port,def=5051" json:"port,omitempty"` + Resources []*Resource `protobuf:"bytes,3,rep,name=resources" json:"resources,omitempty"` + Attributes []*Attribute `protobuf:"bytes,5,rep,name=attributes" json:"attributes,omitempty"` + Id *AgentID `protobuf:"bytes,6,opt,name=id" json:"id,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *AgentInfo) Reset() { *m = AgentInfo{} } +func (m *AgentInfo) String() string { return proto.CompactTextString(m) } +func (*AgentInfo) ProtoMessage() {} +func (*AgentInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } + +const Default_AgentInfo_Port int32 = 5051 + +func (m *AgentInfo) GetHostname() string { + if m != nil && m.Hostname != nil { + return *m.Hostname + } + return "" +} + +func (m *AgentInfo) GetPort() int32 { + if m != nil && m.Port != nil { + return *m.Port + } + return Default_AgentInfo_Port +} + +func (m *AgentInfo) GetResources() []*Resource { + if m != nil { + return m.Resources + } + return nil +} + +func (m *AgentInfo) GetAttributes() []*Attribute { + if m != nil { + return m.Attributes + } + return nil +} + +func (m *AgentInfo) GetId() *AgentID { + if m != nil { + return m.Id + } + return nil +} + +// * +// Describes an Attribute or Resource "value". A value is described +// using the standard protocol buffer "union" trick. +type Value struct { + Type *Value_Type `protobuf:"varint,1,req,name=type,enum=mesos.v1.Value_Type" json:"type,omitempty"` + Scalar *Value_Scalar `protobuf:"bytes,2,opt,name=scalar" json:"scalar,omitempty"` + Ranges *Value_Ranges `protobuf:"bytes,3,opt,name=ranges" json:"ranges,omitempty"` + Set *Value_Set `protobuf:"bytes,4,opt,name=set" json:"set,omitempty"` + Text *Value_Text `protobuf:"bytes,5,opt,name=text" json:"text,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Value) Reset() { *m = Value{} } +func (m *Value) String() string { return proto.CompactTextString(m) } +func (*Value) ProtoMessage() {} +func (*Value) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } + +func (m *Value) GetType() Value_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return Value_SCALAR +} + +func (m *Value) GetScalar() *Value_Scalar { + if m != nil { + return m.Scalar + } + return nil +} + +func (m *Value) GetRanges() *Value_Ranges { + if m != nil { + return m.Ranges + } + return nil +} + +func (m *Value) GetSet() *Value_Set { + if m != nil { + return m.Set + } + return nil +} + +func (m *Value) GetText() *Value_Text { + if m != nil { + return m.Text + } + return nil +} + +type Value_Scalar struct { + // Scalar values are represented using floating point. To reduce + // the chance of unpredictable floating point behavior due to + // roundoff error, Mesos only supports three decimal digits of + // precision for scalar resource values. That is, floating point + // values are converted to a fixed point format that supports + // three decimal digits of precision, and then converted back to + // floating point on output. Any additional precision in scalar + // resource values is discarded (via rounding). + Value *float64 `protobuf:"fixed64,1,req,name=value" json:"value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Value_Scalar) Reset() { *m = Value_Scalar{} } +func (m *Value_Scalar) String() string { return proto.CompactTextString(m) } +func (*Value_Scalar) ProtoMessage() {} +func (*Value_Scalar) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20, 0} } + +func (m *Value_Scalar) GetValue() float64 { + if m != nil && m.Value != nil { + return *m.Value + } + return 0 +} + +type Value_Range struct { + Begin *uint64 `protobuf:"varint,1,req,name=begin" json:"begin,omitempty"` + End *uint64 `protobuf:"varint,2,req,name=end" json:"end,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Value_Range) Reset() { *m = Value_Range{} } +func (m *Value_Range) String() string { return proto.CompactTextString(m) } +func (*Value_Range) ProtoMessage() {} +func (*Value_Range) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20, 1} } + +func (m *Value_Range) GetBegin() uint64 { + if m != nil && m.Begin != nil { + return *m.Begin + } + return 0 +} + +func (m *Value_Range) GetEnd() uint64 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +type Value_Ranges struct { + Range []*Value_Range `protobuf:"bytes,1,rep,name=range" json:"range,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Value_Ranges) Reset() { *m = Value_Ranges{} } +func (m *Value_Ranges) String() string { return proto.CompactTextString(m) } +func (*Value_Ranges) ProtoMessage() {} +func (*Value_Ranges) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20, 2} } + +func (m *Value_Ranges) GetRange() []*Value_Range { + if m != nil { + return m.Range + } + return nil +} + +type Value_Set struct { + Item []string `protobuf:"bytes,1,rep,name=item" json:"item,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Value_Set) Reset() { *m = Value_Set{} } +func (m *Value_Set) String() string { return proto.CompactTextString(m) } +func (*Value_Set) ProtoMessage() {} +func (*Value_Set) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20, 3} } + +func (m *Value_Set) GetItem() []string { + if m != nil { + return m.Item + } + return nil +} + +type Value_Text struct { + Value *string `protobuf:"bytes,1,req,name=value" json:"value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Value_Text) Reset() { *m = Value_Text{} } +func (m *Value_Text) String() string { return proto.CompactTextString(m) } +func (*Value_Text) ProtoMessage() {} +func (*Value_Text) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20, 4} } + +func (m *Value_Text) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +// * +// Describes an attribute that can be set on a machine. For now, +// attributes and resources share the same "value" type, but this may +// change in the future and attributes may only be string based. +type Attribute struct { + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + Type *Value_Type `protobuf:"varint,2,req,name=type,enum=mesos.v1.Value_Type" json:"type,omitempty"` + Scalar *Value_Scalar `protobuf:"bytes,3,opt,name=scalar" json:"scalar,omitempty"` + Ranges *Value_Ranges `protobuf:"bytes,4,opt,name=ranges" json:"ranges,omitempty"` + Set *Value_Set `protobuf:"bytes,6,opt,name=set" json:"set,omitempty"` + Text *Value_Text `protobuf:"bytes,5,opt,name=text" json:"text,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Attribute) Reset() { *m = Attribute{} } +func (m *Attribute) String() string { return proto.CompactTextString(m) } +func (*Attribute) ProtoMessage() {} +func (*Attribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } + +func (m *Attribute) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Attribute) GetType() Value_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return Value_SCALAR +} + +func (m *Attribute) GetScalar() *Value_Scalar { + if m != nil { + return m.Scalar + } + return nil +} + +func (m *Attribute) GetRanges() *Value_Ranges { + if m != nil { + return m.Ranges + } + return nil +} + +func (m *Attribute) GetSet() *Value_Set { + if m != nil { + return m.Set + } + return nil +} + +func (m *Attribute) GetText() *Value_Text { + if m != nil { + return m.Text + } + return nil +} + +// * +// Describes a resource on a machine. The `name` field is a string +// like "cpus" or "mem" that indicates which kind of resource this is; +// the rest of the fields describe the properties of the resource. A +// resource can take on one of three types: scalar (double), a list of +// finite and discrete ranges (e.g., [1-10, 20-30]), or a set of +// items. A resource is described using the standard protocol buffer +// "union" trick. +// +// Note that "disk" and "mem" resources are scalar values expressed in +// megabytes. Fractional "cpus" values are allowed (e.g., "0.5"), +// which correspond to partial shares of a CPU. +type Resource struct { + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + Type *Value_Type `protobuf:"varint,2,req,name=type,enum=mesos.v1.Value_Type" json:"type,omitempty"` + Scalar *Value_Scalar `protobuf:"bytes,3,opt,name=scalar" json:"scalar,omitempty"` + Ranges *Value_Ranges `protobuf:"bytes,4,opt,name=ranges" json:"ranges,omitempty"` + Set *Value_Set `protobuf:"bytes,5,opt,name=set" json:"set,omitempty"` + // The role that this resource is reserved for. If "*", this indicates + // that the resource is unreserved. Otherwise, the resource will only + // be offered to frameworks that belong to this role. + Role *string `protobuf:"bytes,6,opt,name=role,def=*" json:"role,omitempty"` + // If this is set, this resource was dynamically reserved by an + // operator or a framework. Otherwise, this resource is either unreserved + // or statically reserved by an operator via the --resources flag. + Reservation *Resource_ReservationInfo `protobuf:"bytes,8,opt,name=reservation" json:"reservation,omitempty"` + Disk *Resource_DiskInfo `protobuf:"bytes,7,opt,name=disk" json:"disk,omitempty"` + // If this is set, the resources are revocable, i.e., any tasks or + // executors launched using these resources could get preempted or + // throttled at any time. This could be used by frameworks to run + // best effort tasks that do not need strict uptime or performance + // guarantees. Note that if this is set, 'disk' or 'reservation' + // cannot be set. + Revocable *Resource_RevocableInfo `protobuf:"bytes,9,opt,name=revocable" json:"revocable,omitempty"` + // If this is set, the resources are shared, i.e. multiple tasks + // can be launched using this resource and all of them shall refer + // to the same physical resource on the cluster. Note that only + // persistent volumes can be shared currently. + Shared *Resource_SharedInfo `protobuf:"bytes,10,opt,name=shared" json:"shared,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Resource) Reset() { *m = Resource{} } +func (m *Resource) String() string { return proto.CompactTextString(m) } +func (*Resource) ProtoMessage() {} +func (*Resource) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } + +const Default_Resource_Role string = "*" + +func (m *Resource) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Resource) GetType() Value_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return Value_SCALAR +} + +func (m *Resource) GetScalar() *Value_Scalar { + if m != nil { + return m.Scalar + } + return nil +} + +func (m *Resource) GetRanges() *Value_Ranges { + if m != nil { + return m.Ranges + } + return nil +} + +func (m *Resource) GetSet() *Value_Set { + if m != nil { + return m.Set + } + return nil +} + +func (m *Resource) GetRole() string { + if m != nil && m.Role != nil { + return *m.Role + } + return Default_Resource_Role +} + +func (m *Resource) GetReservation() *Resource_ReservationInfo { + if m != nil { + return m.Reservation + } + return nil +} + +func (m *Resource) GetDisk() *Resource_DiskInfo { + if m != nil { + return m.Disk + } + return nil +} + +func (m *Resource) GetRevocable() *Resource_RevocableInfo { + if m != nil { + return m.Revocable + } + return nil +} + +func (m *Resource) GetShared() *Resource_SharedInfo { + if m != nil { + return m.Shared + } + return nil +} + +type Resource_ReservationInfo struct { + // Indicates the principal, if any, of the framework or operator + // that reserved this resource. If reserved by a framework, the + // field should match the `FrameworkInfo.principal`. It is used in + // conjunction with the `UnreserveResources` ACL to determine + // whether the entity attempting to unreserve this resource is + // permitted to do so. + Principal *string `protobuf:"bytes,1,opt,name=principal" json:"principal,omitempty"` + // Labels are free-form key value pairs that can be used to + // associate arbitrary metadata with a reserved resource. For + // example, frameworks can use labels to identify the intended + // purpose for a portion of the resources the framework has + // reserved at a given agent. Labels should not contain duplicate + // key-value pairs. + Labels *Labels `protobuf:"bytes,2,opt,name=labels" json:"labels,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Resource_ReservationInfo) Reset() { *m = Resource_ReservationInfo{} } +func (m *Resource_ReservationInfo) String() string { return proto.CompactTextString(m) } +func (*Resource_ReservationInfo) ProtoMessage() {} +func (*Resource_ReservationInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22, 0} } + +func (m *Resource_ReservationInfo) GetPrincipal() string { + if m != nil && m.Principal != nil { + return *m.Principal + } + return "" +} + +func (m *Resource_ReservationInfo) GetLabels() *Labels { + if m != nil { + return m.Labels + } + return nil +} + +type Resource_DiskInfo struct { + Persistence *Resource_DiskInfo_Persistence `protobuf:"bytes,1,opt,name=persistence" json:"persistence,omitempty"` + // Describes how this disk resource will be mounted in the + // container. If not set, the disk resource will be used as the + // sandbox. Otherwise, it will be mounted according to the + // 'container_path' inside 'volume'. The 'host_path' inside + // 'volume' is ignored. + // NOTE: If 'volume' is set but 'persistence' is not set, the + // volume will be automatically garbage collected after + // task/executor terminates. Currently, if 'persistence' is set, + // 'volume' must be set. + Volume *Volume `protobuf:"bytes,2,opt,name=volume" json:"volume,omitempty"` + Source *Resource_DiskInfo_Source `protobuf:"bytes,3,opt,name=source" json:"source,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Resource_DiskInfo) Reset() { *m = Resource_DiskInfo{} } +func (m *Resource_DiskInfo) String() string { return proto.CompactTextString(m) } +func (*Resource_DiskInfo) ProtoMessage() {} +func (*Resource_DiskInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22, 1} } + +func (m *Resource_DiskInfo) GetPersistence() *Resource_DiskInfo_Persistence { + if m != nil { + return m.Persistence + } + return nil +} + +func (m *Resource_DiskInfo) GetVolume() *Volume { + if m != nil { + return m.Volume + } + return nil +} + +func (m *Resource_DiskInfo) GetSource() *Resource_DiskInfo_Source { + if m != nil { + return m.Source + } + return nil +} + +// Describes a persistent disk volume. +// +// A persistent disk volume will not be automatically garbage +// collected if the task/executor/agent terminates, but will be +// re-offered to the framework(s) belonging to the 'role'. +// +// NOTE: Currently, we do not allow persistent disk volumes +// without a reservation (i.e., 'role' cannot be '*'). +type Resource_DiskInfo_Persistence struct { + // A unique ID for the persistent disk volume. This ID must be + // unique per role on each agent. Although it is possible to use + // the same ID on different agents in the cluster and to reuse + // IDs after a volume with that ID has been destroyed, both + // practices are discouraged. + Id *string `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` + // This field indicates the principal of the operator or + // framework that created this volume. It is used in conjunction + // with the "destroy" ACL to determine whether an entity + // attempting to destroy the volume is permitted to do so. + // + // NOTE: This field is optional, while the `principal` found in + // `ReservationInfo` is required. This field is optional to + // allow for the possibility of volume creation without a + // principal, though currently it must be provided. + // + // NOTE: This field should match the FrameworkInfo.principal of + // the framework that created the volume. + Principal *string `protobuf:"bytes,2,opt,name=principal" json:"principal,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Resource_DiskInfo_Persistence) Reset() { *m = Resource_DiskInfo_Persistence{} } +func (m *Resource_DiskInfo_Persistence) String() string { return proto.CompactTextString(m) } +func (*Resource_DiskInfo_Persistence) ProtoMessage() {} +func (*Resource_DiskInfo_Persistence) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{22, 1, 0} +} + +func (m *Resource_DiskInfo_Persistence) GetId() string { + if m != nil && m.Id != nil { + return *m.Id + } + return "" +} + +func (m *Resource_DiskInfo_Persistence) GetPrincipal() string { + if m != nil && m.Principal != nil { + return *m.Principal + } + return "" +} + +// Describes where a disk originates from. +// TODO(jmlvanre): Add support for BLOCK devices. +type Resource_DiskInfo_Source struct { + Type *Resource_DiskInfo_Source_Type `protobuf:"varint,1,req,name=type,enum=mesos.v1.Resource_DiskInfo_Source_Type" json:"type,omitempty"` + Path *Resource_DiskInfo_Source_Path `protobuf:"bytes,2,opt,name=path" json:"path,omitempty"` + Mount *Resource_DiskInfo_Source_Mount `protobuf:"bytes,3,opt,name=mount" json:"mount,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Resource_DiskInfo_Source) Reset() { *m = Resource_DiskInfo_Source{} } +func (m *Resource_DiskInfo_Source) String() string { return proto.CompactTextString(m) } +func (*Resource_DiskInfo_Source) ProtoMessage() {} +func (*Resource_DiskInfo_Source) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22, 1, 1} } + +func (m *Resource_DiskInfo_Source) GetType() Resource_DiskInfo_Source_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return Resource_DiskInfo_Source_PATH +} + +func (m *Resource_DiskInfo_Source) GetPath() *Resource_DiskInfo_Source_Path { + if m != nil { + return m.Path + } + return nil +} + +func (m *Resource_DiskInfo_Source) GetMount() *Resource_DiskInfo_Source_Mount { + if m != nil { + return m.Mount + } + return nil +} + +// A folder that can be located on a separate disk device. This +// can be shared and carved up as necessary between frameworks. +type Resource_DiskInfo_Source_Path struct { + // Path to the folder (e.g., /mnt/raid/disk0). + Root *string `protobuf:"bytes,1,req,name=root" json:"root,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Resource_DiskInfo_Source_Path) Reset() { *m = Resource_DiskInfo_Source_Path{} } +func (m *Resource_DiskInfo_Source_Path) String() string { return proto.CompactTextString(m) } +func (*Resource_DiskInfo_Source_Path) ProtoMessage() {} +func (*Resource_DiskInfo_Source_Path) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{22, 1, 1, 0} +} + +func (m *Resource_DiskInfo_Source_Path) GetRoot() string { + if m != nil && m.Root != nil { + return *m.Root + } + return "" +} + +// A mounted file-system set up by the Agent administrator. This +// can only be used exclusively: a framework cannot accept a +// partial amount of this disk. +type Resource_DiskInfo_Source_Mount struct { + // Path to mount point (e.g., /mnt/raid/disk0). + Root *string `protobuf:"bytes,1,req,name=root" json:"root,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Resource_DiskInfo_Source_Mount) Reset() { *m = Resource_DiskInfo_Source_Mount{} } +func (m *Resource_DiskInfo_Source_Mount) String() string { return proto.CompactTextString(m) } +func (*Resource_DiskInfo_Source_Mount) ProtoMessage() {} +func (*Resource_DiskInfo_Source_Mount) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{22, 1, 1, 1} +} + +func (m *Resource_DiskInfo_Source_Mount) GetRoot() string { + if m != nil && m.Root != nil { + return *m.Root + } + return "" +} + +type Resource_RevocableInfo struct { + XXX_unrecognized []byte `json:"-"` +} + +func (m *Resource_RevocableInfo) Reset() { *m = Resource_RevocableInfo{} } +func (m *Resource_RevocableInfo) String() string { return proto.CompactTextString(m) } +func (*Resource_RevocableInfo) ProtoMessage() {} +func (*Resource_RevocableInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22, 2} } + +// Allow the resource to be shared across tasks. +type Resource_SharedInfo struct { + XXX_unrecognized []byte `json:"-"` +} + +func (m *Resource_SharedInfo) Reset() { *m = Resource_SharedInfo{} } +func (m *Resource_SharedInfo) String() string { return proto.CompactTextString(m) } +func (*Resource_SharedInfo) ProtoMessage() {} +func (*Resource_SharedInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22, 3} } + +// * +// When the network bandwidth caps are enabled and the container +// is over its limit, outbound packets may be either delayed or +// dropped completely either because it exceeds the maximum bandwidth +// allocation for a single container (the cap) or because the combined +// network traffic of multiple containers on the host exceeds the +// transmit capacity of the host (the share). We can report the +// following statistics for each of these conditions exported directly +// from the Linux Traffic Control Queueing Discipline. +// +// id : name of the limiter, e.g. 'tx_bw_cap' +// backlog : number of packets currently delayed +// bytes : total bytes seen +// drops : number of packets dropped in total +// overlimits : number of packets which exceeded allocation +// packets : total packets seen +// qlen : number of packets currently queued +// rate_bps : throughput in bytes/sec +// rate_pps : throughput in packets/sec +// requeues : number of times a packet has been delayed due to +// locking or device contention issues +// +// More information on the operation of Linux Traffic Control can be +// found at http://www.lartc.org/lartc.html. +type TrafficControlStatistics struct { + Id *string `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` + Backlog *uint64 `protobuf:"varint,2,opt,name=backlog" json:"backlog,omitempty"` + Bytes *uint64 `protobuf:"varint,3,opt,name=bytes" json:"bytes,omitempty"` + Drops *uint64 `protobuf:"varint,4,opt,name=drops" json:"drops,omitempty"` + Overlimits *uint64 `protobuf:"varint,5,opt,name=overlimits" json:"overlimits,omitempty"` + Packets *uint64 `protobuf:"varint,6,opt,name=packets" json:"packets,omitempty"` + Qlen *uint64 `protobuf:"varint,7,opt,name=qlen" json:"qlen,omitempty"` + Ratebps *uint64 `protobuf:"varint,8,opt,name=ratebps" json:"ratebps,omitempty"` + Ratepps *uint64 `protobuf:"varint,9,opt,name=ratepps" json:"ratepps,omitempty"` + Requeues *uint64 `protobuf:"varint,10,opt,name=requeues" json:"requeues,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *TrafficControlStatistics) Reset() { *m = TrafficControlStatistics{} } +func (m *TrafficControlStatistics) String() string { return proto.CompactTextString(m) } +func (*TrafficControlStatistics) ProtoMessage() {} +func (*TrafficControlStatistics) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } + +func (m *TrafficControlStatistics) GetId() string { + if m != nil && m.Id != nil { + return *m.Id + } + return "" +} + +func (m *TrafficControlStatistics) GetBacklog() uint64 { + if m != nil && m.Backlog != nil { + return *m.Backlog + } + return 0 +} + +func (m *TrafficControlStatistics) GetBytes() uint64 { + if m != nil && m.Bytes != nil { + return *m.Bytes + } + return 0 +} + +func (m *TrafficControlStatistics) GetDrops() uint64 { + if m != nil && m.Drops != nil { + return *m.Drops + } + return 0 +} + +func (m *TrafficControlStatistics) GetOverlimits() uint64 { + if m != nil && m.Overlimits != nil { + return *m.Overlimits + } + return 0 +} + +func (m *TrafficControlStatistics) GetPackets() uint64 { + if m != nil && m.Packets != nil { + return *m.Packets + } + return 0 +} + +func (m *TrafficControlStatistics) GetQlen() uint64 { + if m != nil && m.Qlen != nil { + return *m.Qlen + } + return 0 +} + +func (m *TrafficControlStatistics) GetRatebps() uint64 { + if m != nil && m.Ratebps != nil { + return *m.Ratebps + } + return 0 +} + +func (m *TrafficControlStatistics) GetRatepps() uint64 { + if m != nil && m.Ratepps != nil { + return *m.Ratepps + } + return 0 +} + +func (m *TrafficControlStatistics) GetRequeues() uint64 { + if m != nil && m.Requeues != nil { + return *m.Requeues + } + return 0 +} + +type IpStatistics struct { + Forwarding *int64 `protobuf:"varint,1,opt,name=Forwarding" json:"Forwarding,omitempty"` + DefaultTTL *int64 `protobuf:"varint,2,opt,name=DefaultTTL" json:"DefaultTTL,omitempty"` + InReceives *int64 `protobuf:"varint,3,opt,name=InReceives" json:"InReceives,omitempty"` + InHdrErrors *int64 `protobuf:"varint,4,opt,name=InHdrErrors" json:"InHdrErrors,omitempty"` + InAddrErrors *int64 `protobuf:"varint,5,opt,name=InAddrErrors" json:"InAddrErrors,omitempty"` + ForwDatagrams *int64 `protobuf:"varint,6,opt,name=ForwDatagrams" json:"ForwDatagrams,omitempty"` + InUnknownProtos *int64 `protobuf:"varint,7,opt,name=InUnknownProtos" json:"InUnknownProtos,omitempty"` + InDiscards *int64 `protobuf:"varint,8,opt,name=InDiscards" json:"InDiscards,omitempty"` + InDelivers *int64 `protobuf:"varint,9,opt,name=InDelivers" json:"InDelivers,omitempty"` + OutRequests *int64 `protobuf:"varint,10,opt,name=OutRequests" json:"OutRequests,omitempty"` + OutDiscards *int64 `protobuf:"varint,11,opt,name=OutDiscards" json:"OutDiscards,omitempty"` + OutNoRoutes *int64 `protobuf:"varint,12,opt,name=OutNoRoutes" json:"OutNoRoutes,omitempty"` + ReasmTimeout *int64 `protobuf:"varint,13,opt,name=ReasmTimeout" json:"ReasmTimeout,omitempty"` + ReasmReqds *int64 `protobuf:"varint,14,opt,name=ReasmReqds" json:"ReasmReqds,omitempty"` + ReasmOKs *int64 `protobuf:"varint,15,opt,name=ReasmOKs" json:"ReasmOKs,omitempty"` + ReasmFails *int64 `protobuf:"varint,16,opt,name=ReasmFails" json:"ReasmFails,omitempty"` + FragOKs *int64 `protobuf:"varint,17,opt,name=FragOKs" json:"FragOKs,omitempty"` + FragFails *int64 `protobuf:"varint,18,opt,name=FragFails" json:"FragFails,omitempty"` + FragCreates *int64 `protobuf:"varint,19,opt,name=FragCreates" json:"FragCreates,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *IpStatistics) Reset() { *m = IpStatistics{} } +func (m *IpStatistics) String() string { return proto.CompactTextString(m) } +func (*IpStatistics) ProtoMessage() {} +func (*IpStatistics) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } + +func (m *IpStatistics) GetForwarding() int64 { + if m != nil && m.Forwarding != nil { + return *m.Forwarding + } + return 0 +} + +func (m *IpStatistics) GetDefaultTTL() int64 { + if m != nil && m.DefaultTTL != nil { + return *m.DefaultTTL + } + return 0 +} + +func (m *IpStatistics) GetInReceives() int64 { + if m != nil && m.InReceives != nil { + return *m.InReceives + } + return 0 +} + +func (m *IpStatistics) GetInHdrErrors() int64 { + if m != nil && m.InHdrErrors != nil { + return *m.InHdrErrors + } + return 0 +} + +func (m *IpStatistics) GetInAddrErrors() int64 { + if m != nil && m.InAddrErrors != nil { + return *m.InAddrErrors + } + return 0 +} + +func (m *IpStatistics) GetForwDatagrams() int64 { + if m != nil && m.ForwDatagrams != nil { + return *m.ForwDatagrams + } + return 0 +} + +func (m *IpStatistics) GetInUnknownProtos() int64 { + if m != nil && m.InUnknownProtos != nil { + return *m.InUnknownProtos + } + return 0 +} + +func (m *IpStatistics) GetInDiscards() int64 { + if m != nil && m.InDiscards != nil { + return *m.InDiscards + } + return 0 +} + +func (m *IpStatistics) GetInDelivers() int64 { + if m != nil && m.InDelivers != nil { + return *m.InDelivers + } + return 0 +} + +func (m *IpStatistics) GetOutRequests() int64 { + if m != nil && m.OutRequests != nil { + return *m.OutRequests + } + return 0 +} + +func (m *IpStatistics) GetOutDiscards() int64 { + if m != nil && m.OutDiscards != nil { + return *m.OutDiscards + } + return 0 +} + +func (m *IpStatistics) GetOutNoRoutes() int64 { + if m != nil && m.OutNoRoutes != nil { + return *m.OutNoRoutes + } + return 0 +} + +func (m *IpStatistics) GetReasmTimeout() int64 { + if m != nil && m.ReasmTimeout != nil { + return *m.ReasmTimeout + } + return 0 +} + +func (m *IpStatistics) GetReasmReqds() int64 { + if m != nil && m.ReasmReqds != nil { + return *m.ReasmReqds + } + return 0 +} + +func (m *IpStatistics) GetReasmOKs() int64 { + if m != nil && m.ReasmOKs != nil { + return *m.ReasmOKs + } + return 0 +} + +func (m *IpStatistics) GetReasmFails() int64 { + if m != nil && m.ReasmFails != nil { + return *m.ReasmFails + } + return 0 +} + +func (m *IpStatistics) GetFragOKs() int64 { + if m != nil && m.FragOKs != nil { + return *m.FragOKs + } + return 0 +} + +func (m *IpStatistics) GetFragFails() int64 { + if m != nil && m.FragFails != nil { + return *m.FragFails + } + return 0 +} + +func (m *IpStatistics) GetFragCreates() int64 { + if m != nil && m.FragCreates != nil { + return *m.FragCreates + } + return 0 +} + +type IcmpStatistics struct { + InMsgs *int64 `protobuf:"varint,1,opt,name=InMsgs" json:"InMsgs,omitempty"` + InErrors *int64 `protobuf:"varint,2,opt,name=InErrors" json:"InErrors,omitempty"` + InCsumErrors *int64 `protobuf:"varint,3,opt,name=InCsumErrors" json:"InCsumErrors,omitempty"` + InDestUnreachs *int64 `protobuf:"varint,4,opt,name=InDestUnreachs" json:"InDestUnreachs,omitempty"` + InTimeExcds *int64 `protobuf:"varint,5,opt,name=InTimeExcds" json:"InTimeExcds,omitempty"` + InParmProbs *int64 `protobuf:"varint,6,opt,name=InParmProbs" json:"InParmProbs,omitempty"` + InSrcQuenchs *int64 `protobuf:"varint,7,opt,name=InSrcQuenchs" json:"InSrcQuenchs,omitempty"` + InRedirects *int64 `protobuf:"varint,8,opt,name=InRedirects" json:"InRedirects,omitempty"` + InEchos *int64 `protobuf:"varint,9,opt,name=InEchos" json:"InEchos,omitempty"` + InEchoReps *int64 `protobuf:"varint,10,opt,name=InEchoReps" json:"InEchoReps,omitempty"` + InTimestamps *int64 `protobuf:"varint,11,opt,name=InTimestamps" json:"InTimestamps,omitempty"` + InTimestampReps *int64 `protobuf:"varint,12,opt,name=InTimestampReps" json:"InTimestampReps,omitempty"` + InAddrMasks *int64 `protobuf:"varint,13,opt,name=InAddrMasks" json:"InAddrMasks,omitempty"` + InAddrMaskReps *int64 `protobuf:"varint,14,opt,name=InAddrMaskReps" json:"InAddrMaskReps,omitempty"` + OutMsgs *int64 `protobuf:"varint,15,opt,name=OutMsgs" json:"OutMsgs,omitempty"` + OutErrors *int64 `protobuf:"varint,16,opt,name=OutErrors" json:"OutErrors,omitempty"` + OutDestUnreachs *int64 `protobuf:"varint,17,opt,name=OutDestUnreachs" json:"OutDestUnreachs,omitempty"` + OutTimeExcds *int64 `protobuf:"varint,18,opt,name=OutTimeExcds" json:"OutTimeExcds,omitempty"` + OutParmProbs *int64 `protobuf:"varint,19,opt,name=OutParmProbs" json:"OutParmProbs,omitempty"` + OutSrcQuenchs *int64 `protobuf:"varint,20,opt,name=OutSrcQuenchs" json:"OutSrcQuenchs,omitempty"` + OutRedirects *int64 `protobuf:"varint,21,opt,name=OutRedirects" json:"OutRedirects,omitempty"` + OutEchos *int64 `protobuf:"varint,22,opt,name=OutEchos" json:"OutEchos,omitempty"` + OutEchoReps *int64 `protobuf:"varint,23,opt,name=OutEchoReps" json:"OutEchoReps,omitempty"` + OutTimestamps *int64 `protobuf:"varint,24,opt,name=OutTimestamps" json:"OutTimestamps,omitempty"` + OutTimestampReps *int64 `protobuf:"varint,25,opt,name=OutTimestampReps" json:"OutTimestampReps,omitempty"` + OutAddrMasks *int64 `protobuf:"varint,26,opt,name=OutAddrMasks" json:"OutAddrMasks,omitempty"` + OutAddrMaskReps *int64 `protobuf:"varint,27,opt,name=OutAddrMaskReps" json:"OutAddrMaskReps,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *IcmpStatistics) Reset() { *m = IcmpStatistics{} } +func (m *IcmpStatistics) String() string { return proto.CompactTextString(m) } +func (*IcmpStatistics) ProtoMessage() {} +func (*IcmpStatistics) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } + +func (m *IcmpStatistics) GetInMsgs() int64 { + if m != nil && m.InMsgs != nil { + return *m.InMsgs + } + return 0 +} + +func (m *IcmpStatistics) GetInErrors() int64 { + if m != nil && m.InErrors != nil { + return *m.InErrors + } + return 0 +} + +func (m *IcmpStatistics) GetInCsumErrors() int64 { + if m != nil && m.InCsumErrors != nil { + return *m.InCsumErrors + } + return 0 +} + +func (m *IcmpStatistics) GetInDestUnreachs() int64 { + if m != nil && m.InDestUnreachs != nil { + return *m.InDestUnreachs + } + return 0 +} + +func (m *IcmpStatistics) GetInTimeExcds() int64 { + if m != nil && m.InTimeExcds != nil { + return *m.InTimeExcds + } + return 0 +} + +func (m *IcmpStatistics) GetInParmProbs() int64 { + if m != nil && m.InParmProbs != nil { + return *m.InParmProbs + } + return 0 +} + +func (m *IcmpStatistics) GetInSrcQuenchs() int64 { + if m != nil && m.InSrcQuenchs != nil { + return *m.InSrcQuenchs + } + return 0 +} + +func (m *IcmpStatistics) GetInRedirects() int64 { + if m != nil && m.InRedirects != nil { + return *m.InRedirects + } + return 0 +} + +func (m *IcmpStatistics) GetInEchos() int64 { + if m != nil && m.InEchos != nil { + return *m.InEchos + } + return 0 +} + +func (m *IcmpStatistics) GetInEchoReps() int64 { + if m != nil && m.InEchoReps != nil { + return *m.InEchoReps + } + return 0 +} + +func (m *IcmpStatistics) GetInTimestamps() int64 { + if m != nil && m.InTimestamps != nil { + return *m.InTimestamps + } + return 0 +} + +func (m *IcmpStatistics) GetInTimestampReps() int64 { + if m != nil && m.InTimestampReps != nil { + return *m.InTimestampReps + } + return 0 +} + +func (m *IcmpStatistics) GetInAddrMasks() int64 { + if m != nil && m.InAddrMasks != nil { + return *m.InAddrMasks + } + return 0 +} + +func (m *IcmpStatistics) GetInAddrMaskReps() int64 { + if m != nil && m.InAddrMaskReps != nil { + return *m.InAddrMaskReps + } + return 0 +} + +func (m *IcmpStatistics) GetOutMsgs() int64 { + if m != nil && m.OutMsgs != nil { + return *m.OutMsgs + } + return 0 +} + +func (m *IcmpStatistics) GetOutErrors() int64 { + if m != nil && m.OutErrors != nil { + return *m.OutErrors + } + return 0 +} + +func (m *IcmpStatistics) GetOutDestUnreachs() int64 { + if m != nil && m.OutDestUnreachs != nil { + return *m.OutDestUnreachs + } + return 0 +} + +func (m *IcmpStatistics) GetOutTimeExcds() int64 { + if m != nil && m.OutTimeExcds != nil { + return *m.OutTimeExcds + } + return 0 +} + +func (m *IcmpStatistics) GetOutParmProbs() int64 { + if m != nil && m.OutParmProbs != nil { + return *m.OutParmProbs + } + return 0 +} + +func (m *IcmpStatistics) GetOutSrcQuenchs() int64 { + if m != nil && m.OutSrcQuenchs != nil { + return *m.OutSrcQuenchs + } + return 0 +} + +func (m *IcmpStatistics) GetOutRedirects() int64 { + if m != nil && m.OutRedirects != nil { + return *m.OutRedirects + } + return 0 +} + +func (m *IcmpStatistics) GetOutEchos() int64 { + if m != nil && m.OutEchos != nil { + return *m.OutEchos + } + return 0 +} + +func (m *IcmpStatistics) GetOutEchoReps() int64 { + if m != nil && m.OutEchoReps != nil { + return *m.OutEchoReps + } + return 0 +} + +func (m *IcmpStatistics) GetOutTimestamps() int64 { + if m != nil && m.OutTimestamps != nil { + return *m.OutTimestamps + } + return 0 +} + +func (m *IcmpStatistics) GetOutTimestampReps() int64 { + if m != nil && m.OutTimestampReps != nil { + return *m.OutTimestampReps + } + return 0 +} + +func (m *IcmpStatistics) GetOutAddrMasks() int64 { + if m != nil && m.OutAddrMasks != nil { + return *m.OutAddrMasks + } + return 0 +} + +func (m *IcmpStatistics) GetOutAddrMaskReps() int64 { + if m != nil && m.OutAddrMaskReps != nil { + return *m.OutAddrMaskReps + } + return 0 +} + +type TcpStatistics struct { + RtoAlgorithm *int64 `protobuf:"varint,1,opt,name=RtoAlgorithm" json:"RtoAlgorithm,omitempty"` + RtoMin *int64 `protobuf:"varint,2,opt,name=RtoMin" json:"RtoMin,omitempty"` + RtoMax *int64 `protobuf:"varint,3,opt,name=RtoMax" json:"RtoMax,omitempty"` + MaxConn *int64 `protobuf:"varint,4,opt,name=MaxConn" json:"MaxConn,omitempty"` + ActiveOpens *int64 `protobuf:"varint,5,opt,name=ActiveOpens" json:"ActiveOpens,omitempty"` + PassiveOpens *int64 `protobuf:"varint,6,opt,name=PassiveOpens" json:"PassiveOpens,omitempty"` + AttemptFails *int64 `protobuf:"varint,7,opt,name=AttemptFails" json:"AttemptFails,omitempty"` + EstabResets *int64 `protobuf:"varint,8,opt,name=EstabResets" json:"EstabResets,omitempty"` + CurrEstab *int64 `protobuf:"varint,9,opt,name=CurrEstab" json:"CurrEstab,omitempty"` + InSegs *int64 `protobuf:"varint,10,opt,name=InSegs" json:"InSegs,omitempty"` + OutSegs *int64 `protobuf:"varint,11,opt,name=OutSegs" json:"OutSegs,omitempty"` + RetransSegs *int64 `protobuf:"varint,12,opt,name=RetransSegs" json:"RetransSegs,omitempty"` + InErrs *int64 `protobuf:"varint,13,opt,name=InErrs" json:"InErrs,omitempty"` + OutRsts *int64 `protobuf:"varint,14,opt,name=OutRsts" json:"OutRsts,omitempty"` + InCsumErrors *int64 `protobuf:"varint,15,opt,name=InCsumErrors" json:"InCsumErrors,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *TcpStatistics) Reset() { *m = TcpStatistics{} } +func (m *TcpStatistics) String() string { return proto.CompactTextString(m) } +func (*TcpStatistics) ProtoMessage() {} +func (*TcpStatistics) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } + +func (m *TcpStatistics) GetRtoAlgorithm() int64 { + if m != nil && m.RtoAlgorithm != nil { + return *m.RtoAlgorithm + } + return 0 +} + +func (m *TcpStatistics) GetRtoMin() int64 { + if m != nil && m.RtoMin != nil { + return *m.RtoMin + } + return 0 +} + +func (m *TcpStatistics) GetRtoMax() int64 { + if m != nil && m.RtoMax != nil { + return *m.RtoMax + } + return 0 +} + +func (m *TcpStatistics) GetMaxConn() int64 { + if m != nil && m.MaxConn != nil { + return *m.MaxConn + } + return 0 +} + +func (m *TcpStatistics) GetActiveOpens() int64 { + if m != nil && m.ActiveOpens != nil { + return *m.ActiveOpens + } + return 0 +} + +func (m *TcpStatistics) GetPassiveOpens() int64 { + if m != nil && m.PassiveOpens != nil { + return *m.PassiveOpens + } + return 0 +} + +func (m *TcpStatistics) GetAttemptFails() int64 { + if m != nil && m.AttemptFails != nil { + return *m.AttemptFails + } + return 0 +} + +func (m *TcpStatistics) GetEstabResets() int64 { + if m != nil && m.EstabResets != nil { + return *m.EstabResets + } + return 0 +} + +func (m *TcpStatistics) GetCurrEstab() int64 { + if m != nil && m.CurrEstab != nil { + return *m.CurrEstab + } + return 0 +} + +func (m *TcpStatistics) GetInSegs() int64 { + if m != nil && m.InSegs != nil { + return *m.InSegs + } + return 0 +} + +func (m *TcpStatistics) GetOutSegs() int64 { + if m != nil && m.OutSegs != nil { + return *m.OutSegs + } + return 0 +} + +func (m *TcpStatistics) GetRetransSegs() int64 { + if m != nil && m.RetransSegs != nil { + return *m.RetransSegs + } + return 0 +} + +func (m *TcpStatistics) GetInErrs() int64 { + if m != nil && m.InErrs != nil { + return *m.InErrs + } + return 0 +} + +func (m *TcpStatistics) GetOutRsts() int64 { + if m != nil && m.OutRsts != nil { + return *m.OutRsts + } + return 0 +} + +func (m *TcpStatistics) GetInCsumErrors() int64 { + if m != nil && m.InCsumErrors != nil { + return *m.InCsumErrors + } + return 0 +} + +type UdpStatistics struct { + InDatagrams *int64 `protobuf:"varint,1,opt,name=InDatagrams" json:"InDatagrams,omitempty"` + NoPorts *int64 `protobuf:"varint,2,opt,name=NoPorts" json:"NoPorts,omitempty"` + InErrors *int64 `protobuf:"varint,3,opt,name=InErrors" json:"InErrors,omitempty"` + OutDatagrams *int64 `protobuf:"varint,4,opt,name=OutDatagrams" json:"OutDatagrams,omitempty"` + RcvbufErrors *int64 `protobuf:"varint,5,opt,name=RcvbufErrors" json:"RcvbufErrors,omitempty"` + SndbufErrors *int64 `protobuf:"varint,6,opt,name=SndbufErrors" json:"SndbufErrors,omitempty"` + InCsumErrors *int64 `protobuf:"varint,7,opt,name=InCsumErrors" json:"InCsumErrors,omitempty"` + IgnoredMulti *int64 `protobuf:"varint,8,opt,name=IgnoredMulti" json:"IgnoredMulti,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *UdpStatistics) Reset() { *m = UdpStatistics{} } +func (m *UdpStatistics) String() string { return proto.CompactTextString(m) } +func (*UdpStatistics) ProtoMessage() {} +func (*UdpStatistics) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } + +func (m *UdpStatistics) GetInDatagrams() int64 { + if m != nil && m.InDatagrams != nil { + return *m.InDatagrams + } + return 0 +} + +func (m *UdpStatistics) GetNoPorts() int64 { + if m != nil && m.NoPorts != nil { + return *m.NoPorts + } + return 0 +} + +func (m *UdpStatistics) GetInErrors() int64 { + if m != nil && m.InErrors != nil { + return *m.InErrors + } + return 0 +} + +func (m *UdpStatistics) GetOutDatagrams() int64 { + if m != nil && m.OutDatagrams != nil { + return *m.OutDatagrams + } + return 0 +} + +func (m *UdpStatistics) GetRcvbufErrors() int64 { + if m != nil && m.RcvbufErrors != nil { + return *m.RcvbufErrors + } + return 0 +} + +func (m *UdpStatistics) GetSndbufErrors() int64 { + if m != nil && m.SndbufErrors != nil { + return *m.SndbufErrors + } + return 0 +} + +func (m *UdpStatistics) GetInCsumErrors() int64 { + if m != nil && m.InCsumErrors != nil { + return *m.InCsumErrors + } + return 0 +} + +func (m *UdpStatistics) GetIgnoredMulti() int64 { + if m != nil && m.IgnoredMulti != nil { + return *m.IgnoredMulti + } + return 0 +} + +type SNMPStatistics struct { + IpStats *IpStatistics `protobuf:"bytes,1,opt,name=ip_stats,json=ipStats" json:"ip_stats,omitempty"` + IcmpStats *IcmpStatistics `protobuf:"bytes,2,opt,name=icmp_stats,json=icmpStats" json:"icmp_stats,omitempty"` + TcpStats *TcpStatistics `protobuf:"bytes,3,opt,name=tcp_stats,json=tcpStats" json:"tcp_stats,omitempty"` + UdpStats *UdpStatistics `protobuf:"bytes,4,opt,name=udp_stats,json=udpStats" json:"udp_stats,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *SNMPStatistics) Reset() { *m = SNMPStatistics{} } +func (m *SNMPStatistics) String() string { return proto.CompactTextString(m) } +func (*SNMPStatistics) ProtoMessage() {} +func (*SNMPStatistics) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } + +func (m *SNMPStatistics) GetIpStats() *IpStatistics { + if m != nil { + return m.IpStats + } + return nil +} + +func (m *SNMPStatistics) GetIcmpStats() *IcmpStatistics { + if m != nil { + return m.IcmpStats + } + return nil +} + +func (m *SNMPStatistics) GetTcpStats() *TcpStatistics { + if m != nil { + return m.TcpStats + } + return nil +} + +func (m *SNMPStatistics) GetUdpStats() *UdpStatistics { + if m != nil { + return m.UdpStats + } + return nil +} + +// * +// A snapshot of resource usage statistics. +type ResourceStatistics struct { + Timestamp *float64 `protobuf:"fixed64,1,req,name=timestamp" json:"timestamp,omitempty"` + Processes *uint32 `protobuf:"varint,30,opt,name=processes" json:"processes,omitempty"` + Threads *uint32 `protobuf:"varint,31,opt,name=threads" json:"threads,omitempty"` + // CPU Usage Information: + // Total CPU time spent in user mode, and kernel mode. + CpusUserTimeSecs *float64 `protobuf:"fixed64,2,opt,name=cpus_user_time_secs,json=cpusUserTimeSecs" json:"cpus_user_time_secs,omitempty"` + CpusSystemTimeSecs *float64 `protobuf:"fixed64,3,opt,name=cpus_system_time_secs,json=cpusSystemTimeSecs" json:"cpus_system_time_secs,omitempty"` + // Number of CPUs allocated. + CpusLimit *float64 `protobuf:"fixed64,4,opt,name=cpus_limit,json=cpusLimit" json:"cpus_limit,omitempty"` + // cpu.stat on process throttling (for contention issues). + CpusNrPeriods *uint32 `protobuf:"varint,7,opt,name=cpus_nr_periods,json=cpusNrPeriods" json:"cpus_nr_periods,omitempty"` + CpusNrThrottled *uint32 `protobuf:"varint,8,opt,name=cpus_nr_throttled,json=cpusNrThrottled" json:"cpus_nr_throttled,omitempty"` + CpusThrottledTimeSecs *float64 `protobuf:"fixed64,9,opt,name=cpus_throttled_time_secs,json=cpusThrottledTimeSecs" json:"cpus_throttled_time_secs,omitempty"` + // mem_total_bytes was added in 0.23.0 to represent the total memory + // of a process in RAM (as opposed to in Swap). This was previously + // reported as mem_rss_bytes, which was also changed in 0.23.0 to + // represent only the anonymous memory usage, to keep in sync with + // Linux kernel's (arguably erroneous) use of terminology. + MemTotalBytes *uint64 `protobuf:"varint,36,opt,name=mem_total_bytes,json=memTotalBytes" json:"mem_total_bytes,omitempty"` + // Total memory + swap usage. This is set if swap is enabled. + MemTotalMemswBytes *uint64 `protobuf:"varint,37,opt,name=mem_total_memsw_bytes,json=memTotalMemswBytes" json:"mem_total_memsw_bytes,omitempty"` + // Hard memory limit for a container. + MemLimitBytes *uint64 `protobuf:"varint,6,opt,name=mem_limit_bytes,json=memLimitBytes" json:"mem_limit_bytes,omitempty"` + // Soft memory limit for a container. + MemSoftLimitBytes *uint64 `protobuf:"varint,38,opt,name=mem_soft_limit_bytes,json=memSoftLimitBytes" json:"mem_soft_limit_bytes,omitempty"` + // TODO(chzhcn) mem_file_bytes and mem_anon_bytes are deprecated in + // 0.23.0 and will be removed in 0.24.0. + MemFileBytes *uint64 `protobuf:"varint,10,opt,name=mem_file_bytes,json=memFileBytes" json:"mem_file_bytes,omitempty"` + MemAnonBytes *uint64 `protobuf:"varint,11,opt,name=mem_anon_bytes,json=memAnonBytes" json:"mem_anon_bytes,omitempty"` + // mem_cache_bytes is added in 0.23.0 to represent page cache usage. + MemCacheBytes *uint64 `protobuf:"varint,39,opt,name=mem_cache_bytes,json=memCacheBytes" json:"mem_cache_bytes,omitempty"` + // Since 0.23.0, mem_rss_bytes is changed to represent only + // anonymous memory usage. Note that neither its requiredness, type, + // name nor numeric tag has been changed. + MemRssBytes *uint64 `protobuf:"varint,5,opt,name=mem_rss_bytes,json=memRssBytes" json:"mem_rss_bytes,omitempty"` + MemMappedFileBytes *uint64 `protobuf:"varint,12,opt,name=mem_mapped_file_bytes,json=memMappedFileBytes" json:"mem_mapped_file_bytes,omitempty"` + // This is only set if swap is enabled. + MemSwapBytes *uint64 `protobuf:"varint,40,opt,name=mem_swap_bytes,json=memSwapBytes" json:"mem_swap_bytes,omitempty"` + MemUnevictableBytes *uint64 `protobuf:"varint,41,opt,name=mem_unevictable_bytes,json=memUnevictableBytes" json:"mem_unevictable_bytes,omitempty"` + // Number of occurrences of different levels of memory pressure + // events reported by memory cgroup. Pressure listening (re)starts + // with these values set to 0 when agent (re)starts. See + // https://www.kernel.org/doc/Documentation/cgroups/memory.txt for + // more details. + MemLowPressureCounter *uint64 `protobuf:"varint,32,opt,name=mem_low_pressure_counter,json=memLowPressureCounter" json:"mem_low_pressure_counter,omitempty"` + MemMediumPressureCounter *uint64 `protobuf:"varint,33,opt,name=mem_medium_pressure_counter,json=memMediumPressureCounter" json:"mem_medium_pressure_counter,omitempty"` + MemCriticalPressureCounter *uint64 `protobuf:"varint,34,opt,name=mem_critical_pressure_counter,json=memCriticalPressureCounter" json:"mem_critical_pressure_counter,omitempty"` + // Disk Usage Information for executor working directory. + DiskLimitBytes *uint64 `protobuf:"varint,26,opt,name=disk_limit_bytes,json=diskLimitBytes" json:"disk_limit_bytes,omitempty"` + DiskUsedBytes *uint64 `protobuf:"varint,27,opt,name=disk_used_bytes,json=diskUsedBytes" json:"disk_used_bytes,omitempty"` + // Perf statistics. + Perf *PerfStatistics `protobuf:"bytes,13,opt,name=perf" json:"perf,omitempty"` + // Network Usage Information: + NetRxPackets *uint64 `protobuf:"varint,14,opt,name=net_rx_packets,json=netRxPackets" json:"net_rx_packets,omitempty"` + NetRxBytes *uint64 `protobuf:"varint,15,opt,name=net_rx_bytes,json=netRxBytes" json:"net_rx_bytes,omitempty"` + NetRxErrors *uint64 `protobuf:"varint,16,opt,name=net_rx_errors,json=netRxErrors" json:"net_rx_errors,omitempty"` + NetRxDropped *uint64 `protobuf:"varint,17,opt,name=net_rx_dropped,json=netRxDropped" json:"net_rx_dropped,omitempty"` + NetTxPackets *uint64 `protobuf:"varint,18,opt,name=net_tx_packets,json=netTxPackets" json:"net_tx_packets,omitempty"` + NetTxBytes *uint64 `protobuf:"varint,19,opt,name=net_tx_bytes,json=netTxBytes" json:"net_tx_bytes,omitempty"` + NetTxErrors *uint64 `protobuf:"varint,20,opt,name=net_tx_errors,json=netTxErrors" json:"net_tx_errors,omitempty"` + NetTxDropped *uint64 `protobuf:"varint,21,opt,name=net_tx_dropped,json=netTxDropped" json:"net_tx_dropped,omitempty"` + // The kernel keeps track of RTT (round-trip time) for its TCP + // sockets. RTT is a way to tell the latency of a container. + NetTcpRttMicrosecsP50 *float64 `protobuf:"fixed64,22,opt,name=net_tcp_rtt_microsecs_p50,json=netTcpRttMicrosecsP50" json:"net_tcp_rtt_microsecs_p50,omitempty"` + NetTcpRttMicrosecsP90 *float64 `protobuf:"fixed64,23,opt,name=net_tcp_rtt_microsecs_p90,json=netTcpRttMicrosecsP90" json:"net_tcp_rtt_microsecs_p90,omitempty"` + NetTcpRttMicrosecsP95 *float64 `protobuf:"fixed64,24,opt,name=net_tcp_rtt_microsecs_p95,json=netTcpRttMicrosecsP95" json:"net_tcp_rtt_microsecs_p95,omitempty"` + NetTcpRttMicrosecsP99 *float64 `protobuf:"fixed64,25,opt,name=net_tcp_rtt_microsecs_p99,json=netTcpRttMicrosecsP99" json:"net_tcp_rtt_microsecs_p99,omitempty"` + NetTcpActiveConnections *float64 `protobuf:"fixed64,28,opt,name=net_tcp_active_connections,json=netTcpActiveConnections" json:"net_tcp_active_connections,omitempty"` + NetTcpTimeWaitConnections *float64 `protobuf:"fixed64,29,opt,name=net_tcp_time_wait_connections,json=netTcpTimeWaitConnections" json:"net_tcp_time_wait_connections,omitempty"` + // Network traffic flowing into or out of a container can be delayed + // or dropped due to congestion or policy inside and outside the + // container. + NetTrafficControlStatistics []*TrafficControlStatistics `protobuf:"bytes,35,rep,name=net_traffic_control_statistics,json=netTrafficControlStatistics" json:"net_traffic_control_statistics,omitempty"` + // Network SNMP statistics for each container. + NetSnmpStatistics *SNMPStatistics `protobuf:"bytes,42,opt,name=net_snmp_statistics,json=netSnmpStatistics" json:"net_snmp_statistics,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ResourceStatistics) Reset() { *m = ResourceStatistics{} } +func (m *ResourceStatistics) String() string { return proto.CompactTextString(m) } +func (*ResourceStatistics) ProtoMessage() {} +func (*ResourceStatistics) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} } + +func (m *ResourceStatistics) GetTimestamp() float64 { + if m != nil && m.Timestamp != nil { + return *m.Timestamp + } + return 0 +} + +func (m *ResourceStatistics) GetProcesses() uint32 { + if m != nil && m.Processes != nil { + return *m.Processes + } + return 0 +} + +func (m *ResourceStatistics) GetThreads() uint32 { + if m != nil && m.Threads != nil { + return *m.Threads + } + return 0 +} + +func (m *ResourceStatistics) GetCpusUserTimeSecs() float64 { + if m != nil && m.CpusUserTimeSecs != nil { + return *m.CpusUserTimeSecs + } + return 0 +} + +func (m *ResourceStatistics) GetCpusSystemTimeSecs() float64 { + if m != nil && m.CpusSystemTimeSecs != nil { + return *m.CpusSystemTimeSecs + } + return 0 +} + +func (m *ResourceStatistics) GetCpusLimit() float64 { + if m != nil && m.CpusLimit != nil { + return *m.CpusLimit + } + return 0 +} + +func (m *ResourceStatistics) GetCpusNrPeriods() uint32 { + if m != nil && m.CpusNrPeriods != nil { + return *m.CpusNrPeriods + } + return 0 +} + +func (m *ResourceStatistics) GetCpusNrThrottled() uint32 { + if m != nil && m.CpusNrThrottled != nil { + return *m.CpusNrThrottled + } + return 0 +} + +func (m *ResourceStatistics) GetCpusThrottledTimeSecs() float64 { + if m != nil && m.CpusThrottledTimeSecs != nil { + return *m.CpusThrottledTimeSecs + } + return 0 +} + +func (m *ResourceStatistics) GetMemTotalBytes() uint64 { + if m != nil && m.MemTotalBytes != nil { + return *m.MemTotalBytes + } + return 0 +} + +func (m *ResourceStatistics) GetMemTotalMemswBytes() uint64 { + if m != nil && m.MemTotalMemswBytes != nil { + return *m.MemTotalMemswBytes + } + return 0 +} + +func (m *ResourceStatistics) GetMemLimitBytes() uint64 { + if m != nil && m.MemLimitBytes != nil { + return *m.MemLimitBytes + } + return 0 +} + +func (m *ResourceStatistics) GetMemSoftLimitBytes() uint64 { + if m != nil && m.MemSoftLimitBytes != nil { + return *m.MemSoftLimitBytes + } + return 0 +} + +func (m *ResourceStatistics) GetMemFileBytes() uint64 { + if m != nil && m.MemFileBytes != nil { + return *m.MemFileBytes + } + return 0 +} + +func (m *ResourceStatistics) GetMemAnonBytes() uint64 { + if m != nil && m.MemAnonBytes != nil { + return *m.MemAnonBytes + } + return 0 +} + +func (m *ResourceStatistics) GetMemCacheBytes() uint64 { + if m != nil && m.MemCacheBytes != nil { + return *m.MemCacheBytes + } + return 0 +} + +func (m *ResourceStatistics) GetMemRssBytes() uint64 { + if m != nil && m.MemRssBytes != nil { + return *m.MemRssBytes + } + return 0 +} + +func (m *ResourceStatistics) GetMemMappedFileBytes() uint64 { + if m != nil && m.MemMappedFileBytes != nil { + return *m.MemMappedFileBytes + } + return 0 +} + +func (m *ResourceStatistics) GetMemSwapBytes() uint64 { + if m != nil && m.MemSwapBytes != nil { + return *m.MemSwapBytes + } + return 0 +} + +func (m *ResourceStatistics) GetMemUnevictableBytes() uint64 { + if m != nil && m.MemUnevictableBytes != nil { + return *m.MemUnevictableBytes + } + return 0 +} + +func (m *ResourceStatistics) GetMemLowPressureCounter() uint64 { + if m != nil && m.MemLowPressureCounter != nil { + return *m.MemLowPressureCounter + } + return 0 +} + +func (m *ResourceStatistics) GetMemMediumPressureCounter() uint64 { + if m != nil && m.MemMediumPressureCounter != nil { + return *m.MemMediumPressureCounter + } + return 0 +} + +func (m *ResourceStatistics) GetMemCriticalPressureCounter() uint64 { + if m != nil && m.MemCriticalPressureCounter != nil { + return *m.MemCriticalPressureCounter + } + return 0 +} + +func (m *ResourceStatistics) GetDiskLimitBytes() uint64 { + if m != nil && m.DiskLimitBytes != nil { + return *m.DiskLimitBytes + } + return 0 +} + +func (m *ResourceStatistics) GetDiskUsedBytes() uint64 { + if m != nil && m.DiskUsedBytes != nil { + return *m.DiskUsedBytes + } + return 0 +} + +func (m *ResourceStatistics) GetPerf() *PerfStatistics { + if m != nil { + return m.Perf + } + return nil +} + +func (m *ResourceStatistics) GetNetRxPackets() uint64 { + if m != nil && m.NetRxPackets != nil { + return *m.NetRxPackets + } + return 0 +} + +func (m *ResourceStatistics) GetNetRxBytes() uint64 { + if m != nil && m.NetRxBytes != nil { + return *m.NetRxBytes + } + return 0 +} + +func (m *ResourceStatistics) GetNetRxErrors() uint64 { + if m != nil && m.NetRxErrors != nil { + return *m.NetRxErrors + } + return 0 +} + +func (m *ResourceStatistics) GetNetRxDropped() uint64 { + if m != nil && m.NetRxDropped != nil { + return *m.NetRxDropped + } + return 0 +} + +func (m *ResourceStatistics) GetNetTxPackets() uint64 { + if m != nil && m.NetTxPackets != nil { + return *m.NetTxPackets + } + return 0 +} + +func (m *ResourceStatistics) GetNetTxBytes() uint64 { + if m != nil && m.NetTxBytes != nil { + return *m.NetTxBytes + } + return 0 +} + +func (m *ResourceStatistics) GetNetTxErrors() uint64 { + if m != nil && m.NetTxErrors != nil { + return *m.NetTxErrors + } + return 0 +} + +func (m *ResourceStatistics) GetNetTxDropped() uint64 { + if m != nil && m.NetTxDropped != nil { + return *m.NetTxDropped + } + return 0 +} + +func (m *ResourceStatistics) GetNetTcpRttMicrosecsP50() float64 { + if m != nil && m.NetTcpRttMicrosecsP50 != nil { + return *m.NetTcpRttMicrosecsP50 + } + return 0 +} + +func (m *ResourceStatistics) GetNetTcpRttMicrosecsP90() float64 { + if m != nil && m.NetTcpRttMicrosecsP90 != nil { + return *m.NetTcpRttMicrosecsP90 + } + return 0 +} + +func (m *ResourceStatistics) GetNetTcpRttMicrosecsP95() float64 { + if m != nil && m.NetTcpRttMicrosecsP95 != nil { + return *m.NetTcpRttMicrosecsP95 + } + return 0 +} + +func (m *ResourceStatistics) GetNetTcpRttMicrosecsP99() float64 { + if m != nil && m.NetTcpRttMicrosecsP99 != nil { + return *m.NetTcpRttMicrosecsP99 + } + return 0 +} + +func (m *ResourceStatistics) GetNetTcpActiveConnections() float64 { + if m != nil && m.NetTcpActiveConnections != nil { + return *m.NetTcpActiveConnections + } + return 0 +} + +func (m *ResourceStatistics) GetNetTcpTimeWaitConnections() float64 { + if m != nil && m.NetTcpTimeWaitConnections != nil { + return *m.NetTcpTimeWaitConnections + } + return 0 +} + +func (m *ResourceStatistics) GetNetTrafficControlStatistics() []*TrafficControlStatistics { + if m != nil { + return m.NetTrafficControlStatistics + } + return nil +} + +func (m *ResourceStatistics) GetNetSnmpStatistics() *SNMPStatistics { + if m != nil { + return m.NetSnmpStatistics + } + return nil +} + +// * +// Describes a snapshot of the resource usage for executors. +type ResourceUsage struct { + Executors []*ResourceUsage_Executor `protobuf:"bytes,1,rep,name=executors" json:"executors,omitempty"` + // Agent's total resources including checkpointed dynamic + // reservations and persistent volumes. + Total []*Resource `protobuf:"bytes,2,rep,name=total" json:"total,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ResourceUsage) Reset() { *m = ResourceUsage{} } +func (m *ResourceUsage) String() string { return proto.CompactTextString(m) } +func (*ResourceUsage) ProtoMessage() {} +func (*ResourceUsage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} } + +func (m *ResourceUsage) GetExecutors() []*ResourceUsage_Executor { + if m != nil { + return m.Executors + } + return nil +} + +func (m *ResourceUsage) GetTotal() []*Resource { + if m != nil { + return m.Total + } + return nil +} + +type ResourceUsage_Executor struct { + ExecutorInfo *ExecutorInfo `protobuf:"bytes,1,req,name=executor_info,json=executorInfo" json:"executor_info,omitempty"` + // This includes resources used by the executor itself + // as well as its active tasks. + Allocated []*Resource `protobuf:"bytes,2,rep,name=allocated" json:"allocated,omitempty"` + // Current resource usage. If absent, the containerizer + // cannot provide resource usage. + Statistics *ResourceStatistics `protobuf:"bytes,3,opt,name=statistics" json:"statistics,omitempty"` + // The container id for the executor specified in the executor_info field. + ContainerId *ContainerID `protobuf:"bytes,4,req,name=container_id,json=containerId" json:"container_id,omitempty"` + // Non-terminal tasks. + Tasks []*ResourceUsage_Executor_Task `protobuf:"bytes,5,rep,name=tasks" json:"tasks,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ResourceUsage_Executor) Reset() { *m = ResourceUsage_Executor{} } +func (m *ResourceUsage_Executor) String() string { return proto.CompactTextString(m) } +func (*ResourceUsage_Executor) ProtoMessage() {} +func (*ResourceUsage_Executor) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30, 0} } + +func (m *ResourceUsage_Executor) GetExecutorInfo() *ExecutorInfo { + if m != nil { + return m.ExecutorInfo + } + return nil +} + +func (m *ResourceUsage_Executor) GetAllocated() []*Resource { + if m != nil { + return m.Allocated + } + return nil +} + +func (m *ResourceUsage_Executor) GetStatistics() *ResourceStatistics { + if m != nil { + return m.Statistics + } + return nil +} + +func (m *ResourceUsage_Executor) GetContainerId() *ContainerID { + if m != nil { + return m.ContainerId + } + return nil +} + +func (m *ResourceUsage_Executor) GetTasks() []*ResourceUsage_Executor_Task { + if m != nil { + return m.Tasks + } + return nil +} + +type ResourceUsage_Executor_Task struct { + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + Id *TaskID `protobuf:"bytes,2,req,name=id" json:"id,omitempty"` + Resources []*Resource `protobuf:"bytes,3,rep,name=resources" json:"resources,omitempty"` + Labels *Labels `protobuf:"bytes,4,opt,name=labels" json:"labels,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ResourceUsage_Executor_Task) Reset() { *m = ResourceUsage_Executor_Task{} } +func (m *ResourceUsage_Executor_Task) String() string { return proto.CompactTextString(m) } +func (*ResourceUsage_Executor_Task) ProtoMessage() {} +func (*ResourceUsage_Executor_Task) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{30, 0, 0} +} + +func (m *ResourceUsage_Executor_Task) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *ResourceUsage_Executor_Task) GetId() *TaskID { + if m != nil { + return m.Id + } + return nil +} + +func (m *ResourceUsage_Executor_Task) GetResources() []*Resource { + if m != nil { + return m.Resources + } + return nil +} + +func (m *ResourceUsage_Executor_Task) GetLabels() *Labels { + if m != nil { + return m.Labels + } + return nil +} + +// * +// Describes a sample of events from "perf stat". Only available on +// Linux. +// +// NOTE: Each optional field matches the name of a perf event (see +// "perf list") with the following changes: +// 1. Names are downcased. +// 2. Hyphens ('-') are replaced with underscores ('_'). +// 3. Events with alternate names use the name "perf stat" returns, +// e.g., for the event "cycles OR cpu-cycles" perf always returns +// cycles. +type PerfStatistics struct { + Timestamp *float64 `protobuf:"fixed64,1,req,name=timestamp" json:"timestamp,omitempty"` + Duration *float64 `protobuf:"fixed64,2,req,name=duration" json:"duration,omitempty"` + // Hardware event. + Cycles *uint64 `protobuf:"varint,3,opt,name=cycles" json:"cycles,omitempty"` + StalledCyclesFrontend *uint64 `protobuf:"varint,4,opt,name=stalled_cycles_frontend,json=stalledCyclesFrontend" json:"stalled_cycles_frontend,omitempty"` + StalledCyclesBackend *uint64 `protobuf:"varint,5,opt,name=stalled_cycles_backend,json=stalledCyclesBackend" json:"stalled_cycles_backend,omitempty"` + Instructions *uint64 `protobuf:"varint,6,opt,name=instructions" json:"instructions,omitempty"` + CacheReferences *uint64 `protobuf:"varint,7,opt,name=cache_references,json=cacheReferences" json:"cache_references,omitempty"` + CacheMisses *uint64 `protobuf:"varint,8,opt,name=cache_misses,json=cacheMisses" json:"cache_misses,omitempty"` + Branches *uint64 `protobuf:"varint,9,opt,name=branches" json:"branches,omitempty"` + BranchMisses *uint64 `protobuf:"varint,10,opt,name=branch_misses,json=branchMisses" json:"branch_misses,omitempty"` + BusCycles *uint64 `protobuf:"varint,11,opt,name=bus_cycles,json=busCycles" json:"bus_cycles,omitempty"` + RefCycles *uint64 `protobuf:"varint,12,opt,name=ref_cycles,json=refCycles" json:"ref_cycles,omitempty"` + // Software event. + CpuClock *float64 `protobuf:"fixed64,13,opt,name=cpu_clock,json=cpuClock" json:"cpu_clock,omitempty"` + TaskClock *float64 `protobuf:"fixed64,14,opt,name=task_clock,json=taskClock" json:"task_clock,omitempty"` + PageFaults *uint64 `protobuf:"varint,15,opt,name=page_faults,json=pageFaults" json:"page_faults,omitempty"` + MinorFaults *uint64 `protobuf:"varint,16,opt,name=minor_faults,json=minorFaults" json:"minor_faults,omitempty"` + MajorFaults *uint64 `protobuf:"varint,17,opt,name=major_faults,json=majorFaults" json:"major_faults,omitempty"` + ContextSwitches *uint64 `protobuf:"varint,18,opt,name=context_switches,json=contextSwitches" json:"context_switches,omitempty"` + CpuMigrations *uint64 `protobuf:"varint,19,opt,name=cpu_migrations,json=cpuMigrations" json:"cpu_migrations,omitempty"` + AlignmentFaults *uint64 `protobuf:"varint,20,opt,name=alignment_faults,json=alignmentFaults" json:"alignment_faults,omitempty"` + EmulationFaults *uint64 `protobuf:"varint,21,opt,name=emulation_faults,json=emulationFaults" json:"emulation_faults,omitempty"` + // Hardware cache event. + L1DcacheLoads *uint64 `protobuf:"varint,22,opt,name=l1_dcache_loads,json=l1DcacheLoads" json:"l1_dcache_loads,omitempty"` + L1DcacheLoadMisses *uint64 `protobuf:"varint,23,opt,name=l1_dcache_load_misses,json=l1DcacheLoadMisses" json:"l1_dcache_load_misses,omitempty"` + L1DcacheStores *uint64 `protobuf:"varint,24,opt,name=l1_dcache_stores,json=l1DcacheStores" json:"l1_dcache_stores,omitempty"` + L1DcacheStoreMisses *uint64 `protobuf:"varint,25,opt,name=l1_dcache_store_misses,json=l1DcacheStoreMisses" json:"l1_dcache_store_misses,omitempty"` + L1DcachePrefetches *uint64 `protobuf:"varint,26,opt,name=l1_dcache_prefetches,json=l1DcachePrefetches" json:"l1_dcache_prefetches,omitempty"` + L1DcachePrefetchMisses *uint64 `protobuf:"varint,27,opt,name=l1_dcache_prefetch_misses,json=l1DcachePrefetchMisses" json:"l1_dcache_prefetch_misses,omitempty"` + L1IcacheLoads *uint64 `protobuf:"varint,28,opt,name=l1_icache_loads,json=l1IcacheLoads" json:"l1_icache_loads,omitempty"` + L1IcacheLoadMisses *uint64 `protobuf:"varint,29,opt,name=l1_icache_load_misses,json=l1IcacheLoadMisses" json:"l1_icache_load_misses,omitempty"` + L1IcachePrefetches *uint64 `protobuf:"varint,30,opt,name=l1_icache_prefetches,json=l1IcachePrefetches" json:"l1_icache_prefetches,omitempty"` + L1IcachePrefetchMisses *uint64 `protobuf:"varint,31,opt,name=l1_icache_prefetch_misses,json=l1IcachePrefetchMisses" json:"l1_icache_prefetch_misses,omitempty"` + LlcLoads *uint64 `protobuf:"varint,32,opt,name=llc_loads,json=llcLoads" json:"llc_loads,omitempty"` + LlcLoadMisses *uint64 `protobuf:"varint,33,opt,name=llc_load_misses,json=llcLoadMisses" json:"llc_load_misses,omitempty"` + LlcStores *uint64 `protobuf:"varint,34,opt,name=llc_stores,json=llcStores" json:"llc_stores,omitempty"` + LlcStoreMisses *uint64 `protobuf:"varint,35,opt,name=llc_store_misses,json=llcStoreMisses" json:"llc_store_misses,omitempty"` + LlcPrefetches *uint64 `protobuf:"varint,36,opt,name=llc_prefetches,json=llcPrefetches" json:"llc_prefetches,omitempty"` + LlcPrefetchMisses *uint64 `protobuf:"varint,37,opt,name=llc_prefetch_misses,json=llcPrefetchMisses" json:"llc_prefetch_misses,omitempty"` + DtlbLoads *uint64 `protobuf:"varint,38,opt,name=dtlb_loads,json=dtlbLoads" json:"dtlb_loads,omitempty"` + DtlbLoadMisses *uint64 `protobuf:"varint,39,opt,name=dtlb_load_misses,json=dtlbLoadMisses" json:"dtlb_load_misses,omitempty"` + DtlbStores *uint64 `protobuf:"varint,40,opt,name=dtlb_stores,json=dtlbStores" json:"dtlb_stores,omitempty"` + DtlbStoreMisses *uint64 `protobuf:"varint,41,opt,name=dtlb_store_misses,json=dtlbStoreMisses" json:"dtlb_store_misses,omitempty"` + DtlbPrefetches *uint64 `protobuf:"varint,42,opt,name=dtlb_prefetches,json=dtlbPrefetches" json:"dtlb_prefetches,omitempty"` + DtlbPrefetchMisses *uint64 `protobuf:"varint,43,opt,name=dtlb_prefetch_misses,json=dtlbPrefetchMisses" json:"dtlb_prefetch_misses,omitempty"` + ItlbLoads *uint64 `protobuf:"varint,44,opt,name=itlb_loads,json=itlbLoads" json:"itlb_loads,omitempty"` + ItlbLoadMisses *uint64 `protobuf:"varint,45,opt,name=itlb_load_misses,json=itlbLoadMisses" json:"itlb_load_misses,omitempty"` + BranchLoads *uint64 `protobuf:"varint,46,opt,name=branch_loads,json=branchLoads" json:"branch_loads,omitempty"` + BranchLoadMisses *uint64 `protobuf:"varint,47,opt,name=branch_load_misses,json=branchLoadMisses" json:"branch_load_misses,omitempty"` + NodeLoads *uint64 `protobuf:"varint,48,opt,name=node_loads,json=nodeLoads" json:"node_loads,omitempty"` + NodeLoadMisses *uint64 `protobuf:"varint,49,opt,name=node_load_misses,json=nodeLoadMisses" json:"node_load_misses,omitempty"` + NodeStores *uint64 `protobuf:"varint,50,opt,name=node_stores,json=nodeStores" json:"node_stores,omitempty"` + NodeStoreMisses *uint64 `protobuf:"varint,51,opt,name=node_store_misses,json=nodeStoreMisses" json:"node_store_misses,omitempty"` + NodePrefetches *uint64 `protobuf:"varint,52,opt,name=node_prefetches,json=nodePrefetches" json:"node_prefetches,omitempty"` + NodePrefetchMisses *uint64 `protobuf:"varint,53,opt,name=node_prefetch_misses,json=nodePrefetchMisses" json:"node_prefetch_misses,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *PerfStatistics) Reset() { *m = PerfStatistics{} } +func (m *PerfStatistics) String() string { return proto.CompactTextString(m) } +func (*PerfStatistics) ProtoMessage() {} +func (*PerfStatistics) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} } + +func (m *PerfStatistics) GetTimestamp() float64 { + if m != nil && m.Timestamp != nil { + return *m.Timestamp + } + return 0 +} + +func (m *PerfStatistics) GetDuration() float64 { + if m != nil && m.Duration != nil { + return *m.Duration + } + return 0 +} + +func (m *PerfStatistics) GetCycles() uint64 { + if m != nil && m.Cycles != nil { + return *m.Cycles + } + return 0 +} + +func (m *PerfStatistics) GetStalledCyclesFrontend() uint64 { + if m != nil && m.StalledCyclesFrontend != nil { + return *m.StalledCyclesFrontend + } + return 0 +} + +func (m *PerfStatistics) GetStalledCyclesBackend() uint64 { + if m != nil && m.StalledCyclesBackend != nil { + return *m.StalledCyclesBackend + } + return 0 +} + +func (m *PerfStatistics) GetInstructions() uint64 { + if m != nil && m.Instructions != nil { + return *m.Instructions + } + return 0 +} + +func (m *PerfStatistics) GetCacheReferences() uint64 { + if m != nil && m.CacheReferences != nil { + return *m.CacheReferences + } + return 0 +} + +func (m *PerfStatistics) GetCacheMisses() uint64 { + if m != nil && m.CacheMisses != nil { + return *m.CacheMisses + } + return 0 +} + +func (m *PerfStatistics) GetBranches() uint64 { + if m != nil && m.Branches != nil { + return *m.Branches + } + return 0 +} + +func (m *PerfStatistics) GetBranchMisses() uint64 { + if m != nil && m.BranchMisses != nil { + return *m.BranchMisses + } + return 0 +} + +func (m *PerfStatistics) GetBusCycles() uint64 { + if m != nil && m.BusCycles != nil { + return *m.BusCycles + } + return 0 +} + +func (m *PerfStatistics) GetRefCycles() uint64 { + if m != nil && m.RefCycles != nil { + return *m.RefCycles + } + return 0 +} + +func (m *PerfStatistics) GetCpuClock() float64 { + if m != nil && m.CpuClock != nil { + return *m.CpuClock + } + return 0 +} + +func (m *PerfStatistics) GetTaskClock() float64 { + if m != nil && m.TaskClock != nil { + return *m.TaskClock + } + return 0 +} + +func (m *PerfStatistics) GetPageFaults() uint64 { + if m != nil && m.PageFaults != nil { + return *m.PageFaults + } + return 0 +} + +func (m *PerfStatistics) GetMinorFaults() uint64 { + if m != nil && m.MinorFaults != nil { + return *m.MinorFaults + } + return 0 +} + +func (m *PerfStatistics) GetMajorFaults() uint64 { + if m != nil && m.MajorFaults != nil { + return *m.MajorFaults + } + return 0 +} + +func (m *PerfStatistics) GetContextSwitches() uint64 { + if m != nil && m.ContextSwitches != nil { + return *m.ContextSwitches + } + return 0 +} + +func (m *PerfStatistics) GetCpuMigrations() uint64 { + if m != nil && m.CpuMigrations != nil { + return *m.CpuMigrations + } + return 0 +} + +func (m *PerfStatistics) GetAlignmentFaults() uint64 { + if m != nil && m.AlignmentFaults != nil { + return *m.AlignmentFaults + } + return 0 +} + +func (m *PerfStatistics) GetEmulationFaults() uint64 { + if m != nil && m.EmulationFaults != nil { + return *m.EmulationFaults + } + return 0 +} + +func (m *PerfStatistics) GetL1DcacheLoads() uint64 { + if m != nil && m.L1DcacheLoads != nil { + return *m.L1DcacheLoads + } + return 0 +} + +func (m *PerfStatistics) GetL1DcacheLoadMisses() uint64 { + if m != nil && m.L1DcacheLoadMisses != nil { + return *m.L1DcacheLoadMisses + } + return 0 +} + +func (m *PerfStatistics) GetL1DcacheStores() uint64 { + if m != nil && m.L1DcacheStores != nil { + return *m.L1DcacheStores + } + return 0 +} + +func (m *PerfStatistics) GetL1DcacheStoreMisses() uint64 { + if m != nil && m.L1DcacheStoreMisses != nil { + return *m.L1DcacheStoreMisses + } + return 0 +} + +func (m *PerfStatistics) GetL1DcachePrefetches() uint64 { + if m != nil && m.L1DcachePrefetches != nil { + return *m.L1DcachePrefetches + } + return 0 +} + +func (m *PerfStatistics) GetL1DcachePrefetchMisses() uint64 { + if m != nil && m.L1DcachePrefetchMisses != nil { + return *m.L1DcachePrefetchMisses + } + return 0 +} + +func (m *PerfStatistics) GetL1IcacheLoads() uint64 { + if m != nil && m.L1IcacheLoads != nil { + return *m.L1IcacheLoads + } + return 0 +} + +func (m *PerfStatistics) GetL1IcacheLoadMisses() uint64 { + if m != nil && m.L1IcacheLoadMisses != nil { + return *m.L1IcacheLoadMisses + } + return 0 +} + +func (m *PerfStatistics) GetL1IcachePrefetches() uint64 { + if m != nil && m.L1IcachePrefetches != nil { + return *m.L1IcachePrefetches + } + return 0 +} + +func (m *PerfStatistics) GetL1IcachePrefetchMisses() uint64 { + if m != nil && m.L1IcachePrefetchMisses != nil { + return *m.L1IcachePrefetchMisses + } + return 0 +} + +func (m *PerfStatistics) GetLlcLoads() uint64 { + if m != nil && m.LlcLoads != nil { + return *m.LlcLoads + } + return 0 +} + +func (m *PerfStatistics) GetLlcLoadMisses() uint64 { + if m != nil && m.LlcLoadMisses != nil { + return *m.LlcLoadMisses + } + return 0 +} + +func (m *PerfStatistics) GetLlcStores() uint64 { + if m != nil && m.LlcStores != nil { + return *m.LlcStores + } + return 0 +} + +func (m *PerfStatistics) GetLlcStoreMisses() uint64 { + if m != nil && m.LlcStoreMisses != nil { + return *m.LlcStoreMisses + } + return 0 +} + +func (m *PerfStatistics) GetLlcPrefetches() uint64 { + if m != nil && m.LlcPrefetches != nil { + return *m.LlcPrefetches + } + return 0 +} + +func (m *PerfStatistics) GetLlcPrefetchMisses() uint64 { + if m != nil && m.LlcPrefetchMisses != nil { + return *m.LlcPrefetchMisses + } + return 0 +} + +func (m *PerfStatistics) GetDtlbLoads() uint64 { + if m != nil && m.DtlbLoads != nil { + return *m.DtlbLoads + } + return 0 +} + +func (m *PerfStatistics) GetDtlbLoadMisses() uint64 { + if m != nil && m.DtlbLoadMisses != nil { + return *m.DtlbLoadMisses + } + return 0 +} + +func (m *PerfStatistics) GetDtlbStores() uint64 { + if m != nil && m.DtlbStores != nil { + return *m.DtlbStores + } + return 0 +} + +func (m *PerfStatistics) GetDtlbStoreMisses() uint64 { + if m != nil && m.DtlbStoreMisses != nil { + return *m.DtlbStoreMisses + } + return 0 +} + +func (m *PerfStatistics) GetDtlbPrefetches() uint64 { + if m != nil && m.DtlbPrefetches != nil { + return *m.DtlbPrefetches + } + return 0 +} + +func (m *PerfStatistics) GetDtlbPrefetchMisses() uint64 { + if m != nil && m.DtlbPrefetchMisses != nil { + return *m.DtlbPrefetchMisses + } + return 0 +} + +func (m *PerfStatistics) GetItlbLoads() uint64 { + if m != nil && m.ItlbLoads != nil { + return *m.ItlbLoads + } + return 0 +} + +func (m *PerfStatistics) GetItlbLoadMisses() uint64 { + if m != nil && m.ItlbLoadMisses != nil { + return *m.ItlbLoadMisses + } + return 0 +} + +func (m *PerfStatistics) GetBranchLoads() uint64 { + if m != nil && m.BranchLoads != nil { + return *m.BranchLoads + } + return 0 +} + +func (m *PerfStatistics) GetBranchLoadMisses() uint64 { + if m != nil && m.BranchLoadMisses != nil { + return *m.BranchLoadMisses + } + return 0 +} + +func (m *PerfStatistics) GetNodeLoads() uint64 { + if m != nil && m.NodeLoads != nil { + return *m.NodeLoads + } + return 0 +} + +func (m *PerfStatistics) GetNodeLoadMisses() uint64 { + if m != nil && m.NodeLoadMisses != nil { + return *m.NodeLoadMisses + } + return 0 +} + +func (m *PerfStatistics) GetNodeStores() uint64 { + if m != nil && m.NodeStores != nil { + return *m.NodeStores + } + return 0 +} + +func (m *PerfStatistics) GetNodeStoreMisses() uint64 { + if m != nil && m.NodeStoreMisses != nil { + return *m.NodeStoreMisses + } + return 0 +} + +func (m *PerfStatistics) GetNodePrefetches() uint64 { + if m != nil && m.NodePrefetches != nil { + return *m.NodePrefetches + } + return 0 +} + +func (m *PerfStatistics) GetNodePrefetchMisses() uint64 { + if m != nil && m.NodePrefetchMisses != nil { + return *m.NodePrefetchMisses + } + return 0 +} + +// * +// Describes a request for resources that can be used by a framework +// to proactively influence the allocator. If 'agent_id' is provided +// then this request is assumed to only apply to resources on that +// agent. +type Request struct { + AgentId *AgentID `protobuf:"bytes,1,opt,name=agent_id,json=agentId" json:"agent_id,omitempty"` + Resources []*Resource `protobuf:"bytes,2,rep,name=resources" json:"resources,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Request) Reset() { *m = Request{} } +func (m *Request) String() string { return proto.CompactTextString(m) } +func (*Request) ProtoMessage() {} +func (*Request) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} } + +func (m *Request) GetAgentId() *AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *Request) GetResources() []*Resource { + if m != nil { + return m.Resources + } + return nil +} + +// * +// Describes some resources available on an agent. An offer only +// contains resources from a single agent. +type Offer struct { + Id *OfferID `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` + FrameworkId *FrameworkID `protobuf:"bytes,2,req,name=framework_id,json=frameworkId" json:"framework_id,omitempty"` + AgentId *AgentID `protobuf:"bytes,3,req,name=agent_id,json=agentId" json:"agent_id,omitempty"` + Hostname *string `protobuf:"bytes,4,req,name=hostname" json:"hostname,omitempty"` + // URL for reaching the agent running on the host. + Url *URL `protobuf:"bytes,8,opt,name=url" json:"url,omitempty"` + Resources []*Resource `protobuf:"bytes,5,rep,name=resources" json:"resources,omitempty"` + Attributes []*Attribute `protobuf:"bytes,7,rep,name=attributes" json:"attributes,omitempty"` + ExecutorIds []*ExecutorID `protobuf:"bytes,6,rep,name=executor_ids,json=executorIds" json:"executor_ids,omitempty"` + // Signifies that the resources in this Offer may be unavailable during + // the given interval. Any tasks launched using these resources may be + // killed when the interval arrives. For example, these resources may be + // part of a planned maintenance schedule. + // + // This field only provides information about a planned unavailability. + // The unavailability interval may not necessarily start at exactly this + // interval, nor last for exactly the duration of this interval. + // The unavailability may also be forever! See comments in + // `Unavailability` for more details. + Unavailability *Unavailability `protobuf:"bytes,9,opt,name=unavailability" json:"unavailability,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Offer) Reset() { *m = Offer{} } +func (m *Offer) String() string { return proto.CompactTextString(m) } +func (*Offer) ProtoMessage() {} +func (*Offer) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} } + +func (m *Offer) GetId() *OfferID { + if m != nil { + return m.Id + } + return nil +} + +func (m *Offer) GetFrameworkId() *FrameworkID { + if m != nil { + return m.FrameworkId + } + return nil +} + +func (m *Offer) GetAgentId() *AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *Offer) GetHostname() string { + if m != nil && m.Hostname != nil { + return *m.Hostname + } + return "" +} + +func (m *Offer) GetUrl() *URL { + if m != nil { + return m.Url + } + return nil +} + +func (m *Offer) GetResources() []*Resource { + if m != nil { + return m.Resources + } + return nil +} + +func (m *Offer) GetAttributes() []*Attribute { + if m != nil { + return m.Attributes + } + return nil +} + +func (m *Offer) GetExecutorIds() []*ExecutorID { + if m != nil { + return m.ExecutorIds + } + return nil +} + +func (m *Offer) GetUnavailability() *Unavailability { + if m != nil { + return m.Unavailability + } + return nil +} + +// Defines an operation that can be performed against offers. +type Offer_Operation struct { + Type *Offer_Operation_Type `protobuf:"varint,1,opt,name=type,enum=mesos.v1.Offer_Operation_Type" json:"type,omitempty"` + Launch *Offer_Operation_Launch `protobuf:"bytes,2,opt,name=launch" json:"launch,omitempty"` + LaunchGroup *Offer_Operation_LaunchGroup `protobuf:"bytes,7,opt,name=launch_group,json=launchGroup" json:"launch_group,omitempty"` + Reserve *Offer_Operation_Reserve `protobuf:"bytes,3,opt,name=reserve" json:"reserve,omitempty"` + Unreserve *Offer_Operation_Unreserve `protobuf:"bytes,4,opt,name=unreserve" json:"unreserve,omitempty"` + Create *Offer_Operation_Create `protobuf:"bytes,5,opt,name=create" json:"create,omitempty"` + Destroy *Offer_Operation_Destroy `protobuf:"bytes,6,opt,name=destroy" json:"destroy,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Offer_Operation) Reset() { *m = Offer_Operation{} } +func (m *Offer_Operation) String() string { return proto.CompactTextString(m) } +func (*Offer_Operation) ProtoMessage() {} +func (*Offer_Operation) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33, 0} } + +func (m *Offer_Operation) GetType() Offer_Operation_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return Offer_Operation_UNKNOWN +} + +func (m *Offer_Operation) GetLaunch() *Offer_Operation_Launch { + if m != nil { + return m.Launch + } + return nil +} + +func (m *Offer_Operation) GetLaunchGroup() *Offer_Operation_LaunchGroup { + if m != nil { + return m.LaunchGroup + } + return nil +} + +func (m *Offer_Operation) GetReserve() *Offer_Operation_Reserve { + if m != nil { + return m.Reserve + } + return nil +} + +func (m *Offer_Operation) GetUnreserve() *Offer_Operation_Unreserve { + if m != nil { + return m.Unreserve + } + return nil +} + +func (m *Offer_Operation) GetCreate() *Offer_Operation_Create { + if m != nil { + return m.Create + } + return nil +} + +func (m *Offer_Operation) GetDestroy() *Offer_Operation_Destroy { + if m != nil { + return m.Destroy + } + return nil +} + +// TODO(vinod): Deprecate this in favor of `LaunchGroup` below. +type Offer_Operation_Launch struct { + TaskInfos []*TaskInfo `protobuf:"bytes,1,rep,name=task_infos,json=taskInfos" json:"task_infos,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Offer_Operation_Launch) Reset() { *m = Offer_Operation_Launch{} } +func (m *Offer_Operation_Launch) String() string { return proto.CompactTextString(m) } +func (*Offer_Operation_Launch) ProtoMessage() {} +func (*Offer_Operation_Launch) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33, 0, 0} } + +func (m *Offer_Operation_Launch) GetTaskInfos() []*TaskInfo { + if m != nil { + return m.TaskInfos + } + return nil +} + +// Unlike `Launch` above, all the tasks in a `task_group` are +// atomically delivered to an executor. +// +// `NetworkInfo` set on executor will be shared by all tasks in +// the task group. +// +// TODO(vinod): Any volumes set on executor could be used by a +// task by explicitly setting `Volume.source` in its resources. +type Offer_Operation_LaunchGroup struct { + Executor *ExecutorInfo `protobuf:"bytes,1,req,name=executor" json:"executor,omitempty"` + TaskGroup *TaskGroupInfo `protobuf:"bytes,2,req,name=task_group,json=taskGroup" json:"task_group,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Offer_Operation_LaunchGroup) Reset() { *m = Offer_Operation_LaunchGroup{} } +func (m *Offer_Operation_LaunchGroup) String() string { return proto.CompactTextString(m) } +func (*Offer_Operation_LaunchGroup) ProtoMessage() {} +func (*Offer_Operation_LaunchGroup) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{33, 0, 1} +} + +func (m *Offer_Operation_LaunchGroup) GetExecutor() *ExecutorInfo { + if m != nil { + return m.Executor + } + return nil +} + +func (m *Offer_Operation_LaunchGroup) GetTaskGroup() *TaskGroupInfo { + if m != nil { + return m.TaskGroup + } + return nil +} + +type Offer_Operation_Reserve struct { + Resources []*Resource `protobuf:"bytes,1,rep,name=resources" json:"resources,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Offer_Operation_Reserve) Reset() { *m = Offer_Operation_Reserve{} } +func (m *Offer_Operation_Reserve) String() string { return proto.CompactTextString(m) } +func (*Offer_Operation_Reserve) ProtoMessage() {} +func (*Offer_Operation_Reserve) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33, 0, 2} } + +func (m *Offer_Operation_Reserve) GetResources() []*Resource { + if m != nil { + return m.Resources + } + return nil +} + +type Offer_Operation_Unreserve struct { + Resources []*Resource `protobuf:"bytes,1,rep,name=resources" json:"resources,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Offer_Operation_Unreserve) Reset() { *m = Offer_Operation_Unreserve{} } +func (m *Offer_Operation_Unreserve) String() string { return proto.CompactTextString(m) } +func (*Offer_Operation_Unreserve) ProtoMessage() {} +func (*Offer_Operation_Unreserve) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{33, 0, 3} +} + +func (m *Offer_Operation_Unreserve) GetResources() []*Resource { + if m != nil { + return m.Resources + } + return nil +} + +type Offer_Operation_Create struct { + Volumes []*Resource `protobuf:"bytes,1,rep,name=volumes" json:"volumes,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Offer_Operation_Create) Reset() { *m = Offer_Operation_Create{} } +func (m *Offer_Operation_Create) String() string { return proto.CompactTextString(m) } +func (*Offer_Operation_Create) ProtoMessage() {} +func (*Offer_Operation_Create) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33, 0, 4} } + +func (m *Offer_Operation_Create) GetVolumes() []*Resource { + if m != nil { + return m.Volumes + } + return nil +} + +type Offer_Operation_Destroy struct { + Volumes []*Resource `protobuf:"bytes,1,rep,name=volumes" json:"volumes,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Offer_Operation_Destroy) Reset() { *m = Offer_Operation_Destroy{} } +func (m *Offer_Operation_Destroy) String() string { return proto.CompactTextString(m) } +func (*Offer_Operation_Destroy) ProtoMessage() {} +func (*Offer_Operation_Destroy) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33, 0, 5} } + +func (m *Offer_Operation_Destroy) GetVolumes() []*Resource { + if m != nil { + return m.Volumes + } + return nil +} + +// * +// A request to return some resources occupied by a framework. +type InverseOffer struct { + // This is the same OfferID as found in normal offers, which allows + // re-use of some of the OfferID-only messages. + Id *OfferID `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` + // URL for reaching the agent running on the host. This enables some + // optimizations as described in MESOS-3012, such as allowing the + // scheduler driver to bypass the master and talk directly with an agent. + Url *URL `protobuf:"bytes,2,opt,name=url" json:"url,omitempty"` + // The framework that should release its resources. + // If no specifics are provided (i.e. which agent), all the framework's + // resources are requested back. + FrameworkId *FrameworkID `protobuf:"bytes,3,req,name=framework_id,json=frameworkId" json:"framework_id,omitempty"` + // Specified if the resources need to be released from a particular agent. + // All the framework's resources on this agent are requested back, + // unless further qualified by the `resources` field. + AgentId *AgentID `protobuf:"bytes,4,opt,name=agent_id,json=agentId" json:"agent_id,omitempty"` + // This InverseOffer represents a planned unavailability event in the + // specified interval. Any tasks running on the given framework or agent + // may be killed when the interval arrives. Therefore, frameworks should + // aim to gracefully terminate tasks prior to the arrival of the interval. + // + // For reserved resources, the resources are expected to be returned to the + // framework after the unavailability interval. This is an expectation, + // not a guarantee. For example, if the unavailability duration is not set, + // the resources may be removed permanently. + // + // For other resources, there is no guarantee that requested resources will + // be returned after the unavailability interval. The allocator has no + // obligation to re-offer these resources to the prior framework after + // the unavailability. + Unavailability *Unavailability `protobuf:"bytes,5,req,name=unavailability" json:"unavailability,omitempty"` + // A list of resources being requested back from the framework, + // on the agent identified by `agent_id`. If no resources are specified + // then all resources are being requested back. For the purpose of + // maintenance, this field is always empty (maintenance always requests + // all resources back). + Resources []*Resource `protobuf:"bytes,6,rep,name=resources" json:"resources,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *InverseOffer) Reset() { *m = InverseOffer{} } +func (m *InverseOffer) String() string { return proto.CompactTextString(m) } +func (*InverseOffer) ProtoMessage() {} +func (*InverseOffer) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} } + +func (m *InverseOffer) GetId() *OfferID { + if m != nil { + return m.Id + } + return nil +} + +func (m *InverseOffer) GetUrl() *URL { + if m != nil { + return m.Url + } + return nil +} + +func (m *InverseOffer) GetFrameworkId() *FrameworkID { + if m != nil { + return m.FrameworkId + } + return nil +} + +func (m *InverseOffer) GetAgentId() *AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *InverseOffer) GetUnavailability() *Unavailability { + if m != nil { + return m.Unavailability + } + return nil +} + +func (m *InverseOffer) GetResources() []*Resource { + if m != nil { + return m.Resources + } + return nil +} + +// * +// Describes a task. Passed from the scheduler all the way to an +// executor (see SchedulerDriver::launchTasks and +// Executor::launchTask). Either ExecutorInfo or CommandInfo should be set. +// A different executor can be used to launch this task, and subsequent tasks +// meant for the same executor can reuse the same ExecutorInfo struct. +type TaskInfo struct { + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + TaskId *TaskID `protobuf:"bytes,2,req,name=task_id,json=taskId" json:"task_id,omitempty"` + AgentId *AgentID `protobuf:"bytes,3,req,name=agent_id,json=agentId" json:"agent_id,omitempty"` + Resources []*Resource `protobuf:"bytes,4,rep,name=resources" json:"resources,omitempty"` + Executor *ExecutorInfo `protobuf:"bytes,5,opt,name=executor" json:"executor,omitempty"` + Command *CommandInfo `protobuf:"bytes,7,opt,name=command" json:"command,omitempty"` + // Task provided with a container will launch the container as part + // of this task paired with the task's CommandInfo. + Container *ContainerInfo `protobuf:"bytes,9,opt,name=container" json:"container,omitempty"` + // A health check for the task. Implemented for executor-less + // command-based tasks. For tasks that specify an executor, it is + // the executor's responsibility to implement the health checking. + HealthCheck *HealthCheck `protobuf:"bytes,8,opt,name=health_check,json=healthCheck" json:"health_check,omitempty"` + // A kill policy for the task. Implemented for executor-less + // command-based and docker tasks. For tasks that specify other + // executor, it is the executor's responsibility to implement + // the kill policy. + KillPolicy *KillPolicy `protobuf:"bytes,12,opt,name=kill_policy,json=killPolicy" json:"kill_policy,omitempty"` + Data []byte `protobuf:"bytes,6,opt,name=data" json:"data,omitempty"` + // Labels are free-form key value pairs which are exposed through + // master and agent endpoints. Labels will not be interpreted or + // acted upon by Mesos itself. As opposed to the data field, labels + // will be kept in memory on master and agent processes. Therefore, + // labels should be used to tag tasks with light-weight meta-data. + // Labels should not contain duplicate key-value pairs. + Labels *Labels `protobuf:"bytes,10,opt,name=labels" json:"labels,omitempty"` + // Service discovery information for the task. It is not interpreted + // or acted upon by Mesos. It is up to a service discovery system + // to use this information as needed and to handle tasks without + // service discovery information. + Discovery *DiscoveryInfo `protobuf:"bytes,11,opt,name=discovery" json:"discovery,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *TaskInfo) Reset() { *m = TaskInfo{} } +func (m *TaskInfo) String() string { return proto.CompactTextString(m) } +func (*TaskInfo) ProtoMessage() {} +func (*TaskInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} } + +func (m *TaskInfo) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *TaskInfo) GetTaskId() *TaskID { + if m != nil { + return m.TaskId + } + return nil +} + +func (m *TaskInfo) GetAgentId() *AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *TaskInfo) GetResources() []*Resource { + if m != nil { + return m.Resources + } + return nil +} + +func (m *TaskInfo) GetExecutor() *ExecutorInfo { + if m != nil { + return m.Executor + } + return nil +} + +func (m *TaskInfo) GetCommand() *CommandInfo { + if m != nil { + return m.Command + } + return nil +} + +func (m *TaskInfo) GetContainer() *ContainerInfo { + if m != nil { + return m.Container + } + return nil +} + +func (m *TaskInfo) GetHealthCheck() *HealthCheck { + if m != nil { + return m.HealthCheck + } + return nil +} + +func (m *TaskInfo) GetKillPolicy() *KillPolicy { + if m != nil { + return m.KillPolicy + } + return nil +} + +func (m *TaskInfo) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *TaskInfo) GetLabels() *Labels { + if m != nil { + return m.Labels + } + return nil +} + +func (m *TaskInfo) GetDiscovery() *DiscoveryInfo { + if m != nil { + return m.Discovery + } + return nil +} + +// * +// Describes a group of tasks that belong to an executor. The +// executor will receive the task group in a single message to +// allow the group to be launched "atomically". +// +// NOTES: +// 1) `NetworkInfo` must not be set inside task's `ContainerInfo`. +// 2) `TaskInfo.executor` doesn't need to set. If set, it should match +// `LaunchGroup.executor`. +type TaskGroupInfo struct { + Tasks []*TaskInfo `protobuf:"bytes,1,rep,name=tasks" json:"tasks,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *TaskGroupInfo) Reset() { *m = TaskGroupInfo{} } +func (m *TaskGroupInfo) String() string { return proto.CompactTextString(m) } +func (*TaskGroupInfo) ProtoMessage() {} +func (*TaskGroupInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} } + +func (m *TaskGroupInfo) GetTasks() []*TaskInfo { + if m != nil { + return m.Tasks + } + return nil +} + +// * +// Describes a task, similar to `TaskInfo`. +// +// `Task` is used in some of the Mesos messages found below. +// `Task` is used instead of `TaskInfo` if: +// 1) we need additional IDs, such as a specific +// framework, executor, or agent; or +// 2) we do not need the additional data, such as the command run by the +// task or the health checks. These additional fields may be large and +// unnecessary for some Mesos messages. +// +// `Task` is generally constructed from a `TaskInfo`. See protobuf::createTask. +type Task struct { + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + TaskId *TaskID `protobuf:"bytes,2,req,name=task_id,json=taskId" json:"task_id,omitempty"` + FrameworkId *FrameworkID `protobuf:"bytes,3,req,name=framework_id,json=frameworkId" json:"framework_id,omitempty"` + ExecutorId *ExecutorID `protobuf:"bytes,4,opt,name=executor_id,json=executorId" json:"executor_id,omitempty"` + AgentId *AgentID `protobuf:"bytes,5,req,name=agent_id,json=agentId" json:"agent_id,omitempty"` + State *TaskState `protobuf:"varint,6,req,name=state,enum=mesos.v1.TaskState" json:"state,omitempty"` + Resources []*Resource `protobuf:"bytes,7,rep,name=resources" json:"resources,omitempty"` + Statuses []*TaskStatus `protobuf:"bytes,8,rep,name=statuses" json:"statuses,omitempty"` + // These fields correspond to the state and uuid of the latest + // status update forwarded to the master. + // NOTE: Either both the fields must be set or both must be unset. + StatusUpdateState *TaskState `protobuf:"varint,9,opt,name=status_update_state,json=statusUpdateState,enum=mesos.v1.TaskState" json:"status_update_state,omitempty"` + StatusUpdateUuid []byte `protobuf:"bytes,10,opt,name=status_update_uuid,json=statusUpdateUuid" json:"status_update_uuid,omitempty"` + Labels *Labels `protobuf:"bytes,11,opt,name=labels" json:"labels,omitempty"` + // Service discovery information for the task. It is not interpreted + // or acted upon by Mesos. It is up to a service discovery system + // to use this information as needed and to handle tasks without + // service discovery information. + Discovery *DiscoveryInfo `protobuf:"bytes,12,opt,name=discovery" json:"discovery,omitempty"` + // Container information for the task. + Container *ContainerInfo `protobuf:"bytes,13,opt,name=container" json:"container,omitempty"` + // Specific user under which task is running. + User *string `protobuf:"bytes,14,opt,name=user" json:"user,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Task) Reset() { *m = Task{} } +func (m *Task) String() string { return proto.CompactTextString(m) } +func (*Task) ProtoMessage() {} +func (*Task) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} } + +func (m *Task) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Task) GetTaskId() *TaskID { + if m != nil { + return m.TaskId + } + return nil +} + +func (m *Task) GetFrameworkId() *FrameworkID { + if m != nil { + return m.FrameworkId + } + return nil +} + +func (m *Task) GetExecutorId() *ExecutorID { + if m != nil { + return m.ExecutorId + } + return nil +} + +func (m *Task) GetAgentId() *AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *Task) GetState() TaskState { + if m != nil && m.State != nil { + return *m.State + } + return TaskState_TASK_STAGING +} + +func (m *Task) GetResources() []*Resource { + if m != nil { + return m.Resources + } + return nil +} + +func (m *Task) GetStatuses() []*TaskStatus { + if m != nil { + return m.Statuses + } + return nil +} + +func (m *Task) GetStatusUpdateState() TaskState { + if m != nil && m.StatusUpdateState != nil { + return *m.StatusUpdateState + } + return TaskState_TASK_STAGING +} + +func (m *Task) GetStatusUpdateUuid() []byte { + if m != nil { + return m.StatusUpdateUuid + } + return nil +} + +func (m *Task) GetLabels() *Labels { + if m != nil { + return m.Labels + } + return nil +} + +func (m *Task) GetDiscovery() *DiscoveryInfo { + if m != nil { + return m.Discovery + } + return nil +} + +func (m *Task) GetContainer() *ContainerInfo { + if m != nil { + return m.Container + } + return nil +} + +func (m *Task) GetUser() string { + if m != nil && m.User != nil { + return *m.User + } + return "" +} + +// * +// Describes the current status of a task. +type TaskStatus struct { + TaskId *TaskID `protobuf:"bytes,1,req,name=task_id,json=taskId" json:"task_id,omitempty"` + State *TaskState `protobuf:"varint,2,req,name=state,enum=mesos.v1.TaskState" json:"state,omitempty"` + Message *string `protobuf:"bytes,4,opt,name=message" json:"message,omitempty"` + Source *TaskStatus_Source `protobuf:"varint,9,opt,name=source,enum=mesos.v1.TaskStatus_Source" json:"source,omitempty"` + Reason *TaskStatus_Reason `protobuf:"varint,10,opt,name=reason,enum=mesos.v1.TaskStatus_Reason" json:"reason,omitempty"` + Data []byte `protobuf:"bytes,3,opt,name=data" json:"data,omitempty"` + AgentId *AgentID `protobuf:"bytes,5,opt,name=agent_id,json=agentId" json:"agent_id,omitempty"` + ExecutorId *ExecutorID `protobuf:"bytes,7,opt,name=executor_id,json=executorId" json:"executor_id,omitempty"` + Timestamp *float64 `protobuf:"fixed64,6,opt,name=timestamp" json:"timestamp,omitempty"` + // Statuses that are delivered reliably to the scheduler will + // include a 'uuid'. The status is considered delivered once + // it is acknowledged by the scheduler. Schedulers can choose + // to either explicitly acknowledge statuses or let the scheduler + // driver implicitly acknowledge (default). + // + // TODO(bmahler): This is currently overwritten in the scheduler + // driver and executor driver, but executors will need to set this + // to a valid RFC-4122 UUID if using the HTTP API. + Uuid []byte `protobuf:"bytes,11,opt,name=uuid" json:"uuid,omitempty"` + // Describes whether the task has been determined to be healthy + // (true) or unhealthy (false) according to the HealthCheck field in + // the command info. + Healthy *bool `protobuf:"varint,8,opt,name=healthy" json:"healthy,omitempty"` + // Labels are free-form key value pairs which are exposed through + // master and agent endpoints. Labels will not be interpreted or + // acted upon by Mesos itself. As opposed to the data field, labels + // will be kept in memory on master and agent processes. Therefore, + // labels should be used to tag TaskStatus message with light-weight + // meta-data. Labels should not contain duplicate key-value pairs. + Labels *Labels `protobuf:"bytes,12,opt,name=labels" json:"labels,omitempty"` + // Container related information that is resolved dynamically such as + // network address. + ContainerStatus *ContainerStatus `protobuf:"bytes,13,opt,name=container_status,json=containerStatus" json:"container_status,omitempty"` + // The time (according to the master's clock) when the agent where + // this task was running became unreachable. This is only set on + // status updates for tasks running on agents that are unreachable + // (e.g., partitioned away from the master). + UnreachableTime *TimeInfo `protobuf:"bytes,14,opt,name=unreachable_time,json=unreachableTime" json:"unreachable_time,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *TaskStatus) Reset() { *m = TaskStatus{} } +func (m *TaskStatus) String() string { return proto.CompactTextString(m) } +func (*TaskStatus) ProtoMessage() {} +func (*TaskStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{38} } + +func (m *TaskStatus) GetTaskId() *TaskID { + if m != nil { + return m.TaskId + } + return nil +} + +func (m *TaskStatus) GetState() TaskState { + if m != nil && m.State != nil { + return *m.State + } + return TaskState_TASK_STAGING +} + +func (m *TaskStatus) GetMessage() string { + if m != nil && m.Message != nil { + return *m.Message + } + return "" +} + +func (m *TaskStatus) GetSource() TaskStatus_Source { + if m != nil && m.Source != nil { + return *m.Source + } + return TaskStatus_SOURCE_MASTER +} + +func (m *TaskStatus) GetReason() TaskStatus_Reason { + if m != nil && m.Reason != nil { + return *m.Reason + } + return TaskStatus_REASON_COMMAND_EXECUTOR_FAILED +} + +func (m *TaskStatus) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *TaskStatus) GetAgentId() *AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *TaskStatus) GetExecutorId() *ExecutorID { + if m != nil { + return m.ExecutorId + } + return nil +} + +func (m *TaskStatus) GetTimestamp() float64 { + if m != nil && m.Timestamp != nil { + return *m.Timestamp + } + return 0 +} + +func (m *TaskStatus) GetUuid() []byte { + if m != nil { + return m.Uuid + } + return nil +} + +func (m *TaskStatus) GetHealthy() bool { + if m != nil && m.Healthy != nil { + return *m.Healthy + } + return false +} + +func (m *TaskStatus) GetLabels() *Labels { + if m != nil { + return m.Labels + } + return nil +} + +func (m *TaskStatus) GetContainerStatus() *ContainerStatus { + if m != nil { + return m.ContainerStatus + } + return nil +} + +func (m *TaskStatus) GetUnreachableTime() *TimeInfo { + if m != nil { + return m.UnreachableTime + } + return nil +} + +// * +// Describes possible filters that can be applied to unused resources +// (see SchedulerDriver::launchTasks) to influence the allocator. +type Filters struct { + // Time to consider unused resources refused. Note that all unused + // resources will be considered refused and use the default value + // (below) regardless of whether Filters was passed to + // SchedulerDriver::launchTasks. You MUST pass Filters with this + // field set to change this behavior (i.e., get another offer which + // includes unused resources sooner or later than the default). + RefuseSeconds *float64 `protobuf:"fixed64,1,opt,name=refuse_seconds,json=refuseSeconds,def=5" json:"refuse_seconds,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Filters) Reset() { *m = Filters{} } +func (m *Filters) String() string { return proto.CompactTextString(m) } +func (*Filters) ProtoMessage() {} +func (*Filters) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} } + +const Default_Filters_RefuseSeconds float64 = 5 + +func (m *Filters) GetRefuseSeconds() float64 { + if m != nil && m.RefuseSeconds != nil { + return *m.RefuseSeconds + } + return Default_Filters_RefuseSeconds +} + +// * +// Describes a collection of environment variables. This is used with +// CommandInfo in order to set environment variables before running a +// command. +type Environment struct { + Variables []*Environment_Variable `protobuf:"bytes,1,rep,name=variables" json:"variables,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Environment) Reset() { *m = Environment{} } +func (m *Environment) String() string { return proto.CompactTextString(m) } +func (*Environment) ProtoMessage() {} +func (*Environment) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{40} } + +func (m *Environment) GetVariables() []*Environment_Variable { + if m != nil { + return m.Variables + } + return nil +} + +type Environment_Variable struct { + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + Value *string `protobuf:"bytes,2,req,name=value" json:"value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Environment_Variable) Reset() { *m = Environment_Variable{} } +func (m *Environment_Variable) String() string { return proto.CompactTextString(m) } +func (*Environment_Variable) ProtoMessage() {} +func (*Environment_Variable) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{40, 0} } + +func (m *Environment_Variable) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Environment_Variable) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +// * +// A generic (key, value) pair used in various places for parameters. +type Parameter struct { + Key *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"` + Value *string `protobuf:"bytes,2,req,name=value" json:"value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Parameter) Reset() { *m = Parameter{} } +func (m *Parameter) String() string { return proto.CompactTextString(m) } +func (*Parameter) ProtoMessage() {} +func (*Parameter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{41} } + +func (m *Parameter) GetKey() string { + if m != nil && m.Key != nil { + return *m.Key + } + return "" +} + +func (m *Parameter) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +// * +// Collection of Parameter. +type Parameters struct { + Parameter []*Parameter `protobuf:"bytes,1,rep,name=parameter" json:"parameter,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Parameters) Reset() { *m = Parameters{} } +func (m *Parameters) String() string { return proto.CompactTextString(m) } +func (*Parameters) ProtoMessage() {} +func (*Parameters) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{42} } + +func (m *Parameters) GetParameter() []*Parameter { + if m != nil { + return m.Parameter + } + return nil +} + +// * +// Credential used in various places for authentication and +// authorization. +// +// NOTE: A 'principal' is different from 'FrameworkInfo.user'. The +// former is used for authentication and authorization while the +// latter is used to determine the default user under which the +// framework's executors/tasks are run. +type Credential struct { + Principal *string `protobuf:"bytes,1,req,name=principal" json:"principal,omitempty"` + Secret *string `protobuf:"bytes,2,opt,name=secret" json:"secret,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Credential) Reset() { *m = Credential{} } +func (m *Credential) String() string { return proto.CompactTextString(m) } +func (*Credential) ProtoMessage() {} +func (*Credential) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{43} } + +func (m *Credential) GetPrincipal() string { + if m != nil && m.Principal != nil { + return *m.Principal + } + return "" +} + +func (m *Credential) GetSecret() string { + if m != nil && m.Secret != nil { + return *m.Secret + } + return "" +} + +// * +// Credentials used for framework authentication, HTTP authentication +// (where the common 'username' and 'password' are captured as +// 'principal' and 'secret' respectively), etc. +type Credentials struct { + Credentials []*Credential `protobuf:"bytes,1,rep,name=credentials" json:"credentials,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Credentials) Reset() { *m = Credentials{} } +func (m *Credentials) String() string { return proto.CompactTextString(m) } +func (*Credentials) ProtoMessage() {} +func (*Credentials) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{44} } + +func (m *Credentials) GetCredentials() []*Credential { + if m != nil { + return m.Credentials + } + return nil +} + +// * +// Rate (queries per second, QPS) limit for messages from a framework to master. +// Strictly speaking they are the combined rate from all frameworks of the same +// principal. +type RateLimit struct { + // Leaving QPS unset gives it unlimited rate (i.e., not throttled), + // which also implies unlimited capacity. + Qps *float64 `protobuf:"fixed64,1,opt,name=qps" json:"qps,omitempty"` + // Principal of framework(s) to be throttled. Should match + // FrameworkInfo.principal and Credential.principal (if using authentication). + Principal *string `protobuf:"bytes,2,req,name=principal" json:"principal,omitempty"` + // Max number of outstanding messages from frameworks of this principal + // allowed by master before the next message is dropped and an error is sent + // back to the sender. Messages received before the capacity is reached are + // still going to be processed after the error is sent. + // If unspecified, this principal is assigned unlimited capacity. + // NOTE: This value is ignored if 'qps' is not set. + Capacity *uint64 `protobuf:"varint,3,opt,name=capacity" json:"capacity,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *RateLimit) Reset() { *m = RateLimit{} } +func (m *RateLimit) String() string { return proto.CompactTextString(m) } +func (*RateLimit) ProtoMessage() {} +func (*RateLimit) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{45} } + +func (m *RateLimit) GetQps() float64 { + if m != nil && m.Qps != nil { + return *m.Qps + } + return 0 +} + +func (m *RateLimit) GetPrincipal() string { + if m != nil && m.Principal != nil { + return *m.Principal + } + return "" +} + +func (m *RateLimit) GetCapacity() uint64 { + if m != nil && m.Capacity != nil { + return *m.Capacity + } + return 0 +} + +// * +// Collection of RateLimit. +// Frameworks without rate limits defined here are not throttled unless +// 'aggregate_default_qps' is specified. +type RateLimits struct { + // Items should have unique principals. + Limits []*RateLimit `protobuf:"bytes,1,rep,name=limits" json:"limits,omitempty"` + // All the frameworks not specified in 'limits' get this default rate. + // This rate is an aggregate rate for all of them, i.e., their combined + // traffic is throttled together at this rate. + AggregateDefaultQps *float64 `protobuf:"fixed64,2,opt,name=aggregate_default_qps,json=aggregateDefaultQps" json:"aggregate_default_qps,omitempty"` + // All the frameworks not specified in 'limits' get this default capacity. + // This is an aggregate value similar to 'aggregate_default_qps'. + AggregateDefaultCapacity *uint64 `protobuf:"varint,3,opt,name=aggregate_default_capacity,json=aggregateDefaultCapacity" json:"aggregate_default_capacity,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *RateLimits) Reset() { *m = RateLimits{} } +func (m *RateLimits) String() string { return proto.CompactTextString(m) } +func (*RateLimits) ProtoMessage() {} +func (*RateLimits) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{46} } + +func (m *RateLimits) GetLimits() []*RateLimit { + if m != nil { + return m.Limits + } + return nil +} + +func (m *RateLimits) GetAggregateDefaultQps() float64 { + if m != nil && m.AggregateDefaultQps != nil { + return *m.AggregateDefaultQps + } + return 0 +} + +func (m *RateLimits) GetAggregateDefaultCapacity() uint64 { + if m != nil && m.AggregateDefaultCapacity != nil { + return *m.AggregateDefaultCapacity + } + return 0 +} + +// * +// Describe an image used by tasks or executors. Note that it's only +// for tasks or executors launched by MesosContainerizer currently. +type Image struct { + Type *Image_Type `protobuf:"varint,1,req,name=type,enum=mesos.v1.Image_Type" json:"type,omitempty"` + // Only one of the following image messages should be set to match + // the type. + Appc *Image_Appc `protobuf:"bytes,2,opt,name=appc" json:"appc,omitempty"` + Docker *Image_Docker `protobuf:"bytes,3,opt,name=docker" json:"docker,omitempty"` + // With this flag set to false, the mesos containerizer will pull + // the docker/appc image from the registry even if the image is + // already downloaded on the agent. + Cached *bool `protobuf:"varint,4,opt,name=cached,def=1" json:"cached,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Image) Reset() { *m = Image{} } +func (m *Image) String() string { return proto.CompactTextString(m) } +func (*Image) ProtoMessage() {} +func (*Image) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{47} } + +const Default_Image_Cached bool = true + +func (m *Image) GetType() Image_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return Image_APPC +} + +func (m *Image) GetAppc() *Image_Appc { + if m != nil { + return m.Appc + } + return nil +} + +func (m *Image) GetDocker() *Image_Docker { + if m != nil { + return m.Docker + } + return nil +} + +func (m *Image) GetCached() bool { + if m != nil && m.Cached != nil { + return *m.Cached + } + return Default_Image_Cached +} + +// Protobuf for specifying an Appc container image. See: +// https://github.com/appc/spec/blob/master/spec/aci.md +type Image_Appc struct { + // The name of the image. + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + // An image ID is a string of the format "hash-value", where + // "hash" is the hash algorithm used and "value" is the hex + // encoded string of the digest. Currently the only permitted + // hash algorithm is sha512. + Id *string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` + // Optional labels. Suggested labels: "version", "os", and "arch". + Labels *Labels `protobuf:"bytes,3,opt,name=labels" json:"labels,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Image_Appc) Reset() { *m = Image_Appc{} } +func (m *Image_Appc) String() string { return proto.CompactTextString(m) } +func (*Image_Appc) ProtoMessage() {} +func (*Image_Appc) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{47, 0} } + +func (m *Image_Appc) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Image_Appc) GetId() string { + if m != nil && m.Id != nil { + return *m.Id + } + return "" +} + +func (m *Image_Appc) GetLabels() *Labels { + if m != nil { + return m.Labels + } + return nil +} + +type Image_Docker struct { + // The name of the image. Expected format: + // [REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG|@TYPE:DIGEST] + // + // See: https://docs.docker.com/reference/commandline/pull/ + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + // Credential to authenticate with docker registry. + // NOTE: This is not encrypted, therefore framework and operators + // should enable SSL when passing this information. + Credential *Credential `protobuf:"bytes,2,opt,name=credential" json:"credential,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Image_Docker) Reset() { *m = Image_Docker{} } +func (m *Image_Docker) String() string { return proto.CompactTextString(m) } +func (*Image_Docker) ProtoMessage() {} +func (*Image_Docker) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{47, 1} } + +func (m *Image_Docker) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Image_Docker) GetCredential() *Credential { + if m != nil { + return m.Credential + } + return nil +} + +// * +// Describes a volume mapping either from host to container or vice +// versa. Both paths can either refer to a directory or a file. +type Volume struct { + // TODO(gyliu513): Make this as `optional` after deprecation cycle of 1.0. + Mode *Volume_Mode `protobuf:"varint,3,req,name=mode,enum=mesos.v1.Volume_Mode" json:"mode,omitempty"` + // Path pointing to a directory or file in the container. If the + // path is a relative path, it is relative to the container work + // directory. If the path is an absolute path, that path must + // already exist. + ContainerPath *string `protobuf:"bytes,1,req,name=container_path,json=containerPath" json:"container_path,omitempty"` + // Absolute path pointing to a directory or file on the host or a + // path relative to the container work directory. + HostPath *string `protobuf:"bytes,2,opt,name=host_path,json=hostPath" json:"host_path,omitempty"` + // The source of the volume is an Image which describes a root + // filesystem which will be provisioned by Mesos. + Image *Image `protobuf:"bytes,4,opt,name=image" json:"image,omitempty"` + Source *Volume_Source `protobuf:"bytes,5,opt,name=source" json:"source,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Volume) Reset() { *m = Volume{} } +func (m *Volume) String() string { return proto.CompactTextString(m) } +func (*Volume) ProtoMessage() {} +func (*Volume) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{48} } + +func (m *Volume) GetMode() Volume_Mode { + if m != nil && m.Mode != nil { + return *m.Mode + } + return Volume_RW +} + +func (m *Volume) GetContainerPath() string { + if m != nil && m.ContainerPath != nil { + return *m.ContainerPath + } + return "" +} + +func (m *Volume) GetHostPath() string { + if m != nil && m.HostPath != nil { + return *m.HostPath + } + return "" +} + +func (m *Volume) GetImage() *Image { + if m != nil { + return m.Image + } + return nil +} + +func (m *Volume) GetSource() *Volume_Source { + if m != nil { + return m.Source + } + return nil +} + +// Describes where a volume originates from. +type Volume_Source struct { + // Enum fields should be optional, see: MESOS-4997. + Type *Volume_Source_Type `protobuf:"varint,1,opt,name=type,enum=mesos.v1.Volume_Source_Type" json:"type,omitempty"` + // The source of the volume created by docker volume driver. + DockerVolume *Volume_Source_DockerVolume `protobuf:"bytes,2,opt,name=docker_volume,json=dockerVolume" json:"docker_volume,omitempty"` + SandboxPath *Volume_Source_SandboxPath `protobuf:"bytes,3,opt,name=sandbox_path,json=sandboxPath" json:"sandbox_path,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Volume_Source) Reset() { *m = Volume_Source{} } +func (m *Volume_Source) String() string { return proto.CompactTextString(m) } +func (*Volume_Source) ProtoMessage() {} +func (*Volume_Source) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{48, 0} } + +func (m *Volume_Source) GetType() Volume_Source_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return Volume_Source_UNKNOWN +} + +func (m *Volume_Source) GetDockerVolume() *Volume_Source_DockerVolume { + if m != nil { + return m.DockerVolume + } + return nil +} + +func (m *Volume_Source) GetSandboxPath() *Volume_Source_SandboxPath { + if m != nil { + return m.SandboxPath + } + return nil +} + +type Volume_Source_DockerVolume struct { + // Driver of the volume, it can be flocker, convoy, raxrey etc. + Driver *string `protobuf:"bytes,1,opt,name=driver" json:"driver,omitempty"` + // Name of the volume. + Name *string `protobuf:"bytes,2,req,name=name" json:"name,omitempty"` + // Volume driver specific options. + DriverOptions *Parameters `protobuf:"bytes,3,opt,name=driver_options,json=driverOptions" json:"driver_options,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Volume_Source_DockerVolume) Reset() { *m = Volume_Source_DockerVolume{} } +func (m *Volume_Source_DockerVolume) String() string { return proto.CompactTextString(m) } +func (*Volume_Source_DockerVolume) ProtoMessage() {} +func (*Volume_Source_DockerVolume) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{48, 0, 0} +} + +func (m *Volume_Source_DockerVolume) GetDriver() string { + if m != nil && m.Driver != nil { + return *m.Driver + } + return "" +} + +func (m *Volume_Source_DockerVolume) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Volume_Source_DockerVolume) GetDriverOptions() *Parameters { + if m != nil { + return m.DriverOptions + } + return nil +} + +// Describe a path from a container's sandbox. The container can +// be the current container (SELF), or its parent container +// (PARENT). PARENT allows all child containers to share a volume +// from their parent container's sandbox. It'll be an error if +// the current container is a top level container. +type Volume_Source_SandboxPath struct { + Type *Volume_Source_SandboxPath_Type `protobuf:"varint,1,opt,name=type,enum=mesos.v1.Volume_Source_SandboxPath_Type" json:"type,omitempty"` + // A path relative to the corresponding container's sandbox. + // Note that upwards traversal (i.e. ../../abc) is not allowed. + Path *string `protobuf:"bytes,2,req,name=path" json:"path,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Volume_Source_SandboxPath) Reset() { *m = Volume_Source_SandboxPath{} } +func (m *Volume_Source_SandboxPath) String() string { return proto.CompactTextString(m) } +func (*Volume_Source_SandboxPath) ProtoMessage() {} +func (*Volume_Source_SandboxPath) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{48, 0, 1} +} + +func (m *Volume_Source_SandboxPath) GetType() Volume_Source_SandboxPath_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return Volume_Source_SandboxPath_UNKNOWN +} + +func (m *Volume_Source_SandboxPath) GetPath() string { + if m != nil && m.Path != nil { + return *m.Path + } + return "" +} + +// * +// Describes a network request from a framework as well as network resolution +// provided by Mesos. +// +// A framework may request the network isolator on the Agent to isolate the +// container in a network namespace and create a virtual network interface. +// The `NetworkInfo` message describes the properties of that virtual +// interface, including the IP addresses and network isolation policy +// (network group membership). +// +// The NetworkInfo message is not interpreted by the Master or Agent and is +// intended to be used by Agent and Master modules implementing network +// isolation. If the modules are missing, the message is simply ignored. In +// future, the task launch will fail if there is no module providing the +// network isolation capabilities (MESOS-3390). +// +// An executor, Agent, or an Agent module may append NetworkInfos inside +// TaskStatus::container_status to provide information such as the container IP +// address and isolation groups. +type NetworkInfo struct { + // When included in a ContainerInfo, each of these represent a + // request for an IP address. Each request can specify an explicit address + // or the IP protocol to use. + // + // When included in a TaskStatus message, these inform the framework + // scheduler about the IP addresses that are bound to the container + // interface. When there are no custom network isolator modules installed, + // this field is filled in automatically with the Agent IP address. + IpAddresses []*NetworkInfo_IPAddress `protobuf:"bytes,5,rep,name=ip_addresses,json=ipAddresses" json:"ip_addresses,omitempty"` + // Name of the network which will be used by network isolator to determine + // the network that the container joins. It's up to the network isolator + // to decide how to interpret this field. + Name *string `protobuf:"bytes,6,opt,name=name" json:"name,omitempty"` + // A group is the name given to a set of logically-related interfaces that + // are allowed to communicate among themselves. Network traffic is allowed + // between two container interfaces that share at least one network group. + // For example, one might want to create separate groups for isolating dev, + // testing, qa and prod deployment environments. + Groups []string `protobuf:"bytes,3,rep,name=groups" json:"groups,omitempty"` + // To tag certain metadata to be used by Isolator/IPAM, e.g., rack, etc. + Labels *Labels `protobuf:"bytes,4,opt,name=labels" json:"labels,omitempty"` + PortMappings []*NetworkInfo_PortMapping `protobuf:"bytes,7,rep,name=port_mappings,json=portMappings" json:"port_mappings,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *NetworkInfo) Reset() { *m = NetworkInfo{} } +func (m *NetworkInfo) String() string { return proto.CompactTextString(m) } +func (*NetworkInfo) ProtoMessage() {} +func (*NetworkInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{49} } + +func (m *NetworkInfo) GetIpAddresses() []*NetworkInfo_IPAddress { + if m != nil { + return m.IpAddresses + } + return nil +} + +func (m *NetworkInfo) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *NetworkInfo) GetGroups() []string { + if m != nil { + return m.Groups + } + return nil +} + +func (m *NetworkInfo) GetLabels() *Labels { + if m != nil { + return m.Labels + } + return nil +} + +func (m *NetworkInfo) GetPortMappings() []*NetworkInfo_PortMapping { + if m != nil { + return m.PortMappings + } + return nil +} + +// Specifies a request for an IP address, or reports the assigned container +// IP address. +// +// Users can request an automatically assigned IP (for example, via an +// IPAM service) or a specific IP by adding a NetworkInfo to the +// ContainerInfo for a task. On a request, specifying neither `protocol` +// nor `ip_address` means that any available address may be assigned. +type NetworkInfo_IPAddress struct { + // Specify IP address requirement. Set protocol to the desired value to + // request the network isolator on the Agent to assign an IP address to the + // container being launched. If a specific IP address is specified in + // ip_address, this field should not be set. + Protocol *NetworkInfo_Protocol `protobuf:"varint,1,opt,name=protocol,enum=mesos.v1.NetworkInfo_Protocol" json:"protocol,omitempty"` + // Statically assigned IP provided by the Framework. This IP will be + // assigned to the container by the network isolator module on the Agent. + // This field should not be used with the protocol field above. + // + // If an explicit address is requested but is unavailable, the network + // isolator should fail the task. + IpAddress *string `protobuf:"bytes,2,opt,name=ip_address,json=ipAddress" json:"ip_address,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *NetworkInfo_IPAddress) Reset() { *m = NetworkInfo_IPAddress{} } +func (m *NetworkInfo_IPAddress) String() string { return proto.CompactTextString(m) } +func (*NetworkInfo_IPAddress) ProtoMessage() {} +func (*NetworkInfo_IPAddress) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{49, 0} } + +func (m *NetworkInfo_IPAddress) GetProtocol() NetworkInfo_Protocol { + if m != nil && m.Protocol != nil { + return *m.Protocol + } + return NetworkInfo_IPv4 +} + +func (m *NetworkInfo_IPAddress) GetIpAddress() string { + if m != nil && m.IpAddress != nil { + return *m.IpAddress + } + return "" +} + +// Specifies a port mapping request for the task on this network. +type NetworkInfo_PortMapping struct { + HostPort *uint32 `protobuf:"varint,1,req,name=host_port,json=hostPort" json:"host_port,omitempty"` + ContainerPort *uint32 `protobuf:"varint,2,req,name=container_port,json=containerPort" json:"container_port,omitempty"` + // Protocol to expose as (ie: tcp, udp). + Protocol *string `protobuf:"bytes,3,opt,name=protocol" json:"protocol,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *NetworkInfo_PortMapping) Reset() { *m = NetworkInfo_PortMapping{} } +func (m *NetworkInfo_PortMapping) String() string { return proto.CompactTextString(m) } +func (*NetworkInfo_PortMapping) ProtoMessage() {} +func (*NetworkInfo_PortMapping) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{49, 1} } + +func (m *NetworkInfo_PortMapping) GetHostPort() uint32 { + if m != nil && m.HostPort != nil { + return *m.HostPort + } + return 0 +} + +func (m *NetworkInfo_PortMapping) GetContainerPort() uint32 { + if m != nil && m.ContainerPort != nil { + return *m.ContainerPort + } + return 0 +} + +func (m *NetworkInfo_PortMapping) GetProtocol() string { + if m != nil && m.Protocol != nil { + return *m.Protocol + } + return "" +} + +// * +// Encapsulation of `Capabilities` supported by Linux. +// Reference: http://linux.die.net/man/7/capabilities. +type CapabilityInfo struct { + Capabilities []CapabilityInfo_Capability `protobuf:"varint,1,rep,name=capabilities,enum=mesos.v1.CapabilityInfo_Capability" json:"capabilities,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *CapabilityInfo) Reset() { *m = CapabilityInfo{} } +func (m *CapabilityInfo) String() string { return proto.CompactTextString(m) } +func (*CapabilityInfo) ProtoMessage() {} +func (*CapabilityInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{50} } + +func (m *CapabilityInfo) GetCapabilities() []CapabilityInfo_Capability { + if m != nil { + return m.Capabilities + } + return nil +} + +// * +// Encapsulation for Linux specific configuration. +// E.g, capabilities, limits etc. +type LinuxInfo struct { + // Represents the capability whitelist. + CapabilityInfo *CapabilityInfo `protobuf:"bytes,1,opt,name=capability_info,json=capabilityInfo" json:"capability_info,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *LinuxInfo) Reset() { *m = LinuxInfo{} } +func (m *LinuxInfo) String() string { return proto.CompactTextString(m) } +func (*LinuxInfo) ProtoMessage() {} +func (*LinuxInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{51} } + +func (m *LinuxInfo) GetCapabilityInfo() *CapabilityInfo { + if m != nil { + return m.CapabilityInfo + } + return nil +} + +// * +// Describes a container configuration and allows extensible +// configurations for different container implementations. +type ContainerInfo struct { + Type *ContainerInfo_Type `protobuf:"varint,1,req,name=type,enum=mesos.v1.ContainerInfo_Type" json:"type,omitempty"` + Volumes []*Volume `protobuf:"bytes,2,rep,name=volumes" json:"volumes,omitempty"` + Hostname *string `protobuf:"bytes,4,opt,name=hostname" json:"hostname,omitempty"` + // Only one of the following *Info messages should be set to match + // the type. + Docker *ContainerInfo_DockerInfo `protobuf:"bytes,3,opt,name=docker" json:"docker,omitempty"` + Mesos *ContainerInfo_MesosInfo `protobuf:"bytes,5,opt,name=mesos" json:"mesos,omitempty"` + // A list of network requests. A framework can request multiple IP addresses + // for the container. + NetworkInfos []*NetworkInfo `protobuf:"bytes,7,rep,name=network_infos,json=networkInfos" json:"network_infos,omitempty"` + // Linux specific information for the container. + LinuxInfo *LinuxInfo `protobuf:"bytes,8,opt,name=linux_info,json=linuxInfo" json:"linux_info,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ContainerInfo) Reset() { *m = ContainerInfo{} } +func (m *ContainerInfo) String() string { return proto.CompactTextString(m) } +func (*ContainerInfo) ProtoMessage() {} +func (*ContainerInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{52} } + +func (m *ContainerInfo) GetType() ContainerInfo_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return ContainerInfo_DOCKER +} + +func (m *ContainerInfo) GetVolumes() []*Volume { + if m != nil { + return m.Volumes + } + return nil +} + +func (m *ContainerInfo) GetHostname() string { + if m != nil && m.Hostname != nil { + return *m.Hostname + } + return "" +} + +func (m *ContainerInfo) GetDocker() *ContainerInfo_DockerInfo { + if m != nil { + return m.Docker + } + return nil +} + +func (m *ContainerInfo) GetMesos() *ContainerInfo_MesosInfo { + if m != nil { + return m.Mesos + } + return nil +} + +func (m *ContainerInfo) GetNetworkInfos() []*NetworkInfo { + if m != nil { + return m.NetworkInfos + } + return nil +} + +func (m *ContainerInfo) GetLinuxInfo() *LinuxInfo { + if m != nil { + return m.LinuxInfo + } + return nil +} + +type ContainerInfo_DockerInfo struct { + // The docker image that is going to be passed to the registry. + Image *string `protobuf:"bytes,1,req,name=image" json:"image,omitempty"` + Network *ContainerInfo_DockerInfo_Network `protobuf:"varint,2,opt,name=network,enum=mesos.v1.ContainerInfo_DockerInfo_Network,def=1" json:"network,omitempty"` + PortMappings []*ContainerInfo_DockerInfo_PortMapping `protobuf:"bytes,3,rep,name=port_mappings,json=portMappings" json:"port_mappings,omitempty"` + Privileged *bool `protobuf:"varint,4,opt,name=privileged,def=0" json:"privileged,omitempty"` + // Allowing arbitrary parameters to be passed to docker CLI. + // Note that anything passed to this field is not guaranteed + // to be supported moving forward, as we might move away from + // the docker CLI. + Parameters []*Parameter `protobuf:"bytes,5,rep,name=parameters" json:"parameters,omitempty"` + // With this flag set to true, the docker containerizer will + // pull the docker image from the registry even if the image + // is already downloaded on the agent. + ForcePullImage *bool `protobuf:"varint,6,opt,name=force_pull_image,json=forcePullImage" json:"force_pull_image,omitempty"` + // The name of volume driver plugin. + VolumeDriver *string `protobuf:"bytes,7,opt,name=volume_driver,json=volumeDriver" json:"volume_driver,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ContainerInfo_DockerInfo) Reset() { *m = ContainerInfo_DockerInfo{} } +func (m *ContainerInfo_DockerInfo) String() string { return proto.CompactTextString(m) } +func (*ContainerInfo_DockerInfo) ProtoMessage() {} +func (*ContainerInfo_DockerInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{52, 0} } + +const Default_ContainerInfo_DockerInfo_Network ContainerInfo_DockerInfo_Network = ContainerInfo_DockerInfo_HOST +const Default_ContainerInfo_DockerInfo_Privileged bool = false + +func (m *ContainerInfo_DockerInfo) GetImage() string { + if m != nil && m.Image != nil { + return *m.Image + } + return "" +} + +func (m *ContainerInfo_DockerInfo) GetNetwork() ContainerInfo_DockerInfo_Network { + if m != nil && m.Network != nil { + return *m.Network + } + return Default_ContainerInfo_DockerInfo_Network +} + +func (m *ContainerInfo_DockerInfo) GetPortMappings() []*ContainerInfo_DockerInfo_PortMapping { + if m != nil { + return m.PortMappings + } + return nil +} + +func (m *ContainerInfo_DockerInfo) GetPrivileged() bool { + if m != nil && m.Privileged != nil { + return *m.Privileged + } + return Default_ContainerInfo_DockerInfo_Privileged +} + +func (m *ContainerInfo_DockerInfo) GetParameters() []*Parameter { + if m != nil { + return m.Parameters + } + return nil +} + +func (m *ContainerInfo_DockerInfo) GetForcePullImage() bool { + if m != nil && m.ForcePullImage != nil { + return *m.ForcePullImage + } + return false +} + +func (m *ContainerInfo_DockerInfo) GetVolumeDriver() string { + if m != nil && m.VolumeDriver != nil { + return *m.VolumeDriver + } + return "" +} + +type ContainerInfo_DockerInfo_PortMapping struct { + HostPort *uint32 `protobuf:"varint,1,req,name=host_port,json=hostPort" json:"host_port,omitempty"` + ContainerPort *uint32 `protobuf:"varint,2,req,name=container_port,json=containerPort" json:"container_port,omitempty"` + // Protocol to expose as (ie: tcp, udp). + Protocol *string `protobuf:"bytes,3,opt,name=protocol" json:"protocol,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ContainerInfo_DockerInfo_PortMapping) Reset() { *m = ContainerInfo_DockerInfo_PortMapping{} } +func (m *ContainerInfo_DockerInfo_PortMapping) String() string { return proto.CompactTextString(m) } +func (*ContainerInfo_DockerInfo_PortMapping) ProtoMessage() {} +func (*ContainerInfo_DockerInfo_PortMapping) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{52, 0, 0} +} + +func (m *ContainerInfo_DockerInfo_PortMapping) GetHostPort() uint32 { + if m != nil && m.HostPort != nil { + return *m.HostPort + } + return 0 +} + +func (m *ContainerInfo_DockerInfo_PortMapping) GetContainerPort() uint32 { + if m != nil && m.ContainerPort != nil { + return *m.ContainerPort + } + return 0 +} + +func (m *ContainerInfo_DockerInfo_PortMapping) GetProtocol() string { + if m != nil && m.Protocol != nil { + return *m.Protocol + } + return "" +} + +type ContainerInfo_MesosInfo struct { + Image *Image `protobuf:"bytes,1,opt,name=image" json:"image,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ContainerInfo_MesosInfo) Reset() { *m = ContainerInfo_MesosInfo{} } +func (m *ContainerInfo_MesosInfo) String() string { return proto.CompactTextString(m) } +func (*ContainerInfo_MesosInfo) ProtoMessage() {} +func (*ContainerInfo_MesosInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{52, 1} } + +func (m *ContainerInfo_MesosInfo) GetImage() *Image { + if m != nil { + return m.Image + } + return nil +} + +// * +// Container related information that is resolved during container +// setup. The information is sent back to the framework as part of the +// TaskStatus message. +type ContainerStatus struct { + // This field can be reliably used to identify the container IP address. + NetworkInfos []*NetworkInfo `protobuf:"bytes,1,rep,name=network_infos,json=networkInfos" json:"network_infos,omitempty"` + // Information about Linux control group (cgroup). + CgroupInfo *CgroupInfo `protobuf:"bytes,2,opt,name=cgroup_info,json=cgroupInfo" json:"cgroup_info,omitempty"` + // Information about Executor PID. + ExecutorPid *uint32 `protobuf:"varint,3,opt,name=executor_pid,json=executorPid" json:"executor_pid,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ContainerStatus) Reset() { *m = ContainerStatus{} } +func (m *ContainerStatus) String() string { return proto.CompactTextString(m) } +func (*ContainerStatus) ProtoMessage() {} +func (*ContainerStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{53} } + +func (m *ContainerStatus) GetNetworkInfos() []*NetworkInfo { + if m != nil { + return m.NetworkInfos + } + return nil +} + +func (m *ContainerStatus) GetCgroupInfo() *CgroupInfo { + if m != nil { + return m.CgroupInfo + } + return nil +} + +func (m *ContainerStatus) GetExecutorPid() uint32 { + if m != nil && m.ExecutorPid != nil { + return *m.ExecutorPid + } + return 0 +} + +// * +// Linux control group (cgroup) information. +type CgroupInfo struct { + NetCls *CgroupInfo_NetCls `protobuf:"bytes,1,opt,name=net_cls,json=netCls" json:"net_cls,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *CgroupInfo) Reset() { *m = CgroupInfo{} } +func (m *CgroupInfo) String() string { return proto.CompactTextString(m) } +func (*CgroupInfo) ProtoMessage() {} +func (*CgroupInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{54} } + +func (m *CgroupInfo) GetNetCls() *CgroupInfo_NetCls { + if m != nil { + return m.NetCls + } + return nil +} + +// Configuration of a net_cls cgroup subsystem. +type CgroupInfo_NetCls struct { + // The 32-bit classid consists of two parts, a 16 bit major handle + // and a 16-bit minor handle. The major and minor handle are + // represented using the format 0xAAAABBBB, where 0xAAAA is the + // 16-bit major handle and 0xBBBB is the 16-bit minor handle. + Classid *uint32 `protobuf:"varint,1,opt,name=classid" json:"classid,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *CgroupInfo_NetCls) Reset() { *m = CgroupInfo_NetCls{} } +func (m *CgroupInfo_NetCls) String() string { return proto.CompactTextString(m) } +func (*CgroupInfo_NetCls) ProtoMessage() {} +func (*CgroupInfo_NetCls) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{54, 0} } + +func (m *CgroupInfo_NetCls) GetClassid() uint32 { + if m != nil && m.Classid != nil { + return *m.Classid + } + return 0 +} + +// * +// Collection of labels. Labels should not contain duplicate key-value +// pairs. +type Labels struct { + Labels []*Label `protobuf:"bytes,1,rep,name=labels" json:"labels,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Labels) Reset() { *m = Labels{} } +func (m *Labels) String() string { return proto.CompactTextString(m) } +func (*Labels) ProtoMessage() {} +func (*Labels) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{55} } + +func (m *Labels) GetLabels() []*Label { + if m != nil { + return m.Labels + } + return nil +} + +// * +// Key, value pair used to store free form user-data. +type Label struct { + Key *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"` + Value *string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Label) Reset() { *m = Label{} } +func (m *Label) String() string { return proto.CompactTextString(m) } +func (*Label) ProtoMessage() {} +func (*Label) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{56} } + +func (m *Label) GetKey() string { + if m != nil && m.Key != nil { + return *m.Key + } + return "" +} + +func (m *Label) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +// * +// Named port used for service discovery. +type Port struct { + // Port number on which the framework exposes a service. + Number *uint32 `protobuf:"varint,1,req,name=number" json:"number,omitempty"` + // Name of the service hosted on this port. + Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + // Layer 4-7 protocol on which the framework exposes its services. + Protocol *string `protobuf:"bytes,3,opt,name=protocol" json:"protocol,omitempty"` + // This field restricts discovery within a framework (FRAMEWORK), + // within a Mesos cluster (CLUSTER), or places no restrictions (EXTERNAL). + // The visibility setting for a Port overrides the general visibility setting + // in the DiscoveryInfo. + Visibility *DiscoveryInfo_Visibility `protobuf:"varint,4,opt,name=visibility,enum=mesos.v1.DiscoveryInfo_Visibility" json:"visibility,omitempty"` + // This can be used to decorate the message with metadata to be + // interpreted by external applications such as firewalls. + Labels *Labels `protobuf:"bytes,5,opt,name=labels" json:"labels,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Port) Reset() { *m = Port{} } +func (m *Port) String() string { return proto.CompactTextString(m) } +func (*Port) ProtoMessage() {} +func (*Port) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{57} } + +func (m *Port) GetNumber() uint32 { + if m != nil && m.Number != nil { + return *m.Number + } + return 0 +} + +func (m *Port) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Port) GetProtocol() string { + if m != nil && m.Protocol != nil { + return *m.Protocol + } + return "" +} + +func (m *Port) GetVisibility() DiscoveryInfo_Visibility { + if m != nil && m.Visibility != nil { + return *m.Visibility + } + return DiscoveryInfo_FRAMEWORK +} + +func (m *Port) GetLabels() *Labels { + if m != nil { + return m.Labels + } + return nil +} + +// * +// Collection of ports. +type Ports struct { + Ports []*Port `protobuf:"bytes,1,rep,name=ports" json:"ports,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Ports) Reset() { *m = Ports{} } +func (m *Ports) String() string { return proto.CompactTextString(m) } +func (*Ports) ProtoMessage() {} +func (*Ports) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{58} } + +func (m *Ports) GetPorts() []*Port { + if m != nil { + return m.Ports + } + return nil +} + +// * +// Service discovery information. +// The visibility field restricts discovery within a framework (FRAMEWORK), +// within a Mesos cluster (CLUSTER), or places no restrictions (EXTERNAL). +// Each port in the ports field also has an optional visibility field. +// If visibility is specified for a port, it overrides the default service-wide +// DiscoveryInfo.visibility for that port. +// The environment, location, and version fields provide first class support for +// common attributes used to differentiate between similar services. The +// environment may receive values such as PROD/QA/DEV, the location field may +// receive values like EAST-US/WEST-US/EUROPE/AMEA, and the version field may +// receive values like v2.0/v0.9. The exact use of these fields is up to each +// service discovery system. +type DiscoveryInfo struct { + Visibility *DiscoveryInfo_Visibility `protobuf:"varint,1,req,name=visibility,enum=mesos.v1.DiscoveryInfo_Visibility" json:"visibility,omitempty"` + Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + Environment *string `protobuf:"bytes,3,opt,name=environment" json:"environment,omitempty"` + Location *string `protobuf:"bytes,4,opt,name=location" json:"location,omitempty"` + Version *string `protobuf:"bytes,5,opt,name=version" json:"version,omitempty"` + Ports *Ports `protobuf:"bytes,6,opt,name=ports" json:"ports,omitempty"` + Labels *Labels `protobuf:"bytes,7,opt,name=labels" json:"labels,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *DiscoveryInfo) Reset() { *m = DiscoveryInfo{} } +func (m *DiscoveryInfo) String() string { return proto.CompactTextString(m) } +func (*DiscoveryInfo) ProtoMessage() {} +func (*DiscoveryInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{59} } + +func (m *DiscoveryInfo) GetVisibility() DiscoveryInfo_Visibility { + if m != nil && m.Visibility != nil { + return *m.Visibility + } + return DiscoveryInfo_FRAMEWORK +} + +func (m *DiscoveryInfo) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *DiscoveryInfo) GetEnvironment() string { + if m != nil && m.Environment != nil { + return *m.Environment + } + return "" +} + +func (m *DiscoveryInfo) GetLocation() string { + if m != nil && m.Location != nil { + return *m.Location + } + return "" +} + +func (m *DiscoveryInfo) GetVersion() string { + if m != nil && m.Version != nil { + return *m.Version + } + return "" +} + +func (m *DiscoveryInfo) GetPorts() *Ports { + if m != nil { + return m.Ports + } + return nil +} + +func (m *DiscoveryInfo) GetLabels() *Labels { + if m != nil { + return m.Labels + } + return nil +} + +// * +// Named WeightInfo to indicate resource allocation +// priority between the different roles. +type WeightInfo struct { + Weight *float64 `protobuf:"fixed64,1,req,name=weight" json:"weight,omitempty"` + // Related role name. + Role *string `protobuf:"bytes,2,opt,name=role" json:"role,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *WeightInfo) Reset() { *m = WeightInfo{} } +func (m *WeightInfo) String() string { return proto.CompactTextString(m) } +func (*WeightInfo) ProtoMessage() {} +func (*WeightInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{60} } + +func (m *WeightInfo) GetWeight() float64 { + if m != nil && m.Weight != nil { + return *m.Weight + } + return 0 +} + +func (m *WeightInfo) GetRole() string { + if m != nil && m.Role != nil { + return *m.Role + } + return "" +} + +// * +// Version information of a component. +type VersionInfo struct { + Version *string `protobuf:"bytes,1,req,name=version" json:"version,omitempty"` + BuildDate *string `protobuf:"bytes,2,opt,name=build_date,json=buildDate" json:"build_date,omitempty"` + BuildTime *float64 `protobuf:"fixed64,3,opt,name=build_time,json=buildTime" json:"build_time,omitempty"` + BuildUser *string `protobuf:"bytes,4,opt,name=build_user,json=buildUser" json:"build_user,omitempty"` + GitSha *string `protobuf:"bytes,5,opt,name=git_sha,json=gitSha" json:"git_sha,omitempty"` + GitBranch *string `protobuf:"bytes,6,opt,name=git_branch,json=gitBranch" json:"git_branch,omitempty"` + GitTag *string `protobuf:"bytes,7,opt,name=git_tag,json=gitTag" json:"git_tag,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *VersionInfo) Reset() { *m = VersionInfo{} } +func (m *VersionInfo) String() string { return proto.CompactTextString(m) } +func (*VersionInfo) ProtoMessage() {} +func (*VersionInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{61} } + +func (m *VersionInfo) GetVersion() string { + if m != nil && m.Version != nil { + return *m.Version + } + return "" +} + +func (m *VersionInfo) GetBuildDate() string { + if m != nil && m.BuildDate != nil { + return *m.BuildDate + } + return "" +} + +func (m *VersionInfo) GetBuildTime() float64 { + if m != nil && m.BuildTime != nil { + return *m.BuildTime + } + return 0 +} + +func (m *VersionInfo) GetBuildUser() string { + if m != nil && m.BuildUser != nil { + return *m.BuildUser + } + return "" +} + +func (m *VersionInfo) GetGitSha() string { + if m != nil && m.GitSha != nil { + return *m.GitSha + } + return "" +} + +func (m *VersionInfo) GetGitBranch() string { + if m != nil && m.GitBranch != nil { + return *m.GitBranch + } + return "" +} + +func (m *VersionInfo) GetGitTag() string { + if m != nil && m.GitTag != nil { + return *m.GitTag + } + return "" +} + +// * +// Flag consists of a name and optionally its value. +type Flag struct { + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + Value *string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Flag) Reset() { *m = Flag{} } +func (m *Flag) String() string { return proto.CompactTextString(m) } +func (*Flag) ProtoMessage() {} +func (*Flag) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{62} } + +func (m *Flag) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Flag) GetValue() string { + if m != nil && m.Value != nil { + return *m.Value + } + return "" +} + +// * +// Describes a Role. Roles can be used to specify that certain resources are +// reserved for the use of one or more frameworks. +type Role struct { + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + Weight *float64 `protobuf:"fixed64,2,req,name=weight" json:"weight,omitempty"` + Frameworks []*FrameworkID `protobuf:"bytes,3,rep,name=frameworks" json:"frameworks,omitempty"` + Resources []*Resource `protobuf:"bytes,4,rep,name=resources" json:"resources,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Role) Reset() { *m = Role{} } +func (m *Role) String() string { return proto.CompactTextString(m) } +func (*Role) ProtoMessage() {} +func (*Role) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{63} } + +func (m *Role) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Role) GetWeight() float64 { + if m != nil && m.Weight != nil { + return *m.Weight + } + return 0 +} + +func (m *Role) GetFrameworks() []*FrameworkID { + if m != nil { + return m.Frameworks + } + return nil +} + +func (m *Role) GetResources() []*Resource { + if m != nil { + return m.Resources + } + return nil +} + +// * +// Metric consists of a name and optionally its value. +type Metric struct { + Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` + Value *float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Metric) Reset() { *m = Metric{} } +func (m *Metric) String() string { return proto.CompactTextString(m) } +func (*Metric) ProtoMessage() {} +func (*Metric) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{64} } + +func (m *Metric) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *Metric) GetValue() float64 { + if m != nil && m.Value != nil { + return *m.Value + } + return 0 +} + +// * +// Describes a File. +type FileInfo struct { + // Absolute path to the file. + Path *string `protobuf:"bytes,1,req,name=path" json:"path,omitempty"` + // Number of hard links. + Nlink *int32 `protobuf:"varint,2,opt,name=nlink" json:"nlink,omitempty"` + // Total size in bytes. + Size *uint64 `protobuf:"varint,3,opt,name=size" json:"size,omitempty"` + // Last modification time. + Mtime *TimeInfo `protobuf:"bytes,4,opt,name=mtime" json:"mtime,omitempty"` + // Represents a file's mode and permission bits. The bits have the same + // definition on all systems and is portable. + Mode *uint32 `protobuf:"varint,5,opt,name=mode" json:"mode,omitempty"` + // User ID of owner. + Uid *string `protobuf:"bytes,6,opt,name=uid" json:"uid,omitempty"` + // Group ID of owner. + Gid *string `protobuf:"bytes,7,opt,name=gid" json:"gid,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *FileInfo) Reset() { *m = FileInfo{} } +func (m *FileInfo) String() string { return proto.CompactTextString(m) } +func (*FileInfo) ProtoMessage() {} +func (*FileInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{65} } + +func (m *FileInfo) GetPath() string { + if m != nil && m.Path != nil { + return *m.Path + } + return "" +} + +func (m *FileInfo) GetNlink() int32 { + if m != nil && m.Nlink != nil { + return *m.Nlink + } + return 0 +} + +func (m *FileInfo) GetSize() uint64 { + if m != nil && m.Size != nil { + return *m.Size + } + return 0 +} + +func (m *FileInfo) GetMtime() *TimeInfo { + if m != nil { + return m.Mtime + } + return nil +} + +func (m *FileInfo) GetMode() uint32 { + if m != nil && m.Mode != nil { + return *m.Mode + } + return 0 +} + +func (m *FileInfo) GetUid() string { + if m != nil && m.Uid != nil { + return *m.Uid + } + return "" +} + +func (m *FileInfo) GetGid() string { + if m != nil && m.Gid != nil { + return *m.Gid + } + return "" +} + +func init() { + proto.RegisterType((*FrameworkID)(nil), "mesos.v1.FrameworkID") + proto.RegisterType((*OfferID)(nil), "mesos.v1.OfferID") + proto.RegisterType((*AgentID)(nil), "mesos.v1.AgentID") + proto.RegisterType((*TaskID)(nil), "mesos.v1.TaskID") + proto.RegisterType((*ExecutorID)(nil), "mesos.v1.ExecutorID") + proto.RegisterType((*ContainerID)(nil), "mesos.v1.ContainerID") + proto.RegisterType((*TimeInfo)(nil), "mesos.v1.TimeInfo") + proto.RegisterType((*DurationInfo)(nil), "mesos.v1.DurationInfo") + proto.RegisterType((*Address)(nil), "mesos.v1.Address") + proto.RegisterType((*URL)(nil), "mesos.v1.URL") + proto.RegisterType((*Unavailability)(nil), "mesos.v1.Unavailability") + proto.RegisterType((*MachineID)(nil), "mesos.v1.MachineID") + proto.RegisterType((*MachineInfo)(nil), "mesos.v1.MachineInfo") + proto.RegisterType((*FrameworkInfo)(nil), "mesos.v1.FrameworkInfo") + proto.RegisterType((*FrameworkInfo_Capability)(nil), "mesos.v1.FrameworkInfo.Capability") + proto.RegisterType((*HealthCheck)(nil), "mesos.v1.HealthCheck") + proto.RegisterType((*HealthCheck_HTTPCheckInfo)(nil), "mesos.v1.HealthCheck.HTTPCheckInfo") + proto.RegisterType((*HealthCheck_TCPCheckInfo)(nil), "mesos.v1.HealthCheck.TCPCheckInfo") + proto.RegisterType((*KillPolicy)(nil), "mesos.v1.KillPolicy") + proto.RegisterType((*CommandInfo)(nil), "mesos.v1.CommandInfo") + proto.RegisterType((*CommandInfo_URI)(nil), "mesos.v1.CommandInfo.URI") + proto.RegisterType((*ExecutorInfo)(nil), "mesos.v1.ExecutorInfo") + proto.RegisterType((*MasterInfo)(nil), "mesos.v1.MasterInfo") + proto.RegisterType((*AgentInfo)(nil), "mesos.v1.AgentInfo") + proto.RegisterType((*Value)(nil), "mesos.v1.Value") + proto.RegisterType((*Value_Scalar)(nil), "mesos.v1.Value.Scalar") + proto.RegisterType((*Value_Range)(nil), "mesos.v1.Value.Range") + proto.RegisterType((*Value_Ranges)(nil), "mesos.v1.Value.Ranges") + proto.RegisterType((*Value_Set)(nil), "mesos.v1.Value.Set") + proto.RegisterType((*Value_Text)(nil), "mesos.v1.Value.Text") + proto.RegisterType((*Attribute)(nil), "mesos.v1.Attribute") + proto.RegisterType((*Resource)(nil), "mesos.v1.Resource") + proto.RegisterType((*Resource_ReservationInfo)(nil), "mesos.v1.Resource.ReservationInfo") + proto.RegisterType((*Resource_DiskInfo)(nil), "mesos.v1.Resource.DiskInfo") + proto.RegisterType((*Resource_DiskInfo_Persistence)(nil), "mesos.v1.Resource.DiskInfo.Persistence") + proto.RegisterType((*Resource_DiskInfo_Source)(nil), "mesos.v1.Resource.DiskInfo.Source") + proto.RegisterType((*Resource_DiskInfo_Source_Path)(nil), "mesos.v1.Resource.DiskInfo.Source.Path") + proto.RegisterType((*Resource_DiskInfo_Source_Mount)(nil), "mesos.v1.Resource.DiskInfo.Source.Mount") + proto.RegisterType((*Resource_RevocableInfo)(nil), "mesos.v1.Resource.RevocableInfo") + proto.RegisterType((*Resource_SharedInfo)(nil), "mesos.v1.Resource.SharedInfo") + proto.RegisterType((*TrafficControlStatistics)(nil), "mesos.v1.TrafficControlStatistics") + proto.RegisterType((*IpStatistics)(nil), "mesos.v1.IpStatistics") + proto.RegisterType((*IcmpStatistics)(nil), "mesos.v1.IcmpStatistics") + proto.RegisterType((*TcpStatistics)(nil), "mesos.v1.TcpStatistics") + proto.RegisterType((*UdpStatistics)(nil), "mesos.v1.UdpStatistics") + proto.RegisterType((*SNMPStatistics)(nil), "mesos.v1.SNMPStatistics") + proto.RegisterType((*ResourceStatistics)(nil), "mesos.v1.ResourceStatistics") + proto.RegisterType((*ResourceUsage)(nil), "mesos.v1.ResourceUsage") + proto.RegisterType((*ResourceUsage_Executor)(nil), "mesos.v1.ResourceUsage.Executor") + proto.RegisterType((*ResourceUsage_Executor_Task)(nil), "mesos.v1.ResourceUsage.Executor.Task") + proto.RegisterType((*PerfStatistics)(nil), "mesos.v1.PerfStatistics") + proto.RegisterType((*Request)(nil), "mesos.v1.Request") + proto.RegisterType((*Offer)(nil), "mesos.v1.Offer") + proto.RegisterType((*Offer_Operation)(nil), "mesos.v1.Offer.Operation") + proto.RegisterType((*Offer_Operation_Launch)(nil), "mesos.v1.Offer.Operation.Launch") + proto.RegisterType((*Offer_Operation_LaunchGroup)(nil), "mesos.v1.Offer.Operation.LaunchGroup") + proto.RegisterType((*Offer_Operation_Reserve)(nil), "mesos.v1.Offer.Operation.Reserve") + proto.RegisterType((*Offer_Operation_Unreserve)(nil), "mesos.v1.Offer.Operation.Unreserve") + proto.RegisterType((*Offer_Operation_Create)(nil), "mesos.v1.Offer.Operation.Create") + proto.RegisterType((*Offer_Operation_Destroy)(nil), "mesos.v1.Offer.Operation.Destroy") + proto.RegisterType((*InverseOffer)(nil), "mesos.v1.InverseOffer") + proto.RegisterType((*TaskInfo)(nil), "mesos.v1.TaskInfo") + proto.RegisterType((*TaskGroupInfo)(nil), "mesos.v1.TaskGroupInfo") + proto.RegisterType((*Task)(nil), "mesos.v1.Task") + proto.RegisterType((*TaskStatus)(nil), "mesos.v1.TaskStatus") + proto.RegisterType((*Filters)(nil), "mesos.v1.Filters") + proto.RegisterType((*Environment)(nil), "mesos.v1.Environment") + proto.RegisterType((*Environment_Variable)(nil), "mesos.v1.Environment.Variable") + proto.RegisterType((*Parameter)(nil), "mesos.v1.Parameter") + proto.RegisterType((*Parameters)(nil), "mesos.v1.Parameters") + proto.RegisterType((*Credential)(nil), "mesos.v1.Credential") + proto.RegisterType((*Credentials)(nil), "mesos.v1.Credentials") + proto.RegisterType((*RateLimit)(nil), "mesos.v1.RateLimit") + proto.RegisterType((*RateLimits)(nil), "mesos.v1.RateLimits") + proto.RegisterType((*Image)(nil), "mesos.v1.Image") + proto.RegisterType((*Image_Appc)(nil), "mesos.v1.Image.Appc") + proto.RegisterType((*Image_Docker)(nil), "mesos.v1.Image.Docker") + proto.RegisterType((*Volume)(nil), "mesos.v1.Volume") + proto.RegisterType((*Volume_Source)(nil), "mesos.v1.Volume.Source") + proto.RegisterType((*Volume_Source_DockerVolume)(nil), "mesos.v1.Volume.Source.DockerVolume") + proto.RegisterType((*Volume_Source_SandboxPath)(nil), "mesos.v1.Volume.Source.SandboxPath") + proto.RegisterType((*NetworkInfo)(nil), "mesos.v1.NetworkInfo") + proto.RegisterType((*NetworkInfo_IPAddress)(nil), "mesos.v1.NetworkInfo.IPAddress") + proto.RegisterType((*NetworkInfo_PortMapping)(nil), "mesos.v1.NetworkInfo.PortMapping") + proto.RegisterType((*CapabilityInfo)(nil), "mesos.v1.CapabilityInfo") + proto.RegisterType((*LinuxInfo)(nil), "mesos.v1.LinuxInfo") + proto.RegisterType((*ContainerInfo)(nil), "mesos.v1.ContainerInfo") + proto.RegisterType((*ContainerInfo_DockerInfo)(nil), "mesos.v1.ContainerInfo.DockerInfo") + proto.RegisterType((*ContainerInfo_DockerInfo_PortMapping)(nil), "mesos.v1.ContainerInfo.DockerInfo.PortMapping") + proto.RegisterType((*ContainerInfo_MesosInfo)(nil), "mesos.v1.ContainerInfo.MesosInfo") + proto.RegisterType((*ContainerStatus)(nil), "mesos.v1.ContainerStatus") + proto.RegisterType((*CgroupInfo)(nil), "mesos.v1.CgroupInfo") + proto.RegisterType((*CgroupInfo_NetCls)(nil), "mesos.v1.CgroupInfo.NetCls") + proto.RegisterType((*Labels)(nil), "mesos.v1.Labels") + proto.RegisterType((*Label)(nil), "mesos.v1.Label") + proto.RegisterType((*Port)(nil), "mesos.v1.Port") + proto.RegisterType((*Ports)(nil), "mesos.v1.Ports") + proto.RegisterType((*DiscoveryInfo)(nil), "mesos.v1.DiscoveryInfo") + proto.RegisterType((*WeightInfo)(nil), "mesos.v1.WeightInfo") + proto.RegisterType((*VersionInfo)(nil), "mesos.v1.VersionInfo") + proto.RegisterType((*Flag)(nil), "mesos.v1.Flag") + proto.RegisterType((*Role)(nil), "mesos.v1.Role") + proto.RegisterType((*Metric)(nil), "mesos.v1.Metric") + proto.RegisterType((*FileInfo)(nil), "mesos.v1.FileInfo") + proto.RegisterEnum("mesos.v1.Status", Status_name, Status_value) + proto.RegisterEnum("mesos.v1.TaskState", TaskState_name, TaskState_value) + proto.RegisterEnum("mesos.v1.MachineInfo_Mode", MachineInfo_Mode_name, MachineInfo_Mode_value) + proto.RegisterEnum("mesos.v1.FrameworkInfo_Capability_Type", FrameworkInfo_Capability_Type_name, FrameworkInfo_Capability_Type_value) + proto.RegisterEnum("mesos.v1.HealthCheck_Type", HealthCheck_Type_name, HealthCheck_Type_value) + proto.RegisterEnum("mesos.v1.ExecutorInfo_Type", ExecutorInfo_Type_name, ExecutorInfo_Type_value) + proto.RegisterEnum("mesos.v1.Value_Type", Value_Type_name, Value_Type_value) + proto.RegisterEnum("mesos.v1.Resource_DiskInfo_Source_Type", Resource_DiskInfo_Source_Type_name, Resource_DiskInfo_Source_Type_value) + proto.RegisterEnum("mesos.v1.Offer_Operation_Type", Offer_Operation_Type_name, Offer_Operation_Type_value) + proto.RegisterEnum("mesos.v1.TaskStatus_Source", TaskStatus_Source_name, TaskStatus_Source_value) + proto.RegisterEnum("mesos.v1.TaskStatus_Reason", TaskStatus_Reason_name, TaskStatus_Reason_value) + proto.RegisterEnum("mesos.v1.Image_Type", Image_Type_name, Image_Type_value) + proto.RegisterEnum("mesos.v1.Volume_Mode", Volume_Mode_name, Volume_Mode_value) + proto.RegisterEnum("mesos.v1.Volume_Source_Type", Volume_Source_Type_name, Volume_Source_Type_value) + proto.RegisterEnum("mesos.v1.Volume_Source_SandboxPath_Type", Volume_Source_SandboxPath_Type_name, Volume_Source_SandboxPath_Type_value) + proto.RegisterEnum("mesos.v1.NetworkInfo_Protocol", NetworkInfo_Protocol_name, NetworkInfo_Protocol_value) + proto.RegisterEnum("mesos.v1.CapabilityInfo_Capability", CapabilityInfo_Capability_name, CapabilityInfo_Capability_value) + proto.RegisterEnum("mesos.v1.ContainerInfo_Type", ContainerInfo_Type_name, ContainerInfo_Type_value) + proto.RegisterEnum("mesos.v1.ContainerInfo_DockerInfo_Network", ContainerInfo_DockerInfo_Network_name, ContainerInfo_DockerInfo_Network_value) + proto.RegisterEnum("mesos.v1.DiscoveryInfo_Visibility", DiscoveryInfo_Visibility_name, DiscoveryInfo_Visibility_value) +} + +func init() { proto.RegisterFile("mesos.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 8324 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xd4, 0x7c, 0xc9, 0x8f, 0x1b, 0x49, + 0x97, 0xdf, 0xc7, 0x9d, 0x7c, 0x24, 0xab, 0x52, 0x51, 0x92, 0x9a, 0xa2, 0x96, 0xae, 0xce, 0x6e, + 0x75, 0x57, 0xeb, 0xeb, 0xae, 0x96, 0x4a, 0xad, 0x5e, 0xa4, 0xef, 0xfb, 0x3c, 0x2c, 0x32, 0x4b, + 0xe2, 0xa8, 0xb8, 0x4c, 0x90, 0x94, 0xba, 0x0d, 0x03, 0x44, 0x2a, 0x19, 0x55, 0x95, 0x16, 0x99, + 0xc9, 0xce, 0x4c, 0x96, 0x24, 0x9f, 0x3c, 0x9b, 0x97, 0xf1, 0x8c, 0x0f, 0x63, 0xc3, 0x18, 0x60, + 0xce, 0x86, 0x01, 0x0f, 0xe0, 0x7f, 0xc0, 0x86, 0x6f, 0x86, 0x57, 0x18, 0xf0, 0xc1, 0x3e, 0x18, + 0x06, 0x7c, 0xf9, 0x60, 0xcc, 0x78, 0x19, 0x7b, 0xbc, 0x8d, 0x3d, 0xe3, 0x0d, 0xb1, 0x65, 0x46, + 0x26, 0xc9, 0xaa, 0x52, 0xdb, 0x30, 0x30, 0x27, 0x32, 0x5e, 0xfc, 0x5e, 0xe4, 0x8b, 0xf7, 0x5e, + 0x44, 0xbc, 0x58, 0xa1, 0x3c, 0x23, 0xbe, 0xeb, 0xef, 0xce, 0x3d, 0x37, 0x70, 0x51, 0x91, 0x27, + 0x4e, 0xef, 0xe9, 0xef, 0x43, 0xf9, 0xc0, 0x33, 0x67, 0xe4, 0x95, 0xeb, 0xbd, 0x6c, 0xb7, 0xd0, + 0x65, 0xc8, 0x9d, 0x9a, 0xd3, 0x05, 0xa9, 0xa5, 0xb6, 0xd3, 0x3b, 0x25, 0xcc, 0x13, 0xfa, 0xbb, + 0x50, 0xe8, 0x1d, 0x1d, 0x11, 0xef, 0x2c, 0x40, 0xe3, 0x98, 0x38, 0xc1, 0x5a, 0xc0, 0x2d, 0xc8, + 0x0f, 0x4d, 0x7f, 0xfd, 0x17, 0x74, 0x00, 0xe3, 0x35, 0xb1, 0x16, 0x81, 0xbb, 0xfe, 0x23, 0x18, + 0xca, 0x4d, 0xd7, 0x09, 0x4c, 0xdb, 0x59, 0x2f, 0x09, 0xfa, 0x14, 0xf2, 0x73, 0xd3, 0x23, 0x4e, + 0x50, 0x4b, 0x6f, 0xa7, 0x76, 0xca, 0x7b, 0x57, 0x76, 0x65, 0x55, 0x77, 0x15, 0x66, 0x2c, 0x40, + 0xfa, 0x27, 0x50, 0x1c, 0xda, 0x33, 0xd2, 0x76, 0x8e, 0x5c, 0xb4, 0x0d, 0x65, 0xc7, 0x74, 0x5c, + 0x9f, 0x58, 0xae, 0x33, 0xf1, 0x59, 0xb1, 0x19, 0xac, 0x92, 0xf4, 0xbb, 0x50, 0x69, 0x2d, 0x3c, + 0x33, 0xb0, 0x5d, 0xe7, 0x82, 0x1c, 0x6d, 0x28, 0x34, 0x26, 0x13, 0x8f, 0xf8, 0x3e, 0xaa, 0x43, + 0xf1, 0xc4, 0xf5, 0x03, 0xc7, 0x9c, 0x51, 0x91, 0x53, 0x3b, 0x25, 0x1c, 0xa6, 0xd1, 0x06, 0xa4, + 0xed, 0x39, 0x93, 0xb8, 0x84, 0xd3, 0xf6, 0x1c, 0x21, 0xc8, 0xce, 0x5d, 0x2f, 0xa8, 0x65, 0xb6, + 0xd3, 0x3b, 0x39, 0xcc, 0xfe, 0xeb, 0x7f, 0x35, 0x05, 0x99, 0x11, 0x3e, 0x44, 0x57, 0x21, 0xef, + 0x5b, 0x27, 0x64, 0x26, 0x2b, 0x2e, 0x52, 0xe8, 0x87, 0x50, 0x30, 0xf9, 0xa7, 0x6a, 0xe9, 0xed, + 0xf4, 0x4e, 0x79, 0xef, 0x52, 0x54, 0x75, 0x21, 0x03, 0x96, 0x08, 0xf6, 0x01, 0x33, 0x38, 0xa9, + 0x65, 0xd8, 0x27, 0xd9, 0x7f, 0xf4, 0x31, 0xe4, 0xbe, 0x5b, 0x10, 0xef, 0x4d, 0x2d, 0xbb, 0x9d, + 0xd9, 0x29, 0xef, 0x6d, 0x45, 0xec, 0x7d, 0x93, 0xba, 0x48, 0x40, 0x3c, 0xcc, 0x11, 0xb4, 0x2e, + 0x47, 0x9e, 0x79, 0x3c, 0xa3, 0x7a, 0xce, 0xf1, 0xba, 0xc8, 0xb4, 0xee, 0xc0, 0xc6, 0xc8, 0x31, + 0x4f, 0x4d, 0x7b, 0x6a, 0xbe, 0xb0, 0xa7, 0x76, 0xf0, 0x06, 0xed, 0x40, 0xce, 0x0f, 0x4c, 0x2f, + 0x60, 0x02, 0x97, 0xf7, 0x50, 0x54, 0xb0, 0xd4, 0x3d, 0xe6, 0x00, 0xb4, 0x07, 0xc5, 0x89, 0x50, + 0xb0, 0xb0, 0xdf, 0xd5, 0x08, 0xac, 0xaa, 0x1e, 0x87, 0x38, 0xfd, 0x4b, 0x28, 0x75, 0x4c, 0xeb, + 0xc4, 0x76, 0x48, 0xbb, 0xf5, 0x36, 0x4a, 0xd6, 0xff, 0x51, 0x0a, 0xca, 0x92, 0x93, 0x5a, 0xf3, + 0x7d, 0x48, 0xdb, 0x13, 0x21, 0xa3, 0x52, 0xf9, 0xb0, 0x70, 0x9c, 0xb6, 0x27, 0x68, 0x17, 0xb2, + 0x33, 0x77, 0x42, 0x58, 0x31, 0x1b, 0x7b, 0xf5, 0x65, 0x98, 0x73, 0xe4, 0xee, 0x76, 0xdc, 0x09, + 0xc1, 0x0c, 0x87, 0x7e, 0x06, 0x36, 0x16, 0x31, 0x6d, 0x30, 0x95, 0x97, 0xf7, 0x6a, 0x11, 0x67, + 0x5c, 0x5b, 0x38, 0x81, 0xd7, 0x3f, 0x84, 0x2c, 0x2d, 0x0f, 0xe5, 0x21, 0x3d, 0xea, 0x6b, 0x29, + 0x54, 0x81, 0x62, 0x0b, 0x37, 0xda, 0xdd, 0x76, 0xf7, 0xb1, 0x96, 0x46, 0x45, 0xc8, 0xb6, 0x7a, + 0xcf, 0xbb, 0x5a, 0x46, 0xff, 0x69, 0x16, 0xaa, 0x51, 0x53, 0xa6, 0x15, 0x42, 0x90, 0x5d, 0xf8, + 0xc4, 0x13, 0x7e, 0xc2, 0xfe, 0x53, 0x1a, 0x53, 0x4e, 0x9a, 0xd3, 0x98, 0x62, 0x6e, 0xb3, 0x8a, + 0x67, 0x92, 0xed, 0x45, 0xe9, 0x17, 0x58, 0xd5, 0x3f, 0x01, 0xed, 0xc8, 0xb4, 0xa7, 0xee, 0x29, + 0xf1, 0xc6, 0x81, 0x3d, 0x23, 0xee, 0x22, 0xa8, 0x65, 0xb7, 0x53, 0x3b, 0xa9, 0x87, 0xa9, 0xbb, + 0x78, 0x53, 0x66, 0x0d, 0x79, 0x0e, 0xba, 0x0d, 0x60, 0x9d, 0x10, 0xeb, 0xe5, 0xdc, 0xb5, 0x85, + 0x93, 0x14, 0x1f, 0xe6, 0x8e, 0xcc, 0xa9, 0x4f, 0xb0, 0x92, 0x81, 0xae, 0x40, 0xd6, 0x73, 0xa7, + 0xa4, 0x96, 0xa7, 0x66, 0x79, 0x98, 0xba, 0x83, 0x59, 0x32, 0x66, 0xc7, 0x42, 0xc2, 0x8e, 0x37, + 0xa0, 0x34, 0xf7, 0x6c, 0xc7, 0xb2, 0xe7, 0xe6, 0xb4, 0x56, 0x64, 0x99, 0x11, 0x01, 0x5d, 0x87, + 0xd2, 0x2b, 0xf2, 0x62, 0x61, 0x8f, 0x17, 0xde, 0xb4, 0x56, 0xe2, 0xac, 0x8c, 0x30, 0xf2, 0xa6, + 0xe8, 0x00, 0x2a, 0x96, 0x39, 0xe7, 0x9a, 0xb5, 0x89, 0x5f, 0x03, 0xe6, 0xe9, 0xfa, 0xaa, 0x3a, + 0x53, 0x3b, 0x36, 0x25, 0xf6, 0x0d, 0x8e, 0xf1, 0xa1, 0x1d, 0xc8, 0x4f, 0xcd, 0x17, 0x64, 0xea, + 0xd7, 0xca, 0x4c, 0x6b, 0x5a, 0x54, 0xc2, 0x21, 0xa3, 0x63, 0x91, 0x5f, 0xff, 0xc7, 0x29, 0x80, + 0xa8, 0x18, 0xf4, 0x08, 0xb2, 0xc1, 0x9b, 0x39, 0xf7, 0xcd, 0x8d, 0xbd, 0x8f, 0xce, 0xff, 0xf0, + 0xee, 0xf0, 0xcd, 0x9c, 0x60, 0xc6, 0xa4, 0xff, 0x42, 0x0a, 0xb2, 0x34, 0x89, 0xca, 0x50, 0x18, + 0x75, 0x9f, 0x76, 0xa9, 0xdd, 0x7f, 0x80, 0xde, 0x81, 0x2d, 0x6c, 0x3c, 0xeb, 0x35, 0x1b, 0xfb, + 0x87, 0xc6, 0x18, 0x1b, 0x83, 0xde, 0x08, 0x37, 0x8d, 0x81, 0x96, 0x42, 0x57, 0x01, 0x0d, 0x1b, + 0x83, 0xa7, 0xe3, 0xa7, 0xed, 0xc3, 0xc3, 0x76, 0xf7, 0xf1, 0x78, 0x30, 0x6c, 0x0c, 0x0d, 0x2d, + 0x8d, 0x2e, 0x41, 0xf5, 0x71, 0x7f, 0xa4, 0x40, 0x33, 0xe8, 0x32, 0x68, 0x83, 0x27, 0x0d, 0x6c, + 0xb4, 0x14, 0x6a, 0x16, 0x6d, 0xc1, 0x66, 0xbf, 0x81, 0x87, 0xed, 0x61, 0xbb, 0xd7, 0x1d, 0x37, + 0x9e, 0x37, 0xb0, 0xa1, 0xe5, 0xf4, 0xbf, 0x9c, 0x83, 0xf2, 0x13, 0x62, 0x4e, 0x83, 0x93, 0x26, + 0xb5, 0x22, 0xfa, 0x08, 0xaa, 0x13, 0x32, 0x35, 0xdf, 0x8c, 0x65, 0x2f, 0x98, 0x66, 0x2e, 0x91, + 0xbe, 0xf7, 0x00, 0x57, 0x58, 0xc6, 0x80, 0xd3, 0xd1, 0xa7, 0xa0, 0xd9, 0x4e, 0x40, 0xbc, 0x53, + 0x73, 0x1a, 0x62, 0x33, 0x02, 0x7b, 0x17, 0x6f, 0xca, 0x3c, 0x09, 0xff, 0x21, 0x6c, 0x0a, 0x27, + 0x0b, 0xd1, 0xdc, 0xd9, 0xd2, 0x7b, 0x77, 0xf1, 0x86, 0xc8, 0x92, 0xe0, 0xcf, 0xe1, 0xb2, 0xe5, + 0x3a, 0x3e, 0x1d, 0x40, 0xec, 0x53, 0x32, 0xa6, 0xbe, 0xb8, 0xf0, 0x88, 0xcf, 0xdc, 0xae, 0xfa, + 0x30, 0x75, 0x1f, 0x6f, 0x29, 0xd9, 0x07, 0x22, 0x97, 0x72, 0x1d, 0x7b, 0xa6, 0x45, 0xc6, 0x73, + 0xe2, 0xd9, 0xee, 0x24, 0xfc, 0x4e, 0x3e, 0x94, 0x0a, 0xb1, 0xfc, 0x3e, 0xcb, 0x96, 0xdf, 0xda, + 0x15, 0x26, 0x2c, 0x26, 0x7b, 0x00, 0x45, 0x2b, 0x8a, 0xd5, 0xd0, 0x67, 0x50, 0xb0, 0xdc, 0xd9, + 0xcc, 0x74, 0x26, 0xcc, 0x93, 0x13, 0x43, 0x12, 0xcb, 0x60, 0x3d, 0x9a, 0x44, 0xa1, 0x2f, 0x21, + 0x7b, 0x12, 0x04, 0x73, 0xe6, 0x23, 0xe5, 0xbd, 0xf7, 0x57, 0x7f, 0xe0, 0xc9, 0x70, 0xd8, 0x67, + 0xff, 0x18, 0x2f, 0x63, 0x40, 0x9f, 0x43, 0x26, 0xb0, 0xe6, 0xcc, 0xe9, 0x63, 0x4e, 0x1d, 0x13, + 0xac, 0xa9, 0xb0, 0x51, 0x78, 0xfd, 0x25, 0x54, 0x63, 0x85, 0x29, 0x03, 0x0c, 0x1f, 0x1d, 0xe4, + 0x00, 0x23, 0x07, 0x25, 0xda, 0x9d, 0x54, 0xf9, 0xa0, 0x14, 0x8e, 0x23, 0x69, 0x65, 0x1c, 0xa9, + 0x43, 0xd1, 0x0f, 0xcc, 0x60, 0xe1, 0x13, 0x9f, 0x0d, 0x25, 0x55, 0x1c, 0xa6, 0xeb, 0x3a, 0x54, + 0x54, 0x09, 0x56, 0x95, 0xa9, 0xdf, 0x5f, 0xe5, 0xe5, 0x65, 0x28, 0x34, 0x7b, 0x9d, 0x4e, 0xa3, + 0xdb, 0xd2, 0x52, 0xb4, 0xd3, 0xa3, 0x22, 0x6b, 0x69, 0x54, 0x80, 0xcc, 0xb0, 0xd9, 0xd7, 0x32, + 0xfa, 0x63, 0x80, 0xa7, 0xf6, 0x74, 0xda, 0x77, 0xa7, 0xb6, 0xf5, 0x06, 0x7d, 0x0d, 0x15, 0xd5, + 0xb2, 0x42, 0x95, 0xeb, 0xc6, 0x92, 0xb2, 0x62, 0x65, 0xfd, 0x77, 0xd3, 0x34, 0xcc, 0x08, 0xcd, + 0x82, 0x3e, 0x85, 0xec, 0xc2, 0xb3, 0xe9, 0xe0, 0x4e, 0xbb, 0x8a, 0x6b, 0x2b, 0x6d, 0xb7, 0x3b, + 0xc2, 0x6d, 0xcc, 0x60, 0xe8, 0x4b, 0x28, 0x13, 0xe7, 0xd4, 0xf6, 0x5c, 0x67, 0xb6, 0x32, 0x08, + 0x31, 0xa2, 0x4c, 0xac, 0x22, 0x51, 0x1d, 0x72, 0xfe, 0x09, 0x99, 0x4e, 0x99, 0xf7, 0x15, 0x1f, + 0x66, 0x03, 0x6f, 0x41, 0x30, 0x27, 0x45, 0xa1, 0x0e, 0x37, 0x88, 0x08, 0x75, 0x6e, 0x40, 0xc9, + 0xf4, 0x8e, 0x17, 0x94, 0xdb, 0xaf, 0x15, 0xb6, 0x33, 0xb4, 0x1f, 0x0c, 0x09, 0x61, 0xe7, 0xcf, + 0x87, 0x67, 0xf6, 0xbf, 0xfe, 0xeb, 0x2c, 0x84, 0x68, 0xaf, 0x09, 0x9d, 0x6e, 0x01, 0x10, 0x16, + 0x83, 0x99, 0x2f, 0xa6, 0x7c, 0x80, 0x2b, 0x62, 0x85, 0x82, 0x6e, 0x41, 0x81, 0xbc, 0x0e, 0x3c, + 0xd3, 0x0a, 0x98, 0x1c, 0x52, 0x46, 0x49, 0xa4, 0xa5, 0x5a, 0xa6, 0x75, 0x42, 0x58, 0x3b, 0x2d, + 0x62, 0x9e, 0x40, 0xef, 0x42, 0xd9, 0x5d, 0x04, 0xf3, 0x45, 0x30, 0x3e, 0xb2, 0xa7, 0x44, 0x88, + 0x03, 0x9c, 0x74, 0x60, 0x4f, 0x89, 0xfe, 0x3b, 0x59, 0xa8, 0x84, 0xb1, 0x1f, 0xd5, 0xf8, 0x67, + 0xa2, 0x81, 0x6d, 0xb2, 0x06, 0x76, 0x5d, 0xd1, 0x9d, 0x82, 0x52, 0x5b, 0xd8, 0x03, 0x28, 0x13, + 0x91, 0x35, 0x0e, 0x47, 0xf0, 0xcb, 0x2b, 0xf8, 0x5a, 0xb2, 0x3e, 0xae, 0xd7, 0x9e, 0xa0, 0xaf, + 0xa0, 0x72, 0x24, 0x7b, 0x5d, 0xca, 0x57, 0x3c, 0x6b, 0x00, 0x2c, 0x87, 0xd0, 0xf6, 0xe4, 0xed, + 0x9b, 0xf4, 0x03, 0x28, 0x59, 0x32, 0xfa, 0x14, 0x43, 0xc6, 0x3b, 0xab, 0x02, 0x53, 0xca, 0x14, + 0x21, 0xd1, 0x5d, 0x28, 0x79, 0xc4, 0x77, 0x17, 0x9e, 0xc5, 0xfa, 0xb2, 0x4c, 0x3c, 0x78, 0xc2, + 0x22, 0x0b, 0x47, 0xa0, 0x70, 0x78, 0xe7, 0x03, 0x1f, 0x1f, 0xde, 0xeb, 0x90, 0xe7, 0xd9, 0x35, + 0xa0, 0xd4, 0xfd, 0x74, 0x2d, 0x85, 0x05, 0x85, 0xe2, 0x27, 0x66, 0x60, 0x32, 0x93, 0x55, 0x30, + 0xfb, 0x4f, 0x85, 0x9d, 0xd8, 0xbe, 0x45, 0x07, 0xf3, 0x37, 0xb5, 0x4a, 0x52, 0xd8, 0x96, 0xcc, + 0xe2, 0xc2, 0x86, 0x48, 0xf4, 0xb3, 0x70, 0xc5, 0x3f, 0x59, 0x04, 0x13, 0xf7, 0x95, 0x33, 0x8e, + 0x35, 0xbe, 0xea, 0x99, 0x8d, 0x6f, 0x4b, 0x32, 0x3d, 0x8e, 0x1a, 0xa1, 0x32, 0xbe, 0x6e, 0x9c, + 0x3d, 0xbe, 0xea, 0x9f, 0xac, 0xe9, 0x2c, 0x5a, 0xc6, 0x41, 0x63, 0x74, 0x38, 0xd4, 0x52, 0x08, + 0x20, 0xdf, 0x1c, 0x0d, 0x86, 0xbd, 0x8e, 0x96, 0xd6, 0xff, 0x66, 0x0a, 0xa0, 0x63, 0xfa, 0x01, + 0x57, 0x35, 0x8b, 0x08, 0x27, 0xa2, 0x11, 0xd0, 0x08, 0x47, 0x46, 0x88, 0xb4, 0x2f, 0xa2, 0x61, + 0x78, 0x4d, 0x09, 0xc3, 0xab, 0x0f, 0xb3, 0x0f, 0xee, 0x3e, 0xb8, 0x2b, 0xfa, 0x3d, 0x0d, 0x32, + 0x73, 0x7b, 0xc2, 0xd4, 0x56, 0xc2, 0xf4, 0x6f, 0x2c, 0x62, 0xc9, 0x25, 0x22, 0x96, 0x1a, 0x14, + 0x4e, 0x89, 0xe7, 0xd3, 0xa8, 0x96, 0xc5, 0x39, 0x58, 0x26, 0xd5, 0xa0, 0x9d, 0x7b, 0xd2, 0x19, + 0x41, 0xbb, 0xfe, 0x0f, 0x53, 0x50, 0xe2, 0xd3, 0x2c, 0x2a, 0x7c, 0x3c, 0xd4, 0x4d, 0x27, 0x3e, + 0xc8, 0x05, 0xa7, 0x2e, 0x9d, 0x63, 0x82, 0xdf, 0x13, 0x82, 0xc7, 0x5c, 0x2a, 0x73, 0x11, 0x97, + 0xba, 0x0f, 0x60, 0x06, 0x81, 0x67, 0xbf, 0x58, 0x04, 0xa1, 0x17, 0x2a, 0xe1, 0x71, 0x43, 0xe6, + 0x61, 0x05, 0x86, 0xde, 0x63, 0x9a, 0xcd, 0x2f, 0x55, 0x89, 0x4f, 0x12, 0xa9, 0xb2, 0xf5, 0x7f, + 0x96, 0x81, 0xdc, 0x33, 0xd6, 0xf1, 0xec, 0x84, 0x41, 0x51, 0x7a, 0x67, 0x43, 0x6d, 0xb8, 0x2c, + 0x5b, 0x6d, 0xe9, 0xbb, 0x74, 0x68, 0x32, 0xa7, 0xa6, 0xb7, 0x3c, 0x3b, 0xe0, 0xd8, 0x01, 0xcb, + 0xc5, 0x02, 0x45, 0xf1, 0x9e, 0xe9, 0x1c, 0x13, 0x5f, 0x44, 0xb7, 0x4b, 0x78, 0xcc, 0x72, 0xb1, + 0x40, 0xa1, 0xdb, 0x90, 0xf1, 0x09, 0x8f, 0x6a, 0x63, 0x95, 0x14, 0x85, 0x93, 0x00, 0xd3, 0x7c, + 0x26, 0x30, 0x79, 0xcd, 0xa3, 0xda, 0xf2, 0x0a, 0x81, 0xc9, 0xeb, 0x00, 0x33, 0x44, 0xfd, 0x16, + 0xe4, 0xb9, 0x48, 0xf1, 0x3e, 0x37, 0x25, 0xfa, 0xdc, 0xfa, 0x67, 0x90, 0x63, 0x22, 0xd0, 0xec, + 0x17, 0xe4, 0xd8, 0x76, 0x58, 0x76, 0x16, 0xf3, 0x04, 0x75, 0x33, 0xe2, 0x4c, 0x98, 0x47, 0x66, + 0x31, 0xfd, 0x5b, 0x7f, 0x00, 0x79, 0x2e, 0x33, 0xfa, 0x21, 0xe4, 0x98, 0xd4, 0x62, 0x64, 0xba, + 0xb2, 0xb2, 0x6a, 0x98, 0x63, 0xea, 0xd7, 0x20, 0x33, 0x20, 0x6c, 0xb8, 0xb6, 0x03, 0x32, 0x63, + 0x2c, 0x25, 0xcc, 0xfe, 0xd7, 0x6f, 0x40, 0x96, 0x0a, 0xbc, 0x66, 0xd2, 0x7d, 0x4f, 0xb4, 0x2f, + 0x80, 0xfc, 0xa0, 0xd9, 0x38, 0x6c, 0x60, 0xed, 0x07, 0xf4, 0x3f, 0x6e, 0x74, 0x1f, 0xb3, 0x20, + 0xb3, 0x00, 0x99, 0x81, 0x31, 0xe4, 0x13, 0x91, 0xa1, 0xf1, 0xcd, 0x50, 0xcb, 0xe8, 0x7f, 0x40, + 0xdd, 0x54, 0xba, 0x42, 0xd8, 0x23, 0xa5, 0x94, 0x09, 0x87, 0x34, 0x78, 0xfa, 0x2d, 0x0c, 0x9e, + 0x79, 0x4b, 0x83, 0x67, 0xdf, 0xc6, 0xe0, 0xf9, 0xff, 0x57, 0x06, 0xd7, 0x7f, 0x5a, 0x84, 0xa2, + 0x6c, 0x45, 0x7f, 0x34, 0xea, 0x9e, 0x3b, 0xa7, 0xee, 0x6b, 0x66, 0x68, 0x2d, 0x28, 0x7b, 0xc4, + 0xa7, 0x21, 0x3b, 0x9b, 0xad, 0x17, 0x93, 0x41, 0xa7, 0x54, 0x02, 0xfd, 0x23, 0x51, 0x3c, 0xda, + 0x52, 0xd8, 0xe8, 0x58, 0x3f, 0xb1, 0xfd, 0x97, 0xa2, 0xf3, 0xbb, 0xbe, 0x82, 0xbd, 0x65, 0xfb, + 0x22, 0xc6, 0xa5, 0x40, 0xf4, 0x13, 0xda, 0x7f, 0x9d, 0xba, 0x16, 0x8b, 0x51, 0x78, 0xa4, 0xbb, + 0xbd, 0xf2, 0xa3, 0x02, 0xc3, 0x47, 0xa9, 0x90, 0x05, 0x3d, 0x80, 0xbc, 0x7f, 0x62, 0x7a, 0x64, + 0xc2, 0x06, 0xc3, 0xf2, 0xde, 0xcd, 0x15, 0xcc, 0x03, 0x06, 0x60, 0x9c, 0x02, 0x5c, 0xff, 0x16, + 0x36, 0x13, 0xf5, 0x88, 0x4f, 0x43, 0x53, 0xc9, 0x69, 0x68, 0x34, 0x82, 0xa5, 0xcf, 0x99, 0x21, + 0xfe, 0xa5, 0x2c, 0x14, 0x65, 0x25, 0x51, 0x1b, 0xca, 0x73, 0x3a, 0x34, 0xf8, 0x01, 0x71, 0x2c, + 0x22, 0xe2, 0xd6, 0x8f, 0xce, 0x50, 0xcb, 0x6e, 0x3f, 0x82, 0x63, 0x95, 0x97, 0x4a, 0x70, 0xea, + 0x4e, 0x17, 0x33, 0xb2, 0x2c, 0xc1, 0x33, 0x46, 0xc7, 0x22, 0x1f, 0x3d, 0x0c, 0x03, 0x84, 0xcc, + 0x5a, 0x2b, 0x86, 0xdf, 0x1b, 0xf0, 0x01, 0x42, 0x70, 0xd4, 0x1f, 0x41, 0x59, 0x91, 0x60, 0x69, + 0x44, 0x8d, 0x29, 0x29, 0x9d, 0x50, 0x52, 0xfd, 0x37, 0xd2, 0x90, 0xe7, 0xe5, 0x29, 0x13, 0xe3, + 0x74, 0x7c, 0x62, 0xbc, 0x4e, 0x02, 0xb5, 0xa5, 0x3c, 0x52, 0x66, 0x21, 0xe5, 0x0b, 0x31, 0xf7, + 0xcd, 0xe0, 0x44, 0x4c, 0x57, 0x7e, 0x02, 0xb9, 0x99, 0xbb, 0x70, 0x02, 0x51, 0xf9, 0x9d, 0x0b, + 0x70, 0x77, 0x28, 0x1e, 0x73, 0xb6, 0x7a, 0x1d, 0xb2, 0xb4, 0x34, 0xda, 0xd8, 0x3d, 0xd7, 0x0d, + 0x64, 0x63, 0xa7, 0xff, 0xeb, 0xd7, 0x21, 0xc7, 0xb0, 0xab, 0x32, 0xf5, 0xeb, 0xa2, 0x6b, 0x2d, + 0x42, 0xb6, 0xdf, 0x18, 0x3e, 0xd1, 0x52, 0xa8, 0x04, 0xb9, 0x4e, 0x6f, 0xd4, 0x1d, 0x6a, 0xe9, + 0xfa, 0x26, 0x54, 0x63, 0x3e, 0x5c, 0xaf, 0x00, 0x44, 0x7e, 0xa9, 0xff, 0xc5, 0x34, 0xd4, 0x86, + 0x9e, 0x79, 0x74, 0x64, 0x5b, 0x34, 0x7a, 0xf4, 0xdc, 0xe9, 0x20, 0x30, 0x03, 0xdb, 0x0f, 0x6c, + 0xcb, 0x5f, 0x32, 0x42, 0x0d, 0x0a, 0x2f, 0x4c, 0xeb, 0xe5, 0xd4, 0x3d, 0x66, 0x1a, 0xca, 0x62, + 0x99, 0x64, 0xa3, 0xce, 0x9b, 0x40, 0x0c, 0x8f, 0x74, 0xd4, 0xa1, 0x09, 0x4a, 0x9d, 0x78, 0xee, + 0x9c, 0xf7, 0x23, 0x59, 0xcc, 0x13, 0x74, 0x7a, 0x40, 0x03, 0xbd, 0xa9, 0x3d, 0xb3, 0x03, 0x3e, + 0xb3, 0xce, 0x62, 0x85, 0x42, 0xbf, 0x32, 0x37, 0xad, 0x97, 0x24, 0xe0, 0x13, 0xe8, 0x2c, 0x96, + 0x49, 0x5a, 0xf9, 0xef, 0xa6, 0xc4, 0x61, 0x8d, 0x3c, 0x8b, 0xd9, 0x7f, 0x8a, 0xf6, 0xcc, 0x80, + 0xbc, 0x98, 0xfb, 0xac, 0xeb, 0xc8, 0x62, 0x99, 0x94, 0x39, 0xf3, 0xb9, 0xcf, 0xda, 0xb7, 0xc8, + 0x99, 0xcf, 0xd9, 0x0a, 0xaa, 0x47, 0xbe, 0x5b, 0x90, 0x05, 0x5b, 0xb9, 0xa1, 0x59, 0x61, 0x5a, + 0xff, 0xa5, 0x1c, 0x54, 0xda, 0x73, 0x45, 0x09, 0xb7, 0x00, 0x0e, 0x5c, 0xef, 0x95, 0xe9, 0x4d, + 0x6c, 0xe7, 0x98, 0x35, 0xa4, 0x0c, 0x56, 0x28, 0x34, 0xbf, 0x45, 0x8e, 0xcc, 0xc5, 0x34, 0x18, + 0x0e, 0x0f, 0x99, 0x5e, 0x32, 0x58, 0xa1, 0xd0, 0xfc, 0xb6, 0x83, 0x89, 0x45, 0xec, 0x53, 0xa1, + 0x9f, 0x0c, 0x56, 0x28, 0x68, 0x1b, 0xca, 0x6d, 0xe7, 0xc9, 0xc4, 0x33, 0x3c, 0xcf, 0xf5, 0xb8, + 0xaa, 0x32, 0x58, 0x25, 0x21, 0x1d, 0x2a, 0x6d, 0x87, 0x06, 0x71, 0x02, 0x92, 0x63, 0x90, 0x18, + 0x0d, 0x7d, 0x00, 0x55, 0x2a, 0x53, 0xcb, 0x0c, 0xcc, 0x63, 0xcf, 0x9c, 0x71, 0xd5, 0x65, 0x70, + 0x9c, 0x88, 0x76, 0x60, 0xb3, 0xed, 0x8c, 0x9c, 0x97, 0x8e, 0xfb, 0xca, 0xe9, 0x7b, 0x6e, 0xe0, + 0xf2, 0x68, 0x31, 0x83, 0x93, 0x64, 0x2e, 0x35, 0x0d, 0xd1, 0x4d, 0x6f, 0xc2, 0x35, 0xcb, 0xa4, + 0x96, 0x14, 0x91, 0x4f, 0xa6, 0x36, 0x0d, 0x40, 0x99, 0x7e, 0x79, 0xbe, 0xa0, 0xd0, 0x5a, 0xf5, + 0x16, 0x01, 0xa6, 0x5a, 0xf5, 0x03, 0xae, 0xe5, 0x0c, 0x56, 0x49, 0x02, 0x11, 0x7e, 0xa2, 0x1c, + 0x22, 0xc2, 0x6f, 0x70, 0x44, 0xd7, 0xc5, 0x2e, 0x8b, 0x18, 0x2b, 0x21, 0x42, 0x92, 0xa8, 0x66, + 0x30, 0x31, 0xfd, 0x99, 0x58, 0x2b, 0x64, 0x33, 0x84, 0x0c, 0x8e, 0xd1, 0xa8, 0xa4, 0x2c, 0x8d, + 0xc9, 0x77, 0x13, 0x3e, 0x0d, 0xc8, 0x60, 0x85, 0x42, 0x9d, 0x81, 0xa5, 0x7a, 0x4f, 0x7d, 0x36, + 0x53, 0xcc, 0xe0, 0x30, 0x1d, 0xf2, 0x1e, 0x98, 0xf6, 0xd4, 0xaf, 0x69, 0x0a, 0x2f, 0xa3, 0x50, + 0x17, 0x3b, 0xf0, 0xcc, 0x63, 0xca, 0x7a, 0x89, 0x65, 0xca, 0x24, 0xed, 0xaf, 0xe8, 0x5f, 0xce, + 0x88, 0x58, 0x5e, 0x44, 0xa0, 0x35, 0xa3, 0x89, 0xa6, 0x47, 0x4c, 0x5a, 0xb3, 0x2d, 0x5e, 0x33, + 0x85, 0xa4, 0xff, 0xed, 0x02, 0x6c, 0xb4, 0xad, 0x99, 0xea, 0x88, 0x57, 0x21, 0xdf, 0x76, 0x3a, + 0xfe, 0xb1, 0x2f, 0x9c, 0x50, 0xa4, 0x68, 0x05, 0xda, 0x8e, 0x70, 0x0d, 0xee, 0x7e, 0x61, 0x9a, + 0xbb, 0x4e, 0xd3, 0x5f, 0xcc, 0x44, 0x7e, 0x46, 0xba, 0x4e, 0x44, 0x43, 0x1f, 0xc2, 0x06, 0x35, + 0x9c, 0x1f, 0x8c, 0x1c, 0x8f, 0x98, 0xd6, 0x89, 0xf4, 0xc1, 0x04, 0x95, 0x3b, 0x2a, 0xd5, 0xaa, + 0xf1, 0xda, 0x9a, 0x48, 0x2f, 0x54, 0x49, 0x1c, 0xd1, 0x37, 0xbd, 0x59, 0xdf, 0x73, 0x5f, 0x48, + 0x17, 0x54, 0x49, 0x5c, 0x9e, 0x81, 0x67, 0xfd, 0xdc, 0x82, 0x38, 0xf4, 0x4b, 0x05, 0x29, 0x4f, + 0x44, 0xe3, 0xa5, 0x60, 0x32, 0xb1, 0x3d, 0x62, 0x05, 0xd2, 0xf7, 0x54, 0x12, 0x55, 0x7b, 0xdb, + 0x31, 0xac, 0x13, 0x57, 0x7a, 0x9e, 0x4c, 0x72, 0xb7, 0xa4, 0x7f, 0x31, 0x99, 0x4b, 0xaf, 0x53, + 0x28, 0xfc, 0xfb, 0x54, 0x60, 0x3f, 0x30, 0x67, 0x73, 0xe9, 0x75, 0x31, 0x1a, 0x6f, 0x24, 0x61, + 0x9a, 0x15, 0x54, 0x91, 0x8d, 0x24, 0x46, 0xe6, 0x92, 0xd2, 0x46, 0xd8, 0x31, 0xfd, 0x97, 0xbe, + 0xf0, 0x3e, 0x95, 0xc4, 0x75, 0x2b, 0x93, 0xac, 0xa8, 0x0d, 0xa9, 0x5b, 0x95, 0x4a, 0x6b, 0xd4, + 0x5b, 0x04, 0xcc, 0xb8, 0xdc, 0x07, 0x65, 0x92, 0x3a, 0x52, 0x6f, 0x11, 0x08, 0xf3, 0x71, 0x0f, + 0x8c, 0x08, 0x54, 0x56, 0xda, 0x62, 0x54, 0xe3, 0x71, 0x47, 0x4c, 0x92, 0x69, 0xcd, 0x7b, 0x8b, + 0x20, 0x32, 0x1f, 0xf7, 0xc9, 0x18, 0x4d, 0x60, 0x22, 0x03, 0x6e, 0x85, 0x98, 0xc8, 0x82, 0x1f, + 0x40, 0xb5, 0xb7, 0x08, 0x14, 0x13, 0x5e, 0xe6, 0x1d, 0x4d, 0x8c, 0x28, 0x4a, 0x8a, 0x8c, 0x78, + 0x25, 0x2c, 0x29, 0xb2, 0x62, 0x1d, 0x8a, 0xb4, 0x22, 0xcc, 0x8c, 0x57, 0xb9, 0xdf, 0xca, 0xb4, + 0x68, 0xfa, 0xa1, 0x21, 0xdf, 0x09, 0x9b, 0x7e, 0x68, 0x49, 0x2e, 0x87, 0x62, 0xca, 0x5a, 0x28, + 0x87, 0x62, 0xcb, 0x3b, 0xa0, 0xa9, 0x04, 0x56, 0xd8, 0x35, 0x06, 0x5c, 0xa2, 0x0b, 0x99, 0x23, + 0x73, 0xd6, 0x43, 0x99, 0x23, 0x7b, 0x72, 0x7d, 0xc7, 0x0c, 0x7a, 0x3d, 0xd4, 0xb7, 0x4a, 0xd6, + 0xff, 0x49, 0x06, 0xaa, 0x43, 0x4b, 0x6d, 0xbf, 0xb4, 0xb3, 0x0a, 0xdc, 0xc6, 0xf4, 0xd8, 0xf5, + 0xec, 0xe0, 0x64, 0x26, 0x5a, 0x71, 0x8c, 0x46, 0xdb, 0x38, 0x0e, 0xdc, 0x8e, 0xed, 0x88, 0x96, + 0x2c, 0x52, 0x92, 0x6e, 0xbe, 0x16, 0x2d, 0x58, 0xa4, 0xa8, 0xdf, 0x74, 0xcc, 0xd7, 0x4d, 0xd7, + 0x71, 0x44, 0xa3, 0x95, 0x49, 0xaa, 0xc1, 0x86, 0x15, 0xd8, 0xa7, 0xa4, 0x37, 0x27, 0x4e, 0xd8, + 0x5a, 0x15, 0x12, 0x95, 0xa7, 0x6f, 0xfa, 0x7e, 0x08, 0xe1, 0xcd, 0x35, 0x46, 0xa3, 0x98, 0x46, + 0x10, 0x90, 0xd9, 0x3c, 0xe0, 0x3d, 0x99, 0x68, 0xaf, 0x2a, 0x8d, 0x7e, 0xc9, 0xf0, 0x03, 0xf3, + 0x05, 0x8d, 0x6b, 0xa3, 0xf6, 0xaa, 0x90, 0xa8, 0x0f, 0x37, 0x17, 0x9e, 0xc7, 0x48, 0xa2, 0xc5, + 0x46, 0x04, 0xde, 0xaf, 0x0d, 0xc8, 0xb1, 0x6c, 0xaf, 0x22, 0x25, 0xda, 0x04, 0xcb, 0x28, 0x87, + 0x6d, 0x82, 0xe5, 0x6c, 0x43, 0x19, 0x93, 0xc0, 0x33, 0x1d, 0x9f, 0xe5, 0x8a, 0x81, 0x41, 0x21, + 0xf1, 0x32, 0x0d, 0xcf, 0x93, 0x8d, 0x52, 0xa4, 0x44, 0x99, 0x98, 0x0e, 0x49, 0x1b, 0x61, 0x99, + 0x34, 0xb9, 0xd4, 0x53, 0x6e, 0x2e, 0xf7, 0x94, 0xfa, 0x6f, 0xa6, 0xa1, 0x3a, 0x9a, 0xa8, 0x36, + 0x65, 0x3d, 0x40, 0x34, 0xe8, 0xa6, 0x64, 0x0f, 0x10, 0x0d, 0xb9, 0x35, 0x28, 0x74, 0xdd, 0xbe, + 0xeb, 0x05, 0xb2, 0x73, 0x96, 0xc9, 0x58, 0xbf, 0x9d, 0x59, 0xee, 0xb7, 0x69, 0x03, 0x0e, 0x0b, + 0xce, 0x86, 0xbe, 0x18, 0x95, 0x4c, 0xfd, 0xc9, 0x3a, 0x7d, 0xb1, 0x38, 0x8a, 0x87, 0x05, 0x2a, + 0x8d, 0x62, 0x06, 0xce, 0x24, 0xc2, 0x08, 0x1b, 0xab, 0xb4, 0xa5, 0x9a, 0x17, 0x56, 0x8c, 0x11, + 0x14, 0x73, 0xec, 0xb8, 0x1e, 0x99, 0x74, 0x16, 0xd3, 0xc0, 0x16, 0x46, 0x8e, 0xd1, 0xf4, 0xdf, + 0x4e, 0xc1, 0xc6, 0xa0, 0xdb, 0xe9, 0x2b, 0xea, 0xb9, 0x07, 0x45, 0x7b, 0x3e, 0xf6, 0x03, 0x33, + 0xf0, 0x97, 0x97, 0xce, 0xd5, 0x28, 0x0b, 0x17, 0x6c, 0x96, 0xf2, 0xd1, 0x97, 0x00, 0xb6, 0x35, + 0x93, 0x4c, 0xe9, 0xe4, 0x1e, 0x67, 0x7c, 0x4c, 0xc4, 0x25, 0x5b, 0xa4, 0x7d, 0xf4, 0x39, 0x94, + 0x02, 0x4b, 0xf2, 0x65, 0x92, 0xab, 0x8d, 0xb1, 0xa6, 0x88, 0x8b, 0x81, 0x15, 0x71, 0x2d, 0x26, + 0x92, 0x2b, 0x9b, 0xe4, 0x8a, 0x19, 0x1b, 0x17, 0x17, 0x3c, 0xe9, 0xeb, 0xff, 0x60, 0x13, 0x90, + 0x0c, 0xea, 0x95, 0xea, 0xde, 0x80, 0x52, 0x20, 0xbb, 0x14, 0xb1, 0x3c, 0x13, 0x11, 0xf8, 0x14, + 0xc6, 0xb5, 0x88, 0xef, 0x13, 0xbf, 0x76, 0x6b, 0x3b, 0xb5, 0x53, 0xc5, 0x11, 0x81, 0xfa, 0x49, + 0x70, 0xe2, 0x11, 0x73, 0xe2, 0xd7, 0xde, 0x65, 0x79, 0x32, 0x89, 0x3e, 0x85, 0x2d, 0x6b, 0xbe, + 0xf0, 0xc7, 0x0b, 0x5f, 0xec, 0x97, 0x8e, 0x7d, 0x62, 0x89, 0xed, 0x31, 0xac, 0xd1, 0xac, 0x91, + 0xcf, 0xb7, 0x4b, 0x07, 0x84, 0xe9, 0xfc, 0x0a, 0x83, 0xfb, 0x6f, 0xfc, 0x80, 0xcc, 0x14, 0x06, + 0xb6, 0x47, 0x86, 0x11, 0xcd, 0x1c, 0xb0, 0xbc, 0x90, 0xe5, 0x26, 0x00, 0x63, 0x61, 0x01, 0x38, + 0xdf, 0x1d, 0xc3, 0x25, 0x4a, 0x39, 0xa4, 0x04, 0xf4, 0x21, 0x6c, 0xb2, 0x6c, 0xc7, 0x13, 0x2b, + 0xb1, 0xdc, 0x47, 0xaa, 0xb8, 0x4a, 0xc9, 0x5d, 0x8f, 0xaf, 0xb5, 0xd2, 0xce, 0xf6, 0x92, 0xc4, + 0x05, 0x27, 0x9e, 0x1b, 0x04, 0x53, 0xc2, 0x17, 0xc3, 0xab, 0x78, 0x93, 0x23, 0x87, 0x92, 0x8c, + 0xbe, 0x84, 0x1a, 0xc3, 0x86, 0x40, 0x45, 0xd0, 0x12, 0x13, 0x80, 0xd5, 0x22, 0x64, 0x08, 0x65, + 0xfd, 0x10, 0x36, 0x67, 0xb4, 0x5a, 0x6e, 0x60, 0x4e, 0xc7, 0x7c, 0xce, 0xf1, 0x01, 0x0b, 0xe1, + 0xab, 0x33, 0x32, 0x1b, 0x52, 0xea, 0x3e, 0x9b, 0x7b, 0xdc, 0x83, 0x2b, 0x11, 0x6e, 0x46, 0x66, + 0xfe, 0x2b, 0x81, 0xbe, 0xcd, 0xd0, 0x48, 0xa2, 0x3b, 0x34, 0x8b, 0xb3, 0x88, 0xa2, 0x99, 0x16, + 0x04, 0x38, 0x1f, 0x16, 0xcd, 0x54, 0xc1, 0x71, 0x9f, 0xc1, 0x65, 0x8a, 0xf3, 0xdd, 0xa3, 0x20, + 0x06, 0xfe, 0x90, 0x81, 0x2f, 0xcd, 0xc8, 0x6c, 0xe0, 0x1e, 0x05, 0x0a, 0xc3, 0x07, 0xb0, 0x41, + 0x19, 0x8e, 0xec, 0x29, 0x11, 0x50, 0x3e, 0xeb, 0xa8, 0xcc, 0xc8, 0xec, 0xc0, 0x9e, 0x92, 0x18, + 0xca, 0x74, 0x5c, 0x47, 0xa0, 0xca, 0x21, 0xaa, 0xe1, 0xb8, 0x4e, 0x4c, 0x48, 0xb6, 0x27, 0x22, + 0x60, 0x1f, 0x85, 0x42, 0x36, 0x29, 0x95, 0xe3, 0x74, 0xa0, 0x84, 0xb1, 0xe7, 0xfb, 0x02, 0xc5, + 0x27, 0x5a, 0xe5, 0x19, 0x99, 0x61, 0xdf, 0x8f, 0xe9, 0x68, 0x66, 0xce, 0xe7, 0x64, 0xa2, 0x8a, + 0x57, 0x09, 0x75, 0xd4, 0x61, 0x79, 0x4b, 0x42, 0xfa, 0xaf, 0xcc, 0xb9, 0xc0, 0xee, 0x84, 0x42, + 0x0e, 0x5e, 0x99, 0x73, 0x8e, 0xda, 0xe3, 0x05, 0x2f, 0x1c, 0x72, 0x6a, 0x5b, 0x6c, 0xd3, 0x47, + 0x80, 0x3f, 0x66, 0xe0, 0xad, 0x19, 0x99, 0x8d, 0xa2, 0x3c, 0xce, 0xf3, 0x25, 0xd4, 0x98, 0xf6, + 0xdd, 0x57, 0xe3, 0xb9, 0x47, 0x7c, 0x7f, 0xe1, 0x91, 0xb1, 0x45, 0xe7, 0xbc, 0xc4, 0xab, 0x6d, + 0x33, 0x36, 0x5a, 0xe6, 0xa1, 0xfb, 0xaa, 0x2f, 0x72, 0x9b, 0x3c, 0x13, 0xfd, 0x18, 0xae, 0xb3, + 0x5a, 0x90, 0x89, 0xbd, 0x98, 0x2d, 0xf3, 0xbe, 0xc7, 0x78, 0x69, 0xd9, 0x1d, 0x86, 0x48, 0xb2, + 0x37, 0xe0, 0x26, 0x53, 0xa8, 0x67, 0x07, 0xb6, 0x65, 0x4e, 0x97, 0x0b, 0xd0, 0x59, 0x01, 0x75, + 0xaa, 0x5e, 0x81, 0x49, 0x16, 0xb1, 0x03, 0xda, 0xc4, 0xf6, 0x5f, 0xc6, 0x9c, 0xa1, 0xce, 0xb8, + 0x36, 0x28, 0x5d, 0xf1, 0x84, 0x0f, 0x61, 0x93, 0x21, 0x17, 0x3e, 0x99, 0x08, 0xe0, 0x75, 0x6e, + 0x3d, 0x4a, 0x1e, 0xf9, 0x64, 0xc2, 0x71, 0x9f, 0x40, 0x76, 0x4e, 0xbc, 0x23, 0xb1, 0xe5, 0xa1, + 0xf4, 0x7f, 0x7d, 0xe2, 0x1d, 0x29, 0x5d, 0x12, 0x43, 0x51, 0xa3, 0x38, 0x24, 0x18, 0x7b, 0xaf, + 0xc7, 0x72, 0xe2, 0xbc, 0xc1, 0x8d, 0xe2, 0x90, 0x00, 0xbf, 0xee, 0x8b, 0xd9, 0xf3, 0x36, 0x54, + 0x04, 0x8a, 0x7f, 0x78, 0x93, 0xcf, 0xbc, 0x19, 0x26, 0xf4, 0x19, 0x81, 0x20, 0x51, 0xbc, 0x99, + 0xc5, 0x65, 0x06, 0x09, 0x27, 0x9a, 0xf2, 0x5b, 0x74, 0x36, 0x3f, 0x27, 0x13, 0x16, 0x70, 0xca, + 0x6f, 0xb5, 0x38, 0x4d, 0xa2, 0x82, 0x48, 0x22, 0x14, 0xa2, 0x86, 0x49, 0x89, 0x02, 0x29, 0xd1, + 0x56, 0x28, 0xd1, 0x30, 0x2e, 0x51, 0x10, 0x4a, 0x74, 0x39, 0x94, 0x68, 0x98, 0x90, 0x28, 0x88, + 0x24, 0xba, 0xa2, 0x7c, 0x4b, 0x4a, 0xf4, 0x15, 0x5c, 0x63, 0x28, 0x6b, 0x3e, 0xf6, 0x82, 0x60, + 0x3c, 0xb3, 0x2d, 0xcf, 0xa5, 0xbd, 0xcd, 0x78, 0xfe, 0xe0, 0x2e, 0x0b, 0x3f, 0x53, 0xf8, 0x0a, + 0x65, 0xb0, 0xe6, 0x38, 0x08, 0x3a, 0x32, 0xb7, 0xff, 0xe0, 0xee, 0x19, 0x9c, 0x5f, 0xdf, 0x65, + 0x91, 0xe9, 0x6a, 0xce, 0xaf, 0xcf, 0xe4, 0x7c, 0xc0, 0xe2, 0xd5, 0x35, 0x9c, 0x0f, 0xce, 0xe2, + 0xfc, 0x9a, 0x05, 0xb0, 0x6b, 0x38, 0xbf, 0x46, 0x8f, 0xa0, 0x2e, 0x39, 0x4d, 0x16, 0xec, 0x8d, + 0x2d, 0xd7, 0x71, 0x88, 0x15, 0xd8, 0xae, 0xe3, 0xd7, 0x6e, 0x30, 0xd6, 0x77, 0x38, 0x2b, 0x0f, + 0x06, 0x9b, 0x51, 0x36, 0xfa, 0x19, 0xb8, 0x29, 0x99, 0x59, 0x77, 0xfc, 0xca, 0xb4, 0x83, 0x18, + 0xff, 0x4d, 0xc6, 0x7f, 0x8d, 0xf3, 0xd3, 0x3e, 0xf9, 0xb9, 0x69, 0x07, 0x6a, 0x09, 0xc7, 0x70, + 0x8b, 0x95, 0xc0, 0x97, 0x94, 0x28, 0x6f, 0xe0, 0xb9, 0x53, 0x36, 0xbe, 0x72, 0x97, 0xad, 0xbd, + 0x9f, 0x3c, 0x2a, 0xb3, 0x6e, 0xf9, 0x09, 0x5f, 0xa7, 0x9f, 0x59, 0xb7, 0x36, 0xf5, 0x04, 0xb6, + 0xe8, 0x87, 0x7c, 0x47, 0xc4, 0x0a, 0xa2, 0xf4, 0x3b, 0xc9, 0x06, 0x13, 0x8f, 0x48, 0xf0, 0x25, + 0x87, 0x04, 0x03, 0x47, 0x8d, 0x21, 0xf4, 0xbf, 0x93, 0x85, 0xaa, 0x1c, 0xcc, 0x47, 0xbe, 0x79, + 0x4c, 0xd0, 0x4f, 0xa0, 0x24, 0xb7, 0x77, 0xe5, 0x7e, 0xfd, 0x8a, 0xb5, 0x61, 0x86, 0x0d, 0xf7, + 0x84, 0x71, 0xc4, 0x82, 0x76, 0x20, 0xc7, 0xc6, 0x9d, 0x5a, 0x7a, 0xed, 0xbe, 0x18, 0x07, 0xd4, + 0xff, 0x7e, 0x06, 0x8a, 0xb2, 0x04, 0xf4, 0x08, 0xaa, 0xd1, 0xf6, 0xb3, 0x73, 0xe4, 0x8a, 0x0d, + 0xe8, 0xab, 0xab, 0x37, 0xae, 0x71, 0x85, 0xa8, 0x9b, 0xdd, 0x77, 0xa1, 0x64, 0x4e, 0xa7, 0xae, + 0x65, 0x06, 0x64, 0x72, 0xc6, 0x77, 0x23, 0x10, 0xfa, 0x11, 0x80, 0xa2, 0x38, 0x1e, 0x31, 0xdd, + 0x58, 0x66, 0x51, 0x94, 0xa7, 0xe0, 0xd1, 0x57, 0x50, 0x09, 0xf7, 0x97, 0xc7, 0x6c, 0x07, 0x33, + 0xbd, 0xfe, 0x94, 0x64, 0x39, 0x84, 0xb6, 0x27, 0xe8, 0x11, 0xe4, 0x02, 0x36, 0xc1, 0xe2, 0x5b, + 0x80, 0xb7, 0xcf, 0xd3, 0xec, 0xee, 0x90, 0xce, 0xa9, 0x38, 0x4f, 0xfd, 0x37, 0x52, 0x90, 0xa5, + 0xe9, 0x95, 0x5b, 0x22, 0xdb, 0x6c, 0xbd, 0x92, 0x1f, 0x5a, 0x54, 0x56, 0xa9, 0xf9, 0x81, 0x51, + 0xb6, 0x82, 0xf9, 0xf6, 0xbb, 0x96, 0xd1, 0xfa, 0x7b, 0xf6, 0x9c, 0x1d, 0xe4, 0x7f, 0xa1, 0xc1, + 0x46, 0xbc, 0x7b, 0x3e, 0x27, 0x20, 0xac, 0xc7, 0x0e, 0x29, 0xd2, 0xcc, 0x30, 0x4d, 0x27, 0x30, + 0xd6, 0x1b, 0x6b, 0x1a, 0xae, 0xa8, 0x8a, 0x14, 0xfa, 0x02, 0xde, 0xf1, 0x03, 0x73, 0x4a, 0x03, + 0x26, 0x4e, 0x19, 0x1f, 0x79, 0xae, 0x13, 0x10, 0x67, 0x22, 0x16, 0x59, 0xaf, 0x88, 0xec, 0x26, + 0xcb, 0x3d, 0x10, 0x99, 0xe8, 0x73, 0xb8, 0x9a, 0xe0, 0x7b, 0x41, 0x3b, 0x61, 0x67, 0x22, 0xe2, + 0x82, 0xcb, 0x31, 0xb6, 0x7d, 0x9e, 0x47, 0xc3, 0x7e, 0xdb, 0xf1, 0x03, 0x6f, 0x21, 0x9a, 0x3f, + 0x0f, 0x87, 0x62, 0x34, 0xf4, 0x31, 0x68, 0x3c, 0x18, 0xf1, 0xc8, 0x11, 0xf1, 0x88, 0x43, 0x35, + 0xcb, 0x17, 0x68, 0x37, 0x19, 0x1d, 0x87, 0x64, 0xf4, 0x1e, 0x54, 0x38, 0x74, 0x66, 0xb3, 0x20, + 0x98, 0x2f, 0xd8, 0x96, 0x19, 0xad, 0xc3, 0x48, 0x54, 0x27, 0x2f, 0x3c, 0xd3, 0xb1, 0x4e, 0x88, + 0x5c, 0xb5, 0x0d, 0xd3, 0xe8, 0x7d, 0xa8, 0xf2, 0xff, 0x92, 0x5f, 0x44, 0x51, 0x9c, 0x28, 0x0a, + 0xb8, 0x09, 0xf0, 0x62, 0xe1, 0x8b, 0x4a, 0x8a, 0x08, 0xaa, 0xf4, 0x62, 0xe1, 0xf3, 0x8a, 0xd1, + 0x6c, 0x8f, 0x1c, 0xc9, 0x6c, 0x1e, 0xe7, 0x94, 0x3c, 0x72, 0x24, 0xb2, 0xaf, 0x03, 0x8d, 0x7b, + 0xc7, 0xd6, 0xd4, 0xb5, 0x5e, 0xb2, 0xc1, 0x37, 0x85, 0x8b, 0xd6, 0x7c, 0xd1, 0xa4, 0x69, 0xca, + 0x4b, 0x9d, 0x50, 0xe4, 0x6e, 0xf0, 0x30, 0x99, 0x52, 0x78, 0xf6, 0xbb, 0x50, 0x9e, 0x9b, 0xc7, + 0x64, 0xcc, 0x56, 0x7e, 0xc3, 0xe1, 0x95, 0x92, 0x0e, 0x18, 0x85, 0x56, 0x7f, 0x66, 0x3b, 0xae, + 0x27, 0x11, 0x62, 0x74, 0x65, 0x34, 0x05, 0x62, 0xfe, 0xc9, 0x08, 0x72, 0x49, 0x40, 0x28, 0x4d, + 0x40, 0xa8, 0xbe, 0xa9, 0x51, 0x5f, 0x07, 0x63, 0xff, 0x95, 0x1d, 0x30, 0x4d, 0x21, 0xa1, 0x6f, + 0x4e, 0x1f, 0x08, 0x32, 0xba, 0x0d, 0x1b, 0xb4, 0x36, 0x33, 0xfb, 0x98, 0x7b, 0x95, 0x1c, 0x61, + 0x69, 0xdc, 0xde, 0x09, 0x89, 0xb4, 0x44, 0x73, 0x6a, 0x1f, 0xb3, 0xe3, 0x43, 0xf2, 0xc3, 0x7c, + 0x9c, 0xdd, 0x0c, 0xe9, 0xd1, 0xc7, 0xc9, 0x6c, 0x31, 0x65, 0x8c, 0x12, 0xca, 0x47, 0xdb, 0xcd, + 0x90, 0x2e, 0xa0, 0x1f, 0xc2, 0xe6, 0xf4, 0xde, 0x78, 0xc2, 0x0d, 0x3e, 0x75, 0xe9, 0xc4, 0xe6, + 0x2a, 0xff, 0xfa, 0xf4, 0x5e, 0x8b, 0x51, 0x0f, 0x29, 0x91, 0x06, 0xa1, 0x71, 0x9c, 0xb4, 0xee, + 0x3b, 0x3c, 0x08, 0x55, 0xd1, 0xc2, 0xc6, 0x3b, 0xa0, 0x45, 0x2c, 0x7e, 0xe0, 0x7a, 0x84, 0x2f, + 0xff, 0x64, 0xf1, 0x86, 0x44, 0x0f, 0x18, 0x15, 0xdd, 0x87, 0xab, 0x09, 0xa4, 0x2c, 0xfd, 0x1a, + 0x8f, 0x44, 0x63, 0x78, 0x51, 0xfc, 0x5d, 0xb8, 0x1c, 0x31, 0xcd, 0xa9, 0x5b, 0x73, 0x2d, 0xd7, + 0xe3, 0x02, 0xf5, 0xc3, 0x1c, 0xf4, 0x35, 0x5c, 0x5b, 0xe6, 0x90, 0x5f, 0xe2, 0x01, 0xde, 0xd5, + 0x24, 0x9b, 0xf8, 0x18, 0x57, 0x93, 0xad, 0xaa, 0xe9, 0x86, 0x54, 0x53, 0x7b, 0x49, 0x4d, 0xf6, + 0xb2, 0x9a, 0x6e, 0x4a, 0xa9, 0xda, 0x49, 0x35, 0xf1, 0x7a, 0xd8, 0x4b, 0xf5, 0xb8, 0x15, 0xe7, + 0x58, 0xaa, 0x87, 0xbd, 0xba, 0x1e, 0xef, 0xca, 0x7a, 0xb4, 0x57, 0xd5, 0xe3, 0x3a, 0x94, 0xa6, + 0x53, 0x4b, 0xd4, 0x80, 0xc7, 0xeb, 0xc5, 0xe9, 0xd4, 0xe2, 0xc2, 0xd3, 0x4a, 0x8a, 0x4c, 0x59, + 0xda, 0x7b, 0xa2, 0x92, 0x1c, 0x12, 0x35, 0x5e, 0x8a, 0x13, 0x26, 0xe5, 0x81, 0x37, 0x2d, 0x56, + 0x58, 0x93, 0xda, 0x5d, 0x66, 0xcb, 0x72, 0xde, 0x17, 0x76, 0x17, 0x20, 0x51, 0xd0, 0x6d, 0xa0, + 0x14, 0xb5, 0xd2, 0x1f, 0x84, 0xdf, 0x53, 0xea, 0xbb, 0x0b, 0x5b, 0x2a, 0x4c, 0x96, 0xc9, 0xa7, + 0x88, 0x97, 0x14, 0x6c, 0x24, 0xdf, 0x24, 0x98, 0xbe, 0x10, 0xb5, 0xe4, 0xf3, 0xbd, 0x12, 0xa5, + 0xf0, 0x6a, 0xd2, 0x79, 0x80, 0xcc, 0x96, 0x65, 0x7d, 0x24, 0xe6, 0x01, 0x02, 0x24, 0x0a, 0x7a, + 0x17, 0xca, 0x0c, 0x29, 0x6a, 0xca, 0xe7, 0x50, 0xac, 0x6c, 0x51, 0xd5, 0x3b, 0x70, 0x29, 0x02, + 0xc8, 0xb2, 0xf8, 0xec, 0x69, 0x33, 0x84, 0x89, 0xc2, 0x3e, 0x02, 0x46, 0x52, 0x6b, 0x7b, 0x27, + 0xfa, 0xaa, 0x52, 0xdd, 0xbb, 0x70, 0x39, 0x06, 0x94, 0xe5, 0xfe, 0x90, 0x3b, 0x84, 0x8a, 0x8e, + 0x2a, 0x6c, 0x47, 0x15, 0xfe, 0x84, 0x57, 0xd8, 0x56, 0x2b, 0x6c, 0x27, 0x2b, 0xfc, 0x29, 0xff, + 0xb4, 0x1d, 0xaf, 0xf0, 0x7b, 0x20, 0xba, 0x69, 0x51, 0xd4, 0x2e, 0xef, 0xd8, 0x38, 0x8d, 0x17, + 0xf6, 0x09, 0x20, 0x05, 0x22, 0x8b, 0xfb, 0x8c, 0x01, 0xb5, 0x08, 0x18, 0x49, 0xe6, 0xb8, 0x13, + 0xd9, 0x64, 0xee, 0x72, 0xc9, 0x28, 0x25, 0x94, 0x2c, 0xcc, 0x96, 0x45, 0xdd, 0xe3, 0x92, 0x49, + 0x50, 0x64, 0x0a, 0x86, 0x14, 0xa6, 0xd8, 0x13, 0x73, 0x10, 0x77, 0x42, 0x22, 0x53, 0x44, 0x00, + 0x59, 0xd6, 0x7d, 0x6e, 0x8a, 0x10, 0x16, 0x99, 0x82, 0x61, 0x15, 0x53, 0x7c, 0x1e, 0x7d, 0x35, + 0x6e, 0x8a, 0x18, 0x50, 0x96, 0xfb, 0x80, 0x9b, 0x42, 0x45, 0xf3, 0xa2, 0x75, 0x1b, 0x0a, 0x62, + 0xef, 0x0c, 0x7d, 0x02, 0x45, 0xf3, 0x98, 0x76, 0xd6, 0xb6, 0x3c, 0x91, 0xba, 0xe2, 0x68, 0x54, + 0x81, 0x41, 0xda, 0x89, 0x98, 0x27, 0x7d, 0x81, 0x98, 0x47, 0xff, 0x43, 0x80, 0x1c, 0xbb, 0xa7, + 0x23, 0x8e, 0x5f, 0xa5, 0x92, 0xd7, 0x40, 0xc4, 0x25, 0x1e, 0x16, 0x52, 0x25, 0x4f, 0x3f, 0xa6, + 0x93, 0x81, 0xe0, 0xda, 0xd3, 0x8f, 0x6a, 0x35, 0x32, 0x4b, 0x37, 0x4d, 0x92, 0xd5, 0x50, 0x8f, + 0xa9, 0x65, 0x13, 0xc7, 0xd4, 0xde, 0x85, 0xcc, 0xc2, 0x9b, 0x8a, 0xb3, 0x23, 0x55, 0x65, 0xfd, + 0x0e, 0x1f, 0x62, 0x9a, 0xf3, 0x3d, 0x0e, 0x40, 0xc6, 0x4f, 0xab, 0x15, 0x2e, 0x76, 0x5a, 0xed, + 0x4b, 0xa8, 0x28, 0x07, 0x48, 0x69, 0xbc, 0x94, 0x59, 0x7b, 0x82, 0xb4, 0x1c, 0x9d, 0x20, 0xf5, + 0x57, 0xdc, 0xee, 0x28, 0xbd, 0xdd, 0xed, 0x8e, 0xfa, 0xdf, 0x2d, 0x40, 0xa9, 0x37, 0x27, 0x22, + 0x7c, 0xdc, 0x8b, 0x5d, 0x0f, 0xb8, 0x95, 0xb0, 0xdc, 0x6e, 0x08, 0x54, 0x0f, 0x3f, 0x7c, 0x45, + 0x23, 0xdd, 0x85, 0x63, 0xc9, 0xe3, 0x0f, 0xdb, 0xeb, 0xb9, 0x0e, 0x19, 0x0e, 0x0b, 0x3c, 0x7a, + 0x02, 0x15, 0xfe, 0x6f, 0x7c, 0xec, 0xb9, 0x8b, 0xb9, 0x38, 0x84, 0x73, 0xfb, 0x3c, 0xfe, 0xc7, + 0x14, 0x8c, 0xcb, 0xd3, 0x28, 0x81, 0x1e, 0x41, 0x81, 0x9f, 0xea, 0x91, 0x47, 0x48, 0xde, 0x5b, + 0x5f, 0x08, 0x3f, 0x47, 0x43, 0xb0, 0xe4, 0x40, 0x0d, 0x28, 0x2d, 0x1c, 0xc9, 0x9e, 0x4d, 0x1e, + 0x7a, 0x4f, 0xb2, 0x8f, 0x24, 0x14, 0x47, 0x5c, 0x54, 0x07, 0x16, 0xdb, 0x81, 0x15, 0xa7, 0x99, + 0xce, 0xd0, 0x01, 0xdf, 0xa9, 0xc5, 0x02, 0x4f, 0x25, 0x9f, 0x10, 0x3f, 0xf0, 0xdc, 0x37, 0xe2, + 0x10, 0xd8, 0x19, 0x92, 0xb7, 0x38, 0x10, 0x4b, 0x8e, 0xfa, 0x23, 0xc8, 0x73, 0x95, 0xa0, 0x7b, + 0x22, 0xc6, 0xa4, 0xf3, 0x3f, 0x39, 0xf7, 0x44, 0x89, 0xa9, 0x0c, 0x3b, 0x89, 0x14, 0x88, 0x7f, + 0x7e, 0xfd, 0x0d, 0x94, 0x15, 0x7d, 0xa2, 0x3d, 0x28, 0x4a, 0xcf, 0x3a, 0x67, 0x02, 0x19, 0xe2, + 0xd0, 0x17, 0xe2, 0xab, 0xdc, 0x7c, 0xbc, 0x05, 0xbf, 0x13, 0xff, 0x2a, 0x2b, 0x3c, 0xfa, 0x34, + 0x4b, 0xd6, 0x1f, 0xd1, 0x3e, 0x89, 0x6b, 0x2e, 0xd6, 0xc2, 0x52, 0x17, 0x68, 0x61, 0xf5, 0x1f, + 0x43, 0x29, 0xb4, 0xc1, 0xf7, 0x60, 0xff, 0x02, 0xf2, 0xdc, 0x04, 0xe8, 0x13, 0x28, 0xf0, 0x03, + 0x48, 0x67, 0x71, 0x4a, 0x48, 0xfd, 0x4b, 0x28, 0x08, 0xfd, 0xbf, 0x1d, 0xa3, 0x7e, 0xb4, 0xea, + 0x84, 0x30, 0x40, 0xfe, 0xb0, 0x31, 0xea, 0x36, 0x9f, 0x68, 0x29, 0xa4, 0x41, 0x85, 0xff, 0x1f, + 0x3f, 0xc6, 0xbd, 0x51, 0x5f, 0xcb, 0x53, 0x28, 0x36, 0x06, 0x06, 0x7e, 0x66, 0x68, 0x69, 0x54, + 0x85, 0xd2, 0xa8, 0x2b, 0x93, 0x19, 0x76, 0x9c, 0x18, 0x1b, 0x8d, 0xa1, 0xa1, 0x65, 0xf9, 0x39, + 0xe3, 0xc1, 0x10, 0xf7, 0xbe, 0xd5, 0x72, 0xfa, 0xdf, 0x48, 0x43, 0xa5, 0xed, 0x9c, 0x12, 0xcf, + 0x27, 0x17, 0xee, 0x84, 0x45, 0x07, 0x98, 0x5e, 0xdb, 0x01, 0x26, 0x7b, 0xe9, 0xcc, 0xf7, 0xea, + 0xa5, 0xb3, 0xe7, 0x0e, 0x36, 0xcb, 0x1d, 0x59, 0x8e, 0x7d, 0xe9, 0xc2, 0x1d, 0x59, 0xdc, 0x13, + 0xf2, 0x17, 0x19, 0xae, 0x7e, 0x2b, 0x0b, 0x45, 0xd9, 0x30, 0x56, 0xae, 0x0b, 0x7c, 0x0c, 0x05, + 0xde, 0xa8, 0xd6, 0x2f, 0x0e, 0xe4, 0x59, 0x7b, 0x7a, 0xdb, 0x31, 0x29, 0x26, 0x6b, 0xf6, 0x22, + 0xc3, 0x8a, 0xda, 0x3a, 0x73, 0xc9, 0x1d, 0xb1, 0x35, 0xad, 0xf3, 0xff, 0xee, 0x96, 0x40, 0xe9, + 0xc2, 0xb7, 0x04, 0xbe, 0x82, 0xca, 0x09, 0xbb, 0xe1, 0x33, 0x66, 0xf7, 0xea, 0x96, 0xef, 0x31, + 0x28, 0xf7, 0x7f, 0x70, 0xf9, 0x44, 0xb9, 0xbb, 0xf5, 0x00, 0xca, 0x2f, 0xed, 0xe9, 0x74, 0x3c, + 0x67, 0xb7, 0x66, 0xc4, 0x59, 0x7f, 0x65, 0xd8, 0x8b, 0x6e, 0xd4, 0x60, 0x78, 0x19, 0xdd, 0xae, + 0x91, 0x97, 0x06, 0xf2, 0xca, 0xa5, 0x81, 0x68, 0xbd, 0x05, 0xce, 0x5e, 0x6f, 0x89, 0x5f, 0x2f, + 0x28, 0x5f, 0xf4, 0x7a, 0x81, 0xfe, 0x35, 0x54, 0x63, 0xfd, 0x19, 0x5b, 0xad, 0x63, 0xeb, 0x51, + 0xeb, 0x7b, 0x5b, 0x0e, 0xd0, 0x7f, 0x3d, 0x77, 0xc6, 0xe2, 0xd3, 0x5b, 0x38, 0xd9, 0xf7, 0x6f, + 0x8c, 0x89, 0x1b, 0x2a, 0xd9, 0xa4, 0xa2, 0xd7, 0xdc, 0x50, 0x51, 0xbd, 0x3a, 0x77, 0xae, 0x57, + 0x7f, 0xcc, 0xae, 0xd9, 0x06, 0xa4, 0x96, 0x67, 0x67, 0x28, 0xb7, 0xe2, 0xf5, 0x18, 0xd0, 0x2c, + 0xcc, 0x11, 0xf1, 0x06, 0x50, 0xb8, 0x48, 0x03, 0xb8, 0xab, 0x5c, 0xea, 0x2a, 0x26, 0xc3, 0x23, + 0x59, 0xfe, 0xc2, 0x8f, 0xae, 0x7a, 0xa1, 0x26, 0x6c, 0xf1, 0xff, 0xe3, 0xc5, 0x7c, 0x62, 0x06, + 0x64, 0xcc, 0x85, 0x2b, 0xb1, 0xd0, 0x66, 0xa5, 0x70, 0x97, 0x38, 0x7e, 0xc4, 0xe0, 0x8c, 0x44, + 0x27, 0x17, 0xf1, 0x42, 0x16, 0x0b, 0x9b, 0x1f, 0xdd, 0xad, 0x60, 0x4d, 0x85, 0x8f, 0x16, 0xf6, + 0xe4, 0xe2, 0xd7, 0x32, 0xbf, 0xef, 0x1d, 0x97, 0x58, 0x0b, 0xad, 0x5e, 0xb8, 0x85, 0xca, 0xbb, + 0x58, 0x1b, 0xd1, 0x5d, 0x2c, 0xfd, 0x97, 0x2b, 0x00, 0x91, 0xde, 0x54, 0x37, 0x4c, 0x9d, 0xe3, + 0x86, 0xa1, 0x9d, 0xd3, 0xe7, 0xda, 0xb9, 0x06, 0x85, 0x19, 0xf1, 0x7d, 0xf3, 0x98, 0x88, 0xab, + 0x2a, 0x32, 0x89, 0xee, 0x87, 0x67, 0x7e, 0x4b, 0xc9, 0x6b, 0x56, 0x91, 0x54, 0x89, 0xc3, 0xbe, + 0x94, 0xc9, 0x23, 0xa6, 0xef, 0x3a, 0xcc, 0x02, 0xeb, 0x98, 0x30, 0x83, 0x60, 0x01, 0x0d, 0x7b, + 0x8b, 0x8c, 0xd2, 0x5b, 0xc4, 0x1d, 0xfb, 0xbc, 0xc1, 0x29, 0xd1, 0x7a, 0x0a, 0x17, 0x6c, 0x3d, + 0xb1, 0x55, 0xdc, 0xbc, 0x58, 0xf6, 0x0b, 0x57, 0x71, 0xa9, 0x4d, 0xa8, 0x2f, 0x95, 0xb9, 0x58, + 0xf4, 0x3f, 0x55, 0x17, 0xef, 0x1e, 0xdf, 0xb0, 0x4e, 0xb4, 0x88, 0x65, 0x52, 0xf1, 0xac, 0xca, + 0x39, 0x9e, 0xd5, 0xe2, 0xeb, 0x7c, 0x7c, 0x81, 0x9d, 0x7b, 0xa8, 0xf0, 0x94, 0x6b, 0x2b, 0x3c, + 0x45, 0xb4, 0x9a, 0x4d, 0x2b, 0x4e, 0x40, 0x3f, 0x06, 0x6d, 0xc1, 0x8f, 0x80, 0xb1, 0x5d, 0x58, + 0x2a, 0xb6, 0xb8, 0x0a, 0xb5, 0xea, 0xf6, 0xfc, 0xa6, 0x82, 0xa5, 0x44, 0x7d, 0x3f, 0x3c, 0x57, + 0x7d, 0x09, 0xaa, 0xfc, 0x42, 0xef, 0xb8, 0xd3, 0x18, 0x0c, 0x0d, 0xac, 0xfd, 0x80, 0xc6, 0x3b, + 0x82, 0xd4, 0x78, 0x6c, 0x74, 0x87, 0x5a, 0x0a, 0x6d, 0xc1, 0xa6, 0xa0, 0x18, 0xdf, 0x18, 0xcd, + 0xd1, 0xb0, 0x87, 0xb5, 0xb4, 0xfe, 0xd3, 0x3c, 0xe4, 0xb9, 0x29, 0x91, 0x0e, 0xb7, 0xb0, 0xd1, + 0x18, 0xf4, 0xba, 0x63, 0x71, 0x07, 0x33, 0xc4, 0x8d, 0x0f, 0x1a, 0xed, 0x43, 0xa3, 0xa5, 0xfd, + 0x20, 0x86, 0xe9, 0x0e, 0x1b, 0xed, 0xae, 0x81, 0xc7, 0x22, 0xac, 0x12, 0x98, 0x2b, 0xe8, 0x5d, + 0xb8, 0xbe, 0x8c, 0x69, 0x77, 0xda, 0xc3, 0xc6, 0xb0, 0xdd, 0xeb, 0x6a, 0x5b, 0xe8, 0x03, 0xd8, + 0x3e, 0x03, 0x30, 0x6e, 0xb5, 0x07, 0x4f, 0xb5, 0xcb, 0xe8, 0x43, 0xd0, 0xcf, 0x42, 0x75, 0x8c, + 0x4e, 0x0f, 0x7f, 0xab, 0x15, 0xd1, 0x2d, 0xa8, 0x2f, 0xe1, 0xfa, 0xd8, 0x30, 0x3a, 0xfd, 0xa1, + 0xd1, 0xd2, 0x2e, 0xad, 0x14, 0x79, 0xd4, 0x6f, 0x35, 0x86, 0x86, 0x14, 0xf9, 0x2a, 0xda, 0x81, + 0x0f, 0x04, 0x26, 0xac, 0x32, 0x36, 0x1e, 0xb7, 0x07, 0x43, 0xcc, 0x3f, 0x36, 0x6c, 0x77, 0x8c, + 0xde, 0x68, 0xa8, 0xbd, 0x83, 0xee, 0xc0, 0x87, 0xcb, 0xc8, 0x95, 0xd8, 0x9a, 0x22, 0x59, 0x88, + 0x1d, 0x1a, 0xb8, 0xd3, 0xee, 0x36, 0xa8, 0x64, 0x29, 0xb4, 0x0d, 0x37, 0x92, 0xf9, 0x34, 0x06, + 0xa5, 0x65, 0x19, 0xd8, 0x68, 0x69, 0x69, 0x74, 0x03, 0x6a, 0x02, 0x71, 0x80, 0x1b, 0x1d, 0xe3, + 0x79, 0x0f, 0x3f, 0x1d, 0x63, 0xa3, 0xd3, 0x7b, 0x66, 0xb4, 0xb4, 0x0c, 0x35, 0xa8, 0xc8, 0x7d, + 0xdc, 0x1c, 0x1b, 0x18, 0xf7, 0xb0, 0x96, 0x55, 0x3e, 0xda, 0xee, 0x3e, 0x6b, 0x1c, 0xb6, 0x5b, + 0x11, 0x6b, 0xbb, 0xa5, 0xe5, 0xd0, 0x35, 0xb8, 0x92, 0xc8, 0xef, 0x1d, 0x1c, 0x18, 0x78, 0xa0, + 0xe5, 0x15, 0x56, 0xee, 0x45, 0xd4, 0x12, 0xcd, 0x5e, 0xb7, 0x6b, 0x34, 0xa9, 0xbc, 0x05, 0x85, + 0x15, 0x1b, 0xcd, 0x5e, 0xb7, 0xd9, 0x3e, 0x6c, 0x73, 0x93, 0x96, 0x14, 0x41, 0xc3, 0xab, 0xe5, + 0x63, 0x19, 0x87, 0x23, 0x74, 0x13, 0xae, 0x89, 0x5c, 0xe6, 0x8b, 0xf1, 0x72, 0x01, 0xd5, 0xe0, + 0x72, 0x2c, 0x5b, 0xd6, 0xb0, 0x8c, 0xea, 0x70, 0x35, 0x91, 0x33, 0x18, 0x36, 0x30, 0xe5, 0xaa, + 0x2c, 0x71, 0xc9, 0xcf, 0x55, 0x95, 0xcf, 0xb1, 0x9b, 0xf1, 0x2c, 0xde, 0x97, 0xb5, 0xd5, 0xae, + 0x29, 0x0e, 0xa1, 0x64, 0x8f, 0xba, 0x8d, 0xd1, 0xf0, 0x49, 0x0f, 0xb7, 0xff, 0xb8, 0xd1, 0xd2, + 0xea, 0xfc, 0xba, 0x7d, 0x84, 0x91, 0xcc, 0x1b, 0x4a, 0x45, 0x59, 0x46, 0x8c, 0x6d, 0x33, 0xc9, + 0x26, 0x45, 0xd2, 0xf4, 0xfb, 0x50, 0x38, 0xb0, 0xa7, 0x01, 0x61, 0xfb, 0x8f, 0x1b, 0x1e, 0x39, + 0x5a, 0xf8, 0x64, 0x1c, 0xbd, 0x28, 0xc2, 0x9e, 0x57, 0x78, 0x80, 0xab, 0x3c, 0x43, 0xdc, 0x41, + 0xd7, 0x7f, 0x3e, 0x05, 0x65, 0xe5, 0x26, 0x31, 0xfa, 0x11, 0x94, 0x4e, 0x4d, 0xcf, 0xa6, 0xed, + 0x5f, 0xc6, 0x43, 0xb7, 0x56, 0xde, 0x39, 0xde, 0x7d, 0x26, 0x60, 0x38, 0x62, 0xa8, 0x7f, 0x0e, + 0x45, 0x49, 0x5e, 0x19, 0x22, 0x85, 0x37, 0xc3, 0xd2, 0xea, 0xcd, 0xb0, 0xfb, 0x50, 0x0a, 0xdf, + 0x05, 0x41, 0x1a, 0x64, 0x5e, 0x92, 0x37, 0x82, 0x8b, 0xfe, 0x5d, 0xc3, 0xf4, 0xc7, 0x00, 0x42, + 0x26, 0x1f, 0xdd, 0x83, 0xd2, 0x5c, 0xa6, 0x84, 0xd8, 0x2b, 0x5f, 0x1d, 0x89, 0x50, 0xfa, 0x3e, + 0x40, 0xd3, 0x23, 0x13, 0xe2, 0x04, 0xb6, 0x39, 0x4d, 0xde, 0xc1, 0x49, 0xc7, 0xef, 0xe0, 0x5c, + 0x85, 0xbc, 0x4f, 0x2c, 0x8f, 0x04, 0xe2, 0xe6, 0x89, 0x48, 0xe9, 0x06, 0x94, 0xa3, 0x32, 0x7c, + 0xf4, 0x05, 0x94, 0xad, 0x28, 0x29, 0xe4, 0x50, 0x86, 0x97, 0x08, 0x8b, 0x55, 0xa0, 0xfe, 0x1c, + 0x4a, 0xd8, 0x0c, 0x08, 0x3f, 0x6c, 0xa5, 0x41, 0xe6, 0xbb, 0xb9, 0x30, 0x18, 0xa6, 0x7f, 0x93, + 0x57, 0x5f, 0x12, 0xb2, 0xd5, 0xa1, 0x68, 0x99, 0x73, 0xd3, 0x92, 0x2f, 0x82, 0x64, 0x71, 0x98, + 0xd6, 0x7f, 0x2b, 0x05, 0x10, 0x96, 0xec, 0xa3, 0x1f, 0x42, 0x5e, 0x5c, 0xba, 0x58, 0x52, 0x51, + 0x88, 0xc2, 0x02, 0x82, 0xf6, 0xe0, 0x8a, 0x79, 0x7c, 0xec, 0x91, 0x63, 0x1a, 0x2c, 0x4d, 0xf8, + 0x75, 0x86, 0x31, 0x95, 0x8c, 0x9f, 0x3b, 0xdb, 0x0a, 0x33, 0xc5, 0x55, 0x87, 0x9f, 0x9b, 0xfb, + 0xe8, 0x47, 0x50, 0x5f, 0xe6, 0x49, 0x48, 0x57, 0x4b, 0x32, 0x36, 0xa5, 0xb4, 0xbf, 0x97, 0x86, + 0x5c, 0x7b, 0x46, 0x63, 0x8a, 0xb5, 0xf7, 0x38, 0x59, 0xb6, 0xba, 0x66, 0xb5, 0x03, 0x59, 0x73, + 0x3e, 0xb7, 0xc4, 0xc4, 0x77, 0x09, 0xd9, 0x98, 0xcf, 0x2d, 0xcc, 0x10, 0x68, 0x17, 0xf2, 0x13, + 0xd7, 0x7a, 0x49, 0x56, 0x5c, 0x82, 0xe3, 0xd8, 0x16, 0xcb, 0xc5, 0x02, 0x85, 0x6e, 0x40, 0x9e, + 0x6d, 0x73, 0xf0, 0x20, 0x5b, 0xde, 0x51, 0x17, 0xb4, 0xfa, 0x10, 0xb2, 0xb4, 0xec, 0x95, 0x5e, + 0xbe, 0x21, 0x76, 0xa1, 0x53, 0xe2, 0xd6, 0x4c, 0x34, 0xe4, 0x67, 0xce, 0xb9, 0xc1, 0x85, 0x21, + 0xcf, 0xa5, 0x58, 0x59, 0xee, 0xe7, 0x00, 0x91, 0xd7, 0x2c, 0xd7, 0x58, 0xf1, 0x2e, 0x05, 0xa7, + 0xdf, 0x88, 0x2e, 0x07, 0x35, 0xfa, 0xfd, 0x26, 0xbf, 0xc7, 0xdc, 0xea, 0x35, 0x9f, 0x1a, 0x74, + 0x6c, 0xfe, 0xfd, 0x1c, 0xe4, 0xf9, 0x25, 0x2e, 0xf4, 0xb1, 0x78, 0x90, 0x26, 0xc3, 0x94, 0x7e, + 0x25, 0x79, 0xc9, 0x4b, 0x7d, 0x8b, 0xe6, 0x36, 0x6c, 0x44, 0xa1, 0x09, 0xbb, 0x30, 0xc5, 0xe5, + 0xac, 0x86, 0x54, 0x76, 0x91, 0xe9, 0x3a, 0x94, 0x4e, 0x5c, 0x3f, 0x18, 0x2b, 0x0f, 0x3b, 0xb0, + 0x25, 0x5b, 0x96, 0x79, 0x1b, 0x72, 0xf6, 0x4c, 0xc6, 0x93, 0xe5, 0xbd, 0xcd, 0x84, 0x39, 0x30, + 0xcf, 0x45, 0x9f, 0x85, 0xe1, 0x65, 0x2e, 0x19, 0x25, 0x0b, 0xb9, 0x12, 0xf7, 0xc8, 0x7e, 0x2d, + 0x1b, 0x86, 0x2c, 0x77, 0x63, 0x8b, 0xa0, 0x37, 0xd6, 0x70, 0xaa, 0xee, 0xd4, 0x86, 0x2a, 0x37, + 0xff, 0x38, 0x76, 0xe3, 0xed, 0x83, 0x75, 0xac, 0xdc, 0x5a, 0xe2, 0x16, 0x5c, 0x65, 0xa2, 0xa4, + 0xd0, 0x01, 0x54, 0x7c, 0xd3, 0x99, 0xbc, 0x70, 0x5f, 0x8f, 0xc3, 0x07, 0x92, 0x62, 0xeb, 0x91, + 0xf1, 0x92, 0x06, 0x1c, 0xcb, 0xae, 0x93, 0x95, 0xfd, 0x28, 0x51, 0x7f, 0x05, 0x15, 0xf5, 0x2b, + 0xb4, 0x2f, 0x9a, 0x78, 0xf6, 0x29, 0xeb, 0xe7, 0x58, 0x5f, 0xc4, 0x53, 0x2b, 0xdf, 0xe3, 0x79, + 0x04, 0x1b, 0x3c, 0x77, 0xec, 0xce, 0xf9, 0xfe, 0x6f, 0x26, 0xe9, 0x35, 0x51, 0x27, 0x8a, 0xab, + 0x1c, 0xdb, 0xe3, 0xd0, 0xfa, 0xaf, 0xa4, 0xa0, 0xac, 0x48, 0x85, 0x7e, 0x14, 0xd3, 0xe6, 0xce, + 0x05, 0x2a, 0xa2, 0x6a, 0x36, 0x7a, 0xdf, 0x23, 0x2d, 0xdf, 0xf7, 0xd0, 0x3f, 0x5e, 0xb5, 0xa0, + 0x56, 0x84, 0xec, 0xc0, 0x38, 0x3c, 0xe0, 0x7e, 0xda, 0x6f, 0x60, 0x1a, 0x58, 0xa6, 0xf5, 0xaf, + 0x56, 0x41, 0x2f, 0x41, 0x95, 0x3b, 0xf2, 0xf8, 0x59, 0xef, 0x70, 0xd4, 0x31, 0xf8, 0x12, 0xdc, + 0xa0, 0xd1, 0x6d, 0xed, 0xf7, 0xbe, 0x19, 0xb3, 0xab, 0x70, 0x69, 0xfd, 0x6a, 0xf4, 0xea, 0x11, + 0x7e, 0xae, 0xa5, 0xd8, 0x6f, 0x4f, 0x4b, 0xeb, 0xff, 0x2a, 0x03, 0xe5, 0x2e, 0x09, 0xc2, 0x37, + 0x8e, 0xf6, 0xa1, 0x62, 0xcf, 0xc7, 0xe2, 0x86, 0x7c, 0xb8, 0x49, 0xf0, 0x6e, 0x54, 0x4d, 0x05, + 0xbc, 0xdb, 0xee, 0xcb, 0x3b, 0xf5, 0x65, 0x7b, 0xde, 0x90, 0x3c, 0xa1, 0x0d, 0xf2, 0xca, 0xa3, + 0x09, 0x57, 0x21, 0xcf, 0x56, 0x55, 0xf9, 0x71, 0x93, 0x12, 0x16, 0xa9, 0x8b, 0x9f, 0x2b, 0x41, + 0x07, 0x50, 0x9d, 0xbb, 0x5e, 0xc0, 0x8e, 0x69, 0xda, 0xce, 0xb1, 0x9c, 0x67, 0xbf, 0xb7, 0x5a, + 0xb4, 0xbe, 0xeb, 0x05, 0x1d, 0x8e, 0xc4, 0x95, 0x79, 0x94, 0xf0, 0xeb, 0x47, 0x50, 0x0a, 0xe5, + 0x46, 0x0f, 0xa1, 0xc8, 0x5e, 0x70, 0xb3, 0xdc, 0xe9, 0xf2, 0x26, 0x41, 0xac, 0x3c, 0x81, 0xc2, + 0x21, 0x9e, 0x6d, 0x0a, 0x86, 0xaa, 0x92, 0x97, 0x31, 0x43, 0x3d, 0xd4, 0x67, 0x50, 0x56, 0x84, + 0x88, 0x7a, 0x81, 0xe8, 0x79, 0x16, 0xde, 0x0b, 0xb8, 0x5e, 0x90, 0xe8, 0x49, 0x28, 0x82, 0x3f, + 0x9a, 0xa0, 0xf4, 0x24, 0x14, 0x56, 0x57, 0xa4, 0xe5, 0x4f, 0x97, 0x84, 0x69, 0xfd, 0x16, 0x14, + 0xa5, 0x8c, 0xd4, 0x79, 0xda, 0xfd, 0xd3, 0xcf, 0xf9, 0xcb, 0x2e, 0xed, 0xfe, 0xe9, 0x17, 0x5a, + 0x5a, 0xff, 0x97, 0x39, 0xd8, 0x88, 0x9e, 0x41, 0x62, 0xb6, 0x7e, 0x9c, 0x78, 0xbd, 0x89, 0x0e, + 0x87, 0x1b, 0x6a, 0xdb, 0x8c, 0xe3, 0xd7, 0x3e, 0xdf, 0xa4, 0xff, 0x62, 0x2e, 0xf6, 0x28, 0x53, + 0x62, 0x65, 0x38, 0xd7, 0x7c, 0x42, 0xff, 0xfe, 0x76, 0x01, 0x5d, 0x82, 0x4a, 0xab, 0xd1, 0x1c, + 0xf7, 0x9e, 0x19, 0x18, 0xb7, 0x5b, 0x86, 0xf6, 0x3b, 0x05, 0x74, 0x19, 0x36, 0x29, 0x09, 0x1b, + 0x8d, 0xd6, 0x78, 0x60, 0x34, 0x70, 0xf3, 0x89, 0xf6, 0xaf, 0x0b, 0xa8, 0x0c, 0xf9, 0x83, 0xde, + 0xf3, 0xae, 0x81, 0xb5, 0x7f, 0xc3, 0x13, 0x03, 0x63, 0xd8, 0x6e, 0x69, 0xff, 0xb6, 0x80, 0x4a, + 0x90, 0x7d, 0xda, 0x3e, 0x3c, 0xd4, 0xfe, 0x1d, 0xa3, 0x0f, 0x8c, 0xe1, 0xe3, 0x76, 0x4b, 0xfb, + 0x5d, 0x99, 0x18, 0xb5, 0x5b, 0xda, 0xbf, 0x2f, 0xa0, 0x0a, 0x14, 0x06, 0xc6, 0xb0, 0xdf, 0x6c, + 0xf4, 0xb5, 0xff, 0xc0, 0x3e, 0x71, 0xd8, 0xee, 0x8e, 0xbe, 0x19, 0xb7, 0x3b, 0x9d, 0xd1, 0xb0, + 0xb1, 0x7f, 0x68, 0x68, 0xbf, 0x57, 0x40, 0x57, 0x40, 0xeb, 0x1a, 0xc3, 0xf1, 0x7e, 0xbb, 0x4b, + 0x3f, 0x8c, 0x9f, 0xb5, 0x9b, 0x86, 0xf6, 0x1f, 0x0b, 0x08, 0x41, 0x95, 0x91, 0x71, 0xaf, 0xd1, + 0x6a, 0x36, 0x06, 0x43, 0xed, 0x3f, 0x15, 0xd0, 0x06, 0x94, 0x28, 0xad, 0xd1, 0xea, 0xb4, 0xbb, + 0xda, 0x7f, 0x66, 0xc5, 0xd3, 0x34, 0x6e, 0x3c, 0xd7, 0xfe, 0x4b, 0x01, 0x55, 0xa1, 0xd8, 0xee, + 0x37, 0xc7, 0x87, 0xbd, 0xe6, 0x53, 0xed, 0xbf, 0x32, 0x30, 0x4d, 0x72, 0xe9, 0x7f, 0xbf, 0x80, + 0x36, 0x01, 0x06, 0xdf, 0x0e, 0xc6, 0x9d, 0x5e, 0x6b, 0x74, 0x68, 0x68, 0xff, 0x8d, 0x01, 0x28, + 0x01, 0x37, 0x9e, 0xb7, 0x7b, 0xda, 0x7f, 0x0f, 0x01, 0xcd, 0x27, 0xb8, 0xd7, 0x1b, 0x6a, 0x7f, + 0x10, 0x12, 0xfa, 0x43, 0xdc, 0x68, 0x1a, 0xda, 0x1f, 0x86, 0x1c, 0xfd, 0x46, 0xb3, 0x39, 0xd4, + 0xfe, 0x47, 0x98, 0xe6, 0xf2, 0xfc, 0x4f, 0x26, 0x01, 0x4d, 0xef, 0x53, 0xfe, 0xff, 0x15, 0x26, + 0xbb, 0xb4, 0x46, 0xff, 0x9b, 0x29, 0x9d, 0x7d, 0x4f, 0xcc, 0x16, 0xb4, 0x3f, 0x5d, 0x94, 0x08, + 0x3a, 0x7f, 0xd2, 0x7e, 0xbe, 0x88, 0xb6, 0x60, 0x83, 0x25, 0x87, 0xdf, 0xd2, 0x89, 0xdb, 0x41, + 0xfb, 0xb1, 0xf6, 0x0b, 0x45, 0x6a, 0xb7, 0xce, 0xd3, 0x6e, 0xaf, 0xa5, 0xfd, 0x22, 0xfb, 0x7f, + 0x68, 0x34, 0x06, 0x86, 0xf6, 0x4b, 0x45, 0xa4, 0x41, 0xb9, 0x31, 0x6a, 0xb5, 0x87, 0xe3, 0xe7, + 0xb8, 0x3d, 0x34, 0xb4, 0x5f, 0x2e, 0x52, 0x95, 0x71, 0x0a, 0x9d, 0xf5, 0xe1, 0xde, 0xa1, 0xf6, + 0x67, 0x8a, 0xc2, 0x02, 0x07, 0xd4, 0x02, 0x7f, 0xb6, 0x48, 0x45, 0xe8, 0xa8, 0x76, 0xff, 0x73, + 0x45, 0x5a, 0x07, 0x4a, 0xe2, 0x75, 0xf8, 0xf3, 0x45, 0x66, 0xbf, 0x6f, 0x07, 0x87, 0xbd, 0xc7, + 0xda, 0xaf, 0x14, 0xa9, 0x06, 0x9e, 0x37, 0x9e, 0x1a, 0xe3, 0xc6, 0x61, 0x03, 0x77, 0xb4, 0xbf, + 0xc0, 0x3e, 0xb1, 0x4f, 0x15, 0x3c, 0x1e, 0x8c, 0x06, 0x7d, 0xa3, 0xdb, 0xd2, 0x7e, 0x95, 0x81, + 0xf8, 0x67, 0xa9, 0xef, 0x68, 0xbf, 0x56, 0xd4, 0xbb, 0x50, 0x3a, 0xb4, 0x9d, 0xc5, 0x6b, 0xe6, + 0xdb, 0x0d, 0xd8, 0x0c, 0x5d, 0xf4, 0x8d, 0x3c, 0x46, 0x98, 0xd8, 0x4a, 0x8c, 0xbb, 0x37, 0xde, + 0xb0, 0x62, 0x69, 0xfd, 0x9f, 0x17, 0xa0, 0x1a, 0x5b, 0x82, 0x52, 0x46, 0xd2, 0x74, 0x7c, 0x24, + 0x8d, 0xc1, 0xd4, 0xfe, 0xfe, 0x4e, 0xb4, 0xb5, 0xc2, 0xb7, 0x9c, 0x97, 0x6f, 0x8d, 0x4b, 0x40, + 0x62, 0x67, 0x37, 0xfe, 0xe2, 0xc9, 0xc3, 0x44, 0xd8, 0xa6, 0xaf, 0xfb, 0x36, 0x1f, 0x24, 0xf9, + 0x5d, 0x7b, 0x11, 0xc2, 0x7d, 0x09, 0x39, 0x06, 0x16, 0xa1, 0xc3, 0x7b, 0xeb, 0x58, 0x3b, 0x94, + 0xcc, 0xd7, 0x79, 0x19, 0x02, 0x3d, 0x64, 0xa7, 0x8e, 0xf9, 0xea, 0x2c, 0xdb, 0x87, 0x2b, 0x24, + 0x5f, 0xc6, 0x50, 0x7a, 0x48, 0x76, 0xce, 0x58, 0x26, 0x68, 0xdc, 0x0c, 0x53, 0x6a, 0x0c, 0xae, + 0xfa, 0x62, 0xf2, 0x4d, 0x84, 0xd0, 0x50, 0xb8, 0x34, 0x95, 0x7f, 0xeb, 0x7f, 0x25, 0x0b, 0x10, + 0xc9, 0x4f, 0x67, 0x3c, 0x3c, 0x34, 0x12, 0x0f, 0x68, 0xf0, 0x48, 0xe8, 0x67, 0xa1, 0x20, 0x3e, + 0x24, 0xde, 0x0c, 0xbc, 0x73, 0xbe, 0x2a, 0xa4, 0x9c, 0x0f, 0xb3, 0x4f, 0x7a, 0x83, 0x21, 0x96, + 0x05, 0xa0, 0x41, 0x72, 0x48, 0xe1, 0x47, 0x21, 0x77, 0x2f, 0x50, 0xe2, 0xda, 0xf1, 0x05, 0xdd, + 0x06, 0x98, 0x7b, 0xf6, 0xa9, 0x3d, 0x25, 0xc7, 0x61, 0xd4, 0x2c, 0x1f, 0xea, 0x8b, 0x32, 0xd0, + 0x7d, 0x80, 0x70, 0x16, 0xb6, 0xe2, 0x19, 0x98, 0x68, 0xb2, 0xa6, 0xc0, 0xd0, 0x0e, 0x68, 0x47, + 0xae, 0x67, 0x91, 0xf1, 0x7c, 0x31, 0x9d, 0x8e, 0xb9, 0x76, 0xd8, 0xfb, 0x56, 0x78, 0x83, 0xd1, + 0xfb, 0x8b, 0xe9, 0x94, 0xcf, 0x1d, 0x3e, 0x82, 0x2a, 0xf7, 0xab, 0xb1, 0x08, 0x93, 0x0a, 0xe1, + 0x5b, 0x45, 0x15, 0x9e, 0xd1, 0x62, 0xf4, 0xff, 0xdf, 0xc3, 0xd4, 0x7d, 0x28, 0x08, 0x63, 0xb0, + 0x57, 0xc7, 0x7a, 0x03, 0xf1, 0xa4, 0xd0, 0x3e, 0x6e, 0xb7, 0x1e, 0x1b, 0xfc, 0xdd, 0x93, 0x6e, + 0xaf, 0x6b, 0x68, 0x19, 0xfa, 0x6f, 0x34, 0x30, 0xb0, 0x96, 0xad, 0xef, 0x41, 0x29, 0x74, 0xce, + 0x28, 0x62, 0x4e, 0x9d, 0x15, 0x31, 0xeb, 0x37, 0xa3, 0x87, 0x56, 0x44, 0x98, 0xcf, 0xdf, 0x03, + 0x30, 0x06, 0xbd, 0x81, 0x96, 0xd6, 0xff, 0x5a, 0x0a, 0x36, 0x13, 0xab, 0x86, 0xcb, 0xfe, 0x9e, + 0xba, 0xb8, 0xbf, 0x3f, 0x80, 0xb2, 0xc5, 0x42, 0x1a, 0xee, 0xf0, 0xcb, 0xd3, 0x92, 0xe3, 0x70, + 0xe3, 0x18, 0xac, 0xf0, 0x3f, 0x7a, 0x4f, 0x39, 0x29, 0x31, 0x17, 0x8f, 0x46, 0x56, 0xa3, 0x33, + 0x11, 0x7d, 0x7b, 0xa2, 0x1f, 0x01, 0x44, 0xcc, 0xe8, 0x73, 0xe6, 0xfe, 0x63, 0x6b, 0x2a, 0x6f, + 0x92, 0x5d, 0x5f, 0xf5, 0x0d, 0x2a, 0x68, 0x93, 0xc6, 0x4e, 0x0e, 0xfb, 0xad, 0xeb, 0x90, 0xe7, + 0x14, 0x54, 0x83, 0x82, 0x35, 0x35, 0x7d, 0x5f, 0x1c, 0x99, 0xa9, 0x62, 0x99, 0xd4, 0xef, 0x41, + 0x9e, 0x47, 0x5c, 0xe8, 0xa3, 0x30, 0x26, 0xe3, 0x0a, 0xd8, 0x4c, 0xc4, 0x64, 0xe1, 0x51, 0xdf, + 0xcf, 0x20, 0xc7, 0x08, 0x67, 0x2f, 0x57, 0x44, 0x4f, 0xac, 0xe9, 0x7f, 0x2b, 0x05, 0x59, 0xe6, + 0x22, 0x57, 0x21, 0xef, 0x2c, 0x66, 0x2f, 0xc4, 0x63, 0x9a, 0x55, 0x2c, 0x52, 0x4a, 0xf8, 0xae, + 0xbe, 0xb7, 0xb5, 0xd6, 0x9d, 0xd0, 0x3e, 0xc0, 0xa9, 0xed, 0xdb, 0x62, 0x8f, 0x35, 0xcb, 0x3a, + 0x04, 0x7d, 0xcd, 0xc6, 0xc3, 0xee, 0xb3, 0x10, 0x89, 0x15, 0x2e, 0x25, 0x04, 0xcd, 0x9d, 0x73, + 0xb4, 0xf9, 0x53, 0xc8, 0xf1, 0x3b, 0x8b, 0x1f, 0x40, 0x6e, 0xce, 0xee, 0x32, 0x72, 0x05, 0x6d, + 0x28, 0xed, 0xd6, 0xf5, 0x02, 0xcc, 0x33, 0xf5, 0xbf, 0x97, 0x86, 0x6a, 0x4c, 0x82, 0x84, 0xb8, + 0x7c, 0x18, 0x79, 0x5b, 0x71, 0x57, 0xa9, 0x68, 0x3b, 0xfe, 0x4a, 0x1e, 0xd7, 0x52, 0xe2, 0x39, + 0xbc, 0x22, 0x3b, 0xf0, 0x6e, 0xbb, 0x8e, 0x1c, 0x5c, 0x64, 0x5a, 0x7d, 0x4e, 0x2b, 0x17, 0x7f, + 0x4e, 0xeb, 0xb6, 0xac, 0x67, 0x3e, 0xd9, 0xd6, 0x98, 0x1e, 0x44, 0x45, 0x15, 0x0d, 0x16, 0xce, + 0xd1, 0xe0, 0x17, 0x00, 0x51, 0xb5, 0x50, 0x15, 0x4a, 0xe1, 0x92, 0xa9, 0x78, 0x93, 0xf0, 0x70, + 0xc4, 0x56, 0xd5, 0xd9, 0xb3, 0xac, 0xc6, 0x37, 0x43, 0x03, 0x77, 0x1b, 0x87, 0x6c, 0xe2, 0x03, + 0xcf, 0x89, 0x7d, 0x7c, 0x12, 0xc8, 0x17, 0x15, 0x5f, 0xb1, 0x94, 0x38, 0x4c, 0x2e, 0x52, 0xfc, + 0x55, 0x90, 0x69, 0xa8, 0x1a, 0xfa, 0x5f, 0xff, 0xa7, 0x29, 0x28, 0x3f, 0xe3, 0xd5, 0x61, 0xbc, + 0x4a, 0x65, 0xb9, 0xbb, 0x86, 0x95, 0x65, 0x47, 0xa6, 0xed, 0xe9, 0x64, 0x3c, 0xe1, 0x9b, 0x41, + 0x2c, 0x9e, 0x67, 0x94, 0x96, 0x19, 0x90, 0x28, 0x9b, 0x6d, 0x1e, 0xf0, 0x5b, 0x84, 0x3c, 0x7b, + 0x68, 0xcf, 0x94, 0x6c, 0xb6, 0x33, 0x95, 0x55, 0xb8, 0x47, 0x3e, 0xf1, 0xd0, 0x3b, 0x50, 0x38, + 0xb6, 0x83, 0xb1, 0x7f, 0x62, 0x0a, 0x1d, 0xe7, 0x8f, 0xed, 0x60, 0x70, 0x62, 0x52, 0x3e, 0x9a, + 0xc1, 0x0f, 0xf6, 0x89, 0x29, 0x53, 0xe9, 0xd8, 0x0e, 0xf6, 0x19, 0x41, 0xf2, 0x05, 0xe6, 0xb1, + 0x78, 0xb7, 0x95, 0xf2, 0x0d, 0xcd, 0x63, 0xfd, 0x2e, 0x64, 0x0f, 0xa6, 0xe6, 0xf1, 0x79, 0x0b, + 0x8c, 0x4a, 0xe3, 0xfb, 0xcd, 0x14, 0x64, 0xb1, 0xbb, 0x66, 0x4d, 0x32, 0x52, 0x69, 0x3a, 0xa6, + 0xd2, 0x07, 0x00, 0xe1, 0xc6, 0xab, 0x1c, 0x1f, 0xd7, 0xec, 0xd0, 0x2a, 0xc0, 0xb7, 0x3f, 0x11, + 0xa0, 0xef, 0x41, 0xbe, 0x43, 0x02, 0xcf, 0xb6, 0xce, 0xaf, 0x91, 0x7c, 0xed, 0x4b, 0xff, 0xeb, + 0x29, 0x28, 0x1e, 0xd8, 0xfc, 0x41, 0x97, 0x70, 0x6a, 0x9d, 0x8a, 0xa6, 0xd6, 0x94, 0xcd, 0x99, + 0xda, 0x0e, 0x0f, 0x15, 0x72, 0x98, 0x27, 0x28, 0xd2, 0xb7, 0xff, 0x14, 0x11, 0x2b, 0x71, 0xec, + 0x3f, 0xda, 0x81, 0xdc, 0x8c, 0x19, 0x36, 0xbb, 0x76, 0x57, 0x88, 0x03, 0x28, 0x37, 0x5b, 0x20, + 0x62, 0x6f, 0xa1, 0x8a, 0x95, 0x20, 0x0d, 0x32, 0x0b, 0xf1, 0x3e, 0x5b, 0x09, 0xd3, 0xbf, 0x94, + 0x72, 0x2c, 0xf6, 0xd6, 0x4a, 0x98, 0xfe, 0xbd, 0xf3, 0x27, 0x20, 0x2f, 0xc6, 0x99, 0xab, 0x80, + 0x5a, 0xb8, 0xfd, 0xcc, 0xc0, 0xe3, 0x6e, 0x6f, 0x38, 0x96, 0xeb, 0xec, 0x29, 0x84, 0x60, 0x43, + 0xd0, 0xf1, 0xa8, 0x2b, 0xde, 0x23, 0x8e, 0x68, 0x8d, 0xfd, 0x1e, 0xc3, 0x65, 0x14, 0xda, 0x60, + 0xd8, 0xeb, 0xf7, 0x8d, 0x96, 0x96, 0xbd, 0xf3, 0xab, 0x69, 0x28, 0x85, 0xdb, 0x95, 0x74, 0xfe, + 0xcf, 0x96, 0xc5, 0x07, 0xc3, 0xc6, 0x63, 0x5a, 0x4e, 0x1e, 0x5d, 0x82, 0xaa, 0xa4, 0xe0, 0x21, + 0x25, 0xfd, 0x20, 0x04, 0xc9, 0x8f, 0xa5, 0x42, 0x8a, 0x78, 0xe1, 0x56, 0x2b, 0x86, 0x6c, 0x07, + 0xed, 0x6e, 0x7b, 0xf0, 0x84, 0xed, 0x94, 0x6c, 0x42, 0x99, 0x93, 0xf8, 0x96, 0x4e, 0x26, 0x24, + 0x50, 0x2e, 0x2a, 0x0b, 0xda, 0x00, 0x60, 0x04, 0xbe, 0x51, 0x42, 0x27, 0x24, 0x25, 0x96, 0x3e, + 0xa4, 0xa3, 0x7d, 0x2e, 0xfc, 0x4a, 0x0b, 0x73, 0xe1, 0x4b, 0xe8, 0x32, 0x68, 0x62, 0x15, 0x1f, + 0x1b, 0x8d, 0xe6, 0x13, 0x36, 0x45, 0x83, 0x90, 0xed, 0x31, 0x0d, 0x07, 0xca, 0xe8, 0x1a, 0x5c, + 0x09, 0x93, 0xe3, 0xfd, 0x6f, 0xc7, 0xbd, 0xbe, 0x81, 0x1b, 0xc3, 0x1e, 0xd6, 0x2a, 0x61, 0x89, + 0xe1, 0xc6, 0xc4, 0xfe, 0x4d, 0xd8, 0x72, 0xbd, 0xe3, 0x5d, 0x73, 0x6e, 0x5a, 0x27, 0x24, 0xb4, + 0xe5, 0x7e, 0x9e, 0x3f, 0xeb, 0xf2, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xaf, 0x89, 0xda, 0x1f, + 0xbd, 0x5d, 0x00, 0x00, +} diff --git a/bcs-common/pkg/scheduler/mesosproto/mesos/mesos.proto b/bcs-common/pkg/scheduler/mesosproto/mesos/mesos.proto new file mode 100644 index 0000000000..def33ef5e4 --- /dev/null +++ b/bcs-common/pkg/scheduler/mesosproto/mesos/mesos.proto @@ -0,0 +1,2337 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mesos.v1; + +option java_package = "org.apache.mesos.v1"; +option java_outer_classname = "Protos"; + + +/** + * Status is used to indicate the state of the scheduler and executor + * driver after function calls. + */ +enum Status { + DRIVER_NOT_STARTED = 1; + DRIVER_RUNNING = 2; + DRIVER_ABORTED = 3; + DRIVER_STOPPED = 4; +} + + +/** + * A unique ID assigned to a framework. A framework can reuse this ID + * in order to do failover (see MesosSchedulerDriver). + */ +message FrameworkID { + required string value = 1; +} + + +/** + * A unique ID assigned to an offer. + */ +message OfferID { + required string value = 1; +} + + +/** + * A unique ID assigned to an agent. Currently, an agent gets a new ID + * whenever it (re)registers with Mesos. Framework writers shouldn't + * assume any binding between an agent ID and and a hostname. + */ +message AgentID { + required string value = 1; +} + + +/** + * A framework-generated ID to distinguish a task. The ID must remain + * unique while the task is active. A framework can reuse an ID _only_ + * if the previous task with the same ID has reached a terminal state + * (e.g., TASK_FINISHED, TASK_LOST, TASK_KILLED, etc.). However, + * reusing task IDs is strongly discouraged (MESOS-2198). + */ +message TaskID { + required string value = 1; +} + + +/** + * A framework-generated ID to distinguish an executor. Only one + * executor with the same ID can be active on the same agent at a + * time. However, reusing executor IDs is discouraged. + */ +message ExecutorID { + required string value = 1; +} + + +/** + * ID used to uniquely identify a container. If the `parent` is not + * specified, the ID is a UUID generated by the agent to uniquely + * identify the container of an executor run. If the `parent` field is + * specified, it represents a nested container. + */ +message ContainerID { + required string value = 1; + optional ContainerID parent = 2; +} + + +/** + * Represents time since the epoch, in nanoseconds. + */ +message TimeInfo { + required int64 nanoseconds = 1; + + // TODO(josephw): Add time zone information, if necessary. +} + + +/** + * Represents duration in nanoseconds. + */ +message DurationInfo { + required int64 nanoseconds = 1; +} + + +/** + * A network address. + * + * TODO(bmahler): Use this more widely. + */ +message Address { + // May contain a hostname, IP address, or both. + optional string hostname = 1; + optional string ip = 2; + + required int32 port = 3; +} + + +/** + * Represents a URL. + */ +message URL { + required string scheme = 1; + required Address address = 2; + optional string path = 3; + repeated Parameter query = 4; + optional string fragment = 5; +} + + +/** + * Represents an interval, from a given start time over a given duration. + * This interval pertains to an unavailability event, such as maintenance, + * and is not a generic interval. + */ +message Unavailability { + required TimeInfo start = 1; + + // When added to `start`, this represents the end of the interval. + // If unspecified, the duration is assumed to be infinite. + optional DurationInfo duration = 2; + + // TODO(josephw): Add additional fields for expressing the purpose and + // urgency of the unavailability event. +} + + +/** + * Represents a single machine, which may hold one or more agents. + * + * NOTE: In order to match an agent to a machine, both the `hostname` and + * `ip` must match the values advertised by the agent to the master. + * Hostname is not case-sensitive. + */ +message MachineID { + optional string hostname = 1; + optional string ip = 2; +} + + +/** + * Holds information about a single machine, its `mode`, and any other + * relevant information which may affect the behavior of the machine. + */ +message MachineInfo { + // Describes the several states that a machine can be in. A `Mode` + // applies to a machine and to all associated agents on the machine. + enum Mode { + // In this mode, a machine is behaving normally; + // offering resources, executing tasks, etc. + UP = 1; + + // In this mode, all agents on the machine are expected to cooperate with + // frameworks to drain resources. In general, draining is done ahead of + // a pending `unavailability`. The resources should be drained so as to + // maximize utilization prior to the maintenance but without knowingly + // violating the frameworks' requirements. + DRAINING = 2; + + // In this mode, a machine is not running any tasks and will not offer + // any of its resources. Agents on the machine will not be allowed to + // register with the master. + DOWN = 3; + } + + required MachineID id = 1; + optional Mode mode = 2; + + // Signifies that the machine may be unavailable during the given interval. + // See comments in `Unavailability` and for the `unavailability` fields + // in `Offer` and `InverseOffer` for more information. + optional Unavailability unavailability = 3; +} + + +/** + * Describes a framework. + */ +message FrameworkInfo { + // Used to determine the Unix user that an executor or task should be + // launched as. + // + // When using the MesosSchedulerDriver, if the field is set to an + // empty string, it will automagically set it to the current user. + // + // When using the HTTP Scheduler API, the user has to be set + // explicitly. + required string user = 1; + + // Name of the framework that shows up in the Mesos Web UI. + required string name = 2; + + // Note that 'id' is only available after a framework has + // registered, however, it is included here in order to facilitate + // scheduler failover (i.e., if it is set then the + // MesosSchedulerDriver expects the scheduler is performing + // failover). + optional FrameworkID id = 3; + + // The amount of time (in seconds) that the master will wait for the + // scheduler to failover before it tears down the framework by + // killing all its tasks/executors. This should be non-zero if a + // framework expects to reconnect after a failure and not lose its + // tasks/executors. + // + // NOTE: To avoid accidental destruction of tasks, production + // frameworks typically set this to a large value (e.g., 1 week). + optional double failover_timeout = 4 [default = 0.0]; + + // If set, agents running tasks started by this framework will write + // the framework pid, executor pids and status updates to disk. If + // the agent exits (e.g., due to a crash or as part of upgrading + // Mesos), this checkpointed data allows the restarted agent to + // reconnect to executors that were started by the old instance of + // the agent. Enabling checkpointing improves fault tolerance, at + // the cost of a (usually small) increase in disk I/O. + optional bool checkpoint = 5 [default = false]; + + // Used to group frameworks for allocation decisions, depending on + // the allocation policy being used. + optional string role = 6 [default = "*"]; + + // Used to indicate the current host from which the scheduler is + // registered in the Mesos Web UI. If set to an empty string Mesos + // will automagically set it to the current hostname if one is + // available. + optional string hostname = 7; + + // This field should match the credential's principal the framework + // uses for authentication. This field is used for framework API + // rate limiting and dynamic reservations. It should be set even + // if authentication is not enabled if these features are desired. + optional string principal = 8; + + // This field allows a framework to advertise its web UI, so that + // the Mesos web UI can link to it. It is expected to be a full URL, + // for example http://my-scheduler.example.com:8080/. + optional string webui_url = 9; + + message Capability { + enum Type { + // This must be the first enum value in this list, to + // ensure that if 'type' is not set, the default value + // is UNKNOWN. This enables enum values to be added + // in a backwards-compatible way. See: MESOS-4997. + UNKNOWN = 0; + + // Receive offers with revocable resources. See 'Resource' + // message for details. + REVOCABLE_RESOURCES = 1; + + // Receive the TASK_KILLING TaskState when a task is being + // killed by an executor. The executor will examine this + // capability to determine whether it can send TASK_KILLING. + TASK_KILLING_STATE = 2; + + // Indicates whether the framework is aware of GPU resources. + // Frameworks that are aware of GPU resources are expected to + // avoid placing non-GPU workloads on GPU agents, in order + // to avoid occupying a GPU agent and preventing GPU workloads + // from running! Currently, if a framework is unaware of GPU + // resources, it will not be offered *any* of the resources on + // an agent with GPUs. This restriction is in place because we + // do not have a revocation mechanism that ensures GPU workloads + // can evict GPU agent occupants if necessary. + // + // TODO(bmahler): As we add revocation we can relax the + // restriction here. See MESOS-5634 for more information. + GPU_RESOURCES = 3; + + // Receive offers with resources that are shared. + SHARED_RESOURCES = 4; + + // Indicates that (1) the framework is prepared to handle the + // following TaskStates: TASK_UNREACHABLE, TASK_DROPPED, + // TASK_GONE, TASK_GONE_BY_OPERATOR, and TASK_UNKNOWN, and (2) + // the framework will assume responsibility for managing + // partitioned tasks that reregister with the master. + // + // Frameworks that enable this capability can define how they + // would like to handle partitioned tasks. Frameworks will + // receive TASK_UNREACHABLE for tasks on agents that are + // partitioned from the master. If/when a partitioned agent + // reregisters, tasks on the agent that were started by + // PARTITION_AWARE frameworks will not killed. + // + // Without this capability, frameworks will receive TASK_LOST + // for tasks on partitioned agents; such tasks will be killed by + // Mesos when the agent reregisters (unless the master has + // failed over). + PARTITION_AWARE = 5; + } + + // Enum fields should be optional, see: MESOS-4997. + optional Type type = 1; + } + + // This field allows a framework to advertise its set of + // capabilities (e.g., ability to receive offers for revocable + // resources). + repeated Capability capabilities = 10; + + // Labels are free-form key value pairs supplied by the framework + // scheduler (e.g., to describe additional functionality offered by + // the framework). These labels are not interpreted by Mesos itself. + // Labels should not contain duplicate key-value pairs. + optional Labels labels = 11; +} + + +/** + * Describes a health check for a task or executor (or any arbitrary + * process/command). A type is picked by specifying one of the + * optional fields. Specifying more than one type is an error. + */ +message HealthCheck { + enum Type { + UNKNOWN = 0; + COMMAND = 1; + HTTP = 2; + TCP = 3; + } + + // Describes an HTTP health check. Sends a GET request to + // scheme://:port/path. Note that is not configurable and is + // resolved automatically, in most cases to 127.0.0.1. Default executors + // treat return codes between 200 and 399 as success; custom executors + // may employ a different strategy, e.g. leveraging the `statuses` field. + message HTTPCheckInfo { + // Currently "http" and "https" are supported. + optional string scheme = 3; + + // Port to send the HTTP request. + required uint32 port = 1; + + // HTTP request path. + optional string path = 2; + + // TODO(alexr): Add support for HTTP method. While adding POST + // and PUT is simple, supporting payload is more involved. + + // TODO(alexr): Add support for custom HTTP headers. + + // TODO(alexr): Add support for success and possibly failure + // statuses. + + // NOTE: It is up to the custom executor to interpret and act on this + // field. Setting this field has no effect on the default executors. + // + // TODO(haosdent): Deprecate this field when we add better support for + // success and possibly failure statuses, e.g. ranges of success and + // failure statuses. + repeated uint32 statuses = 4; + + // TODO(haosdent): Consider adding a flag to enable task's certificate + // validation for HTTPS health checks, see MESOS-5997. + + // TODO(benh): Include an 'optional bytes data' field for checking + // for specific data in the response. + } + + // Describes a TCP health check, i.e. based on establishing + // a TCP connection to the specified port. + message TCPCheckInfo { + // Port expected to be open. + required uint32 port = 1; + } + + // TODO(benh): Consider adding a URL health check strategy which + // allows doing something similar to the HTTP strategy but + // encapsulates all the details in a single string field. + + // Amount of time to wait until starting the health checks. + optional double delay_seconds = 2 [default = 15.0]; + + // Interval between health checks. + optional double interval_seconds = 3 [default = 10.0]; + + // Amount of time to wait for the health check to complete. + optional double timeout_seconds = 4 [default = 20.0]; + + // Number of consecutive failures until signaling kill task. + optional uint32 consecutive_failures = 5 [default = 3]; + + // Amount of time to allow failed health checks since launch. + optional double grace_period_seconds = 6 [default = 10.0]; + + // TODO(alexr): Add an optional `KillPolicy` that should be used + // if the task is killed because of a health check failure. + + // The type of health check. + optional Type type = 8; + + // Command health check. + optional CommandInfo command = 7; + + // HTTP health check. + optional HTTPCheckInfo http = 1; + + // TCP health check. + optional TCPCheckInfo tcp = 9; +} + + +/** + * Describes a kill policy for a task. Currently does not express + * different policies (e.g. hitting HTTP endpoints), only controls + * how long to wait between graceful and forcible task kill: + * + * graceful kill --------------> forcible kill + * grace_period + * + * Kill policies are best-effort, because machine failures / forcible + * terminations may occur. + * + * NOTE: For executor-less command-based tasks, the kill is performed + * via sending a signal to the task process: SIGTERM for the graceful + * kill and SIGKILL for the forcible kill. For the docker executor-less + * tasks the grace period is passed to 'docker stop --time'. + */ +message KillPolicy { + // The grace period specifies how long to wait before forcibly + // killing the task. It is recommended to attempt to gracefully + // kill the task (and send TASK_KILLING) to indicate that the + // graceful kill is in progress. Once the grace period elapses, + // if the task has not terminated, a forcible kill should occur. + // The task should not assume that it will always be allotted + // the full grace period. For example, the executor may be + // shutdown more quickly by the agent, or failures / forcible + // terminations may occur. + optional DurationInfo grace_period = 1; +} + + +/** + * Describes a command, executed via: '/bin/sh -c value'. Any URIs specified + * are fetched before executing the command. If the executable field for an + * uri is set, executable file permission is set on the downloaded file. + * Otherwise, if the downloaded file has a recognized archive extension + * (currently [compressed] tar and zip) it is extracted into the executor's + * working directory. This extraction can be disabled by setting `extract` to + * false. In addition, any environment variables are set before executing + * the command (so they can be used to "parameterize" your command). + */ +message CommandInfo { + message URI { + required string value = 1; + optional bool executable = 2; + + // In case the fetched file is recognized as an archive, extract + // its contents into the sandbox. Note that a cached archive is + // not copied from the cache to the sandbox in case extraction + // originates from an archive in the cache. + optional bool extract = 3 [default = true]; + + // If this field is "true", the fetcher cache will be used. If not, + // fetching bypasses the cache and downloads directly into the + // sandbox directory, no matter whether a suitable cache file is + // available or not. The former directs the fetcher to download to + // the file cache, then copy from there to the sandbox. Subsequent + // fetch attempts with the same URI will omit downloading and copy + // from the cache as long as the file is resident there. Cache files + // may get evicted at any time, which then leads to renewed + // downloading. See also "docs/fetcher.md" and + // "docs/fetcher-cache-internals.md". + optional bool cache = 4; + + // The fetcher's default behavior is to use the URI string's basename to + // name the local copy. If this field is provided, the local copy will be + // named with its value instead. If there is a directory component (which + // must be a relative path), the local copy will be stored in that + // subdirectory inside the sandbox. + optional string output_file = 5; + } + + repeated URI uris = 1; + + optional Environment environment = 2; + + // There are two ways to specify the command: + // 1) If 'shell == true', the command will be launched via shell + // (i.e., /bin/sh -c 'value'). The 'value' specified will be + // treated as the shell command. The 'arguments' will be ignored. + // 2) If 'shell == false', the command will be launched by passing + // arguments to an executable. The 'value' specified will be + // treated as the filename of the executable. The 'arguments' + // will be treated as the arguments to the executable. This is + // similar to how POSIX exec families launch processes (i.e., + // execlp(value, arguments(0), arguments(1), ...)). + // NOTE: The field 'value' is changed from 'required' to 'optional' + // in 0.20.0. It will only cause issues if a new framework is + // connecting to an old master. + optional bool shell = 6 [default = true]; + optional string value = 3; + repeated string arguments = 7; + + // Enables executor and tasks to run as a specific user. If the user + // field is present both in FrameworkInfo and here, the CommandInfo + // user value takes precedence. + optional string user = 5; +} + + +/** + * Describes information about an executor. + */ +message ExecutorInfo { + enum Type { + UNKNOWN = 0; + + // Mesos provides a simple built-in default executor that frameworks can + // leverage to run shell commands and containers. + // + // NOTES: + // + // 1) `command` must not be set when using a default executor. + // + // 2) Default executor only accepts a *single* `LAUNCH` or `LAUNCH_GROUP` + // offer operation. + DEFAULT = 1; + + // For frameworks that need custom functionality to run tasks, a `CUSTOM` + // executor can be used. Note that `command` must be set when using a + // `CUSTOM` executor. + CUSTOM = 2; + } + + // For backwards compatibility, if this field is not set when using `LAUNCH` + // offer operation, Mesos will infer the type by checking if `command` is + // set (`CUSTOM`) or unset (`DEFAULT`). `type` must be set when using + // `LAUNCH_GROUP` offer operation. + // + // TODO(vinod): Add support for explicitly setting `type` to `DEFAULT ` + // in `LAUNCH` offer operation. + optional Type type = 15; + + required ExecutorID executor_id = 1; + optional FrameworkID framework_id = 8; // TODO(benh): Make this required. + optional CommandInfo command = 7; + + // Executor provided with a container will launch the container + // with the executor's CommandInfo and we expect the container to + // act as a Mesos executor. + optional ContainerInfo container = 11; + + repeated Resource resources = 5; + optional string name = 9; + + // 'source' is an identifier style string used by frameworks to + // track the source of an executor. This is useful when it's + // possible for different executor ids to be related semantically. + // + // NOTE: 'source' is exposed alongside the resource usage of the + // executor via JSON on the agent. This allows users to import usage + // information into a time series database for monitoring. + // + // This field is deprecated since 1.0. Please use labels for + // free-form metadata instead. + optional string source = 10 [deprecated = true]; // Since 1.0. + + // This field can be used to pass arbitrary bytes to an executor. + optional bytes data = 4; + + // Service discovery information for the executor. It is not + // interpreted or acted upon by Mesos. It is up to a service + // discovery system to use this information as needed and to handle + // executors without service discovery information. + optional DiscoveryInfo discovery = 12; + + // When shutting down an executor the agent will wait in a + // best-effort manner for the grace period specified here + // before forcibly destroying the container. The executor + // must not assume that it will always be allotted the full + // grace period, as the agent may decide to allot a shorter + // period and failures / forcible terminations may occur. + optional DurationInfo shutdown_grace_period = 13; + + // Labels are free-form key value pairs which are exposed through + // master and agent endpoints. Labels will not be interpreted or + // acted upon by Mesos itself. As opposed to the data field, labels + // will be kept in memory on master and agent processes. Therefore, + // labels should be used to tag executors with lightweight metadata. + // Labels should not contain duplicate key-value pairs. + optional Labels labels = 14; +} + + +/** + * Describes a master. This will probably have more fields in the + * future which might be used, for example, to link a framework webui + * to a master webui. + */ +message MasterInfo { + required string id = 1; + + // The IP address (only IPv4) as a packed 4-bytes integer, + // stored in network order. Deprecated, use `address.ip` instead. + required uint32 ip = 2; + + // The TCP port the Master is listening on for incoming + // HTTP requests; deprecated, use `address.port` instead. + required uint32 port = 3 [default = 5050]; + + // In the default implementation, this will contain information + // about both the IP address, port and Master name; it should really + // not be relied upon by external tooling/frameworks and be + // considered an "internal" implementation field. + optional string pid = 4; + + // The server's hostname, if available; it may be unreliable + // in environments where the DNS configuration does not resolve + // internal hostnames (eg, some public cloud providers). + // Deprecated, use `address.hostname` instead. + optional string hostname = 5; + + // The running Master version, as a string; taken from the + // generated "master/version.hpp". + optional string version = 6; + + // The full IP address (supports both IPv4 and IPv6 formats) + // and supersedes the use of `ip`, `port` and `hostname`. + // Since Mesos 0.24. + optional Address address = 7; +} + + +/** + * Describes an agent. Note that the 'id' field is only available + * after an agent is registered with the master, and is made available + * here to facilitate re-registration. + */ +message AgentInfo { + required string hostname = 1; + optional int32 port = 8 [default = 5051]; + repeated Resource resources = 3; + repeated Attribute attributes = 5; + optional AgentID id = 6; +} + + +/** + * Describes an Attribute or Resource "value". A value is described + * using the standard protocol buffer "union" trick. + */ +message Value { + enum Type { + SCALAR = 0; + RANGES = 1; + SET = 2; + TEXT = 3; + } + + message Scalar { + // Scalar values are represented using floating point. To reduce + // the chance of unpredictable floating point behavior due to + // roundoff error, Mesos only supports three decimal digits of + // precision for scalar resource values. That is, floating point + // values are converted to a fixed point format that supports + // three decimal digits of precision, and then converted back to + // floating point on output. Any additional precision in scalar + // resource values is discarded (via rounding). + required double value = 1; + } + + message Range { + required uint64 begin = 1; + required uint64 end = 2; + } + + message Ranges { + repeated Range range = 1; + } + + message Set { + repeated string item = 1; + } + + message Text { + required string value = 1; + } + + required Type type = 1; + optional Scalar scalar = 2; + optional Ranges ranges = 3; + optional Set set = 4; + optional Text text = 5; +} + + +/** + * Describes an attribute that can be set on a machine. For now, + * attributes and resources share the same "value" type, but this may + * change in the future and attributes may only be string based. + */ +message Attribute { + required string name = 1; + required Value.Type type = 2; + optional Value.Scalar scalar = 3; + optional Value.Ranges ranges = 4; + optional Value.Set set = 6; + optional Value.Text text = 5; +} + + +/** + * Describes a resource on a machine. The `name` field is a string + * like "cpus" or "mem" that indicates which kind of resource this is; + * the rest of the fields describe the properties of the resource. A + * resource can take on one of three types: scalar (double), a list of + * finite and discrete ranges (e.g., [1-10, 20-30]), or a set of + * items. A resource is described using the standard protocol buffer + * "union" trick. + * + * Note that "disk" and "mem" resources are scalar values expressed in + * megabytes. Fractional "cpus" values are allowed (e.g., "0.5"), + * which correspond to partial shares of a CPU. + */ +message Resource { + required string name = 1; + required Value.Type type = 2; + optional Value.Scalar scalar = 3; + optional Value.Ranges ranges = 4; + optional Value.Set set = 5; + + // The role that this resource is reserved for. If "*", this indicates + // that the resource is unreserved. Otherwise, the resource will only + // be offered to frameworks that belong to this role. + optional string role = 6 [default = "*"]; + + message ReservationInfo { + // Describes a dynamic reservation. A dynamic reservation is + // acquired by an operator via the '/reserve' HTTP endpoint or by + // a framework via the offer cycle by sending back an + // 'Offer::Operation::Reserve' message. + // NOTE: We currently do not allow frameworks with role "*" to + // make dynamic reservations. + + // Indicates the principal, if any, of the framework or operator + // that reserved this resource. If reserved by a framework, the + // field should match the `FrameworkInfo.principal`. It is used in + // conjunction with the `UnreserveResources` ACL to determine + // whether the entity attempting to unreserve this resource is + // permitted to do so. + optional string principal = 1; + + // Labels are free-form key value pairs that can be used to + // associate arbitrary metadata with a reserved resource. For + // example, frameworks can use labels to identify the intended + // purpose for a portion of the resources the framework has + // reserved at a given agent. Labels should not contain duplicate + // key-value pairs. + optional Labels labels = 2; + } + + // If this is set, this resource was dynamically reserved by an + // operator or a framework. Otherwise, this resource is either unreserved + // or statically reserved by an operator via the --resources flag. + optional ReservationInfo reservation = 8; + + message DiskInfo { + // Describes a persistent disk volume. + // + // A persistent disk volume will not be automatically garbage + // collected if the task/executor/agent terminates, but will be + // re-offered to the framework(s) belonging to the 'role'. + // + // NOTE: Currently, we do not allow persistent disk volumes + // without a reservation (i.e., 'role' cannot be '*'). + message Persistence { + // A unique ID for the persistent disk volume. This ID must be + // unique per role on each agent. Although it is possible to use + // the same ID on different agents in the cluster and to reuse + // IDs after a volume with that ID has been destroyed, both + // practices are discouraged. + required string id = 1; + + // This field indicates the principal of the operator or + // framework that created this volume. It is used in conjunction + // with the "destroy" ACL to determine whether an entity + // attempting to destroy the volume is permitted to do so. + // + // NOTE: This field is optional, while the `principal` found in + // `ReservationInfo` is required. This field is optional to + // allow for the possibility of volume creation without a + // principal, though currently it must be provided. + // + // NOTE: This field should match the FrameworkInfo.principal of + // the framework that created the volume. + optional string principal = 2; + } + + optional Persistence persistence = 1; + + // Describes how this disk resource will be mounted in the + // container. If not set, the disk resource will be used as the + // sandbox. Otherwise, it will be mounted according to the + // 'container_path' inside 'volume'. The 'host_path' inside + // 'volume' is ignored. + // NOTE: If 'volume' is set but 'persistence' is not set, the + // volume will be automatically garbage collected after + // task/executor terminates. Currently, if 'persistence' is set, + // 'volume' must be set. + optional Volume volume = 2; + + // Describes where a disk originates from. + // TODO(jmlvanre): Add support for BLOCK devices. + message Source { + enum Type { + PATH = 1; + MOUNT = 2; + } + + // A folder that can be located on a separate disk device. This + // can be shared and carved up as necessary between frameworks. + message Path { + // Path to the folder (e.g., /mnt/raid/disk0). + required string root = 1; + } + + // A mounted file-system set up by the Agent administrator. This + // can only be used exclusively: a framework cannot accept a + // partial amount of this disk. + message Mount { + // Path to mount point (e.g., /mnt/raid/disk0). + required string root = 1; + } + + required Type type = 1; + optional Path path = 2; + optional Mount mount = 3; + } + + optional Source source = 3; + } + + optional DiskInfo disk = 7; + + message RevocableInfo {} + + // If this is set, the resources are revocable, i.e., any tasks or + // executors launched using these resources could get preempted or + // throttled at any time. This could be used by frameworks to run + // best effort tasks that do not need strict uptime or performance + // guarantees. Note that if this is set, 'disk' or 'reservation' + // cannot be set. + optional RevocableInfo revocable = 9; + + // Allow the resource to be shared across tasks. + message SharedInfo {} + + // If this is set, the resources are shared, i.e. multiple tasks + // can be launched using this resource and all of them shall refer + // to the same physical resource on the cluster. Note that only + // persistent volumes can be shared currently. + optional SharedInfo shared = 10; +} + +/** + * When the network bandwidth caps are enabled and the container + * is over its limit, outbound packets may be either delayed or + * dropped completely either because it exceeds the maximum bandwidth + * allocation for a single container (the cap) or because the combined + * network traffic of multiple containers on the host exceeds the + * transmit capacity of the host (the share). We can report the + * following statistics for each of these conditions exported directly + * from the Linux Traffic Control Queueing Discipline. + * + * id : name of the limiter, e.g. 'tx_bw_cap' + * backlog : number of packets currently delayed + * bytes : total bytes seen + * drops : number of packets dropped in total + * overlimits : number of packets which exceeded allocation + * packets : total packets seen + * qlen : number of packets currently queued + * rate_bps : throughput in bytes/sec + * rate_pps : throughput in packets/sec + * requeues : number of times a packet has been delayed due to + * locking or device contention issues + * + * More information on the operation of Linux Traffic Control can be + * found at http://www.lartc.org/lartc.html. + */ +message TrafficControlStatistics { + required string id = 1; + optional uint64 backlog = 2; + optional uint64 bytes = 3; + optional uint64 drops = 4; + optional uint64 overlimits = 5; + optional uint64 packets = 6; + optional uint64 qlen = 7; + optional uint64 ratebps = 8; + optional uint64 ratepps = 9; + optional uint64 requeues = 10; +} + + +message IpStatistics { + optional int64 Forwarding = 1; + optional int64 DefaultTTL = 2; + optional int64 InReceives = 3; + optional int64 InHdrErrors = 4; + optional int64 InAddrErrors = 5; + optional int64 ForwDatagrams = 6; + optional int64 InUnknownProtos = 7; + optional int64 InDiscards = 8; + optional int64 InDelivers = 9; + optional int64 OutRequests = 10; + optional int64 OutDiscards = 11; + optional int64 OutNoRoutes = 12; + optional int64 ReasmTimeout = 13; + optional int64 ReasmReqds = 14; + optional int64 ReasmOKs = 15; + optional int64 ReasmFails = 16; + optional int64 FragOKs = 17; + optional int64 FragFails = 18; + optional int64 FragCreates = 19; +} + + +message IcmpStatistics { + optional int64 InMsgs = 1; + optional int64 InErrors = 2; + optional int64 InCsumErrors = 3; + optional int64 InDestUnreachs = 4; + optional int64 InTimeExcds = 5; + optional int64 InParmProbs = 6; + optional int64 InSrcQuenchs = 7; + optional int64 InRedirects = 8; + optional int64 InEchos = 9; + optional int64 InEchoReps = 10; + optional int64 InTimestamps = 11; + optional int64 InTimestampReps = 12; + optional int64 InAddrMasks = 13; + optional int64 InAddrMaskReps = 14; + optional int64 OutMsgs = 15; + optional int64 OutErrors = 16; + optional int64 OutDestUnreachs = 17; + optional int64 OutTimeExcds = 18; + optional int64 OutParmProbs = 19; + optional int64 OutSrcQuenchs = 20; + optional int64 OutRedirects = 21; + optional int64 OutEchos = 22; + optional int64 OutEchoReps = 23; + optional int64 OutTimestamps = 24; + optional int64 OutTimestampReps = 25; + optional int64 OutAddrMasks = 26; + optional int64 OutAddrMaskReps = 27; +} + + +message TcpStatistics { + optional int64 RtoAlgorithm = 1; + optional int64 RtoMin = 2; + optional int64 RtoMax = 3; + optional int64 MaxConn = 4; + optional int64 ActiveOpens = 5; + optional int64 PassiveOpens = 6; + optional int64 AttemptFails = 7; + optional int64 EstabResets = 8; + optional int64 CurrEstab = 9; + optional int64 InSegs = 10; + optional int64 OutSegs = 11; + optional int64 RetransSegs = 12; + optional int64 InErrs = 13; + optional int64 OutRsts = 14; + optional int64 InCsumErrors = 15; +} + + +message UdpStatistics { + optional int64 InDatagrams = 1; + optional int64 NoPorts = 2; + optional int64 InErrors = 3; + optional int64 OutDatagrams = 4; + optional int64 RcvbufErrors = 5; + optional int64 SndbufErrors = 6; + optional int64 InCsumErrors = 7; + optional int64 IgnoredMulti = 8; +} + + +message SNMPStatistics { + optional IpStatistics ip_stats = 1; + optional IcmpStatistics icmp_stats = 2; + optional TcpStatistics tcp_stats = 3; + optional UdpStatistics udp_stats = 4; +} + + +/** + * A snapshot of resource usage statistics. + */ +message ResourceStatistics { + required double timestamp = 1; // Snapshot time, in seconds since the Epoch. + + optional uint32 processes = 30; + optional uint32 threads = 31; + + // CPU Usage Information: + // Total CPU time spent in user mode, and kernel mode. + optional double cpus_user_time_secs = 2; + optional double cpus_system_time_secs = 3; + + // Number of CPUs allocated. + optional double cpus_limit = 4; + + // cpu.stat on process throttling (for contention issues). + optional uint32 cpus_nr_periods = 7; + optional uint32 cpus_nr_throttled = 8; + optional double cpus_throttled_time_secs = 9; + + // Memory Usage Information: + + // mem_total_bytes was added in 0.23.0 to represent the total memory + // of a process in RAM (as opposed to in Swap). This was previously + // reported as mem_rss_bytes, which was also changed in 0.23.0 to + // represent only the anonymous memory usage, to keep in sync with + // Linux kernel's (arguably erroneous) use of terminology. + optional uint64 mem_total_bytes = 36; + + // Total memory + swap usage. This is set if swap is enabled. + optional uint64 mem_total_memsw_bytes = 37; + + // Hard memory limit for a container. + optional uint64 mem_limit_bytes = 6; + + // Soft memory limit for a container. + optional uint64 mem_soft_limit_bytes = 38; + + // Broken out memory usage information: pagecache, rss (anonymous), + // mmaped files and swap. + + // TODO(chzhcn) mem_file_bytes and mem_anon_bytes are deprecated in + // 0.23.0 and will be removed in 0.24.0. + optional uint64 mem_file_bytes = 10; + optional uint64 mem_anon_bytes = 11; + + // mem_cache_bytes is added in 0.23.0 to represent page cache usage. + optional uint64 mem_cache_bytes = 39; + + // Since 0.23.0, mem_rss_bytes is changed to represent only + // anonymous memory usage. Note that neither its requiredness, type, + // name nor numeric tag has been changed. + optional uint64 mem_rss_bytes = 5; + + optional uint64 mem_mapped_file_bytes = 12; + // This is only set if swap is enabled. + optional uint64 mem_swap_bytes = 40; + optional uint64 mem_unevictable_bytes = 41; + + // Number of occurrences of different levels of memory pressure + // events reported by memory cgroup. Pressure listening (re)starts + // with these values set to 0 when agent (re)starts. See + // https://www.kernel.org/doc/Documentation/cgroups/memory.txt for + // more details. + optional uint64 mem_low_pressure_counter = 32; + optional uint64 mem_medium_pressure_counter = 33; + optional uint64 mem_critical_pressure_counter = 34; + + // Disk Usage Information for executor working directory. + optional uint64 disk_limit_bytes = 26; + optional uint64 disk_used_bytes = 27; + + // Perf statistics. + optional PerfStatistics perf = 13; + + // Network Usage Information: + optional uint64 net_rx_packets = 14; + optional uint64 net_rx_bytes = 15; + optional uint64 net_rx_errors = 16; + optional uint64 net_rx_dropped = 17; + optional uint64 net_tx_packets = 18; + optional uint64 net_tx_bytes = 19; + optional uint64 net_tx_errors = 20; + optional uint64 net_tx_dropped = 21; + + // The kernel keeps track of RTT (round-trip time) for its TCP + // sockets. RTT is a way to tell the latency of a container. + optional double net_tcp_rtt_microsecs_p50 = 22; + optional double net_tcp_rtt_microsecs_p90 = 23; + optional double net_tcp_rtt_microsecs_p95 = 24; + optional double net_tcp_rtt_microsecs_p99 = 25; + + optional double net_tcp_active_connections = 28; + optional double net_tcp_time_wait_connections = 29; + + // Network traffic flowing into or out of a container can be delayed + // or dropped due to congestion or policy inside and outside the + // container. + repeated TrafficControlStatistics net_traffic_control_statistics = 35; + + // Network SNMP statistics for each container. + optional SNMPStatistics net_snmp_statistics = 42; +} + + +/** + * Describes a snapshot of the resource usage for executors. + */ +message ResourceUsage { + message Executor { + required ExecutorInfo executor_info = 1; + + // This includes resources used by the executor itself + // as well as its active tasks. + repeated Resource allocated = 2; + + // Current resource usage. If absent, the containerizer + // cannot provide resource usage. + optional ResourceStatistics statistics = 3; + + // The container id for the executor specified in the executor_info field. + required ContainerID container_id = 4; + + message Task { + required string name = 1; + required TaskID id = 2; + repeated Resource resources = 3; + optional Labels labels = 4; + } + + // Non-terminal tasks. + repeated Task tasks = 5; + } + + repeated Executor executors = 1; + + // Agent's total resources including checkpointed dynamic + // reservations and persistent volumes. + repeated Resource total = 2; +} + + +/** + * Describes a sample of events from "perf stat". Only available on + * Linux. + * + * NOTE: Each optional field matches the name of a perf event (see + * "perf list") with the following changes: + * 1. Names are downcased. + * 2. Hyphens ('-') are replaced with underscores ('_'). + * 3. Events with alternate names use the name "perf stat" returns, + * e.g., for the event "cycles OR cpu-cycles" perf always returns + * cycles. + */ +message PerfStatistics { + required double timestamp = 1; // Start of sample interval, in seconds since the Epoch. + required double duration = 2; // Duration of sample interval, in seconds. + + // Hardware event. + optional uint64 cycles = 3; + optional uint64 stalled_cycles_frontend = 4; + optional uint64 stalled_cycles_backend = 5; + optional uint64 instructions = 6; + optional uint64 cache_references = 7; + optional uint64 cache_misses = 8; + optional uint64 branches = 9; + optional uint64 branch_misses = 10; + optional uint64 bus_cycles = 11; + optional uint64 ref_cycles = 12; + + // Software event. + optional double cpu_clock = 13; + optional double task_clock = 14; + optional uint64 page_faults = 15; + optional uint64 minor_faults = 16; + optional uint64 major_faults = 17; + optional uint64 context_switches = 18; + optional uint64 cpu_migrations = 19; + optional uint64 alignment_faults = 20; + optional uint64 emulation_faults = 21; + + // Hardware cache event. + optional uint64 l1_dcache_loads = 22; + optional uint64 l1_dcache_load_misses = 23; + optional uint64 l1_dcache_stores = 24; + optional uint64 l1_dcache_store_misses = 25; + optional uint64 l1_dcache_prefetches = 26; + optional uint64 l1_dcache_prefetch_misses = 27; + optional uint64 l1_icache_loads = 28; + optional uint64 l1_icache_load_misses = 29; + optional uint64 l1_icache_prefetches = 30; + optional uint64 l1_icache_prefetch_misses = 31; + optional uint64 llc_loads = 32; + optional uint64 llc_load_misses = 33; + optional uint64 llc_stores = 34; + optional uint64 llc_store_misses = 35; + optional uint64 llc_prefetches = 36; + optional uint64 llc_prefetch_misses = 37; + optional uint64 dtlb_loads = 38; + optional uint64 dtlb_load_misses = 39; + optional uint64 dtlb_stores = 40; + optional uint64 dtlb_store_misses = 41; + optional uint64 dtlb_prefetches = 42; + optional uint64 dtlb_prefetch_misses = 43; + optional uint64 itlb_loads = 44; + optional uint64 itlb_load_misses = 45; + optional uint64 branch_loads = 46; + optional uint64 branch_load_misses = 47; + optional uint64 node_loads = 48; + optional uint64 node_load_misses = 49; + optional uint64 node_stores = 50; + optional uint64 node_store_misses = 51; + optional uint64 node_prefetches = 52; + optional uint64 node_prefetch_misses = 53; +} + + +/** + * Describes a request for resources that can be used by a framework + * to proactively influence the allocator. If 'agent_id' is provided + * then this request is assumed to only apply to resources on that + * agent. + */ +message Request { + optional AgentID agent_id = 1; + repeated Resource resources = 2; +} + + +/** + * Describes some resources available on an agent. An offer only + * contains resources from a single agent. + */ +message Offer { + required OfferID id = 1; + required FrameworkID framework_id = 2; + required AgentID agent_id = 3; + required string hostname = 4; + + // URL for reaching the agent running on the host. + optional URL url = 8; + + repeated Resource resources = 5; + repeated Attribute attributes = 7; + repeated ExecutorID executor_ids = 6; + + // Signifies that the resources in this Offer may be unavailable during + // the given interval. Any tasks launched using these resources may be + // killed when the interval arrives. For example, these resources may be + // part of a planned maintenance schedule. + // + // This field only provides information about a planned unavailability. + // The unavailability interval may not necessarily start at exactly this + // interval, nor last for exactly the duration of this interval. + // The unavailability may also be forever! See comments in + // `Unavailability` for more details. + optional Unavailability unavailability = 9; + + // Defines an operation that can be performed against offers. + message Operation { + enum Type { + UNKNOWN = 0; + LAUNCH = 1; + LAUNCH_GROUP = 6; + RESERVE = 2; + UNRESERVE = 3; + CREATE = 4; + DESTROY = 5; + } + + // TODO(vinod): Deprecate this in favor of `LaunchGroup` below. + message Launch { + repeated TaskInfo task_infos = 1; + } + + // Unlike `Launch` above, all the tasks in a `task_group` are + // atomically delivered to an executor. + // + // `NetworkInfo` set on executor will be shared by all tasks in + // the task group. + // + // TODO(vinod): Any volumes set on executor could be used by a + // task by explicitly setting `Volume.source` in its resources. + message LaunchGroup { + required ExecutorInfo executor = 1; + required TaskGroupInfo task_group = 2; + } + + message Reserve { + repeated Resource resources = 1; + } + + message Unreserve { + repeated Resource resources = 1; + } + + message Create { + repeated Resource volumes = 1; + } + + message Destroy { + repeated Resource volumes = 1; + } + + optional Type type = 1; + optional Launch launch = 2; + optional LaunchGroup launch_group = 7; + optional Reserve reserve = 3; + optional Unreserve unreserve = 4; + optional Create create = 5; + optional Destroy destroy = 6; + } +} + + +/** + * A request to return some resources occupied by a framework. + */ +message InverseOffer { + // This is the same OfferID as found in normal offers, which allows + // re-use of some of the OfferID-only messages. + required OfferID id = 1; + + // URL for reaching the agent running on the host. This enables some + // optimizations as described in MESOS-3012, such as allowing the + // scheduler driver to bypass the master and talk directly with an agent. + optional URL url = 2; + + // The framework that should release its resources. + // If no specifics are provided (i.e. which agent), all the framework's + // resources are requested back. + required FrameworkID framework_id = 3; + + // Specified if the resources need to be released from a particular agent. + // All the framework's resources on this agent are requested back, + // unless further qualified by the `resources` field. + optional AgentID agent_id = 4; + + // This InverseOffer represents a planned unavailability event in the + // specified interval. Any tasks running on the given framework or agent + // may be killed when the interval arrives. Therefore, frameworks should + // aim to gracefully terminate tasks prior to the arrival of the interval. + // + // For reserved resources, the resources are expected to be returned to the + // framework after the unavailability interval. This is an expectation, + // not a guarantee. For example, if the unavailability duration is not set, + // the resources may be removed permanently. + // + // For other resources, there is no guarantee that requested resources will + // be returned after the unavailability interval. The allocator has no + // obligation to re-offer these resources to the prior framework after + // the unavailability. + required Unavailability unavailability = 5; + + // A list of resources being requested back from the framework, + // on the agent identified by `agent_id`. If no resources are specified + // then all resources are being requested back. For the purpose of + // maintenance, this field is always empty (maintenance always requests + // all resources back). + repeated Resource resources = 6; + + // TODO(josephw): Add additional options for narrowing down the resources + // being requested back. Such as specific executors, tasks, etc. +} + + +/** + * Describes a task. Passed from the scheduler all the way to an + * executor (see SchedulerDriver::launchTasks and + * Executor::launchTask). Either ExecutorInfo or CommandInfo should be set. + * A different executor can be used to launch this task, and subsequent tasks + * meant for the same executor can reuse the same ExecutorInfo struct. + */ +message TaskInfo { + required string name = 1; + required TaskID task_id = 2; + required AgentID agent_id = 3; + repeated Resource resources = 4; + optional ExecutorInfo executor = 5; + optional CommandInfo command = 7; + + // Task provided with a container will launch the container as part + // of this task paired with the task's CommandInfo. + optional ContainerInfo container = 9; + + // A health check for the task. Implemented for executor-less + // command-based tasks. For tasks that specify an executor, it is + // the executor's responsibility to implement the health checking. + optional HealthCheck health_check = 8; + + // A kill policy for the task. Implemented for executor-less + // command-based and docker tasks. For tasks that specify other + // executor, it is the executor's responsibility to implement + // the kill policy. + optional KillPolicy kill_policy = 12; + + optional bytes data = 6; + + // Labels are free-form key value pairs which are exposed through + // master and agent endpoints. Labels will not be interpreted or + // acted upon by Mesos itself. As opposed to the data field, labels + // will be kept in memory on master and agent processes. Therefore, + // labels should be used to tag tasks with light-weight meta-data. + // Labels should not contain duplicate key-value pairs. + optional Labels labels = 10; + + // Service discovery information for the task. It is not interpreted + // or acted upon by Mesos. It is up to a service discovery system + // to use this information as needed and to handle tasks without + // service discovery information. + optional DiscoveryInfo discovery = 11; +} + + +/** + * Describes a group of tasks that belong to an executor. The + * executor will receive the task group in a single message to + * allow the group to be launched "atomically". + * + * NOTES: + * 1) `NetworkInfo` must not be set inside task's `ContainerInfo`. + * 2) `TaskInfo.executor` doesn't need to set. If set, it should match + * `LaunchGroup.executor`. + */ +message TaskGroupInfo { + repeated TaskInfo tasks = 1; +} + + +// TODO(bmahler): Add executor_uuid here, and send it to the master. This will +// allow us to expose executor work directories for tasks in the webui when +// looking from the master level. Currently only the agent knows which run the +// task belongs to. +/** + * Describes a task, similar to `TaskInfo`. + * + * `Task` is used in some of the Mesos messages found below. + * `Task` is used instead of `TaskInfo` if: + * 1) we need additional IDs, such as a specific + * framework, executor, or agent; or + * 2) we do not need the additional data, such as the command run by the + * task or the health checks. These additional fields may be large and + * unnecessary for some Mesos messages. + * + * `Task` is generally constructed from a `TaskInfo`. See protobuf::createTask. + */ +message Task { + required string name = 1; + required TaskID task_id = 2; + required FrameworkID framework_id = 3; + optional ExecutorID executor_id = 4; + required AgentID agent_id = 5; + required TaskState state = 6; // Latest state of the task. + repeated Resource resources = 7; + repeated TaskStatus statuses = 8; + + // These fields correspond to the state and uuid of the latest + // status update forwarded to the master. + // NOTE: Either both the fields must be set or both must be unset. + optional TaskState status_update_state = 9; + optional bytes status_update_uuid = 10; + + optional Labels labels = 11; + + // Service discovery information for the task. It is not interpreted + // or acted upon by Mesos. It is up to a service discovery system + // to use this information as needed and to handle tasks without + // service discovery information. + optional DiscoveryInfo discovery = 12; + + // Container information for the task. + optional ContainerInfo container = 13; + + // Specific user under which task is running. + optional string user = 14; +} + + +/** + * Describes possible task states. IMPORTANT: Mesos assumes tasks that + * enter terminal states (see below) imply the task is no longer + * running and thus clean up any thing associated with the task + * (ultimately offering any resources being consumed by that task to + * another task). + */ +enum TaskState { + TASK_STAGING = 6; // Initial state. Framework status updates should not use. + TASK_STARTING = 0; // The task is being launched by the executor. + TASK_RUNNING = 1; + + // NOTE: This should only be sent when the framework has + // the TASK_KILLING_STATE capability. + TASK_KILLING = 8; // The task is being killed by the executor. + + TASK_FINISHED = 2; // TERMINAL: The task finished successfully. + TASK_FAILED = 3; // TERMINAL: The task failed to finish successfully. + TASK_KILLED = 4; // TERMINAL: The task was killed by the executor. + TASK_ERROR = 7; // TERMINAL: The task description contains an error. + + // In Mesos 1.2, this will only be sent when the framework does NOT + // opt-in to the PARTITION_AWARE capability. + TASK_LOST = 5; // TERMINAL: The task failed but can be rescheduled. + + // The following task statuses are only sent when the framework + // opts-in to the PARTITION_AWARE capability. + + // The task failed to launch because of a transient error. The + // task's executor never started running. Unlike TASK_ERROR, the + // task description is valid -- attempting to launch the task again + // may be successful. + TASK_DROPPED = 9; // TERMINAL. + + // The task was running on an agent that has lost contact with the + // master, typically due to a network failure or partition. The task + // may or may not still be running. + TASK_UNREACHABLE = 10; + + // The task was running on an agent that has been shutdown (e.g., + // the agent become partitioned, rebooted, and then reconnected to + // the master; any tasks running before the reboot will transition + // from UNREACHABLE to GONE). The task is no longer running. + TASK_GONE = 11; // TERMINAL. + + // The task was running on an agent that the master cannot contact; + // the operator has asserted that the agent has been shutdown, but + // this has not been directly confirmed by the master. If the + // operator is correct, the task is not running and this is a + // terminal state; if the operator is mistaken, the task may still + // be running and might return to RUNNING in the future. + TASK_GONE_BY_OPERATOR = 12; + + // The master has no knowledge of the task. This is typically + // because either (a) the master never had knowledge of the task, or + // (b) the master forgot about the task because it garbage collected + // its metadata about the task. The task may or may not still be + // running. + TASK_UNKNOWN = 13; +} + + +/** + * Describes the current status of a task. + */ +message TaskStatus { + // Describes the source of the task status update. + enum Source { + SOURCE_MASTER = 0; + SOURCE_AGENT = 1; + SOURCE_EXECUTOR = 2; + } + + // Detailed reason for the task status update. + // + // TODO(bmahler): Differentiate between agent removal reasons + // (e.g. unhealthy vs. unregistered for maintenance). + enum Reason { + // TODO(jieyu): The default value when a caller doesn't check for + // presence is 0 and so ideally the 0 reason is not a valid one. + // Since this is not used anywhere, consider removing this reason. + REASON_COMMAND_EXECUTOR_FAILED = 0; + + REASON_CONTAINER_LAUNCH_FAILED = 21; + REASON_CONTAINER_LIMITATION = 19; + REASON_CONTAINER_LIMITATION_DISK = 20; + REASON_CONTAINER_LIMITATION_MEMORY = 8; + REASON_CONTAINER_PREEMPTED = 17; + REASON_CONTAINER_UPDATE_FAILED = 22; + REASON_EXECUTOR_REGISTRATION_TIMEOUT = 23; + REASON_EXECUTOR_REREGISTRATION_TIMEOUT = 24; + REASON_EXECUTOR_TERMINATED = 1; + REASON_EXECUTOR_UNREGISTERED = 2; + REASON_FRAMEWORK_REMOVED = 3; + REASON_GC_ERROR = 4; + REASON_INVALID_FRAMEWORKID = 5; + REASON_INVALID_OFFERS = 6; + REASON_MASTER_DISCONNECTED = 7; + REASON_RECONCILIATION = 9; + REASON_RESOURCES_UNKNOWN = 18; + REASON_AGENT_DISCONNECTED = 10; + REASON_AGENT_REMOVED = 11; + REASON_AGENT_RESTARTED = 12; + REASON_AGENT_UNKNOWN = 13; + REASON_TASK_GROUP_INVALID = 25; + REASON_TASK_GROUP_UNAUTHORIZED = 26; + REASON_TASK_INVALID = 14; + REASON_TASK_UNAUTHORIZED = 15; + REASON_TASK_UNKNOWN = 16; + } + + required TaskID task_id = 1; + required TaskState state = 2; + optional string message = 4; // Possible message explaining state. + optional Source source = 9; + optional Reason reason = 10; + optional bytes data = 3; + optional AgentID agent_id = 5; + optional ExecutorID executor_id = 7; // TODO(benh): Use in master/agent. + optional double timestamp = 6; + + // Statuses that are delivered reliably to the scheduler will + // include a 'uuid'. The status is considered delivered once + // it is acknowledged by the scheduler. Schedulers can choose + // to either explicitly acknowledge statuses or let the scheduler + // driver implicitly acknowledge (default). + // + // TODO(bmahler): This is currently overwritten in the scheduler + // driver and executor driver, but executors will need to set this + // to a valid RFC-4122 UUID if using the HTTP API. + optional bytes uuid = 11; + + // Describes whether the task has been determined to be healthy + // (true) or unhealthy (false) according to the HealthCheck field in + // the command info. + optional bool healthy = 8; + + // Labels are free-form key value pairs which are exposed through + // master and agent endpoints. Labels will not be interpreted or + // acted upon by Mesos itself. As opposed to the data field, labels + // will be kept in memory on master and agent processes. Therefore, + // labels should be used to tag TaskStatus message with light-weight + // meta-data. Labels should not contain duplicate key-value pairs. + optional Labels labels = 12; + + // Container related information that is resolved dynamically such as + // network address. + optional ContainerStatus container_status = 13; + + // The time (according to the master's clock) when the agent where + // this task was running became unreachable. This is only set on + // status updates for tasks running on agents that are unreachable + // (e.g., partitioned away from the master). + optional TimeInfo unreachable_time = 14; +} + + +/** + * Describes possible filters that can be applied to unused resources + * (see SchedulerDriver::launchTasks) to influence the allocator. + */ +message Filters { + // Time to consider unused resources refused. Note that all unused + // resources will be considered refused and use the default value + // (below) regardless of whether Filters was passed to + // SchedulerDriver::launchTasks. You MUST pass Filters with this + // field set to change this behavior (i.e., get another offer which + // includes unused resources sooner or later than the default). + optional double refuse_seconds = 1 [default = 5.0]; +} + + +/** +* Describes a collection of environment variables. This is used with +* CommandInfo in order to set environment variables before running a +* command. +*/ +message Environment { + message Variable { + required string name = 1; + required string value = 2; + } + + repeated Variable variables = 1; +} + + +/** + * A generic (key, value) pair used in various places for parameters. + */ +message Parameter { + required string key = 1; + required string value = 2; +} + + +/** + * Collection of Parameter. + */ +message Parameters { + repeated Parameter parameter = 1; +} + + +/** + * Credential used in various places for authentication and + * authorization. + * + * NOTE: A 'principal' is different from 'FrameworkInfo.user'. The + * former is used for authentication and authorization while the + * latter is used to determine the default user under which the + * framework's executors/tasks are run. + */ +message Credential { + required string principal = 1; + optional string secret = 2; +} + + +/** + * Credentials used for framework authentication, HTTP authentication + * (where the common 'username' and 'password' are captured as + * 'principal' and 'secret' respectively), etc. + */ +message Credentials { + repeated Credential credentials = 1; +} + + +/** + * Rate (queries per second, QPS) limit for messages from a framework to master. + * Strictly speaking they are the combined rate from all frameworks of the same + * principal. + */ +message RateLimit { + // Leaving QPS unset gives it unlimited rate (i.e., not throttled), + // which also implies unlimited capacity. + optional double qps = 1; + + // Principal of framework(s) to be throttled. Should match + // FrameworkInfo.principal and Credential.principal (if using authentication). + required string principal = 2; + + // Max number of outstanding messages from frameworks of this principal + // allowed by master before the next message is dropped and an error is sent + // back to the sender. Messages received before the capacity is reached are + // still going to be processed after the error is sent. + // If unspecified, this principal is assigned unlimited capacity. + // NOTE: This value is ignored if 'qps' is not set. + optional uint64 capacity = 3; +} + + +/** + * Collection of RateLimit. + * Frameworks without rate limits defined here are not throttled unless + * 'aggregate_default_qps' is specified. + */ +message RateLimits { + // Items should have unique principals. + repeated RateLimit limits = 1; + + // All the frameworks not specified in 'limits' get this default rate. + // This rate is an aggregate rate for all of them, i.e., their combined + // traffic is throttled together at this rate. + optional double aggregate_default_qps = 2; + + // All the frameworks not specified in 'limits' get this default capacity. + // This is an aggregate value similar to 'aggregate_default_qps'. + optional uint64 aggregate_default_capacity = 3; +} + + +/** + * Describe an image used by tasks or executors. Note that it's only + * for tasks or executors launched by MesosContainerizer currently. + */ +message Image { + enum Type { + APPC = 1; + DOCKER = 2; + } + + // Protobuf for specifying an Appc container image. See: + // https://github.com/appc/spec/blob/master/spec/aci.md + message Appc { + // The name of the image. + required string name = 1; + + // An image ID is a string of the format "hash-value", where + // "hash" is the hash algorithm used and "value" is the hex + // encoded string of the digest. Currently the only permitted + // hash algorithm is sha512. + optional string id = 2; + + // Optional labels. Suggested labels: "version", "os", and "arch". + optional Labels labels = 3; + } + + message Docker { + // The name of the image. Expected format: + // [REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG|@TYPE:DIGEST] + // + // See: https://docs.docker.com/reference/commandline/pull/ + required string name = 1; + + // Credential to authenticate with docker registry. + // NOTE: This is not encrypted, therefore framework and operators + // should enable SSL when passing this information. + optional Credential credential = 2; + } + + required Type type = 1; + + // Only one of the following image messages should be set to match + // the type. + optional Appc appc = 2; + optional Docker docker = 3; + + // With this flag set to false, the mesos containerizer will pull + // the docker/appc image from the registry even if the image is + // already downloaded on the agent. + optional bool cached = 4 [default = true]; +} + + +/** + * Describes a volume mapping either from host to container or vice + * versa. Both paths can either refer to a directory or a file. + */ +message Volume { + enum Mode { + RW = 1; // read-write. + RO = 2; // read-only. + } + + // TODO(gyliu513): Make this as `optional` after deprecation cycle of 1.0. + required Mode mode = 3; + + // Path pointing to a directory or file in the container. If the + // path is a relative path, it is relative to the container work + // directory. If the path is an absolute path, that path must + // already exist. + required string container_path = 1; + + // The following specifies the source of this volume. At most one of + // the following should be set. + + // Absolute path pointing to a directory or file on the host or a + // path relative to the container work directory. + optional string host_path = 2; + + // The source of the volume is an Image which describes a root + // filesystem which will be provisioned by Mesos. + optional Image image = 4; + + // Describes where a volume originates from. + message Source { + enum Type { + // This must be the first enum value in this list, to + // ensure that if 'type' is not set, the default value + // is UNKNOWN. This enables enum values to be added + // in a backwards-compatible way. See: MESOS-4997. + UNKNOWN = 0; + + // TODO(gyliu513): Add HOST_PATH and IMAGE as volume source type. + DOCKER_VOLUME = 1; + SANDBOX_PATH = 2; + } + + message DockerVolume { + // Driver of the volume, it can be flocker, convoy, raxrey etc. + optional string driver = 1; + + // Name of the volume. + required string name = 2; + + // Volume driver specific options. + optional Parameters driver_options = 3; + } + + // Describe a path from a container's sandbox. The container can + // be the current container (SELF), or its parent container + // (PARENT). PARENT allows all child containers to share a volume + // from their parent container's sandbox. It'll be an error if + // the current container is a top level container. + message SandboxPath { + enum Type { + UNKNOWN = 0; + SELF = 1; + PARENT = 2; + } + + optional Type type = 1; + + // A path relative to the corresponding container's sandbox. + // Note that upwards traversal (i.e. ../../abc) is not allowed. + required string path = 2; + } + + // Enum fields should be optional, see: MESOS-4997. + optional Type type = 1; + + // The following specifies the source of this volume. At most one of + // the following should be set. + + // The source of the volume created by docker volume driver. + optional DockerVolume docker_volume = 2; + + optional SandboxPath sandbox_path = 3; + } + + optional Source source = 5; +} + + +/** + * Describes a network request from a framework as well as network resolution + * provided by Mesos. + * + * A framework may request the network isolator on the Agent to isolate the + * container in a network namespace and create a virtual network interface. + * The `NetworkInfo` message describes the properties of that virtual + * interface, including the IP addresses and network isolation policy + * (network group membership). + * + * The NetworkInfo message is not interpreted by the Master or Agent and is + * intended to be used by Agent and Master modules implementing network + * isolation. If the modules are missing, the message is simply ignored. In + * future, the task launch will fail if there is no module providing the + * network isolation capabilities (MESOS-3390). + * + * An executor, Agent, or an Agent module may append NetworkInfos inside + * TaskStatus::container_status to provide information such as the container IP + * address and isolation groups. + */ +message NetworkInfo { + enum Protocol { + IPv4 = 1; + IPv6 = 2; + } + + // Specifies a request for an IP address, or reports the assigned container + // IP address. + // + // Users can request an automatically assigned IP (for example, via an + // IPAM service) or a specific IP by adding a NetworkInfo to the + // ContainerInfo for a task. On a request, specifying neither `protocol` + // nor `ip_address` means that any available address may be assigned. + message IPAddress { + // Specify IP address requirement. Set protocol to the desired value to + // request the network isolator on the Agent to assign an IP address to the + // container being launched. If a specific IP address is specified in + // ip_address, this field should not be set. + optional Protocol protocol = 1; + + // Statically assigned IP provided by the Framework. This IP will be + // assigned to the container by the network isolator module on the Agent. + // This field should not be used with the protocol field above. + // + // If an explicit address is requested but is unavailable, the network + // isolator should fail the task. + optional string ip_address = 2; + } + + // When included in a ContainerInfo, each of these represent a + // request for an IP address. Each request can specify an explicit address + // or the IP protocol to use. + // + // When included in a TaskStatus message, these inform the framework + // scheduler about the IP addresses that are bound to the container + // interface. When there are no custom network isolator modules installed, + // this field is filled in automatically with the Agent IP address. + repeated IPAddress ip_addresses = 5; + + // Name of the network which will be used by network isolator to determine + // the network that the container joins. It's up to the network isolator + // to decide how to interpret this field. + optional string name = 6; + + // A group is the name given to a set of logically-related interfaces that + // are allowed to communicate among themselves. Network traffic is allowed + // between two container interfaces that share at least one network group. + // For example, one might want to create separate groups for isolating dev, + // testing, qa and prod deployment environments. + repeated string groups = 3; + + // To tag certain metadata to be used by Isolator/IPAM, e.g., rack, etc. + optional Labels labels = 4; + + // Specifies a port mapping request for the task on this network. + message PortMapping { + required uint32 host_port = 1; + required uint32 container_port = 2; + // Protocol to expose as (ie: tcp, udp). + optional string protocol = 3; + } + + repeated PortMapping port_mappings = 7; +}; + + +/** + * Encapsulation of `Capabilities` supported by Linux. + * Reference: http://linux.die.net/man/7/capabilities. + */ +message CapabilityInfo { + // We start the actual values at an offset(1000) because Protobuf 2 + // uses the first value as the default one. Separating the default + // value from the real first value helps to disambiguate them. This + // is especially valuable for backward compatibility. + // See: MESOS-4997. + enum Capability { + UNKNOWN = 0; + CHOWN = 1000; + DAC_OVERRIDE = 1001; + DAC_READ_SEARCH = 1002; + FOWNER = 1003; + FSETID = 1004; + KILL = 1005; + SETGID = 1006; + SETUID = 1007; + SETPCAP = 1008; + LINUX_IMMUTABLE = 1009; + NET_BIND_SERVICE = 1010; + NET_BROADCAST = 1011; + NET_ADMIN = 1012; + NET_RAW = 1013; + IPC_LOCK = 1014; + IPC_OWNER = 1015; + SYS_MODULE = 1016; + SYS_RAWIO = 1017; + SYS_CHROOT = 1018; + SYS_PTRACE = 1019; + SYS_PACCT = 1020; + SYS_ADMIN = 1021; + SYS_BOOT = 1022; + SYS_NICE = 1023; + SYS_RESOURCE = 1024; + SYS_TIME = 1025; + SYS_TTY_CONFIG = 1026; + MKNOD = 1027; + LEASE = 1028; + AUDIT_WRITE = 1029; + AUDIT_CONTROL = 1030; + SETFCAP = 1031; + MAC_OVERRIDE = 1032; + MAC_ADMIN = 1033; + SYSLOG = 1034; + WAKE_ALARM = 1035; + BLOCK_SUSPEND = 1036; + AUDIT_READ = 1037; + } + + repeated Capability capabilities = 1; +} + + +/** + * Encapsulation for Linux specific configuration. + * E.g, capabilities, limits etc. + */ +message LinuxInfo { + // Represents the capability whitelist. + optional CapabilityInfo capability_info = 1; +} + + +/** + * Describes a container configuration and allows extensible + * configurations for different container implementations. + */ +message ContainerInfo { + // All container implementation types. + enum Type { + DOCKER = 1; + MESOS = 2; + } + + message DockerInfo { + // The docker image that is going to be passed to the registry. + required string image = 1; + + // Network options. + enum Network { + HOST = 1; + BRIDGE = 2; + NONE = 3; + USER = 4; + } + + optional Network network = 2 [default = HOST]; + + message PortMapping { + required uint32 host_port = 1; + required uint32 container_port = 2; + // Protocol to expose as (ie: tcp, udp). + optional string protocol = 3; + } + + repeated PortMapping port_mappings = 3; + + optional bool privileged = 4 [default = false]; + + // Allowing arbitrary parameters to be passed to docker CLI. + // Note that anything passed to this field is not guaranteed + // to be supported moving forward, as we might move away from + // the docker CLI. + repeated Parameter parameters = 5; + + // With this flag set to true, the docker containerizer will + // pull the docker image from the registry even if the image + // is already downloaded on the agent. + optional bool force_pull_image = 6; + + // The name of volume driver plugin. + optional string volume_driver = 7 [deprecated = true]; // Since 1.0 + } + + message MesosInfo { + optional Image image = 1; + } + + required Type type = 1; + repeated Volume volumes = 2; + optional string hostname = 4; + + // Only one of the following *Info messages should be set to match + // the type. + optional DockerInfo docker = 3; + optional MesosInfo mesos = 5; + + // A list of network requests. A framework can request multiple IP addresses + // for the container. + repeated NetworkInfo network_infos = 7; + + // Linux specific information for the container. + optional LinuxInfo linux_info = 8; +} + + +/** + * Container related information that is resolved during container + * setup. The information is sent back to the framework as part of the + * TaskStatus message. + */ +message ContainerStatus { + // This field can be reliably used to identify the container IP address. + repeated NetworkInfo network_infos = 1; + + // Information about Linux control group (cgroup). + optional CgroupInfo cgroup_info = 2; + + // Information about Executor PID. + optional uint32 executor_pid = 3; +} + + +/** + * Linux control group (cgroup) information. + */ +message CgroupInfo { + // Configuration of a net_cls cgroup subsystem. + message NetCls { + // The 32-bit classid consists of two parts, a 16 bit major handle + // and a 16-bit minor handle. The major and minor handle are + // represented using the format 0xAAAABBBB, where 0xAAAA is the + // 16-bit major handle and 0xBBBB is the 16-bit minor handle. + optional uint32 classid = 1; + } + + optional NetCls net_cls = 1; +} + + +/** + * Collection of labels. Labels should not contain duplicate key-value + * pairs. + */ +message Labels { + repeated Label labels = 1; +} + + +/** + * Key, value pair used to store free form user-data. + */ +message Label { + required string key = 1; + optional string value = 2; +} + + +/** + * Named port used for service discovery. + */ +message Port { + // Port number on which the framework exposes a service. + required uint32 number = 1; + + // Name of the service hosted on this port. + optional string name = 2; + + // Layer 4-7 protocol on which the framework exposes its services. + optional string protocol = 3; + + // This field restricts discovery within a framework (FRAMEWORK), + // within a Mesos cluster (CLUSTER), or places no restrictions (EXTERNAL). + // The visibility setting for a Port overrides the general visibility setting + // in the DiscoveryInfo. + optional DiscoveryInfo.Visibility visibility = 4; + + // This can be used to decorate the message with metadata to be + // interpreted by external applications such as firewalls. + optional Labels labels = 5; +} + + +/** + * Collection of ports. + */ +message Ports { + repeated Port ports = 1; +} + + +/** +* Service discovery information. +* The visibility field restricts discovery within a framework (FRAMEWORK), +* within a Mesos cluster (CLUSTER), or places no restrictions (EXTERNAL). +* Each port in the ports field also has an optional visibility field. +* If visibility is specified for a port, it overrides the default service-wide +* DiscoveryInfo.visibility for that port. +* The environment, location, and version fields provide first class support for +* common attributes used to differentiate between similar services. The +* environment may receive values such as PROD/QA/DEV, the location field may +* receive values like EAST-US/WEST-US/EUROPE/AMEA, and the version field may +* receive values like v2.0/v0.9. The exact use of these fields is up to each +* service discovery system. +*/ +message DiscoveryInfo { + enum Visibility { + FRAMEWORK = 0; + CLUSTER = 1; + EXTERNAL = 2; + } + + required Visibility visibility = 1; + optional string name = 2; + optional string environment = 3; + optional string location = 4; + optional string version = 5; + optional Ports ports = 6; + optional Labels labels = 7; +} + + +/** + * Named WeightInfo to indicate resource allocation + * priority between the different roles. + */ +message WeightInfo { + required double weight = 1; + + // Related role name. + optional string role = 2; +} + + +/** + * Version information of a component. + */ +message VersionInfo { + required string version = 1; + optional string build_date = 2; + optional double build_time = 3; + optional string build_user = 4; + optional string git_sha = 5; + optional string git_branch = 6; + optional string git_tag = 7; +} + + +/** + * Flag consists of a name and optionally its value. + */ +message Flag { + required string name = 1; + optional string value = 2; +} + + +/** + * Describes a Role. Roles can be used to specify that certain resources are + * reserved for the use of one or more frameworks. + */ +message Role { + required string name = 1; + required double weight = 2; + repeated FrameworkID frameworks = 3; + repeated Resource resources = 4; +} + + +/** + * Metric consists of a name and optionally its value. + */ +message Metric { + required string name = 1; + optional double value = 2; +} + + +/** + * Describes a File. + */ +message FileInfo { + // Absolute path to the file. + required string path = 1; + + // Number of hard links. + optional int32 nlink = 2; + + // Total size in bytes. + optional uint64 size = 3; + + // Last modification time. + optional TimeInfo mtime = 4; + + // Represents a file's mode and permission bits. The bits have the same + // definition on all systems and is portable. + optional uint32 mode = 5; + + // User ID of owner. + optional string uid = 6; + + // Group ID of owner. + optional string gid = 7; +} diff --git a/bcs-common/pkg/scheduler/mesosproto/mesos/quota/quota.pb.go b/bcs-common/pkg/scheduler/mesosproto/mesos/quota/quota.pb.go new file mode 100644 index 0000000000..6d670682f6 --- /dev/null +++ b/bcs-common/pkg/scheduler/mesosproto/mesos/quota/quota.pb.go @@ -0,0 +1,162 @@ +// Code generated by protoc-gen-go. +// source: quota.proto +// DO NOT EDIT! + +/* +Package mesos_quota is a generated protocol buffer package. + +It is generated from these files: + quota.proto + +It has these top-level messages: + QuotaInfo + QuotaRequest + QuotaStatus +*/ +package mesos_quota + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import mesos "bk-bcs/bcs-common/pkg/scheduler/mesosproto/mesos" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// TODO(joerg84): Add limits, i.e. upper bounds of resources that a +// role is allowed to use. +type QuotaInfo struct { + // Quota is granted per role and not per framework, similar to + // dynamic reservations. + Role *string `protobuf:"bytes,1,opt,name=role" json:"role,omitempty"` + // Principal which set the quota. Currently only operators can set quotas. + Principal *string `protobuf:"bytes,2,opt,name=principal" json:"principal,omitempty"` + // The guarantee that these resources are allocatable for the above role. + // NOTE: `guarantee.role` should not specify any role except '*', + // because quota does not reserve specific resources. + Guarantee []*mesos.Resource `protobuf:"bytes,3,rep,name=guarantee" json:"guarantee,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *QuotaInfo) Reset() { *m = QuotaInfo{} } +func (m *QuotaInfo) String() string { return proto.CompactTextString(m) } +func (*QuotaInfo) ProtoMessage() {} +func (*QuotaInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *QuotaInfo) GetRole() string { + if m != nil && m.Role != nil { + return *m.Role + } + return "" +} + +func (m *QuotaInfo) GetPrincipal() string { + if m != nil && m.Principal != nil { + return *m.Principal + } + return "" +} + +func (m *QuotaInfo) GetGuarantee() []*mesos.Resource { + if m != nil { + return m.Guarantee + } + return nil +} + +// * +// `QuotaRequest` provides a schema for set quota JSON requests. +type QuotaRequest struct { + // Disables the capacity heuristic check if set to `true`. + Force *bool `protobuf:"varint,1,opt,name=force,def=0" json:"force,omitempty"` + // The role for which to set quota. + Role *string `protobuf:"bytes,2,opt,name=role" json:"role,omitempty"` + // The requested guarantee that these resources will be allocatable for + // the above role. + Guarantee []*mesos.Resource `protobuf:"bytes,3,rep,name=guarantee" json:"guarantee,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *QuotaRequest) Reset() { *m = QuotaRequest{} } +func (m *QuotaRequest) String() string { return proto.CompactTextString(m) } +func (*QuotaRequest) ProtoMessage() {} +func (*QuotaRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +const Default_QuotaRequest_Force bool = false + +func (m *QuotaRequest) GetForce() bool { + if m != nil && m.Force != nil { + return *m.Force + } + return Default_QuotaRequest_Force +} + +func (m *QuotaRequest) GetRole() string { + if m != nil && m.Role != nil { + return *m.Role + } + return "" +} + +func (m *QuotaRequest) GetGuarantee() []*mesos.Resource { + if m != nil { + return m.Guarantee + } + return nil +} + +// * +// `QuotaStatus` describes the internal representation for the /quota/status +// response. +type QuotaStatus struct { + // Quotas which are currently set, i.e. known to the master. + Infos []*QuotaInfo `protobuf:"bytes,1,rep,name=infos" json:"infos,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *QuotaStatus) Reset() { *m = QuotaStatus{} } +func (m *QuotaStatus) String() string { return proto.CompactTextString(m) } +func (*QuotaStatus) ProtoMessage() {} +func (*QuotaStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *QuotaStatus) GetInfos() []*QuotaInfo { + if m != nil { + return m.Infos + } + return nil +} + +func init() { + proto.RegisterType((*QuotaInfo)(nil), "mesos.v1.quota.QuotaInfo") + proto.RegisterType((*QuotaRequest)(nil), "mesos.v1.quota.QuotaRequest") + proto.RegisterType((*QuotaStatus)(nil), "mesos.v1.quota.QuotaStatus") +} + +func init() { proto.RegisterFile("quota.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 234 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x90, 0x31, 0x4f, 0xc3, 0x30, + 0x10, 0x85, 0x95, 0x96, 0x20, 0x72, 0x41, 0x0c, 0x16, 0x43, 0x0a, 0x0c, 0x55, 0x59, 0x3a, 0x39, + 0x94, 0x91, 0x81, 0xa1, 0x1b, 0x1b, 0x98, 0x5f, 0x70, 0x8a, 0x2e, 0x25, 0x52, 0xc8, 0x25, 0x3e, + 0xbb, 0xbf, 0x1f, 0xf5, 0x22, 0x25, 0xc0, 0xd6, 0xcd, 0x7e, 0xef, 0x9d, 0xbe, 0xa7, 0x07, 0xf9, + 0x10, 0x39, 0xa0, 0xed, 0x3d, 0x07, 0x36, 0x37, 0xdf, 0x24, 0x2c, 0xf6, 0xb8, 0xb3, 0xaa, 0xde, + 0xdd, 0xea, 0xbf, 0x3c, 0xee, 0xca, 0xd1, 0xd0, 0xd4, 0x86, 0x21, 0xfb, 0x38, 0xd9, 0x6f, 0x5d, + 0xcd, 0xc6, 0xc0, 0x85, 0xe7, 0x96, 0x8a, 0x64, 0x9d, 0x6c, 0x33, 0xa7, 0x6f, 0xf3, 0x00, 0x59, + 0xef, 0x9b, 0xae, 0x6a, 0x7a, 0x6c, 0x8b, 0x85, 0x1a, 0xb3, 0x60, 0x9e, 0x20, 0x3b, 0x44, 0xf4, + 0xd8, 0x05, 0xa2, 0x62, 0xb9, 0x5e, 0x6e, 0xf3, 0x67, 0x63, 0x27, 0xb0, 0x23, 0xe1, 0xe8, 0x2b, + 0x72, 0x73, 0x68, 0x33, 0xc0, 0xb5, 0x02, 0x1d, 0x0d, 0x91, 0x24, 0x98, 0x7b, 0x48, 0x6b, 0xf6, + 0xd5, 0x08, 0xbd, 0x7a, 0x49, 0x6b, 0x6c, 0x85, 0xdc, 0xa8, 0x4d, 0x85, 0x16, 0xbf, 0x0a, 0x9d, + 0x8f, 0x7c, 0x85, 0x5c, 0x91, 0x9f, 0x01, 0x43, 0x14, 0x53, 0x42, 0xda, 0x74, 0x35, 0x4b, 0x91, + 0xe8, 0xf1, 0xca, 0xfe, 0x1d, 0xca, 0x4e, 0x7b, 0xb8, 0x31, 0xb7, 0x7f, 0x84, 0x15, 0xfb, 0x83, + 0xc5, 0x1e, 0xab, 0x2f, 0xfa, 0x97, 0xde, 0x5f, 0xbe, 0x9f, 0x76, 0x94, 0x9f, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x55, 0x0b, 0x2c, 0x31, 0x7c, 0x01, 0x00, 0x00, +} diff --git a/bcs-common/pkg/scheduler/mesosproto/sched/scheduler.pb.go b/bcs-common/pkg/scheduler/mesosproto/sched/scheduler.pb.go new file mode 100644 index 0000000000..82894008d6 --- /dev/null +++ b/bcs-common/pkg/scheduler/mesosproto/sched/scheduler.pb.go @@ -0,0 +1,1171 @@ +// Code generated by protoc-gen-go. +// source: scheduler.proto +// DO NOT EDIT! + +/* +Package mesos_scheduler is a generated protocol buffer package. + +It is generated from these files: + scheduler.proto + +It has these top-level messages: + Event + Call +*/ +package sched + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import mesos "bk-bcs/bcs-common/pkg/scheduler/mesosproto/mesos" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// Possible event types, followed by message definitions if +// applicable. +type Event_Type int32 + +const ( + // This must be the first enum value in this list, to + // ensure that if 'type' is not set, the default value + // is UNKNOWN. This enables enum values to be added + // in a backwards-compatible way. See: MESOS-4997. + Event_UNKNOWN Event_Type = 0 + Event_SUBSCRIBED Event_Type = 1 + Event_OFFERS Event_Type = 2 + Event_INVERSE_OFFERS Event_Type = 9 + Event_RESCIND Event_Type = 3 + Event_RESCIND_INVERSE_OFFER Event_Type = 10 + Event_UPDATE Event_Type = 4 + Event_MESSAGE Event_Type = 5 + Event_FAILURE Event_Type = 6 + Event_ERROR Event_Type = 7 + // Periodic message sent by the Mesos master according to + // 'Subscribed.heartbeat_interval_seconds'. If the scheduler does + // not receive any events (including heartbeats) for an extended + // period of time (e.g., 5 x heartbeat_interval_seconds), there is + // likely a network partition. In such a case the scheduler should + // close the existing subscription connection and resubscribe + // using a backoff strategy. + Event_HEARTBEAT Event_Type = 8 +) + +var Event_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "SUBSCRIBED", + 2: "OFFERS", + 9: "INVERSE_OFFERS", + 3: "RESCIND", + 10: "RESCIND_INVERSE_OFFER", + 4: "UPDATE", + 5: "MESSAGE", + 6: "FAILURE", + 7: "ERROR", + 8: "HEARTBEAT", +} +var Event_Type_value = map[string]int32{ + "UNKNOWN": 0, + "SUBSCRIBED": 1, + "OFFERS": 2, + "INVERSE_OFFERS": 9, + "RESCIND": 3, + "RESCIND_INVERSE_OFFER": 10, + "UPDATE": 4, + "MESSAGE": 5, + "FAILURE": 6, + "ERROR": 7, + "HEARTBEAT": 8, +} + +func (x Event_Type) Enum() *Event_Type { + p := new(Event_Type) + *p = x + return p +} +func (x Event_Type) String() string { + return proto.EnumName(Event_Type_name, int32(x)) +} +func (x *Event_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Event_Type_value, data, "Event_Type") + if err != nil { + return err + } + *x = Event_Type(value) + return nil +} +func (Event_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} } + +// Possible call types, followed by message definitions if +// applicable. +type Call_Type int32 + +const ( + // See comments above on `Event::Type` for more details on this enum value. + Call_UNKNOWN Call_Type = 0 + Call_SUBSCRIBE Call_Type = 1 + Call_TEARDOWN Call_Type = 2 + Call_ACCEPT Call_Type = 3 + Call_DECLINE Call_Type = 4 + Call_ACCEPT_INVERSE_OFFERS Call_Type = 13 + Call_DECLINE_INVERSE_OFFERS Call_Type = 14 + Call_REVIVE Call_Type = 5 + Call_KILL Call_Type = 6 + Call_SHUTDOWN Call_Type = 7 + Call_ACKNOWLEDGE Call_Type = 8 + Call_RECONCILE Call_Type = 9 + Call_MESSAGE Call_Type = 10 + Call_REQUEST Call_Type = 11 + Call_SUPPRESS Call_Type = 12 +) + +var Call_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "SUBSCRIBE", + 2: "TEARDOWN", + 3: "ACCEPT", + 4: "DECLINE", + 13: "ACCEPT_INVERSE_OFFERS", + 14: "DECLINE_INVERSE_OFFERS", + 5: "REVIVE", + 6: "KILL", + 7: "SHUTDOWN", + 8: "ACKNOWLEDGE", + 9: "RECONCILE", + 10: "MESSAGE", + 11: "REQUEST", + 12: "SUPPRESS", +} +var Call_Type_value = map[string]int32{ + "UNKNOWN": 0, + "SUBSCRIBE": 1, + "TEARDOWN": 2, + "ACCEPT": 3, + "DECLINE": 4, + "ACCEPT_INVERSE_OFFERS": 13, + "DECLINE_INVERSE_OFFERS": 14, + "REVIVE": 5, + "KILL": 6, + "SHUTDOWN": 7, + "ACKNOWLEDGE": 8, + "RECONCILE": 9, + "MESSAGE": 10, + "REQUEST": 11, + "SUPPRESS": 12, +} + +func (x Call_Type) Enum() *Call_Type { + p := new(Call_Type) + *p = x + return p +} +func (x Call_Type) String() string { + return proto.EnumName(Call_Type_name, int32(x)) +} +func (x *Call_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Call_Type_value, data, "Call_Type") + if err != nil { + return err + } + *x = Call_Type(value) + return nil +} +func (Call_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 0} } + +// * +// Scheduler event API. +// +// An event is described using the standard protocol buffer "union" +// trick, see: +// https://developers.google.com/protocol-buffers/docs/techniques#union. +type Event struct { + // Type of the event, indicates which optional field below should be + // present if that type has a nested message definition. + // Enum fields should be optional, see: MESOS-4997. + Type *Event_Type `protobuf:"varint,1,opt,name=type,enum=mesos.v1.scheduler.Event_Type" json:"type,omitempty"` + Subscribed *Event_Subscribed `protobuf:"bytes,2,opt,name=subscribed" json:"subscribed,omitempty"` + Offers *Event_Offers `protobuf:"bytes,3,opt,name=offers" json:"offers,omitempty"` + InverseOffers *Event_InverseOffers `protobuf:"bytes,9,opt,name=inverse_offers,json=inverseOffers" json:"inverse_offers,omitempty"` + Rescind *Event_Rescind `protobuf:"bytes,4,opt,name=rescind" json:"rescind,omitempty"` + RescindInverseOffer *Event_RescindInverseOffer `protobuf:"bytes,10,opt,name=rescind_inverse_offer,json=rescindInverseOffer" json:"rescind_inverse_offer,omitempty"` + Update *Event_Update `protobuf:"bytes,5,opt,name=update" json:"update,omitempty"` + Message *Event_Message `protobuf:"bytes,6,opt,name=message" json:"message,omitempty"` + Failure *Event_Failure `protobuf:"bytes,7,opt,name=failure" json:"failure,omitempty"` + Error *Event_Error `protobuf:"bytes,8,opt,name=error" json:"error,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event) Reset() { *m = Event{} } +func (m *Event) String() string { return proto.CompactTextString(m) } +func (*Event) ProtoMessage() {} +func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *Event) GetType() Event_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return Event_UNKNOWN +} + +func (m *Event) GetSubscribed() *Event_Subscribed { + if m != nil { + return m.Subscribed + } + return nil +} + +func (m *Event) GetOffers() *Event_Offers { + if m != nil { + return m.Offers + } + return nil +} + +func (m *Event) GetInverseOffers() *Event_InverseOffers { + if m != nil { + return m.InverseOffers + } + return nil +} + +func (m *Event) GetRescind() *Event_Rescind { + if m != nil { + return m.Rescind + } + return nil +} + +func (m *Event) GetRescindInverseOffer() *Event_RescindInverseOffer { + if m != nil { + return m.RescindInverseOffer + } + return nil +} + +func (m *Event) GetUpdate() *Event_Update { + if m != nil { + return m.Update + } + return nil +} + +func (m *Event) GetMessage() *Event_Message { + if m != nil { + return m.Message + } + return nil +} + +func (m *Event) GetFailure() *Event_Failure { + if m != nil { + return m.Failure + } + return nil +} + +func (m *Event) GetError() *Event_Error { + if m != nil { + return m.Error + } + return nil +} + +// First event received when the scheduler subscribes. +type Event_Subscribed struct { + FrameworkId *mesos.FrameworkID `protobuf:"bytes,1,req,name=framework_id,json=frameworkId" json:"framework_id,omitempty"` + // This value will be set if the master is sending heartbeats. See + // the comment above on 'HEARTBEAT' for more details. + HeartbeatIntervalSeconds *float64 `protobuf:"fixed64,2,opt,name=heartbeat_interval_seconds,json=heartbeatIntervalSeconds" json:"heartbeat_interval_seconds,omitempty"` + // Since Mesos 1.1. + MasterInfo *mesos.MasterInfo `protobuf:"bytes,3,opt,name=master_info,json=masterInfo" json:"master_info,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event_Subscribed) Reset() { *m = Event_Subscribed{} } +func (m *Event_Subscribed) String() string { return proto.CompactTextString(m) } +func (*Event_Subscribed) ProtoMessage() {} +func (*Event_Subscribed) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} } + +func (m *Event_Subscribed) GetFrameworkId() *mesos.FrameworkID { + if m != nil { + return m.FrameworkId + } + return nil +} + +func (m *Event_Subscribed) GetHeartbeatIntervalSeconds() float64 { + if m != nil && m.HeartbeatIntervalSeconds != nil { + return *m.HeartbeatIntervalSeconds + } + return 0 +} + +func (m *Event_Subscribed) GetMasterInfo() *mesos.MasterInfo { + if m != nil { + return m.MasterInfo + } + return nil +} + +// Received whenever there are new resources that are offered to the +// scheduler. Each offer corresponds to a set of resources on an +// agent. Until the scheduler accepts or declines an offer the +// resources are considered allocated to the scheduler. +type Event_Offers struct { + Offers []*mesos.Offer `protobuf:"bytes,1,rep,name=offers" json:"offers,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event_Offers) Reset() { *m = Event_Offers{} } +func (m *Event_Offers) String() string { return proto.CompactTextString(m) } +func (*Event_Offers) ProtoMessage() {} +func (*Event_Offers) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 1} } + +func (m *Event_Offers) GetOffers() []*mesos.Offer { + if m != nil { + return m.Offers + } + return nil +} + +// Received whenever there are resources requested back from the +// scheduler. Each inverse offer specifies the agent, and +// optionally specific resources. Accepting or Declining an inverse +// offer informs the allocator of the scheduler's ability to release +// the specified resources without violating an SLA. If no resources +// are specified then all resources on the agent are requested to be +// released. +type Event_InverseOffers struct { + InverseOffers []*mesos.InverseOffer `protobuf:"bytes,1,rep,name=inverse_offers,json=inverseOffers" json:"inverse_offers,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event_InverseOffers) Reset() { *m = Event_InverseOffers{} } +func (m *Event_InverseOffers) String() string { return proto.CompactTextString(m) } +func (*Event_InverseOffers) ProtoMessage() {} +func (*Event_InverseOffers) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 2} } + +func (m *Event_InverseOffers) GetInverseOffers() []*mesos.InverseOffer { + if m != nil { + return m.InverseOffers + } + return nil +} + +// Received when a particular offer is no longer valid (e.g., the +// agent corresponding to the offer has been removed) and hence +// needs to be rescinded. Any future calls ('Accept' / 'Decline') made +// by the scheduler regarding this offer will be invalid. +type Event_Rescind struct { + OfferId *mesos.OfferID `protobuf:"bytes,1,req,name=offer_id,json=offerId" json:"offer_id,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event_Rescind) Reset() { *m = Event_Rescind{} } +func (m *Event_Rescind) String() string { return proto.CompactTextString(m) } +func (*Event_Rescind) ProtoMessage() {} +func (*Event_Rescind) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 3} } + +func (m *Event_Rescind) GetOfferId() *mesos.OfferID { + if m != nil { + return m.OfferId + } + return nil +} + +// Received when a particular inverse offer is no longer valid +// (e.g., the agent corresponding to the offer has been removed) +// and hence needs to be rescinded. Any future calls ('Accept' / +// 'Decline') made by the scheduler regarding this inverse offer +// will be invalid. +type Event_RescindInverseOffer struct { + InverseOfferId *mesos.OfferID `protobuf:"bytes,1,req,name=inverse_offer_id,json=inverseOfferId" json:"inverse_offer_id,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event_RescindInverseOffer) Reset() { *m = Event_RescindInverseOffer{} } +func (m *Event_RescindInverseOffer) String() string { return proto.CompactTextString(m) } +func (*Event_RescindInverseOffer) ProtoMessage() {} +func (*Event_RescindInverseOffer) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 4} } + +func (m *Event_RescindInverseOffer) GetInverseOfferId() *mesos.OfferID { + if m != nil { + return m.InverseOfferId + } + return nil +} + +// Received whenever there is a status update that is generated by +// the executor or agent or master. Status updates should be used by +// executors to reliably communicate the status of the tasks that +// they manage. It is crucial that a terminal update (see TaskState +// in v1/mesos.proto) is sent by the executor as soon as the task +// terminates, in order for Mesos to release the resources allocated +// to the task. It is also the responsibility of the scheduler to +// explicitly acknowledge the receipt of a status update. See +// 'Acknowledge' in the 'Call' section below for the semantics. +type Event_Update struct { + Status *mesos.TaskStatus `protobuf:"bytes,1,req,name=status" json:"status,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event_Update) Reset() { *m = Event_Update{} } +func (m *Event_Update) String() string { return proto.CompactTextString(m) } +func (*Event_Update) ProtoMessage() {} +func (*Event_Update) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 5} } + +func (m *Event_Update) GetStatus() *mesos.TaskStatus { + if m != nil { + return m.Status + } + return nil +} + +// Received when a custom message generated by the executor is +// forwarded by the master. Note that this message is not +// interpreted by Mesos and is only forwarded (without reliability +// guarantees) to the scheduler. It is up to the executor to retry +// if the message is dropped for any reason. +type Event_Message struct { + AgentId *mesos.AgentID `protobuf:"bytes,1,req,name=agent_id,json=agentId" json:"agent_id,omitempty"` + ExecutorId *mesos.ExecutorID `protobuf:"bytes,2,req,name=executor_id,json=executorId" json:"executor_id,omitempty"` + Data []byte `protobuf:"bytes,3,req,name=data" json:"data,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event_Message) Reset() { *m = Event_Message{} } +func (m *Event_Message) String() string { return proto.CompactTextString(m) } +func (*Event_Message) ProtoMessage() {} +func (*Event_Message) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 6} } + +func (m *Event_Message) GetAgentId() *mesos.AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *Event_Message) GetExecutorId() *mesos.ExecutorID { + if m != nil { + return m.ExecutorId + } + return nil +} + +func (m *Event_Message) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +// Received when an agent is removed from the cluster (e.g., failed +// health checks) or when an executor is terminated. Note that, this +// event coincides with receipt of terminal UPDATE events for any +// active tasks belonging to the agent or executor and receipt of +// 'Rescind' events for any outstanding offers belonging to the +// agent. Note that there is no guaranteed order between the +// 'Failure', 'Update' and 'Rescind' events when an agent or executor +// is removed. +// TODO(vinod): Consider splitting the lost agent and terminated +// executor into separate events and ensure it's reliably generated. +type Event_Failure struct { + AgentId *mesos.AgentID `protobuf:"bytes,1,opt,name=agent_id,json=agentId" json:"agent_id,omitempty"` + // If this was just a failure of an executor on an agent then + // 'executor_id' will be set and possibly 'status' (if we were + // able to determine the exit status). + ExecutorId *mesos.ExecutorID `protobuf:"bytes,2,opt,name=executor_id,json=executorId" json:"executor_id,omitempty"` + Status *int32 `protobuf:"varint,3,opt,name=status" json:"status,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event_Failure) Reset() { *m = Event_Failure{} } +func (m *Event_Failure) String() string { return proto.CompactTextString(m) } +func (*Event_Failure) ProtoMessage() {} +func (*Event_Failure) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 7} } + +func (m *Event_Failure) GetAgentId() *mesos.AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *Event_Failure) GetExecutorId() *mesos.ExecutorID { + if m != nil { + return m.ExecutorId + } + return nil +} + +func (m *Event_Failure) GetStatus() int32 { + if m != nil && m.Status != nil { + return *m.Status + } + return 0 +} + +// Received when there is an unrecoverable error in the scheduler (e.g., +// scheduler failed over, rate limiting, authorization errors etc.). The +// scheduler should abort on receiving this event. +type Event_Error struct { + Message *string `protobuf:"bytes,1,req,name=message" json:"message,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Event_Error) Reset() { *m = Event_Error{} } +func (m *Event_Error) String() string { return proto.CompactTextString(m) } +func (*Event_Error) ProtoMessage() {} +func (*Event_Error) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 8} } + +func (m *Event_Error) GetMessage() string { + if m != nil && m.Message != nil { + return *m.Message + } + return "" +} + +// * +// Scheduler call API. +// +// Like Event, a Call is described using the standard protocol buffer +// "union" trick (see above). +type Call struct { + // Identifies who generated this call. Master assigns a framework id + // when a new scheduler subscribes for the first time. Once assigned, + // the scheduler must set the 'framework_id' here and within its + // FrameworkInfo (in any further 'Subscribe' calls). This allows the + // master to identify a scheduler correctly across disconnections, + // failovers, etc. + FrameworkId *mesos.FrameworkID `protobuf:"bytes,1,opt,name=framework_id,json=frameworkId" json:"framework_id,omitempty"` + // Type of the call, indicates which optional field below should be + // present if that type has a nested message definition. + // See comments on `Event::Type` above on the reasoning behind this field being optional. + Type *Call_Type `protobuf:"varint,2,opt,name=type,enum=mesos.v1.scheduler.Call_Type" json:"type,omitempty"` + Subscribe *Call_Subscribe `protobuf:"bytes,3,opt,name=subscribe" json:"subscribe,omitempty"` + Accept *Call_Accept `protobuf:"bytes,4,opt,name=accept" json:"accept,omitempty"` + Decline *Call_Decline `protobuf:"bytes,5,opt,name=decline" json:"decline,omitempty"` + AcceptInverseOffers *Call_AcceptInverseOffers `protobuf:"bytes,13,opt,name=accept_inverse_offers,json=acceptInverseOffers" json:"accept_inverse_offers,omitempty"` + DeclineInverseOffers *Call_DeclineInverseOffers `protobuf:"bytes,14,opt,name=decline_inverse_offers,json=declineInverseOffers" json:"decline_inverse_offers,omitempty"` + Kill *Call_Kill `protobuf:"bytes,6,opt,name=kill" json:"kill,omitempty"` + Shutdown *Call_Shutdown `protobuf:"bytes,7,opt,name=shutdown" json:"shutdown,omitempty"` + Acknowledge *Call_Acknowledge `protobuf:"bytes,8,opt,name=acknowledge" json:"acknowledge,omitempty"` + Reconcile *Call_Reconcile `protobuf:"bytes,9,opt,name=reconcile" json:"reconcile,omitempty"` + Message *Call_Message `protobuf:"bytes,10,opt,name=message" json:"message,omitempty"` + Request *Call_Request `protobuf:"bytes,11,opt,name=request" json:"request,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call) Reset() { *m = Call{} } +func (m *Call) String() string { return proto.CompactTextString(m) } +func (*Call) ProtoMessage() {} +func (*Call) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *Call) GetFrameworkId() *mesos.FrameworkID { + if m != nil { + return m.FrameworkId + } + return nil +} + +func (m *Call) GetType() Call_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return Call_UNKNOWN +} + +func (m *Call) GetSubscribe() *Call_Subscribe { + if m != nil { + return m.Subscribe + } + return nil +} + +func (m *Call) GetAccept() *Call_Accept { + if m != nil { + return m.Accept + } + return nil +} + +func (m *Call) GetDecline() *Call_Decline { + if m != nil { + return m.Decline + } + return nil +} + +func (m *Call) GetAcceptInverseOffers() *Call_AcceptInverseOffers { + if m != nil { + return m.AcceptInverseOffers + } + return nil +} + +func (m *Call) GetDeclineInverseOffers() *Call_DeclineInverseOffers { + if m != nil { + return m.DeclineInverseOffers + } + return nil +} + +func (m *Call) GetKill() *Call_Kill { + if m != nil { + return m.Kill + } + return nil +} + +func (m *Call) GetShutdown() *Call_Shutdown { + if m != nil { + return m.Shutdown + } + return nil +} + +func (m *Call) GetAcknowledge() *Call_Acknowledge { + if m != nil { + return m.Acknowledge + } + return nil +} + +func (m *Call) GetReconcile() *Call_Reconcile { + if m != nil { + return m.Reconcile + } + return nil +} + +func (m *Call) GetMessage() *Call_Message { + if m != nil { + return m.Message + } + return nil +} + +func (m *Call) GetRequest() *Call_Request { + if m != nil { + return m.Request + } + return nil +} + +// Subscribes the scheduler with the master to receive events. A +// scheduler must send other calls only after it has received the +// SUBCRIBED event. +type Call_Subscribe struct { + // See the comments below on 'framework_id' on the semantics for + // 'framework_info.id'. + FrameworkInfo *mesos.FrameworkInfo `protobuf:"bytes,1,req,name=framework_info,json=frameworkInfo" json:"framework_info,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_Subscribe) Reset() { *m = Call_Subscribe{} } +func (m *Call_Subscribe) String() string { return proto.CompactTextString(m) } +func (*Call_Subscribe) ProtoMessage() {} +func (*Call_Subscribe) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 0} } + +func (m *Call_Subscribe) GetFrameworkInfo() *mesos.FrameworkInfo { + if m != nil { + return m.FrameworkInfo + } + return nil +} + +// Accepts an offer, performing the specified operations +// in a sequential manner. +// +// E.g. Launch a task with a newly reserved persistent volume: +// +// Accept { +// offer_ids: [ ... ] +// operations: [ +// { type: RESERVE, +// reserve: { resources: [ disk(role):2 ] } } +// { type: CREATE, +// create: { volumes: [ disk(role):1+persistence ] } } +// { type: LAUNCH, +// launch: { task_infos ... disk(role):1;disk(role):1+persistence } } +// ] +// } +// +// Note that any of the offer’s resources not used in the 'Accept' +// call (e.g., to launch a task) are considered unused and might be +// reoffered to other frameworks. In other words, the same OfferID +// cannot be used in more than one 'Accept' call. +type Call_Accept struct { + OfferIds []*mesos.OfferID `protobuf:"bytes,1,rep,name=offer_ids,json=offerIds" json:"offer_ids,omitempty"` + Operations []*mesos.Offer_Operation `protobuf:"bytes,2,rep,name=operations" json:"operations,omitempty"` + Filters *mesos.Filters `protobuf:"bytes,3,opt,name=filters" json:"filters,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_Accept) Reset() { *m = Call_Accept{} } +func (m *Call_Accept) String() string { return proto.CompactTextString(m) } +func (*Call_Accept) ProtoMessage() {} +func (*Call_Accept) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 1} } + +func (m *Call_Accept) GetOfferIds() []*mesos.OfferID { + if m != nil { + return m.OfferIds + } + return nil +} + +func (m *Call_Accept) GetOperations() []*mesos.Offer_Operation { + if m != nil { + return m.Operations + } + return nil +} + +func (m *Call_Accept) GetFilters() *mesos.Filters { + if m != nil { + return m.Filters + } + return nil +} + +// Declines an offer, signaling the master to potentially reoffer +// the resources to a different framework. Note that this is same +// as sending an Accept call with no operations. See comments on +// top of 'Accept' for semantics. +type Call_Decline struct { + OfferIds []*mesos.OfferID `protobuf:"bytes,1,rep,name=offer_ids,json=offerIds" json:"offer_ids,omitempty"` + Filters *mesos.Filters `protobuf:"bytes,2,opt,name=filters" json:"filters,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_Decline) Reset() { *m = Call_Decline{} } +func (m *Call_Decline) String() string { return proto.CompactTextString(m) } +func (*Call_Decline) ProtoMessage() {} +func (*Call_Decline) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 2} } + +func (m *Call_Decline) GetOfferIds() []*mesos.OfferID { + if m != nil { + return m.OfferIds + } + return nil +} + +func (m *Call_Decline) GetFilters() *mesos.Filters { + if m != nil { + return m.Filters + } + return nil +} + +// Accepts an inverse offer. Inverse offers should only be accepted +// if the resources in the offer can be safely evacuated before the +// provided unavailability. +type Call_AcceptInverseOffers struct { + InverseOfferIds []*mesos.OfferID `protobuf:"bytes,1,rep,name=inverse_offer_ids,json=inverseOfferIds" json:"inverse_offer_ids,omitempty"` + Filters *mesos.Filters `protobuf:"bytes,2,opt,name=filters" json:"filters,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_AcceptInverseOffers) Reset() { *m = Call_AcceptInverseOffers{} } +func (m *Call_AcceptInverseOffers) String() string { return proto.CompactTextString(m) } +func (*Call_AcceptInverseOffers) ProtoMessage() {} +func (*Call_AcceptInverseOffers) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 3} } + +func (m *Call_AcceptInverseOffers) GetInverseOfferIds() []*mesos.OfferID { + if m != nil { + return m.InverseOfferIds + } + return nil +} + +func (m *Call_AcceptInverseOffers) GetFilters() *mesos.Filters { + if m != nil { + return m.Filters + } + return nil +} + +// Declines an inverse offer. Inverse offers should be declined if +// the resources in the offer might not be safely evacuated before +// the provided unavailability. +type Call_DeclineInverseOffers struct { + InverseOfferIds []*mesos.OfferID `protobuf:"bytes,1,rep,name=inverse_offer_ids,json=inverseOfferIds" json:"inverse_offer_ids,omitempty"` + Filters *mesos.Filters `protobuf:"bytes,2,opt,name=filters" json:"filters,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_DeclineInverseOffers) Reset() { *m = Call_DeclineInverseOffers{} } +func (m *Call_DeclineInverseOffers) String() string { return proto.CompactTextString(m) } +func (*Call_DeclineInverseOffers) ProtoMessage() {} +func (*Call_DeclineInverseOffers) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 4} } + +func (m *Call_DeclineInverseOffers) GetInverseOfferIds() []*mesos.OfferID { + if m != nil { + return m.InverseOfferIds + } + return nil +} + +func (m *Call_DeclineInverseOffers) GetFilters() *mesos.Filters { + if m != nil { + return m.Filters + } + return nil +} + +// Kills a specific task. If the scheduler has a custom executor, +// the kill is forwarded to the executor and it is up to the +// executor to kill the task and send a TASK_KILLED (or TASK_FAILED) +// update. Note that Mesos releases the resources for a task once it +// receives a terminal update (See TaskState in v1/mesos.proto) for +// it. If the task is unknown to the master, a TASK_LOST update is +// generated. +// +// If a task within a task group is killed before the group is +// delivered to the executor, all tasks in the task group are +// killed. When a task group has been delivered to the executor, +// it is up to the executor to decide how to deal with the kill. +// Note The default Mesos executor will currently kill all the +// tasks in the task group if it gets a kill for any task. +type Call_Kill struct { + TaskId *mesos.TaskID `protobuf:"bytes,1,req,name=task_id,json=taskId" json:"task_id,omitempty"` + AgentId *mesos.AgentID `protobuf:"bytes,2,opt,name=agent_id,json=agentId" json:"agent_id,omitempty"` + // If set, overrides any previously specified kill policy for this task. + // This includes 'TaskInfo.kill_policy' and 'Executor.kill.kill_policy'. + // Can be used to forcefully kill a task which is already being killed. + KillPolicy *mesos.KillPolicy `protobuf:"bytes,3,opt,name=kill_policy,json=killPolicy" json:"kill_policy,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_Kill) Reset() { *m = Call_Kill{} } +func (m *Call_Kill) String() string { return proto.CompactTextString(m) } +func (*Call_Kill) ProtoMessage() {} +func (*Call_Kill) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 5} } + +func (m *Call_Kill) GetTaskId() *mesos.TaskID { + if m != nil { + return m.TaskId + } + return nil +} + +func (m *Call_Kill) GetAgentId() *mesos.AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *Call_Kill) GetKillPolicy() *mesos.KillPolicy { + if m != nil { + return m.KillPolicy + } + return nil +} + +// Shuts down a custom executor. When the executor gets a shutdown +// event, it is expected to kill all its tasks (and send TASK_KILLED +// updates) and terminate. If the executor doesn’t terminate within +// a certain timeout (configurable via +// '--executor_shutdown_grace_period' agent flag), the agent will +// forcefully destroy the container (executor and its tasks) and +// transition its active tasks to TASK_LOST. +type Call_Shutdown struct { + ExecutorId *mesos.ExecutorID `protobuf:"bytes,1,req,name=executor_id,json=executorId" json:"executor_id,omitempty"` + AgentId *mesos.AgentID `protobuf:"bytes,2,req,name=agent_id,json=agentId" json:"agent_id,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_Shutdown) Reset() { *m = Call_Shutdown{} } +func (m *Call_Shutdown) String() string { return proto.CompactTextString(m) } +func (*Call_Shutdown) ProtoMessage() {} +func (*Call_Shutdown) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 6} } + +func (m *Call_Shutdown) GetExecutorId() *mesos.ExecutorID { + if m != nil { + return m.ExecutorId + } + return nil +} + +func (m *Call_Shutdown) GetAgentId() *mesos.AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +// Acknowledges the receipt of status update. Schedulers are +// responsible for explicitly acknowledging the receipt of status +// updates that have 'Update.status().uuid()' field set. Such status +// updates are retried by the agent until they are acknowledged by +// the scheduler. +type Call_Acknowledge struct { + AgentId *mesos.AgentID `protobuf:"bytes,1,req,name=agent_id,json=agentId" json:"agent_id,omitempty"` + TaskId *mesos.TaskID `protobuf:"bytes,2,req,name=task_id,json=taskId" json:"task_id,omitempty"` + Uuid []byte `protobuf:"bytes,3,req,name=uuid" json:"uuid,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_Acknowledge) Reset() { *m = Call_Acknowledge{} } +func (m *Call_Acknowledge) String() string { return proto.CompactTextString(m) } +func (*Call_Acknowledge) ProtoMessage() {} +func (*Call_Acknowledge) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 7} } + +func (m *Call_Acknowledge) GetAgentId() *mesos.AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *Call_Acknowledge) GetTaskId() *mesos.TaskID { + if m != nil { + return m.TaskId + } + return nil +} + +func (m *Call_Acknowledge) GetUuid() []byte { + if m != nil { + return m.Uuid + } + return nil +} + +// Allows the scheduler to query the status for non-terminal tasks. +// This causes the master to send back the latest task status for +// each task in 'tasks', if possible. Tasks that are no longer known +// will result in a TASK_LOST update. If 'statuses' is empty, then +// the master will send the latest status for each task currently +// known. +type Call_Reconcile struct { + Tasks []*Call_Reconcile_Task `protobuf:"bytes,1,rep,name=tasks" json:"tasks,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_Reconcile) Reset() { *m = Call_Reconcile{} } +func (m *Call_Reconcile) String() string { return proto.CompactTextString(m) } +func (*Call_Reconcile) ProtoMessage() {} +func (*Call_Reconcile) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 8} } + +func (m *Call_Reconcile) GetTasks() []*Call_Reconcile_Task { + if m != nil { + return m.Tasks + } + return nil +} + +// TODO(vinod): Support arbitrary queries than just state of tasks. +type Call_Reconcile_Task struct { + TaskId *mesos.TaskID `protobuf:"bytes,1,req,name=task_id,json=taskId" json:"task_id,omitempty"` + AgentId *mesos.AgentID `protobuf:"bytes,2,opt,name=agent_id,json=agentId" json:"agent_id,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_Reconcile_Task) Reset() { *m = Call_Reconcile_Task{} } +func (m *Call_Reconcile_Task) String() string { return proto.CompactTextString(m) } +func (*Call_Reconcile_Task) ProtoMessage() {} +func (*Call_Reconcile_Task) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 8, 0} } + +func (m *Call_Reconcile_Task) GetTaskId() *mesos.TaskID { + if m != nil { + return m.TaskId + } + return nil +} + +func (m *Call_Reconcile_Task) GetAgentId() *mesos.AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +// Sends arbitrary binary data to the executor. Note that Mesos +// neither interprets this data nor makes any guarantees about the +// delivery of this message to the executor. +type Call_Message struct { + AgentId *mesos.AgentID `protobuf:"bytes,1,req,name=agent_id,json=agentId" json:"agent_id,omitempty"` + ExecutorId *mesos.ExecutorID `protobuf:"bytes,2,req,name=executor_id,json=executorId" json:"executor_id,omitempty"` + Data []byte `protobuf:"bytes,3,req,name=data" json:"data,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_Message) Reset() { *m = Call_Message{} } +func (m *Call_Message) String() string { return proto.CompactTextString(m) } +func (*Call_Message) ProtoMessage() {} +func (*Call_Message) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 9} } + +func (m *Call_Message) GetAgentId() *mesos.AgentID { + if m != nil { + return m.AgentId + } + return nil +} + +func (m *Call_Message) GetExecutorId() *mesos.ExecutorID { + if m != nil { + return m.ExecutorId + } + return nil +} + +func (m *Call_Message) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +// Requests a specific set of resources from Mesos's allocator. If +// the allocator has support for this, corresponding offers will be +// sent asynchronously via the OFFERS event(s). +// +// NOTE: The built-in hierarchical allocator doesn't have support +// for this call and hence simply ignores it. +type Call_Request struct { + Requests []*mesos.Request `protobuf:"bytes,1,rep,name=requests" json:"requests,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Call_Request) Reset() { *m = Call_Request{} } +func (m *Call_Request) String() string { return proto.CompactTextString(m) } +func (*Call_Request) ProtoMessage() {} +func (*Call_Request) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 10} } + +func (m *Call_Request) GetRequests() []*mesos.Request { + if m != nil { + return m.Requests + } + return nil +} + +func init() { + proto.RegisterType((*Event)(nil), "mesos.v1.scheduler.Event") + proto.RegisterType((*Event_Subscribed)(nil), "mesos.v1.scheduler.Event.Subscribed") + proto.RegisterType((*Event_Offers)(nil), "mesos.v1.scheduler.Event.Offers") + proto.RegisterType((*Event_InverseOffers)(nil), "mesos.v1.scheduler.Event.InverseOffers") + proto.RegisterType((*Event_Rescind)(nil), "mesos.v1.scheduler.Event.Rescind") + proto.RegisterType((*Event_RescindInverseOffer)(nil), "mesos.v1.scheduler.Event.RescindInverseOffer") + proto.RegisterType((*Event_Update)(nil), "mesos.v1.scheduler.Event.Update") + proto.RegisterType((*Event_Message)(nil), "mesos.v1.scheduler.Event.Message") + proto.RegisterType((*Event_Failure)(nil), "mesos.v1.scheduler.Event.Failure") + proto.RegisterType((*Event_Error)(nil), "mesos.v1.scheduler.Event.Error") + proto.RegisterType((*Call)(nil), "mesos.v1.scheduler.Call") + proto.RegisterType((*Call_Subscribe)(nil), "mesos.v1.scheduler.Call.Subscribe") + proto.RegisterType((*Call_Accept)(nil), "mesos.v1.scheduler.Call.Accept") + proto.RegisterType((*Call_Decline)(nil), "mesos.v1.scheduler.Call.Decline") + proto.RegisterType((*Call_AcceptInverseOffers)(nil), "mesos.v1.scheduler.Call.AcceptInverseOffers") + proto.RegisterType((*Call_DeclineInverseOffers)(nil), "mesos.v1.scheduler.Call.DeclineInverseOffers") + proto.RegisterType((*Call_Kill)(nil), "mesos.v1.scheduler.Call.Kill") + proto.RegisterType((*Call_Shutdown)(nil), "mesos.v1.scheduler.Call.Shutdown") + proto.RegisterType((*Call_Acknowledge)(nil), "mesos.v1.scheduler.Call.Acknowledge") + proto.RegisterType((*Call_Reconcile)(nil), "mesos.v1.scheduler.Call.Reconcile") + proto.RegisterType((*Call_Reconcile_Task)(nil), "mesos.v1.scheduler.Call.Reconcile.Task") + proto.RegisterType((*Call_Message)(nil), "mesos.v1.scheduler.Call.Message") + proto.RegisterType((*Call_Request)(nil), "mesos.v1.scheduler.Call.Request") + proto.RegisterEnum("mesos.v1.scheduler.Event_Type", Event_Type_name, Event_Type_value) + proto.RegisterEnum("mesos.v1.scheduler.Call_Type", Call_Type_name, Call_Type_value) +} + +func init() { proto.RegisterFile("scheduler.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 1379 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x56, 0xc1, 0x6e, 0xdb, 0x46, + 0x10, 0x2d, 0x65, 0x49, 0x94, 0x46, 0x96, 0xcc, 0xac, 0x63, 0x97, 0x21, 0x90, 0xc6, 0x31, 0x02, + 0xd8, 0x45, 0x13, 0x01, 0x31, 0x90, 0x26, 0x4d, 0xea, 0xa2, 0xb2, 0xb4, 0x4a, 0x08, 0x3b, 0xb2, + 0xbb, 0x94, 0xd2, 0xa3, 0xca, 0x90, 0x2b, 0x9b, 0x30, 0x2d, 0xaa, 0x24, 0xe5, 0x34, 0xbd, 0x35, + 0x87, 0x7e, 0x42, 0xcf, 0x3d, 0x16, 0xc8, 0x27, 0xf4, 0x97, 0xfa, 0x07, 0xbd, 0x14, 0xbb, 0x5c, + 0x52, 0x94, 0x44, 0x59, 0xf6, 0xa1, 0x45, 0x6f, 0x24, 0xe7, 0xbd, 0x99, 0xe1, 0xee, 0xcc, 0xbc, + 0x81, 0xb5, 0xc0, 0x3a, 0xa3, 0xf6, 0xd8, 0xa5, 0x7e, 0x7d, 0xe4, 0x7b, 0xa1, 0x87, 0xd0, 0x05, + 0x0d, 0xbc, 0xa0, 0x7e, 0xf9, 0xb8, 0x9e, 0x58, 0xb4, 0x4a, 0xf4, 0x8d, 0x03, 0xb6, 0xff, 0x5e, + 0x85, 0x02, 0xbe, 0xa4, 0xc3, 0x10, 0xed, 0x41, 0x3e, 0x7c, 0x3f, 0xa2, 0xaa, 0xb4, 0x25, 0xed, + 0xd6, 0xf6, 0x3e, 0xab, 0xcf, 0x33, 0xeb, 0x1c, 0x58, 0xef, 0xbe, 0x1f, 0x51, 0xc2, 0xb1, 0xa8, + 0x05, 0x10, 0x8c, 0xdf, 0x06, 0x96, 0xef, 0xbc, 0xa5, 0xb6, 0x9a, 0xdb, 0x92, 0x76, 0x2b, 0x7b, + 0x0f, 0x16, 0x33, 0x8d, 0x04, 0x4b, 0x52, 0x3c, 0xf4, 0x0c, 0x8a, 0xde, 0x60, 0x40, 0xfd, 0x40, + 0x5d, 0xe1, 0x1e, 0xb6, 0x16, 0x7b, 0x38, 0xe6, 0x38, 0x22, 0xf0, 0xa8, 0x03, 0x35, 0x67, 0x78, + 0x49, 0xfd, 0x80, 0xf6, 0x85, 0x87, 0x32, 0xf7, 0xb0, 0xb3, 0xd8, 0x83, 0x1e, 0xe1, 0x85, 0xa3, + 0xaa, 0x93, 0x7e, 0x45, 0x2f, 0x40, 0xf6, 0x69, 0x60, 0x39, 0x43, 0x5b, 0xcd, 0x73, 0x47, 0xf7, + 0x17, 0x3b, 0x22, 0x11, 0x90, 0xc4, 0x0c, 0x64, 0xc2, 0x86, 0x78, 0xec, 0x4f, 0x25, 0xa5, 0x02, + 0x77, 0xf5, 0x68, 0xa9, 0xab, 0x74, 0x6a, 0x64, 0xdd, 0x9f, 0xff, 0xc8, 0x4e, 0x6a, 0x3c, 0xb2, + 0xcd, 0x90, 0xaa, 0x85, 0x65, 0x27, 0xd5, 0xe3, 0x38, 0x22, 0xf0, 0xec, 0xcf, 0x2e, 0x68, 0x10, + 0x98, 0xa7, 0x54, 0x2d, 0x2e, 0xfb, 0xb3, 0xd7, 0x11, 0x90, 0xc4, 0x0c, 0x46, 0x1e, 0x98, 0x8e, + 0x3b, 0xf6, 0xa9, 0x2a, 0x2f, 0x23, 0xb7, 0x23, 0x20, 0x89, 0x19, 0xe8, 0x09, 0x14, 0xa8, 0xef, + 0x7b, 0xbe, 0x5a, 0xe2, 0xd4, 0x7b, 0x8b, 0xa9, 0x98, 0xc1, 0x48, 0x84, 0xd6, 0xfe, 0x94, 0x00, + 0x8c, 0x74, 0x8d, 0xac, 0x0e, 0x7c, 0xf3, 0x82, 0xbe, 0xf3, 0xfc, 0xf3, 0xbe, 0x63, 0xab, 0xd2, + 0x56, 0x6e, 0xb7, 0xb2, 0xb7, 0x31, 0x71, 0xd6, 0x8e, 0xad, 0x7a, 0x8b, 0x54, 0x12, 0xa8, 0x6e, + 0xa3, 0xaf, 0x41, 0x3b, 0xa3, 0xa6, 0x1f, 0xbe, 0xa5, 0x66, 0xd8, 0x77, 0x86, 0x21, 0xf5, 0x2f, + 0x4d, 0xb7, 0x1f, 0x50, 0xcb, 0x1b, 0xda, 0x01, 0xaf, 0x59, 0x89, 0xa8, 0x09, 0x42, 0x17, 0x00, + 0x23, 0xb2, 0xa3, 0x27, 0x50, 0xb9, 0x30, 0x83, 0x90, 0xfa, 0x7d, 0x67, 0x38, 0xf0, 0x44, 0x81, + 0xde, 0x9e, 0x84, 0x7d, 0xcd, 0x8d, 0xfa, 0x70, 0xe0, 0x11, 0xb8, 0x48, 0x9e, 0xb5, 0xc7, 0x50, + 0x14, 0x25, 0xb5, 0x93, 0x14, 0xb7, 0xb4, 0xb5, 0xb2, 0x5b, 0xd9, 0x5b, 0x9b, 0x70, 0xa3, 0x8b, + 0x16, 0x66, 0xad, 0x03, 0xd5, 0xa9, 0xda, 0x44, 0xfb, 0x73, 0xc5, 0x1d, 0x79, 0xd8, 0x9c, 0x78, + 0x98, 0xaa, 0x98, 0xe9, 0x5a, 0xd6, 0x9e, 0x82, 0x2c, 0xea, 0x0a, 0x3d, 0x84, 0x12, 0xf7, 0x30, + 0x39, 0xb8, 0x5b, 0x33, 0x59, 0xe8, 0x2d, 0x22, 0x73, 0x88, 0x6e, 0x6b, 0x04, 0xd6, 0x33, 0x0a, + 0x12, 0xbd, 0x00, 0x65, 0x2a, 0x9d, 0x2b, 0x9d, 0xd5, 0xd2, 0xb9, 0xe8, 0xb6, 0xf6, 0x25, 0x14, + 0xa3, 0x82, 0x44, 0x0f, 0xa1, 0x18, 0x84, 0x66, 0x38, 0x0e, 0x04, 0x39, 0x75, 0x96, 0x5d, 0x33, + 0x38, 0x37, 0xb8, 0x8d, 0x08, 0x8c, 0xf6, 0x41, 0x02, 0x59, 0x94, 0x23, 0xfb, 0x0b, 0xf3, 0x94, + 0x0e, 0xc3, 0xcc, 0xc0, 0x0d, 0x66, 0x61, 0x7f, 0xc1, 0x21, 0xba, 0xcd, 0x2e, 0x8e, 0xfe, 0x44, + 0xad, 0x71, 0xe8, 0xf1, 0x4c, 0x73, 0xb3, 0xc1, 0xb0, 0x30, 0xea, 0x2d, 0x02, 0x31, 0x50, 0xb7, + 0x11, 0x82, 0xbc, 0x6d, 0x86, 0xa6, 0xba, 0xb2, 0x95, 0xdb, 0x5d, 0x25, 0xfc, 0x59, 0xfb, 0x55, + 0x02, 0x59, 0x94, 0xf5, 0x4c, 0x12, 0xd2, 0x4d, 0x93, 0x90, 0xae, 0x95, 0xc4, 0x66, 0x72, 0x46, + 0xac, 0xde, 0x0a, 0xc9, 0x69, 0xdc, 0x87, 0x02, 0xef, 0x11, 0xa4, 0x4e, 0xba, 0x99, 0x9d, 0x44, + 0x39, 0x69, 0xd5, 0xed, 0x8f, 0x12, 0xe4, 0xd9, 0x80, 0x46, 0x15, 0x90, 0x7b, 0x9d, 0xc3, 0xce, + 0xf1, 0xf7, 0x1d, 0xe5, 0x13, 0x54, 0x03, 0x30, 0x7a, 0x07, 0x46, 0x93, 0xe8, 0x07, 0xb8, 0xa5, + 0x48, 0x08, 0xa0, 0x78, 0xdc, 0x6e, 0x63, 0x62, 0x28, 0x39, 0x84, 0xa0, 0xa6, 0x77, 0xde, 0x60, + 0x62, 0xe0, 0xbe, 0xf8, 0x56, 0x66, 0x64, 0x82, 0x8d, 0xa6, 0xde, 0x69, 0x29, 0x2b, 0xe8, 0x0e, + 0x6c, 0x88, 0x97, 0xfe, 0x14, 0x50, 0x01, 0xe6, 0xa7, 0x77, 0xd2, 0x6a, 0x74, 0xb1, 0x92, 0x67, + 0x9c, 0xd7, 0xd8, 0x30, 0x1a, 0x2f, 0xb1, 0x52, 0x60, 0x2f, 0xed, 0x86, 0x7e, 0xd4, 0x23, 0x58, + 0x29, 0xa2, 0x32, 0x14, 0x30, 0x21, 0xc7, 0x44, 0x91, 0x51, 0x15, 0xca, 0xaf, 0x70, 0x83, 0x74, + 0x0f, 0x70, 0xa3, 0xab, 0x94, 0xb6, 0xff, 0x58, 0x87, 0x7c, 0xd3, 0x74, 0xdd, 0x8c, 0xf6, 0x96, + 0xae, 0xd9, 0xde, 0x8f, 0x85, 0x6c, 0xe5, 0xb8, 0x6c, 0xdd, 0xcd, 0x9a, 0x2e, 0x2c, 0x42, 0x5a, + 0xb5, 0xbe, 0x85, 0x72, 0xa2, 0x3e, 0xa2, 0xa3, 0xb7, 0x17, 0xf2, 0x92, 0x19, 0x44, 0x26, 0x24, + 0xf4, 0x14, 0x8a, 0xa6, 0x65, 0xd1, 0x51, 0x28, 0x64, 0xe2, 0xde, 0x42, 0x7a, 0x83, 0xc3, 0x88, + 0x80, 0xa3, 0xe7, 0x20, 0xdb, 0xd4, 0x72, 0x9d, 0xe1, 0x95, 0x13, 0x9c, 0x33, 0x5b, 0x11, 0x8e, + 0xc4, 0x04, 0xf4, 0x03, 0x6c, 0x44, 0x5e, 0xfa, 0x33, 0x63, 0xa1, 0xca, 0x3d, 0x3d, 0x5c, 0x92, + 0xc3, 0xb4, 0xf0, 0xad, 0x9b, 0xf3, 0x1f, 0x91, 0x05, 0x9b, 0x22, 0xd8, 0x6c, 0x88, 0xda, 0x62, + 0x09, 0x4b, 0x27, 0x3b, 0x1d, 0xe3, 0xb6, 0x9d, 0xf1, 0x95, 0x5d, 0xd8, 0xb9, 0xe3, 0xba, 0x42, + 0x86, 0x16, 0x5f, 0xd8, 0xa1, 0xe3, 0xba, 0x84, 0x43, 0xd1, 0x3e, 0x94, 0x82, 0xb3, 0x71, 0x68, + 0x7b, 0xef, 0x86, 0x57, 0x09, 0x50, 0x74, 0x5f, 0x02, 0x48, 0x12, 0x0a, 0x6a, 0x43, 0xc5, 0xb4, + 0xce, 0x87, 0xde, 0x3b, 0x97, 0xda, 0xa7, 0x54, 0xe8, 0xd0, 0x83, 0x2b, 0x8e, 0x2b, 0xc1, 0x92, + 0x34, 0x91, 0xd5, 0x8d, 0xcf, 0x64, 0xc1, 0x72, 0x5c, 0x2a, 0x16, 0x8d, 0xc5, 0x75, 0x43, 0x62, + 0x24, 0x99, 0x90, 0xd8, 0xf5, 0xc7, 0x7d, 0x0b, 0x4b, 0xae, 0x7f, 0x4e, 0x84, 0x9f, 0xb3, 0xdd, + 0xe4, 0xc7, 0x31, 0x0d, 0x42, 0xb5, 0xb2, 0x84, 0x4b, 0x22, 0x1c, 0x89, 0x09, 0xda, 0x21, 0x94, + 0x93, 0x3a, 0x46, 0xdf, 0x40, 0x2d, 0xd5, 0x6b, 0x4c, 0xd5, 0xa2, 0x69, 0xfa, 0x69, 0x56, 0xb7, + 0x31, 0x61, 0xab, 0x0e, 0xd2, 0xaf, 0xda, 0xef, 0x12, 0x14, 0xa3, 0x92, 0x42, 0x75, 0x28, 0xc7, + 0x5a, 0x10, 0xab, 0x53, 0x86, 0x18, 0x94, 0x84, 0xb2, 0x04, 0xe8, 0x2b, 0x00, 0x6f, 0x44, 0x7d, + 0x33, 0x74, 0xbc, 0x21, 0xd3, 0x5e, 0x46, 0xb8, 0x33, 0x43, 0xa8, 0x1f, 0xc7, 0x08, 0x92, 0x02, + 0xa3, 0x2f, 0x40, 0x1e, 0x38, 0x6e, 0x38, 0xd9, 0x12, 0x53, 0x81, 0xda, 0x91, 0x81, 0xc4, 0x08, + 0x6d, 0x00, 0xb2, 0xa8, 0xc8, 0x1b, 0xa7, 0x98, 0x8a, 0x93, 0x5b, 0x1a, 0xe7, 0x17, 0x09, 0xd6, + 0x33, 0xba, 0x0b, 0xed, 0xc3, 0xad, 0x59, 0xad, 0xbc, 0x22, 0xf8, 0xda, 0xb4, 0x58, 0xde, 0x30, + 0x87, 0x0f, 0x12, 0xdc, 0xce, 0x6a, 0xbf, 0xff, 0x34, 0x89, 0xdf, 0x24, 0xc8, 0xb3, 0x86, 0x45, + 0x9f, 0x83, 0x1c, 0x9a, 0x41, 0x6a, 0x45, 0x53, 0xa6, 0xf5, 0x5d, 0x6f, 0x91, 0x22, 0x03, 0xe8, + 0xf6, 0x94, 0x94, 0xe6, 0xae, 0x23, 0xa5, 0x6c, 0x16, 0xf4, 0x47, 0x9e, 0xeb, 0x58, 0xef, 0xe7, + 0x17, 0x31, 0x16, 0xfd, 0x84, 0xdb, 0x08, 0x9c, 0x27, 0xcf, 0x9a, 0x07, 0xa5, 0x78, 0x22, 0xcc, + 0xaa, 0xb1, 0x74, 0xcd, 0x95, 0x60, 0x3a, 0xcf, 0x25, 0x7b, 0x87, 0xf6, 0x33, 0x54, 0x52, 0x03, + 0xe4, 0x86, 0x4b, 0x4b, 0xea, 0xf4, 0x72, 0x4b, 0x4e, 0x0f, 0x41, 0x7e, 0x3c, 0x76, 0xec, 0x78, + 0x51, 0x61, 0xcf, 0xda, 0x47, 0x09, 0xca, 0xc9, 0xdc, 0x41, 0xfb, 0x50, 0x60, 0xd8, 0xf8, 0xce, + 0x77, 0x96, 0x8f, 0x2a, 0x1e, 0x83, 0x44, 0x2c, 0xad, 0x0f, 0x79, 0xf6, 0xfa, 0xaf, 0xdd, 0xe8, + 0xff, 0x63, 0xb7, 0x7b, 0xc6, 0xb6, 0x64, 0x3e, 0x24, 0xd1, 0x23, 0x28, 0x89, 0x79, 0x99, 0xd1, + 0x26, 0xf1, 0x48, 0x4d, 0x20, 0xdb, 0x7f, 0x65, 0x6e, 0x5a, 0x55, 0x28, 0x27, 0x9b, 0x96, 0x22, + 0xa1, 0x55, 0x28, 0x75, 0x71, 0x83, 0xb4, 0x98, 0x31, 0xc7, 0xd6, 0xa5, 0x46, 0xb3, 0x89, 0x4f, + 0xba, 0xca, 0x0a, 0x63, 0xb5, 0x70, 0xf3, 0x48, 0xef, 0xb0, 0xdd, 0xe9, 0x0e, 0x6c, 0x44, 0x86, + 0xfe, 0xcc, 0x2a, 0x56, 0x45, 0x1a, 0x6c, 0x0a, 0xdc, 0xac, 0xad, 0xc6, 0xfc, 0x11, 0xfc, 0x46, + 0x7f, 0xc3, 0x36, 0xae, 0x12, 0xe4, 0x0f, 0xf5, 0xa3, 0x23, 0xa5, 0xc8, 0x62, 0x1a, 0xaf, 0x7a, + 0x5d, 0x1e, 0x53, 0x46, 0x6b, 0x50, 0x69, 0x34, 0x59, 0x76, 0x47, 0xb8, 0xf5, 0x12, 0x2b, 0x25, + 0x96, 0x21, 0xc1, 0xcd, 0xe3, 0x4e, 0x53, 0x3f, 0xc2, 0xd1, 0xaa, 0x17, 0xaf, 0x6d, 0x10, 0xed, + 0x7d, 0xdf, 0xf5, 0xb0, 0xd1, 0x55, 0x2a, 0xdc, 0x4f, 0xef, 0xe4, 0x84, 0x60, 0xc3, 0x50, 0x56, + 0x0f, 0x76, 0xe0, 0xae, 0xe7, 0x9f, 0xd6, 0xcd, 0x91, 0x69, 0x9d, 0xd1, 0x8c, 0x52, 0x3a, 0x28, + 0x9e, 0xf8, 0x5e, 0xe8, 0x05, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xc6, 0x59, 0x82, 0xd3, 0x84, + 0x10, 0x00, 0x00, +} diff --git a/bcs-common/pkg/scheduler/mesosproto/sched/scheduler.proto b/bcs-common/pkg/scheduler/mesosproto/sched/scheduler.proto new file mode 100644 index 0000000000..ad304a8d27 --- /dev/null +++ b/bcs-common/pkg/scheduler/mesosproto/sched/scheduler.proto @@ -0,0 +1,381 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mesos; +import "mesos/mesos.proto"; +option go_package = "sched"; +//option java_package = "org.apache.mesos.v1.scheduler"; +//option java_outer_classname = "Protos"; + + +/** + * Scheduler event API. + * + * An event is described using the standard protocol buffer "union" + * trick, see: + * https://developers.google.com/protocol-buffers/docs/techniques#union. + */ +message Event { + // Possible event types, followed by message definitions if + // applicable. + enum Type { + // This must be the first enum value in this list, to + // ensure that if 'type' is not set, the default value + // is UNKNOWN. This enables enum values to be added + // in a backwards-compatible way. See: MESOS-4997. + UNKNOWN = 0; + + SUBSCRIBED = 1; // See 'Subscribed' below. + OFFERS = 2; // See 'Offers' below. + INVERSE_OFFERS = 9; // See 'InverseOffers' below. + RESCIND = 3; // See 'Rescind' below. + RESCIND_INVERSE_OFFER = 10; // See 'RescindInverseOffer' below. + UPDATE = 4; // See 'Update' below. + MESSAGE = 5; // See 'Message' below. + FAILURE = 6; // See 'Failure' below. + ERROR = 7; // See 'Error' below. + + // Periodic message sent by the Mesos master according to + // 'Subscribed.heartbeat_interval_seconds'. If the scheduler does + // not receive any events (including heartbeats) for an extended + // period of time (e.g., 5 x heartbeat_interval_seconds), there is + // likely a network partition. In such a case the scheduler should + // close the existing subscription connection and resubscribe + // using a backoff strategy. + HEARTBEAT = 8; + } + + // First event received when the scheduler subscribes. + message Subscribed { + required FrameworkID framework_id = 1; + + // This value will be set if the master is sending heartbeats. See + // the comment above on 'HEARTBEAT' for more details. + optional double heartbeat_interval_seconds = 2; + + // Since Mesos 1.1. + optional MasterInfo master_info = 3; + } + + // Received whenever there are new resources that are offered to the + // scheduler. Each offer corresponds to a set of resources on an + // agent. Until the scheduler accepts or declines an offer the + // resources are considered allocated to the scheduler. + message Offers { + repeated Offer offers = 1; + } + + // Received whenever there are resources requested back from the + // scheduler. Each inverse offer specifies the agent, and + // optionally specific resources. Accepting or Declining an inverse + // offer informs the allocator of the scheduler's ability to release + // the specified resources without violating an SLA. If no resources + // are specified then all resources on the agent are requested to be + // released. + message InverseOffers { + repeated InverseOffer inverse_offers = 1; + } + + // Received when a particular offer is no longer valid (e.g., the + // agent corresponding to the offer has been removed) and hence + // needs to be rescinded. Any future calls ('Accept' / 'Decline') made + // by the scheduler regarding this offer will be invalid. + message Rescind { + required OfferID offer_id = 1; + } + + // Received when a particular inverse offer is no longer valid + // (e.g., the agent corresponding to the offer has been removed) + // and hence needs to be rescinded. Any future calls ('Accept' / + // 'Decline') made by the scheduler regarding this inverse offer + // will be invalid. + message RescindInverseOffer { + required OfferID inverse_offer_id = 1; + } + + // Received whenever there is a status update that is generated by + // the executor or agent or master. Status updates should be used by + // executors to reliably communicate the status of the tasks that + // they manage. It is crucial that a terminal update (see TaskState + // in v1/mesos.proto) is sent by the executor as soon as the task + // terminates, in order for Mesos to release the resources allocated + // to the task. It is also the responsibility of the scheduler to + // explicitly acknowledge the receipt of a status update. See + // 'Acknowledge' in the 'Call' section below for the semantics. + message Update { + required TaskStatus status = 1; + } + + // Received when a custom message generated by the executor is + // forwarded by the master. Note that this message is not + // interpreted by Mesos and is only forwarded (without reliability + // guarantees) to the scheduler. It is up to the executor to retry + // if the message is dropped for any reason. + message Message { + required AgentID agent_id = 1; + required ExecutorID executor_id = 2; + required bytes data = 3; + } + + // Received when an agent is removed from the cluster (e.g., failed + // health checks) or when an executor is terminated. Note that, this + // event coincides with receipt of terminal UPDATE events for any + // active tasks belonging to the agent or executor and receipt of + // 'Rescind' events for any outstanding offers belonging to the + // agent. Note that there is no guaranteed order between the + // 'Failure', 'Update' and 'Rescind' events when an agent or executor + // is removed. + // TODO(vinod): Consider splitting the lost agent and terminated + // executor into separate events and ensure it's reliably generated. + message Failure { + optional AgentID agent_id = 1; + + // If this was just a failure of an executor on an agent then + // 'executor_id' will be set and possibly 'status' (if we were + // able to determine the exit status). + optional ExecutorID executor_id = 2; + optional int32 status = 3; + } + + // Received when there is an unrecoverable error in the scheduler (e.g., + // scheduler failed over, rate limiting, authorization errors etc.). The + // scheduler should abort on receiving this event. + message Error { + required string message = 1; + } + + // Type of the event, indicates which optional field below should be + // present if that type has a nested message definition. + // Enum fields should be optional, see: MESOS-4997. + optional Type type = 1; + + optional Subscribed subscribed = 2; + optional Offers offers = 3; + optional InverseOffers inverse_offers = 9; + optional Rescind rescind = 4; + optional RescindInverseOffer rescind_inverse_offer = 10; + optional Update update = 5; + optional Message message = 6; + optional Failure failure = 7; + optional Error error = 8; +} + + +/** + * Scheduler call API. + * + * Like Event, a Call is described using the standard protocol buffer + * "union" trick (see above). + */ +message Call { + // Possible call types, followed by message definitions if + // applicable. + enum Type { + // See comments above on `Event::Type` for more details on this enum value. + UNKNOWN = 0; + + SUBSCRIBE = 1; // See 'Subscribe' below. + TEARDOWN = 2; // Shuts down all tasks/executors and removes framework. + ACCEPT = 3; // See 'Accept' below. + DECLINE = 4; // See 'Decline' below. + ACCEPT_INVERSE_OFFERS = 13; // See 'AcceptInverseOffers' below. + DECLINE_INVERSE_OFFERS = 14; // See 'DeclineInverseOffers' below. + REVIVE = 5; // Removes any previous filters set via ACCEPT or DECLINE. + KILL = 6; // See 'Kill' below. + SHUTDOWN = 7; // See 'Shutdown' below. + ACKNOWLEDGE = 8; // See 'Acknowledge' below. + RECONCILE = 9; // See 'Reconcile' below. + MESSAGE = 10; // See 'Message' below. + REQUEST = 11; // See 'Request' below. + SUPPRESS = 12; // Inform master to stop sending offers to the framework. + + // TODO(benh): Consider adding an 'ACTIVATE' and 'DEACTIVATE' for + // already subscribed frameworks as a way of stopping offers from + // being generated and other events from being sent by the master. + // Note that this functionality existed originally to support + // SchedulerDriver::abort which was only necessary to handle + // exceptions getting thrown from within Scheduler callbacks, + // something that is not an issue with the Event/Call API. + } + + // Subscribes the scheduler with the master to receive events. A + // scheduler must send other calls only after it has received the + // SUBCRIBED event. + message Subscribe { + // See the comments below on 'framework_id' on the semantics for + // 'framework_info.id'. + required FrameworkInfo framework_info = 1; + } + + // Accepts an offer, performing the specified operations + // in a sequential manner. + // + // E.g. Launch a task with a newly reserved persistent volume: + // + // Accept { + // offer_ids: [ ... ] + // operations: [ + // { type: RESERVE, + // reserve: { resources: [ disk(role):2 ] } } + // { type: CREATE, + // create: { volumes: [ disk(role):1+persistence ] } } + // { type: LAUNCH, + // launch: { task_infos ... disk(role):1;disk(role):1+persistence } } + // ] + // } + // + // Note that any of the offer’s resources not used in the 'Accept' + // call (e.g., to launch a task) are considered unused and might be + // reoffered to other frameworks. In other words, the same OfferID + // cannot be used in more than one 'Accept' call. + message Accept { + repeated OfferID offer_ids = 1; + repeated Offer.Operation operations = 2; + optional Filters filters = 3; + } + + // Declines an offer, signaling the master to potentially reoffer + // the resources to a different framework. Note that this is same + // as sending an Accept call with no operations. See comments on + // top of 'Accept' for semantics. + message Decline { + repeated OfferID offer_ids = 1; + optional Filters filters = 2; + } + + // Accepts an inverse offer. Inverse offers should only be accepted + // if the resources in the offer can be safely evacuated before the + // provided unavailability. + message AcceptInverseOffers { + repeated OfferID inverse_offer_ids = 1; + optional Filters filters = 2; + } + + // Declines an inverse offer. Inverse offers should be declined if + // the resources in the offer might not be safely evacuated before + // the provided unavailability. + message DeclineInverseOffers { + repeated OfferID inverse_offer_ids = 1; + optional Filters filters = 2; + } + + // Kills a specific task. If the scheduler has a custom executor, + // the kill is forwarded to the executor and it is up to the + // executor to kill the task and send a TASK_KILLED (or TASK_FAILED) + // update. Note that Mesos releases the resources for a task once it + // receives a terminal update (See TaskState in v1/mesos.proto) for + // it. If the task is unknown to the master, a TASK_LOST update is + // generated. + // + // If a task within a task group is killed before the group is + // delivered to the executor, all tasks in the task group are + // killed. When a task group has been delivered to the executor, + // it is up to the executor to decide how to deal with the kill. + // Note The default Mesos executor will currently kill all the + // tasks in the task group if it gets a kill for any task. + message Kill { + required TaskID task_id = 1; + optional AgentID agent_id = 2; + + // If set, overrides any previously specified kill policy for this task. + // This includes 'TaskInfo.kill_policy' and 'Executor.kill.kill_policy'. + // Can be used to forcefully kill a task which is already being killed. + optional KillPolicy kill_policy = 3; + } + + // Shuts down a custom executor. When the executor gets a shutdown + // event, it is expected to kill all its tasks (and send TASK_KILLED + // updates) and terminate. If the executor doesn’t terminate within + // a certain timeout (configurable via + // '--executor_shutdown_grace_period' agent flag), the agent will + // forcefully destroy the container (executor and its tasks) and + // transition its active tasks to TASK_LOST. + message Shutdown { + required ExecutorID executor_id = 1; + required AgentID agent_id = 2; + } + + // Acknowledges the receipt of status update. Schedulers are + // responsible for explicitly acknowledging the receipt of status + // updates that have 'Update.status().uuid()' field set. Such status + // updates are retried by the agent until they are acknowledged by + // the scheduler. + message Acknowledge { + required AgentID agent_id = 1; + required TaskID task_id = 2; + required bytes uuid = 3; + } + + // Allows the scheduler to query the status for non-terminal tasks. + // This causes the master to send back the latest task status for + // each task in 'tasks', if possible. Tasks that are no longer known + // will result in a TASK_LOST update. If 'statuses' is empty, then + // the master will send the latest status for each task currently + // known. + message Reconcile { + // TODO(vinod): Support arbitrary queries than just state of tasks. + message Task { + required TaskID task_id = 1; + optional AgentID agent_id = 2; + } + + repeated Task tasks = 1; + } + + // Sends arbitrary binary data to the executor. Note that Mesos + // neither interprets this data nor makes any guarantees about the + // delivery of this message to the executor. + message Message { + required AgentID agent_id = 1; + required ExecutorID executor_id = 2; + required bytes data = 3; + } + + // Requests a specific set of resources from Mesos's allocator. If + // the allocator has support for this, corresponding offers will be + // sent asynchronously via the OFFERS event(s). + // + // NOTE: The built-in hierarchical allocator doesn't have support + // for this call and hence simply ignores it. + message Request { + repeated mesos.v1.Request requests = 1; + } + + // Identifies who generated this call. Master assigns a framework id + // when a new scheduler subscribes for the first time. Once assigned, + // the scheduler must set the 'framework_id' here and within its + // FrameworkInfo (in any further 'Subscribe' calls). This allows the + // master to identify a scheduler correctly across disconnections, + // failovers, etc. + optional FrameworkID framework_id = 1; + + // Type of the call, indicates which optional field below should be + // present if that type has a nested message definition. + // See comments on `Event::Type` above on the reasoning behind this field being optional. + optional Type type = 2; + + optional Subscribe subscribe = 3; + optional Accept accept = 4; + optional Decline decline = 5; + optional AcceptInverseOffers accept_inverse_offers = 13; + optional DeclineInverseOffers decline_inverse_offers = 14; + optional Kill kill = 6; + optional Shutdown shutdown = 7; + optional Acknowledge acknowledge = 8; + optional Reconcile reconcile = 9; + optional Message message = 10; + optional Request request = 11; +} diff --git a/bcs-common/pkg/scheduler/types/application.go b/bcs-common/pkg/scheduler/types/application.go new file mode 100644 index 0000000000..1c0ac36a0f --- /dev/null +++ b/bcs-common/pkg/scheduler/types/application.go @@ -0,0 +1,718 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package types + +import ( + "bk-bcs/bcs-common/pkg/scheduler/mesosproto/mesos" + mesos_master "bk-bcs/bcs-common/pkg/scheduler/mesosproto/mesos/master" + "time" + + commtypes "bk-bcs/bcs-common/common/types" + //"fmt" +) + +//executor or task default resources limits +const ( + CPUS_PER_EXECUTOR = 0.01 + CPUS_PER_TASK = 1 + MEM_PER_EXECUTOR = 64 + MEM_PER_TASK = 64 + DISK_PER_EXECUTOR = 64 + DISK_PER_TASK = 64 +) + +// operation operate +const ( + OPERATION_LAUNCH = "LAUNCH" + OPERATION_DELETE = "DELETE" + OPERATION_SCALE = "SCALE" + OPERATION_INNERSCALE = "INNERSCALE" + OPERATION_ROLLBACK = "ROLLBACK" + OPERATION_RESCHEDULE = "RESCHEDULE" + OPERATION_UPDATE = "UPDATE" +) + +//operation status +const ( + OPERATION_STATUS_INIT = "INIT" + OPERATION_STATUS_FINISH = "FINISH" + OPERATION_STATUS_FAIL = "FAIL" + OPERATION_STATUS_TIMEOUT = "TIMEOUT" +) + +// extension for TaskState_TASK_... +const ( + Ext_TaskState_TASK_RESTARTING int32 = 101 +) + +//app status +const ( + APP_STATUS_STAGING = "Staging" + APP_STATUS_DEPLOYING = "Deploying" + APP_STATUS_RUNNING = "Running" + APP_STATUS_FINISH = "Finish" + APP_STATUS_ERROR = "Error" + APP_STATUS_OPERATING = "Operating" + APP_STATUS_ROLLINGUPDATE = "RollingUpdate" + APP_STATUS_UNKOWN = "Unknown" + APP_STATUS_ABNORMAL = "Abnormal" +) + +//task status +const ( + TASK_STATUS_STAGING = "Staging" + TASK_STATUS_STARTING = "Starting" + TASK_STATUS_RUNNING = "Running" + TASK_STATUS_FINISH = "Finish" + TASK_STATUS_ERROR = "Error" + TASK_STATUS_KILLING = "Killing" + TASK_STATUS_KILLED = "Killed" + TASK_STATUS_FAIL = "Failed" + TASK_STATUS_LOST = "Lost" + + TASK_STATUS_RESTARTING = "Restarting" + + TASK_STATUS_UNKOWN = "Unknown" +) + +//taskgroup status +const ( + TASKGROUP_STATUS_STAGING = "Staging" + TASKGROUP_STATUS_STARTING = "Starting" + TASKGROUP_STATUS_RUNNING = "Running" + TASKGROUP_STATUS_FINISH = "Finish" + TASKGROUP_STATUS_ERROR = "Error" + TASKGROUP_STATUS_KILLING = "Killing" + TASKGROUP_STATUS_KILLED = "Killed" + TASKGROUP_STATUS_FAIL = "Failed" + TASKGROUP_STATUS_LOST = "Lost" + + TASKGROUP_STATUS_RESTARTING = "Restarting" + + TASKGROUP_STATUS_UNKNOWN = "Unknown" +) + +//Version for api resources application or deployment +type Version struct { + ID string + Name string + ObjectMeta commtypes.ObjectMeta + PodObjectMeta commtypes.ObjectMeta + Instances int32 + RunAs string + Container []*Container + Labels map[string]string + KillPolicy *commtypes.KillPolicy + RestartPolicy *commtypes.RestartPolicy + + Constraints *commtypes.Constraint + Uris []string + Ip []string + Mode string +} + +//Resource discribe resources needed by a task +type Resource struct { + Cpus float64 + CPUSet int16 + Mem float64 + Disk float64 + //IOTps uint32 //default times per second + //IOBps uint32 //default MB/s +} + +//CheckAndDefaultResource check the resource of each container, if no resource, set default value +func (version *Version) CheckAndDefaultResource() error { + + for index, container := range version.Container { + if nil == container.DataClass { + version.Container[index].DataClass = &DataClass{} + } + if nil == container.DataClass.Resources { + version.Container[index].DataClass.Resources = &Resource{ + Cpus: float64(CPUS_PER_TASK), + Mem: float64(MEM_PER_TASK), + Disk: float64(DISK_PER_TASK), + } + } + } + + return nil +} + +//check application constraints whether is valid +func (version *Version) CheckConstraints() bool { + if version.Constraints == nil { + return true + } + + for _, constraint := range version.Constraints.IntersectionItem { + if constraint == nil { + continue + } + for _, oneData := range constraint.UnionData { + if oneData == nil { + continue + } + if oneData.Type == commtypes.ConstValueType_Scalar && oneData.Scalar == nil { + return false + } + if oneData.Type == commtypes.ConstValueType_Text && oneData.Text == nil { + return false + } + if oneData.Type == commtypes.ConstValueType_Set && oneData.Set == nil { + return false + } + if oneData.Type == commtypes.ConstValueType_Range { + for _, oneRange := range oneData.Ranges { + if oneRange == nil { + return false + } + } + } + } + } + + return true +} + +//AllCpus return taskgroup will use cpu resources +func (version *Version) AllCpus() float64 { + var allCpus float64 + allCpus = 0 + for _, container := range version.Container { + allCpus = allCpus + container.DataClass.Resources.Cpus + } + return allCpus + float64(CPUS_PER_EXECUTOR) +} + +//AllMems return taskgroup will use memory resource +func (version *Version) AllMems() float64 { + var allMem float64 + allMem = 0 + for _, container := range version.Container { + allMem = allMem + container.DataClass.Resources.Mem + } + return allMem + float64(MEM_PER_EXECUTOR) +} + +//AllDisk return taskgroup will use disk resources +func (version *Version) AllDisk() float64 { + var allDisk float64 + allDisk = 0 + for _, container := range version.Container { + allDisk = allDisk + container.DataClass.Resources.Disk + } + return allDisk + float64(DISK_PER_EXECUTOR) +} + +//AllResource return taskgroup used cpu, memory, disk resources +func (version *Version) AllResource() *Resource { + return &Resource{ + Cpus: version.AllCpus(), + Mem: version.AllMems(), + Disk: version.AllDisk(), + } +} + +//IsResourceFit return if resource is fit for version +//func (version *Version) IsResourceFit(r Resource) bool { +// if version.AllCpus() <= r.Cpus && version.AllMems() <= r.Mem && version.AllDisk() <= r.Disk { +// return true +// } +// return false +//} + +//Container for Version +type Container struct { + Type string + Docker *Docker + Volumes []*Volume + Resources *Resource + DataClass *DataClass + + ConfigMaps []commtypes.ConfigMap + Secrets []commtypes.Secret + + HealthChecks []*commtypes.HealthCheck + + //network flow limit + NetLimit *commtypes.NetLimit +} + +//Docker for container +type Docker struct { + Hostname string + ForcePullImage bool + Image string + ImagePullUser string + ImagePullPasswd string + Network string + NetworkType string + Command string + Arguments []string + Parameters []*Parameter + PortMappings []*PortMapping + Env map[string]string + Privileged bool +} + +//Parameter for container +type Parameter struct { + Key string + Value string +} + +//PortMapping for container +type PortMapping struct { + ContainerPort int32 + HostPort int32 + Name string + Protocol string +} + +//Volume for container +type Volume struct { + ContainerPath string + HostPath string + Mode string +} + +//UpdatePolicy for container +type UpdatePolicy struct { + UpdateDelay int32 + MaxRetries int32 + MaxFailovers int32 + Action string +} + +//HealthCheck for container +type HealthCheck struct { + ID string + Address string + TaskID string + AppID string + Protocol string + Port int32 + PortIndex int32 + PortName string + Command *Command + Path string + MaxConsecutiveFailures uint32 + GracePeriodSeconds float64 + IntervalSeconds float64 + TimeoutSeconds float64 + DelaySeconds float64 + ConsecutiveFailures uint32 +} + +//Command for container +type Command struct { + Value string +} + +//Task for container +type Task struct { + ID string + Name string + Hostame string + Command string + Arguments []string + Image string + ImagePullUser string + ImagePullPasswd string + Network string + PortMappings []*PortMapping + Privileged bool + Parameters []*Parameter + ForcePullImage bool + Volumes []*Volume + Env map[string]string + Labels map[string]string + DataClass *DataClass + HealthChecks []*commtypes.HealthCheck + // health check status + HealthCheckStatus []*commtypes.BcsHealthCheckStatus + Healthy bool + OfferId string + AgentId string + AgentHostname string + Status string + LastStatus string + UpdateTime int64 + StatusData string + AppId string + RunAs string + KillPolicy *commtypes.KillPolicy + Uris []string + LastUpdateTime int64 + Message string + //network flow limit + NetLimit *commtypes.NetLimit +} + +// taskgroup describes the implements of multiple tasks +type TaskGroup struct { + ID string + Name string + AppID string + RunAs string + ObjectMeta commtypes.ObjectMeta + AgentID string + ExecutorID string + Status string + LastStatus string + InstanceID uint64 + Taskgroup []*Task + KillPolicy *commtypes.KillPolicy + RestartPolicy *commtypes.RestartPolicy + VersionName string + LastUpdateTime int64 + Attributes []*mesos.Attribute + StartTime int64 + UpdateTime int64 + ReschededTimes int + LastReschedTime int64 + //we should replace the next three BcsXXX, using ObjectMeta.Labels directly + BcsAppID string + BcsSetID string + BcsModuleID string + HostName string + Message string + LaunchResource *Resource + CurrResource *Resource + BcsMessages map[int64]*BcsMessage +} + +//GetName for ObjectMeta +func (om *TaskGroup) GetName() string { + return om.Name +} + +//SetName set object name +func (om *TaskGroup) SetName(name string) { + om.Name = name +} + +//GetNamespace for ObjectMeta +func (om *TaskGroup) GetNamespace() string { + return om.ObjectMeta.NameSpace +} + +//SetNamespace set object namespace +func (om *TaskGroup) SetNamespace(ns string) { + om.ObjectMeta.NameSpace = ns +} + +//GetCreationTimestamp get create timestamp +func (om *TaskGroup) GetCreationTimestamp() time.Time { + return om.ObjectMeta.CreationTimestamp +} + +//SetCreationTimestamp set creat timestamp +func (om *TaskGroup) SetCreationTimestamp(timestamp time.Time) { + om.ObjectMeta.CreationTimestamp = timestamp +} + +//GetLabels for ObjectMeta +func (om *TaskGroup) GetLabels() map[string]string { + return om.ObjectMeta.Labels +} + +//SetLabels set objec labels +func (om *TaskGroup) SetLabels(labels map[string]string) { + om.ObjectMeta.Labels = labels +} + +//GetAnnotations for ObjectMeta +func (om *TaskGroup) GetAnnotations() map[string]string { + return om.ObjectMeta.Annotations +} + +//SetAnnotations get annotation name +func (om *TaskGroup) SetAnnotations(annotation map[string]string) { + om.ObjectMeta.Annotations = annotation +} + +//GetClusterName get cluster name +func (om *TaskGroup) GetClusterName() string { + return om.ObjectMeta.ClusterName +} + +//SetClusterName set cluster name +func (om *TaskGroup) SetClusterName(clusterName string) { + om.ObjectMeta.ClusterName = clusterName +} + +//PortMappings for container +type PortMappings struct { + Port uint32 + Protocol string + Name string +} + +//Application for container +type Application struct { + ID string + Name string + ObjectMeta commtypes.ObjectMeta + DefineInstances uint64 + Instances uint64 + RunningInstances uint64 + RunAs string + ClusterId string + Status string + LastStatus string + Created int64 + UpdateTime int64 + Mode string + LastUpdateTime int64 + + //we should replace the next three BcsXXX, using ObjectMeta.Labels directly + BcsAppID string + BcsSetID string + BcsModuleID string + + Message string + Pods []*commtypes.BcsPodIndex +} + +//GetName for ObjectMeta +func (om *Application) GetName() string { + return om.Name +} + +//SetName set object name +func (om *Application) SetName(name string) { + om.Name = name +} + +//GetNamespace for ObjectMeta +func (om *Application) GetNamespace() string { + return om.ObjectMeta.NameSpace +} + +//SetNamespace set object namespace +func (om *Application) SetNamespace(ns string) { + om.ObjectMeta.NameSpace = ns +} + +//GetCreationTimestamp get create timestamp +func (om *Application) GetCreationTimestamp() time.Time { + return om.ObjectMeta.CreationTimestamp +} + +//SetCreationTimestamp set creat timestamp +func (om *Application) SetCreationTimestamp(timestamp time.Time) { + om.ObjectMeta.CreationTimestamp = timestamp +} + +//GetLabels for ObjectMeta +func (om *Application) GetLabels() map[string]string { + return om.ObjectMeta.Labels +} + +//SetLabels set objec labels +func (om *Application) SetLabels(labels map[string]string) { + om.ObjectMeta.Labels = labels +} + +//GetAnnotations for ObjectMeta +func (om *Application) GetAnnotations() map[string]string { + return om.ObjectMeta.Annotations +} + +//SetAnnotations get annotation name +func (om *Application) SetAnnotations(annotation map[string]string) { + om.ObjectMeta.Annotations = annotation +} + +//GetClusterName get cluster name +func (om *Application) GetClusterName() string { + return om.ObjectMeta.ClusterName +} + +//SetClusterName set cluster name +func (om *Application) SetClusterName(clusterName string) { + om.ObjectMeta.ClusterName = clusterName +} + +//Operation for application +type Operation struct { + ID string + RunAs string + AppID string + OperationType string + Status string + CreateTime int64 + LastUpdateTime int64 + ErrorStr string +} + +type OperationIndex struct { + Operation string +} + +// mesos slave info +type Agent struct { + Key string + LastSyncTime int64 + AgentInfo *mesos_master.Response_GetAgents_Agent +} + +//GetName for ObjectMeta +func (om *Agent) GetName() string { + return om.Key +} + +//SetName set object name +func (om *Agent) SetName(name string) { + om.Key = name +} + +//GetNamespace for ObjectMeta +func (om *Agent) GetNamespace() string { + return "" +} + +//SetNamespace set object namespace +func (om *Agent) SetNamespace(ns string) { + // +} + +//GetCreationTimestamp get create timestamp +func (om *Agent) GetCreationTimestamp() time.Time { + return time.Now() +} + +//SetCreationTimestamp set creat timestamp +func (om *Agent) SetCreationTimestamp(timestamp time.Time) { + // +} + +//GetLabels for ObjectMeta +func (om *Agent) GetLabels() map[string]string { + return nil +} + +//SetLabels set objec labels +func (om *Agent) SetLabels(labels map[string]string) { + // +} + +//GetAnnotations for ObjectMeta +func (om *Agent) GetAnnotations() map[string]string { + return nil +} + +//SetAnnotations get annotation name +func (om *Agent) SetAnnotations(annotation map[string]string) { + // +} + +//GetClusterName get cluster name +func (om *Agent) GetClusterName() string { + return "" +} + +//SetClusterName set cluster name +func (om *Agent) SetClusterName(clusterName string) { + // +} + +func (om *Agent) GetAgentIP() string { + if om.AgentInfo == nil || om.AgentInfo.AgentInfo == nil { + return "" + } + if len(om.AgentInfo.AgentInfo.Attributes) == 0 { + return "" + } + for _, attr := range om.AgentInfo.AgentInfo.Attributes { + if attr.GetName() == "InnerIP" { + return attr.GetText().GetValue() + } + } + + return "" +} + +type Check struct { + ID string `json:"id"` + Protocol string `json:"protocol"` + Address string `json:"address"` + Port int `json:"port"` + Command *Command `json:"command"` + Path string `json:"path"` + MaxFailures int `json:"max_failures"` + Interval int `json:"interval"` + Timeout int `json:"timeout"` + TaskID string `json:"task_id"` + TaskGroupID string `json:"taskgroup_id"` + AppID string `json:"app_id"` +} + +type DataClass struct { + Resources *Resource + Msgs []*BcsMessage + NetLimit *commtypes.NetLimit +} + +type DeploymentDef struct { + ObjectMeta commtypes.ObjectMeta `json:"metadata"` + Selector map[string]string `json:"selector,omitempty"` + Version *Version `json:"version"` + Strategy commtypes.UpgradeStrategy `json:"strategy"` +} + +const ( + DEPLOYMENT_STATUS_DEPLOYING = "Deploying" + DEPLOYMENT_STATUS_RUNNING = "Running" + DEPLOYMENT_STATUS_ROLLINGUPDATE = "Update" + DEPLOYMENT_STATUS_ROLLINGUPDATE_PAUSED = "UpdatePaused" + DEPLOYMENT_STATUS_ROLLINGUPDATE_SUSPEND = "UpdateSuspend" + DEPLOYMENT_STATUS_DELETING = "Deleting" +) + +const ( + DEPLOYMENT_OPERATION_NIL = "" + DEPLOYMENT_OPERATION_DELETE = "DELETE" + DEPLOYMENT_OPERATION_START = "START" +) + +type Deployment struct { + ObjectMeta commtypes.ObjectMeta `json:"metadata"` + Selector map[string]string `json:"selector,omitempty"` + Strategy commtypes.UpgradeStrategy `json:"strategy"` + Status string `json:"status"` + Application *DeploymentReferApplication `json:"application"` + ApplicationExt *DeploymentReferApplication `json:"application_ext"` + LastRollingTime int64 `json:"last_rolling_time"` + CurrRollingOp string `json:"curr_rolling_operation"` + IsInRolling bool `json:"is_in_rolling"` + CheckTime int64 `json:"check_time"` + Message string `json:"message"` +} + +type DeploymentReferApplication struct { + ApplicationName string `json:"name"` + CurrentTargetInstances int `json:"curr_target_instances"` +} + +type AgentSchedInfo struct { + HostName string `json:"host_name"` + DeltaCPU float64 `json:"delta_cpu"` + DeltaMem float64 `json:"delta_mem"` + DeltaDisk float64 `json:"delta_disk"` + Taskgroups map[string]*Resource +} diff --git a/bcs-common/pkg/scheduler/types/message.go b/bcs-common/pkg/scheduler/types/message.go new file mode 100644 index 0000000000..b84ec76655 --- /dev/null +++ b/bcs-common/pkg/scheduler/types/message.go @@ -0,0 +1,182 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package types + +import ( + "bk-bcs/bcs-common/pkg/scheduler/mesosproto/mesos" + //commtypes "bcs/bmsf-mesh/pkg/datatype/bcs/common/types" +) + +//Message discribe all msg from bcs scheduler to bcs executor +//Include binary file, text file, signal, env +type Msg_Type int32 + +const ( + Msg_UNKNOWN Msg_Type = 0 + Msg_LOCALFILE Msg_Type = 1 + Msg_SIGNAL Msg_Type = 2 + Msg_ENV Msg_Type = 3 + Msg_REMOTE Msg_Type = 4 + Msg_SECRET Msg_Type = 5 + Msg_TASK_STATUS_QUERY Msg_Type = 6 + Msg_ENV_REMOTE Msg_Type = 7 + Msg_UPDATE_TASK Msg_Type = 8 + Msg_COMMIT_TASK Msg_Type = 9 +) + +const ( + Msg_UNKNOWN_STR string = "unknown" + Msg_LOCALFILE_STR string = "localfile" + Msg_SIGNAL_STR string = "signal" + Msg_ENV_STR string = "env" + Msg_REMOTE_STR string = "remote" + Msg_SECRET_STR string = "secret" + Msg_TASK_STATUS_QUERY_STR string = "task_status_query" + Msg_ENV_REMOTE_STR string = "env_remote" + Msg_UPDATE_TASK_STR string = "update_task" + Msg_COMMIT_TASK_STR string = "commit_task" +) + +type Secret_Type int32 + +const ( + Secret_Unknown Secret_Type = 0 + Secret_Env Secret_Type = 1 + Secret_File Secret_Type = 2 +) + +//BcsMessage discribe msg from scheduler to executor by mesos MESSAGE call +type BcsMessage struct { + Id int64 + Type *Msg_Type + TaskGroupId string + //if TaskID is null, message should be send to all tasks in same executor instance, + //else if TaskID is not null, message should be sendto the task specialed by TaskID. + TaskID *mesos.TaskID + Local *Msg_LocalFile `json:",omitempty"` + Sig *Msg_Signal `json:",omitempty"` + Env *Msg_Env `json:",omitempty"` + EnvRemote *Msg_EnvRemote `json:",omitempty"` + Remote *Msg_Remote `json:",omitempty"` + Secret *Msg_Secret `json:",omitempty"` + TaskStatusQuery *Msg_TaskStatusQuery `json:",omitempty"` + UpdateTaskResources *Msg_UpdateTaskResources `json:",omitempty"` + CommitTask *Msg_CommitTask `json:",omitempty"` + + Status MsgStatus_type + //if status=failed, then message is failed info + Message string + //complete time + CompleteTime int64 + CreateTime int64 +} + +type MsgStatus_type string + +const ( + Msg_Status_Staging MsgStatus_type = "staging" + Msg_Status_Success MsgStatus_type = "success" + Msg_Status_Failed MsgStatus_type = "failed" +) + +//Msg_BinFile discribe where the file should be save, and the +type Msg_LocalFile struct { + To *string + Right *string + User *string + Base64 *string +} + +type Msg_Signal struct { + Signal *uint32 + ProcessName *string +} + +type Msg_Env struct { + Name *string + Value *string + //Rep bool +} + +type Msg_EnvRemote struct { + Name *string + From *string + Type *string //http, https, ftp, ftps + RemoteUser *string + RemotePasswd *string +} + +type Msg_Remote struct { + To *string + Right *string + User *string + From *string + Type *string //http, https, ftp, ftps + RemoteUser *string + RemotePasswd *string +} + +type Msg_Secret struct { + Name *string + Value *string + Type *Secret_Type +} + +type Msg_TaskStatusQuery struct { + Reason *string +} + +type Msg_UpdateTaskResources struct { + Resources []*TaskResources +} + +type TaskResources struct { + TaskId *string + Cpu *float64 + Mem *float64 +} + +type Msg_CommitTask struct { + Tasks []*CommitTask +} + +type CommitTask struct { + TaskId *string + Image *string +} + +func (x Msg_Type) Enum() *Msg_Type { + p := new(Msg_Type) + *p = x + return p +} + +func (x Secret_Type) Enum() *Secret_Type { + p := new(Secret_Type) + *p = x + return p +} + +type TaskFail_Reason int32 + +const ( + TaskFail_UNKOWN TaskFail_Reason = 0 + TaskFail_IP_SHORT TaskFail_Reason = 1 + TaskFail_IP_USED TaskFail_Reason = 2 +) + +type BCSTaskFailMsg struct { + Reason TaskFail_Reason + Desc string +} diff --git a/bcs-common/pkg/storage/etcd/client.go b/bcs-common/pkg/storage/etcd/client.go new file mode 100644 index 0000000000..0ce534d638 --- /dev/null +++ b/bcs-common/pkg/storage/etcd/client.go @@ -0,0 +1,371 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package etcd + +import ( + "crypto/tls" + "fmt" + "path" + "strings" + "time" + + "bk-bcs/bcs-common/common/blog" + "bk-bcs/bcs-common/pkg/meta" + "bk-bcs/bcs-common/pkg/storage" + "bk-bcs/bcs-common/pkg/watch" + + "github.com/coreos/etcd/clientv3" + "golang.org/x/net/context" +) + +//Config etcd storage config +type Config struct { + Host string //etcd host info + PathPrefix string //operation path prefix to join with key, if needed + User string //user name for authentication + Passwd string //password relative to user + NewFunc meta.ObjectNewFn //func for object creation + Codec meta.Codec //Codec for encoder & decoder + TLS *tls.Config //tls config for https +} + +//NewStorage create etcd accessor implemented storage interface +func NewStorage(config *Config) (storage.Storage, error) { + endpoints := strings.Split(config.Host, ",") + if len(endpoints) == 0 { + return nil, fmt.Errorf("Lost etcd host with prefix: %s", config.PathPrefix) + } + c, err := clientv3.New(clientv3.Config{ + Endpoints: endpoints, + DialTimeout: time.Second * 5, + AutoSyncInterval: time.Minute * 5, + TLS: config.TLS, + Username: config.User, + Password: config.Passwd, + }) + if err != nil { + blog.V(3).Infof("create etcd storage with %s prefix %s failed, %s", config.Host, config.PathPrefix, err) + return nil, err + } + s := &Storage{ + client: c, + objectNewFn: config.NewFunc, + codec: config.Codec, + pathPrefix: config.PathPrefix, + } + return s, nil +} + +//Storage implementation storage interface with etcd client +type Storage struct { + client *clientv3.Client //etcd client + objectNewFn meta.ObjectNewFn //create new object for codec.decode + codec meta.Codec //json Codec for object + pathPrefix string //etcd prefix +} + +//Create implements storage interface +//param key: full path for etcd +func (s *Storage) Create(cxt context.Context, key string, obj meta.Object, ttl int) (out meta.Object, err error) { + if len(key) == 0 { + return nil, fmt.Errorf("lost object key") + } + var clientCxt context.Context + if ttl > 0 { + var cancelFn context.CancelFunc + clientCxt, cancelFn = context.WithTimeout(cxt, time.Second*time.Duration(ttl)) + defer cancelFn() + } else { + clientCxt = cxt + } + //serialize object + data, err := s.codec.Encode(obj) + if err != nil { + blog.V(5).Infof("etcd storage %s encode %s/%s failed, %s", s.pathPrefix, obj.GetNamespace(), obj.GetName(), err) + return nil, fmt.Errorf("encode %s/%s: %s", obj.GetNamespace(), obj.GetName(), err) + } + fullPath := path.Join(s.pathPrefix, key) + if len(fullPath) == 0 { + blog.V(5).Infof("etcd storage %s construct path for %s/%s failed. discard operation", s.pathPrefix, obj.GetNamespace(), obj.GetName()) + return nil, fmt.Errorf("empty object storage full path") + } + response, err := s.client.Put(clientCxt, fullPath, string(data), clientv3.WithPrevKV()) + if err != nil { + blog.V(3).Infof("etcd storage %s Create %s/%s failed, %s", s.pathPrefix, obj.GetNamespace(), obj.GetName(), err) + return nil, err + } + if response.PrevKv != nil && len(response.PrevKv.Value) > 0 { + //we got previous key-value from creation + target := s.objectNewFn() + if err := s.codec.Decode(response.PrevKv.Value, target); err != nil { + blog.V(3).Infof("etcd storage %s decode %s/%s Previous value failed, %s", s.pathPrefix, obj.GetNamespace(), obj.GetName(), err) + //even got previous data failed, we still consider Create successfully + return nil, nil + } + blog.V(3).Infof("etcd storage %s update %s/%s & got previous kv success", s.pathPrefix, obj.GetNamespace(), obj.GetName()) + return target, nil + } + blog.V(3).Infof("etcd storage %s create %s/%s success", s.pathPrefix, obj.GetNamespace(), obj.GetName()) + return nil, nil +} + +//Delete implements storage interface +//for etcd operation, there are two situations for key +//* if key is empty, delete all data node under storage.pathPrefix +//* if key is not empty, delete all data under pathPrefix/key +//actually, Storage do not return object deleted +func (s *Storage) Delete(ctx context.Context, key string) (obj meta.Object, err error) { + fullPath := s.pathPrefix + if len(key) != 0 { + fullPath = path.Join(s.pathPrefix, key) + } + response, err := s.client.Delete(ctx, fullPath, clientv3.WithPrefix()) + if err != nil { + blog.V(3).Infof("etcd storage delete %s failed, %s", fullPath, err) + return nil, err + } + blog.V(3).Infof("etcd storage clean data node under %s success, node num: %d", fullPath, response.Deleted) + return nil, nil +} + +//Watch implements storage interface +//* if key empty, watch all data +//* if key is namespace, watch all data under namespace +//* if key is namespace/name, watch detail data +//watch is Stopped when any error occure +func (s *Storage) Watch(cxt context.Context, key, version string, selector storage.Selector) (watch.Interface, error) { + fullPath := s.pathPrefix + if len(key) != 0 { + fullPath = path.Join(s.pathPrefix, key) + } + proxy := newEtcdProxyWatch(cxt, s.codec, selector) + //create watchchan + etcdChan := s.client.Watch(cxt, fullPath, clientv3.WithPrefix(), clientv3.WithPrevKV()) + go proxy.eventProxy(etcdChan, s.objectNewFn) + blog.V(3).Infof("etcd client is ready to watch %s", fullPath) + return proxy, nil +} + +//WatchList implements storage interface +//Watch & WatchList are the same for etcd storage +func (s *Storage) WatchList(ctx context.Context, key, version string, selector storage.Selector) (watch.Interface, error) { + return s.Watch(ctx, key, version, selector) +} + +//Get implements storage interface +//get exactly data object from etcd client. so key must be resource fullpath +func (s *Storage) Get(cxt context.Context, key, version string, ignoreNotFound bool) (obj meta.Object, err error) { + if len(key) == 0 { + return nil, fmt.Errorf("lost object key") + } + fullPath := path.Join(s.pathPrefix, key) + response, err := s.client.Get(cxt, fullPath) + if err != nil { + blog.V(3).Infof("etcd storage exact get %s failed, %s", fullPath, err) + return nil, err + } + if len(response.Kvs) == 0 { + if ignoreNotFound { + blog.V(5).Infof("etcd storage got nothing under %s", fullPath) + return nil, nil + } + return nil, storage.ErrNotFound + } + value := response.Kvs[0].Value + if len(value) == 0 { + blog.V(3).Infof("etcd storage got empty data for %s", fullPath) + return nil, storage.ErrNotFound + } + target := s.objectNewFn() + if err := s.codec.Decode(value, target); err != nil { + blog.V(3).Infof("etcd storage decode data object %s failed, %s", fullPath, err) + return nil, fmt.Errorf("%s decode: %s", s.pathPrefix, err) + } + blog.V(3).Infof("etcd client got %s success", fullPath) + return target, nil +} + +//List implements storage interface +//list namespace-based data or all data +func (s *Storage) List(cxt context.Context, key string, selector storage.Selector) (objs []meta.Object, err error) { + fullPath := s.pathPrefix + if len(key) != 0 { + fullPath = path.Join(s.pathPrefix, key) + } + response, err := s.client.Get(cxt, fullPath, clientv3.WithPrefix()) + if err != nil { + blog.V(3).Infof("etcd storage exact get %s failed, %s", fullPath, err) + return nil, err + } + if len(response.Kvs) == 0 { + blog.V(5).Infof("etcd storage list nothing under %s", fullPath) + return nil, nil + } + for _, node := range response.Kvs { + target := s.objectNewFn() + if err := s.codec.Decode(node.Value, target); err != nil { + blog.V(3).Infof("etcd storage decode data object %s failed, %s", fullPath, err) + continue + } + if selector == nil { + objs = append(objs, target) + continue + } + if ok, _ := selector.Matchs(target); ok { + objs = append(objs, target) + } + } + blog.V(3).Infof("etcd storage list %s success, got %d objects", fullPath, len(objs)) + return objs, nil +} + +//Close storage conenction, clean resource +func (s *Storage) Close() { + blog.V(3).Infof("etcd storage %s exit.", s.pathPrefix) + s.client.Close() +} + +//etcdProxyWatch create etcdproxy watch +func newEtcdProxyWatch(cxt context.Context, codec meta.Codec, s storage.Selector) *etcdProxyWatch { + localCxt, canceler := context.WithCancel(cxt) + proxy := &etcdProxyWatch{ + selector: s, + codec: codec, + filterChannel: make(chan watch.Event, watch.DefaultChannelBuffer), + cxt: localCxt, + stopFn: canceler, + } + return proxy +} + +//etcdProxyWatch wrapper for etcd watch, filter data by selector if needed. +//* delegates etcd client watch, decode raw bytes to object +//* constructs event and dispaths to user channel +//* maintains watch availability even if network connection is broken until user stop watach +type etcdProxyWatch struct { + selector storage.Selector + codec meta.Codec + filterChannel chan watch.Event + cxt context.Context //context from storage.Watch + stopFn context.CancelFunc +} + +//Stop watch channel +func (e *etcdProxyWatch) Stop() { + e.stopFn() +} + +//WatchEvent get watch events, if watch stopped/error, watch must close +// channel and exit, watch user must read channel like +// e, ok := <-channel +func (e *etcdProxyWatch) WatchEvent() <-chan watch.Event { + return e.filterChannel +} + +func (e *etcdProxyWatch) eventProxy(etcdCh clientv3.WatchChan, objectNewFn meta.ObjectNewFn) { + defer func() { + close(e.filterChannel) + }() + for { + select { + case <-e.cxt.Done(): + blog.V(3).Infof("etcdProxyWatch is stopped by user") + return + case response, ok := <-etcdCh: + if !ok || response.Err() != nil { + //etcd channel error happened + blog.V(3).Infof("etcd proxy watch got etcd channel err, channel[%v], response[%s]", ok, response.Err()) + return + } + for _, event := range response.Events { + targetEvent := e.eventConstruct(event, objectNewFn) + if targetEvent == nil { + blog.V(3).Infof("etcdProxyWatch construct event failed, event LOST") + continue + } + e.filterChannel <- *targetEvent + } + } + } +} + +func (e *etcdProxyWatch) eventConstruct(event *clientv3.Event, objectNewFn meta.ObjectNewFn) *watch.Event { + obj := objectNewFn() + targetEvent := &watch.Event{} + if event.IsCreate() { + targetEvent.Type = watch.EventAdded + if err := e.codec.Decode(event.Kv.Value, obj); err != nil { + blog.V(3).Infof("etcdProxyWatch decode create event failed, %s", err) + return nil + } + targetEvent.Data = obj + if e.selector == nil { + return targetEvent + } + if ok, _ := e.selector.Matchs(obj); !ok { + blog.V(3).Infof("etcdProxyWatch filter block data, filter: %s", e.selector.String()) + return nil + } + return targetEvent + } + if event.IsModify() { + targetEvent.Type = watch.EventUpdated + if err := e.codec.Decode(event.Kv.Value, obj); err != nil { + blog.V(3).Infof("etcdProxyWatch decode modifyEvent newData failed, %s", err) + return nil + } + if e.selector == nil { + targetEvent.Data = obj + return targetEvent + } + cur, _ := e.selector.Matchs(obj) + oldObj := objectNewFn() + if err := e.codec.Decode(event.PrevKv.Value, oldObj); err != nil { + blog.V(3).Infof("etcdProxyWatch decode modifyEvent oldData failed, %s", err) + return nil + } + old, _ := e.selector.Matchs(oldObj) + switch { + case cur && old: + targetEvent.Data = obj + case cur && !old: + targetEvent.Type = watch.EventAdded + targetEvent.Data = obj + case !cur && old: + targetEvent.Type = watch.EventDeleted + targetEvent.Data = oldObj + case !cur && !old: + blog.V(3).Infof("etcdProxyWatch filter etcd modify event") + return nil + } + return targetEvent + } + if event.Type == clientv3.EventTypeDelete { + targetEvent.Type = watch.EventDeleted + if err := e.codec.Decode(event.PrevKv.Value, obj); err != nil { + blog.V(3).Infof("etcdProxyWatch decode deleteEvent data failed, %s", err) + return nil + } + targetEvent.Data = obj + if e.selector == nil { + return targetEvent + } + if ok, _ := e.selector.Matchs(obj); !ok { + return nil + } + return targetEvent + } + blog.V(3).Infof("etcdProxyWatch got unexpect event: %v", event.Type) + return nil +} diff --git a/bcs-common/pkg/storage/etcd/etcd.go b/bcs-common/pkg/storage/etcd/util.go similarity index 94% rename from bcs-common/pkg/storage/etcd/etcd.go rename to bcs-common/pkg/storage/etcd/util.go index f60be9d06f..44feae943a 100644 --- a/bcs-common/pkg/storage/etcd/etcd.go +++ b/bcs-common/pkg/storage/etcd/util.go @@ -12,3 +12,5 @@ */ package etcd + +//util is tools collection for etcd client diff --git a/bcs-common/pkg/storage/http/client.go b/bcs-common/pkg/storage/http/client.go new file mode 100644 index 0000000000..a98a7f9770 --- /dev/null +++ b/bcs-common/pkg/storage/http/client.go @@ -0,0 +1,470 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package http + +import ( + "bk-bcs/bcs-common/common/blog" + "bk-bcs/bcs-common/pkg/meta" + "bk-bcs/bcs-common/pkg/storage" + "bk-bcs/bcs-common/pkg/watch" + "bufio" + "bytes" + "crypto/tls" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "math/rand" + syshttp "net/http" + "strings" + "time" + + "golang.org/x/net/context" +) + +const ( + //http api default prefix + defaultAPIPrefix = "apis" +) + +var ( + //PrevDataErr this error means operation success, but got previous data failed + PrevDataErr = errors.New("Previous data err") +) + +//Config etcd storage config +type Config struct { + Hosts []string //http api host link, http://ip:host + User string //user name for http basic authentication + Passwd string //password relative to user + Codec meta.Codec //Codec for encoder & decoder + ObjectNewFunc meta.ObjectNewFn //object pointer for serialization + ObjectListFunc meta.ObjectListNewFn //decode raw json data to object list + TLS *tls.Config //tls config for https +} + +//NewStorage create etcd accessor implemented storage interface +func NewStorage(config *Config) (storage.Storage, error) { + if config == nil { + return nil, fmt.Errorf("lost client configuration") + } + return NewClient(config) +} + +//NewClient create new client for http event apis +func NewClient(config *Config) (*Client, error) { + if len(config.Hosts) == 0 { + return nil, fmt.Errorf("Lost http api hosts info") + } + c := &syshttp.Client{ + Transport: &syshttp.Transport{ + TLSClientConfig: config.TLS, + TLSHandshakeTimeout: time.Second * 3, + IdleConnTimeout: time.Second * 300, + }, + } + s := &Client{ + client: c, + codec: config.Codec, + objectNewFn: config.ObjectNewFunc, + objectListFn: config.ObjectListFunc, + servers: config.Hosts, + } + return s, nil +} + +//Client implementation storage interface with etcd client +type Client struct { + client *syshttp.Client //http client + codec meta.Codec //json Codec for object + objectNewFn meta.ObjectNewFn //create new object for json Decode + objectListFn meta.ObjectListNewFn //decode json list objects + servers []string //server http api prefix +} + +//Create implements storage interface +//param cxt: context for use decline Creation, not used +//param key: http full api path +//param obj: object for creation +//param ttl: second for time-to-live, not used +//return out: exist object data +func (s *Client) Create(cxt context.Context, key string, obj meta.Object, ttl int) (meta.Object, error) { + if len(key) == 0 { + return nil, fmt.Errorf("http client lost object key") + } + if obj == nil { + blog.V(3).Infof("http storage client lost object data for %s", key) + return nil, fmt.Errorf("lost object data") + } + //serialize object + data, err := s.codec.Encode(obj) + if err != nil { + blog.V(3).Infof("http storage client encode %s/%s for %s failed, %s", obj.GetNamespace(), obj.GetName(), key, err) + return nil, fmt.Errorf("encode %s/%s: %s", obj.GetNamespace(), obj.GetName(), err) + } + fullPath := fmt.Sprintf("%s/%s/%s", s.selectServers(), defaultAPIPrefix, key) + //check path for http method + method := "POST" + if strings.Contains(key, "namespace") { + //this means updating with detail url + method = "PUT" + } + blog.V(3).Infof("obj encoded data %s", string(data)) + request, err := syshttp.NewRequest(method, fullPath, bytes.NewBuffer(data)) + if err != nil { + blog.V(3).Infof("http storage client create %s request for %s failed, %s", method, fullPath, err) + return nil, err + } + request.Header.Set("Content-type", "application/json") + response, err := s.client.Do(request) + if err != nil { + blog.V(3).Infof("http storage client %s with %s for %s/%s failed, %s", method, fullPath, obj.GetNamespace(), obj.GetName(), err) + return nil, err + } + defer response.Body.Close() + if response.StatusCode != syshttp.StatusOK { + blog.V(3).Infof("http storage %s with %s failed, http response code: %d, status: %s", method, fullPath, response.StatusCode, response.Status) + return nil, fmt.Errorf("response: %d, message: %s", response.StatusCode, response.Status) + } + rawData, err := ioutil.ReadAll(response.Body) + if err != nil { + blog.V(3).Infof("http storage client read %s %s response body failed, %s. Operation status unknown.", method, fullPath, err) + return nil, err + } + //format data + standarResponse := &Response{} + if err := json.Unmarshal(rawData, standarResponse); err != nil { + blog.V(3).Infof("http storage client parse %s %s response failed, %s. Operation status unknown", method, fullPath, err) + return nil, err + } + if standarResponse.Code != 0 { + blog.V(3).Infof("http storage %s %s failed, %s", method, fullPath, standarResponse.Message) + return nil, fmt.Errorf("%s", standarResponse.Message) + } + //check exist data + if len(standarResponse.Data) == 0 { + blog.V(5).Infof("http storage %s %s got no response data", method, fullPath) + return nil, nil + } + target := s.objectNewFn() + if err := s.codec.Decode(standarResponse.Data, target); err != nil { + blog.V(3).Infof("http storage decode %s %s Previous value failed, %s", method, fullPath, err) + //even got previous data failed, we still consider Create successfully + return nil, PrevDataErr + } + blog.V(3).Infof("etcd storage %s %s & got previous kv success", method, fullPath) + return target, nil +} + +//Delete implements storage interface +//for http api operation, there are three situations for key +//* if key likes apis/v1/dns, clean all dns data under version v1 +//* if key likes apis/v1/dns/cluster/$clustername, delete all data under cluster +//* if key likes apis/v1/dns/cluster/$clustername/namespace/bmsf-system, delete all data under namespace +//* if key likes apis/v1/dns/cluster/$clustername/namespace/bmsf-system/data, delete detail data +// in this version, no delete objects reply +func (s *Client) Delete(ctx context.Context, key string) (obj meta.Object, err error) { + if len(key) == 0 { + return nil, fmt.Errorf("empty key") + } + if strings.HasSuffix(key, "/") { + return nil, fmt.Errorf("error format key, cannot end with /") + } + fullPath := fmt.Sprintf("%s/%s/%s", s.selectServers(), defaultAPIPrefix, key) + request, err := syshttp.NewRequest("DELETE", fullPath, nil) + if err != nil { + blog.V(3).Infof("http storage client create request for %s failed, %s", fullPath, err) + return nil, err + } + request.Header.Set("Content-type", "application/json") + response, err := s.client.Do(request) + if err != nil { + blog.V(3).Infof("http storage client DELETE request to %s failed, %s", fullPath, err) + return nil, err + } + defer response.Body.Close() + if response.StatusCode < syshttp.StatusOK || response.StatusCode >= syshttp.StatusMultipleChoices { + blog.V(3).Infof("http storage client delete to %s failed, code: %d, message: %s", fullPath, response.StatusCode, response.Status) + return nil, fmt.Errorf("delete response failed, code: %d, status: %s", response.StatusCode, response.Status) + } + rawByets, err := ioutil.ReadAll(response.Body) + if err != nil { + blog.V(3).Infof("http storage delete %s http status success, but read response body failed, %s", fullPath, err) + return nil, err + } + //format http response + standarResponse := &Response{} + if err := json.Unmarshal(rawByets, standarResponse); err != nil { + blog.V(3).Infof("http storage decode %s http response failed, %s", fullPath, err) + return nil, err + } + if standarResponse.Code != 0 { + blog.V(3).Infof("http storage delete %s failed, %s", fullPath, standarResponse.Message) + return nil, fmt.Errorf("remote err: %s", standarResponse.Message) + } + blog.V(3).Infof("http storage delete %s success, status: %s", fullPath, standarResponse.Message) + return nil, nil +} + +//Watch implements storage interface +//* if key empty, watch all data +//* if key is namespace, watch all data under namespace +//* if key is namespace/name, watch detail data +//watch is Stopped when any error occure, close event channel immediatly +//param cxt: context for background running, not used, only reserved now +//param version: data version, not used, reserved +//param selector: labels selector +//return: +// watch: watch implementation for changing event, need to Stop manually +func (s *Client) Watch(cxt context.Context, key, version string, selector storage.Selector) (watch.Interface, error) { + if len(key) == 0 || strings.HasSuffix(key, "/") { + return nil, fmt.Errorf("error key formate") + } + fullPath := fmt.Sprintf("%s/%s/%s", s.selectServers(), defaultAPIPrefix, key) + if selector != nil { + // fullPath = fullPath + "?labelSelector=" + selector.String() + "&watch=true" + fullPath = fullPath + "?" + selector.String() + "&watch=true" + } else { + fullPath = fullPath + "?watch=true" + } + request, err := syshttp.NewRequest("GET", fullPath, nil) + if err != nil { + blog.V(3).Infof("http storage create watch request %s failed, %s", fullPath, err) + return nil, err + } + request.Header.Set("Content-type", "application/json") + response, err := s.client.Do(request) + if err != nil { + blog.V(3).Infof("http storage do watch request %s failed, %s", fullPath, err) + return nil, err + } + //defer response.Body.Close() + proxy := newHTTPWatch(fullPath, response, s.objectNewFn) + go proxy.eventProxy() + if selector != nil { + blog.V(3).Infof("http storage client is ready to watch %s, selector %s", fullPath, selector.String()) + } else { + blog.V(3).Infof("http storage client is ready to watch %s, selector null", fullPath) + } + return proxy, nil +} + +//WatchList implements storage interface +//Watch & WatchList are the same for http api +func (s *Client) WatchList(ctx context.Context, key, version string, selector storage.Selector) (watch.Interface, error) { + return s.Watch(ctx, key, version, selector) +} + +//Get implements storage interface +//get exactly data object from http event storage. so key must be resource fullpath +//param cxt: not used +//param version: reserved for future +func (s *Client) Get(cxt context.Context, key, version string, ignoreNotFound bool) (meta.Object, error) { + if len(key) == 0 { + return nil, fmt.Errorf("lost object key") + } + if !strings.Contains(key, "cluster") { + return nil, fmt.Errorf("lost cluster parameter") + } + if !strings.Contains(key, "namespace") { + return nil, fmt.Errorf("lost namespace parameter") + } + if strings.HasSuffix(key, "/") { + return nil, fmt.Errorf("err key format, no / ends") + } + fullPath := fmt.Sprintf("%s/%s/%s", s.selectServers(), defaultAPIPrefix, key) + request, err := syshttp.NewRequest("GET", fullPath, nil) + if err != nil { + blog.V(3).Infof("http storage create GET %s failed, %s", fullPath, err) + return nil, err + } + request.Header.Set("Content-type", "application/json") + response, err := s.client.Do(request) + if err != nil { + blog.V(3).Infof("http storage Do %s request failed, %s", fullPath, err) + return nil, err + } + defer response.Body.Close() + if response.StatusCode < syshttp.StatusOK || response.StatusCode >= syshttp.StatusMultipleChoices { + blog.V(3).Infof("http storage get %s failed, code: %d, message: %s", fullPath, response.StatusCode, response.Status) + return nil, fmt.Errorf("remote err, code: %d, status: %s", response.StatusCode, response.Status) + } + rawData, err := ioutil.ReadAll(response.Body) + if err != nil { + blog.V(3).Infof("http storage get %s http status success, but read response body failed, %s", fullPath, err) + return nil, err + } + //format http response + standarResponse := &Response{} + if err := json.Unmarshal(rawData, standarResponse); err != nil { + blog.V(3).Infof("http storage decode GET %s http response failed, %s", fullPath, err) + return nil, err + } + if standarResponse.Code != 0 { + blog.V(3).Infof("http storage GET %s failed, %s", fullPath, standarResponse.Message) + return nil, fmt.Errorf("remote err: %s", standarResponse.Message) + } + if len(standarResponse.Data) == 0 { + blog.V(3).Infof("http storage GET %s success, but got no data", fullPath) + if ignoreNotFound { + return nil, nil + } + return nil, PrevDataErr + } + target := s.objectNewFn() + if err := s.codec.Decode(standarResponse.Data, target); err != nil { + blog.V(3).Infof("http storage decode data object %s failed, %s", fullPath, err) + return nil, fmt.Errorf("json decode: %s", err) + } + blog.V(3).Infof("http storage client got %s success", fullPath) + return target, nil +} + +//List implements storage interface +//list namespace-based data or all data +func (s *Client) List(cxt context.Context, key string, selector storage.Selector) ([]meta.Object, error) { + if len(key) == 0 || strings.HasSuffix(key, "/") { + return nil, fmt.Errorf("error key format") + } + fullPath := fmt.Sprintf("%s/%s/%s", s.selectServers(), defaultAPIPrefix, key) + if selector != nil { + filter := selector.String() + if len(filter) != 0 { + fullPath = fullPath + "?" + filter + } + } + request, err := syshttp.NewRequest("GET", fullPath, nil) + if err != nil { + blog.V(3).Infof("http storage create requestfor GET %s failed, %s", fullPath, err) + return nil, err + } + request.Header.Set("Content-type", "application/json") + response, err := s.client.Do(request) + if err != nil { + blog.V(3).Infof("http storage get %s failed, %s", fullPath, err) + return nil, err + } + defer response.Body.Close() + rawData, err := ioutil.ReadAll(response.Body) + if err != nil { + blog.V(3).Infof("http storage read %s failed, %s", fullPath, err) + return nil, err + } + standardResponse := &Response{} + if err := json.Unmarshal(rawData, standardResponse); err != nil { + blog.V(3).Infof("http storage decode %s response failed, %s", fullPath, err) + return nil, err + } + if standardResponse.Code != 0 { + blog.V(3).Infof("http storage List %s failed, %s", fullPath, err) + return nil, fmt.Errorf("remote err, code: %d, %s", standardResponse.Code, standardResponse.Message) + } + if len(standardResponse.Data) == 0 { + blog.V(3).Infof("http storage list empty data with %s", fullPath) + return nil, nil + } + objs, err := s.objectListFn(standardResponse.Data) + if err != nil { + blog.V(3).Infof("http storage list %s success, but parse json list failed, %s", fullPath, err) + return nil, err + } + blog.V(3).Infof("http storage list %s success, got %d objects", fullPath, len(objs)) + return objs, nil +} + +//Close storage conenction, clean resource +func (s *Client) Close() { + blog.V(3).Infof("http api event storage %v exit.", s.servers) +} + +func (s *Client) selectServers() string { + index := rand.Intn(len(s.servers)) + return s.servers[index] +} + +//newHTTPWatch create http watch +func newHTTPWatch(url string, response *syshttp.Response, objectFn meta.ObjectNewFn) *Watch { + proxy := &Watch{ + url: url, + response: response, + objectNewFn: objectFn, + filterChannel: make(chan watch.Event, watch.DefaultChannelBuffer), + isStop: false, + } + return proxy +} + +//Watch wrapper for http chunk response +type Watch struct { + url string + response *syshttp.Response + objectNewFn meta.ObjectNewFn + filterChannel chan watch.Event + isStop bool +} + +//Stop watch channel +func (e *Watch) Stop() { + e.response.Body.Close() + e.isStop = true +} + +//WatchEvent get watch events, if watch stopped/error, watch must close +// channel and exit, watch user must read channel like +// e, ok := <-channel +func (e *Watch) WatchEvent() <-chan watch.Event { + return e.filterChannel +} + +//eventProxy read all event json data from http response +//end then dispatch to use by Watch.Interface channel +func (e *Watch) eventProxy() { + defer func() { + close(e.filterChannel) + }() + buf := bufio.NewReader(e.response.Body) + for { + if e.isStop { + blog.V(3).Infof("http watch is asked stopped") + return + } + //reading all data from repsonse connection + rawStr, err := buf.ReadSlice('\n') + if err != nil { + blog.V(3).Infof("http watch %s read continue response failed, %s", e.url, err) + return + } + //parse data + watchRes := &WatchResponse{} + if err := json.Unmarshal(rawStr, watchRes); err != nil { + blog.V(3).Infof("http watch %s parse json %s failed, %s", string(rawStr), e.url, err) + return + } + if watchRes.Code != 0 { + //todo(jimwu): error code classification for recovery + blog.V(3).Infof("http watch %s failed, code: %d, message: %s", e.url, watchRes.Code, watchRes.Message) + return + } + target := e.objectNewFn() + if err := json.Unmarshal(watchRes.Data.Data, target); err != nil { + blog.V(3).Infof("http watch %s got unexpect json parsing err, %s", e.url, err) + return + } + targetEvent := watch.Event{ + Type: watchRes.Data.Type, + Data: target, + } + e.filterChannel <- targetEvent + } +} diff --git a/bcs-common/pkg/storage/http/types.go b/bcs-common/pkg/storage/http/types.go new file mode 100644 index 0000000000..598bcd24a9 --- /dev/null +++ b/bcs-common/pkg/storage/http/types.go @@ -0,0 +1,39 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package http + +import ( + "bk-bcs/bcs-common/pkg/watch" + "encoding/json" +) + +//Response basic response from http api +type Response struct { + Code int `json:"code"` //operation code + Message string `json:"message"` //response message + Data json.RawMessage `json:"data,omitempty"` //response data +} + +//WatchResponse basic response from http api +type WatchResponse struct { + Code int `json:"code"` //operation code + Message string `json:"message"` //response message + Data *Event `json:"data,omitempty"` //response data +} + +//Event for http watch event +type Event struct { + Type watch.EventType `json:"type"` + Data json.RawMessage `json:"data"` +} diff --git a/bcs-common/pkg/storage/interface.go b/bcs-common/pkg/storage/interface.go index 95b8b4b3f0..c45152b2fb 100644 --- a/bcs-common/pkg/storage/interface.go +++ b/bcs-common/pkg/storage/interface.go @@ -13,32 +13,60 @@ package storage -//http://daizuozhuo.github.io/etcd-service-discovery/ +import ( + "bk-bcs/bcs-common/pkg/meta" + "bk-bcs/bcs-common/pkg/watch" + "errors" -//Event for callback register -type Event interface { - AddEvent(key string, value []byte) - UpdateEvent(key string, oldData, curData []byte) - DeleteEvent(key string, value []byte) -} + "golang.org/x/net/context" +) -//Locker for storage, basic use -//for pool Delete & IP lease/release -type Locker interface { - Lock() error - Unlock() error -} +var ( + //ErrNotFound define err for no data in storage + ErrNotFound = errors.New("Data Not Found") +) -//Storage interface for key/value storage +//Storage offer one common interface for serialization of meta.Object and hide +//all event storage operation type Storage interface { - GetLocker(path string) (Locker, error) //get locker with new connection - Register(path string, data []byte) error //register self node - Add(key string, value []byte) error //add new node data - CreateDeepNode(key string, value []byte) error //add new node data - Delete(key string) ([]byte, error) //delete node - Update(key string, data []byte) error //update node data - Get(key string) ([]byte, error) //get node data - List(key string) ([]string, error) //list all children nodes - Exist(key string) (bool, error) //check node exist - Stop() //close connection + //Create add new object data to storage, if data already exists, force update + //and return data already exists + //param ctx: reserved + //param key: update data key in event storage + //param obj: data object + //param ttl: time-to-live in seconds, 0 means forever + //return obj: nil or holding data if data already exists + Create(ctx context.Context, key string, obj meta.Object, ttl int) (out meta.Object, err error) + //Delete clean data by key, return object already delete + //if data do not exist, return + //param ctx: reserved + //param key: delete data key in event storage + Delete(ctx context.Context, key string) (obj meta.Object, err error) + //Watch begin to watch key + //param ctx: reserved + //param key: specified key for watching + //param version: specified version for watching, empty means latest version + //param selector: filter for origin data in storage, nil means no filter + //return watch.Interface: interface instance for watch + Watch(ctx context.Context, key, version string, selector Selector) (watch.Interface, error) + //Watch begin to watch all items under key directory + //param ctx: reserved + //param key: specified key for watching + //param version: specified version for watching, empty means latest version + //param selector: filter for origin data in storage, nil means no filter + //return watch.Interface: interface instance for watch + WatchList(ctx context.Context, key, version string, selector Selector) (watch.Interface, error) + //Get data object by key + //param ctx: reserved + //param key: data key + //param ignoreNotFound: nil object and no error when setting true + Get(ctx context.Context, key, version string, ignoreNotFound bool) (obj meta.Object, err error) + //List data object under key directory + //param ctx: reserved + //param key: data directory + //param ignoreNotFound: no error returns when setting true even nil object + //param selector: filter for origin data in storage, nil means no filter + List(ctx context.Context, key string, selector Selector) (objs []meta.Object, err error) + //Close storage conenction, clean resource + Close() } diff --git a/bcs-common/pkg/storage/selector.go b/bcs-common/pkg/storage/selector.go new file mode 100644 index 0000000000..9448cbff9b --- /dev/null +++ b/bcs-common/pkg/storage/selector.go @@ -0,0 +1,188 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package storage + +import ( + "bk-bcs/bcs-common/pkg/meta" + "strings" +) + +//Selector is a filter when reading data from event-storage +//if data object is matched, object will push to watch tunnel +type Selector interface { + String() string + Matchs(obj meta.Object) (bool, error) + MatchList(objs []meta.Object) ([]meta.Object, error) +} + +//NewSelectors create multiple selector +func NewSelectors(s ...Selector) Selector { + ss := &Selectors{} + for _, se := range s { + if se == nil { + continue + } + ss.list = append(ss.list, se) + } + if len(ss.list) == 0 { + return &Everything{} + } + return ss +} + +//Selectors compose multiple Selector +type Selectors struct { + list []Selector +} + +//String match string +func (ss *Selectors) String() string { + var strs []string + for _, s := range ss.list { + strs = append(strs, s.String()) + } + return strings.Join(strs, "|") +} + +//Matchs match object +func (ss *Selectors) Matchs(obj meta.Object) (bool, error) { + if obj == nil { + return false, nil + } + for _, s := range ss.list { + ok, err := s.Matchs(obj) + if err != nil { + return false, err + } + if ok { + continue + } + return false, nil + } + return true, nil +} + +//MatchList match object list +func (ss *Selectors) MatchList(objs []meta.Object) ([]meta.Object, error) { + var targets []meta.Object + for _, obj := range objs { + if ok, _ := ss.Matchs(obj); ok { + targets = append(targets, obj) + } + } + return targets, nil +} + +//Everything filter nothing +type Everything struct{} + +//String match string +func (e *Everything) String() string { + return "Everything" +} + +//Matchs match object +func (e *Everything) Matchs(obj meta.Object) (bool, error) { + if obj == nil { + return false, nil + } + return true, nil +} + +//MatchList match object list +func (e *Everything) MatchList(objs []meta.Object) ([]meta.Object, error) { + return objs, nil +} + +//LabelAsSelector create selector from labels +func LabelAsSelector(l meta.Labels) Selector { + if l != nil { + return &LabelSelector{ + labels: l, + } + } + return &Everything{} +} + +//LabelSelector implements selector interface with Labels +type LabelSelector struct { + labels meta.Labels +} + +//String match string +func (ls *LabelSelector) String() string { + //modified by marsjma + //return ls.labels.String() + return "labelSelector=" + ls.labels.String() +} + +//Matchs match object +func (ls *LabelSelector) Matchs(obj meta.Object) (bool, error) { + if obj == nil { + return false, nil + } + if ls.labels == nil { + return true, nil + } + target := obj.GetLabels() + if target == nil { + return false, nil + } + matched := meta.LabelsAllMatch(ls.labels, meta.Labels(target)) + return matched, nil +} + +//MatchList match object list +func (ls *LabelSelector) MatchList(objs []meta.Object) ([]meta.Object, error) { + var targets []meta.Object + for _, obj := range objs { + if ok, _ := ls.Matchs(obj); ok { + targets = append(targets, obj) + } + } + return targets, nil +} + +//NamespaceSelector select expected namespace +type NamespaceSelector struct { + Namespace string +} + +//String match string +func (ns *NamespaceSelector) String() string { + return ns.Namespace +} + +//Matchs match object +func (ns *NamespaceSelector) Matchs(obj meta.Object) (bool, error) { + if obj == nil { + return false, nil + } + target := obj.GetNamespace() + if target == ns.Namespace { + return true, nil + } + return false, nil +} + +//MatchList match object list +func (ns *NamespaceSelector) MatchList(objs []meta.Object) ([]meta.Object, error) { + var targets []meta.Object + for _, obj := range objs { + if ok, _ := ns.Matchs(obj); ok { + targets = append(targets, obj) + } + } + return targets, nil +} diff --git a/bcs-common/pkg/storage/zookeeper/nsclient.go b/bcs-common/pkg/storage/zookeeper/nsclient.go new file mode 100644 index 0000000000..f5ac267a9a --- /dev/null +++ b/bcs-common/pkg/storage/zookeeper/nsclient.go @@ -0,0 +1,478 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package zookeeper + +import ( + "bk-bcs/bcs-common/common/blog" + "bk-bcs/bcs-common/common/zkclient" + "bk-bcs/bcs-common/pkg/meta" + "bk-bcs/bcs-common/pkg/storage" + "bk-bcs/bcs-common/pkg/watch" + "context" + "fmt" + "path" + "strings" + "time" +) + +//ZkConfig only data type node config +type ZkConfig struct { + Hosts []string //http api host link, ip:host + PrefixPath string //basic path for namespace data + Name string //data type name + Codec meta.Codec //Codec for encoder & decoder + ObjectNewFunc meta.ObjectNewFn //object pointer for serialization +} + +func convertToNodeConfig(config *ZkConfig, pushEventfn PushWatchEventFn) map[int]*Layer { + nodeConfig := make(map[int]*Layer) + datalayer := &Layer{ + Index: 0, + Name: config.Name, + IsData: true, + IsWatchChildren: false, + PushEventFunc: pushEventfn, + } + nodeConfig[datalayer.Index] = datalayer + return nodeConfig +} + +func convertToNamespaceConfig(config *ZkConfig, pushEventfn PushWatchEventFn) map[int]*Layer { + namespaceConfig := make(map[int]*Layer) + nslayer := &Layer{ + Index: 0, + Name: "namespace", + IsData: false, + PushEventFunc: nil, + IsWatchChildren: true, + } + namespaceConfig[nslayer.Index] = nslayer + //detail data node + datalayer := &Layer{ + Index: 1, + Name: config.Name, + IsData: true, + IsWatchChildren: false, + PushEventFunc: pushEventfn, + } + namespaceConfig[datalayer.Index] = datalayer + return namespaceConfig +} + +func convertToTypeConfig(config *ZkConfig, pushEventfn PushWatchEventFn) map[int]*Layer { + layerConfig := make(map[int]*Layer) + //create first layer for namespace node + typelayer := &Layer{ + Index: 0, + Name: config.Name, + IsData: false, + PushEventFunc: nil, + IsWatchChildren: true, + } + layerConfig[typelayer.Index] = typelayer + nslayer := &Layer{ + Index: 1, + Name: "namespace", + IsData: false, + PushEventFunc: nil, + IsWatchChildren: true, + } + layerConfig[nslayer.Index] = nslayer + //detail data node + datalayer := &Layer{ + Index: 2, + Name: config.Name, + IsData: true, + IsWatchChildren: false, + PushEventFunc: pushEventfn, + } + layerConfig[datalayer.Index] = datalayer + return layerConfig +} + +//NewStorage create etcd accessor implemented storage interface +func NewStorage(config *ZkConfig) (storage.Storage, error) { + return NewNSClient(config) +} + +//NewNSClient create new client for namespace-based datas that store in zookeeper. +//namespace-based datas store in path {namespace}/{name}, namespace nodes store +//nothing, only name nodes store json data +func NewNSClient(config *ZkConfig) (*NSClient, error) { + if len(config.Hosts) == 0 { + return nil, fmt.Errorf("Lost http api hosts info") + } + //create client for zookeeper + c := zkclient.NewZkClient(config.Hosts) + if err := c.ConnectEx(time.Second * 3); err != nil { + return nil, fmt.Errorf("zookeeper connect: %s", err) + } + s := &NSClient{ + config: config, + client: c, + codec: config.Codec, + objectNewFn: config.ObjectNewFunc, + prefixPath: config.PrefixPath, + } + return s, nil +} + +//NSClient implementation storage interface with zookeeper client, all operations +//are based on namespace-like data types. All data store with namespace feature. +//so full paths of objects are like /prefix/{dataType}/{namespace}/{name}, +//all object json contents are hold by name node +type NSClient struct { + config *ZkConfig //configuration for nsclient + client *zkclient.ZkClient //http client + codec meta.Codec //json Codec for object + objectNewFn meta.ObjectNewFn //create new object for json Decode + prefixPath string //zookeeper storage prefix, like /bcs/mesh/v1/discovery +} + +//Create implements storage interface +//param cxt: context for use decline Creation, not used +//param key: http full api path +//param obj: object for creation +//param ttl: second for time-to-live, not used +//return out: exist object data +func (s *NSClient) Create(cxt context.Context, key string, obj meta.Object, ttl int) (out meta.Object, err error) { + if len(key) == 0 { + return nil, fmt.Errorf("zk client lost object key") + } + if obj == nil { + blog.V(3).Infof("zk client lost object data for %s", key) + return nil, fmt.Errorf("lost object data") + } + fullPath := path.Join(s.prefixPath, key) + //check history node's data + exist, err := s.client.Exist(fullPath) + if err != nil { + blog.V(3).Infof("zk client check %s old Object failed, %s", fullPath, err) + return nil, fmt.Errorf("check old Object: %s", err) + } + if exist { + out = s.objectNewFn() + oldRawBytes, _, gerr := s.client.GetEx(fullPath) + if gerr != nil { + blog.V(3).Infof("zk client ready to get exist target %s data failed, %s", fullPath, gerr) + } else { + if derr := s.codec.Decode(oldRawBytes, out); derr != nil { + blog.V(3).Infof("zk client decode %s json failed, %s", fullPath, derr) + } + } + } + //create new data + targetBytes, err := s.codec.Encode(obj) + if err != nil { + blog.V(3).Infof("zk client encode %s object to json failed, %s", fullPath, err) + return nil, err + } + if err := s.client.Update(fullPath, string(targetBytes)); err != nil { + blog.V(3).Infof("zk client created %s failed, %s", fullPath, err) + return out, err + } + blog.V(3).Infof("zk client create %s success, prev exist: %v", fullPath, exist) + return out, nil +} + +//Delete implements storage interface +//for http api operation, there are three situations for key +//* if key likes apis/v1/dns, clean all dns data under version v1 +//* if key likes apis/v1/dns/namespace/bmsf-system, delete all data under namespace +//* if key likes apis/v1/dns/namespace/bmsf-system/data, delete detail data +// in this version, no delete objects reply +func (s *NSClient) Delete(ctx context.Context, key string) (obj meta.Object, err error) { + if strings.HasSuffix(key, "/") { + return nil, fmt.Errorf("error format key, cannot end with /") + } + fullPath := s.prefixPath + if len(key) == 0 { + blog.Warnf("zk namespace client ready to clean all data under %s", s.prefixPath) + } else { + fullPath = path.Join(s.prefixPath, key) + } + if err := s.client.Del(fullPath, 0); err != nil { + blog.V(3).Infof("zk client delete %s failed, %s", fullPath, err) + return nil, err + } + blog.V(3).Infof("zk delete %s success", fullPath) + return nil, nil +} + +//Watch implements storage interface +//* if key empty, watch all data +//* if key is namespace, watch all data under namespace +//* if key is namespace/name, watch detail data +//watch is Stopped when any error occure, close event channel immediatly +//param cxt: context for background running, not used, only reserved now +//param version: data version, not used, reserved +//param selector: labels selector +//return: +// watch: watch implementation for changing event, need to Stop manually +func (s *NSClient) Watch(cxt context.Context, key, version string, selector storage.Selector) (watch.Interface, error) { + if strings.HasSuffix(key, "/") { + return nil, fmt.Errorf("error key formate") + } + fullpath := s.prefixPath + if len(key) != 0 { + fullpath = path.Join(s.prefixPath, key) + } + nswatch := newNSWatch(fullpath, s.config, s.client, selector) + var layer map[int]*Layer + level := strings.Count(key, "/") + if len(key) == 0 { + layer = convertToTypeConfig(s.config, nswatch.pushEventFunc) + } else if level == 0 { + layer = convertToNamespaceConfig(s.config, nswatch.pushEventFunc) + } else if level == 1 { + layer = convertToNodeConfig(s.config, nswatch.pushEventFunc) + } + nswatch.setLayerConfig(layer) + //running watch + go nswatch.run() + return nswatch, nil +} + +//WatchList implements storage interface +//Watch & WatchList are the same for http api +func (s *NSClient) WatchList(ctx context.Context, key, version string, selector storage.Selector) (watch.Interface, error) { + return s.Watch(ctx, key, version, selector) +} + +//Get implements storage interface +//get exactly data object from http event storage. so key must be resource fullpath +//param cxt: not used +//param version: reserved for future +func (s *NSClient) Get(cxt context.Context, key, version string, ignoreNotFound bool) (meta.Object, error) { + if len(key) == 0 { + return nil, fmt.Errorf("lost object key") + } + if strings.HasSuffix(key, "/") { + return nil, fmt.Errorf("err key format, no / ends") + } + fullPath := path.Join(s.prefixPath, key) + rawBytes, _, err := s.client.GetEx(fullPath) + if err != nil { + blog.V(3).Infof("zk client got %s data failed, %s", fullPath, err) + if err == zkclient.ErrNoNode && ignoreNotFound { + return nil, nil + } + return nil, err + } + if len(rawBytes) < 4 { + blog.V(3).Infof("zk client got nothing in %s.", fullPath) + return nil, fmt.Errorf("data content empty") + } + target := s.objectNewFn() + if err := s.codec.Decode(rawBytes, target); err != nil { + blog.V(3).Infof("zk client decode %s data object failed, %s", fullPath, err) + return nil, fmt.Errorf("json decode: %s", err) + } + blog.V(3).Infof("zk client got %s success", fullPath) + return target, nil +} + +//List implements storage interface +//list namespace-based data or all data, detail node should use Get +//* if key is empty, list all data under prefix, data must be target object +//* if key is not empty, list all data under prefix/key, data must be target object. +//if one node errors, we consider all errors. List Function only list leaf data nodes +func (s *NSClient) List(cxt context.Context, key string, selector storage.Selector) ([]meta.Object, error) { + if strings.HasSuffix(key, "/") { + return nil, fmt.Errorf("error key format") + } + fullPath := s.prefixPath + if len(key) != 0 { + fullPath = path.Join(s.prefixPath, key) + } + blog.V(3).Infof("zk ready to list all objects under %s...", fullPath) + //detecte all leaf nodes for reading detail contents + nodes, err := s.getLeafNode(fullPath) + if err != nil { + blog.V(3).Infof("zk client got all childrens under %s failed, %s", fullPath, err) + return nil, err + } + if len(nodes) == 0 { + blog.V(3).Infof("zk client list %s success, got nothing.", fullPath) + return nil, nil + } + var outs []meta.Object + for _, node := range nodes { + //get node content from zookeeper + rawBytes, _, err := s.client.GetEx(node) + if err != nil { + if err == zkclient.ErrNoNode { + //data consistency problem here, maybe node is deleted after we + //got it, just skip disappearing nodes + blog.V(3).Infof("zk namespace client find %s lost when getting contents", node) + continue + } + blog.V(3).Infof("zk client gets %s content failed, %s", node, err) + return nil, fmt.Errorf("list %s err: %s", node, err) + } + target := s.objectNewFn() + if err := s.codec.Decode(rawBytes, target); err != nil { + blog.V(3).Infof("zk client decode %s data failed, %s", node, err) + return nil, fmt.Errorf("decode %s failed, %s", node, err) + } + if selector != nil { + ok, _ := selector.Matchs(target) + if !ok { + continue + } + } + outs = append(outs, target) + } + blog.V(3).Infof("zk list %s success, got %d objects", fullPath, len(outs)) + return outs, nil +} + +//Close storage conenction, clean resource +func (s *NSClient) Close() { + blog.V(3).Infof("zookeeper event storage %s exit.", s.prefixPath) + s.client.Close() +} + +//getLeafNode recursive get all leaf nodes, pay more attension +func (s *NSClient) getLeafNode(node string) ([]string, error) { + if len(node) == 0 { + return nil, fmt.Errorf("empty node") + } + childrens, err := s.client.GetChildren(node) + if err != nil { + blog.V(3).Infof("zk client check %s children nodes failed, %s", node, err) + return nil, err + } + if len(childrens) == 0 { + return nil, nil + } + var leafNodes []string + for _, child := range childrens { + subNode := path.Join(node, child) + subNodes, err := s.getLeafNode(subNode) + if err != nil { + return nil, err + } + if len(subNodes) == 0 { + //based-on namespace data path rule, + //check if leafNode is a really data node + //for example: + // prefix is /data/application + // data node is /data/application/namespace/mydata + // sub is namespace/mydata + sub := subNode[len(s.prefixPath)+1:] + if len(strings.Split(sub, "/")) == 2 { + leafNodes = append(leafNodes, subNode) + } + } else { + leafNodes = append(leafNodes, subNodes...) + } + } + return leafNodes, nil +} + +//newZookeeperWatch create zookeeper watch +func newNSWatch(basic string, config *ZkConfig, c *zkclient.ZkClient, s storage.Selector) *nsWatch { + w := &nsWatch{ + selfpath: basic, + config: config, + client: c, + dataChannel: make(chan watch.Event, watch.DefaultChannelBuffer), + isStop: false, + selector: s, + } + return w +} + +//NSWatch implements watch interface, and wrap for zookeeper layer watch +type nsWatch struct { + selfpath string + config *ZkConfig + client *zkclient.ZkClient + nodeWatch NodeWatch + layers map[int]*Layer + dataChannel chan watch.Event + isStop bool + selector storage.Selector +} + +func (e *nsWatch) setLayerConfig(c map[int]*Layer) { + e.layers = c +} + +//Stop watch channel +func (e *nsWatch) Stop() { + e.isStop = true + e.nodeWatch.Stop() + close(e.dataChannel) +} + +func (e *nsWatch) run() error { + nodeWatch, err := NewNodeWatch(0, e.selfpath, nil, e.client, e.layers) + if err != nil { + blog.Errorf("zk namespace client running watch for %s failed, %s", e.selfpath, err) + return err + } + e.nodeWatch = nodeWatch + nodeWatch.Run() + return nil +} + +//WatchEvent get watch events, if watch stopped/error, watch must close +// channel and exit, watch user must read channel like +// e, ok := <-channel +func (e *nsWatch) WatchEvent() <-chan watch.Event { + return e.dataChannel +} + +//pushEventFunc callback event when object data trigger +//warnning(jimwu): nsWatch do not support detail data node watch +func (e *nsWatch) pushEventFunc(eventType watch.EventType, nodepath string, rawBytes []byte) { + if e.isStop { + return + } + event := new(watch.Event) + event.Type = eventType + if len(rawBytes) != 0 { + target := e.config.ObjectNewFunc() + if err := e.config.Codec.Decode(rawBytes, target); err != nil { + blog.Errorf("zk namespace client decode path %s failed: %s", nodepath, err) + return + } + event.Data = target + } + //check delete eventType + if eventType == watch.EventDeleted { + //deletion, this event is especial because + //no data can obtain from zookeeper, we only know node is deleted. + //so we construct empty data for this object from nodepath + nodes := strings.Split(nodepath, "/") + if len(nodes) < 2 { + blog.Errorf("zk namespace watch match error path in zookeeper, %s", nodepath) + return + } + target := e.config.ObjectNewFunc() + target.SetNamespace(nodes[len(nodes)-2]) + target.SetName(nodes[len(nodes)-1]) + event.Data = target + } + if e.selector != nil { + ok, _ := e.selector.Matchs(event.Data) + if !ok { + blog.V(5).Infof("zk namespace %s watch discard %s by filter", e.selfpath, nodepath) + return + } + } + e.dataChannel <- *event +} diff --git a/bcs-common/pkg/storage/zookeeper/podclient.go b/bcs-common/pkg/storage/zookeeper/podclient.go new file mode 100644 index 0000000000..d205da59c0 --- /dev/null +++ b/bcs-common/pkg/storage/zookeeper/podclient.go @@ -0,0 +1,523 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package zookeeper + +import ( + "bk-bcs/bcs-common/common/blog" + "bk-bcs/bcs-common/common/zkclient" + "bk-bcs/bcs-common/pkg/meta" + "bk-bcs/bcs-common/pkg/storage" + "bk-bcs/bcs-common/pkg/watch" + "fmt" + "path" + "strings" + "time" + + "golang.org/x/net/context" +) + +func convertToAppData(pushFunc PushWatchEventFn) map[int]*Layer { + layerConfig := make(map[int]*Layer) + dataType := &Layer{ + Index: 0, + Name: "DataType", + IsData: false, + PushEventFunc: nil, + IsWatchChildren: true, + } + layerConfig[dataType.Index] = dataType + ns := &Layer{ + Index: 1, + Name: "namespace", + IsData: false, + PushEventFunc: nil, + IsWatchChildren: true, + } + layerConfig[ns.Index] = ns + app := &Layer{ + Index: 2, + Name: "Application", + IsData: false, + PushEventFunc: nil, + IsWatchChildren: true, + } + layerConfig[app.Index] = app + data := &Layer{ + Index: 3, + Name: "TaskGroup", + IsData: true, + PushEventFunc: pushFunc, + IsWatchChildren: false, + } + layerConfig[data.Index] = data + return layerConfig +} + +func convertToAppNS(pushFunc PushWatchEventFn) map[int]*Layer { + layerConfig := make(map[int]*Layer) + ns := &Layer{ + Index: 0, + Name: "namespace", + IsData: false, + PushEventFunc: nil, + IsWatchChildren: true, + } + layerConfig[ns.Index] = ns + app := &Layer{ + Index: 1, + Name: "Application", + IsData: false, + PushEventFunc: nil, + IsWatchChildren: true, + } + layerConfig[app.Index] = app + data := &Layer{ + Index: 2, + Name: "TaskGroup", + IsData: true, + PushEventFunc: pushFunc, + IsWatchChildren: false, + } + layerConfig[data.Index] = data + return layerConfig +} + +func convertToAppNode(pushFunc PushWatchEventFn) map[int]*Layer { + layerConfig := make(map[int]*Layer) + app := &Layer{ + Index: 0, + Name: "Application", + IsData: false, + PushEventFunc: nil, + IsWatchChildren: true, + } + layerConfig[app.Index] = app + data := &Layer{ + Index: 1, + Name: "TaskGroup", + IsData: true, + PushEventFunc: pushFunc, + IsWatchChildren: false, + } + layerConfig[data.Index] = data + return layerConfig +} + +//NewPodClient create pod client for bcs-scheduler in +func NewPodClient(config *ZkConfig) (*PodClient, error) { + if len(config.Hosts) == 0 { + return nil, fmt.Errorf("Lost zookeeper server info") + } + if len(config.PrefixPath) == 0 { + return nil, fmt.Errorf("Lost zookeeper prefix path") + } + if config.Codec == nil { + return nil, fmt.Errorf("Lost Codec in config") + } + if config.ObjectNewFunc == nil { + return nil, fmt.Errorf("Lost Object New function") + } + //create client for zookeeper + c := zkclient.NewZkClient(config.Hosts) + if err := c.ConnectEx(time.Second * 3); err != nil { + return nil, fmt.Errorf("podclient zookeeper connect: %s", err) + } + s := &PodClient{ + config: config, + client: c, + prefixPath: config.PrefixPath, + codec: config.Codec, + objectNewFn: config.ObjectNewFunc, + } + return s, nil +} + +//PodClient implements storage interface with zookeeper client, all operations +//are based on one object data types, but data may be stored at different levels of nodes. +type PodClient struct { + config *ZkConfig //configuration for nsclient + prefixPath string //zookeeper storage prefix, like bcs/mesh/v1/datatype + client *zkclient.ZkClient //http client + codec meta.Codec //json encoder/decoder + objectNewFn meta.ObjectNewFn //injection for new object +} + +//Create implements storage interface +func (s *PodClient) Create(cxt context.Context, key string, obj meta.Object, ttl int) (out meta.Object, err error) { + if len(key) == 0 { + return nil, fmt.Errorf("zk podclient lost object key") + } + if obj == nil { + blog.V(3).Infof("zk podclient lost object data for %s", key) + return nil, fmt.Errorf("lost object data") + } + fullPath := path.Join(s.prefixPath, key) + //check history node's data + exist, eerr := s.client.Exist(fullPath) + if eerr != nil { + blog.V(3).Infof("zk podclient check %s old Object failed, %s", fullPath, eerr) + return nil, fmt.Errorf("check old Object: %s", eerr) + } + if exist { + out = s.objectNewFn() + oldRawBytes, _, gerr := s.client.GetEx(fullPath) + if gerr != nil { + blog.V(3).Infof("zk podclient ready to get exist target %s data failed, %s", fullPath, gerr) + } else { + if derr := s.codec.Decode(oldRawBytes, out); derr != nil { + blog.V(3).Infof("zk client decode %s json failed, %s", fullPath, derr) + } + } + } + //create new data + targetBytes, err := s.codec.Encode(obj) + if err != nil { + blog.V(3).Infof("zk podclient encode %s object to json failed, %s", fullPath, err) + return nil, err + } + if err := s.client.Update(fullPath, string(targetBytes)); err != nil { + blog.V(3).Infof("zk podclient created %s failed, %s", fullPath, err) + return out, err + } + blog.V(3).Infof("zk podclient create %s success, prev exist: %v", fullPath, exist) + return out, nil +} + +//Delete implements storage interface +//for http api operation, there are three situations for key +//* if key likes apis/v1/dns, clean all dns data under version v1 +//* if key likes apis/v1/dns/namespace/bmsf-system, delete all data under namespace +//* if key likes apis/v1/dns/namespace/bmsf-system/data, delete detail data +// in this version, no delete objects reply +func (s *PodClient) Delete(ctx context.Context, key string) (obj meta.Object, err error) { + if len(key) != 0 { + return nil, fmt.Errorf("empty key") + } + if strings.HasSuffix(key, "/") { + return nil, fmt.Errorf("error format key, cannot end with /") + } + fullPath := path.Join(s.prefixPath, key) + //delete all children under this node + if err := s.recursiveDelete(fullPath); err != nil { + blog.Errorf("zk podclient delete fullpath resource %s failed, %s", fullPath, err) + return nil, err + } + blog.V(3).Infof("zk podclient delete %s success", fullPath) + return nil, nil +} + +func (s *PodClient) recursiveDelete(p string) error { + children, err := s.client.GetChildren(p) + if err != nil { + blog.Errorf("zk podclient check %s in recursive deletion failed, %s", p, err) + return err + } + if len(children) == 0 { + if err := s.client.Del(p, 0); err != nil { + blog.Errorf("zk podclient recursively delete %s failed, %s", p, err) + return err + } + blog.V(3).Infof("zk podclient delete leaf node %s successfully", p) + return nil + } + //we got children here + for _, child := range children { + childpath := path.Join(p, child) + if err := s.recursiveDelete(childpath); err != nil { + return err + } + } + blog.V(5).Infof("zk podclient recursive delete %s success", p) + return nil +} + +//Watch implements storage interface +//* if key empty, watch all data +//* if key is namespace, watch all data under namespace +//* if key is namespace/name, watch detail data based-on application +//watch is Stopped when any error occure, close event channel immediatly +//param cxt: context for background running, not used, only reserved now +//param version: data version, not used, reserved +//param selector: selector for target object data +//return: +// watch: watch implementation for changing event, need to Stop manually +func (s *PodClient) Watch(cxt context.Context, key, version string, selector storage.Selector) (watch.Interface, error) { + if strings.HasSuffix(key, "/") { + return nil, fmt.Errorf("error key formate") + } + fullpath := s.prefixPath + if len(key) != 0 { + fullpath = path.Join(s.prefixPath, key) + } + podwatch := newPodWatch(fullpath, s.config, s.client, selector) + level := strings.Count(key, "/") + var layerConfig map[int]*Layer + if len(key) == 0 { + //data type path watch, watch all pod data + layerConfig = convertToAppData(podwatch.pushWatchEventFn) + } else if level == 0 { + layerConfig = convertToAppNS(podwatch.pushWatchEventFn) + } else if level == 1 { + layerConfig = convertToAppNode(podwatch.pushWatchEventFn) + } + nodewatch, err := NewNodeWatch(0, fullpath, nil, s.client, layerConfig) + if err != nil { + blog.V(3).Infof("zk podclient create watch for %s failed, %s", fullpath, err) + return nil, err + } + podwatch.nodeWatch = nodewatch + //running watch + go podwatch.run() + return podwatch, nil +} + +//WatchList implements storage interface +//Watch & WatchList are the same for http api +func (s *PodClient) WatchList(ctx context.Context, key, version string, selector storage.Selector) (watch.Interface, error) { + return s.Watch(ctx, key, version, selector) +} + +//Get implements storage interface +//get exactly data object from http event storage. so key must be resource fullpath +//param cxt: not used +//param version: reserved for future +func (s *PodClient) Get(cxt context.Context, key, version string, ignoreNotFound bool) (meta.Object, error) { + if len(key) == 0 { + return nil, fmt.Errorf("lost object key") + } + if strings.HasSuffix(key, "/") { + return nil, fmt.Errorf("err key format, no / ends") + } + fullPath := path.Join(s.prefixPath, key) + rawBytes, _, err := s.client.GetEx(fullPath) + if err != nil { + blog.V(3).Infof("zk podclient got %s data failed, %s", fullPath, err) + if err == zkclient.ErrNoNode && ignoreNotFound { + return nil, nil + } + return nil, err + } + if len(rawBytes) <= 23 { + blog.V(3).Infof("zk podclient got not enough data at %s, rawBytes: %s", fullPath, string(rawBytes)) + return nil, fmt.Errorf("not enough data for decoder") + } + target := s.objectNewFn() + if err := s.codec.Decode(rawBytes, target); err != nil { + blog.V(3).Infof("zk podclient decode %s data object failed, %s", fullPath, err) + return nil, fmt.Errorf("json decode: %s", err) + } + blog.V(3).Infof("zk podclient got %s success", fullPath) + return target, nil +} + +//List implements storage interface +//list all data under prefixPath/key, there may be several data type under children +//nodes of prefixPath, we use selector to filt all types of data. +//param cxt: context for cancel, not used now +//param key: key only can be empty, namespace or namespace/{name} +//param selector: data filter +func (s *PodClient) List(cxt context.Context, key string, selector storage.Selector) ([]meta.Object, error) { + if strings.HasSuffix(key, "/") { + return nil, fmt.Errorf("error key format") + } + fullPath := s.prefixPath + keyLvl := 0 + if len(key) != 0 { + fullPath = path.Join(s.prefixPath, key) + num := strings.Count(key, "/") + if num == 0 { + keyLvl = 1 + } else if num == 1 { + keyLvl = 2 + } else { + return nil, fmt.Errorf("key formation error") + } + } + blog.V(3).Infof("zk podclient begins to list %s", fullPath) + //detecte all data nodes for reading detail contents + nodes, err := s.getDataNode(fullPath, keyLvl, 3) + if err != nil { + blog.V(3).Infof("zk podclient got all childrens under %s failed, %s", fullPath, err) + return nil, err + } + if len(nodes) == 0 { + blog.V(3).Infof("zk podclient list %s success, got nothing.", fullPath) + return nil, nil + } + var outs []meta.Object + for _, node := range nodes { + //get node content from zookeeper + rawBytes, _, err := s.client.GetEx(node) + if err != nil { + if err == zkclient.ErrNoNode { + //data consistency problem here, maybe node is deleted after we + //got it, just skip disappearing nodes + blog.V(3).Infof("zk podclient find %s lost when getting contents", node) + continue + } + blog.V(3).Infof("zk podclient gets %s content failed, %s", node, err) + return nil, fmt.Errorf("list %s err: %s", node, err) + } + if len(rawBytes) < 23 { + blog.V(3).Infof("zk podclient gets %s not enough data for decode", node) + continue + } + target := s.objectNewFn() + if err := s.codec.Decode(rawBytes, target); err != nil { + blog.V(3).Infof("zk podclient decode %s data failed, %s", node, err) + return nil, fmt.Errorf("decode %s failed, %s", node, err) + } + outs = append(outs, target) + } + blog.V(3).Infof("zk podclient list %s success, got %d objects", fullPath, len(outs)) + return outs, nil +} + +//Close storage conenction, clean resource +//warnning: if you want to Close client, you have better close Watch first +func (s *PodClient) Close() { + blog.V(3).Infof("podclient zookeeper event storage %s exit.", s.prefixPath) + s.client.Close() +} + +//getLeafNode recursive get all leaf nodes +func (s *PodClient) getDataNode(node string, now, target int) ([]string, error) { + if len(node) == 0 { + return nil, fmt.Errorf("empty node") + } + childrens, err := s.client.GetChildren(node) + if err != nil { + blog.V(3).Infof("zk podclient check %s children nodes failed, %s", node, err) + return nil, err + } + if len(childrens) == 0 { + return nil, nil + } + var dataNodes []string + done := false + if now+1 == target { + done = true + } + for _, child := range childrens { + subNode := path.Join(node, child) + if done { + dataNodes = append(dataNodes, subNode) + continue + } + subNodes, err := s.getDataNode(subNode, now+1, target) + if err != nil { + return nil, err + } + if len(subNodes) != 0 { + dataNodes = append(dataNodes, subNodes...) + } + } + return dataNodes, nil +} + +//newPodWatch create zookeeper watch +func newPodWatch(basic string, config *ZkConfig, c *zkclient.ZkClient, se storage.Selector) *podWatch { + w := &podWatch{ + selfpath: basic, + config: config, + selector: se, + dataChannel: make(chan watch.Event, watch.DefaultChannelBuffer), + isStop: false, + } + return w +} + +//podWatch wrapper for zookeeper all pod data +type podWatch struct { + selfpath string //zookeeper path + config *ZkConfig + selector storage.Selector + nodeWatch NodeWatch + dataChannel chan watch.Event + isStop bool +} + +//Stop watch channel +func (e *podWatch) Stop() { + e.isStop = true + e.nodeWatch.Stop() + close(e.dataChannel) +} + +//WatchEvent get watch events, if watch stopped/error, watch must close +// channel and exit, watch user must read channel like +// e, ok := <-channel +func (e *podWatch) WatchEvent() <-chan watch.Event { + return e.dataChannel +} + +func (e *podWatch) run() { + //just running node watch + e.nodeWatch.Run() +} + +//addEvent dispatch event to client +//param eventType: zookeeper event type +//param nodepath: pod data path +//param rawBytes: raw json bytes +func (e *podWatch) pushWatchEventFn(eventType watch.EventType, nodepath string, rawBytes []byte) { + if e.isStop { + return + } + event := new(watch.Event) + event.Type = eventType + if len(rawBytes) != 0 { + target := e.config.ObjectNewFunc() + if err := e.config.Codec.Decode(rawBytes, target); err != nil { + blog.Errorf("zk podwatch decode path %s failed: %s", nodepath, err) + return + } + event.Data = target + } + //check deletion eventType + if eventType == watch.EventDeleted { + //deletion, this event is especial because + //no data can obtain from zookeeper, we only know that node is deleted. + //so we construct empty data for this object from nodepath + nodes := strings.Split(nodepath, "/") + if len(nodes) < 3 { + blog.Errorf("zk podwatch match error path in zookeeper, %s", nodepath) + return + } + target := e.config.ObjectNewFunc() + //fix(DeveloperJim): construting name from nodepath + target.SetNamespace(nodes[len(nodes)-3]) + parts := strings.Split(nodes[len(nodes)-1], ".") + if len(parts) < 4 { + blog.Errorf("zk podwatch got error formation podname: %s", nodes[len(nodes)-1]) + return + } + name := fmt.Sprintf("%s-%s", parts[1], parts[0]) + target.SetName(name) + zkFlag := make(map[string]string) + zkFlag["bk-bcs-inner-storage"] = "bkbcs-zookeeper" + target.SetAnnotations(zkFlag) + event.Data = target + //only for debug + blog.V(3).Infof("zk client podwatch %s/%s is delete, path %s", target.GetNamespace(), target.GetName(), nodepath) + } + if e.selector != nil { + ok, _ := e.selector.Matchs(event.Data) + if !ok { + blog.V(5).Infof("zk podwatch %s discard %s by filter", e.selfpath, nodepath) + return + } + } + e.dataChannel <- *event +} diff --git a/bcs-common/pkg/storage/zookeeper/util.go b/bcs-common/pkg/storage/zookeeper/util.go new file mode 100644 index 0000000000..b796f480e7 --- /dev/null +++ b/bcs-common/pkg/storage/zookeeper/util.go @@ -0,0 +1,328 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package zookeeper + +import ( + "bk-bcs/bcs-common/common/blog" + "bk-bcs/bcs-common/common/zkclient" + "bk-bcs/bcs-common/pkg/watch" + "fmt" + "path" + "sync" + "time" + + "golang.org/x/net/context" +) + +// const ( +// //mesos scheduler data prefix, followed by dataType, such as configmaps, applications +// defaultPrefixPath = "/blueking" +// //DefaultCRDPrefixPath default prefix for crd, followed by dataType/namespace/name +// defaultCRDPrefixPath = "/blueking/crd" +// //second for watch +// defaultWatchCheckPeriod = 60 +// ) + +//PushWatchEventFn function to dispath event +//param EventType: zk event type +//param string: event path, especially for delete event +//param []byte: detail data for object, nil when it's deletion +type PushWatchEventFn func(watch.EventType, string, []byte) + +//NodeWatch interface for watch definition +type NodeWatch interface { + GetSelfPath() string //get self node path + DeleteNextWatch(next NodeWatch) //delete children watch + Run() //ready to start up watch + Stop() //stop watch, only parent watch to stop +} + +//NewNodeWatch create one nodewatch from configuration +func NewNodeWatch(index int, selfpath string, parent NodeWatch, c *zkclient.ZkClient, configs map[int]*Layer) (NodeWatch, error) { + config, ok := configs[index] + if !ok { + return nil, fmt.Errorf("Lost layer config for node %s", selfpath) + } + cxt, stopFn := context.WithCancel(context.Background()) + n := &Node{ + selfpath: selfpath, + config: config, + allConfig: configs, + parent: parent, + client: c, + children: make(map[string]NodeWatch), + watchCxt: cxt, + stopFn: stopFn, + isStopped: false, + underSelfloop: false, + underChildrenloop: false, + } + return n, nil +} + +//Layer info +type Layer struct { + Index int //layer index from path + IsData bool //flag to present this layer store data + IsWatchChildren bool //flag for watch children if not + Name string //data type for this layer + PushEventFunc PushWatchEventFn //event dispatch function +} + +//Node for zookeeper every node +type Node struct { + selfpath string //node absolute path + config *Layer //node config + allConfig map[int]*Layer //next layer configuration + parent NodeWatch //parent node for refference + client *zkclient.ZkClient //zookeeper client + childrenLock sync.Mutex //lock for map + children map[string]NodeWatch //all children's watch + watchCxt context.Context //root context for self + stopFn context.CancelFunc //stop func to stop all backgroup context + isStopped bool //flag for stop + underSelfloop bool //flag for selfLoop + underChildrenloop bool //flag for childrenLoop +} + +//GetSelfPath get self node path +func (n *Node) GetSelfPath() string { + return n.selfpath +} + +//DeleteNextWatch clen next watch when child node deletion +func (n *Node) DeleteNextWatch(next NodeWatch) { + n.childrenLock.Lock() + defer n.childrenLock.Unlock() + delete(n.children, next.GetSelfPath()) +} + +//Run start to run all inner event loop +func (n *Node) Run() { + go n.selfLoop() + if n.config.IsWatchChildren { + go n.childrenLoop() + } + tick := time.NewTicker(time.Second * 3) + for { + if n.isStopped { + return + } + select { + case <-n.watchCxt.Done(): + return + case <-tick.C: + if n.isStopped { + return + } + if !n.underSelfloop { + go n.selfLoop() + } + if !n.underChildrenloop && n.config.IsWatchChildren { + go n.childrenLoop() + } + } + } +} + +//Stop all events & clean sub node events +func (n *Node) Stop() { + n.childrenLock.Lock() + defer n.childrenLock.Unlock() + if n.isStopped { + return + } + n.isStopped = true + n.stopFn() + blog.V(3).Infof("zk node %s ready to stop, clean all NextWatch.", n.selfpath) + for node, next := range n.children { + blog.V(3).Infof("zk stop Children watch %s", next.GetSelfPath()) + delete(n.children, node) + next.Stop() + } +} + +//SelfLoop check self node & ends +//for zookeeper, it's not easy to iterate all data when Synchronization, +//so after watch data nodes, we decide to force sync datas every 45 seconds +func (n *Node) selfLoop() { + if n.isStopped { + return + } + blog.V(5).Infof("node %s is under watch", n.selfpath) + n.underSelfloop = true + //check node existence + exist, err := n.client.Exist(n.selfpath) + if err != nil { + blog.Errorf("zk node %s Exist failed, %s", n.selfpath, err) + n.Stop() + if n.parent != nil { + blog.V(3).Infof("zk node %s notify parent node clean reference", n.selfpath) + n.parent.DeleteNextWatch(n) + } + n.underSelfloop = false + return + } + if !exist { + blog.V(3).Infof("zk node %s do not exist", n.selfpath) + n.Stop() + if n.parent != nil { + blog.V(3).Infof("zk node %s notify parent node clean reference", n.selfpath) + n.parent.DeleteNextWatch(n) + } + n.underSelfloop = false + return + } + //get watch + rawBytes, _, eventCh, err := n.client.GetW(n.selfpath) + if err != nil { + blog.V(3).Infof("zk client node watch %s failed, %s.", n.selfpath, err) + n.Stop() + if n.parent != nil { + blog.V(3).Infof("zk node %s notify parent node clean reference", n.selfpath) + n.parent.DeleteNextWatch(n) + } + n.underSelfloop = false + return + } + //format to object datas + if len(rawBytes) > 23 && n.config.IsData { + n.config.PushEventFunc(watch.EventUpdated, n.selfpath, rawBytes) + } + //wait for next event + forceTick := time.NewTicker(time.Second * 45) + for { + select { + case <-n.watchCxt.Done(): + blog.V(3).Infof("zk client node %s watch is asked to exit", n.selfpath) + //n.underSelfloop = false + return + case event := <-eventCh: + //here we need to focus on deletion & changed + if event.Type == zkclient.EventNodeDeleted { + blog.V(3).Infof("zk client got node %s deletion, clean watch", n.selfpath) + if n.config.IsData { + n.config.PushEventFunc(watch.EventDeleted, n.selfpath, nil) + } + //self node deletion, clean all sub watch + n.Stop() + if n.parent != nil { + n.parent.DeleteNextWatch(n) + } + n.underSelfloop = false + return + } + if event.Type == zkclient.EventNodeDataChanged { + blog.V(3).Infof("zk client node %s data changed. refresh watch again", n.selfpath) + go n.selfLoop() + return + } + //Creation event can not happen here + case <-forceTick.C: + if !n.config.IsData { + continue + } + blog.V(5).Infof("zk client watch %s force synchronization", n.selfpath) + exist, err := n.client.Exist(n.selfpath) + if err != nil { + blog.Errorf("zk client %s force synchronization exist failed, %s, wait next force tick.", n.selfpath, err) + continue + } + if !exist { + blog.V(3).Infof("zk node %s force synchronization found no data, clean watch", n.selfpath) + n.Stop() + if n.parent != nil { + blog.V(3).Infof("zk node %s notify parent node clean reference", n.selfpath) + n.parent.DeleteNextWatch(n) + } + n.underSelfloop = false + return + } + //get watch + rawBytes, _, err := n.client.GetEx(n.selfpath) + if err != nil { + blog.Errorf("zk client node watch %s forceSync get failed, %s.", n.selfpath, err) + continue + } + n.config.PushEventFunc(watch.EventSync, n.selfpath, rawBytes) + } + } +} + +//childrenLoop check self node & ends +func (n *Node) childrenLoop() { + if n.isStopped { + return + } + n.underChildrenloop = true + //check node existence + children, evCh, err := n.client.WatchChildren(n.selfpath) + if err != nil { + blog.Errorf("zk node %s childrenLoop failed, %s", n.selfpath, err) + n.Stop() + if n.parent != nil { + n.parent.DeleteNextWatch(n) + } + n.underChildrenloop = false + return + } + n.childrenLock.Lock() + //get all node from local children map + localChildren := make(map[string]bool) + for key := range n.children { + localChildren[key] = true + } + //find out new children, create watch for it + for _, child := range children { + node := path.Join(n.selfpath, child) + if _, ok := n.children[node]; !ok { + nodeWatch, err := NewNodeWatch(n.config.Index+1, node, n, n.client, n.allConfig) + if err != nil { + blog.Error("zk create node watch for %s failed, %s", node, err) + continue + } + n.children[node] = nodeWatch + //starting children node watch + go nodeWatch.Run() + } else { + //clean exist key for searching lost key in zookeeper + delete(localChildren, node) + } + } + //clean keys that lost in zookeeper but exist in local children map + for key := range localChildren { + nodeWatch := n.children[key] + delete(n.children, key) + nodeWatch.Stop() + blog.V(3).Infof("zk NodeWatch %s lost in zookeeper, but NodeWatch got no event. ready to clean it.", key) + } + n.childrenLock.Unlock() + select { + case <-n.watchCxt.Done(): + blog.V(3).Infof("zk NodeWatch %s is asked to exit", n.selfpath) + return + case event := <-evCh: + if event.Type == zkclient.EventNodeChildrenChanged { + go n.childrenLoop() + return + } + //we do not sure that zookeeper client will report other events. + //so we consider children loop here will exit. we will recovery + //children loop by time ticker under Run() + blog.V(3).Infof("zk %s NodeWatch detects children loop exit, eventType: %d, state: %d, "+ + "Err: %s, server: %s, path: %s", n.selfpath, event.Type, event.State, event.Err, event.Server, event.Path) + n.underChildrenloop = false + return + } +} diff --git a/bcs-common/pkg/storage/zookeeper/zookeeper.go b/bcs-common/pkg/storage/zookeeper/zookeeper.go deleted file mode 100644 index d83dc5f306..0000000000 --- a/bcs-common/pkg/storage/zookeeper/zookeeper.go +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Blueking Container Service available. - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * Licensed under the MIT License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package zookeeper - -import ( - "bk-bcs/bcs-common/common/blog" - "bk-bcs/bcs-common/common/zkclient" - "bk-bcs/bcs-common/pkg/storage" - "strings" - "time" -) - -//ConLocker wrapper lock for release connection -type ConLocker struct { - path string //path for lock - lock *zkclient.ZkLock //bcs common lock -} - -//Lock try to Lock -func (cl *ConLocker) Lock() error { - return cl.lock.LockEx(cl.path, time.Second*3) -} - -//Unlock release lock and connection -func (cl *ConLocker) Unlock() error { - cl.lock.UnLock() - return nil -} - -//NewStorage create etcd storage -func NewStorage(hosts string) storage.Storage { - //create zookeeper connection - host := strings.Split(hosts, ",") - blog.Info("Storage create zookeeper connection with %s", hosts) - // conn, _, conErr := zk.Connect(host, time.Second*5) - // if conErr != nil { - // blog.Error("Storage create zookeeper connection failed: %v", conErr) - // return nil - // } - bcsClient := zkclient.NewZkClient(host) - if conErr := bcsClient.ConnectEx(time.Second * 5); conErr != nil { - blog.Errorf("Storage create zookeeper connection failed: %v", conErr) - return nil - } - - blog.Infof("Storage connect to zookeeper %s success", hosts) - s := &zkStorage{ - zkHost: host, - zkClient: bcsClient, - } - return s -} - -//eStorage storage data in etcd -type zkStorage struct { - zkHost []string //zookeeper host info, for reconnection - zkClient *zkclient.ZkClient //zookeeper client for operation -} - -// Stop stop implementation -func (zks *zkStorage) Stop() { - zks.zkClient.Close() -} - -// GetLocker implementation -func (zks *zkStorage) GetLocker(key string) (storage.Locker, error) { - blog.Infof("zkStorage create %s locker", key) - bcsLock := zkclient.NewZkLock(zks.zkHost) - wrap := &ConLocker{ - path: key, - lock: bcsLock, - } - return wrap, nil -} - -//Register register self node -func (zks *zkStorage) Register(path string, data []byte) error { - err := zks.zkClient.CreateEphAndSeq(path, data) - if err != nil { - blog.Errorf("zkStorage register %s failed, %v", path, err) - return err - } - return nil -} - -//Add add data -func (zks *zkStorage) Add(key string, value []byte) error { - err := zks.zkClient.Create(key, value) - if err != nil { - blog.Errorf("zkStorage add %s with value %s err, %v", key, string(value), err) - return err - } - return nil -} - -//Delete delete node by key -func (zks *zkStorage) Delete(key string) ([]byte, error) { - //done(developerJim): get data before delete - data, err := zks.Get(key) - if err != nil { - return []byte(""), err - } - err = zks.zkClient.Del(key, -1) - return data, err -} - -//Update update node by value -func (zks *zkStorage) Update(key string, value []byte) error { - return zks.zkClient.Set(key, string(value), -1) -} - -//Get get data of path -func (zks *zkStorage) Get(key string) ([]byte, error) { - data, err := zks.zkClient.Get(key) - if err != nil { - return nil, err - } - return []byte(data), nil -} - -//List all children nodes -func (zks *zkStorage) List(key string) ([]string, error) { - list, err := zks.zkClient.GetChildren(key) - if err != nil { - return nil, err - } - - return list, nil -} - -//Exist check path exist -func (zks *zkStorage) Exist(key string) (bool, error) { - e, err := zks.zkClient.Exist(key) - if err != nil { - return false, err - } - return e, nil -} - -func (zks *zkStorage) CreateDeepNode(key string, value []byte) error { - return zks.zkClient.CreateDeepNode(key, value) -} diff --git a/bcs-common/pkg/watch/filter.go b/bcs-common/pkg/watch/filter.go new file mode 100644 index 0000000000..c2004da310 --- /dev/null +++ b/bcs-common/pkg/watch/filter.go @@ -0,0 +1,85 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package watch + +import ( + "bk-bcs/bcs-common/pkg/meta" + + "golang.org/x/net/context" +) + +//SelectFunc custom function to verify how filter acts +type SelectFunc func(meta.Object) (bool, error) + +//NewSelectWatch wrap watcher with filter func +func NewSelectWatch(w Interface, fn SelectFunc) Interface { + cxt, canceler := context.WithCancel(context.Background()) + f := &SelectorWatch{ + watch: w, + cxt: cxt, + selectFn: fn, + stopFn: canceler, + eventChannel: make(chan Event, DefaultChannelBuffer), + } + go f.selectWatchEvent() + return f +} + +//SelectorWatch watcher wraper offer filter function to filter data object if needed +type SelectorWatch struct { + watch Interface //inner watch for original data to filte + selectFn SelectFunc //filter for watch + cxt context.Context //context for stop + stopFn context.CancelFunc //stopFn for context + eventChannel chan Event //event channel for data already filtered +} + +//Stop stop watch channel +func (fw *SelectorWatch) Stop() { + fw.stopFn() +} + +//WatchEvent get watch events +func (fw *SelectorWatch) WatchEvent() <-chan Event { + return fw.eventChannel +} + +//filterWatchEvent handler for filter +func (fw *SelectorWatch) selectWatchEvent() { + tunnel := fw.watch.WatchEvent() + if tunnel == nil { + fw.watch.Stop() + close(fw.eventChannel) + return + } + defer func() { + fw.watch.Stop() + close(fw.eventChannel) + }() + for { + select { + case event, ok := <-tunnel: + if !ok { + return + } + matched, err := fw.selectFn(event.Data) + if err != nil || !matched { + continue + } + fw.eventChannel <- event + case <-fw.cxt.Done(): + return + } + } +} diff --git a/bcs-common/pkg/watch/interface.go b/bcs-common/pkg/watch/interface.go new file mode 100644 index 0000000000..d9b8de0a87 --- /dev/null +++ b/bcs-common/pkg/watch/interface.go @@ -0,0 +1,52 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package watch + +import ( + "bk-bcs/bcs-common/pkg/meta" +) + +//EventType definition for watch +type EventType string + +const ( + //EventSync sync event, reserved for force synchronization + EventSync EventType = "SYNC" + //EventAdded add event + EventAdded EventType = "ADDED" + //EventUpdated updated/modified event + EventUpdated EventType = "UPDATED" + //EventDeleted deleted event + EventDeleted EventType = "DELETED" + //EventErr error event for watch, error occured, but watch still works + EventErr EventType = "ERROR" + //DefaultChannelBuffer buffer for watch event channel + DefaultChannelBuffer = 128 +) + +//Interface define watch channel +type Interface interface { + //stop watch channel + Stop() + //get watch events, if watch stopped/error, watch must close + // channel and exit, watch user must read channel like + // e, ok := <-channel + WatchEvent() <-chan Event +} + +//Event holding event info for data object +type Event struct { + Type EventType `json:"type"` + Data meta.Object `json:"data"` +} diff --git a/bcs-mesos/bcs-container-executor/app/bcs_executor.go b/bcs-mesos/bcs-container-executor/app/bcs_executor.go index 3db5572b8f..3a0ce0d29a 100644 --- a/bcs-mesos/bcs-container-executor/app/bcs_executor.go +++ b/bcs-mesos/bcs-container-executor/app/bcs_executor.go @@ -563,9 +563,12 @@ func (executor *BcsExecutor) monitorPod() { executor.exeLock.Unlock() return } + + var changed bool podNewStatus := executor.podInst.GetPodStatus() if executor.podStatus != podNewStatus { logs.Infof("Pod status change from %s to %s\n", executor.podStatus, podNewStatus) + changed = true executor.podStatus = podNewStatus } switch executor.podStatus { @@ -587,19 +590,19 @@ func (executor *BcsExecutor) monitorPod() { delete(executor.messages, message.Id) } + var healthyChanged bool for _, task := range executor.podInst.GetContainerTasks() { - var changed bool if task.HealthCheck != nil { if task.RuntimeConf.Healthy != task.HealthCheck.IsHealthy() || task.RuntimeConf.IsChecked != task.HealthCheck.IsTicks() || task.RuntimeConf.ConsecutiveFailureTimes != task.HealthCheck.ConsecutiveFailure() { - changed = true + healthyChanged = true task.RuntimeConf.Healthy = task.HealthCheck.IsHealthy() task.RuntimeConf.IsChecked = task.HealthCheck.IsTicks() task.RuntimeConf.ConsecutiveFailureTimes = task.HealthCheck.ConsecutiveFailure() } } - if reporting%30 == 0 || changed || message != nil { + if reporting%30 == 0 || changed || healthyChanged || message != nil { //report data every 30 seconds or pod healthy status changed executor.status = ExecutorStatus_RUNNING logs.Infof("all task is Running, healthy: %t, isChecked: %t, ConsecutiveFailureTimes: %d"+ @@ -608,20 +611,36 @@ func (executor *BcsExecutor) monitorPod() { ///for _, info := range containers { info := task.RuntimeConf info.BcsMessage = message - localInfo := executor.tasks.GetContainer(info.Name) localInfo.Update(info) + infoby, _ := json.Marshal(localInfo) taskInfo := executor.tasks.GetTaskByContainerID(info.Name) - update := &mesos.TaskStatus{ - TaskId: taskInfo.GetTaskId(), - State: mesos.TaskState_TASK_RUNNING.Enum(), - Message: proto.String(localInfo.Message), - Source: mesos.TaskStatus_SOURCE_EXECUTOR.Enum(), - Healthy: proto.Bool(task.RuntimeConf.Healthy), + + //if changed, send task status update + if changed { + update := &mesos.TaskStatus{ + TaskId: taskInfo.GetTaskId(), + State: mesos.TaskState_TASK_RUNNING.Enum(), + Message: proto.String(localInfo.Message), + Source: mesos.TaskStatus_SOURCE_EXECUTOR.Enum(), + Healthy: proto.Bool(task.RuntimeConf.Healthy), + } + update.Data = infoby + executor.driver.SendStatusUpdate(update) + //if running, send message for task status update + } else { + bcsMsg := &bcstype.BcsMessage{ + Id: time.Now().UnixNano(), + TaskID: taskInfo.GetTaskId(), + Type: bcstype.Msg_TASK_STATUS_UPDATE.Enum(), + TaskStatus: infoby, + } + by, _ := json.Marshal(bcsMsg) + _, err := executor.driver.SendFrameworkMessage(string(by)) + if err != nil { + logs.Errorf("send framework message error %s", err.Error()) + } } - update.Data, _ = json.Marshal(localInfo) - executor.driver.SendStatusUpdate(update) - //} } } diff --git a/bcs-mesos/bcs-container-executor/container/cni/cni_pod.go b/bcs-mesos/bcs-container-executor/container/cni/cni_pod.go index 2809c178e0..8e789c8095 100644 --- a/bcs-mesos/bcs-container-executor/container/cni/cni_pod.go +++ b/bcs-mesos/bcs-container-executor/container/cni/cni_pod.go @@ -580,13 +580,6 @@ func (p *CNIPod) containersWatch(cxt context.Context) { logs.Errorf("CNIPod status Error, request %s, but got %s, CNIPod Container watch exit\n", container.PodStatus_STARTING, p.status) return } - defer func() { - if err := recover(); err != nil { - logs.Infof("CNIPod panic:\n\n%+v", err) - p.runningFailedStop(fmt.Errorf("Pod failed because panic")) - return - } - }() tick := time.NewTicker(defaultPodWatchInterval * time.Second) for { @@ -608,16 +601,18 @@ func (p *CNIPod) containerCheck() error { healthyCount := 0 p.lock.Lock() defer p.lock.Unlock() + tolerance := 0 for name := range p.runningContainer { info, err := p.conClient.InspectContainer(name) - info.Healthy = true if err != nil { //inspect error tolerance++ logs.Errorf("CNIPod Inspect info from container runtime Err: %s, #########wait for next tick, tolerance: %d#########\n", err.Error(), tolerance) continue } + + info.Healthy = true task := p.conTasks[name] if task.RuntimeConf.Status != info.Status { //status changed diff --git a/bcs-mesos/bcs-container-executor/container/cnm/cnm_pod.go b/bcs-mesos/bcs-container-executor/container/cnm/cnm_pod.go index 86f52bf085..540d71e57e 100644 --- a/bcs-mesos/bcs-container-executor/container/cnm/cnm_pod.go +++ b/bcs-mesos/bcs-container-executor/container/cnm/cnm_pod.go @@ -491,13 +491,6 @@ func (p *DockerPod) containersWatch(cxt context.Context) { logs.Errorf("DockerPod status Error, request %s, but got %s, DockerPod Container watch exit\n", container.PodStatus_STARTING, p.status) return } - defer func() { - if err := recover(); err != nil { - logs.Infof("CNMPod panic:\n\n%+v", err) - p.runningFailedStop(fmt.Errorf("CNMPod failed because panic")) - return - } - }() tick := time.NewTicker(defaultPodWatchInterval * time.Second) //total := defaultErrTolerate * len(p.runningContainer) @@ -521,17 +514,16 @@ func (p *DockerPod) containerCheck() error { p.lock.Lock() defer p.lock.Unlock() - //logs.Infof("start check container...") - for name := range p.runningContainer { info, err := p.conClient.InspectContainer(name) - info.Healthy = true if err != nil { //todo(developerJim): inspect error, how to handle ? tolerance++ logs.Errorf("DockerPod Inspect info from container runtime Err: %s, #########wait for next tick, tolerance: %d#########\n", err.Error(), tolerance) continue } + + info.Healthy = true //logs.Infof("DEBUG %+v\n", info) if p.cnmIPAddr == "" && info.IPAddress != "" { //setting cnm ip address again if get nothing in Init Stage diff --git a/bcs-mesos/bcs-container-executor/container/docker.go b/bcs-mesos/bcs-container-executor/container/docker.go index ad2375ac06..9103f4b8a8 100644 --- a/bcs-mesos/bcs-container-executor/container/docker.go +++ b/bcs-mesos/bcs-container-executor/container/docker.go @@ -486,11 +486,6 @@ func (docker *DockerContainer) KillContainer(containerName string, signal int) e //InspectContainer inspect container by name func (docker *DockerContainer) InspectContainer(containerName string) (*BcsContainerInfo, error) { - if docker.client == nil { - err := fmt.Errorf("docker client is nil") - logs.Infof(err.Error()) - return nil, err - } container, err := docker.client.InspectContainer(containerName) if err != nil { return nil, err diff --git a/bcs-mesos/bcs-container-executor/executor/executor.go b/bcs-mesos/bcs-container-executor/executor/executor.go index 130987009a..9d8652e4c1 100644 --- a/bcs-mesos/bcs-container-executor/executor/executor.go +++ b/bcs-mesos/bcs-container-executor/executor/executor.go @@ -422,7 +422,7 @@ func (driver *BcsExecutorDriver) SendStatusUpdate(taskStatus *mesos.TaskStatus) //best effort; do not expect a framework message to be //retransmitted in any reliable fashion. func (driver *BcsExecutorDriver) SendFrameworkMessage(data string) (mesos.Status, error) { - fmt.Fprintf(os.Stdout, "Sending Framework message: %s", data) + fmt.Fprintf(os.Stdout, "Sending Framework message: %s\n", data) if driver.status != mesos.Status_DRIVER_RUNNING { fmt.Fprintf(os.Stderr, "Unable to SendFramworkMessage, expecting status %s, but Got %s\n", mesos.Status_DRIVER_RUNNING, driver.status) return driver.status, fmt.Errorf("ExecutorDriver is Not Running") diff --git a/bcs-mesos/bcs-scheduler/src/manager/sched/scheduler/scheduler.go b/bcs-mesos/bcs-scheduler/src/manager/sched/scheduler/scheduler.go index 755d770ef1..af095864cf 100644 --- a/bcs-mesos/bcs-scheduler/src/manager/sched/scheduler/scheduler.go +++ b/bcs-mesos/bcs-scheduler/src/manager/sched/scheduler/scheduler.go @@ -997,7 +997,7 @@ func (s *Scheduler) handleEvents(resp *http.Response) { message := event.GetMessage() blog.Info("receive message(%s)", message.String()) data := message.GetData() - var bcsMsg types.BcsMessage + var bcsMsg *types.BcsMessage err := json.Unmarshal(data, &bcsMsg) if err != nil { blog.Error("unmarshal bcsmessage(%s) err:%s", data, err.Error()) @@ -1005,7 +1005,9 @@ func (s *Scheduler) handleEvents(resp *http.Response) { } switch *bcsMsg.Type { case types.Msg_Res_COMMAND_TASK: - go s.ProcessCommandMessage(&bcsMsg) + go s.ProcessCommandMessage(bcsMsg) + case types.Msg_TASK_STATUS_UPDATE: + go s.UpdateTaskStatus(message.GetAgentId().GetValue(), message.GetExecutorId().GetValue(), bcsMsg) default: blog.Error("unknown message type(%s)", *bcsMsg.Type) } diff --git a/bcs-mesos/bcs-scheduler/src/manager/sched/scheduler/update.go b/bcs-mesos/bcs-scheduler/src/manager/sched/scheduler/update.go index 82fe0d7313..a3b1f39f5e 100644 --- a/bcs-mesos/bcs-scheduler/src/manager/sched/scheduler/update.go +++ b/bcs-mesos/bcs-scheduler/src/manager/sched/scheduler/update.go @@ -176,7 +176,7 @@ func (s *Scheduler) StatusReport(status *mesos.TaskStatus) { taskGroupStatus := taskGroup.Status // update taskGroup Status according to tasks status - taskgroupUpdated, err := s.updateTaskgroup(taskGroup, agentID, executorID) + taskgroupUpdated, err := s.updateTaskgroup(taskGroup, agentID.GetValue(), executorID.GetValue()) if err != nil { blog.Error("status report: updateTaskgroup %s failed", taskGroupID) return @@ -378,16 +378,16 @@ func (s *Scheduler) preCheckTaskStatusReport(status *mesos.TaskStatus) bool { return true } -func (s *Scheduler) updateTaskgroup(taskGroup *types.TaskGroup, agentId *mesos.AgentID, executorId *mesos.ExecutorID) (bool, error) { +func (s *Scheduler) updateTaskgroup(taskGroup *types.TaskGroup, agentId, executorId string) (bool, error) { isUpdated := false - if nil != agentId && taskGroup.AgentID != *(agentId.Value) { - taskGroup.AgentID = *(agentId.Value) + if "" != agentId && taskGroup.AgentID != agentId { + taskGroup.AgentID = agentId isUpdated = true } - if nil != executorId && taskGroup.ExecutorID != *(executorId.Value) { - taskGroup.ExecutorID = *(executorId.Value) + if "" != executorId && taskGroup.ExecutorID != executorId { + taskGroup.ExecutorID = executorId isUpdated = true } @@ -740,3 +740,171 @@ func (s *Scheduler) applicationStatusUpdated(app *types.Application, originStatu return } + +//current only update task status running by mesos message, if task status changed by mesos status update +func (s *Scheduler) UpdateTaskStatus(agentID, executorID string, bcsMsg *types.BcsMessage) { + taskId := bcsMsg.TaskID.GetValue() + taskGroupID := store.GetTaskGroupID(taskId) + if taskGroupID == "" { + blog.Error("message status report: can not get taskGroupId from taskID(%s)", taskId) + return + } + runAs, appId := store.GetRunAsAndAppIDbyTaskGroupID(taskGroupID) + s.store.LockApplication(runAs + "." + appId) + defer s.store.UnLockApplication(runAs + "." + appId) + + // ack and check + if s.preCheckMessageTaskStatus(agentID, executorID, taskId) == false { + return + } + + now := time.Now().Unix() + updateTime := now - MAX_DATA_UPDATE_INTERVAL + task, err := s.store.FetchTask(taskId) + if task == nil { + blog.Warn("message status report: fetch task(%s) return nil", taskId) + return + } + + var taskInfo *containertypes.BcsContainerInfo + err = json.Unmarshal(bcsMsg.TaskStatus, &taskInfo) + if err != nil { + blog.Errorf("message Unmarshal data(%s) to types.BcsMessage error %s", string(bcsMsg.TaskStatus), err.Error()) + return + } + oldStatus := task.Status + oldData := task.StatusData + reportStatus := "" + // update task status + switch strings.ToLower(taskInfo.Status) { + case "running": + blog.V(3).Infof("message status report: Task(%s) Running", taskId) + reportStatus = types.TASK_STATUS_RUNNING + default: + blog.Error("message status report: Unprocessed task status (%d), TaskID:%s", taskInfo, taskId) + return + } + + task.Status = reportStatus + task.StatusData = string(bcsMsg.TaskStatus) + + var msg *types.BcsMessage + if task.StatusData != oldData { + blog.Info("message status report: task %s, statusData change: %s --> %s", taskId, oldData, task.StatusData) + var containerInfo *containertypes.BcsContainerInfo + err = json.Unmarshal([]byte(task.StatusData), &containerInfo) + if err != nil { + blog.Errorf("message unmarshal task statusdata(%s) error: %s", task.StatusData, err.Error()) + } else { + msg = containerInfo.BcsMessage + task.IsChecked = containerInfo.IsChecked + task.ConsecutiveFailureTimes = uint32(containerInfo.ConsecutiveFailureTimes) + } + } + if oldData != "" && task.StatusData == "" { + blog.Warn("message status report: Task %s, Status: %s, reported StatusData is empty, keep oldData(%s)", taskId, task.Status, oldData) + task.StatusData = oldData + } + + healthyChg := s.checkTaskHealth(task, taskGroupID, taskInfo.Healthy) + taskUpdated := false + if task.Status != oldStatus || task.StatusData != oldData || healthyChg { + task.UpdateTime = now + taskUpdated = true + } + + if taskUpdated || task.LastUpdateTime <= updateTime { + blog.V(3).Infof("message status report: Save Task %s, Status: %s, StatusData: %s, Healthy: %t", + taskId, task.Status, task.StatusData, task.Healthy) + } else { + blog.V(3).Infof("task %s status report, not change", taskId) + return + } + task.LastUpdateTime = now + if err = s.store.SaveTask(task); err != nil { + blog.Error("message status report: SaveTask %s err: %s", taskId, err.Error()) + return + } + + // NOTE: in function FetchTaskGroup, tasks` data will update to taskgroup, we must fetch taskgroup here again + taskGroup, err := s.store.FetchTaskGroup(taskGroupID) + if err != nil { + blog.Error("message status report: Fetch task group %s failed: %s", taskGroupID, err.Error()) + return + } + blog.Info("message status report: task(%s) status(%s), taskgroup(%s)", taskId, task.Status, taskGroup.Status) + + taskGroupStatus := taskGroup.Status + // update taskGroup Status according to tasks status + taskgroupUpdated, err := s.updateTaskgroup(taskGroup, agentID, executorID) + if err != nil { + blog.Error("status report: updateTaskgroup %s failed", taskGroupID) + return + } + if taskUpdated == true { + taskgroupUpdated = true + } + if taskgroupUpdated == true { + taskGroup.UpdateTime = now + } + + // taskgroup info changed + if taskGroup.LastUpdateTime <= updateTime || taskgroupUpdated == true { + s.ServiceMgr.TaskgroupUpdate(taskGroup) + if taskGroup.Status != taskGroupStatus { + s.taskGroupStatusUpdated(taskGroup, taskGroupStatus) + } + if msg != nil { + taskGroup.BcsEventMsg = msg + } + taskGroup.LastUpdateTime = now + //save taskGroup into zk, in this function, task will alse be saved + if err = s.store.SaveTaskGroup(taskGroup); err != nil { + blog.Error("message status report: save taskgroup: %s information into db failed! err:%s", taskGroup.ID, err.Error()) + return + } + } + + s.checkApplicationChange(runAs, appId, taskGroupStatus, taskGroup, now) + return +} + +func (s *Scheduler) preCheckMessageTaskStatus(agentID, executorID, taskId string) bool { + + taskGroupID := store.GetTaskGroupID(taskId) + runAs, appId := store.GetRunAsAndAppIDbyTaskGroupID(taskGroupID) + task, err := s.store.FetchTask(taskId) + if err != nil && err != zk.ErrNoNode { + blog.Warn("message status report: fetch task(%s) err(%s)", taskId, err.Error()) + return false + } + blog.V(3).Infof("message status report: get status report: task %s, executorID: %s, agentID: %s ", + taskId, executorID, agentID) + + if task == nil { + blog.Warn("message status report: task(%s) not exist", taskId) + taskGroups, err1 := s.store.ListTaskGroups(runAs, appId) + if err1 != nil { + blog.Warn("message status report: list taskgroups(%s.%s) failed, err:%s", runAs, appId, err1.Error()) + return false + } + for _, taskGroup := range taskGroups { + if taskGroup.ID == taskGroupID { + blog.Error("message status report: task(%s) not exist but taskgroup(%s) exist", taskId, taskGroupID) + return false + } + } + + if agentID == "" || executorID == "" { + blog.Warn("message status report: task(%s) not exist and reported executor(%s) or agent(%s) error, do nothing", + taskId, executorID, agentID) + return false + } + + blog.Warn("message status report: task(%s) not eixst, kill executor(%s) on agent(%s)", taskId, executorID, agentID) + s.KillExecutor(agentID, executorID) + return false + } + + return true +} diff --git a/bcs-mesos/bcs-scheduler/src/types/message.go b/bcs-mesos/bcs-scheduler/src/types/message.go index b5bc71fffd..d37c1f8be5 100644 --- a/bcs-mesos/bcs-scheduler/src/types/message.go +++ b/bcs-mesos/bcs-scheduler/src/types/message.go @@ -23,37 +23,39 @@ import ( type Msg_Type int32 const ( - Msg_UNKNOWN Msg_Type = 0 - Msg_LOCALFILE Msg_Type = 1 - Msg_SIGNAL Msg_Type = 2 - Msg_ENV Msg_Type = 3 - Msg_REMOTE Msg_Type = 4 - Msg_SECRET Msg_Type = 5 - Msg_TASK_STATUS_QUERY Msg_Type = 6 - Msg_ENV_REMOTE Msg_Type = 7 - Msg_UPDATE_TASK Msg_Type = 8 - Msg_COMMIT_TASK Msg_Type = 9 - Msg_RELOAD_TASK Msg_Type = 10 - Msg_RESTART_TASK Msg_Type = 11 - Msg_Req_COMMAND_TASK Msg_Type = 12 - Msg_Res_COMMAND_TASK Msg_Type = 13 + Msg_UNKNOWN Msg_Type = 0 + Msg_LOCALFILE Msg_Type = 1 + Msg_SIGNAL Msg_Type = 2 + Msg_ENV Msg_Type = 3 + Msg_REMOTE Msg_Type = 4 + Msg_SECRET Msg_Type = 5 + Msg_TASK_STATUS_QUERY Msg_Type = 6 + Msg_ENV_REMOTE Msg_Type = 7 + Msg_UPDATE_TASK Msg_Type = 8 + Msg_COMMIT_TASK Msg_Type = 9 + Msg_RELOAD_TASK Msg_Type = 10 + Msg_RESTART_TASK Msg_Type = 11 + Msg_Req_COMMAND_TASK Msg_Type = 12 + Msg_Res_COMMAND_TASK Msg_Type = 13 + Msg_TASK_STATUS_UPDATE Msg_Type = 14 ) const ( - Msg_UNKNOWN_STR string = "unknown" - Msg_LOCALFILE_STR string = "localfile" - Msg_SIGNAL_STR string = "signal" - Msg_ENV_STR string = "env" - Msg_REMOTE_STR string = "remote" - Msg_SECRET_STR string = "secret" - Msg_TASK_STATUS_QUERY_STR string = "task_status_query" - Msg_ENV_REMOTE_STR string = "env_remote" - Msg_UPDATE_TASK_STR string = "update_task" - Msg_COMMIT_TASK_STR string = "commit_task" - Msg_RELOAD_TASK_STR string = "reload_task" - Msg_RESTART_TASK_STR string = "restart_task" - Msg_Req_COMMAND_TASK_STR string = "request_command_task" - Msg_Res_COMMAND_TASK_STR string = "response_command_task" + Msg_UNKNOWN_STR string = "unknown" + Msg_LOCALFILE_STR string = "localfile" + Msg_SIGNAL_STR string = "signal" + Msg_ENV_STR string = "env" + Msg_REMOTE_STR string = "remote" + Msg_SECRET_STR string = "secret" + Msg_TASK_STATUS_QUERY_STR string = "task_status_query" + Msg_ENV_REMOTE_STR string = "env_remote" + Msg_UPDATE_TASK_STR string = "update_task" + Msg_COMMIT_TASK_STR string = "commit_task" + Msg_RELOAD_TASK_STR string = "reload_task" + Msg_RESTART_TASK_STR string = "restart_task" + Msg_Req_COMMAND_TASK_STR string = "request_command_task" + Msg_Res_COMMAND_TASK_STR string = "response_command_task" + Msg_TASK_STATUS_UPDATE_STR string = "task_status_update" ) type Secret_Type int32 @@ -85,6 +87,7 @@ type BcsMessage struct { RestartTask *Msg_RestartTasks `json:",omitempty"` RequestCommandTask *RequestCommandTask `json:",omitempty"` ResponseCommandTask *ResponseCommandTask `json:",omitempty"` + TaskStatus []byte `json:",omitempty"` Status MsgStatus_type //if status=failed, then message is failed info diff --git a/vendor/k8s.io/client-go/tools/cache/thread_safe_store.go b/vendor/k8s.io/client-go/tools/cache/thread_safe_store.go index 1c201efb62..a94d9b866c 100644 --- a/vendor/k8s.io/client-go/tools/cache/thread_safe_store.go +++ b/vendor/k8s.io/client-go/tools/cache/thread_safe_store.go @@ -146,6 +146,7 @@ func (c *threadSafeMap) Index(indexName string, obj interface{}) ([]interface{}, if err != nil { return nil, err } + index := c.indices[indexName] // need to de-dupe the return list. Since multiple keys are allowed, this can happen.