diff --git a/pkg/kubelet/api/testing/fake_runtime_service.go b/pkg/kubelet/api/testing/fake_runtime_service.go index 99b9f580e18..92c845e3507 100644 --- a/pkg/kubelet/api/testing/fake_runtime_service.go +++ b/pkg/kubelet/api/testing/fake_runtime_service.go @@ -33,12 +33,8 @@ var ( ) type FakePodSandbox struct { - // PodSandbox contains minimal information about a sandbox. - runtimeApi.PodSandbox - - // Annotations is an unstructured key value map that may be set by external - // tools to store and retrieve arbitrary metadata. - Annotations map[string]string + // PodSandboxStatus contains the runtime information for a sandbox. + runtimeApi.PodSandboxStatus } type FakeContainer struct { @@ -75,7 +71,7 @@ func (r *FakeRuntimeService) SetFakeContainers(containers []*FakeContainer) { r.Containers = make(map[string]*FakeContainer) for _, c := range containers { - containerID := c.GetName() + containerID := c.GetId() r.Containers[containerID] = c } @@ -110,19 +106,19 @@ func (r *FakeRuntimeService) CreatePodSandbox(config *runtimeApi.PodSandboxConfi r.Called = append(r.Called, "CreatePodSandbox") // PodSandboxID should be randomized for real container runtime, but here just use - // sandbox's name for easily making fake sandboxes. - podSandboxID := config.GetName() + // fixed name from BuildSandboxName() for easily making fake sandboxes. + podSandboxID := BuildSandboxName(config.Metadata) createdAt := time.Now().Unix() readyState := runtimeApi.PodSandBoxState_READY r.Sandboxes[podSandboxID] = &FakePodSandbox{ - PodSandbox: runtimeApi.PodSandbox{ - Id: &podSandboxID, - Name: config.Name, - State: &readyState, - CreatedAt: &createdAt, - Labels: config.Labels, + PodSandboxStatus: runtimeApi.PodSandboxStatus{ + Id: &podSandboxID, + Metadata: config.Metadata, + State: &readyState, + CreatedAt: &createdAt, + Labels: config.Labels, + Annotations: config.Annotations, }, - Annotations: config.Annotations, } return podSandboxID, nil @@ -169,7 +165,7 @@ func (r *FakeRuntimeService) PodSandboxStatus(podSandboxID string) (*runtimeApi. return &runtimeApi.PodSandboxStatus{ Id: &podSandboxID, - Name: s.Name, + Metadata: s.Metadata, CreatedAt: s.CreatedAt, State: s.State, Network: &runtimeApi.PodSandboxNetworkStatus{ @@ -192,7 +188,7 @@ func (r *FakeRuntimeService) ListPodSandbox(filter *runtimeApi.PodSandboxFilter) if filter.Id != nil && filter.GetId() != id { continue } - if filter.Name != nil && filter.GetName() != s.GetName() { + if filter.Name != nil && filter.GetName() != s.Metadata.GetName() { continue } if filter.State != nil && filter.GetState() != s.GetState() { @@ -205,7 +201,7 @@ func (r *FakeRuntimeService) ListPodSandbox(filter *runtimeApi.PodSandboxFilter) result = append(result, &runtimeApi.PodSandbox{ Id: s.Id, - Name: s.Name, + Metadata: s.Metadata, State: s.State, CreatedAt: s.CreatedAt, Labels: s.Labels, @@ -222,15 +218,15 @@ func (r *FakeRuntimeService) CreateContainer(podSandboxID string, config *runtim r.Called = append(r.Called, "CreateContainer") // ContainerID should be randomized for real container runtime, but here just use - // container's name for easily making fake containers. - containerID := config.GetName() + // fixed BuildContainerName() for easily making fake containers. + containerID := BuildContainerName(config.Metadata) createdAt := time.Now().Unix() createdState := runtimeApi.ContainerState_CREATED imageRef := config.Image.GetImage() r.Containers[containerID] = &FakeContainer{ ContainerStatus: runtimeApi.ContainerStatus{ Id: &containerID, - Name: config.Name, + Metadata: config.Metadata, Image: config.Image, ImageRef: &imageRef, CreatedAt: &createdAt, @@ -308,7 +304,7 @@ func (r *FakeRuntimeService) ListContainers(filter *runtimeApi.ContainerFilter) if filter.Id != nil && filter.GetId() != s.GetId() { continue } - if filter.Name != nil && filter.GetName() != s.GetName() { + if filter.Name != nil && filter.GetName() != s.Metadata.GetName() { continue } if filter.PodSandboxId != nil && filter.GetPodSandboxId() != s.SandboxID { @@ -324,7 +320,7 @@ func (r *FakeRuntimeService) ListContainers(filter *runtimeApi.ContainerFilter) result = append(result, &runtimeApi.Container{ Id: s.Id, - Name: s.Name, + Metadata: s.Metadata, State: s.State, Image: s.Image, ImageRef: s.ImageRef, @@ -348,7 +344,7 @@ func (r *FakeRuntimeService) ContainerStatus(containerID string) (*runtimeApi.Co return &runtimeApi.ContainerStatus{ Id: c.Id, - Name: c.Name, + Metadata: c.Metadata, State: c.State, CreatedAt: c.CreatedAt, Image: c.Image, diff --git a/pkg/kubelet/api/testing/utils.go b/pkg/kubelet/api/testing/utils.go index 660ca338160..447386f2743 100644 --- a/pkg/kubelet/api/testing/utils.go +++ b/pkg/kubelet/api/testing/utils.go @@ -16,6 +16,20 @@ limitations under the License. package testing +import ( + "fmt" + + runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" +) + +func BuildContainerName(metadata *runtimeApi.ContainerMetadata) string { + return fmt.Sprintf("%s_%d", metadata.GetName(), metadata.GetAttempt()) +} + +func BuildSandboxName(metadata *runtimeApi.PodSandboxMetadata) string { + return fmt.Sprintf("%s_%s_%s_%d", metadata.GetName(), metadata.GetNamespace(), metadata.GetUid(), metadata.GetAttempt()) +} + func filterInLabels(filter, labels map[string]string) bool { for k, v := range filter { if value, ok := labels[k]; ok { diff --git a/pkg/kubelet/api/v1alpha1/runtime/api.pb.go b/pkg/kubelet/api/v1alpha1/runtime/api.pb.go index c9da02a6eb6..b09a00f8765 100644 --- a/pkg/kubelet/api/v1alpha1/runtime/api.pb.go +++ b/pkg/kubelet/api/v1alpha1/runtime/api.pb.go @@ -32,6 +32,7 @@ It has these top-level messages: Mount NamespaceOption LinuxPodSandboxConfig + PodSandboxMetadata PodSandboxConfig CreatePodSandboxRequest CreatePodSandboxResponse @@ -56,6 +57,7 @@ It has these top-level messages: Capability LinuxContainerConfig LinuxUser + ContainerMetadata ContainerConfig CreateContainerRequest CreateContainerResponse @@ -484,11 +486,63 @@ func (m *LinuxPodSandboxConfig) GetNamespaceOptions() *NamespaceOption { return nil } +// PodSandboxMetadata holds all necessary information for building the sandbox name. +// The container runtime is encouraged to expose the metadata associated with the +// PodSandbox in its user interface for better user experience. E.g., runtime can +// construct a unique PodSandboxName based on the metadata. +type PodSandboxMetadata struct { + // The pod name of the sandbox. Same as the pod name in the PodSpec. + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // The pod uid of the sandbox. Same as the pod UID in the PodSpec. + Uid *string `protobuf:"bytes,2,opt,name=uid" json:"uid,omitempty"` + // The pod namespace of the sandbox. Same as the pod namespace in the PodSpec. + Namespace *string `protobuf:"bytes,3,opt,name=namespace" json:"namespace,omitempty"` + // The attempt number of creating the sandbox. + Attempt *uint32 `protobuf:"varint,4,opt,name=attempt" json:"attempt,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *PodSandboxMetadata) Reset() { *m = PodSandboxMetadata{} } +func (m *PodSandboxMetadata) String() string { return proto.CompactTextString(m) } +func (*PodSandboxMetadata) ProtoMessage() {} +func (*PodSandboxMetadata) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{7} } + +func (m *PodSandboxMetadata) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *PodSandboxMetadata) GetUid() string { + if m != nil && m.Uid != nil { + return *m.Uid + } + return "" +} + +func (m *PodSandboxMetadata) GetNamespace() string { + if m != nil && m.Namespace != nil { + return *m.Namespace + } + return "" +} + +func (m *PodSandboxMetadata) GetAttempt() uint32 { + if m != nil && m.Attempt != nil { + return *m.Attempt + } + return 0 +} + // PodSandboxConfig holds all the required and optional fields for creating a // sandbox. type PodSandboxConfig struct { - // The name of the sandbox. - Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // The metadata of the sandbox. This information will uniquely identify + // the sandbox, and the runtime should leverage this to ensure correct + // operation. The runtime may also use this information to improve UX, such + // as by constructing a readable name. + Metadata *PodSandboxMetadata `protobuf:"bytes,1,opt,name=metadata" json:"metadata,omitempty"` // The hostname of the sandbox. Hostname *string `protobuf:"bytes,2,opt,name=hostname" json:"hostname,omitempty"` // Path to the directory on the host in which container log files are @@ -524,13 +578,13 @@ type PodSandboxConfig struct { func (m *PodSandboxConfig) Reset() { *m = PodSandboxConfig{} } func (m *PodSandboxConfig) String() string { return proto.CompactTextString(m) } func (*PodSandboxConfig) ProtoMessage() {} -func (*PodSandboxConfig) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{7} } +func (*PodSandboxConfig) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{8} } -func (m *PodSandboxConfig) GetName() string { - if m != nil && m.Name != nil { - return *m.Name +func (m *PodSandboxConfig) GetMetadata() *PodSandboxMetadata { + if m != nil { + return m.Metadata } - return "" + return nil } func (m *PodSandboxConfig) GetHostname() string { @@ -591,7 +645,7 @@ type CreatePodSandboxRequest struct { func (m *CreatePodSandboxRequest) Reset() { *m = CreatePodSandboxRequest{} } func (m *CreatePodSandboxRequest) String() string { return proto.CompactTextString(m) } func (*CreatePodSandboxRequest) ProtoMessage() {} -func (*CreatePodSandboxRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{8} } +func (*CreatePodSandboxRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{9} } func (m *CreatePodSandboxRequest) GetConfig() *PodSandboxConfig { if m != nil { @@ -609,7 +663,7 @@ type CreatePodSandboxResponse struct { func (m *CreatePodSandboxResponse) Reset() { *m = CreatePodSandboxResponse{} } func (m *CreatePodSandboxResponse) String() string { return proto.CompactTextString(m) } func (*CreatePodSandboxResponse) ProtoMessage() {} -func (*CreatePodSandboxResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{9} } +func (*CreatePodSandboxResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{10} } func (m *CreatePodSandboxResponse) GetPodSandboxId() string { if m != nil && m.PodSandboxId != nil { @@ -627,7 +681,7 @@ type StopPodSandboxRequest struct { func (m *StopPodSandboxRequest) Reset() { *m = StopPodSandboxRequest{} } func (m *StopPodSandboxRequest) String() string { return proto.CompactTextString(m) } func (*StopPodSandboxRequest) ProtoMessage() {} -func (*StopPodSandboxRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{10} } +func (*StopPodSandboxRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{11} } func (m *StopPodSandboxRequest) GetPodSandboxId() string { if m != nil && m.PodSandboxId != nil { @@ -643,7 +697,7 @@ type StopPodSandboxResponse struct { func (m *StopPodSandboxResponse) Reset() { *m = StopPodSandboxResponse{} } func (m *StopPodSandboxResponse) String() string { return proto.CompactTextString(m) } func (*StopPodSandboxResponse) ProtoMessage() {} -func (*StopPodSandboxResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{11} } +func (*StopPodSandboxResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{12} } type RemovePodSandboxRequest struct { // The id of the PodSandBox @@ -654,7 +708,7 @@ type RemovePodSandboxRequest struct { func (m *RemovePodSandboxRequest) Reset() { *m = RemovePodSandboxRequest{} } func (m *RemovePodSandboxRequest) String() string { return proto.CompactTextString(m) } func (*RemovePodSandboxRequest) ProtoMessage() {} -func (*RemovePodSandboxRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{12} } +func (*RemovePodSandboxRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{13} } func (m *RemovePodSandboxRequest) GetPodSandboxId() string { if m != nil && m.PodSandboxId != nil { @@ -670,7 +724,7 @@ type RemovePodSandboxResponse struct { func (m *RemovePodSandboxResponse) Reset() { *m = RemovePodSandboxResponse{} } func (m *RemovePodSandboxResponse) String() string { return proto.CompactTextString(m) } func (*RemovePodSandboxResponse) ProtoMessage() {} -func (*RemovePodSandboxResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{13} } +func (*RemovePodSandboxResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{14} } type PodSandboxStatusRequest struct { // The id of the PodSandBox @@ -681,7 +735,7 @@ type PodSandboxStatusRequest struct { func (m *PodSandboxStatusRequest) Reset() { *m = PodSandboxStatusRequest{} } func (m *PodSandboxStatusRequest) String() string { return proto.CompactTextString(m) } func (*PodSandboxStatusRequest) ProtoMessage() {} -func (*PodSandboxStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{14} } +func (*PodSandboxStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{15} } func (m *PodSandboxStatusRequest) GetPodSandboxId() string { if m != nil && m.PodSandboxId != nil { @@ -700,7 +754,7 @@ type PodSandboxNetworkStatus struct { func (m *PodSandboxNetworkStatus) Reset() { *m = PodSandboxNetworkStatus{} } func (m *PodSandboxNetworkStatus) String() string { return proto.CompactTextString(m) } func (*PodSandboxNetworkStatus) ProtoMessage() {} -func (*PodSandboxNetworkStatus) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{15} } +func (*PodSandboxNetworkStatus) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{16} } func (m *PodSandboxNetworkStatus) GetIp() string { if m != nil && m.Ip != nil { @@ -721,7 +775,7 @@ type Namespace struct { func (m *Namespace) Reset() { *m = Namespace{} } func (m *Namespace) String() string { return proto.CompactTextString(m) } func (*Namespace) ProtoMessage() {} -func (*Namespace) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{16} } +func (*Namespace) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{17} } func (m *Namespace) GetNetwork() string { if m != nil && m.Network != nil { @@ -747,7 +801,7 @@ type LinuxPodSandboxStatus struct { func (m *LinuxPodSandboxStatus) Reset() { *m = LinuxPodSandboxStatus{} } func (m *LinuxPodSandboxStatus) String() string { return proto.CompactTextString(m) } func (*LinuxPodSandboxStatus) ProtoMessage() {} -func (*LinuxPodSandboxStatus) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{17} } +func (*LinuxPodSandboxStatus) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{18} } func (m *LinuxPodSandboxStatus) GetNamespaces() *Namespace { if m != nil { @@ -760,8 +814,8 @@ func (m *LinuxPodSandboxStatus) GetNamespaces() *Namespace { type PodSandboxStatus struct { // ID of the sandbox. Id *string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - // Name of the sandbox - Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + // Metadata of the sandbox. + Metadata *PodSandboxMetadata `protobuf:"bytes,2,opt,name=metadata" json:"metadata,omitempty"` // State of the sandbox. State *PodSandBoxState `protobuf:"varint,3,opt,name=state,enum=runtime.PodSandBoxState" json:"state,omitempty"` // Creation timestamp of the sandbox @@ -781,7 +835,7 @@ type PodSandboxStatus struct { func (m *PodSandboxStatus) Reset() { *m = PodSandboxStatus{} } func (m *PodSandboxStatus) String() string { return proto.CompactTextString(m) } func (*PodSandboxStatus) ProtoMessage() {} -func (*PodSandboxStatus) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{18} } +func (*PodSandboxStatus) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{19} } func (m *PodSandboxStatus) GetId() string { if m != nil && m.Id != nil { @@ -790,11 +844,11 @@ func (m *PodSandboxStatus) GetId() string { return "" } -func (m *PodSandboxStatus) GetName() string { - if m != nil && m.Name != nil { - return *m.Name +func (m *PodSandboxStatus) GetMetadata() *PodSandboxMetadata { + if m != nil { + return m.Metadata } - return "" + return nil } func (m *PodSandboxStatus) GetState() PodSandBoxState { @@ -848,7 +902,7 @@ type PodSandboxStatusResponse struct { func (m *PodSandboxStatusResponse) Reset() { *m = PodSandboxStatusResponse{} } func (m *PodSandboxStatusResponse) String() string { return proto.CompactTextString(m) } func (*PodSandboxStatusResponse) ProtoMessage() {} -func (*PodSandboxStatusResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{19} } +func (*PodSandboxStatusResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{20} } func (m *PodSandboxStatusResponse) GetStatus() *PodSandboxStatus { if m != nil { @@ -876,7 +930,7 @@ type PodSandboxFilter struct { func (m *PodSandboxFilter) Reset() { *m = PodSandboxFilter{} } func (m *PodSandboxFilter) String() string { return proto.CompactTextString(m) } func (*PodSandboxFilter) ProtoMessage() {} -func (*PodSandboxFilter) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{20} } +func (*PodSandboxFilter) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{21} } func (m *PodSandboxFilter) GetName() string { if m != nil && m.Name != nil { @@ -915,7 +969,7 @@ type ListPodSandboxRequest struct { func (m *ListPodSandboxRequest) Reset() { *m = ListPodSandboxRequest{} } func (m *ListPodSandboxRequest) String() string { return proto.CompactTextString(m) } func (*ListPodSandboxRequest) ProtoMessage() {} -func (*ListPodSandboxRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{21} } +func (*ListPodSandboxRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{22} } func (m *ListPodSandboxRequest) GetFilter() *PodSandboxFilter { if m != nil { @@ -928,8 +982,8 @@ func (m *ListPodSandboxRequest) GetFilter() *PodSandboxFilter { type PodSandbox struct { // The id of the PodSandbox Id *string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - // The name of the PodSandbox - Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + // Metadata of the sandbox + Metadata *PodSandboxMetadata `protobuf:"bytes,2,opt,name=metadata" json:"metadata,omitempty"` // The state of the PodSandbox State *PodSandBoxState `protobuf:"varint,3,opt,name=state,enum=runtime.PodSandBoxState" json:"state,omitempty"` // Creation timestamps of the sandbox @@ -942,7 +996,7 @@ type PodSandbox struct { func (m *PodSandbox) Reset() { *m = PodSandbox{} } func (m *PodSandbox) String() string { return proto.CompactTextString(m) } func (*PodSandbox) ProtoMessage() {} -func (*PodSandbox) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{22} } +func (*PodSandbox) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{23} } func (m *PodSandbox) GetId() string { if m != nil && m.Id != nil { @@ -951,11 +1005,11 @@ func (m *PodSandbox) GetId() string { return "" } -func (m *PodSandbox) GetName() string { - if m != nil && m.Name != nil { - return *m.Name +func (m *PodSandbox) GetMetadata() *PodSandboxMetadata { + if m != nil { + return m.Metadata } - return "" + return nil } func (m *PodSandbox) GetState() PodSandBoxState { @@ -988,7 +1042,7 @@ type ListPodSandboxResponse struct { func (m *ListPodSandboxResponse) Reset() { *m = ListPodSandboxResponse{} } func (m *ListPodSandboxResponse) String() string { return proto.CompactTextString(m) } func (*ListPodSandboxResponse) ProtoMessage() {} -func (*ListPodSandboxResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{23} } +func (*ListPodSandboxResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{24} } func (m *ListPodSandboxResponse) GetItems() []*PodSandbox { if m != nil { @@ -1009,7 +1063,7 @@ type ImageSpec struct { func (m *ImageSpec) Reset() { *m = ImageSpec{} } func (m *ImageSpec) String() string { return proto.CompactTextString(m) } func (*ImageSpec) ProtoMessage() {} -func (*ImageSpec) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{24} } +func (*ImageSpec) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{25} } func (m *ImageSpec) GetImage() string { if m != nil && m.Image != nil { @@ -1027,7 +1081,7 @@ type KeyValue struct { func (m *KeyValue) Reset() { *m = KeyValue{} } func (m *KeyValue) String() string { return proto.CompactTextString(m) } func (*KeyValue) ProtoMessage() {} -func (*KeyValue) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{25} } +func (*KeyValue) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{26} } func (m *KeyValue) GetKey() string { if m != nil && m.Key != nil { @@ -1064,7 +1118,7 @@ type LinuxContainerResources struct { func (m *LinuxContainerResources) Reset() { *m = LinuxContainerResources{} } func (m *LinuxContainerResources) String() string { return proto.CompactTextString(m) } func (*LinuxContainerResources) ProtoMessage() {} -func (*LinuxContainerResources) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{26} } +func (*LinuxContainerResources) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{27} } func (m *LinuxContainerResources) GetCpuPeriod() int64 { if m != nil && m.CpuPeriod != nil { @@ -1113,7 +1167,7 @@ type SELinuxOption struct { func (m *SELinuxOption) Reset() { *m = SELinuxOption{} } func (m *SELinuxOption) String() string { return proto.CompactTextString(m) } func (*SELinuxOption) ProtoMessage() {} -func (*SELinuxOption) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{27} } +func (*SELinuxOption) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{28} } func (m *SELinuxOption) GetUser() string { if m != nil && m.User != nil { @@ -1155,7 +1209,7 @@ type Capability struct { func (m *Capability) Reset() { *m = Capability{} } func (m *Capability) String() string { return proto.CompactTextString(m) } func (*Capability) ProtoMessage() {} -func (*Capability) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{28} } +func (*Capability) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{29} } func (m *Capability) GetAddCapabilities() []string { if m != nil { @@ -1188,7 +1242,7 @@ type LinuxContainerConfig struct { func (m *LinuxContainerConfig) Reset() { *m = LinuxContainerConfig{} } func (m *LinuxContainerConfig) String() string { return proto.CompactTextString(m) } func (*LinuxContainerConfig) ProtoMessage() {} -func (*LinuxContainerConfig) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{29} } +func (*LinuxContainerConfig) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{30} } func (m *LinuxContainerConfig) GetResources() *LinuxContainerResources { if m != nil { @@ -1231,7 +1285,7 @@ type LinuxUser struct { func (m *LinuxUser) Reset() { *m = LinuxUser{} } func (m *LinuxUser) String() string { return proto.CompactTextString(m) } func (*LinuxUser) ProtoMessage() {} -func (*LinuxUser) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{30} } +func (*LinuxUser) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{31} } func (m *LinuxUser) GetUid() int64 { if m != nil && m.Uid != nil { @@ -1254,9 +1308,46 @@ func (m *LinuxUser) GetAdditionalGids() []int64 { return nil } -type ContainerConfig struct { - // Name of the container. +// ContainerMetadata holds all necessary information for building the container +// name. The container runtime is encouraged to expose the metadata in its user +// interface for better user experience. E.g., runtime can construct a unique +// container name based on the metadata. Note that (name, attempt) is unique +// within a sandbox for the entire lifetime of the sandbox. +type ContainerMetadata struct { + // The name of the container. Same as the container name in the PodSpec. Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // The attempt number of creating the container. + Attempt *uint32 `protobuf:"varint,2,opt,name=attempt" json:"attempt,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ContainerMetadata) Reset() { *m = ContainerMetadata{} } +func (m *ContainerMetadata) String() string { return proto.CompactTextString(m) } +func (*ContainerMetadata) ProtoMessage() {} +func (*ContainerMetadata) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{32} } + +func (m *ContainerMetadata) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *ContainerMetadata) GetAttempt() uint32 { + if m != nil && m.Attempt != nil { + return *m.Attempt + } + return 0 +} + +// ContainerConfig holds all the required and optional fields for creating a +// container. +type ContainerConfig struct { + // The metadata of the container. This information will uniquely identify + // the container, and the runtime should leverage this to ensure correct + // operation. The runtime may also use this information to improve UX, such + // as by constructing a readable name. + Metadata *ContainerMetadata `protobuf:"bytes,1,opt,name=metadata" json:"metadata,omitempty"` // Image to use. Image *ImageSpec `protobuf:"bytes,2,opt,name=image" json:"image,omitempty"` // Command to execute (i.e., entrypoint for docker) @@ -1310,13 +1401,13 @@ type ContainerConfig struct { func (m *ContainerConfig) Reset() { *m = ContainerConfig{} } func (m *ContainerConfig) String() string { return proto.CompactTextString(m) } func (*ContainerConfig) ProtoMessage() {} -func (*ContainerConfig) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{31} } +func (*ContainerConfig) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{33} } -func (m *ContainerConfig) GetName() string { - if m != nil && m.Name != nil { - return *m.Name +func (m *ContainerConfig) GetMetadata() *ContainerMetadata { + if m != nil { + return m.Metadata } - return "" + return nil } func (m *ContainerConfig) GetImage() *ImageSpec { @@ -1437,7 +1528,7 @@ type CreateContainerRequest struct { func (m *CreateContainerRequest) Reset() { *m = CreateContainerRequest{} } func (m *CreateContainerRequest) String() string { return proto.CompactTextString(m) } func (*CreateContainerRequest) ProtoMessage() {} -func (*CreateContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{32} } +func (*CreateContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{34} } func (m *CreateContainerRequest) GetPodSandboxId() string { if m != nil && m.PodSandboxId != nil { @@ -1469,7 +1560,7 @@ type CreateContainerResponse struct { func (m *CreateContainerResponse) Reset() { *m = CreateContainerResponse{} } func (m *CreateContainerResponse) String() string { return proto.CompactTextString(m) } func (*CreateContainerResponse) ProtoMessage() {} -func (*CreateContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{33} } +func (*CreateContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{35} } func (m *CreateContainerResponse) GetContainerId() string { if m != nil && m.ContainerId != nil { @@ -1487,7 +1578,7 @@ type StartContainerRequest struct { func (m *StartContainerRequest) Reset() { *m = StartContainerRequest{} } func (m *StartContainerRequest) String() string { return proto.CompactTextString(m) } func (*StartContainerRequest) ProtoMessage() {} -func (*StartContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{34} } +func (*StartContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{36} } func (m *StartContainerRequest) GetContainerId() string { if m != nil && m.ContainerId != nil { @@ -1503,7 +1594,7 @@ type StartContainerResponse struct { func (m *StartContainerResponse) Reset() { *m = StartContainerResponse{} } func (m *StartContainerResponse) String() string { return proto.CompactTextString(m) } func (*StartContainerResponse) ProtoMessage() {} -func (*StartContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{35} } +func (*StartContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{37} } type StopContainerRequest struct { // The id of the container @@ -1516,7 +1607,7 @@ type StopContainerRequest struct { func (m *StopContainerRequest) Reset() { *m = StopContainerRequest{} } func (m *StopContainerRequest) String() string { return proto.CompactTextString(m) } func (*StopContainerRequest) ProtoMessage() {} -func (*StopContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{36} } +func (*StopContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{38} } func (m *StopContainerRequest) GetContainerId() string { if m != nil && m.ContainerId != nil { @@ -1539,7 +1630,7 @@ type StopContainerResponse struct { func (m *StopContainerResponse) Reset() { *m = StopContainerResponse{} } func (m *StopContainerResponse) String() string { return proto.CompactTextString(m) } func (*StopContainerResponse) ProtoMessage() {} -func (*StopContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{37} } +func (*StopContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{39} } type RemoveContainerRequest struct { // The id of the container @@ -1550,7 +1641,7 @@ type RemoveContainerRequest struct { func (m *RemoveContainerRequest) Reset() { *m = RemoveContainerRequest{} } func (m *RemoveContainerRequest) String() string { return proto.CompactTextString(m) } func (*RemoveContainerRequest) ProtoMessage() {} -func (*RemoveContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{38} } +func (*RemoveContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{40} } func (m *RemoveContainerRequest) GetContainerId() string { if m != nil && m.ContainerId != nil { @@ -1566,7 +1657,7 @@ type RemoveContainerResponse struct { func (m *RemoveContainerResponse) Reset() { *m = RemoveContainerResponse{} } func (m *RemoveContainerResponse) String() string { return proto.CompactTextString(m) } func (*RemoveContainerResponse) ProtoMessage() {} -func (*RemoveContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{39} } +func (*RemoveContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{41} } // ContainerFilter is used to filter containers. // All those fields are combined with 'AND' @@ -1589,7 +1680,7 @@ type ContainerFilter struct { func (m *ContainerFilter) Reset() { *m = ContainerFilter{} } func (m *ContainerFilter) String() string { return proto.CompactTextString(m) } func (*ContainerFilter) ProtoMessage() {} -func (*ContainerFilter) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{40} } +func (*ContainerFilter) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{42} } func (m *ContainerFilter) GetName() string { if m != nil && m.Name != nil { @@ -1634,7 +1725,7 @@ type ListContainersRequest struct { func (m *ListContainersRequest) Reset() { *m = ListContainersRequest{} } func (m *ListContainersRequest) String() string { return proto.CompactTextString(m) } func (*ListContainersRequest) ProtoMessage() {} -func (*ListContainersRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{41} } +func (*ListContainersRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{43} } func (m *ListContainersRequest) GetFilter() *ContainerFilter { if m != nil { @@ -1649,8 +1740,8 @@ type Container struct { // The ID of the container, used by the container runtime to identify // a container. Id *string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - // The name of the container - Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + // The metadata of the container. + Metadata *ContainerMetadata `protobuf:"bytes,2,opt,name=metadata" json:"metadata,omitempty"` // The spec of the image Image *ImageSpec `protobuf:"bytes,3,opt,name=image" json:"image,omitempty"` // Reference to the image in use. For most runtimes, this should be an @@ -1669,7 +1760,7 @@ type Container struct { func (m *Container) Reset() { *m = Container{} } func (m *Container) String() string { return proto.CompactTextString(m) } func (*Container) ProtoMessage() {} -func (*Container) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{42} } +func (*Container) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{44} } func (m *Container) GetId() string { if m != nil && m.Id != nil { @@ -1678,11 +1769,11 @@ func (m *Container) GetId() string { return "" } -func (m *Container) GetName() string { - if m != nil && m.Name != nil { - return *m.Name +func (m *Container) GetMetadata() *ContainerMetadata { + if m != nil { + return m.Metadata } - return "" + return nil } func (m *Container) GetImage() *ImageSpec { @@ -1729,7 +1820,7 @@ type ListContainersResponse struct { func (m *ListContainersResponse) Reset() { *m = ListContainersResponse{} } func (m *ListContainersResponse) String() string { return proto.CompactTextString(m) } func (*ListContainersResponse) ProtoMessage() {} -func (*ListContainersResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{43} } +func (*ListContainersResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{45} } func (m *ListContainersResponse) GetContainers() []*Container { if m != nil { @@ -1747,7 +1838,7 @@ type ContainerStatusRequest struct { func (m *ContainerStatusRequest) Reset() { *m = ContainerStatusRequest{} } func (m *ContainerStatusRequest) String() string { return proto.CompactTextString(m) } func (*ContainerStatusRequest) ProtoMessage() {} -func (*ContainerStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{44} } +func (*ContainerStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{46} } func (m *ContainerStatusRequest) GetContainerId() string { if m != nil && m.ContainerId != nil { @@ -1760,8 +1851,8 @@ func (m *ContainerStatusRequest) GetContainerId() string { type ContainerStatus struct { // ID of the container. Id *string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - // Name of the container. - Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + // Metadata of the container. + Metadata *ContainerMetadata `protobuf:"bytes,2,opt,name=metadata" json:"metadata,omitempty"` // Status of the container. State *ContainerState `protobuf:"varint,3,opt,name=state,enum=runtime.ContainerState" json:"state,omitempty"` // Creation time of the container. @@ -1791,7 +1882,7 @@ type ContainerStatus struct { func (m *ContainerStatus) Reset() { *m = ContainerStatus{} } func (m *ContainerStatus) String() string { return proto.CompactTextString(m) } func (*ContainerStatus) ProtoMessage() {} -func (*ContainerStatus) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{45} } +func (*ContainerStatus) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{47} } func (m *ContainerStatus) GetId() string { if m != nil && m.Id != nil { @@ -1800,11 +1891,11 @@ func (m *ContainerStatus) GetId() string { return "" } -func (m *ContainerStatus) GetName() string { - if m != nil && m.Name != nil { - return *m.Name +func (m *ContainerStatus) GetMetadata() *ContainerMetadata { + if m != nil { + return m.Metadata } - return "" + return nil } func (m *ContainerStatus) GetState() ContainerState { @@ -1893,7 +1984,7 @@ type ContainerStatusResponse struct { func (m *ContainerStatusResponse) Reset() { *m = ContainerStatusResponse{} } func (m *ContainerStatusResponse) String() string { return proto.CompactTextString(m) } func (*ContainerStatusResponse) ProtoMessage() {} -func (*ContainerStatusResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{46} } +func (*ContainerStatusResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{48} } func (m *ContainerStatusResponse) GetStatus() *ContainerStatus { if m != nil { @@ -1917,7 +2008,7 @@ type ExecRequest struct { func (m *ExecRequest) Reset() { *m = ExecRequest{} } func (m *ExecRequest) String() string { return proto.CompactTextString(m) } func (*ExecRequest) ProtoMessage() {} -func (*ExecRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{47} } +func (*ExecRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{49} } func (m *ExecRequest) GetContainerId() string { if m != nil && m.ContainerId != nil { @@ -1958,7 +2049,7 @@ type ExecResponse struct { func (m *ExecResponse) Reset() { *m = ExecResponse{} } func (m *ExecResponse) String() string { return proto.CompactTextString(m) } func (*ExecResponse) ProtoMessage() {} -func (*ExecResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{48} } +func (*ExecResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{50} } func (m *ExecResponse) GetStdout() []byte { if m != nil { @@ -1983,7 +2074,7 @@ type ImageFilter struct { func (m *ImageFilter) Reset() { *m = ImageFilter{} } func (m *ImageFilter) String() string { return proto.CompactTextString(m) } func (*ImageFilter) ProtoMessage() {} -func (*ImageFilter) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{49} } +func (*ImageFilter) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{51} } func (m *ImageFilter) GetImage() *ImageSpec { if m != nil { @@ -2001,7 +2092,7 @@ type ListImagesRequest struct { func (m *ListImagesRequest) Reset() { *m = ListImagesRequest{} } func (m *ListImagesRequest) String() string { return proto.CompactTextString(m) } func (*ListImagesRequest) ProtoMessage() {} -func (*ListImagesRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{50} } +func (*ListImagesRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{52} } func (m *ListImagesRequest) GetFilter() *ImageFilter { if m != nil { @@ -2026,7 +2117,7 @@ type Image struct { func (m *Image) Reset() { *m = Image{} } func (m *Image) String() string { return proto.CompactTextString(m) } func (*Image) ProtoMessage() {} -func (*Image) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{51} } +func (*Image) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{53} } func (m *Image) GetId() string { if m != nil && m.Id != nil { @@ -2065,7 +2156,7 @@ type ListImagesResponse struct { func (m *ListImagesResponse) Reset() { *m = ListImagesResponse{} } func (m *ListImagesResponse) String() string { return proto.CompactTextString(m) } func (*ListImagesResponse) ProtoMessage() {} -func (*ListImagesResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{52} } +func (*ListImagesResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{54} } func (m *ListImagesResponse) GetImages() []*Image { if m != nil { @@ -2083,7 +2174,7 @@ type ImageStatusRequest struct { func (m *ImageStatusRequest) Reset() { *m = ImageStatusRequest{} } func (m *ImageStatusRequest) String() string { return proto.CompactTextString(m) } func (*ImageStatusRequest) ProtoMessage() {} -func (*ImageStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{53} } +func (*ImageStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{55} } func (m *ImageStatusRequest) GetImage() *ImageSpec { if m != nil { @@ -2101,7 +2192,7 @@ type ImageStatusResponse struct { func (m *ImageStatusResponse) Reset() { *m = ImageStatusResponse{} } func (m *ImageStatusResponse) String() string { return proto.CompactTextString(m) } func (*ImageStatusResponse) ProtoMessage() {} -func (*ImageStatusResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{54} } +func (*ImageStatusResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{56} } func (m *ImageStatusResponse) GetImage() *Image { if m != nil { @@ -2127,7 +2218,7 @@ type AuthConfig struct { func (m *AuthConfig) Reset() { *m = AuthConfig{} } func (m *AuthConfig) String() string { return proto.CompactTextString(m) } func (*AuthConfig) ProtoMessage() {} -func (*AuthConfig) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{55} } +func (*AuthConfig) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{57} } func (m *AuthConfig) GetUsername() string { if m != nil && m.Username != nil { @@ -2184,7 +2275,7 @@ type PullImageRequest struct { func (m *PullImageRequest) Reset() { *m = PullImageRequest{} } func (m *PullImageRequest) String() string { return proto.CompactTextString(m) } func (*PullImageRequest) ProtoMessage() {} -func (*PullImageRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{56} } +func (*PullImageRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{58} } func (m *PullImageRequest) GetImage() *ImageSpec { if m != nil { @@ -2214,7 +2305,7 @@ type PullImageResponse struct { func (m *PullImageResponse) Reset() { *m = PullImageResponse{} } func (m *PullImageResponse) String() string { return proto.CompactTextString(m) } func (*PullImageResponse) ProtoMessage() {} -func (*PullImageResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{57} } +func (*PullImageResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{59} } type RemoveImageRequest struct { // The spec of the image @@ -2225,7 +2316,7 @@ type RemoveImageRequest struct { func (m *RemoveImageRequest) Reset() { *m = RemoveImageRequest{} } func (m *RemoveImageRequest) String() string { return proto.CompactTextString(m) } func (*RemoveImageRequest) ProtoMessage() {} -func (*RemoveImageRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{58} } +func (*RemoveImageRequest) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{60} } func (m *RemoveImageRequest) GetImage() *ImageSpec { if m != nil { @@ -2241,7 +2332,7 @@ type RemoveImageResponse struct { func (m *RemoveImageResponse) Reset() { *m = RemoveImageResponse{} } func (m *RemoveImageResponse) String() string { return proto.CompactTextString(m) } func (*RemoveImageResponse) ProtoMessage() {} -func (*RemoveImageResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{59} } +func (*RemoveImageResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, []int{61} } func init() { proto.RegisterType((*VersionRequest)(nil), "runtime.VersionRequest") @@ -2251,6 +2342,7 @@ func init() { proto.RegisterType((*Mount)(nil), "runtime.Mount") proto.RegisterType((*NamespaceOption)(nil), "runtime.NamespaceOption") proto.RegisterType((*LinuxPodSandboxConfig)(nil), "runtime.LinuxPodSandboxConfig") + proto.RegisterType((*PodSandboxMetadata)(nil), "runtime.PodSandboxMetadata") proto.RegisterType((*PodSandboxConfig)(nil), "runtime.PodSandboxConfig") proto.RegisterType((*CreatePodSandboxRequest)(nil), "runtime.CreatePodSandboxRequest") proto.RegisterType((*CreatePodSandboxResponse)(nil), "runtime.CreatePodSandboxResponse") @@ -2275,6 +2367,7 @@ func init() { proto.RegisterType((*Capability)(nil), "runtime.Capability") proto.RegisterType((*LinuxContainerConfig)(nil), "runtime.LinuxContainerConfig") proto.RegisterType((*LinuxUser)(nil), "runtime.LinuxUser") + proto.RegisterType((*ContainerMetadata)(nil), "runtime.ContainerMetadata") proto.RegisterType((*ContainerConfig)(nil), "runtime.ContainerConfig") proto.RegisterType((*CreateContainerRequest)(nil), "runtime.CreateContainerRequest") proto.RegisterType((*CreateContainerResponse)(nil), "runtime.CreateContainerResponse") @@ -3022,177 +3115,182 @@ var _ImageService_serviceDesc = grpc.ServiceDesc{ } var fileDescriptorApi = []byte{ - // 2747 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x1a, 0x4d, 0x73, 0xdb, 0xc6, - 0xd5, 0x14, 0x45, 0x89, 0x7c, 0x14, 0x29, 0x6a, 0x2d, 0x4b, 0x34, 0x1d, 0xdb, 0x32, 0x92, 0xb4, - 0xb6, 0x92, 0x68, 0x5c, 0xb5, 0xd3, 0xd4, 0x4e, 0xe2, 0x58, 0x91, 0x54, 0x8f, 0x62, 0x59, 0x56, - 0x41, 0xdb, 0x8d, 0x4f, 0x18, 0x98, 0x58, 0x49, 0xb0, 0x49, 0x00, 0x01, 0x40, 0xd5, 0xea, 0xb5, - 0xbf, 0xa1, 0xe7, 0xf6, 0xd0, 0x99, 0x9e, 0x7a, 0xe9, 0x4c, 0xff, 0x44, 0x3b, 0x3d, 0xf5, 0x77, - 0xf4, 0xd4, 0x4b, 0x2f, 0x9d, 0xf6, 0xed, 0x07, 0x16, 0x8b, 0x0f, 0xca, 0x92, 0x33, 0x53, 0xe7, - 0x86, 0x7d, 0xef, 0xed, 0xdb, 0xb7, 0xef, 0xbd, 0x7d, 0x1f, 0xbb, 0x80, 0x86, 0x1d, 0xb8, 0x6b, - 0x41, 0xe8, 0xc7, 0x3e, 0x99, 0x0d, 0xc7, 0x5e, 0xec, 0x8e, 0xa8, 0xb1, 0x0a, 0xed, 0x67, 0x34, - 0x8c, 0x5c, 0xdf, 0x33, 0xe9, 0xb7, 0x63, 0x1a, 0xc5, 0xa4, 0x0b, 0xb3, 0xc7, 0x02, 0xd2, 0xad, - 0xac, 0x54, 0x6e, 0x36, 0xcc, 0x64, 0x68, 0xfc, 0xb1, 0x02, 0xf3, 0x8a, 0x38, 0x0a, 0x7c, 0x2f, - 0xa2, 0x93, 0xa9, 0xc9, 0x0d, 0x98, 0x93, 0x8b, 0x58, 0x9e, 0x3d, 0xa2, 0xdd, 0x29, 0x8e, 0x6e, - 0x4a, 0xd8, 0x1e, 0x82, 0xc8, 0x0f, 0x61, 0x3e, 0x21, 0x49, 0x98, 0x54, 0x39, 0x55, 0x5b, 0x82, - 0xe5, 0x6a, 0x64, 0x0d, 0x2e, 0x26, 0x84, 0xb8, 0x07, 0x45, 0x3c, 0xcd, 0x89, 0x17, 0x24, 0x6a, - 0x23, 0x70, 0x25, 0xbd, 0xb1, 0x01, 0x8d, 0xad, 0xbd, 0xfe, 0xe3, 0x20, 0x66, 0x93, 0x51, 0xc4, - 0x88, 0x86, 0x6c, 0x0e, 0x8a, 0x58, 0x65, 0x22, 0xca, 0x21, 0xe9, 0x41, 0x3d, 0xa2, 0x76, 0x38, - 0x38, 0xa2, 0x11, 0x8a, 0xc7, 0x50, 0x6a, 0x6c, 0xfc, 0xa9, 0x02, 0xcd, 0x7d, 0x3f, 0x8c, 0x1f, - 0xd9, 0x41, 0xe0, 0x7a, 0x87, 0x84, 0xc0, 0x34, 0xdf, 0x86, 0xd8, 0x25, 0xff, 0x26, 0x9f, 0x40, - 0x9d, 0xab, 0x73, 0xe0, 0x0f, 0xf9, 0xf6, 0xda, 0xeb, 0x0b, 0x6b, 0x52, 0x98, 0xb5, 0x7d, 0x89, - 0x30, 0x15, 0x09, 0xf9, 0x10, 0xda, 0x03, 0xdf, 0x8b, 0x6d, 0xd7, 0xa3, 0xa1, 0x15, 0x20, 0x6f, - 0xbe, 0xdb, 0x9a, 0xd9, 0x52, 0x50, 0xb6, 0x20, 0xb9, 0x02, 0x8d, 0x23, 0x3f, 0x8a, 0x05, 0xc5, - 0x34, 0xa7, 0xa8, 0x33, 0x00, 0x47, 0x2e, 0xc3, 0x2c, 0x47, 0xba, 0x41, 0xb7, 0xc6, 0x25, 0x99, - 0x61, 0xc3, 0x9d, 0xc0, 0xf8, 0x43, 0x05, 0x6a, 0x8f, 0x7c, 0x5c, 0xbc, 0x54, 0xd2, 0xec, 0xd2, - 0x76, 0x7c, 0x24, 0xcd, 0xa1, 0x2d, 0x8d, 0xc0, 0x74, 0x69, 0x46, 0x21, 0x4c, 0x21, 0x96, 0x66, - 0x48, 0xd4, 0x56, 0x48, 0x6d, 0xc7, 0xf7, 0x86, 0x27, 0x5c, 0xac, 0xba, 0xa9, 0xc6, 0xcc, 0x92, - 0x11, 0x1d, 0xba, 0xde, 0xf8, 0xb5, 0x15, 0xd2, 0xa1, 0xfd, 0x82, 0x0e, 0xb9, 0x78, 0x75, 0xb3, - 0x2d, 0xc1, 0xa6, 0x80, 0x1a, 0x2f, 0x61, 0x9e, 0x99, 0x3e, 0x0a, 0xec, 0x01, 0x95, 0xf6, 0x41, - 0x47, 0xe1, 0x8b, 0x7a, 0x34, 0xfe, 0x95, 0x1f, 0xbe, 0xe2, 0x72, 0xd7, 0xcd, 0x26, 0x83, 0xed, - 0x09, 0x10, 0xb9, 0x0c, 0x75, 0x21, 0x97, 0xeb, 0x70, 0xc1, 0xeb, 0x26, 0xd7, 0xc2, 0xbe, 0xeb, - 0x28, 0x94, 0x1b, 0x0c, 0xb8, 0xc4, 0x12, 0xb5, 0x13, 0x0c, 0x8c, 0xdf, 0x54, 0xe0, 0xd2, 0x2e, - 0x5b, 0x7c, 0xdf, 0x77, 0xfa, 0xb6, 0xe7, 0xbc, 0xf0, 0x5f, 0x6f, 0xfa, 0xde, 0x81, 0x7b, 0x48, - 0xde, 0x87, 0xd6, 0xe0, 0x30, 0xf4, 0xc7, 0x01, 0xee, 0x34, 0xa4, 0x5e, 0x2c, 0x75, 0x35, 0x27, - 0x80, 0xfb, 0x1c, 0x46, 0xb6, 0x61, 0xc1, 0x4b, 0x44, 0xb5, 0x7c, 0x2e, 0x6b, 0xc4, 0x57, 0x6f, - 0xae, 0x77, 0x95, 0x99, 0x73, 0x9b, 0x31, 0x3b, 0x5e, 0x16, 0x10, 0x19, 0xbf, 0x9d, 0x86, 0x4e, - 0x41, 0x80, 0x32, 0x1b, 0xf5, 0xc4, 0x4e, 0xb4, 0xc3, 0xa2, 0xc6, 0x4c, 0xe0, 0xa1, 0x7f, 0x68, - 0x39, 0x6e, 0x48, 0x07, 0xb1, 0x1f, 0x9e, 0x48, 0xe3, 0xcc, 0x21, 0x70, 0x2b, 0x81, 0x91, 0x1f, - 0x43, 0xd3, 0xf1, 0x22, 0x25, 0xea, 0x34, 0x17, 0x95, 0x28, 0x51, 0xd5, 0x89, 0x30, 0x01, 0xc9, - 0xa4, 0x78, 0xe4, 0x0e, 0xb4, 0x98, 0xa3, 0x59, 0x23, 0xe1, 0xe7, 0x11, 0xda, 0xad, 0x8a, 0xd3, - 0x16, 0x53, 0x47, 0x4e, 0x0f, 0x81, 0x39, 0x17, 0xa4, 0x83, 0x88, 0x7c, 0x01, 0x33, 0xdc, 0xa8, - 0x51, 0x77, 0x86, 0xcf, 0xf9, 0x50, 0x9b, 0x93, 0xdd, 0xef, 0xda, 0x2e, 0xa7, 0xdb, 0xf6, 0xe2, - 0xf0, 0xc4, 0x94, 0x93, 0xc8, 0x2e, 0x34, 0x6d, 0xcf, 0xf3, 0x63, 0x5b, 0x88, 0x3b, 0xcb, 0x79, - 0xac, 0x4e, 0xe6, 0xb1, 0x91, 0x12, 0x0b, 0x46, 0xfa, 0x74, 0xf2, 0x13, 0xa8, 0x71, 0x47, 0xeb, - 0xd6, 0xf9, 0xb6, 0xaf, 0x29, 0x3e, 0xa5, 0x1e, 0x60, 0x0a, 0xe2, 0xde, 0x1d, 0x68, 0x6a, 0xa2, - 0x91, 0x0e, 0x54, 0x5f, 0xd1, 0x13, 0x69, 0x15, 0xf6, 0x49, 0x16, 0xa1, 0x76, 0x6c, 0x0f, 0xc7, - 0x89, 0x45, 0xc4, 0xe0, 0xee, 0xd4, 0xcf, 0x2a, 0xbd, 0x7b, 0xd0, 0xc9, 0x4b, 0x74, 0x9e, 0xf9, - 0xc6, 0x2e, 0x2c, 0x6f, 0xe2, 0xf9, 0x89, 0x69, 0x2a, 0x5b, 0x12, 0x82, 0x7f, 0x04, 0x33, 0x03, - 0x2e, 0x26, 0xe7, 0xd4, 0x5c, 0xbf, 0x3c, 0x51, 0x29, 0xa6, 0x24, 0x34, 0xee, 0x43, 0xb7, 0xc8, - 0x4d, 0xc6, 0xe8, 0x0f, 0xa0, 0x1d, 0xf8, 0x8e, 0x15, 0x09, 0xb0, 0x85, 0x67, 0x48, 0xba, 0x7b, - 0xa0, 0x68, 0x77, 0x1c, 0xe3, 0x0b, 0xb8, 0xd4, 0x8f, 0xfd, 0xa0, 0x28, 0xcd, 0xd9, 0xa6, 0x77, - 0x61, 0x29, 0x3f, 0x5d, 0x2c, 0x6f, 0x7c, 0x09, 0xcb, 0x26, 0x1d, 0xf9, 0xc7, 0xf4, 0x6d, 0x59, - 0xf7, 0xa0, 0x5b, 0x64, 0x90, 0x32, 0x4f, 0xa1, 0x7d, 0x34, 0xc6, 0x38, 0x3a, 0x1f, 0xf3, 0x5b, - 0x3a, 0x03, 0x19, 0x6f, 0x04, 0x1f, 0xd2, 0x86, 0x29, 0x0c, 0xb3, 0x62, 0x12, 0x7e, 0x19, 0xcf, - 0xa1, 0xa1, 0x8e, 0x3b, 0xcb, 0x2a, 0x7a, 0xc0, 0xc2, 0xac, 0x22, 0x87, 0x64, 0x1d, 0x66, 0xcf, - 0x1a, 0x2d, 0x12, 0x42, 0xe3, 0x61, 0x21, 0x52, 0x49, 0x19, 0xd6, 0x01, 0x54, 0x44, 0x89, 0xa4, - 0x3b, 0x90, 0x22, 0x3f, 0x53, 0xa3, 0x32, 0xfe, 0x5b, 0xd5, 0x23, 0x8e, 0xb6, 0x19, 0x47, 0x6d, - 0xc6, 0x51, 0x11, 0x68, 0x4a, 0x8b, 0x40, 0x6b, 0x50, 0x8b, 0x90, 0x9a, 0xf2, 0xe8, 0xd2, 0xd6, - 0xe4, 0x96, 0xdc, 0xbe, 0x12, 0xdc, 0xa8, 0x29, 0xc8, 0xc8, 0x55, 0x80, 0x01, 0x77, 0x3a, 0xc7, - 0xb2, 0x45, 0xaa, 0xaa, 0x9a, 0x0d, 0x09, 0xd9, 0x88, 0xc9, 0xdd, 0x54, 0x45, 0x35, 0x2e, 0xf8, - 0x4a, 0x89, 0x1f, 0x67, 0x54, 0x9e, 0x2a, 0x51, 0x1d, 0xe7, 0x99, 0xd3, 0x8f, 0xb3, 0x9c, 0x27, - 0x88, 0xb5, 0x88, 0x34, 0x3b, 0x31, 0x22, 0x89, 0x19, 0x67, 0x89, 0x48, 0xf5, 0x89, 0x11, 0x49, - 0xf2, 0x38, 0x35, 0x22, 0xbd, 0xcb, 0xd8, 0xf2, 0x08, 0xba, 0xc5, 0x53, 0x21, 0xa3, 0x01, 0x06, - 0x97, 0x88, 0x43, 0x4e, 0x09, 0x2e, 0x72, 0x8a, 0x24, 0x34, 0xfe, 0x53, 0xd1, 0x1d, 0xea, 0xe7, - 0xee, 0x30, 0xa6, 0x61, 0x69, 0x0a, 0x13, 0x4e, 0x36, 0xa5, 0x9c, 0xec, 0xbc, 0x0e, 0xd5, 0x87, - 0x36, 0x37, 0x85, 0x85, 0x55, 0x03, 0x4f, 0x6a, 0xe8, 0x54, 0xcc, 0x06, 0x1f, 0x97, 0xc8, 0x28, - 0xc4, 0x10, 0x76, 0xec, 0x4b, 0x72, 0x61, 0x85, 0xd6, 0x50, 0x87, 0xf5, 0xee, 0x03, 0x29, 0x12, - 0x9d, 0x4b, 0x9d, 0x5f, 0xb3, 0xd3, 0xc9, 0x0a, 0xb0, 0x92, 0x40, 0x7d, 0xc0, 0xc5, 0x38, 0x45, - 0x97, 0x42, 0x4e, 0x53, 0x12, 0x1a, 0xff, 0xaa, 0x00, 0xa4, 0xc8, 0x77, 0x71, 0x2c, 0x3f, 0x55, - 0x87, 0x44, 0xa4, 0xfa, 0xeb, 0x25, 0x42, 0x97, 0x1d, 0x8f, 0xef, 0xe0, 0xd0, 0xc6, 0x26, 0x2c, - 0xe5, 0x35, 0x28, 0xdd, 0xf1, 0x16, 0xd4, 0xdc, 0x98, 0x8e, 0x44, 0x6d, 0xde, 0x5c, 0xbf, 0x58, - 0x22, 0x8c, 0x29, 0x28, 0x8c, 0x1b, 0xd0, 0xd8, 0x19, 0xd9, 0x87, 0xb4, 0x1f, 0xd0, 0x01, 0x5b, - 0xcb, 0x65, 0x03, 0xb9, 0xbe, 0x18, 0x18, 0xeb, 0x50, 0x7f, 0x48, 0x4f, 0x9e, 0xb1, 0x75, 0xcf, - 0x2a, 0x9f, 0xf1, 0xb7, 0x0a, 0x2c, 0xf3, 0xa8, 0xb2, 0x99, 0xd4, 0xc2, 0x28, 0x9c, 0x3f, 0x0e, - 0x31, 0x94, 0x72, 0x55, 0x06, 0x63, 0x2b, 0xa0, 0xa1, 0xeb, 0x0b, 0x33, 0x31, 0x55, 0x06, 0xe3, - 0x7d, 0x0e, 0x60, 0xf5, 0x32, 0x43, 0x7f, 0x3b, 0xc6, 0xa3, 0xca, 0x99, 0x56, 0xcd, 0x3a, 0x02, - 0x7e, 0xc1, 0xc6, 0xc9, 0xdc, 0xe8, 0x08, 0xcb, 0xc9, 0x88, 0xdb, 0x4e, 0xcc, 0xed, 0x73, 0x00, - 0xfa, 0xce, 0xa5, 0x11, 0x66, 0xb5, 0xf0, 0xc4, 0x1a, 0xba, 0x23, 0x17, 0x0b, 0x58, 0xcf, 0x7a, - 0x71, 0x12, 0xd3, 0x48, 0x1a, 0x8c, 0x08, 0xe4, 0x2e, 0xc3, 0xed, 0x78, 0x5f, 0x31, 0x0c, 0x31, - 0xa0, 0xe5, 0xfb, 0x23, 0x2b, 0x1a, 0xf8, 0x21, 0x36, 0x42, 0xce, 0x4b, 0x1e, 0x56, 0xab, 0x66, - 0x13, 0x81, 0x7d, 0x06, 0xdb, 0x70, 0x5e, 0x1a, 0x36, 0xb4, 0xfa, 0xdb, 0x7c, 0x3b, 0xb2, 0xbc, - 0x46, 0x8f, 0x1a, 0x47, 0xd2, 0x43, 0xd1, 0xa3, 0xd8, 0x37, 0x83, 0x85, 0xfe, 0x50, 0x79, 0x19, - 0xfb, 0x66, 0xb0, 0xf8, 0x24, 0xa0, 0xb2, 0xb2, 0xe4, 0xdf, 0x4c, 0x61, 0x43, 0x7a, 0x8c, 0xc5, - 0xbc, 0xe8, 0xb4, 0xc4, 0xc0, 0x70, 0x00, 0x36, 0xed, 0xc0, 0x7e, 0xe1, 0x0e, 0xdd, 0xf8, 0x04, - 0x0d, 0xd8, 0xb1, 0x1d, 0xc7, 0x1a, 0x24, 0x10, 0x97, 0x26, 0x7d, 0xd6, 0x3c, 0xc2, 0x37, 0x35, - 0x30, 0xf9, 0x08, 0x16, 0x9c, 0xd0, 0x0f, 0xb2, 0xb4, 0xa2, 0xf1, 0xea, 0x30, 0x84, 0x4e, 0x6c, - 0xfc, 0xbb, 0x02, 0x8b, 0x59, 0xb3, 0xc8, 0xda, 0xf9, 0x1e, 0x34, 0xc2, 0xc4, 0x40, 0xf2, 0xdc, - 0xad, 0x64, 0xd3, 0x43, 0xd1, 0x90, 0x66, 0x3a, 0x05, 0xfd, 0x7f, 0x2e, 0x27, 0x40, 0x25, 0xe3, - 0x78, 0xe9, 0xde, 0xcc, 0x0c, 0x21, 0xf9, 0x32, 0x6d, 0x72, 0x92, 0x04, 0x5f, 0xe5, 0x73, 0x97, - 0xd4, 0xdc, 0x8c, 0xea, 0x55, 0xf3, 0x93, 0xd4, 0xda, 0x3f, 0x90, 0xa6, 0xc8, 0x57, 0xe6, 0x7c, - 0xce, 0x53, 0xc4, 0x08, 0xf3, 0x18, 0xdf, 0x40, 0x43, 0x81, 0x98, 0x1b, 0x8f, 0xdd, 0xc4, 0xf7, - 0xd8, 0x27, 0x83, 0x1c, 0xca, 0x30, 0x8b, 0x10, 0xfc, 0x64, 0xed, 0x17, 0xea, 0xda, 0x65, 0xab, - 0xd8, 0x43, 0x0b, 0x21, 0x4c, 0xb2, 0x2a, 0x62, 0xdb, 0x29, 0xf8, 0x01, 0x42, 0x8d, 0x7f, 0xd4, - 0x60, 0x3e, 0xaf, 0xcf, 0xb2, 0x40, 0x7e, 0x33, 0x39, 0x5d, 0x53, 0x39, 0x51, 0xd5, 0x01, 0x94, - 0x27, 0x8e, 0xd5, 0x41, 0x03, 0x7f, 0x34, 0xc2, 0x93, 0xca, 0x97, 0xc4, 0x3a, 0x48, 0x0e, 0x19, - 0x5f, 0x3b, 0x3c, 0x8c, 0x78, 0x08, 0x47, 0xbe, 0xec, 0x9b, 0x5c, 0x87, 0x26, 0x4b, 0xef, 0xd8, - 0x3e, 0xb0, 0x5e, 0x46, 0xb6, 0xb0, 0x20, 0x41, 0xd8, 0xc9, 0x60, 0xa3, 0x3a, 0x4d, 0xbd, 0xe3, - 0xa4, 0xa3, 0x48, 0xdb, 0xe9, 0xe4, 0x54, 0x9b, 0x1c, 0x8d, 0x9a, 0x9c, 0x19, 0xb1, 0x66, 0x37, - 0x49, 0xf4, 0x6d, 0x45, 0xc8, 0x7b, 0x60, 0x53, 0x62, 0xc9, 0xe7, 0x2a, 0xd6, 0x89, 0x64, 0xfe, - 0x41, 0x6a, 0xe5, 0xac, 0x16, 0x4a, 0xeb, 0x81, 0x87, 0xd9, 0x7a, 0xa0, 0xc1, 0x59, 0xdc, 0x9a, - 0xc8, 0xe2, 0xf4, 0x06, 0xe5, 0x1a, 0x40, 0x10, 0xba, 0xc7, 0xee, 0x90, 0x1e, 0x52, 0xa7, 0x0b, - 0xbc, 0x55, 0xd5, 0x20, 0xfc, 0x32, 0x44, 0xb6, 0xd3, 0x56, 0xe8, 0xfb, 0xf1, 0x41, 0xd4, 0x6d, - 0x8a, 0x16, 0x3a, 0x01, 0x9b, 0x1c, 0xca, 0x3a, 0x5e, 0xd6, 0x0b, 0xf2, 0x1e, 0x7d, 0x4e, 0x94, - 0x9e, 0x38, 0xe6, 0x2d, 0xfa, 0x22, 0xcb, 0x14, 0x8e, 0xeb, 0x75, 0x5b, 0x7c, 0xa6, 0x18, 0xb0, - 0x40, 0xc4, 0x3f, 0x2c, 0xdf, 0x1b, 0xd0, 0x6e, 0x9b, 0xa3, 0x1a, 0x1c, 0xf2, 0x18, 0x01, 0xcc, - 0x9d, 0xe2, 0xf8, 0xa4, 0x3b, 0xcf, 0xe1, 0xec, 0x13, 0x1b, 0x49, 0x59, 0x7c, 0x75, 0xb8, 0xf5, - 0xaf, 0x4e, 0x38, 0x5d, 0xdf, 0x9b, 0x56, 0xea, 0xcf, 0x15, 0x58, 0x12, 0xdd, 0x8f, 0x76, 0xf2, - 0xcf, 0xd1, 0x04, 0x90, 0xdb, 0xaa, 0xe1, 0xca, 0x57, 0xec, 0xf9, 0xcd, 0x4a, 0x3a, 0x72, 0x1f, - 0xda, 0x09, 0x4f, 0x39, 0xb3, 0xfa, 0xa6, 0x56, 0xad, 0x15, 0xe9, 0x43, 0xe3, 0xf3, 0xa4, 0xff, - 0xd3, 0xa3, 0x95, 0xc8, 0x89, 0x37, 0x30, 0x42, 0xa9, 0xdb, 0x1a, 0x25, 0x72, 0x53, 0xc1, 0xb0, - 0x6d, 0xb9, 0xcb, 0xba, 0x35, 0x3b, 0x8c, 0x0b, 0x1b, 0x3e, 0xc3, 0x5c, 0xde, 0xaa, 0x65, 0xe7, - 0xca, 0x6e, 0xaa, 0x0f, 0x8b, 0xac, 0x89, 0x7b, 0x0b, 0xa6, 0x2c, 0x0e, 0xb0, 0x6d, 0xfb, 0xe3, - 0x58, 0x06, 0xa6, 0x64, 0x68, 0x2c, 0x8b, 0xc6, 0xb2, 0xb8, 0xda, 0x67, 0xb0, 0x24, 0xfa, 0xba, - 0xb7, 0xd9, 0xc4, 0xe5, 0xa4, 0xab, 0x2c, 0xf2, 0xfd, 0xfd, 0x94, 0x16, 0xe4, 0xce, 0x51, 0xad, - 0x7e, 0x92, 0xad, 0xb3, 0x96, 0x8b, 0x4e, 0x90, 0x29, 0xb3, 0x8a, 0xae, 0x35, 0x5d, 0xe2, 0x5a, - 0x66, 0xa1, 0xa4, 0x15, 0x55, 0xd7, 0x47, 0x45, 0xee, 0xff, 0xc7, 0x8a, 0x76, 0x47, 0x54, 0xb4, - 0x6a, 0x69, 0xd5, 0x34, 0xdf, 0xce, 0x55, 0xb4, 0xdd, 0x49, 0x62, 0xaa, 0x82, 0xf6, 0x77, 0x55, - 0x68, 0x28, 0xdc, 0x99, 0xea, 0x59, 0x95, 0x5c, 0xaa, 0x6f, 0x4a, 0x2e, 0x58, 0x5f, 0xf1, 0x0f, - 0x2b, 0xa4, 0x07, 0x52, 0xbb, 0x75, 0x0e, 0x30, 0xe9, 0x41, 0x6a, 0xae, 0xda, 0x99, 0xcc, 0xf5, - 0xd3, 0xdc, 0x6d, 0xd5, 0xb5, 0x22, 0x7d, 0x69, 0x12, 0xd8, 0x2e, 0xbb, 0xa6, 0x7a, 0xbf, 0x64, - 0xf2, 0xf7, 0xb6, 0x1b, 0xdc, 0x15, 0xc5, 0xb7, 0x6e, 0x6c, 0x19, 0x68, 0xd6, 0xb1, 0x44, 0x55, - 0x50, 0x59, 0x81, 0x93, 0xe2, 0xd6, 0x4c, 0x8d, 0x8a, 0x9d, 0xda, 0x8c, 0x82, 0xd3, 0x0b, 0x97, - 0x33, 0x9c, 0xda, 0x7f, 0x4e, 0x6b, 0x47, 0xf3, 0x1c, 0x37, 0x13, 0xe7, 0x3c, 0x9a, 0x6f, 0xe8, - 0x80, 0x78, 0x42, 0xc4, 0x00, 0x28, 0xd0, 0xa2, 0x88, 0x6e, 0x48, 0x08, 0xa2, 0xb1, 0x48, 0x39, - 0x70, 0x3d, 0x37, 0x3a, 0x12, 0xf8, 0x19, 0x8e, 0x87, 0x04, 0xb4, 0xc1, 0x6f, 0xe8, 0xe9, 0x6b, - 0x2c, 0xd9, 0x07, 0xbe, 0x43, 0xd1, 0x21, 0xf8, 0x0d, 0x3d, 0x03, 0x6c, 0xe2, 0x38, 0xf5, 0xee, - 0xfa, 0xb9, 0xbc, 0xbb, 0x91, 0xf3, 0xee, 0x25, 0x98, 0x41, 0x79, 0x23, 0xdf, 0xe3, 0xa5, 0x42, - 0xc3, 0x94, 0x23, 0xad, 0xa2, 0x69, 0x4e, 0xaa, 0x68, 0x4e, 0xb9, 0xe1, 0xc8, 0x55, 0x34, 0x73, - 0x93, 0x2a, 0x9a, 0xb3, 0x5c, 0x70, 0x68, 0x45, 0x58, 0xeb, 0xb4, 0x22, 0xec, 0x5d, 0xba, 0xfe, - 0x43, 0x4c, 0xb2, 0x79, 0x67, 0x95, 0xbe, 0x7f, 0x3b, 0x77, 0x0f, 0xd2, 0x9d, 0xa4, 0x05, 0x75, - 0x0d, 0xf2, 0x12, 0x9a, 0xdb, 0xaf, 0xd1, 0x7c, 0x67, 0x4f, 0x8a, 0x28, 0xea, 0x60, 0xe4, 0xc8, - 0x16, 0x87, 0x7d, 0x26, 0xc5, 0x56, 0x35, 0x2d, 0xb6, 0x54, 0xcd, 0xc6, 0xdc, 0x74, 0x4e, 0xd6, - 0x6c, 0xc6, 0x3d, 0x98, 0x13, 0x6b, 0x49, 0x69, 0x97, 0x98, 0xb4, 0x0e, 0xcb, 0xae, 0x15, 0x4e, - 0x26, 0x47, 0x12, 0x4e, 0xc3, 0x90, 0xef, 0x5d, 0xc0, 0x71, 0x64, 0x7c, 0x0a, 0x4d, 0xee, 0x6f, - 0x32, 0xfd, 0xdd, 0xd4, 0xbb, 0xe5, 0xd3, 0x9c, 0xd2, 0xd8, 0x80, 0x05, 0x16, 0x2c, 0x38, 0x5c, - 0x9d, 0xec, 0x8f, 0x73, 0x59, 0x61, 0x31, 0x3b, 0x3f, 0x97, 0x11, 0x5e, 0x41, 0x8d, 0x83, 0x0b, - 0x27, 0xfb, 0x0a, 0xeb, 0xdc, 0x02, 0xdf, 0x8a, 0xed, 0x43, 0xf5, 0xe0, 0xc6, 0x00, 0x4f, 0x70, - 0xcc, 0xdf, 0x0b, 0x19, 0xd2, 0x71, 0x71, 0xe1, 0x38, 0x92, 0xdd, 0x44, 0x93, 0xc1, 0xb6, 0x04, - 0x88, 0x45, 0x86, 0xc8, 0xfd, 0x35, 0xe5, 0x9a, 0x9a, 0x36, 0xf9, 0x37, 0x96, 0x51, 0x44, 0x97, - 0x57, 0xaa, 0x0b, 0x5d, 0x93, 0x6f, 0x27, 0x09, 0x6a, 0xed, 0xac, 0xc0, 0xa6, 0xc4, 0xa2, 0x9a, - 0x89, 0xd0, 0x40, 0x26, 0x90, 0x9d, 0x5d, 0x5b, 0x9f, 0xc1, 0xc5, 0xcc, 0x7c, 0x75, 0xe3, 0x9e, - 0x61, 0x90, 0x5f, 0x5d, 0x4e, 0xfe, 0x7b, 0x05, 0x60, 0x63, 0x1c, 0x1f, 0xc9, 0x3e, 0xac, 0x07, - 0x75, 0xd6, 0xfd, 0x69, 0x65, 0x8a, 0x1a, 0x33, 0x5c, 0x60, 0x47, 0x11, 0x36, 0x4a, 0x49, 0xc1, - 0xa2, 0xc6, 0xbc, 0xcf, 0x1a, 0xab, 0xf7, 0x3a, 0xfe, 0xcd, 0xde, 0xfb, 0xc4, 0x23, 0xa7, 0x85, - 0x0d, 0x20, 0xb6, 0xbe, 0x91, 0xcc, 0x9e, 0x2d, 0x01, 0xdd, 0x10, 0x40, 0x46, 0xe6, 0x3a, 0x14, - 0x45, 0x8b, 0x4f, 0xac, 0xd8, 0x7f, 0x45, 0x3d, 0xd9, 0x91, 0xb5, 0x12, 0xe8, 0x13, 0x06, 0x64, - 0x64, 0x21, 0x3d, 0x44, 0x2d, 0x87, 0x09, 0xd9, 0x8c, 0x20, 0x4b, 0xa0, 0x9c, 0x8c, 0xbd, 0x0f, - 0x77, 0xf6, 0xc7, 0xc3, 0xa1, 0xd8, 0xe4, 0x79, 0x75, 0x89, 0x0d, 0x90, 0xd8, 0x47, 0xbe, 0x1f, - 0x4f, 0x55, 0x24, 0x37, 0xf7, 0xdd, 0x6b, 0xef, 0x8b, 0xb0, 0xa0, 0x09, 0x2a, 0xcb, 0x46, 0xf4, - 0x05, 0x51, 0x51, 0xbe, 0x9d, 0xfc, 0xc6, 0x25, 0xb8, 0x98, 0x99, 0x2f, 0xd8, 0xae, 0xbe, 0x07, - 0xf5, 0xe4, 0x2d, 0x98, 0xcc, 0x42, 0xf5, 0xc9, 0xe6, 0x7e, 0xe7, 0x02, 0xfb, 0x78, 0xba, 0xb5, - 0xdf, 0xa9, 0xac, 0xae, 0xc2, 0x7c, 0xee, 0x16, 0x8f, 0x34, 0xa0, 0x66, 0x6e, 0x6f, 0x6c, 0x3d, - 0x47, 0xb2, 0x39, 0xa8, 0xef, 0x3d, 0x7e, 0x22, 0x46, 0x95, 0xd5, 0x4d, 0x68, 0x67, 0xd3, 0x1d, - 0x69, 0xc2, 0xec, 0x26, 0x62, 0x9f, 0x6c, 0x6f, 0x21, 0x31, 0x0e, 0xcc, 0xa7, 0x7b, 0x7b, 0x3b, - 0x7b, 0x0f, 0x3a, 0x15, 0x02, 0x30, 0xb3, 0xfd, 0xcd, 0x0e, 0x43, 0x4c, 0x31, 0xc4, 0xd3, 0xbd, - 0x87, 0x7b, 0x8f, 0x7f, 0xb9, 0xd7, 0xa9, 0xae, 0xff, 0xb5, 0x0e, 0x6d, 0x53, 0x6c, 0xa1, 0x8f, - 0xbe, 0xe0, 0x62, 0x03, 0x78, 0x0f, 0x66, 0x93, 0x87, 0xf6, 0x34, 0xb1, 0x66, 0xff, 0x0a, 0xe8, - 0x75, 0x8b, 0x08, 0xa9, 0xb6, 0x0b, 0xe4, 0x39, 0x74, 0xf2, 0x6f, 0x4f, 0x24, 0xbd, 0x91, 0x99, - 0xf0, 0xc8, 0xd5, 0xbb, 0x71, 0x0a, 0x85, 0x62, 0xdd, 0x87, 0x76, 0xf6, 0x55, 0x89, 0xa4, 0x65, - 0x5b, 0xe9, 0x6b, 0x55, 0xef, 0xfa, 0x44, 0xbc, 0x2e, 0x6f, 0xfe, 0x3d, 0x49, 0x93, 0x77, 0xc2, - 0x5b, 0x95, 0x26, 0xef, 0xc4, 0xc7, 0x28, 0xce, 0xba, 0xf0, 0xf2, 0xb2, 0x32, 0xf9, 0x82, 0xbd, - 0xc0, 0x7a, 0xd2, 0xad, 0xbd, 0x50, 0x45, 0xf6, 0x0a, 0x95, 0xe8, 0x8f, 0x22, 0x25, 0xb7, 0xd3, - 0x9a, 0x2a, 0xca, 0xef, 0x5e, 0x91, 0xe9, 0x33, 0x2c, 0xc7, 0xb2, 0x4d, 0x28, 0xb9, 0x9e, 0xb3, - 0x4b, 0xbe, 0x39, 0xeb, 0xad, 0x4c, 0x26, 0xc8, 0xda, 0x4d, 0x6f, 0x31, 0x33, 0x76, 0x2b, 0xe9, - 0x5b, 0x33, 0x76, 0x2b, 0xed, 0x4d, 0x2f, 0x90, 0x7d, 0x68, 0x65, 0x1a, 0x49, 0x72, 0x35, 0x63, - 0xeb, 0x02, 0xcb, 0x6b, 0x93, 0xd0, 0xfa, 0xf6, 0x73, 0x4d, 0xa4, 0xb6, 0xfd, 0xf2, 0xde, 0xb4, - 0xb7, 0x32, 0x99, 0x20, 0x6f, 0xab, 0xb4, 0xe2, 0xce, 0xd9, 0xaa, 0xd0, 0x77, 0xe5, 0x6c, 0x55, - 0x2c, 0xd5, 0xa5, 0xad, 0x72, 0xa5, 0xf3, 0xf5, 0x89, 0x35, 0x4b, 0xd1, 0x56, 0xe5, 0x65, 0x10, - 0xf2, 0xbd, 0x03, 0xd3, 0xac, 0xd4, 0x20, 0x69, 0x52, 0xd7, 0xaa, 0x9c, 0xde, 0xa5, 0x1c, 0x34, - 0x99, 0x76, 0xb3, 0x72, 0xbb, 0xb2, 0xfe, 0x97, 0x29, 0x98, 0x13, 0x71, 0x50, 0x86, 0x92, 0x07, - 0x00, 0x69, 0x36, 0x26, 0xbd, 0xcc, 0xa6, 0x32, 0x25, 0x45, 0xef, 0x4a, 0x29, 0x4e, 0x09, 0xf5, - 0xb5, 0xac, 0x5f, 0xe4, 0x46, 0xaf, 0xe4, 0xc2, 0x6e, 0x66, 0x93, 0xef, 0x95, 0x23, 0x15, 0xaf, - 0x2d, 0x68, 0xa8, 0x68, 0x4f, 0xb4, 0x24, 0x91, 0x4b, 0x55, 0xbd, 0x5e, 0x19, 0x4a, 0x97, 0x48, - 0x0b, 0xef, 0x9a, 0x44, 0xc5, 0xa4, 0xa1, 0x49, 0x54, 0x92, 0x11, 0x8c, 0x0b, 0xff, 0x0b, 0x00, - 0x00, 0xff, 0xff, 0x3e, 0xe9, 0xdd, 0x26, 0x8a, 0x25, 0x00, 0x00, + // 2829 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x5a, 0x4b, 0x73, 0x1b, 0xc7, + 0x11, 0x16, 0x08, 0x82, 0x04, 0x1a, 0x04, 0x08, 0x8e, 0x28, 0x12, 0x82, 0x5e, 0xd4, 0xda, 0x4e, + 0x24, 0xda, 0x66, 0x29, 0x4c, 0x4a, 0x8a, 0x64, 0x5b, 0x16, 0x4d, 0x32, 0x2a, 0x5a, 0x14, 0xc5, + 0x2c, 0x24, 0xc5, 0x3a, 0xa1, 0x56, 0xd8, 0x21, 0xb9, 0x12, 0xb0, 0xbb, 0xde, 0x5d, 0x30, 0x62, + 0xae, 0xf9, 0x05, 0xb9, 0xe5, 0x98, 0x83, 0xab, 0x72, 0xca, 0x25, 0x55, 0xb9, 0xe4, 0x9a, 0x5b, + 0x52, 0xf9, 0x3d, 0xc9, 0x25, 0x55, 0xe9, 0x79, 0xec, 0xec, 0xec, 0x03, 0x14, 0x21, 0x57, 0xd9, + 0xba, 0xed, 0x74, 0xf7, 0xcc, 0xf4, 0x74, 0xf7, 0xf4, 0xf4, 0x37, 0xb3, 0x50, 0xb3, 0x7c, 0x67, + 0xcd, 0x0f, 0xbc, 0xc8, 0x23, 0xb3, 0xc1, 0xc8, 0x8d, 0x9c, 0x21, 0x35, 0x56, 0xa1, 0xf9, 0x9c, + 0x06, 0xa1, 0xe3, 0xb9, 0x26, 0xfd, 0x76, 0x44, 0xc3, 0x88, 0xb4, 0x61, 0xf6, 0x58, 0x50, 0xda, + 0xa5, 0x95, 0xd2, 0x8d, 0x9a, 0x19, 0x37, 0x8d, 0x3f, 0x97, 0x60, 0x5e, 0x09, 0x87, 0xbe, 0xe7, + 0x86, 0x74, 0xbc, 0x34, 0xb9, 0x0e, 0x73, 0x72, 0x92, 0x9e, 0x6b, 0x0d, 0x69, 0x7b, 0x8a, 0xb3, + 0xeb, 0x92, 0xb6, 0x87, 0x24, 0xf2, 0x53, 0x98, 0x8f, 0x45, 0xe2, 0x41, 0xca, 0x5c, 0xaa, 0x29, + 0xc9, 0x72, 0x36, 0xb2, 0x06, 0xe7, 0x63, 0x41, 0x5c, 0x83, 0x12, 0x9e, 0xe6, 0xc2, 0x0b, 0x92, + 0xb5, 0xe1, 0x3b, 0x52, 0xde, 0xd8, 0x80, 0xda, 0xd6, 0x5e, 0xf7, 0x89, 0x1f, 0xb1, 0xce, 0xa8, + 0x62, 0x48, 0x03, 0xd6, 0x07, 0x55, 0x2c, 0x33, 0x15, 0x65, 0x93, 0x74, 0xa0, 0x1a, 0x52, 0x2b, + 0xe8, 0x1f, 0xd1, 0x10, 0xd5, 0x63, 0x2c, 0xd5, 0x36, 0xfe, 0x52, 0x82, 0xfa, 0xbe, 0x17, 0x44, + 0x8f, 0x2d, 0xdf, 0x77, 0xdc, 0x43, 0x42, 0x60, 0x9a, 0x2f, 0x43, 0xac, 0x92, 0x7f, 0x93, 0x4f, + 0xa1, 0xca, 0xcd, 0xd9, 0xf7, 0x06, 0x7c, 0x79, 0xcd, 0xf5, 0x85, 0x35, 0xa9, 0xcc, 0xda, 0xbe, + 0x64, 0x98, 0x4a, 0x84, 0x7c, 0x04, 0xcd, 0xbe, 0xe7, 0x46, 0x96, 0xe3, 0xd2, 0xa0, 0xe7, 0xe3, + 0xd8, 0x7c, 0xb5, 0x15, 0xb3, 0xa1, 0xa8, 0x6c, 0x42, 0x72, 0x09, 0x6a, 0x47, 0x5e, 0x18, 0x09, + 0x89, 0x69, 0x2e, 0x51, 0x65, 0x04, 0xce, 0x5c, 0x86, 0x59, 0xce, 0x74, 0xfc, 0x76, 0x85, 0x6b, + 0x32, 0xc3, 0x9a, 0x3b, 0xbe, 0xf1, 0x5d, 0x09, 0x2a, 0x8f, 0x3d, 0x9c, 0xbc, 0x50, 0xd3, 0xf4, + 0xd4, 0x56, 0x74, 0x24, 0xdd, 0xa1, 0x4d, 0x8d, 0xc4, 0x64, 0x6a, 0x26, 0x21, 0x5c, 0x21, 0xa6, + 0x66, 0x4c, 0xb4, 0x56, 0x40, 0x2d, 0xdb, 0x73, 0x07, 0x27, 0x5c, 0xad, 0xaa, 0xa9, 0xda, 0xcc, + 0x93, 0x21, 0x1d, 0x38, 0xee, 0xe8, 0x4d, 0x2f, 0xa0, 0x03, 0xeb, 0x25, 0x1d, 0x70, 0xf5, 0xaa, + 0x66, 0x53, 0x92, 0x4d, 0x41, 0x35, 0x5e, 0xc1, 0x3c, 0x73, 0x7d, 0xe8, 0x5b, 0x7d, 0x2a, 0xfd, + 0x83, 0x81, 0xc2, 0x27, 0x75, 0x69, 0xf4, 0x5b, 0x2f, 0x78, 0xcd, 0xf5, 0xae, 0x9a, 0x75, 0x46, + 0xdb, 0x13, 0x24, 0x72, 0x11, 0xaa, 0x42, 0x2f, 0xc7, 0xe6, 0x8a, 0x57, 0x4d, 0x6e, 0x85, 0x7d, + 0xc7, 0x56, 0x2c, 0xc7, 0xef, 0x73, 0x8d, 0x25, 0x6b, 0xc7, 0xef, 0x1b, 0xbf, 0x2f, 0xc1, 0x85, + 0x5d, 0x36, 0xf9, 0xbe, 0x67, 0x77, 0x2d, 0xd7, 0x7e, 0xe9, 0xbd, 0xd9, 0xf4, 0xdc, 0x03, 0xe7, + 0x90, 0x7c, 0x00, 0x8d, 0xfe, 0x61, 0xe0, 0x8d, 0x7c, 0x5c, 0x69, 0x40, 0xdd, 0x48, 0xda, 0x6a, + 0x4e, 0x10, 0xf7, 0x39, 0x8d, 0x6c, 0xc3, 0x82, 0x1b, 0xab, 0xda, 0xf3, 0xb8, 0xae, 0x21, 0x9f, + 0xbd, 0xbe, 0xde, 0x56, 0x6e, 0xce, 0x2c, 0xc6, 0x6c, 0xb9, 0x69, 0x42, 0x68, 0x04, 0x40, 0x92, + 0xf9, 0x1f, 0xd3, 0xc8, 0xb2, 0xad, 0xc8, 0x2a, 0x74, 0x52, 0x0b, 0xca, 0x23, 0xb9, 0xc0, 0x9a, + 0xc9, 0x3e, 0xc9, 0x65, 0xa8, 0xa9, 0xf1, 0xa4, 0x3f, 0x12, 0x02, 0x0b, 0x6c, 0x2b, 0x8a, 0xe8, + 0xd0, 0x17, 0x61, 0xd2, 0x30, 0xe3, 0xa6, 0xf1, 0xf7, 0x69, 0x68, 0xe5, 0x16, 0x7d, 0x07, 0xaa, + 0x43, 0x39, 0x3d, 0x9f, 0xb6, 0xbe, 0x7e, 0x29, 0x89, 0xd6, 0x9c, 0x86, 0xa6, 0x12, 0x66, 0x8e, + 0x67, 0x26, 0xd5, 0x76, 0xb1, 0x6a, 0x33, 0x4b, 0x0e, 0xbc, 0xc3, 0x9e, 0xed, 0x04, 0xb4, 0x1f, + 0x79, 0xc1, 0x89, 0xd4, 0x72, 0x0e, 0x89, 0x5b, 0x31, 0x8d, 0xfc, 0x1c, 0xea, 0xb6, 0x1b, 0x2a, + 0x1b, 0x4e, 0xf3, 0xc9, 0x89, 0x9a, 0x5c, 0x6d, 0x55, 0x13, 0x50, 0x4c, 0xda, 0x8d, 0xdc, 0x85, + 0x06, 0xdb, 0x01, 0xbd, 0xa1, 0xd8, 0x80, 0x21, 0x06, 0x54, 0x19, 0xbb, 0x2d, 0x6a, 0x3a, 0xab, + 0xdd, 0x69, 0xce, 0xf9, 0x49, 0x23, 0x24, 0x5f, 0xc0, 0x0c, 0x8f, 0xb6, 0xb0, 0x3d, 0xc3, 0xfb, + 0x7c, 0x54, 0xb0, 0x4e, 0x61, 0x94, 0xb5, 0x5d, 0x2e, 0xb7, 0xed, 0x46, 0xc1, 0x89, 0x29, 0x3b, + 0x91, 0x5d, 0xa8, 0x5b, 0xae, 0xeb, 0x45, 0x96, 0x50, 0x77, 0x96, 0x8f, 0xb1, 0x3a, 0x7e, 0x8c, + 0x8d, 0x44, 0x58, 0x0c, 0xa4, 0x77, 0x27, 0xbf, 0x80, 0x0a, 0xdf, 0x01, 0xed, 0x2a, 0x5f, 0xf6, + 0x55, 0x35, 0x4e, 0x61, 0x68, 0x9a, 0x42, 0xb8, 0x73, 0x17, 0xea, 0x9a, 0x6a, 0x2c, 0x34, 0x5e, + 0xd3, 0x13, 0x19, 0x2d, 0xec, 0x93, 0x2c, 0x42, 0xe5, 0xd8, 0x1a, 0x8c, 0x62, 0x8f, 0x88, 0xc6, + 0xbd, 0xa9, 0x5f, 0x96, 0x3a, 0xf7, 0xa1, 0x95, 0xd5, 0x68, 0x92, 0xfe, 0xc6, 0x2e, 0x2c, 0x6f, + 0xe2, 0xc6, 0x8e, 0x68, 0xa2, 0x5b, 0x7c, 0x36, 0xfc, 0x0c, 0x66, 0xfa, 0x5c, 0x4d, 0x19, 0x40, + 0x17, 0xc7, 0x1a, 0xc5, 0x94, 0x82, 0xc6, 0x03, 0x68, 0xe7, 0x47, 0x93, 0x87, 0xc7, 0x87, 0xd0, + 0xf4, 0x3d, 0xbb, 0x17, 0x0a, 0x72, 0x0f, 0x63, 0x5f, 0xee, 0x43, 0x5f, 0xc9, 0xee, 0xd8, 0xc6, + 0x17, 0x70, 0xa1, 0x1b, 0x79, 0x7e, 0x5e, 0x9b, 0xb3, 0x75, 0x6f, 0xc3, 0x52, 0xb6, 0xbb, 0x98, + 0xde, 0xf8, 0x12, 0x96, 0x4d, 0x3a, 0xf4, 0x8e, 0xe9, 0xbb, 0x0e, 0xdd, 0x81, 0x76, 0x7e, 0x80, + 0x64, 0xf0, 0x84, 0xda, 0x45, 0x67, 0x8c, 0xc2, 0xc9, 0x06, 0xbf, 0xa9, 0x0f, 0x20, 0x13, 0xa1, + 0x18, 0x87, 0x34, 0x61, 0x0a, 0xf3, 0xbf, 0xe8, 0x84, 0x5f, 0xc6, 0x0b, 0xa8, 0xed, 0xe9, 0x59, + 0x41, 0xcf, 0xa4, 0x78, 0xdc, 0xc9, 0x26, 0x59, 0x87, 0xd9, 0xb3, 0xa6, 0xb1, 0x58, 0xd0, 0x78, + 0x94, 0x4b, 0xa1, 0x52, 0x87, 0x75, 0x00, 0x95, 0x89, 0x42, 0x19, 0x0e, 0x24, 0x3f, 0x9e, 0xa9, + 0x49, 0x19, 0xdf, 0xa5, 0xd2, 0x92, 0xb6, 0x18, 0x5b, 0x2d, 0xc6, 0x4e, 0xa5, 0xa9, 0xa9, 0x49, + 0xd2, 0xd4, 0x1a, 0x54, 0x42, 0x1c, 0x52, 0x24, 0xca, 0xa6, 0xb6, 0x38, 0xd9, 0xeb, 0x2b, 0x31, + 0x25, 0x35, 0x85, 0x18, 0xb9, 0x02, 0xd0, 0xe7, 0x91, 0x69, 0xf7, 0x2c, 0x91, 0x41, 0xcb, 0x66, + 0x4d, 0x52, 0x36, 0x22, 0x72, 0x2f, 0xb1, 0x63, 0x85, 0xab, 0xb1, 0x52, 0xa0, 0x46, 0xca, 0x2f, + 0x89, 0xa5, 0xd5, 0x9e, 0x9f, 0x39, 0x7d, 0xcf, 0xcb, 0x7e, 0x42, 0x58, 0x4b, 0x5b, 0xb3, 0x63, + 0xd3, 0x96, 0xe8, 0x71, 0x96, 0xb4, 0x55, 0x1d, 0x9b, 0xb6, 0xe4, 0x18, 0xa7, 0xa6, 0xad, 0x1f, + 0x33, 0x01, 0x3d, 0x86, 0x76, 0x7e, 0xeb, 0xc8, 0x94, 0x81, 0x19, 0x28, 0xe4, 0x94, 0x53, 0x32, + 0x90, 0xec, 0x22, 0x05, 0x8d, 0xff, 0x95, 0xf4, 0xa8, 0xfb, 0x95, 0x33, 0x88, 0x68, 0x50, 0x78, + 0xfe, 0x8a, 0x48, 0x9c, 0x52, 0x91, 0x38, 0x69, 0x40, 0x75, 0xa1, 0xc9, 0x5d, 0xd1, 0xc3, 0x9a, + 0x87, 0x9f, 0x7c, 0x18, 0x54, 0xcc, 0x07, 0x9f, 0x14, 0xe8, 0x28, 0xd4, 0x10, 0x7e, 0xec, 0x4a, + 0x71, 0xe1, 0x85, 0xc6, 0x40, 0xa7, 0x75, 0x1e, 0x00, 0xc9, 0x0b, 0x4d, 0x64, 0xce, 0xaf, 0xd9, + 0x16, 0x66, 0xe5, 0x63, 0x41, 0x36, 0x3f, 0xe0, 0x6a, 0x9c, 0x62, 0x4b, 0xa1, 0xa7, 0x29, 0x05, + 0x8d, 0x3f, 0x4e, 0x01, 0x24, 0xcc, 0xf7, 0x76, 0xef, 0xde, 0x51, 0x3b, 0x49, 0x14, 0x0d, 0xd7, + 0x0a, 0xb4, 0x28, 0xda, 0x43, 0xdf, 0x23, 0xea, 0x8d, 0x4d, 0x58, 0xca, 0x9a, 0x59, 0xc6, 0xec, + 0x4d, 0xa8, 0x38, 0x58, 0x97, 0x09, 0xf8, 0x51, 0x5f, 0x3f, 0x5f, 0xa0, 0x8c, 0x29, 0x24, 0x8c, + 0xeb, 0x50, 0xdb, 0x19, 0x5a, 0x87, 0xb4, 0xeb, 0xd3, 0x3e, 0x9b, 0xcb, 0x61, 0x0d, 0x39, 0xbf, + 0x68, 0x18, 0xeb, 0x50, 0x7d, 0x44, 0x4f, 0x9e, 0xb3, 0x79, 0xcf, 0xaa, 0x9f, 0xf1, 0xaf, 0x12, + 0x2c, 0xf3, 0xd4, 0xb3, 0x19, 0x97, 0xfb, 0xa8, 0x9c, 0x37, 0x0a, 0x30, 0x29, 0x73, 0x53, 0xfa, + 0xa3, 0x9e, 0x4f, 0x03, 0xc7, 0x13, 0xbe, 0x64, 0xa6, 0xf4, 0x47, 0xfb, 0x9c, 0xc0, 0x20, 0x01, + 0x63, 0x7f, 0x3b, 0xf2, 0xa4, 0x4f, 0xcb, 0x66, 0x15, 0x09, 0xbf, 0x66, 0xed, 0xb8, 0x6f, 0x78, + 0x84, 0x15, 0x73, 0xc8, 0x7d, 0x27, 0xfa, 0x76, 0x39, 0x01, 0x03, 0xec, 0xc2, 0x10, 0xcf, 0xc7, + 0xe0, 0xa4, 0x37, 0x70, 0x86, 0x0e, 0xd6, 0xe8, 0x6e, 0xef, 0xe5, 0x49, 0x44, 0x43, 0xe9, 0x30, + 0x22, 0x98, 0xbb, 0x8c, 0xb7, 0xe3, 0x7e, 0xc5, 0x38, 0xc4, 0x80, 0x86, 0xe7, 0x0d, 0x7b, 0x61, + 0xdf, 0x0b, 0x10, 0xeb, 0xd9, 0xaf, 0x78, 0xee, 0x2d, 0x9b, 0x75, 0x24, 0x76, 0x19, 0x6d, 0xc3, + 0x7e, 0x65, 0x58, 0xd0, 0xe8, 0x6e, 0xf3, 0xe5, 0x48, 0x04, 0x81, 0x9b, 0x79, 0x14, 0xca, 0x30, + 0xc6, 0xcd, 0xcc, 0xbe, 0x19, 0x2d, 0xf0, 0x06, 0xb1, 0x1d, 0xf8, 0x37, 0xa3, 0x45, 0x27, 0x7e, + 0x5c, 0x49, 0xf3, 0x6f, 0x66, 0xb0, 0x01, 0x3d, 0x46, 0xbc, 0x22, 0xc0, 0xa4, 0x68, 0x18, 0x36, + 0xc0, 0xa6, 0xe5, 0x5b, 0x2f, 0x9d, 0x81, 0x13, 0x9d, 0xa0, 0x03, 0x5b, 0x96, 0x6d, 0xf7, 0xfa, + 0x31, 0xc5, 0xa1, 0x31, 0x94, 0x9c, 0x47, 0xfa, 0xa6, 0x46, 0x26, 0x1f, 0xc3, 0x82, 0x1d, 0x78, + 0x7e, 0x5a, 0x56, 0x60, 0xcb, 0x16, 0x63, 0xe8, 0xc2, 0xc6, 0x7f, 0x4b, 0xb0, 0x98, 0x76, 0x8b, + 0x2c, 0xd5, 0xef, 0x43, 0x2d, 0x88, 0x1d, 0x24, 0x37, 0xe7, 0x4a, 0xfa, 0x0c, 0xc9, 0x3b, 0xd2, + 0x4c, 0xba, 0x60, 0xfc, 0xcf, 0x65, 0x14, 0x28, 0xa5, 0x02, 0x2f, 0x59, 0x9b, 0x99, 0x12, 0x24, + 0x5f, 0x26, 0x38, 0x2e, 0x2e, 0x15, 0xca, 0xbc, 0xef, 0x92, 0xea, 0x9b, 0x32, 0xbd, 0xc2, 0x77, + 0x71, 0xd5, 0xfe, 0x13, 0xe9, 0x8a, 0x6c, 0x8d, 0xcf, 0xfb, 0x3c, 0x43, 0x8e, 0x70, 0x8f, 0xf1, + 0x0d, 0xd4, 0x14, 0x29, 0x06, 0x3e, 0x22, 0xf6, 0x38, 0xf0, 0x41, 0xca, 0xa1, 0xcc, 0xc5, 0x48, + 0xc1, 0x4f, 0x86, 0x30, 0xd1, 0xd6, 0x0e, 0x9b, 0xc5, 0x1a, 0xf4, 0x90, 0xc2, 0x34, 0x2b, 0x23, + 0xb7, 0x99, 0x90, 0x1f, 0x22, 0x15, 0xb1, 0xff, 0x82, 0x32, 0xce, 0xa9, 0x70, 0x4b, 0x83, 0x4f, + 0x53, 0x69, 0xf8, 0xf4, 0x9f, 0x0a, 0xcc, 0x67, 0x5d, 0x72, 0x3b, 0x87, 0x9e, 0x3a, 0x89, 0x39, + 0xb3, 0xf3, 0x69, 0x99, 0xed, 0x46, 0xbc, 0x89, 0xa7, 0x32, 0x16, 0x51, 0xfb, 0x5c, 0x6e, 0x6c, + 0xa6, 0x4f, 0xdf, 0x1b, 0x0e, 0x31, 0x21, 0xf0, 0x95, 0x61, 0xe1, 0x26, 0x9b, 0x4c, 0x7b, 0x2b, + 0x38, 0x0c, 0xf9, 0x71, 0x82, 0xda, 0xb3, 0x6f, 0x72, 0x0d, 0xea, 0xac, 0xd4, 0x40, 0xbc, 0xc3, + 0xc0, 0x97, 0xbc, 0x0c, 0x00, 0x49, 0x42, 0xe8, 0x85, 0x90, 0x7f, 0x9a, 0xba, 0xc7, 0x31, 0x04, + 0x4a, 0x2e, 0x26, 0xe2, 0xe4, 0x61, 0x72, 0x36, 0x3a, 0x6c, 0x66, 0xc8, 0xae, 0x0d, 0xe2, 0xa2, + 0xa3, 0xa9, 0x04, 0xf9, 0x6d, 0x82, 0x29, 0xb9, 0xe4, 0x73, 0x95, 0x52, 0x45, 0x61, 0xf1, 0x61, + 0x7e, 0xf5, 0xa7, 0x40, 0xaa, 0x47, 0xe9, 0xda, 0xa4, 0xc6, 0x87, 0xb8, 0x39, 0x76, 0x88, 0xd3, + 0x11, 0xd5, 0x55, 0x00, 0x3f, 0x70, 0x8e, 0x9d, 0x01, 0x3d, 0xa4, 0x76, 0x1b, 0x38, 0xe8, 0xd7, + 0x28, 0xfc, 0x5a, 0x49, 0x5e, 0x4c, 0xf4, 0x02, 0xcf, 0x8b, 0x0e, 0xc2, 0x76, 0x5d, 0x5c, 0x46, + 0xc4, 0x64, 0x93, 0x53, 0xd9, 0xdd, 0x01, 0x03, 0xaf, 0xfc, 0xb6, 0x63, 0x4e, 0xd4, 0xca, 0xd8, + 0xe6, 0x97, 0x1d, 0x8b, 0xec, 0x40, 0xb2, 0x1d, 0xb7, 0xdd, 0xe0, 0x3d, 0x45, 0x83, 0xe5, 0x3b, + 0xfe, 0xd1, 0xf3, 0x5c, 0x04, 0xe4, 0x4d, 0xce, 0xaa, 0x71, 0xca, 0x13, 0x24, 0xb0, 0xa8, 0x8d, + 0xa2, 0x93, 0xf6, 0x3c, 0xa7, 0xb3, 0x4f, 0x44, 0xbe, 0xb2, 0x10, 0x6c, 0x71, 0xef, 0x5f, 0x19, + 0xb3, 0x89, 0xdf, 0x1b, 0xec, 0xf7, 0xd7, 0x12, 0x2c, 0x09, 0xb8, 0xa6, 0x25, 0x98, 0x09, 0x50, + 0x0b, 0xb9, 0xa5, 0x10, 0x62, 0x16, 0x62, 0x64, 0x17, 0x2b, 0xe5, 0xc8, 0x03, 0x68, 0xc6, 0x63, + 0xca, 0x9e, 0xe5, 0xb7, 0x61, 0xcb, 0x46, 0xa8, 0x37, 0x8d, 0xcf, 0x63, 0xc0, 0xaa, 0x27, 0x45, + 0x71, 0xf4, 0x5e, 0xc7, 0x44, 0xa8, 0xee, 0xbd, 0x94, 0xca, 0x75, 0x45, 0x43, 0x9c, 0x75, 0x8f, + 0xc1, 0x4b, 0x2b, 0x88, 0x72, 0x0b, 0x3e, 0x43, 0x5f, 0x8e, 0x2d, 0xd3, 0x7d, 0x25, 0xfc, 0xeb, + 0xc2, 0x22, 0x43, 0x9d, 0xef, 0x30, 0x28, 0xcb, 0x03, 0x6c, 0xd9, 0xde, 0x28, 0x92, 0xf9, 0x2f, + 0x6e, 0x1a, 0xcb, 0x02, 0x09, 0xe7, 0x67, 0xfb, 0x0c, 0x96, 0x04, 0x10, 0x7d, 0x97, 0x45, 0x5c, + 0x8c, 0x61, 0x70, 0x7e, 0xdc, 0x3f, 0x4d, 0x69, 0x89, 0x70, 0x82, 0xca, 0xf9, 0xd3, 0x74, 0x39, + 0xb7, 0x9c, 0x0f, 0x82, 0x54, 0x35, 0x97, 0x0f, 0xad, 0xe9, 0x82, 0xd0, 0x32, 0x73, 0xe5, 0xb5, + 0x28, 0xee, 0x3e, 0xce, 0x8f, 0xfe, 0x03, 0x56, 0xd7, 0x3b, 0xa2, 0xba, 0x56, 0x53, 0x2b, 0x94, + 0x7f, 0x2b, 0x53, 0x5d, 0xb7, 0xc7, 0xa9, 0xa9, 0x8a, 0xeb, 0x7f, 0x94, 0xa1, 0xa6, 0x78, 0xb9, + 0xda, 0xfa, 0x76, 0xae, 0xb6, 0x9e, 0xf0, 0x00, 0x2a, 0xbf, 0xed, 0x00, 0xc2, 0x52, 0x8f, 0x7f, + 0xf4, 0x02, 0x7a, 0x20, 0x3d, 0x50, 0xe5, 0x04, 0x93, 0x1e, 0x24, 0x2e, 0xad, 0x9c, 0xc9, 0xa5, + 0xb7, 0x33, 0x57, 0x70, 0x57, 0xf3, 0xf2, 0x85, 0x07, 0xc5, 0x76, 0xd1, 0xdd, 0xdb, 0x07, 0x05, + 0x9d, 0xdf, 0x5b, 0xf4, 0xba, 0x2b, 0x70, 0x80, 0x1e, 0x10, 0x32, 0x19, 0xad, 0x63, 0xb5, 0xac, + 0xa8, 0x12, 0x0c, 0x90, 0xfc, 0xd2, 0x4c, 0x4d, 0x8a, 0xed, 0xec, 0x94, 0x81, 0x93, 0x5b, 0xa4, + 0x33, 0xec, 0xec, 0x3f, 0xe8, 0x75, 0xcc, 0x98, 0xeb, 0x96, 0x77, 0x0d, 0xab, 0x09, 0xb7, 0xf8, + 0x5b, 0x00, 0x1b, 0x3f, 0x58, 0x31, 0x91, 0x0a, 0xb6, 0xa8, 0xf9, 0x6b, 0x92, 0x82, 0x6c, 0x2c, + 0x76, 0x0e, 0x1c, 0xd7, 0x09, 0x8f, 0x04, 0x7f, 0x86, 0xf3, 0x21, 0x26, 0x6d, 0xf0, 0x37, 0x13, + 0xfa, 0x06, 0x11, 0x46, 0xdf, 0xb3, 0x29, 0x06, 0x0d, 0x7f, 0x33, 0x61, 0x84, 0x4d, 0x6c, 0x27, + 0x3b, 0xa0, 0x3a, 0xd1, 0x0e, 0xa8, 0x65, 0x76, 0xc0, 0x12, 0xcc, 0xa0, 0xbe, 0xa1, 0xe7, 0xf2, + 0x92, 0xa3, 0x66, 0xca, 0x96, 0x56, 0x19, 0xd5, 0xc7, 0x55, 0x46, 0xa7, 0xdc, 0xda, 0x64, 0x2a, + 0xa3, 0xb9, 0x71, 0x95, 0xd1, 0x59, 0x2e, 0x6d, 0xb4, 0x62, 0xae, 0x71, 0x5a, 0x31, 0xf7, 0x63, + 0x6e, 0x8f, 0x47, 0x78, 0x58, 0x67, 0x03, 0x5a, 0xee, 0x8f, 0x5b, 0x99, 0xbb, 0x9d, 0xf6, 0x38, + 0x2b, 0xa8, 0xab, 0x9d, 0x57, 0x50, 0xdf, 0x7e, 0x83, 0xee, 0x3b, 0xfb, 0xe1, 0x8a, 0xaa, 0xf6, + 0x87, 0xb6, 0x44, 0x64, 0xec, 0x33, 0x2e, 0xda, 0xca, 0x49, 0xd1, 0xa6, 0x6a, 0x3f, 0x16, 0xa6, + 0x73, 0xb2, 0xf6, 0x33, 0xee, 0xc3, 0x9c, 0x98, 0x4b, 0x6a, 0xbb, 0xc4, 0xb4, 0xb5, 0xd9, 0x29, + 0x5d, 0xe2, 0x62, 0xb2, 0x25, 0xe9, 0x34, 0x08, 0xf8, 0xda, 0x05, 0x1d, 0x5b, 0xc6, 0x1d, 0xa8, + 0xf3, 0x78, 0x93, 0xc7, 0xe8, 0x0d, 0x1d, 0xdc, 0x9f, 0x16, 0x94, 0x0c, 0xd0, 0xb0, 0x84, 0xc2, + 0xe9, 0x6a, 0xf7, 0x7f, 0x92, 0x39, 0x5d, 0x16, 0xd3, 0xfd, 0x33, 0x27, 0xcb, 0x6b, 0xa8, 0x70, + 0x72, 0x6e, 0xf7, 0x5f, 0x62, 0x40, 0xd3, 0xf7, 0x7a, 0x91, 0x75, 0xa8, 0x9e, 0x40, 0x19, 0xe1, + 0x29, 0xb6, 0xf9, 0x0b, 0x2e, 0x63, 0xda, 0x0e, 0x4e, 0x1c, 0x85, 0x12, 0x95, 0xd4, 0x19, 0x6d, + 0x4b, 0x90, 0x58, 0x31, 0x10, 0x3a, 0xbf, 0xa3, 0xdc, 0x52, 0xd3, 0x26, 0xff, 0xc6, 0x72, 0x8c, + 0xe8, 0xfa, 0x4a, 0x73, 0x61, 0x68, 0xf2, 0xe5, 0xc4, 0x89, 0xaf, 0x99, 0x56, 0xd8, 0x94, 0x5c, + 0x34, 0x33, 0x11, 0x16, 0x48, 0x25, 0xbb, 0xb3, 0x5b, 0xeb, 0x33, 0x38, 0x9f, 0xea, 0xaf, 0x9e, + 0x1a, 0x52, 0x03, 0x64, 0x67, 0x97, 0x9d, 0xff, 0x5d, 0x02, 0xd8, 0x18, 0x45, 0x47, 0x12, 0xf3, + 0x75, 0xa0, 0xca, 0xc0, 0xaa, 0x56, 0xee, 0xa8, 0x36, 0xe3, 0xf9, 0x56, 0x18, 0x22, 0xe0, 0x8a, + 0x0b, 0x1f, 0xd5, 0xe6, 0x78, 0x6d, 0xa4, 0x5e, 0x50, 0xf9, 0x37, 0x7b, 0x81, 0x15, 0xcf, 0xce, + 0x3d, 0xc4, 0xab, 0x88, 0xd4, 0x43, 0x79, 0xc2, 0x36, 0x04, 0x75, 0x43, 0x10, 0x99, 0x98, 0x63, + 0x53, 0x54, 0x2d, 0x3a, 0xe9, 0x45, 0xde, 0x6b, 0xea, 0x4a, 0x64, 0xd7, 0x88, 0xa9, 0x4f, 0x19, + 0x91, 0x89, 0x05, 0xf4, 0x10, 0xad, 0x1c, 0xc4, 0x62, 0x33, 0x42, 0x2c, 0xa6, 0x72, 0x31, 0xf6, + 0x62, 0xdf, 0xda, 0x1f, 0x0d, 0x06, 0x62, 0x91, 0x93, 0xda, 0x12, 0x81, 0x94, 0x58, 0x47, 0xf6, + 0xfa, 0x20, 0x31, 0x91, 0x5c, 0xdc, 0xf7, 0xaf, 0xe1, 0xcf, 0xc3, 0x82, 0xa6, 0xa8, 0x2c, 0x3f, + 0x31, 0x16, 0x44, 0x65, 0xfa, 0x6e, 0xfa, 0x1b, 0x17, 0xe0, 0x7c, 0xaa, 0xbf, 0x18, 0x76, 0xf5, + 0x32, 0x54, 0xe3, 0xd7, 0x79, 0x32, 0x0b, 0xe5, 0xa7, 0x9b, 0xfb, 0xad, 0x73, 0xec, 0xe3, 0xd9, + 0xd6, 0x7e, 0xab, 0xb4, 0xba, 0x0a, 0xf3, 0x99, 0x4b, 0x47, 0x52, 0x83, 0x8a, 0xb9, 0xbd, 0xb1, + 0xf5, 0x02, 0xc5, 0xe6, 0xa0, 0xba, 0xf7, 0xe4, 0xa9, 0x68, 0x95, 0x56, 0x37, 0xa1, 0x99, 0x3e, + 0xee, 0x48, 0x1d, 0x66, 0x37, 0x91, 0xfb, 0x74, 0x7b, 0x0b, 0x85, 0xb1, 0x61, 0x3e, 0xdb, 0xdb, + 0xdb, 0xd9, 0x7b, 0xd8, 0x2a, 0x11, 0x80, 0x99, 0xed, 0x6f, 0x76, 0x18, 0x63, 0x8a, 0x31, 0x9e, + 0xed, 0x3d, 0xda, 0x7b, 0xf2, 0x9b, 0xbd, 0x56, 0x79, 0xfd, 0x9f, 0x55, 0x68, 0x9a, 0x62, 0x09, + 0x5d, 0x8c, 0x05, 0x07, 0x81, 0xe4, 0x7d, 0x98, 0x8d, 0x7f, 0x7d, 0x48, 0x0e, 0xd6, 0xf4, 0x7f, + 0x1a, 0x9d, 0x76, 0x9e, 0x21, 0xcd, 0x76, 0x8e, 0xbc, 0x80, 0x56, 0xf6, 0xd1, 0x8d, 0x24, 0x17, + 0x48, 0x63, 0x5e, 0xf7, 0x3a, 0xd7, 0x4f, 0x91, 0x50, 0x43, 0x77, 0xa1, 0x99, 0x7e, 0x4e, 0x23, + 0x49, 0x69, 0x57, 0xf8, 0x4c, 0xd7, 0xb9, 0x36, 0x96, 0xaf, 0xeb, 0x9b, 0x7d, 0x48, 0xd3, 0xf4, + 0x1d, 0xf3, 0x48, 0xa7, 0xe9, 0x3b, 0xf6, 0x15, 0x8e, 0x0f, 0x9d, 0x7b, 0x72, 0x5a, 0x19, 0xff, + 0x68, 0x90, 0x1b, 0x7a, 0xdc, 0x4b, 0x84, 0x30, 0x45, 0xfa, 0xc6, 0x97, 0xe8, 0x0f, 0x3d, 0x05, + 0x37, 0xee, 0x9a, 0x29, 0x8a, 0xaf, 0x8a, 0x71, 0xd0, 0xe7, 0x58, 0xb2, 0xa5, 0xc1, 0x2c, 0xb9, + 0x96, 0xf1, 0x4b, 0x16, 0xe4, 0x75, 0x56, 0xc6, 0x0b, 0xa4, 0xfd, 0xa6, 0x43, 0xd5, 0x94, 0xdf, + 0x0a, 0xf0, 0x6f, 0xca, 0x6f, 0x85, 0x18, 0xf7, 0x1c, 0xd9, 0x87, 0x46, 0x0a, 0x90, 0x92, 0x2b, + 0x29, 0x5f, 0xe7, 0x86, 0xbc, 0x3a, 0x8e, 0xad, 0x2f, 0x3f, 0x03, 0x46, 0xb5, 0xe5, 0x17, 0x63, + 0xdc, 0xce, 0xca, 0x78, 0x81, 0xac, 0xaf, 0x92, 0xaa, 0x3c, 0xe3, 0xab, 0x1c, 0x7e, 0xcb, 0xf8, + 0x2a, 0x5f, 0xce, 0x4b, 0x5f, 0x65, 0xca, 0xeb, 0x6b, 0x63, 0x6b, 0x96, 0xbc, 0xaf, 0x8a, 0xcb, + 0x20, 0x1c, 0xf7, 0x2e, 0x4c, 0xb3, 0x52, 0x83, 0x24, 0x87, 0xba, 0x56, 0xe5, 0x74, 0x2e, 0x64, + 0xa8, 0x71, 0xb7, 0x1b, 0xa5, 0x5b, 0xa5, 0xf5, 0xbf, 0x4d, 0xc1, 0x9c, 0xc8, 0x83, 0x32, 0x95, + 0x3c, 0x04, 0x48, 0x4e, 0x63, 0xd2, 0x49, 0x2d, 0x2a, 0x55, 0x52, 0x74, 0x2e, 0x15, 0xf2, 0x94, + 0x52, 0x5f, 0xcb, 0xfa, 0x45, 0x2e, 0xf4, 0x52, 0x26, 0xed, 0xa6, 0x16, 0x79, 0xb9, 0x98, 0xa9, + 0xc6, 0xda, 0x82, 0x9a, 0xca, 0xf6, 0x44, 0x3b, 0x24, 0x32, 0x47, 0x55, 0xa7, 0x53, 0xc4, 0xd2, + 0x35, 0xd2, 0xd2, 0xbb, 0xa6, 0x51, 0xfe, 0xd0, 0xd0, 0x34, 0x2a, 0x38, 0x11, 0x8c, 0x73, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0xff, 0x42, 0xad, 0xb8, 0x8d, 0x1c, 0x27, 0x00, 0x00, } diff --git a/pkg/kubelet/api/v1alpha1/runtime/api.proto b/pkg/kubelet/api/v1alpha1/runtime/api.proto index 72d9de6ad7b..1082501966e 100644 --- a/pkg/kubelet/api/v1alpha1/runtime/api.proto +++ b/pkg/kubelet/api/v1alpha1/runtime/api.proto @@ -134,11 +134,29 @@ message LinuxPodSandboxConfig { optional NamespaceOption namespace_options = 2; } +// PodSandboxMetadata holds all necessary information for building the sandbox name. +// The container runtime is encouraged to expose the metadata associated with the +// PodSandbox in its user interface for better user experience. E.g., runtime can +// construct a unique PodSandboxName based on the metadata. +message PodSandboxMetadata { + // The pod name of the sandbox. Same as the pod name in the PodSpec. + optional string name = 1; + // The pod uid of the sandbox. Same as the pod UID in the PodSpec. + optional string uid = 2; + // The pod namespace of the sandbox. Same as the pod namespace in the PodSpec. + optional string namespace = 3; + // The attempt number of creating the sandbox. + optional uint32 attempt = 4; +} + // PodSandboxConfig holds all the required and optional fields for creating a // sandbox. message PodSandboxConfig { - // The name of the sandbox. - optional string name = 1; + // The metadata of the sandbox. This information will uniquely identify + // the sandbox, and the runtime should leverage this to ensure correct + // operation. The runtime may also use this information to improve UX, such + // as by constructing a readable name. + optional PodSandboxMetadata metadata = 1; // The hostname of the sandbox. optional string hostname = 2; // Path to the directory on the host in which container log files are @@ -228,8 +246,8 @@ enum PodSandBoxState { message PodSandboxStatus { // ID of the sandbox. optional string id = 1; - // Name of the sandbox - optional string name = 2; + // Metadata of the sandbox. + optional PodSandboxMetadata metadata = 2; // State of the sandbox. optional PodSandBoxState state = 3; // Creation timestamp of the sandbox @@ -275,8 +293,8 @@ message ListPodSandboxRequest { message PodSandbox { // The id of the PodSandbox optional string id = 1; - // The name of the PodSandbox - optional string name = 2; + // Metadata of the sandbox + optional PodSandboxMetadata metadata = 2; // The state of the PodSandbox optional PodSandBoxState state = 3; // Creation timestamps of the sandbox @@ -358,9 +376,26 @@ message LinuxUser { repeated int64 additional_gids = 3; } -message ContainerConfig { - // Name of the container. +// ContainerMetadata holds all necessary information for building the container +// name. The container runtime is encouraged to expose the metadata in its user +// interface for better user experience. E.g., runtime can construct a unique +// container name based on the metadata. Note that (name, attempt) is unique +// within a sandbox for the entire lifetime of the sandbox. +message ContainerMetadata { + // The name of the container. Same as the container name in the PodSpec. optional string name = 1; + // The attempt number of creating the container. + optional uint32 attempt = 2; +} + +// ContainerConfig holds all the required and optional fields for creating a +// container. +message ContainerConfig { + // The metadata of the container. This information will uniquely identify + // the container, and the runtime should leverage this to ensure correct + // operation. The runtime may also use this information to improve UX, such + // as by constructing a readable name. + optional ContainerMetadata metadata = 1 ; // Image to use. optional ImageSpec image = 2; // Command to execute (i.e., entrypoint for docker) @@ -484,8 +519,8 @@ message Container { // The ID of the container, used by the container runtime to identify // a container. optional string id = 1; - // The name of the container - optional string name = 2; + // The metadata of the container. + optional ContainerMetadata metadata = 2; // The spec of the image optional ImageSpec image = 3; // Reference to the image in use. For most runtimes, this should be an @@ -514,8 +549,8 @@ message ContainerStatusRequest { message ContainerStatus { // ID of the container. optional string id = 1; - // Name of the container. - optional string name = 2; + // Metadata of the container. + optional ContainerMetadata metadata = 2; // Status of the container. optional ContainerState state = 3; // Creation time of the container. diff --git a/pkg/kubelet/dockershim/convert.go b/pkg/kubelet/dockershim/convert.go index 0672e78fba0..a2ee3bfc772 100644 --- a/pkg/kubelet/dockershim/convert.go +++ b/pkg/kubelet/dockershim/convert.go @@ -51,9 +51,13 @@ func toRuntimeAPIImage(image *dockertypes.Image) (*runtimeApi.Image, error) { func toRuntimeAPIContainer(c *dockertypes.Container) *runtimeApi.Container { state := toRuntimeAPIContainerState(c.Status) + _, _, _, containerName, attempt, _ := parseContainerName(c.Names[0]) return &runtimeApi.Container{ - Id: &c.ID, - Name: &c.Names[0], + Id: &c.ID, + Metadata: &runtimeApi.ContainerMetadata{ + Name: &containerName, + Attempt: &attempt, + }, Image: &runtimeApi.ImageSpec{Image: &c.Image}, ImageRef: &c.ImageID, State: &state, @@ -104,9 +108,15 @@ func toRuntimeAPISandboxState(state string) runtimeApi.PodSandBoxState { func toRuntimeAPISandbox(c *dockertypes.Container) *runtimeApi.PodSandbox { state := toRuntimeAPISandboxState(c.Status) + podName, podNamespace, podUID, attempt, _ := parseSandboxName(c.Names[0]) return &runtimeApi.PodSandbox{ - Id: &c.ID, - Name: &c.Names[0], + Id: &c.ID, + Metadata: &runtimeApi.PodSandboxMetadata{ + Name: &podName, + Namespace: &podNamespace, + Uid: &podUID, + Attempt: &attempt, + }, State: &state, CreatedAt: &c.Created, // TODO: Why do we need CreateAt timestamp for sandboxes? Labels: c.Labels, // TODO: Need to disthinguish annotaions and labels. diff --git a/pkg/kubelet/dockershim/docker_container.go b/pkg/kubelet/dockershim/docker_container.go index c602f3c564f..a9f9d5526ff 100644 --- a/pkg/kubelet/dockershim/docker_container.go +++ b/pkg/kubelet/dockershim/docker_container.go @@ -38,9 +38,6 @@ func (ds *dockerService) ListContainers(filter *runtimeApi.ContainerFilter) ([]* f := newDockerFilter(&opts.Filter) if filter != nil { - if filter.Name != nil { - f.Add("name", filter.GetName()) - } if filter.Id != nil { f.Add("id", filter.GetId()) } @@ -66,6 +63,13 @@ func (ds *dockerService) ListContainers(filter *runtimeApi.ContainerFilter) ([]* // Convert docker to runtime api containers. result := []*runtimeApi.Container{} for _, c := range containers { + if len(filter.GetName()) > 0 { + _, _, _, containerName, _, err := parseContainerName(c.Names[0]) + if err != nil || containerName != filter.GetName() { + continue + } + } + result = append(result, toRuntimeAPIContainer(&c)) } return result, nil @@ -79,7 +83,7 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi return "", fmt.Errorf("container config is nil") } if sandboxConfig == nil { - return "", fmt.Errorf("sandbox config is nil for container %q", config.GetName()) + return "", fmt.Errorf("sandbox config is nil for container %q", config.Metadata.GetName()) } // Merge annotations and labels because docker supports only labels. @@ -94,7 +98,7 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi image = iSpec.GetImage() } createConfig := dockertypes.ContainerCreateConfig{ - Name: config.GetName(), + Name: buildContainerName(sandboxConfig, config), Config: &dockercontainer.Config{ // TODO: set User. Hostname: sandboxConfig.GetHostname(), @@ -274,9 +278,17 @@ func (ds *dockerService) ContainerStatus(containerID string) (*runtimeApi.Contai ct, st, ft := createdAt.Unix(), startedAt.Unix(), finishedAt.Unix() exitCode := int32(r.State.ExitCode) + _, _, _, containerName, attempt, err := parseContainerName(r.Name) + if err != nil { + return nil, err + } + return &runtimeApi.ContainerStatus{ - Id: &r.ID, - Name: &r.Name, + Id: &r.ID, + Metadata: &runtimeApi.ContainerMetadata{ + Name: &containerName, + Attempt: &attempt, + }, Image: &runtimeApi.ImageSpec{Image: &r.Config.Image}, ImageRef: &r.Image, Mounts: mounts, diff --git a/pkg/kubelet/dockershim/docker_sandbox.go b/pkg/kubelet/dockershim/docker_sandbox.go index 4dd87024025..c1a0e8a0b90 100644 --- a/pkg/kubelet/dockershim/docker_sandbox.go +++ b/pkg/kubelet/dockershim/docker_sandbox.go @@ -55,7 +55,7 @@ func (ds *dockerService) CreatePodSandbox(config *runtimeApi.PodSandboxConfig) ( createConfig := makeSandboxDockerConfig(config, image) createResp, err := ds.client.CreateContainer(*createConfig) if err != nil || createResp == nil { - return "", fmt.Errorf("failed to create a sandbox for pod %q: %v", config.GetName(), err) + return "", fmt.Errorf("failed to create a sandbox for pod %q: %v", config.Metadata.GetName(), err) } // Step 3: Start the sandbox container. @@ -117,11 +117,21 @@ func (ds *dockerService) PodSandboxStatus(podSandboxID string) (*runtimeApi.PodS network := &runtimeApi.PodSandboxNetworkStatus{Ip: &IP} netNS := getNetworkNamespace(r) + podName, podNamespace, podUID, attempt, err := parseSandboxName(r.Name) + if err != nil { + return nil, err + } + return &runtimeApi.PodSandboxStatus{ Id: &r.ID, - Name: &r.Name, State: &state, CreatedAt: &ct, + Metadata: &runtimeApi.PodSandboxMetadata{ + Name: &podName, + Namespace: &podNamespace, + Uid: &podUID, + Attempt: &attempt, + }, // TODO: We write annotations as labels on the docker containers. All // these annotations will be read back as labels. Need to fix this. // Also filter out labels only relevant to this shim. @@ -140,9 +150,6 @@ func (ds *dockerService) ListPodSandbox(filter *runtimeApi.PodSandboxFilter) ([] opts.Filter = dockerfilters.NewArgs() f := newDockerFilter(&opts.Filter) if filter != nil { - if filter.Name != nil { - f.Add("name", filter.GetName()) - } if filter.Id != nil { f.Add("id", filter.GetId()) } @@ -176,6 +183,13 @@ func (ds *dockerService) ListPodSandbox(filter *runtimeApi.PodSandboxFilter) ([] // Convert docker containers to runtime api sandboxes. result := []*runtimeApi.PodSandbox{} for _, c := range containers { + if len(filter.GetName()) > 0 { + sandboxName, _, _, _, err := parseSandboxName(c.Names[0]) + if err != nil || sandboxName != filter.GetName() { + continue + } + } + s := toRuntimeAPISandbox(&c) if filterOutReadySandboxes && s.GetState() == runtimeApi.PodSandBoxState_READY { continue @@ -193,7 +207,7 @@ func makeSandboxDockerConfig(c *runtimeApi.PodSandboxConfig, image string) *dock hc := &dockercontainer.HostConfig{} createConfig := &dockertypes.ContainerCreateConfig{ - Name: c.GetName(), + Name: buildSandboxName(c), Config: &dockercontainer.Config{ Hostname: c.GetHostname(), // TODO: Handle environment variables. diff --git a/pkg/kubelet/dockershim/docker_sandbox_test.go b/pkg/kubelet/dockershim/docker_sandbox_test.go index b5066bf6d9e..c10c35cf479 100644 --- a/pkg/kubelet/dockershim/docker_sandbox_test.go +++ b/pkg/kubelet/dockershim/docker_sandbox_test.go @@ -27,18 +27,19 @@ import ( func TestCreateSandbox(t *testing.T) { ds, fakeDocker := newTestDockerSevice() name := "FOO" - // We don't really want to test k8s name format and parsing, - // but FakeDockerClient parses the name internally during AssertCreated(). - // TODO: fix this. - fullName := "k8s_" + name + ".abcde_foo_new_12345678_0" - config := &runtimeApi.PodSandboxConfig{Name: &fullName} + namespace := "BAR" + uid := "1" + config := &runtimeApi.PodSandboxConfig{ + Metadata: &runtimeApi.PodSandboxMetadata{ + Name: &name, + Namespace: &namespace, + Uid: &uid, + }, + } id, err := ds.CreatePodSandbox(config) if err != nil { t.Errorf("Unexpected error: %v", err) } - if err := fakeDocker.AssertCreated([]string{name}); err != nil { - t.Errorf("%v", err) - } if err := fakeDocker.AssertStarted([]string{id}); err != nil { t.Errorf("%v", err) } diff --git a/pkg/kubelet/dockershim/helpers.go b/pkg/kubelet/dockershim/helpers.go index a8aa51d3cbd..95e23a5aa45 100644 --- a/pkg/kubelet/dockershim/helpers.go +++ b/pkg/kubelet/dockershim/helpers.go @@ -18,6 +18,7 @@ package dockershim import ( "fmt" + "math/rand" "strconv" "strings" @@ -30,6 +31,13 @@ import ( runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" ) +const ( + // kubePrefix is used to identify the containers/sandboxes on the node managed by kubelet + kubePrefix = "k8s" + // kubeSandboxNamePrefix is used to keep sandbox name consistent with old podInfraContainer name + kubeSandboxNamePrefix = "POD" +) + // apiVersion implements kubecontainer.Version interface by implementing // Compare() and String(). It uses the compare function of engine-api to // compare docker apiversions. @@ -158,6 +166,71 @@ func getNetworkNamespace(c *dockertypes.ContainerJSON) string { return fmt.Sprintf(dockerNetNSFmt, c.State.Pid) } +// buildKubeGenericName creates a name which can be reversed to identify container/sandbox name. +// This function returns the unique name. +func buildKubeGenericName(sandboxConfig *runtimeApi.PodSandboxConfig, containerName string) string { + stableName := fmt.Sprintf("%s_%s_%s_%s_%s", + kubePrefix, + containerName, + sandboxConfig.Metadata.GetName(), + sandboxConfig.Metadata.GetNamespace(), + sandboxConfig.Metadata.GetUid(), + ) + UID := fmt.Sprintf("%08x", rand.Uint32()) + return fmt.Sprintf("%s_%s", stableName, UID) +} + +// buildSandboxName creates a name which can be reversed to identify sandbox full name. +func buildSandboxName(sandboxConfig *runtimeApi.PodSandboxConfig) string { + sandboxName := fmt.Sprintf("%s.%d", kubeSandboxNamePrefix, sandboxConfig.Metadata.GetAttempt()) + return buildKubeGenericName(sandboxConfig, sandboxName) +} + +// parseSandboxName unpacks a sandbox full name, returning the pod name, namespace, uid and attempt. +func parseSandboxName(name string) (string, string, string, uint32, error) { + podName, podNamespace, podUID, _, attempt, err := parseContainerName(name) + if err != nil { + return "", "", "", 0, err + } + + return podName, podNamespace, podUID, attempt, nil +} + +// buildContainerName creates a name which can be reversed to identify container name. +// This function returns stable name, unique name and an unique id. +func buildContainerName(sandboxConfig *runtimeApi.PodSandboxConfig, containerConfig *runtimeApi.ContainerConfig) string { + containerName := fmt.Sprintf("%s.%d", containerConfig.Metadata.GetName(), containerConfig.Metadata.GetAttempt()) + return buildKubeGenericName(sandboxConfig, containerName) +} + +// parseContainerName unpacks a container name, returning the pod name, namespace, UID, +// container name and attempt. +func parseContainerName(name string) (podName, podNamespace, podUID, containerName string, attempt uint32, err error) { + parts := strings.Split(name, "_") + if len(parts) == 0 || parts[0] != kubePrefix { + err = fmt.Errorf("failed to parse container name %q into parts", name) + return "", "", "", "", 0, err + } + if len(parts) < 6 { + glog.Warningf("Found a container with the %q prefix, but too few fields (%d): %q", kubePrefix, len(parts), name) + err = fmt.Errorf("container name %q has fewer parts than expected %v", name, parts) + return "", "", "", "", 0, err + } + + nameParts := strings.Split(parts[1], ".") + containerName = nameParts[0] + if len(nameParts) > 1 { + attemptNumber, err := strconv.ParseUint(nameParts[1], 10, 32) + if err != nil { + glog.Warningf("invalid container attempt %q in container %q", nameParts[1], name) + } + + attempt = uint32(attemptNumber) + } + + return parts[2], parts[3], parts[4], containerName, attempt, nil +} + // dockerFilter wraps around dockerfilters.Args and provides methods to modify // the filter easily. type dockerFilter struct { diff --git a/pkg/kubelet/kuberuntime/helpers.go b/pkg/kubelet/kuberuntime/helpers.go index d3a03d6acce..7cc24dedc74 100644 --- a/pkg/kubelet/kuberuntime/helpers.go +++ b/pkg/kubelet/kuberuntime/helpers.go @@ -18,9 +18,6 @@ package kuberuntime import ( "fmt" - "math/rand" - "strconv" - "strings" "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" @@ -29,11 +26,6 @@ import ( ) const ( - // kubePrefix is used to identify the containers/sandboxes on the node managed by kubelet - kubePrefix = "k8s" - // kubeSandboxNamePrefix is used to keep sandbox name consistent with old podInfraContainer name - kubeSandboxNamePrefix = "POD" - // Taken from lmctfy https://github.com/google/lmctfy/blob/master/lmctfy/controllers/cpu_controller.cc minShares = 2 sharesPerCPU = 1024 @@ -56,69 +48,6 @@ func (b containersByID) Len() int { return len(b) } func (b containersByID) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b containersByID) Less(i, j int) bool { return b[i].ID.ID < b[j].ID.ID } -// buildSandboxName creates a name which can be reversed to identify sandbox full name -func buildSandboxName(pod *api.Pod) string { - _, sandboxName, _ := buildKubeGenericName(pod, kubeSandboxNamePrefix) - return sandboxName -} - -// parseSandboxName unpacks a sandbox full name, returning the pod name, namespace and uid -func parseSandboxName(name string) (string, string, string, error) { - podName, podNamespace, podUID, _, _, err := parseContainerName(name) - if err != nil { - return "", "", "", err - } - - return podName, podNamespace, podUID, nil -} - -// buildContainerName creates a name which can be reversed to identify container name. -// This function returns stable name, unique name and an unique id. -func buildContainerName(pod *api.Pod, container *api.Container) (string, string, string) { - // kubelet uses hash to determine whether an existing container matches the desired spec. - containerName := container.Name + "." + strconv.FormatUint(kubecontainer.HashContainer(container), 16) - return buildKubeGenericName(pod, containerName) -} - -// buildKubeGenericName creates a name which can be reversed to identify container/sandbox name. -// This function returns stable name, unique name and an unique id. -func buildKubeGenericName(pod *api.Pod, containerName string) (string, string, string) { - stableName := fmt.Sprintf("%s_%s_%s_%s_%s", - kubePrefix, - containerName, - pod.Name, - pod.Namespace, - string(pod.UID), - ) - UID := fmt.Sprintf("%08x", rand.Uint32()) - return stableName, fmt.Sprintf("%s_%s", stableName, UID), UID -} - -// parseContainerName unpacks a container name, returning the pod name, namespace, UID and container name -func parseContainerName(name string) (podName, podNamespace, podUID, containerName string, hash uint64, err error) { - parts := strings.Split(name, "_") - if len(parts) == 0 || parts[0] != kubePrefix { - err = fmt.Errorf("failed to parse container name %q into parts", name) - return "", "", "", "", 0, err - } - if len(parts) < 6 { - glog.Warningf("Found a container with the %q prefix, but too few fields (%d): %q", kubePrefix, len(parts), name) - err = fmt.Errorf("container name %q has fewer parts than expected %v", name, parts) - return "", "", "", "", 0, err - } - - nameParts := strings.Split(parts[1], ".") - containerName = nameParts[0] - if len(nameParts) > 1 { - hash, err = strconv.ParseUint(nameParts[1], 16, 32) - if err != nil { - glog.Warningf("Invalid container hash %q in container %q", nameParts[1], name) - } - } - - return parts[2], parts[3], parts[4], containerName, hash, nil -} - // toKubeContainerState converts runtimeApi.ContainerState to kubecontainer.ContainerState. func toKubeContainerState(state runtimeApi.ContainerState) kubecontainer.ContainerState { switch state { diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container.go b/pkg/kubelet/kuberuntime/kuberuntime_container.go index cee8c9ee3da..c39809f3c4f 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container.go @@ -19,6 +19,7 @@ package kuberuntime import ( "fmt" "io" + "math/rand" "os" "path" @@ -42,19 +43,22 @@ func (m *kubeGenericRuntimeManager) generateContainerConfig(container *api.Conta return nil, err } - _, containerName, cid := buildContainerName(pod, container) command, args := kubecontainer.ExpandContainerCommandAndArgs(container, opts.Envs) - containerLogsPath := getContainerLogsPath(containerName, pod.UID) + containerLogsPath := getContainerLogsPath(container.Name, pod.UID) podHasSELinuxLabel := pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.SELinuxOptions != nil + restartCountUint32 := uint32(restartCount) config := &runtimeApi.ContainerConfig{ - Name: &containerName, + Metadata: &runtimeApi.ContainerMetadata{ + Name: &container.Name, + Attempt: &restartCountUint32, + }, Image: &runtimeApi.ImageSpec{Image: &container.Image}, Command: command, Args: args, WorkingDir: &container.WorkingDir, Labels: newContainerLabels(container, pod), Annotations: newContainerAnnotations(container, pod, restartCount), - Mounts: makeMounts(cid, opts, container, podHasSELinuxLabel), + Mounts: makeMounts(opts, container, podHasSELinuxLabel), LogPath: &containerLogsPath, Stdin: &container.Stdin, StdinOnce: &container.StdinOnce, @@ -150,7 +154,7 @@ func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(container *api. } // makeMounts generates container volume mounts for kubelet runtime api. -func makeMounts(cid string, opts *kubecontainer.RunContainerOptions, container *api.Container, podHasSELinuxLabel bool) []*runtimeApi.Mount { +func makeMounts(opts *kubecontainer.RunContainerOptions, container *api.Container, podHasSELinuxLabel bool) []*runtimeApi.Mount { volumeMounts := []*runtimeApi.Mount{} for idx := range opts.Mounts { @@ -173,8 +177,9 @@ func makeMounts(cid string, opts *kubecontainer.RunContainerOptions, container * // mount the file before actually starting the container. if opts.PodContainerDir != "" && len(container.TerminationMessagePath) != 0 { // Because the PodContainerDir contains pod uid and container name which is unique enough, - // here we just add an unique container id to make the path unique for different instances + // here we just add a random id to make the path unique for different instances // of the same container. + cid := makeUID() containerLogPath := path.Join(opts.PodContainerDir, cid) fs, err := os.Create(containerLogPath) if err != nil { @@ -222,6 +227,11 @@ func (m *kubeGenericRuntimeManager) getContainersHelper(filter *runtimeApi.Conta return resp, err } +// makeUID returns a randomly generated string. +func makeUID() string { + return fmt.Sprintf("%08x", rand.Uint32()) +} + // AttachContainer attaches to the container's console func (m *kubeGenericRuntimeManager) AttachContainer(id kubecontainer.ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan term.Size) (err error) { return fmt.Errorf("not implemented") diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager.go b/pkg/kubelet/kuberuntime/kuberuntime_manager.go index c6952a0d8b9..96a4b0fb96a 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager.go @@ -229,12 +229,11 @@ func (m *kubeGenericRuntimeManager) GetPods(all bool) ([]*kubecontainer.Pod, err return nil, err } for _, s := range sandboxes { - name, namespace, uid, _ := parseSandboxName(s.GetName()) - podUID := kubetypes.UID(uid) + podUID := kubetypes.UID(s.Metadata.GetUid()) pods[podUID] = &kubecontainer.Pod{ ID: podUID, - Name: name, - Namespace: namespace, + Name: s.Metadata.GetName(), + Namespace: s.Metadata.GetNamespace(), } } diff --git a/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go b/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go index a1915328766..060636d7cd9 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_manager_test.go @@ -69,22 +69,21 @@ func makeAndSetFakePod(m *kubeGenericRuntimeManager, fakeRuntime *apitest.FakeRu } func makeFakePodSandbox(m *kubeGenericRuntimeManager, pod *api.Pod) (*apitest.FakePodSandbox, error) { - config, err := m.generatePodSandboxConfig(pod, "") + config, err := m.generatePodSandboxConfig(pod, "", 0) if err != nil { return nil, err } - podSandboxID := config.GetName() + podSandboxID := apitest.BuildSandboxName(config.Metadata) readyState := runtimeApi.PodSandBoxState_READY return &apitest.FakePodSandbox{ - PodSandbox: runtimeApi.PodSandbox{ + PodSandboxStatus: runtimeApi.PodSandboxStatus{ Id: &podSandboxID, - Name: config.Name, + Metadata: config.Metadata, State: &readyState, CreatedAt: &fakeCreatedAt, Labels: config.Labels, }, - Annotations: config.Annotations, }, nil } @@ -94,13 +93,14 @@ func makeFakeContainer(m *kubeGenericRuntimeManager, pod *api.Pod, container api return nil, err } - containerID := containerConfig.GetName() + containerID := apitest.BuildContainerName(containerConfig.Metadata) + podSandboxID := apitest.BuildSandboxName(sandboxConfig.Metadata) runningState := runtimeApi.ContainerState_RUNNING imageRef := containerConfig.Image.GetImage() return &apitest.FakeContainer{ ContainerStatus: runtimeApi.ContainerStatus{ Id: &containerID, - Name: containerConfig.Name, + Metadata: containerConfig.Metadata, Image: containerConfig.Image, ImageRef: &imageRef, CreatedAt: &fakeCreatedAt, @@ -108,12 +108,12 @@ func makeFakeContainer(m *kubeGenericRuntimeManager, pod *api.Pod, container api Labels: containerConfig.Labels, Annotations: containerConfig.Annotations, }, - SandboxID: sandboxConfig.GetName(), + SandboxID: podSandboxID, }, nil } func makeFakeContainers(m *kubeGenericRuntimeManager, pod *api.Pod, containers []api.Container) ([]*apitest.FakeContainer, error) { - sandboxConfig, err := m.generatePodSandboxConfig(pod, "") + sandboxConfig, err := m.generatePodSandboxConfig(pod, "", 0) if err != nil { return nil, err } @@ -208,7 +208,7 @@ func TestGetPods(t *testing.T) { fakeContainer := fakeContainers[i] c, err := m.toKubeContainer(&runtimeApi.Container{ Id: fakeContainer.Id, - Name: fakeContainer.Name, + Metadata: fakeContainer.Metadata, State: fakeContainer.State, Image: fakeContainer.Image, ImageRef: fakeContainer.ImageRef, diff --git a/pkg/kubelet/kuberuntime/kuberuntime_sandbox.go b/pkg/kubelet/kuberuntime/kuberuntime_sandbox.go index f3af601a885..9e18a7c5a58 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_sandbox.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_sandbox.go @@ -24,12 +24,17 @@ import ( ) // generatePodSandboxConfig generates pod sandbox config from api.Pod. -func (m *kubeGenericRuntimeManager) generatePodSandboxConfig(pod *api.Pod, podIP string) (*runtimeApi.PodSandboxConfig, error) { - sandboxName := buildSandboxName(pod) +func (m *kubeGenericRuntimeManager) generatePodSandboxConfig(pod *api.Pod, podIP string, attempt uint32) (*runtimeApi.PodSandboxConfig, error) { // TODO: deprecating podsandbox resource requirements in favor of the pod level cgroup // Refer https://github.com/kubernetes/kubernetes/issues/29871 + podUID := string(pod.UID) podSandboxConfig := &runtimeApi.PodSandboxConfig{ - Name: &sandboxName, + Metadata: &runtimeApi.PodSandboxMetadata{ + Name: &pod.Name, + Namespace: &pod.Namespace, + Uid: &podUID, + Attempt: &attempt, + }, Labels: newPodLabels(pod), Annotations: newPodAnnotations(pod), } @@ -126,7 +131,8 @@ func (m *kubeGenericRuntimeManager) getKubeletSandboxes(all bool) ([]*runtimeApi result := []*runtimeApi.PodSandbox{} for _, s := range resp { if !isManagedByKubelet(s.Labels) { - glog.V(5).Infof("Sandbox %s is not managed by kubelet", s.GetName()) + glog.V(5).Infof("Sandbox %s is not managed by kubelet", kubecontainer.BuildPodFullName( + s.Metadata.GetName(), s.Metadata.GetNamespace())) continue } diff --git a/pkg/kubelet/rktshim/fake-app-interface.go b/pkg/kubelet/rktshim/fake-app-interface.go index 7176d513920..23ffefd3f86 100644 --- a/pkg/kubelet/rktshim/fake-app-interface.go +++ b/pkg/kubelet/rktshim/fake-app-interface.go @@ -181,7 +181,7 @@ func (r *FakeRuntime) ListContainers(*runtimeApi.ContainerFilter) ([]*runtimeApi for _, c := range r.Containers { list = append(list, &runtimeApi.Container{ Id: c.Status.Id, - Name: c.Config.Name, + Metadata: c.Config.Metadata, Labels: c.Config.Labels, ImageRef: c.Status.ImageRef, State: &c.State,