Merge pull request #526 from crosbymichael/no-bundles

Remove concept of bundles from API
This commit is contained in:
Michael Crosby 2017-02-16 11:27:40 -08:00 committed by GitHub
commit 8a4ad6e381
142 changed files with 11129 additions and 27653 deletions

File diff suppressed because it is too large Load diff

View file

@ -3,116 +3,54 @@ syntax = "proto3";
package containerd.v1.services;
import "google/protobuf/empty.proto";
import "google/protobuf/any.proto";
import "gogoproto/gogo.proto";
import "github.com/docker/containerd/api/types/mount/mount.proto";
import "github.com/docker/containerd/api/types/container/container.proto";
import "github.com/docker/containerd/api/types/process/process.proto";
service ExecutionService {
rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse);
rpc StartContainer(StartContainerRequest) returns (google.protobuf.Empty);
rpc UpdateContainer(UpdateContainerRequest) returns (google.protobuf.Empty);
rpc PauseContainer(PauseContainerRequest) returns (google.protobuf.Empty);
rpc ResumeContainer(ResumeContainerRequest) returns (google.protobuf.Empty);
rpc DeleteContainer(DeleteContainerRequest) returns (google.protobuf.Empty);
rpc GetContainer(GetContainerRequest) returns (GetContainerResponse);
rpc ListContainers(ListContainersRequest) returns (ListContainersResponse);
rpc StartProcess(StartProcessRequest) returns (StartProcessResponse);
rpc GetProcess(GetProcessRequest) returns (GetProcessResponse);
rpc SignalProcess(SignalProcessRequest) returns (google.protobuf.Empty);
rpc DeleteProcess(DeleteProcessRequest) returns (google.protobuf.Empty);
rpc ListProcesses(ListProcessesRequest) returns (ListProcessesResponse);
service ContainerService {
rpc Create(CreateRequest) returns (CreateResponse);
rpc Start(StartRequest) returns (google.protobuf.Empty);
rpc Delete(DeleteRequest) returns (google.protobuf.Empty);
rpc List(ListRequest) returns (ListResponse);
rpc Events(EventsRequest) returns (stream containerd.v1.types.Event);
}
message StartContainerRequest {
message CreateRequest {
string id = 1 [(gogoproto.customname) = "ID"];
google.protobuf.Any spec = 2;
repeated containerd.v1.types.Mount rootfs = 3;
string runtime = 4;
string stdin = 5;
string stdout = 6;
string stderr = 7;
bool terminal = 8;
}
message CreateContainerRequest {
message CreateResponse {
string id = 1 [(gogoproto.customname) = "ID"];
string bundle_path = 2;
bool console = 3;
string stdin = 4;
string stdout = 5;
string stderr = 6;
}
message CreateContainerResponse {
types.Container container = 1;
types.Process initProcess = 2;
}
message DeleteContainerRequest {
string id = 1 [(gogoproto.customname) = "ID"];
}
message ListContainersRequest {
repeated string owner = 1;
}
message ListContainersResponse {
repeated types.Container containers = 1;
}
message StartProcessRequest {
string container_id = 1 [(gogoproto.customname) = "ContainerID"];
types.Process process = 2;
bool console = 3;
string stdin = 4;
string stdout = 5;
string stderr = 6;
}
message StartProcessResponse {
types.Process process = 1;
}
message GetContainerRequest {
string id = 1 [(gogoproto.customname) = "ID"];
}
message GetContainerResponse {
types.Container container = 1;
}
message UpdateContainerRequest {
string container_id = 1 [(gogoproto.customname) = "ContainerID"];
string bundle_path = 2;
}
message PauseContainerRequest {
string id = 1 [(gogoproto.customname) = "ID"];
}
message ResumeContainerRequest {
string id = 1 [(gogoproto.customname) = "ID"];
}
message GetProcessRequest {
string container_id = 1 [(gogoproto.customname) = "ContainerID"];
uint32 pid = 2;
}
message GetProcessResponse {
types.Process process = 1;
message StartRequest {
string id = 1 [(gogoproto.customname) = "ID"];
}
message SignalProcessRequest {
string container_id = 1 [(gogoproto.customname) = "ContainerID"];
uint32 pid = 2;
uint32 signal = 3;
message DeleteRequest {
string id = 1 [(gogoproto.customname) = "ID"];
}
message DeleteProcessRequest {
string container_id = 1 [(gogoproto.customname) = "ContainerID"];
uint32 pid = 2;
message DeleteResponse {
string id = 1 [(gogoproto.customname) = "ID"];
uint32 exit_status = 2;
}
message ListProcessesRequest {
string container_id = 1 [(gogoproto.customname) = "ContainerID"];
message ListRequest {
}
message ListProcessesResponse {
repeated types.Process processes = 1;
message ListResponse {
repeated containerd.v1.types.Container containers = 1;
}
message EventsRequest {
}

View file

@ -19,11 +19,11 @@
ExecResponse
PtyRequest
EventsRequest
Event
StateRequest
StateResponse
PauseRequest
ResumeRequest
ExitRequest
*/
package shim
@ -32,8 +32,8 @@ import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/ptypes/empty"
import _ "github.com/gogo/protobuf/gogoproto"
import containerd_v1_types2 "github.com/docker/containerd/api/types/process"
import containerd_v1_types "github.com/docker/containerd/api/types/user"
import containerd_v1_types "github.com/docker/containerd/api/types/mount"
import containerd_v1_types1 "github.com/docker/containerd/api/types/container"
import (
context "golang.org/x/net/context"
@ -56,45 +56,16 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
type EventType int32
const (
EventType_EXIT EventType = 0
EventType_OOM EventType = 1
EventType_CREATE EventType = 2
EventType_START EventType = 3
EventType_EXEC_ADDED EventType = 4
)
var EventType_name = map[int32]string{
0: "EXIT",
1: "OOM",
2: "CREATE",
3: "START",
4: "EXEC_ADDED",
}
var EventType_value = map[string]int32{
"EXIT": 0,
"OOM": 1,
"CREATE": 2,
"START": 3,
"EXEC_ADDED": 4,
}
func (x EventType) String() string {
return proto.EnumName(EventType_name, int32(x))
}
func (EventType) EnumDescriptor() ([]byte, []int) { return fileDescriptorShim, []int{0} }
type CreateRequest struct {
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Bundle string `protobuf:"bytes,2,opt,name=bundle,proto3" json:"bundle,omitempty"`
Runtime string `protobuf:"bytes,3,opt,name=runtime,proto3" json:"runtime,omitempty"`
NoPivot bool `protobuf:"varint,4,opt,name=no_pivot,json=noPivot,proto3" json:"no_pivot,omitempty"`
Terminal bool `protobuf:"varint,5,opt,name=terminal,proto3" json:"terminal,omitempty"`
Stdin string `protobuf:"bytes,6,opt,name=stdin,proto3" json:"stdin,omitempty"`
Stdout string `protobuf:"bytes,7,opt,name=stdout,proto3" json:"stdout,omitempty"`
Stderr string `protobuf:"bytes,8,opt,name=stderr,proto3" json:"stderr,omitempty"`
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Bundle string `protobuf:"bytes,2,opt,name=bundle,proto3" json:"bundle,omitempty"`
Runtime string `protobuf:"bytes,3,opt,name=runtime,proto3" json:"runtime,omitempty"`
NoPivot bool `protobuf:"varint,4,opt,name=no_pivot,json=noPivot,proto3" json:"no_pivot,omitempty"`
Terminal bool `protobuf:"varint,5,opt,name=terminal,proto3" json:"terminal,omitempty"`
Stdin string `protobuf:"bytes,6,opt,name=stdin,proto3" json:"stdin,omitempty"`
Stdout string `protobuf:"bytes,7,opt,name=stdout,proto3" json:"stdout,omitempty"`
Stderr string `protobuf:"bytes,8,opt,name=stderr,proto3" json:"stderr,omitempty"`
Rootfs []*containerd_v1_types.Mount `protobuf:"bytes,9,rep,name=rootfs" json:"rootfs,omitempty"`
}
func (m *CreateRequest) Reset() { *m = CreateRequest{} }
@ -133,19 +104,19 @@ func (*DeleteResponse) ProtoMessage() {}
func (*DeleteResponse) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{4} }
type ExecRequest struct {
Terminal bool `protobuf:"varint,1,opt,name=terminal,proto3" json:"terminal,omitempty"`
Stdin string `protobuf:"bytes,2,opt,name=stdin,proto3" json:"stdin,omitempty"`
Stdout string `protobuf:"bytes,3,opt,name=stdout,proto3" json:"stdout,omitempty"`
Stderr string `protobuf:"bytes,4,opt,name=stderr,proto3" json:"stderr,omitempty"`
SelinuxLabel string `protobuf:"bytes,5,opt,name=selinux_label,json=selinuxLabel,proto3" json:"selinux_label,omitempty"`
User *containerd_v1_types.User `protobuf:"bytes,6,opt,name=user" json:"user,omitempty"`
Args []string `protobuf:"bytes,7,rep,name=args" json:"args,omitempty"`
Env []string `protobuf:"bytes,8,rep,name=env" json:"env,omitempty"`
Cwd string `protobuf:"bytes,9,opt,name=cwd,proto3" json:"cwd,omitempty"`
Capabilities []string `protobuf:"bytes,10,rep,name=capabilities" json:"capabilities,omitempty"`
Rlimits []*Rlimit `protobuf:"bytes,11,rep,name=rlimits" json:"rlimits,omitempty"`
NoNewPrivileges bool `protobuf:"varint,12,opt,name=no_new_privileges,json=noNewPrivileges,proto3" json:"no_new_privileges,omitempty"`
ApparmorProfile string `protobuf:"bytes,13,opt,name=apparmor_profile,json=apparmorProfile,proto3" json:"apparmor_profile,omitempty"`
Terminal bool `protobuf:"varint,1,opt,name=terminal,proto3" json:"terminal,omitempty"`
Stdin string `protobuf:"bytes,2,opt,name=stdin,proto3" json:"stdin,omitempty"`
Stdout string `protobuf:"bytes,3,opt,name=stdout,proto3" json:"stdout,omitempty"`
Stderr string `protobuf:"bytes,4,opt,name=stderr,proto3" json:"stderr,omitempty"`
SelinuxLabel string `protobuf:"bytes,5,opt,name=selinux_label,json=selinuxLabel,proto3" json:"selinux_label,omitempty"`
User *containerd_v1_types1.User `protobuf:"bytes,6,opt,name=user" json:"user,omitempty"`
Args []string `protobuf:"bytes,7,rep,name=args" json:"args,omitempty"`
Env []string `protobuf:"bytes,8,rep,name=env" json:"env,omitempty"`
Cwd string `protobuf:"bytes,9,opt,name=cwd,proto3" json:"cwd,omitempty"`
Capabilities []string `protobuf:"bytes,10,rep,name=capabilities" json:"capabilities,omitempty"`
Rlimits []*Rlimit `protobuf:"bytes,11,rep,name=rlimits" json:"rlimits,omitempty"`
NoNewPrivileges bool `protobuf:"varint,12,opt,name=no_new_privileges,json=noNewPrivileges,proto3" json:"no_new_privileges,omitempty"`
ApparmorProfile string `protobuf:"bytes,13,opt,name=apparmor_profile,json=apparmorProfile,proto3" json:"apparmor_profile,omitempty"`
}
func (m *ExecRequest) Reset() { *m = ExecRequest{} }
@ -187,49 +158,44 @@ func (m *EventsRequest) Reset() { *m = EventsRequest{} }
func (*EventsRequest) ProtoMessage() {}
func (*EventsRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{9} }
// should be moved to api/types/event maybe
type Event struct {
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Type EventType `protobuf:"varint,2,opt,name=type,proto3,enum=containerd.v1.services.EventType" json:"type,omitempty"`
Pid uint32 `protobuf:"varint,3,opt,name=pid,proto3" json:"pid,omitempty"`
ExitStatus uint32 `protobuf:"varint,4,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"`
}
func (m *Event) Reset() { *m = Event{} }
func (*Event) ProtoMessage() {}
func (*Event) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{10} }
type StateRequest struct {
}
func (m *StateRequest) Reset() { *m = StateRequest{} }
func (*StateRequest) ProtoMessage() {}
func (*StateRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{11} }
func (*StateRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{10} }
type StateResponse struct {
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Bundle string `protobuf:"bytes,2,opt,name=bundle,proto3" json:"bundle,omitempty"`
InitPid uint32 `protobuf:"varint,3,opt,name=initPid,proto3" json:"initPid,omitempty"`
Processes []*containerd_v1_types2.Process `protobuf:"bytes,4,rep,name=processes" json:"processes,omitempty"`
Pid uint32 `protobuf:"varint,3,opt,name=pid,proto3" json:"pid,omitempty"`
Processes []*containerd_v1_types1.Process `protobuf:"bytes,4,rep,name=processes" json:"processes,omitempty"`
}
func (m *StateResponse) Reset() { *m = StateResponse{} }
func (*StateResponse) ProtoMessage() {}
func (*StateResponse) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{12} }
func (*StateResponse) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{11} }
type PauseRequest struct {
}
func (m *PauseRequest) Reset() { *m = PauseRequest{} }
func (*PauseRequest) ProtoMessage() {}
func (*PauseRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{13} }
func (*PauseRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{12} }
type ResumeRequest struct {
}
func (m *ResumeRequest) Reset() { *m = ResumeRequest{} }
func (*ResumeRequest) ProtoMessage() {}
func (*ResumeRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{14} }
func (*ResumeRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{13} }
type ExitRequest struct {
}
func (m *ExitRequest) Reset() { *m = ExitRequest{} }
func (*ExitRequest) ProtoMessage() {}
func (*ExitRequest) Descriptor() ([]byte, []int) { return fileDescriptorShim, []int{14} }
func init() {
proto.RegisterType((*CreateRequest)(nil), "containerd.v1.services.CreateRequest")
@ -242,12 +208,11 @@ func init() {
proto.RegisterType((*ExecResponse)(nil), "containerd.v1.services.ExecResponse")
proto.RegisterType((*PtyRequest)(nil), "containerd.v1.services.PtyRequest")
proto.RegisterType((*EventsRequest)(nil), "containerd.v1.services.EventsRequest")
proto.RegisterType((*Event)(nil), "containerd.v1.services.Event")
proto.RegisterType((*StateRequest)(nil), "containerd.v1.services.StateRequest")
proto.RegisterType((*StateResponse)(nil), "containerd.v1.services.StateResponse")
proto.RegisterType((*PauseRequest)(nil), "containerd.v1.services.PauseRequest")
proto.RegisterType((*ResumeRequest)(nil), "containerd.v1.services.ResumeRequest")
proto.RegisterEnum("containerd.v1.services.EventType", EventType_name, EventType_value)
proto.RegisterType((*ExitRequest)(nil), "containerd.v1.services.ExitRequest")
}
// Reference imports to suppress errors if they are not otherwise used.
@ -270,6 +235,7 @@ type ShimClient interface {
State(ctx context.Context, in *StateRequest, opts ...grpc.CallOption) (*StateResponse, error)
Pause(ctx context.Context, in *PauseRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error)
Resume(ctx context.Context, in *ResumeRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error)
Exit(ctx context.Context, in *ExitRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error)
}
type shimClient struct {
@ -341,7 +307,7 @@ func (c *shimClient) Events(ctx context.Context, in *EventsRequest, opts ...grpc
}
type Shim_EventsClient interface {
Recv() (*Event, error)
Recv() (*containerd_v1_types1.Event, error)
grpc.ClientStream
}
@ -349,8 +315,8 @@ type shimEventsClient struct {
grpc.ClientStream
}
func (x *shimEventsClient) Recv() (*Event, error) {
m := new(Event)
func (x *shimEventsClient) Recv() (*containerd_v1_types1.Event, error) {
m := new(containerd_v1_types1.Event)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
@ -384,6 +350,15 @@ func (c *shimClient) Resume(ctx context.Context, in *ResumeRequest, opts ...grpc
return out, nil
}
func (c *shimClient) Exit(ctx context.Context, in *ExitRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error) {
out := new(google_protobuf.Empty)
err := grpc.Invoke(ctx, "/containerd.v1.services.Shim/Exit", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Shim service
type ShimServer interface {
@ -396,6 +371,7 @@ type ShimServer interface {
State(context.Context, *StateRequest) (*StateResponse, error)
Pause(context.Context, *PauseRequest) (*google_protobuf.Empty, error)
Resume(context.Context, *ResumeRequest) (*google_protobuf.Empty, error)
Exit(context.Context, *ExitRequest) (*google_protobuf.Empty, error)
}
func RegisterShimServer(s *grpc.Server, srv ShimServer) {
@ -501,7 +477,7 @@ func _Shim_Events_Handler(srv interface{}, stream grpc.ServerStream) error {
}
type Shim_EventsServer interface {
Send(*Event) error
Send(*containerd_v1_types1.Event) error
grpc.ServerStream
}
@ -509,7 +485,7 @@ type shimEventsServer struct {
grpc.ServerStream
}
func (x *shimEventsServer) Send(m *Event) error {
func (x *shimEventsServer) Send(m *containerd_v1_types1.Event) error {
return x.ServerStream.SendMsg(m)
}
@ -567,6 +543,24 @@ func _Shim_Resume_Handler(srv interface{}, ctx context.Context, dec func(interfa
return interceptor(ctx, in, info, handler)
}
func _Shim_Exit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ExitRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ShimServer).Exit(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/containerd.v1.services.Shim/Exit",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ShimServer).Exit(ctx, req.(*ExitRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Shim_serviceDesc = grpc.ServiceDesc{
ServiceName: "containerd.v1.services.Shim",
HandlerType: (*ShimServer)(nil),
@ -603,6 +597,10 @@ var _Shim_serviceDesc = grpc.ServiceDesc{
MethodName: "Resume",
Handler: _Shim_Resume_Handler,
},
{
MethodName: "Exit",
Handler: _Shim_Exit_Handler,
},
},
Streams: []grpc.StreamDesc{
{
@ -685,6 +683,18 @@ func (m *CreateRequest) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintShim(dAtA, i, uint64(len(m.Stderr)))
i += copy(dAtA[i:], m.Stderr)
}
if len(m.Rootfs) > 0 {
for _, msg := range m.Rootfs {
dAtA[i] = 0x4a
i++
i = encodeVarintShim(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n
}
}
return i, nil
}
@ -1024,45 +1034,6 @@ func (m *EventsRequest) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *Event) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Event) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.ID) > 0 {
dAtA[i] = 0xa
i++
i = encodeVarintShim(dAtA, i, uint64(len(m.ID)))
i += copy(dAtA[i:], m.ID)
}
if m.Type != 0 {
dAtA[i] = 0x10
i++
i = encodeVarintShim(dAtA, i, uint64(m.Type))
}
if m.Pid != 0 {
dAtA[i] = 0x18
i++
i = encodeVarintShim(dAtA, i, uint64(m.Pid))
}
if m.ExitStatus != 0 {
dAtA[i] = 0x20
i++
i = encodeVarintShim(dAtA, i, uint64(m.ExitStatus))
}
return i, nil
}
func (m *StateRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -1108,10 +1079,10 @@ func (m *StateResponse) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintShim(dAtA, i, uint64(len(m.Bundle)))
i += copy(dAtA[i:], m.Bundle)
}
if m.InitPid != 0 {
if m.Pid != 0 {
dAtA[i] = 0x18
i++
i = encodeVarintShim(dAtA, i, uint64(m.InitPid))
i = encodeVarintShim(dAtA, i, uint64(m.Pid))
}
if len(m.Processes) > 0 {
for _, msg := range m.Processes {
@ -1164,6 +1135,24 @@ func (m *ResumeRequest) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *ExitRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *ExitRequest) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
return i, nil
}
func encodeFixed64Shim(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
@ -1224,6 +1213,12 @@ func (m *CreateRequest) Size() (n int) {
if l > 0 {
n += 1 + l + sovShim(uint64(l))
}
if len(m.Rootfs) > 0 {
for _, e := range m.Rootfs {
l = e.Size()
n += 1 + l + sovShim(uint64(l))
}
}
return n
}
@ -1370,25 +1365,6 @@ func (m *EventsRequest) Size() (n int) {
return n
}
func (m *Event) Size() (n int) {
var l int
_ = l
l = len(m.ID)
if l > 0 {
n += 1 + l + sovShim(uint64(l))
}
if m.Type != 0 {
n += 1 + sovShim(uint64(m.Type))
}
if m.Pid != 0 {
n += 1 + sovShim(uint64(m.Pid))
}
if m.ExitStatus != 0 {
n += 1 + sovShim(uint64(m.ExitStatus))
}
return n
}
func (m *StateRequest) Size() (n int) {
var l int
_ = l
@ -1406,8 +1382,8 @@ func (m *StateResponse) Size() (n int) {
if l > 0 {
n += 1 + l + sovShim(uint64(l))
}
if m.InitPid != 0 {
n += 1 + sovShim(uint64(m.InitPid))
if m.Pid != 0 {
n += 1 + sovShim(uint64(m.Pid))
}
if len(m.Processes) > 0 {
for _, e := range m.Processes {
@ -1430,6 +1406,12 @@ func (m *ResumeRequest) Size() (n int) {
return n
}
func (m *ExitRequest) Size() (n int) {
var l int
_ = l
return n
}
func sovShim(x uint64) (n int) {
for {
n++
@ -1456,6 +1438,7 @@ func (this *CreateRequest) String() string {
`Stdin:` + fmt.Sprintf("%v", this.Stdin) + `,`,
`Stdout:` + fmt.Sprintf("%v", this.Stdout) + `,`,
`Stderr:` + fmt.Sprintf("%v", this.Stderr) + `,`,
`Rootfs:` + strings.Replace(fmt.Sprintf("%v", this.Rootfs), "Mount", "containerd_v1_types.Mount", 1) + `,`,
`}`,
}, "")
return s
@ -1509,7 +1492,7 @@ func (this *ExecRequest) String() string {
`Stdout:` + fmt.Sprintf("%v", this.Stdout) + `,`,
`Stderr:` + fmt.Sprintf("%v", this.Stderr) + `,`,
`SelinuxLabel:` + fmt.Sprintf("%v", this.SelinuxLabel) + `,`,
`User:` + strings.Replace(fmt.Sprintf("%v", this.User), "User", "containerd_v1_types.User", 1) + `,`,
`User:` + strings.Replace(fmt.Sprintf("%v", this.User), "User", "containerd_v1_types1.User", 1) + `,`,
`Args:` + fmt.Sprintf("%v", this.Args) + `,`,
`Env:` + fmt.Sprintf("%v", this.Env) + `,`,
`Cwd:` + fmt.Sprintf("%v", this.Cwd) + `,`,
@ -1564,19 +1547,6 @@ func (this *EventsRequest) String() string {
}, "")
return s
}
func (this *Event) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&Event{`,
`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
`Type:` + fmt.Sprintf("%v", this.Type) + `,`,
`Pid:` + fmt.Sprintf("%v", this.Pid) + `,`,
`ExitStatus:` + fmt.Sprintf("%v", this.ExitStatus) + `,`,
`}`,
}, "")
return s
}
func (this *StateRequest) String() string {
if this == nil {
return "nil"
@ -1593,8 +1563,8 @@ func (this *StateResponse) String() string {
s := strings.Join([]string{`&StateResponse{`,
`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
`Bundle:` + fmt.Sprintf("%v", this.Bundle) + `,`,
`InitPid:` + fmt.Sprintf("%v", this.InitPid) + `,`,
`Processes:` + strings.Replace(fmt.Sprintf("%v", this.Processes), "Process", "containerd_v1_types2.Process", 1) + `,`,
`Pid:` + fmt.Sprintf("%v", this.Pid) + `,`,
`Processes:` + strings.Replace(fmt.Sprintf("%v", this.Processes), "Process", "containerd_v1_types1.Process", 1) + `,`,
`}`,
}, "")
return s
@ -1617,6 +1587,15 @@ func (this *ResumeRequest) String() string {
}, "")
return s
}
func (this *ExitRequest) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&ExitRequest{`,
`}`,
}, "")
return s
}
func valueToStringShim(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
@ -1868,6 +1847,37 @@ func (m *CreateRequest) Unmarshal(dAtA []byte) error {
}
m.Stderr = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 9:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Rootfs", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowShim
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthShim
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Rootfs = append(m.Rootfs, &containerd_v1_types.Mount{})
if err := m.Rootfs[len(m.Rootfs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipShim(dAtA[iNdEx:])
@ -2338,7 +2348,7 @@ func (m *ExecRequest) Unmarshal(dAtA []byte) error {
return io.ErrUnexpectedEOF
}
if m.User == nil {
m.User = &containerd_v1_types.User{}
m.User = &containerd_v1_types1.User{}
}
if err := m.User.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
@ -2904,142 +2914,6 @@ func (m *EventsRequest) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *Event) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowShim
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Event: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Event: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowShim
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthShim
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ID = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
}
m.Type = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowShim
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Type |= (EventType(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Pid", wireType)
}
m.Pid = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowShim
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Pid |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ExitStatus", wireType)
}
m.ExitStatus = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowShim
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.ExitStatus |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipShim(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthShim
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *StateRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@ -3179,9 +3053,9 @@ func (m *StateResponse) Unmarshal(dAtA []byte) error {
iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field InitPid", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field Pid", wireType)
}
m.InitPid = 0
m.Pid = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowShim
@ -3191,7 +3065,7 @@ func (m *StateResponse) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.InitPid |= (uint32(b) & 0x7F) << shift
m.Pid |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
@ -3222,7 +3096,7 @@ func (m *StateResponse) Unmarshal(dAtA []byte) error {
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Processes = append(m.Processes, &containerd_v1_types2.Process{})
m.Processes = append(m.Processes, &containerd_v1_types1.Process{})
if err := m.Processes[len(m.Processes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
@ -3348,6 +3222,56 @@ func (m *ResumeRequest) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *ExitRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowShim
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ExitRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ExitRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
default:
iNdEx = preIndex
skippy, err := skipShim(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthShim
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipShim(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
@ -3458,66 +3382,63 @@ func init() {
}
var fileDescriptorShim = []byte{
// 976 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x55, 0x4f, 0x6f, 0xe3, 0x44,
0x14, 0xaf, 0x13, 0xe7, 0xdf, 0x6b, 0xdd, 0x86, 0xd1, 0xaa, 0xf2, 0x06, 0xc8, 0x76, 0xbd, 0xbb,
0xa8, 0xac, 0x84, 0xc3, 0x16, 0x81, 0x00, 0x71, 0xe9, 0x36, 0x16, 0x5a, 0x69, 0x61, 0x83, 0x1b,
0xc4, 0xde, 0x22, 0x27, 0x7e, 0x4d, 0x46, 0x38, 0xb6, 0x99, 0x19, 0xa7, 0xed, 0x8d, 0x2b, 0x1f,
0x80, 0xef, 0xc1, 0xc7, 0xd8, 0x0b, 0x12, 0x27, 0xc4, 0x09, 0xb1, 0xf9, 0x24, 0x68, 0x66, 0xec,
0xa4, 0xd9, 0xad, 0x5b, 0xc4, 0x25, 0x79, 0xef, 0xe7, 0xdf, 0xbc, 0x79, 0xff, 0x07, 0xbe, 0x98,
0x52, 0x31, 0xcb, 0xc6, 0xee, 0x24, 0x99, 0xf7, 0xc2, 0x64, 0xf2, 0x23, 0xb2, 0xde, 0x24, 0x89,
0x45, 0x40, 0x63, 0x64, 0x61, 0x2f, 0x48, 0x69, 0x8f, 0x23, 0x5b, 0xd0, 0x09, 0xf2, 0x1e, 0x9f,
0xd1, 0xb9, 0xfa, 0x71, 0x53, 0x96, 0x88, 0x84, 0xec, 0xaf, 0x89, 0xee, 0xe2, 0x89, 0x5b, 0xf0,
0x3a, 0xef, 0x4e, 0x93, 0x64, 0x1a, 0x61, 0x4f, 0xb1, 0xc6, 0xd9, 0x59, 0x0f, 0xe7, 0xa9, 0xb8,
0xd4, 0x87, 0x3a, 0x77, 0xa6, 0xc9, 0x34, 0x51, 0x62, 0x4f, 0x4a, 0x39, 0xfa, 0xd5, 0xad, 0x5e,
0x88, 0xcb, 0x14, 0xb9, 0x34, 0x39, 0x41, 0xbe, 0xfa, 0xcf, 0x4f, 0x7f, 0xf6, 0x1f, 0x4f, 0x67,
0x1c, 0x99, 0xfa, 0xd1, 0xe7, 0x9c, 0x3f, 0x0d, 0xb0, 0x4e, 0x18, 0x06, 0x02, 0x7d, 0xfc, 0x29,
0x43, 0x2e, 0xc8, 0x3e, 0x54, 0x68, 0x68, 0x1b, 0x07, 0xc6, 0x61, 0xeb, 0x69, 0x7d, 0xf9, 0xf7,
0xbd, 0xca, 0xb3, 0xbe, 0x5f, 0xa1, 0x21, 0xd9, 0x87, 0xfa, 0x38, 0x8b, 0xc3, 0x08, 0xed, 0x8a,
0xfc, 0xe6, 0xe7, 0x1a, 0xb1, 0xa1, 0xc1, 0xb2, 0x58, 0xd0, 0x39, 0xda, 0x55, 0xf5, 0xa1, 0x50,
0xc9, 0x5d, 0x68, 0xc6, 0xc9, 0x28, 0xa5, 0x8b, 0x44, 0xd8, 0xe6, 0x81, 0x71, 0xd8, 0xf4, 0x1b,
0x71, 0x32, 0x90, 0x2a, 0xe9, 0x40, 0x53, 0x20, 0x9b, 0xd3, 0x38, 0x88, 0xec, 0x9a, 0xfa, 0xb4,
0xd2, 0xc9, 0x1d, 0xa8, 0x71, 0x11, 0xd2, 0xd8, 0xae, 0x2b, 0x73, 0x5a, 0x91, 0xd7, 0x73, 0x11,
0x26, 0x99, 0xb0, 0x1b, 0xfa, 0x7a, 0xad, 0xe5, 0x38, 0x32, 0x66, 0x37, 0x57, 0x38, 0x32, 0xe6,
0x38, 0xb0, 0x5b, 0xc4, 0xc5, 0xd3, 0x24, 0xe6, 0x48, 0xda, 0x50, 0x4d, 0xf3, 0xc8, 0x2c, 0x5f,
0x8a, 0xce, 0x2e, 0xec, 0x9c, 0x8a, 0x80, 0x89, 0x3c, 0x74, 0xe7, 0x3e, 0x58, 0x7d, 0x8c, 0x70,
0x9d, 0x8b, 0xb7, 0x8f, 0x3c, 0x81, 0xdd, 0x82, 0x92, 0x9b, 0xbd, 0x07, 0xdb, 0x78, 0x41, 0xc5,
0x88, 0x8b, 0x40, 0x64, 0x3c, 0xe7, 0x82, 0x84, 0x4e, 0x15, 0xe2, 0xfc, 0x56, 0x85, 0x6d, 0xef,
0x02, 0x27, 0x85, 0xd1, 0xab, 0xb1, 0x1b, 0x65, 0xb1, 0x57, 0xae, 0x8f, 0xbd, 0x5a, 0x12, 0xbb,
0x79, 0x35, 0x76, 0xf2, 0x00, 0x2c, 0x8e, 0x11, 0x8d, 0xb3, 0x8b, 0x51, 0x14, 0x8c, 0x51, 0xa7,
0xb8, 0xe5, 0xef, 0xe4, 0xe0, 0x73, 0x89, 0x91, 0x8f, 0xc0, 0x94, 0x7d, 0xa0, 0xb2, 0xbc, 0x7d,
0x74, 0xd7, 0xdd, 0xec, 0x64, 0xd5, 0x2d, 0xee, 0xf7, 0x1c, 0x99, 0xaf, 0x68, 0x84, 0x80, 0x19,
0xb0, 0x29, 0xb7, 0x1b, 0x07, 0xd5, 0xc3, 0x96, 0xaf, 0x64, 0x99, 0x1e, 0x8c, 0x17, 0x76, 0x53,
0x41, 0x52, 0x94, 0xc8, 0xe4, 0x3c, 0xb4, 0x5b, 0xea, 0x3e, 0x29, 0x12, 0x07, 0x76, 0x26, 0x41,
0x1a, 0x8c, 0x69, 0x44, 0x05, 0x45, 0x6e, 0x83, 0x22, 0x6f, 0x60, 0xe4, 0x73, 0x68, 0xb0, 0x88,
0xce, 0xa9, 0xe0, 0xf6, 0xf6, 0x41, 0xf5, 0x70, 0xfb, 0xa8, 0xeb, 0x5e, 0x3f, 0x57, 0xae, 0xaf,
0x68, 0x7e, 0x41, 0x27, 0x8f, 0xe1, 0x9d, 0x38, 0x19, 0xc5, 0x78, 0x3e, 0x4a, 0x19, 0x5d, 0xd0,
0x08, 0xa7, 0xc8, 0xed, 0x1d, 0x95, 0xd4, 0xbd, 0x38, 0xf9, 0x16, 0xcf, 0x07, 0x2b, 0x98, 0x7c,
0x08, 0xed, 0x20, 0x4d, 0x03, 0x36, 0x4f, 0xd8, 0x28, 0x65, 0xc9, 0x19, 0x8d, 0xd0, 0xb6, 0x94,
0xa3, 0x7b, 0x05, 0x3e, 0xd0, 0xb0, 0xd3, 0x87, 0xba, 0xbe, 0x49, 0x86, 0x2d, 0x53, 0xa1, 0xe7,
0xc1, 0x57, 0xb2, 0xc4, 0x66, 0x01, 0x0b, 0x55, 0x8d, 0x4c, 0x5f, 0xc9, 0x12, 0xe3, 0xc9, 0x99,
0x2e, 0x90, 0xe9, 0x2b, 0xd9, 0x39, 0x80, 0x1d, 0x5d, 0xf7, 0xd2, 0x06, 0x7c, 0x0e, 0x30, 0x10,
0x97, 0xa5, 0xdd, 0x26, 0xdb, 0xe1, 0x9c, 0x86, 0x62, 0xa6, 0xae, 0xb2, 0x7c, 0xad, 0xc8, 0xb2,
0xcf, 0x90, 0x4e, 0x67, 0xfa, 0x36, 0xcb, 0xcf, 0x35, 0x67, 0x0f, 0x2c, 0x6f, 0x81, 0xb1, 0xe0,
0x45, 0x3f, 0xff, 0x62, 0x40, 0x4d, 0x21, 0xa5, 0x43, 0xfd, 0x69, 0x1e, 0x9e, 0xb4, 0xbf, 0x7b,
0x74, 0xbf, 0x2c, 0xed, 0xca, 0xc8, 0xf0, 0x32, 0xc5, 0x3c, 0x03, 0xb9, 0xa7, 0xd5, 0xb5, 0xa7,
0x6f, 0x4c, 0x81, 0xf9, 0xd6, 0x14, 0xe8, 0x59, 0x5b, 0x8d, 0x96, 0xf3, 0xab, 0x01, 0x56, 0x0e,
0xe4, 0xe9, 0xf9, 0x1f, 0x8b, 0x87, 0xc6, 0x54, 0x0c, 0x56, 0x8e, 0x14, 0x2a, 0xf9, 0x12, 0x5a,
0xf9, 0x76, 0x44, 0xe9, 0x8a, 0xec, 0xa8, 0xf7, 0xae, 0xed, 0xef, 0x81, 0x66, 0xf9, 0x6b, 0xba,
0xf4, 0x73, 0x10, 0x64, 0x7c, 0xe5, 0xe7, 0x1e, 0x58, 0x3e, 0xf2, 0x6c, 0x5e, 0x00, 0x8f, 0x3d,
0x68, 0xad, 0xd2, 0x41, 0x9a, 0x60, 0x7a, 0x2f, 0x9f, 0x0d, 0xdb, 0x5b, 0xa4, 0x01, 0xd5, 0x17,
0x2f, 0xbe, 0x69, 0x1b, 0x04, 0xa0, 0x7e, 0xe2, 0x7b, 0xc7, 0x43, 0xaf, 0x5d, 0x21, 0x2d, 0xa8,
0x9d, 0x0e, 0x8f, 0xfd, 0x61, 0xbb, 0x4a, 0x76, 0x01, 0xbc, 0x97, 0xde, 0xc9, 0xe8, 0xb8, 0xdf,
0xf7, 0xfa, 0x6d, 0xf3, 0xe8, 0xf7, 0x1a, 0x98, 0xa7, 0x33, 0x3a, 0x27, 0x3f, 0x40, 0x5d, 0x2f,
0x2a, 0xf2, 0xa8, 0x2c, 0xfd, 0x1b, 0x0b, 0xba, 0xf3, 0xc1, 0x6d, 0xb4, 0x3c, 0x9f, 0x1e, 0xd4,
0xd4, 0x76, 0x23, 0x0f, 0xcb, 0x0e, 0x5c, 0x5d, 0x7e, 0x9d, 0x7d, 0x57, 0xbf, 0x59, 0x6e, 0xf1,
0x66, 0xb9, 0x9e, 0x7c, 0xb3, 0xa4, 0x7f, 0x7a, 0xe3, 0x95, 0xfb, 0xb7, 0xb1, 0x34, 0xcb, 0xfd,
0x7b, 0x63, 0x71, 0x7e, 0x07, 0xa6, 0x1c, 0x0f, 0xf2, 0xa0, 0xb4, 0xeb, 0xd6, 0x4b, 0xb3, 0xf3,
0xf0, 0x66, 0x52, 0x6e, 0xf2, 0x18, 0xaa, 0x03, 0x71, 0x49, 0x9c, 0x32, 0xf2, 0x7a, 0xd8, 0x4a,
0xc3, 0x1d, 0x40, 0x5d, 0x0f, 0x51, 0x79, 0xb8, 0x1b, 0x43, 0xd6, 0x79, 0xff, 0x46, 0xda, 0xc7,
0x06, 0x19, 0xaa, 0x3a, 0x08, 0xbc, 0xb1, 0x0e, 0xeb, 0xf4, 0x3d, 0xba, 0x85, 0xb5, 0xae, 0xae,
0xea, 0xd3, 0x72, 0xab, 0x57, 0xdb, 0xb8, 0x34, 0xdc, 0xaf, 0xa1, 0xae, 0xdb, 0xbb, 0x3c, 0xdc,
0x8d, 0xf6, 0x2f, 0x33, 0xf4, 0xd4, 0x7e, 0xf5, 0xba, 0xbb, 0xf5, 0xd7, 0xeb, 0xee, 0xd6, 0xcf,
0xcb, 0xae, 0xf1, 0x6a, 0xd9, 0x35, 0xfe, 0x58, 0x76, 0x8d, 0x7f, 0x96, 0x5d, 0x63, 0x5c, 0x57,
0xcc, 0x4f, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x7d, 0x28, 0xed, 0x88, 0x67, 0x09, 0x00, 0x00,
// 918 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x55, 0xc1, 0x6f, 0xe3, 0xc4,
0x17, 0x5e, 0x27, 0xa9, 0x9b, 0xbc, 0xc4, 0xed, 0xfe, 0x46, 0xab, 0x6a, 0x36, 0x3f, 0x94, 0x0d,
0xde, 0x5d, 0x54, 0x90, 0x70, 0xd8, 0x72, 0x59, 0x38, 0xc1, 0x6e, 0x2b, 0x84, 0xb4, 0x8b, 0x82,
0x0b, 0xe2, 0x18, 0x39, 0xf1, 0x6b, 0x32, 0xc2, 0xf6, 0x98, 0x99, 0x71, 0xda, 0xde, 0x38, 0x23,
0x21, 0xfe, 0x15, 0xfe, 0x8c, 0x3d, 0x72, 0xe4, 0x84, 0xd8, 0xfc, 0x25, 0x68, 0x66, 0xec, 0xa4,
0x81, 0xb8, 0x85, 0x4b, 0xf4, 0xde, 0x97, 0x6f, 0x66, 0xde, 0x7c, 0xef, 0x9b, 0x67, 0xf8, 0x64,
0xce, 0xd4, 0xa2, 0x98, 0x06, 0x33, 0x9e, 0x8e, 0x62, 0x3e, 0xfb, 0x1e, 0xc5, 0x68, 0xc6, 0x33,
0x15, 0xb1, 0x0c, 0x45, 0x3c, 0x8a, 0x72, 0x36, 0x92, 0x28, 0x96, 0x6c, 0x86, 0x72, 0x24, 0x17,
0x2c, 0x35, 0x3f, 0x41, 0x2e, 0xb8, 0xe2, 0xe4, 0x68, 0x43, 0x0c, 0x96, 0xcf, 0x82, 0x8a, 0xd7,
0xff, 0xff, 0x9c, 0xf3, 0x79, 0x82, 0x23, 0xc3, 0x9a, 0x16, 0x17, 0x23, 0x4c, 0x73, 0x75, 0x6d,
0x17, 0xf5, 0x1f, 0xcc, 0xf9, 0x9c, 0x9b, 0x70, 0xa4, 0xa3, 0x12, 0x7d, 0x7e, 0x67, 0x15, 0xea,
0x3a, 0x47, 0x39, 0x4a, 0x79, 0x91, 0x29, 0xfb, 0x5b, 0xae, 0xfc, 0xec, 0x5f, 0xae, 0x5c, 0x83,
0x9b, 0xc8, 0xee, 0xe0, 0xff, 0xd4, 0x00, 0xef, 0xa5, 0xc0, 0x48, 0x61, 0x88, 0x3f, 0x14, 0x28,
0x15, 0x39, 0x82, 0x06, 0x8b, 0xa9, 0x33, 0x74, 0x8e, 0x3b, 0x2f, 0xdc, 0xd5, 0x1f, 0x8f, 0x1a,
0x5f, 0x9e, 0x86, 0x0d, 0x16, 0x93, 0x23, 0x70, 0xa7, 0x45, 0x16, 0x27, 0x48, 0x1b, 0xfa, 0xbf,
0xb0, 0xcc, 0x08, 0x85, 0x7d, 0x51, 0x64, 0x8a, 0xa5, 0x48, 0x9b, 0xe6, 0x8f, 0x2a, 0x25, 0x0f,
0xa1, 0x9d, 0xf1, 0x49, 0xce, 0x96, 0x5c, 0xd1, 0xd6, 0xd0, 0x39, 0x6e, 0x87, 0xfb, 0x19, 0x1f,
0xeb, 0x94, 0xf4, 0xa1, 0xad, 0x50, 0xa4, 0x2c, 0x8b, 0x12, 0xba, 0x67, 0xfe, 0x5a, 0xe7, 0xe4,
0x01, 0xec, 0x49, 0x15, 0xb3, 0x8c, 0xba, 0x66, 0x3b, 0x9b, 0xe8, 0xe3, 0xa5, 0x8a, 0x79, 0xa1,
0xe8, 0xbe, 0x3d, 0xde, 0x66, 0x25, 0x8e, 0x42, 0xd0, 0xf6, 0x1a, 0x47, 0x21, 0xc8, 0x09, 0xb8,
0x82, 0x73, 0x75, 0x21, 0x69, 0x67, 0xd8, 0x3c, 0xee, 0x9e, 0xf4, 0x83, 0xed, 0x86, 0x19, 0x61,
0x82, 0xd7, 0x5a, 0xcc, 0xb0, 0x64, 0xfa, 0x3e, 0x1c, 0x54, 0x5a, 0xc8, 0x9c, 0x67, 0x12, 0xc9,
0x7d, 0x68, 0xe6, 0xa5, 0x1a, 0x5e, 0xa8, 0x43, 0xff, 0x00, 0x7a, 0xe7, 0x2a, 0x12, 0xaa, 0x94,
0xcb, 0x7f, 0x17, 0xbc, 0x53, 0x4c, 0x70, 0xa3, 0xdf, 0x3f, 0x97, 0x3c, 0x83, 0x83, 0x8a, 0x52,
0x6e, 0xfb, 0x08, 0xba, 0x78, 0xc5, 0xd4, 0x44, 0xaa, 0x48, 0x15, 0xb2, 0xe4, 0x82, 0x86, 0xce,
0x0d, 0xe2, 0xff, 0xda, 0x84, 0xee, 0xd9, 0x15, 0xce, 0xaa, 0x4d, 0x6f, 0xea, 0xe5, 0xd4, 0xe9,
0xd5, 0xd8, 0xad, 0x57, 0xb3, 0x46, 0xaf, 0xd6, 0x96, 0x5e, 0x8f, 0xc1, 0x93, 0x98, 0xb0, 0xac,
0xb8, 0x9a, 0x24, 0xd1, 0x14, 0x6d, 0x5b, 0x3a, 0x61, 0xaf, 0x04, 0x5f, 0x69, 0x8c, 0x7c, 0x08,
0xad, 0x42, 0xa2, 0x30, 0x9d, 0xe9, 0x9e, 0x3c, 0xdc, 0x29, 0xe9, 0xb7, 0x12, 0x45, 0x68, 0x68,
0x84, 0x40, 0x2b, 0x12, 0x73, 0x49, 0xf7, 0x87, 0xcd, 0xe3, 0x4e, 0x68, 0x62, 0x2d, 0x0f, 0x66,
0x4b, 0xda, 0x36, 0x90, 0x0e, 0x35, 0x32, 0xbb, 0x8c, 0x69, 0xc7, 0x9c, 0xa7, 0x43, 0xe2, 0x43,
0x6f, 0x16, 0xe5, 0xd1, 0x94, 0x25, 0x4c, 0x31, 0x94, 0x14, 0x0c, 0x79, 0x0b, 0x23, 0xcf, 0x61,
0x5f, 0x24, 0x2c, 0x65, 0x4a, 0xd2, 0xae, 0x69, 0xf0, 0x20, 0xd8, 0xfd, 0x22, 0x83, 0xd0, 0xd0,
0xc2, 0x8a, 0x4e, 0x3e, 0x80, 0xff, 0x65, 0x7c, 0x92, 0xe1, 0xe5, 0x24, 0x17, 0x6c, 0xc9, 0x12,
0x9c, 0xa3, 0xa4, 0x3d, 0x23, 0xea, 0x61, 0xc6, 0xbf, 0xc2, 0xcb, 0xf1, 0x1a, 0x26, 0xef, 0xc3,
0xfd, 0x28, 0xcf, 0x23, 0x91, 0x72, 0x31, 0xc9, 0x05, 0xbf, 0x60, 0x09, 0x52, 0xcf, 0x14, 0x7a,
0x58, 0xe1, 0x63, 0x0b, 0xfb, 0xa7, 0xe0, 0xda, 0x93, 0xf4, 0xb5, 0xb5, 0x14, 0xf6, 0x0d, 0x85,
0x26, 0xd6, 0xd8, 0x22, 0x12, 0xb1, 0xe9, 0x51, 0x2b, 0x34, 0xb1, 0xc6, 0x24, 0xbf, 0xb0, 0x0d,
0x6a, 0x85, 0x26, 0xf6, 0x87, 0xd0, 0xb3, 0x7d, 0xaf, 0x35, 0xe0, 0x2b, 0x80, 0xb1, 0xba, 0xae,
0x75, 0x9b, 0xb6, 0xc3, 0x25, 0x8b, 0xd5, 0xc2, 0x1c, 0xe5, 0x85, 0x36, 0xd1, 0x6d, 0x5f, 0x20,
0x9b, 0x2f, 0xec, 0x69, 0x5e, 0x58, 0x66, 0xfe, 0x21, 0x78, 0x67, 0x4b, 0xcc, 0x94, 0xac, 0xfc,
0x6c, 0xfd, 0xbd, 0xb6, 0xb3, 0xff, 0xb3, 0x03, 0x5e, 0x09, 0x94, 0x25, 0xfd, 0xd7, 0x01, 0x51,
0x96, 0xd8, 0xdc, 0x94, 0xf8, 0x29, 0x74, 0x72, 0xc1, 0x67, 0x28, 0x25, 0x4a, 0xda, 0x32, 0xdd,
0x7b, 0x67, 0xa7, 0x97, 0xc6, 0x96, 0x15, 0x6e, 0xe8, 0xba, 0xbe, 0x71, 0x54, 0xc8, 0x75, 0x7d,
0x87, 0xe0, 0x85, 0x28, 0x8b, 0x74, 0x0d, 0x78, 0xfa, 0xe5, 0xb0, 0xea, 0x7d, 0x9e, 0xfc, 0xe2,
0x42, 0xeb, 0x7c, 0xc1, 0x52, 0xf2, 0x1d, 0xb8, 0xf6, 0x71, 0x93, 0xa7, 0x75, 0x4e, 0xd9, 0x1a,
0x84, 0xfd, 0xf7, 0xee, 0xa2, 0x95, 0x7a, 0x9c, 0xc1, 0x9e, 0x99, 0x08, 0xe4, 0x49, 0xdd, 0x82,
0x9b, 0x03, 0xa3, 0x7f, 0x14, 0xd8, 0x2f, 0x44, 0x50, 0x7d, 0x21, 0x82, 0x33, 0xfd, 0x85, 0xd0,
0xf5, 0xd9, 0x29, 0x51, 0x5f, 0xdf, 0xd6, 0xa0, 0xa9, 0xaf, 0xef, 0x6f, 0xc3, 0xe6, 0x6b, 0x68,
0x69, 0x4b, 0x91, 0xc7, 0x75, 0xfc, 0x1b, 0x83, 0xa6, 0xff, 0xe4, 0x76, 0x52, 0xb9, 0xe5, 0xe7,
0xd0, 0x1c, 0xab, 0x6b, 0xe2, 0xd7, 0x91, 0x37, 0x06, 0xad, 0xbd, 0xee, 0x6b, 0x70, 0xad, 0xf1,
0xea, 0xaf, 0xbb, 0x65, 0xcc, 0xfe, 0xee, 0x01, 0x6e, 0x38, 0x1f, 0x39, 0xe4, 0x1b, 0xd3, 0x04,
0x85, 0xb7, 0x36, 0x61, 0xa3, 0xdd, 0xd3, 0x3b, 0x58, 0x9b, 0xd6, 0x1a, 0xb3, 0xd5, 0xef, 0x7a,
0xd3, 0x8b, 0xb5, 0x77, 0xfd, 0x02, 0x5c, 0xeb, 0xd1, 0xfa, 0xbb, 0x6e, 0x79, 0xb8, 0x76, 0xa3,
0x97, 0xba, 0x95, 0x4c, 0xdd, 0xd6, 0x4a, 0x76, 0x97, 0xd1, 0x5e, 0xd0, 0x37, 0x6f, 0x07, 0xf7,
0x7e, 0x7f, 0x3b, 0xb8, 0xf7, 0xe3, 0x6a, 0xe0, 0xbc, 0x59, 0x0d, 0x9c, 0xdf, 0x56, 0x03, 0xe7,
0xcf, 0xd5, 0xc0, 0x99, 0xba, 0x86, 0xf9, 0xf1, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb2, 0x82,
0x40, 0x80, 0x17, 0x09, 0x00, 0x00,
}

View file

@ -4,8 +4,8 @@ package containerd.v1.services;
import "google/protobuf/empty.proto";
import "gogoproto/gogo.proto";
import "github.com/docker/containerd/api/types/process/process.proto";
import "github.com/docker/containerd/api/types/user/user.proto";
import "github.com/docker/containerd/api/types/mount/mount.proto";
import "github.com/docker/containerd/api/types/container/container.proto";
service Shim {
rpc Create(CreateRequest) returns (CreateResponse);
@ -13,10 +13,11 @@ service Shim {
rpc Delete(DeleteRequest) returns (DeleteResponse);
rpc Exec(ExecRequest) returns (ExecResponse);
rpc Pty(PtyRequest) returns (google.protobuf.Empty);
rpc Events(EventsRequest) returns (stream Event);
rpc Events(EventsRequest) returns (stream containerd.v1.types.Event);
rpc State(StateRequest) returns (StateResponse);
rpc Pause(PauseRequest) returns (google.protobuf.Empty);
rpc Resume(ResumeRequest) returns (google.protobuf.Empty);
rpc Exit(ExitRequest) returns (google.protobuf.Empty);
}
message CreateRequest {
@ -28,6 +29,7 @@ message CreateRequest {
string stdin = 6;
string stdout = 7;
string stderr = 8;
repeated containerd.v1.types.Mount rootfs = 9;
}
message CreateResponse {
@ -51,7 +53,7 @@ message ExecRequest {
string stdout = 3;
string stderr = 4;
string selinux_label = 5;
types.User user = 6;
containerd.v1.types.User user = 6;
repeated string args = 7;
repeated string env = 8;
string cwd = 9;
@ -80,34 +82,22 @@ message PtyRequest {
message EventsRequest {
}
enum EventType {
EXIT = 0;
OOM = 1;
CREATE = 2;
START = 3;
EXEC_ADDED = 4;
}
// should be moved to api/types/event maybe
message Event {
string id = 1 [(gogoproto.customname) = "ID"];
EventType type = 2;
uint32 pid = 3;
uint32 exit_status = 4;
}
message StateRequest {
}
message StateResponse {
string id = 1 [(gogoproto.customname) = "ID"];
string bundle = 2;
uint32 initPid = 3;
repeated types.Process processes = 4;
uint32 pid = 3;
repeated containerd.v1.types.Process processes = 4;
}
message PauseRequest {
}
message ResumeRequest {
}
message ExitRequest {
}

File diff suppressed because it is too large Load diff

View file

@ -3,10 +3,50 @@ syntax = "proto3";
package containerd.v1.types;
import "gogoproto/gogo.proto";
import "github.com/docker/containerd/api/types/state/state.proto";
enum Status {
CREATED = 0;
RUNNING = 1;
STOPPED = 2;
PAUSED = 3;
}
message Container {
string id = 1 [(gogoproto.customname) = "ID"];
string bundle = 2;
State state = 4;
uint32 pid = 2;
Status status = 3;
}
message Process {
uint32 pid = 1;
repeated string args = 2;
repeated string env = 3;
User user = 4;
string cwd = 5;
bool terminal = 6;
uint32 exit_status = 7;
Status status = 8;
}
message User {
uint32 uid = 1;
uint32 gid = 2;
repeated uint32 additional_gids = 3;
}
message Event {
string id = 1 [(gogoproto.customname) = "ID"];
enum EventType {
EXIT = 0;
OOM = 1;
CREATE = 2;
START = 3;
EXEC_ADDED = 4;
PAUSED = 5;
}
EventType type = 2;
uint32 pid = 3;
uint32 exit_status = 4;
}

View file

@ -472,19 +472,18 @@ func init() {
}
var fileDescriptorMount = []byte{
// 212 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x4c, 0x8e, 0xb1, 0x4a, 0x43, 0x31,
0x14, 0x86, 0x1b, 0x5b, 0x2b, 0xcd, 0x18, 0x41, 0x82, 0x43, 0x28, 0x4e, 0x5d, 0x4c, 0x10, 0x17,
0x67, 0x77, 0x97, 0xbe, 0xc1, 0xbd, 0x69, 0x8c, 0x41, 0x9a, 0x13, 0x72, 0x4f, 0x04, 0x37, 0x1f,
0xef, 0x8e, 0x8e, 0x8e, 0xde, 0x3c, 0x89, 0xdc, 0x13, 0xc5, 0x2e, 0x87, 0xff, 0xfb, 0xf9, 0xf9,
0x38, 0xfc, 0xc1, 0x07, 0x7c, 0x29, 0xbd, 0xb6, 0x70, 0x34, 0x07, 0xb0, 0xaf, 0x2e, 0x1b, 0x0b,
0x11, 0xbb, 0x10, 0x5d, 0x3e, 0x98, 0x2e, 0x05, 0x83, 0xef, 0xc9, 0x0d, 0xe6, 0x08, 0x25, 0x62,
0xbb, 0x3a, 0x65, 0x40, 0x10, 0x97, 0xff, 0x3b, 0xfd, 0x76, 0xa7, 0x69, 0x76, 0x7d, 0x7b, 0xa2,
0xf3, 0xe0, 0xc1, 0xd0, 0xb6, 0x2f, 0xcf, 0x44, 0x04, 0x94, 0x9a, 0xe3, 0xc6, 0xf1, 0xf3, 0xa7,
0x59, 0x29, 0x04, 0x5f, 0xcd, 0x02, 0xc9, 0xb6, 0x6c, 0xb7, 0xd9, 0x53, 0x16, 0x57, 0x7c, 0x3d,
0x40, 0xc9, 0xd6, 0xc9, 0x33, 0x6a, 0x7f, 0x69, 0xee, 0xb1, 0xcb, 0xde, 0xa1, 0x5c, 0xb6, 0xbe,
0x91, 0x90, 0xfc, 0x02, 0x12, 0x06, 0x88, 0x83, 0x5c, 0x6d, 0x97, 0xbb, 0xcd, 0xfe, 0x0f, 0x1f,
0xe5, 0x38, 0xa9, 0xc5, 0xd7, 0xa4, 0x16, 0x1f, 0x55, 0xb1, 0xb1, 0x2a, 0xf6, 0x59, 0x15, 0xfb,
0xae, 0x8a, 0xf5, 0x6b, 0xfa, 0xe3, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xcf, 0x31, 0x1e,
0x07, 0x01, 0x00, 0x00,
// 204 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xb2, 0x48, 0xcf, 0x2c, 0xc9,
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xc9, 0x4f, 0xce, 0x4e, 0x2d, 0xd2, 0x4f, 0xce,
0xcf, 0x2b, 0x49, 0xcc, 0xcc, 0x4b, 0x2d, 0x4a, 0xd1, 0x4f, 0x2c, 0xc8, 0xd4, 0x2f, 0xa9, 0x2c,
0x48, 0x2d, 0xd6, 0xcf, 0xcd, 0x2f, 0xcd, 0x2b, 0x81, 0x90, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9,
0x42, 0xc2, 0x08, 0x75, 0x7a, 0x65, 0x86, 0x7a, 0x60, 0x65, 0x52, 0x22, 0xe9, 0xf9, 0xe9, 0xf9,
0x60, 0x79, 0x7d, 0x10, 0x0b, 0xa2, 0x54, 0x29, 0x95, 0x8b, 0xd5, 0x17, 0xa4, 0x53, 0x48, 0x88,
0x8b, 0x05, 0xa4, 0x4e, 0x82, 0x51, 0x81, 0x51, 0x83, 0x33, 0x08, 0xcc, 0x16, 0x12, 0xe3, 0x62,
0x2b, 0xce, 0x2f, 0x2d, 0x4a, 0x4e, 0x95, 0x60, 0x02, 0x8b, 0x42, 0x79, 0x20, 0xf1, 0x92, 0xc4,
0xa2, 0xf4, 0xd4, 0x12, 0x09, 0x66, 0x88, 0x38, 0x84, 0x27, 0x24, 0xc1, 0xc5, 0x9e, 0x5f, 0x50,
0x92, 0x99, 0x9f, 0x57, 0x2c, 0xc1, 0xa2, 0xc0, 0xac, 0xc1, 0x19, 0x04, 0xe3, 0x3a, 0x49, 0x9c,
0x78, 0x28, 0xc7, 0x70, 0xe3, 0xa1, 0x1c, 0x43, 0xc3, 0x23, 0x39, 0xc6, 0x13, 0x8f, 0xe4, 0x18,
0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x31, 0x89, 0x0d, 0xec, 0x0e, 0x63, 0x40, 0x00,
0x00, 0x00, 0xff, 0xff, 0xf3, 0x5c, 0x4b, 0x3a, 0xee, 0x00, 0x00, 0x00,
}

View file

@ -2,7 +2,7 @@ syntax = "proto3";
package containerd.v1.types;
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
import "gogoproto/gogo.proto";
// Mount describes mounts for a container.
//

View file

@ -1,625 +0,0 @@
// Code generated by protoc-gen-gogo.
// source: github.com/docker/containerd/api/types/process/process.proto
// DO NOT EDIT!
/*
Package process is a generated protocol buffer package.
It is generated from these files:
github.com/docker/containerd/api/types/process/process.proto
It has these top-level messages:
Process
*/
package process
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import containerd_v1_types "github.com/docker/containerd/api/types/user"
import containerd_v1_types1 "github.com/docker/containerd/api/types/state"
import strings "strings"
import reflect "reflect"
import io "io"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
type Process struct {
Pid uint32 `protobuf:"varint,1,opt,name=pid,proto3" json:"pid,omitempty"`
Args []string `protobuf:"bytes,2,rep,name=args" json:"args,omitempty"`
Env []string `protobuf:"bytes,3,rep,name=env" json:"env,omitempty"`
User *containerd_v1_types.User `protobuf:"bytes,4,opt,name=user" json:"user,omitempty"`
Cwd string `protobuf:"bytes,5,opt,name=cwd,proto3" json:"cwd,omitempty"`
Terminal bool `protobuf:"varint,6,opt,name=terminal,proto3" json:"terminal,omitempty"`
State containerd_v1_types1.State `protobuf:"varint,7,opt,name=state,proto3,enum=containerd.v1.types.State" json:"state,omitempty"`
ExitStatus uint32 `protobuf:"varint,8,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"`
}
func (m *Process) Reset() { *m = Process{} }
func (*Process) ProtoMessage() {}
func (*Process) Descriptor() ([]byte, []int) { return fileDescriptorProcess, []int{0} }
func init() {
proto.RegisterType((*Process)(nil), "containerd.v1.types.Process")
}
func (m *Process) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Process) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.Pid != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintProcess(dAtA, i, uint64(m.Pid))
}
if len(m.Args) > 0 {
for _, s := range m.Args {
dAtA[i] = 0x12
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
}
}
if len(m.Env) > 0 {
for _, s := range m.Env {
dAtA[i] = 0x1a
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
}
}
if m.User != nil {
dAtA[i] = 0x22
i++
i = encodeVarintProcess(dAtA, i, uint64(m.User.Size()))
n1, err := m.User.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n1
}
if len(m.Cwd) > 0 {
dAtA[i] = 0x2a
i++
i = encodeVarintProcess(dAtA, i, uint64(len(m.Cwd)))
i += copy(dAtA[i:], m.Cwd)
}
if m.Terminal {
dAtA[i] = 0x30
i++
if m.Terminal {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i++
}
if m.State != 0 {
dAtA[i] = 0x38
i++
i = encodeVarintProcess(dAtA, i, uint64(m.State))
}
if m.ExitStatus != 0 {
dAtA[i] = 0x40
i++
i = encodeVarintProcess(dAtA, i, uint64(m.ExitStatus))
}
return i, nil
}
func encodeFixed64Process(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Process(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintProcess(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
}
func (m *Process) Size() (n int) {
var l int
_ = l
if m.Pid != 0 {
n += 1 + sovProcess(uint64(m.Pid))
}
if len(m.Args) > 0 {
for _, s := range m.Args {
l = len(s)
n += 1 + l + sovProcess(uint64(l))
}
}
if len(m.Env) > 0 {
for _, s := range m.Env {
l = len(s)
n += 1 + l + sovProcess(uint64(l))
}
}
if m.User != nil {
l = m.User.Size()
n += 1 + l + sovProcess(uint64(l))
}
l = len(m.Cwd)
if l > 0 {
n += 1 + l + sovProcess(uint64(l))
}
if m.Terminal {
n += 2
}
if m.State != 0 {
n += 1 + sovProcess(uint64(m.State))
}
if m.ExitStatus != 0 {
n += 1 + sovProcess(uint64(m.ExitStatus))
}
return n
}
func sovProcess(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozProcess(x uint64) (n int) {
return sovProcess(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (this *Process) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&Process{`,
`Pid:` + fmt.Sprintf("%v", this.Pid) + `,`,
`Args:` + fmt.Sprintf("%v", this.Args) + `,`,
`Env:` + fmt.Sprintf("%v", this.Env) + `,`,
`User:` + strings.Replace(fmt.Sprintf("%v", this.User), "User", "containerd_v1_types.User", 1) + `,`,
`Cwd:` + fmt.Sprintf("%v", this.Cwd) + `,`,
`Terminal:` + fmt.Sprintf("%v", this.Terminal) + `,`,
`State:` + fmt.Sprintf("%v", this.State) + `,`,
`ExitStatus:` + fmt.Sprintf("%v", this.ExitStatus) + `,`,
`}`,
}, "")
return s
}
func valueToStringProcess(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("*%v", pv)
}
func (m *Process) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProcess
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Process: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Process: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Pid", wireType)
}
m.Pid = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProcess
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Pid |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Args", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProcess
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthProcess
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Args = append(m.Args, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Env", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProcess
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthProcess
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Env = append(m.Env, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field User", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProcess
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthProcess
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.User == nil {
m.User = &containerd_v1_types.User{}
}
if err := m.User.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Cwd", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProcess
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthProcess
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Cwd = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 6:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Terminal", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProcess
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.Terminal = bool(v != 0)
case 7:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field State", wireType)
}
m.State = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProcess
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.State |= (containerd_v1_types1.State(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 8:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ExitStatus", wireType)
}
m.ExitStatus = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowProcess
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.ExitStatus |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipProcess(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthProcess
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipProcess(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowProcess
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowProcess
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
return iNdEx, nil
case 1:
iNdEx += 8
return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowProcess
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthProcess
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowProcess
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
innerWire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
innerWireType := int(innerWire & 0x7)
if innerWireType == 4 {
break
}
next, err := skipProcess(dAtA[start:])
if err != nil {
return 0, err
}
iNdEx = start + next
}
return iNdEx, nil
case 4:
return iNdEx, nil
case 5:
iNdEx += 4
return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
}
panic("unreachable")
}
var (
ErrInvalidLengthProcess = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowProcess = fmt.Errorf("proto: integer overflow")
)
func init() {
proto.RegisterFile("github.com/docker/containerd/api/types/process/process.proto", fileDescriptorProcess)
}
var fileDescriptorProcess = []byte{
// 297 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x8c, 0x90, 0xb1, 0x4e, 0xc3, 0x30,
0x10, 0x86, 0x7b, 0x34, 0x6d, 0x83, 0x2b, 0x10, 0x32, 0x8b, 0xc9, 0x60, 0x2c, 0xa6, 0x2c, 0x38,
0x50, 0x24, 0xc4, 0xc0, 0xc4, 0x13, 0xa0, 0x54, 0xcc, 0x28, 0x75, 0xac, 0x62, 0x41, 0xe3, 0xc8,
0x76, 0x5a, 0xd8, 0x78, 0xbc, 0x8e, 0x8c, 0x8c, 0x34, 0x6f, 0xc0, 0x1b, 0x20, 0x3b, 0x52, 0x59,
0x3a, 0x74, 0x39, 0xdf, 0xfd, 0xfa, 0xee, 0xd7, 0x7f, 0x46, 0xf7, 0x73, 0xe5, 0x5e, 0x9a, 0x19,
0x17, 0x7a, 0x91, 0x95, 0x5a, 0xbc, 0x4a, 0x93, 0x09, 0x5d, 0xb9, 0x42, 0x55, 0xd2, 0x94, 0x59,
0x51, 0xab, 0xcc, 0x7d, 0xd4, 0xd2, 0x66, 0xb5, 0xd1, 0x42, 0xda, 0xed, 0xcb, 0x6b, 0xa3, 0x9d,
0xc6, 0xa7, 0xff, 0x2c, 0x5f, 0x5e, 0xf3, 0x80, 0x26, 0xb7, 0x7b, 0x5a, 0x36, 0x56, 0x9a, 0x50,
0x3a, 0xb3, 0xe4, 0x6e, 0xcf, 0x3d, 0xeb, 0x0a, 0x27, 0xbb, 0xda, 0x6d, 0x5e, 0xfc, 0x02, 0x1a,
0x3d, 0x76, 0xc1, 0xf0, 0x09, 0xea, 0xd7, 0xaa, 0x24, 0xc0, 0x20, 0x3d, 0xca, 0x7d, 0x8b, 0x31,
0x8a, 0x0a, 0x33, 0xb7, 0xe4, 0x80, 0xf5, 0xd3, 0xc3, 0x3c, 0xf4, 0x9e, 0x92, 0xd5, 0x92, 0xf4,
0x83, 0xe4, 0x5b, 0x7c, 0x89, 0x22, 0x9f, 0x85, 0x44, 0x0c, 0xd2, 0xf1, 0xe4, 0x8c, 0xef, 0xb8,
0x8c, 0x3f, 0x59, 0x69, 0xf2, 0x80, 0x79, 0x03, 0xb1, 0x2a, 0xc9, 0x80, 0x81, 0x37, 0x10, 0xab,
0x12, 0x27, 0x28, 0x76, 0xd2, 0x2c, 0x54, 0x55, 0xbc, 0x91, 0x21, 0x83, 0x34, 0xce, 0xb7, 0x33,
0xbe, 0x42, 0x83, 0x90, 0x97, 0x8c, 0x18, 0xa4, 0xc7, 0x93, 0x64, 0xa7, 0xfb, 0xd4, 0x13, 0x79,
0x07, 0xe2, 0x73, 0x34, 0x96, 0xef, 0xca, 0x3d, 0xfb, 0xa9, 0xb1, 0x24, 0x0e, 0xe7, 0x20, 0x2f,
0x4d, 0x83, 0xf2, 0x40, 0xd6, 0x1b, 0xda, 0xfb, 0xde, 0xd0, 0xde, 0x67, 0x4b, 0x61, 0xdd, 0x52,
0xf8, 0x6a, 0x29, 0xfc, 0xb4, 0x14, 0x66, 0xc3, 0xf0, 0x29, 0x37, 0x7f, 0x01, 0x00, 0x00, 0xff,
0xff, 0x19, 0xf5, 0x94, 0x44, 0xdb, 0x01, 0x00, 0x00,
}

View file

@ -1,17 +0,0 @@
syntax = "proto3";
package containerd.v1.types;
import "github.com/docker/containerd/api/types/user/user.proto";
import "github.com/docker/containerd/api/types/state/state.proto";
message Process {
uint32 pid = 1;
repeated string args = 2;
repeated string env = 3;
User user = 4;
string cwd = 5;
bool terminal = 6;
State state = 7; // only used by shim at the moment
uint32 exit_status = 8;
}

View file

@ -1,83 +0,0 @@
// Code generated by protoc-gen-gogo.
// source: github.com/docker/containerd/api/types/state/state.proto
// DO NOT EDIT!
/*
Package state is a generated protocol buffer package.
It is generated from these files:
github.com/docker/containerd/api/types/state/state.proto
It has these top-level messages:
*/
package state
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
// At the moment we have same State type for Container and Process
type State int32
const (
State_UNKNOWN State = 0
State_CREATED State = 1
State_RUNNING State = 2
State_STOPPED State = 3
State_PAUSED State = 4
)
var State_name = map[int32]string{
0: "UNKNOWN",
1: "CREATED",
2: "RUNNING",
3: "STOPPED",
4: "PAUSED",
}
var State_value = map[string]int32{
"UNKNOWN": 0,
"CREATED": 1,
"RUNNING": 2,
"STOPPED": 3,
"PAUSED": 4,
}
func (x State) String() string {
return proto.EnumName(State_name, int32(x))
}
func (State) EnumDescriptor() ([]byte, []int) { return fileDescriptorState, []int{0} }
func init() {
proto.RegisterEnum("containerd.v1.types.State", State_name, State_value)
}
func init() {
proto.RegisterFile("github.com/docker/containerd/api/types/state/state.proto", fileDescriptorState)
}
var fileDescriptorState = []byte{
// 184 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xb2, 0x48, 0xcf, 0x2c, 0xc9,
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xc9, 0x4f, 0xce, 0x4e, 0x2d, 0xd2, 0x4f, 0xce,
0xcf, 0x2b, 0x49, 0xcc, 0xcc, 0x4b, 0x2d, 0x4a, 0xd1, 0x4f, 0x2c, 0xc8, 0xd4, 0x2f, 0xa9, 0x2c,
0x48, 0x2d, 0xd6, 0x2f, 0x2e, 0x49, 0x2c, 0x49, 0x85, 0x90, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9,
0x42, 0xc2, 0x08, 0x75, 0x7a, 0x65, 0x86, 0x7a, 0x60, 0x65, 0x5a, 0xee, 0x5c, 0xac, 0xc1, 0x20,
0x35, 0x42, 0xdc, 0x5c, 0xec, 0xa1, 0x7e, 0xde, 0x7e, 0xfe, 0xe1, 0x7e, 0x02, 0x0c, 0x20, 0x8e,
0x73, 0x90, 0xab, 0x63, 0x88, 0xab, 0x8b, 0x00, 0x23, 0x88, 0x13, 0x14, 0xea, 0xe7, 0xe7, 0xe9,
0xe7, 0x2e, 0xc0, 0x04, 0xe2, 0x04, 0x87, 0xf8, 0x07, 0x04, 0xb8, 0xba, 0x08, 0x30, 0x0b, 0x71,
0x71, 0xb1, 0x05, 0x38, 0x86, 0x06, 0xbb, 0xba, 0x08, 0xb0, 0x38, 0x49, 0x9c, 0x78, 0x28, 0xc7,
0x70, 0xe3, 0xa1, 0x1c, 0x43, 0xc3, 0x23, 0x39, 0xc6, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92,
0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x31, 0x89, 0x0d, 0x6c, 0xbd, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff,
0xcd, 0xc9, 0x58, 0x29, 0xba, 0x00, 0x00, 0x00,
}

View file

@ -1,12 +0,0 @@
syntax = "proto3";
package containerd.v1.types;
// At the moment we have same State type for Container and Process
enum State {
UNKNOWN = 0;
CREATED = 1;
RUNNING = 2;
STOPPED = 3;
PAUSED = 4;
}

View file

@ -1,446 +0,0 @@
// Code generated by protoc-gen-gogo.
// source: github.com/docker/containerd/api/types/user/user.proto
// DO NOT EDIT!
/*
Package user is a generated protocol buffer package.
It is generated from these files:
github.com/docker/containerd/api/types/user/user.proto
It has these top-level messages:
User
*/
package user
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import strings "strings"
import reflect "reflect"
import io "io"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
type User struct {
Uid uint32 `protobuf:"varint,1,opt,name=uid,proto3" json:"uid,omitempty"`
Gid uint32 `protobuf:"varint,2,opt,name=gid,proto3" json:"gid,omitempty"`
AdditionalGids []uint32 `protobuf:"varint,3,rep,packed,name=additional_gids,json=additionalGids" json:"additional_gids,omitempty"`
}
func (m *User) Reset() { *m = User{} }
func (*User) ProtoMessage() {}
func (*User) Descriptor() ([]byte, []int) { return fileDescriptorUser, []int{0} }
func init() {
proto.RegisterType((*User)(nil), "containerd.v1.types.User")
}
func (m *User) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *User) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.Uid != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintUser(dAtA, i, uint64(m.Uid))
}
if m.Gid != 0 {
dAtA[i] = 0x10
i++
i = encodeVarintUser(dAtA, i, uint64(m.Gid))
}
if len(m.AdditionalGids) > 0 {
dAtA2 := make([]byte, len(m.AdditionalGids)*10)
var j1 int
for _, num := range m.AdditionalGids {
for num >= 1<<7 {
dAtA2[j1] = uint8(uint64(num)&0x7f | 0x80)
num >>= 7
j1++
}
dAtA2[j1] = uint8(num)
j1++
}
dAtA[i] = 0x1a
i++
i = encodeVarintUser(dAtA, i, uint64(j1))
i += copy(dAtA[i:], dAtA2[:j1])
}
return i, nil
}
func encodeFixed64User(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32User(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintUser(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
}
func (m *User) Size() (n int) {
var l int
_ = l
if m.Uid != 0 {
n += 1 + sovUser(uint64(m.Uid))
}
if m.Gid != 0 {
n += 1 + sovUser(uint64(m.Gid))
}
if len(m.AdditionalGids) > 0 {
l = 0
for _, e := range m.AdditionalGids {
l += sovUser(uint64(e))
}
n += 1 + sovUser(uint64(l)) + l
}
return n
}
func sovUser(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozUser(x uint64) (n int) {
return sovUser(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (this *User) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&User{`,
`Uid:` + fmt.Sprintf("%v", this.Uid) + `,`,
`Gid:` + fmt.Sprintf("%v", this.Gid) + `,`,
`AdditionalGids:` + fmt.Sprintf("%v", this.AdditionalGids) + `,`,
`}`,
}, "")
return s
}
func valueToStringUser(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("*%v", pv)
}
func (m *User) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowUser
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: User: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: User: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Uid", wireType)
}
m.Uid = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowUser
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Uid |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Gid", wireType)
}
m.Gid = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowUser
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Gid |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 3:
if wireType == 2 {
var packedLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowUser
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
packedLen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if packedLen < 0 {
return ErrInvalidLengthUser
}
postIndex := iNdEx + packedLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
for iNdEx < postIndex {
var v uint32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowUser
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.AdditionalGids = append(m.AdditionalGids, v)
}
} else if wireType == 0 {
var v uint32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowUser
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= (uint32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.AdditionalGids = append(m.AdditionalGids, v)
} else {
return fmt.Errorf("proto: wrong wireType = %d for field AdditionalGids", wireType)
}
default:
iNdEx = preIndex
skippy, err := skipUser(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthUser
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipUser(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowUser
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowUser
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
return iNdEx, nil
case 1:
iNdEx += 8
return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowUser
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthUser
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowUser
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
innerWire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
innerWireType := int(innerWire & 0x7)
if innerWireType == 4 {
break
}
next, err := skipUser(dAtA[start:])
if err != nil {
return 0, err
}
iNdEx = start + next
}
return iNdEx, nil
case 4:
return iNdEx, nil
case 5:
iNdEx += 4
return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
}
panic("unreachable")
}
var (
ErrInvalidLengthUser = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowUser = fmt.Errorf("proto: integer overflow")
)
func init() {
proto.RegisterFile("github.com/docker/containerd/api/types/user/user.proto", fileDescriptorUser)
}
var fileDescriptorUser = []byte{
// 188 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x32, 0x4b, 0xcf, 0x2c, 0xc9,
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xc9, 0x4f, 0xce, 0x4e, 0x2d, 0xd2, 0x4f, 0xce,
0xcf, 0x2b, 0x49, 0xcc, 0xcc, 0x4b, 0x2d, 0x4a, 0xd1, 0x4f, 0x2c, 0xc8, 0xd4, 0x2f, 0xa9, 0x2c,
0x48, 0x2d, 0xd6, 0x2f, 0x2d, 0x4e, 0x2d, 0x02, 0x13, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42,
0xc2, 0x08, 0x55, 0x7a, 0x65, 0x86, 0x7a, 0x60, 0x45, 0x4a, 0xc1, 0x5c, 0x2c, 0xa1, 0xc5, 0xa9,
0x45, 0x42, 0x02, 0x5c, 0xcc, 0xa5, 0x99, 0x29, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xbc, 0x41, 0x20,
0x26, 0x48, 0x24, 0x3d, 0x33, 0x45, 0x82, 0x09, 0x22, 0x92, 0x9e, 0x99, 0x22, 0xa4, 0xce, 0xc5,
0x9f, 0x98, 0x92, 0x92, 0x59, 0x92, 0x99, 0x9f, 0x97, 0x98, 0x13, 0x9f, 0x9e, 0x99, 0x52, 0x2c,
0xc1, 0xac, 0xc0, 0xac, 0xc1, 0x1b, 0xc4, 0x87, 0x10, 0x76, 0xcf, 0x4c, 0x29, 0x76, 0x92, 0x38,
0xf1, 0x50, 0x8e, 0xe1, 0xc6, 0x43, 0x39, 0x86, 0x86, 0x47, 0x72, 0x8c, 0x27, 0x1e, 0xc9, 0x31,
0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0x63, 0x12, 0x1b, 0xd8, 0x29, 0xc6, 0x80, 0x00,
0x00, 0x00, 0xff, 0xff, 0x39, 0x97, 0xe1, 0xe0, 0xc4, 0x00, 0x00, 0x00,
}

View file

@ -1,9 +0,0 @@
syntax = "proto3";
package containerd.v1.types;
message User {
uint32 uid = 1;
uint32 gid = 2;
repeated uint32 additional_gids = 3;
}

View file

@ -1,70 +0,0 @@
package bundle
import (
"encoding/json"
"os"
"path/filepath"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
const configName = "config.json"
func New(path string, s *specs.Spec) (*Bundle, error) {
if err := os.Mkdir(path, 0700); err != nil {
return nil, err
}
b := &Bundle{
Path: path,
}
if err := os.Mkdir(filepath.Join(path, "rootfs"), 0700); err != nil {
b.Delete()
return nil, err
}
f, err := os.Create(filepath.Join(path, configName))
if err != nil {
b.Delete()
return nil, err
}
err = json.NewEncoder(f).Encode(s)
f.Close()
if err != nil {
b.Delete()
return nil, err
}
return b, nil
}
func Load(path string) (*Bundle, error) {
fi, err := os.Stat(path)
if err != nil {
return nil, errors.Wrapf(err, "failed to access %q", path)
}
if !fi.IsDir() {
return nil, errors.Errorf("%q is not a directory", path)
}
return &Bundle{
Path: path,
}, nil
}
type Bundle struct {
Path string
}
func (b *Bundle) Config() (*specs.Spec, error) {
var s specs.Spec
f, err := os.Open(filepath.Join(b.Path, configName))
if err != nil {
return nil, err
}
err = json.NewDecoder(f).Decode(&s)
f.Close()
return &s, err
}
func (b *Bundle) Delete() error {
return os.RemoveAll(b.Path)
}

View file

@ -2,6 +2,7 @@ package main
import (
"fmt"
"net"
"os"
"os/signal"
"strings"
@ -52,6 +53,9 @@ func main() {
if err != nil {
return err
}
if err := setupRoot(); err != nil {
return err
}
var (
server = grpc.NewServer()
sv = shim.New()
@ -84,7 +88,7 @@ func setupSignals() (chan os.Signal, error) {
// serve serves the grpc API over a unix socket at the provided path
// this function does not block
func serve(server *grpc.Server, path string) error {
l, err := utils.CreateUnixSocket(path)
l, err := net.FileListener(os.NewFile(3, "socket"))
if err != nil {
return err
}
@ -126,3 +130,8 @@ func handleSignals(signals chan os.Signal, server *grpc.Server, service *shim.Se
}
return nil
}
// setupRoot sets up the root as the shim is started in its own mount namespace
func setupRoot() error {
return syscall.Mount("", "/", "", syscall.MS_SLAVE|syscall.MS_REC, "")
}

View file

@ -3,16 +3,12 @@ package main
import (
_ "expvar"
"fmt"
"net"
"net/http"
_ "net/http/pprof"
"net/url"
"os"
"os/signal"
"runtime"
"strconv"
"strings"
"syscall"
"time"
gocontext "golang.org/x/net/context"
"google.golang.org/grpc"
@ -20,17 +16,13 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/containerd"
api "github.com/docker/containerd/api/services/execution"
"github.com/docker/containerd/events"
_ "github.com/docker/containerd/linux"
"github.com/docker/containerd/log"
"github.com/docker/containerd/supervisor"
"github.com/docker/containerd/services/execution"
"github.com/docker/containerd/utils"
metrics "github.com/docker/go-metrics"
"github.com/pkg/errors"
"github.com/urfave/cli"
natsd "github.com/nats-io/gnatsd/server"
"github.com/nats-io/go-nats"
stand "github.com/nats-io/nats-streaming-server/server"
)
const usage = `
@ -43,10 +35,7 @@ const usage = `
high performance container runtime
`
const (
StanClusterID = "containerd"
stanClientID = "containerd"
)
var global = log.WithModule(gocontext.Background(), "containerd")
func main() {
app := cli.NewApp()
@ -83,108 +72,36 @@ func main() {
Usage: "tcp address to serve metrics on",
Value: "127.0.0.1:7897",
},
cli.StringFlag{
Name: "events-address, e",
Usage: "nats address to serve events on",
Value: nats.DefaultURL,
},
}
app.Before = func(context *cli.Context) error {
if context.GlobalBool("debug") {
logrus.SetLevel(logrus.DebugLevel)
}
if logLevel := context.GlobalString("log-level"); logLevel != "" {
lvl, err := logrus.ParseLevel(logLevel)
if err != nil {
lvl = logrus.InfoLevel
fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n, and being defaulted to info", logLevel)
}
logrus.SetLevel(lvl)
}
return nil
}
app.Before = before
app.Action = func(context *cli.Context) error {
start := time.Now()
// start the signal handler as soon as we can to make sure that
// we don't miss any signals during boot
signals := make(chan os.Signal, 2048)
signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT, syscall.SIGUSR1)
ctx := log.WithModule(gocontext.Background(), "containerd")
if address := context.GlobalString("metrics-address"); address != "" {
log.G(ctx).WithField("metrics-address", address).Info("listening and serving metrics")
go serveMetrics(ctx, address)
}
ea := context.GlobalString("events-address")
log.G(ctx).WithField("events-address", ea).Info("starting nats-streaming-server")
s, err := startNATSServer(ea)
if err != nil {
return nil
}
defer s.Shutdown()
debugPath := context.GlobalString("debug-socket")
if debugPath == "" {
return errors.New("--debug-socket path cannot be empty")
}
d, err := utils.CreateUnixSocket(debugPath)
log.G(global).Info("starting containerd boot...")
runtimes, err := loadRuntimes(context)
if err != nil {
return err
}
//publish profiling and debug socket.
log.G(ctx).WithField("socket", debugPath).Info("starting profiler handlers")
log.G(ctx).WithFields(logrus.Fields{"expvars": "/debug/vars", "socket": debugPath}).Debug("serving expvars requests")
log.G(ctx).WithFields(logrus.Fields{"pprof": "/debug/pprof", "socket": debugPath}).Debug("serving pprof requests")
go serveProfiler(ctx, d)
path := context.GlobalString("socket")
if path == "" {
return errors.New("--socket path cannot be empty")
}
l, err := utils.CreateUnixSocket(path)
supervisor, err := containerd.NewSupervisor(log.WithModule(global, "execution"), runtimes)
if err != nil {
return err
}
// Get events publisher
natsPoster, err := events.NewNATSPoster(StanClusterID, stanClientID)
if err != nil {
// start debug and metrics APIs
if err := serveDebugAPI(context); err != nil {
return err
}
execCtx := log.WithModule(ctx, "execution")
execCtx = events.WithPoster(execCtx, natsPoster)
execService, err := supervisor.New(execCtx, context.GlobalString("root"))
if err != nil {
serveMetricsAPI(context)
// start the GRPC api with the execution service registered
server := newGRPCServer(execution.New(supervisor))
if err := serveGRPC(context, server); err != nil {
return err
}
// Intercept the GRPC call in order to populate the correct module path
interceptor := func(ctx gocontext.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
ctx = log.WithModule(ctx, "containerd")
switch info.Server.(type) {
case api.ExecutionServiceServer:
ctx = log.WithModule(ctx, "execution")
ctx = events.WithPoster(ctx, natsPoster)
default:
fmt.Printf("Unknown type: %#v\n", info.Server)
}
return handler(ctx, req)
}
server := grpc.NewServer(grpc.UnaryInterceptor(interceptor))
api.RegisterExecutionServiceServer(server, execService)
log.G(ctx).WithField("socket", l.Addr()).Info("start serving GRPC API")
go serveGRPC(ctx, server, l)
for s := range signals {
switch s {
case syscall.SIGUSR1:
dumpStacks(ctx)
default:
log.G(ctx).WithField("signal", s).Info("stopping GRPC server")
server.Stop()
return nil
}
}
return nil
log.G(global).Infof("containerd successfully booted in %fs", time.Now().Sub(start).Seconds())
return handleSignals(signals, server)
}
if err := app.Run(os.Args); err != nil {
fmt.Fprintf(os.Stderr, "containerd: %s\n", err)
@ -192,81 +109,123 @@ func main() {
}
}
func serveMetrics(ctx gocontext.Context, address string) {
func before(context *cli.Context) error {
if context.GlobalBool("debug") {
logrus.SetLevel(logrus.DebugLevel)
}
if l := context.GlobalString("log-level"); l != "" {
lvl, err := logrus.ParseLevel(l)
if err != nil {
lvl = logrus.InfoLevel
fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n, and being defaulted to info", l)
}
logrus.SetLevel(lvl)
}
return nil
}
func serveMetricsAPI(context *cli.Context) {
if addr := context.GlobalString("metrics-address"); addr != "" {
log.G(global).WithField("metrics", addr).Info("starting metrics API...")
h := newMetricsHandler()
go func() {
if err := http.ListenAndServe(addr, h); err != nil {
log.G(global).WithError(err).Fatal("serve metrics API")
}
}()
}
}
func newMetricsHandler() http.Handler {
m := http.NewServeMux()
m.Handle("/metrics", metrics.Handler())
if err := http.ListenAndServe(address, m); err != nil {
log.G(ctx).WithError(err).Fatal("metrics server failure")
}
return m
}
func serveGRPC(ctx gocontext.Context, server *grpc.Server, l net.Listener) {
defer l.Close()
if err := server.Serve(l); err != nil {
log.G(ctx).WithError(err).Fatal("GRPC server failure")
func serveDebugAPI(context *cli.Context) error {
path := context.GlobalString("debug-socket")
if path == "" {
return errors.New("--debug-socket path cannot be empty")
}
}
func serveProfiler(ctx gocontext.Context, l net.Listener) {
defer l.Close()
if err := http.Serve(l, nil); err != nil {
log.G(ctx).WithError(err).Fatal("profiler server failure")
l, err := utils.CreateUnixSocket(path)
if err != nil {
return err
}
}
// DumpStacks dumps the runtime stack.
func dumpStacks(ctx gocontext.Context) {
var (
buf []byte
stackSize int
)
bufferLen := 16384
for stackSize == len(buf) {
buf = make([]byte, bufferLen)
stackSize = runtime.Stack(buf, true)
bufferLen *= 2
}
buf = buf[:stackSize]
log.G(ctx).Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
}
func startNATSServer(address string) (s *stand.StanServer, err error) {
defer func() {
if r := recover(); r != nil {
s = nil
if _, ok := r.(error); !ok {
err = fmt.Errorf("failed to start NATS server: %v", r)
} else {
err = r.(error)
}
log.G(global).WithField("debug", path).Info("starting debug API...")
go func() {
defer l.Close()
// pprof and expvars are imported and automatically register their endpoints
// under /debug
if err := http.Serve(l, nil); err != nil {
log.G(global).WithError(err).Fatal("serve debug API")
}
}()
so, no, err := getServerOptions(address)
if err != nil {
return nil, err
}
s = stand.RunServerWithOpts(so, no)
return s, err
return nil
}
func getServerOptions(address string) (*stand.Options, *natsd.Options, error) {
url, err := url.Parse(address)
if err != nil {
return nil, nil, errors.Wrapf(err, "failed to parse address url %q", address)
func loadRuntimes(context *cli.Context) (map[string]containerd.Runtime, error) {
var (
root = context.GlobalString("root")
o = make(map[string]containerd.Runtime)
)
for _, name := range containerd.Runtimes() {
r, err := containerd.NewRuntime(name, root)
if err != nil {
return nil, err
}
o[name] = r
log.G(global).WithField("runtime", name).Info("load runtime")
}
no := stand.DefaultNatsServerOptions
parts := strings.Split(url.Host, ":")
if len(parts) == 2 {
no.Port, err = strconv.Atoi(parts[1])
} else {
no.Port = nats.DefaultPort
}
no.Host = parts[0]
so := stand.GetDefaultOptions()
so.ID = StanClusterID
return so, &no, nil
return o, nil
}
func newGRPCServer(service api.ContainerServiceServer) *grpc.Server {
s := grpc.NewServer(grpc.UnaryInterceptor(interceptor))
api.RegisterContainerServiceServer(s, service)
return s
}
func serveGRPC(context *cli.Context, server *grpc.Server) error {
path := context.GlobalString("socket")
if path == "" {
return errors.New("--socket path cannot be empty")
}
l, err := utils.CreateUnixSocket(path)
if err != nil {
return err
}
go func() {
defer l.Close()
if err := server.Serve(l); err != nil {
log.G(global).WithError(err).Fatal("serve GRPC")
}
}()
return nil
}
func interceptor(ctx gocontext.Context,
req interface{},
info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler,
) (interface{}, error) {
ctx = log.WithModule(ctx, "containerd")
switch info.Server.(type) {
case api.ContainerServiceServer:
ctx = log.WithModule(global, "execution")
default:
fmt.Printf("unknown GRPC server type: %#v\n", info.Server)
}
return handler(global, req)
}
func handleSignals(signals chan os.Signal, server *grpc.Server) error {
for s := range signals {
log.G(global).WithField("signal", s).Debug("received signal")
switch s {
default:
server.Stop()
return nil
}
}
return nil
}

View file

@ -10,43 +10,20 @@ import (
var deleteCommand = cli.Command{
Name: "delete",
Usage: "delete a process from containerd store",
Usage: "delete an existing container",
ArgsUsage: "CONTAINER",
Flags: []cli.Flag{
cli.StringFlag{
Name: "pid, p",
Usage: "process id to be deleted",
},
},
Action: func(context *cli.Context) error {
executionService, err := getExecutionService(context)
containers, err := getExecutionService(context)
if err != nil {
return err
}
id := context.Args().First()
if id == "" {
return errors.New("container id must be provided")
return errors.New(" id must be provided")
}
pid := uint32(context.Int64("pid"))
if pid != 0 {
_, err = executionService.DeleteProcess(gocontext.Background(), &execution.DeleteProcessRequest{
ContainerID: id,
Pid: pid,
})
if err != nil {
return err
}
return nil
}
if _, err := executionService.DeleteContainer(gocontext.Background(), &execution.DeleteContainerRequest{
_, err = containers.Delete(gocontext.Background(), &execution.DeleteRequest{
ID: id,
}); err != nil {
return err
}
return nil
})
return err
},
}

View file

@ -1,61 +1,47 @@
package main
import (
"bytes"
"encoding/json"
gocontext "context"
"fmt"
"os"
"text/tabwriter"
"github.com/nats-io/go-nats"
"github.com/docker/containerd/api/services/execution"
"github.com/urfave/cli"
)
var eventsCommand = cli.Command{
Name: "events",
Usage: "display containerd events",
Flags: []cli.Flag{
cli.StringFlag{
Name: "subject, s",
Usage: "subjects filter",
Value: "containerd.>",
},
},
Action: func(context *cli.Context) error {
nc, err := nats.Connect(nats.DefaultURL)
containers, err := getExecutionService(context)
if err != nil {
return err
}
nec, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
if err != nil {
nc.Close()
return err
}
defer nec.Close()
evCh := make(chan *nats.Msg, 64)
sub, err := nec.Subscribe(context.String("subject"), func(e *nats.Msg) {
evCh <- e
})
events, err := containers.Events(gocontext.Background(), &execution.EventsRequest{})
if err != nil {
return err
}
defer sub.Unsubscribe()
w := tabwriter.NewWriter(os.Stdout, 10, 1, 3, ' ', 0)
fmt.Fprintln(w, "TYPE\tID\tPID\tEXIT_STATUS")
for {
e, more := <-evCh
if !more {
break
}
var prettyJSON bytes.Buffer
err := json.Indent(&prettyJSON, e.Data, "", "\t")
e, err := events.Recv()
if err != nil {
fmt.Println(string(e.Data))
} else {
fmt.Println(prettyJSON.String())
return err
}
if _, err := fmt.Fprintf(w,
"%s\t%s\t%d\t%d\n",
e.Type.String(),
e.ID,
e.Pid,
e.ExitStatus,
); err != nil {
return err
}
if err := w.Flush(); err != nil {
return err
}
}
return nil
},
}

View file

@ -1,87 +0,0 @@
package main
import (
"os"
"path/filepath"
"time"
gocontext "context"
"github.com/docker/containerd/api/services/execution"
"github.com/docker/containerd/api/types/process"
"github.com/urfave/cli"
)
var execCommand = cli.Command{
Name: "exec",
Usage: "exec a new process in a running container",
Flags: []cli.Flag{
cli.StringFlag{
Name: "id, i",
Usage: "target container id",
},
cli.StringFlag{
Name: "cwd, c",
Usage: "current working directory for the process",
},
cli.BoolFlag{
Name: "tty, t",
Usage: "create a terminal for the process",
},
cli.StringSliceFlag{
Name: "env, e",
Value: &cli.StringSlice{},
Usage: "environment variables for the process",
},
},
Action: func(context *cli.Context) error {
executionService, err := getExecutionService(context)
if err != nil {
return err
}
tmpDir, err := getTempDir(time.Now().Format("2006-02-01_15:04:05"))
if err != nil {
return err
}
defer os.RemoveAll(tmpDir)
id := context.String("id")
sOpts := &execution.StartProcessRequest{
ContainerID: id,
Process: &process.Process{
Cwd: context.String("cwd"),
Terminal: context.Bool("tty"),
Args: context.Args(),
Env: context.StringSlice("env"),
},
Stdin: filepath.Join(tmpDir, "stdin"),
Stdout: filepath.Join(tmpDir, "stdout"),
Stderr: filepath.Join(tmpDir, "stderr"),
Console: context.Bool("tty"),
}
fwg, err := prepareStdio(sOpts.Stdin, sOpts.Stdout, sOpts.Stderr, sOpts.Console)
if err != nil {
return err
}
sr, err := executionService.StartProcess(gocontext.Background(), sOpts)
if err != nil {
return err
}
_, err = executionService.DeleteProcess(gocontext.Background(), &execution.DeleteProcessRequest{
ContainerID: id,
Pid: sr.Process.Pid,
})
if err != nil {
return err
}
// Ensure we read all io
fwg.Wait()
return nil
},
}

View file

@ -1,42 +0,0 @@
package main
import (
gocontext "context"
"errors"
"github.com/davecgh/go-spew/spew"
"github.com/docker/containerd/api/services/execution"
"github.com/urfave/cli"
)
var inspectCommand = cli.Command{
Name: "inspect",
Usage: "inspect a container",
ArgsUsage: "CONTAINER",
Action: func(context *cli.Context) error {
executionService, err := getExecutionService(context)
if err != nil {
return err
}
id := context.Args().First()
if id == "" {
return errors.New("container id must be provided")
}
getResponse, err := executionService.GetContainer(gocontext.Background(),
&execution.GetContainerRequest{ID: id})
if err != nil {
return err
}
listProcResponse, err := executionService.ListProcesses(gocontext.Background(),
&execution.ListProcessesRequest{ContainerID: id})
if err != nil {
return err
}
dumper := spew.NewDefaultConfig()
dumper.Indent = "\t"
dumper.DisableMethods = true
dumper.DisablePointerAddresses = true
dumper.Dump(getResponse, listProcResponse)
return nil
},
}

View file

@ -3,6 +3,8 @@ package main
import (
gocontext "context"
"fmt"
"os"
"text/tabwriter"
"github.com/docker/containerd/api/services/execution"
"github.com/urfave/cli"
@ -12,29 +14,27 @@ var listCommand = cli.Command{
Name: "list",
Usage: "list containers",
Action: func(context *cli.Context) error {
executionService, err := getExecutionService(context)
containers, err := getExecutionService(context)
if err != nil {
return err
}
listResponse, err := executionService.ListContainers(gocontext.Background(), &execution.ListContainersRequest{
Owner: []string{},
})
response, err := containers.List(gocontext.Background(), &execution.ListRequest{})
if err != nil {
return err
}
fmt.Println("ID\tSTATUS\tPROCS\tBUNDLE")
for _, c := range listResponse.Containers {
listProcResponse, err := executionService.ListProcesses(gocontext.Background(),
&execution.ListProcessesRequest{ContainerID: c.ID})
if err != nil {
w := tabwriter.NewWriter(os.Stdout, 10, 1, 3, ' ', 0)
fmt.Fprintln(w, "ID\tPID\tSTATUS")
for _, c := range response.Containers {
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n",
c.ID,
c.Pid,
c.Status.String(),
); err != nil {
return err
}
if err := w.Flush(); err != nil {
return err
}
fmt.Printf("%s\t%s\t%d\t%s\n",
c.ID,
c.State,
len(listProcResponse.Processes),
c.Bundle,
)
}
return nil
},

View file

@ -35,11 +35,9 @@ containerd client
}
app.Commands = []cli.Command{
runCommand,
execCommand,
eventsCommand,
deleteCommand,
listCommand,
inspectCommand,
shimCommand,
pprofCommand,
}

View file

@ -3,148 +3,232 @@ package main
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"time"
gocontext "context"
"runtime"
"github.com/crosbymichael/console"
"github.com/docker/containerd/api/services/execution"
execEvents "github.com/docker/containerd/execution"
"github.com/nats-io/go-nats"
"github.com/nats-io/go-nats-streaming"
"github.com/pkg/errors"
"github.com/docker/containerd/api/types/mount"
protobuf "github.com/gogo/protobuf/types"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/urfave/cli"
)
var rwm = "rwm"
func spec(id string, args []string, tty bool) *specs.Spec {
return &specs.Spec{
Version: specs.Version,
Platform: specs.Platform{
OS: runtime.GOOS,
Arch: runtime.GOARCH,
},
Root: specs.Root{
Path: "rootfs",
Readonly: true,
},
Process: specs.Process{
Args: args,
Env: []string{
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
},
Terminal: tty,
Cwd: "/",
NoNewPrivileges: true,
},
Mounts: []specs.Mount{
{
Destination: "/proc",
Type: "proc",
Source: "proc",
},
{
Destination: "/dev",
Type: "tmpfs",
Source: "tmpfs",
Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"},
},
{
Destination: "/dev/pts",
Type: "devpts",
Source: "devpts",
Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"},
},
{
Destination: "/dev/shm",
Type: "tmpfs",
Source: "shm",
Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"},
},
{
Destination: "/dev/mqueue",
Type: "mqueue",
Source: "mqueue",
Options: []string{"nosuid", "noexec", "nodev"},
},
{
Destination: "/sys",
Type: "sysfs",
Source: "sysfs",
Options: []string{"nosuid", "noexec", "nodev"},
},
{
Destination: "/run",
Type: "tmpfs",
Source: "tmpfs",
Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"},
},
{
Destination: "/etc/resolv.conf",
Type: "bind",
Source: "/etc/resolv.conf",
Options: []string{"rbind", "ro"},
},
{
Destination: "/etc/hosts",
Type: "bind",
Source: "/etc/hosts",
Options: []string{"rbind", "ro"},
},
{
Destination: "/etc/localtime",
Type: "bind",
Source: "/etc/localtime",
Options: []string{"rbind", "ro"},
},
},
Hostname: id,
Linux: &specs.Linux{
Resources: &specs.LinuxResources{
Devices: []specs.LinuxDeviceCgroup{
{
Allow: false,
Access: &rwm,
},
},
},
Namespaces: []specs.LinuxNamespace{
{
Type: "pid",
},
{
Type: "ipc",
},
{
Type: "uts",
},
{
Type: "mount",
},
{
Type: "network",
},
},
},
}
}
var runCommand = cli.Command{
Name: "run",
Usage: "run a container",
Flags: []cli.Flag{
cli.StringFlag{
Name: "bundle, b",
Usage: "path to the container's bundle",
Name: "id",
Usage: "id of the container",
},
cli.BoolFlag{
Name: "tty, t",
Name: "tty,t",
Usage: "allocate a TTY for the container",
},
cli.StringFlag{
Name: "rootfs,r",
Usage: "path to the container's root filesystem",
},
},
Action: func(context *cli.Context) error {
id := context.Args().First()
id := context.String("id")
if id == "" {
return fmt.Errorf("container id must be provided")
}
executionService, err := getExecutionService(context)
containers, err := getExecutionService(context)
if err != nil {
return err
}
// setup our event subscriber
sc, err := stan.Connect("containerd", "ctr", stan.ConnectWait(5*time.Second))
if err != nil {
return err
}
defer sc.Close()
evCh := make(chan *execEvents.ContainerEvent, 64)
sub, err := sc.Subscribe(fmt.Sprintf("containers.%s", id), func(m *stan.Msg) {
var e execEvents.ContainerEvent
err := json.Unmarshal(m.Data, &e)
if err != nil {
fmt.Printf("failed to unmarshal event: %v", err)
return
}
evCh <- &e
})
if err != nil {
return err
}
defer sub.Unsubscribe()
tmpDir, err := getTempDir(id)
if err != nil {
return err
}
defer os.RemoveAll(tmpDir)
bundle, err := filepath.Abs(context.String("bundle"))
events, err := containers.Events(gocontext.Background(), &execution.EventsRequest{})
if err != nil {
return err
}
crOpts := &execution.CreateContainerRequest{
ID: id,
BundlePath: bundle,
Console: context.Bool("tty"),
Stdin: filepath.Join(tmpDir, "stdin"),
Stdout: filepath.Join(tmpDir, "stdout"),
Stderr: filepath.Join(tmpDir, "stderr"),
// for ctr right now just do a bind mount
rootfs := []*mount.Mount{
{
Type: "bind",
Source: context.String("rootfs"),
Options: []string{
"rw",
"rbind",
},
},
}
if crOpts.Console {
s := spec(id, []string(context.Args()), context.Bool("tty"))
data, err := json.Marshal(s)
if err != nil {
return err
}
create := &execution.CreateRequest{
ID: id,
Spec: &protobuf.Any{
TypeUrl: specs.Version,
Value: data,
},
Rootfs: rootfs,
Runtime: "linux",
Terminal: context.Bool("tty"),
Stdin: filepath.Join(tmpDir, "stdin"),
Stdout: filepath.Join(tmpDir, "stdout"),
Stderr: filepath.Join(tmpDir, "stderr"),
}
if create.Terminal {
con := console.Current()
defer con.Reset()
if err := con.SetRaw(); err != nil {
return err
}
}
fwg, err := prepareStdio(crOpts.Stdin, crOpts.Stdout, crOpts.Stderr, crOpts.Console)
fwg, err := prepareStdio(create.Stdin, create.Stdout, create.Stderr, create.Terminal)
if err != nil {
return err
}
cr, err := executionService.CreateContainer(gocontext.Background(), crOpts)
response, err := containers.Create(gocontext.Background(), create)
if err != nil {
return errors.Wrap(err, "CreateContainer RPC failed")
return err
}
if _, err := executionService.StartContainer(gocontext.Background(), &execution.StartContainerRequest{
ID: cr.Container.ID,
if _, err := containers.Start(gocontext.Background(), &execution.StartRequest{
ID: response.ID,
}); err != nil {
return errors.Wrap(err, "StartContainer RPC failed")
return err
}
var ec uint32
eventLoop:
for {
select {
case e, more := <-evCh:
if !more {
break eventLoop
}
if e.Type != "exit" {
continue
}
if e.ID == cr.Container.ID && e.Pid == cr.InitProcess.Pid {
ec = e.ExitStatus
break eventLoop
}
case <-time.After(1 * time.Second):
if sc.NatsConn().Status() != nats.CONNECTED {
break eventLoop
}
}
status, err := waitContainer(events, response)
if err != nil {
return err
}
if _, err := executionService.DeleteContainer(gocontext.Background(), &execution.DeleteContainerRequest{
ID: cr.Container.ID,
if _, err := containers.Delete(gocontext.Background(), &execution.DeleteRequest{
ID: response.ID,
}); err != nil {
return errors.Wrap(err, "DeleteContainer RPC failed")
return err
}
// Ensure we read all io
fwg.Wait()
if ec != 0 {
return cli.NewExitError("", int(ec))
if status != 0 {
return cli.NewExitError("", int(status))
}
return nil
},
}

View file

@ -15,6 +15,7 @@ import (
gocontext "context"
"github.com/docker/containerd/api/services/execution"
"github.com/docker/containerd/api/types/container"
"github.com/pkg/errors"
"github.com/tonistiigi/fifo"
"github.com/urfave/cli"
@ -103,12 +104,12 @@ func getGRPCConnection(context *cli.Context) (*grpc.ClientConn, error) {
return grpcConn, nil
}
func getExecutionService(context *cli.Context) (execution.ExecutionServiceClient, error) {
func getExecutionService(context *cli.Context) (execution.ContainerServiceClient, error) {
conn, err := getGRPCConnection(context)
if err != nil {
return nil, err
}
return execution.NewExecutionServiceClient(conn), nil
return execution.NewContainerServiceClient(conn), nil
}
func getTempDir(id string) (string, error) {
@ -122,3 +123,19 @@ func getTempDir(id string) (string, error) {
}
return tmpDir, nil
}
func waitContainer(events execution.ContainerService_EventsClient, response *execution.CreateResponse) (uint32, error) {
for {
e, err := events.Recv()
if err != nil {
return 255, err
}
if e.Type != container.Event_EXIT {
continue
}
if e.ID == response.ID &&
e.Pid == response.Pid {
return e.ExitStatus, nil
}
}
}

View file

@ -42,6 +42,7 @@ var (
// becomes the M declarations at the end of the declaration.
packageMap = map[string]string{
"google/protobuf/timestamp.proto": "github.com/gogo/protobuf/types",
"google/protobuf/any.proto": "github.com/gogo/protobuf/types",
"google/protobuf/descriptor.proto": "github.com/gogo/protobuf/protoc-gen-gogo/descriptor",
"gogoproto/gogo.proto": "github.com/gogo/protobuf/gogoproto",
}
@ -148,8 +149,9 @@ func main() {
// pass to sh -c so we don't need to re-split here.
args := []string{"-c", arg}
cmd := exec.Command("sh", args...)
if err := cmd.Run(); err != nil {
log.Fatalln(err)
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatalf("%s %s\n", out, err)
}
}
}

92
collector.go Normal file
View file

@ -0,0 +1,92 @@
package containerd
import (
"sync"
"golang.org/x/net/context"
)
func newCollector(ctx context.Context, runtimes map[string]Runtime) (*collector, error) {
c := &collector{
context: ctx,
ch: make(chan *Event, 2048),
eventClients: make(map[*eventClient]struct{}),
}
for _, r := range runtimes {
if err := c.collect(r); err != nil {
return nil, err
}
}
// run the publisher
go c.publisher()
// run a goroutine that waits for the context to be done
// and closes the channel after all writes have finished
go c.waitDone()
return c, nil
}
type eventClient struct {
eCh chan error
w EventWriter
}
type collector struct {
mu sync.Mutex
wg sync.WaitGroup
context context.Context
ch chan *Event
eventClients map[*eventClient]struct{}
}
// collect collects events from the provided runtime
func (c *collector) collect(r Runtime) error {
c.wg.Add(1)
go func() {
defer c.wg.Done()
for e := range r.Events(c.context) {
c.ch <- e
}
}()
return nil
}
// Forward forwards all events from the collector to the EventWriters
//
// It forwards events until the channels are closed or the EventWriter
// returns an error
// This is a blocking call
func (c *collector) forward(w EventWriter) error {
client := &eventClient{
w: w,
eCh: make(chan error, 1),
}
c.mu.Lock()
c.eventClients[client] = struct{}{}
c.mu.Unlock()
err := <-client.eCh
c.mu.Lock()
delete(c.eventClients, client)
c.mu.Unlock()
return err
}
func (c *collector) publisher() {
for e := range c.ch {
c.mu.Lock()
for client := range c.eventClients {
if err := client.w.Write(e); err != nil {
client.eCh <- err
}
}
c.mu.Unlock()
}
}
// waitDone waits for the context to finish, waits for all the goroutines to finish
// collecting grpc events from the shim, and closes the output channel
func (c *collector) waitDone() {
<-c.context.Done()
c.wg.Wait()
close(c.ch)
}

34
container.go Normal file
View file

@ -0,0 +1,34 @@
package containerd
import "golang.org/x/net/context"
type ContainerInfo struct {
ID string
Runtime string
}
type Container interface {
// Information of the container
Info() ContainerInfo
// Start the container's user defined process
Start(context.Context) error
// State returns the container's state
State(context.Context) (State, error)
}
type ContainerStatus int
const (
CreatedStatus ContainerStatus = iota + 1
RunningStatus
StoppedStatus
DeletedStatus
PausedStatus
)
type State interface {
// Status is the current status of the container
Status() ContainerStatus
// Pid is the main process id for the container
Pid() uint32
}

10
errors.go Normal file
View file

@ -0,0 +1,10 @@
package containerd
import "errors"
var (
ErrUnknownRuntime = errors.New("unknown runtime")
ErrContainerExists = errors.New("container with id already exists")
ErrContainerNotExist = errors.New("container does not exist")
ErrRuntimeNotExist = errors.New("runtime does not exist")
)

70
event.go Normal file
View file

@ -0,0 +1,70 @@
package containerd
import "time"
type EventType int
func (t EventType) String() string {
switch t {
case ExitEvent:
return "exit"
case PausedEvent:
return "paused"
case CreateEvent:
return "create"
case StartEvent:
return "start"
case OOMEvent:
return "oom"
case ExecAddEvent:
return "execAdd"
}
return "unknown"
}
const (
ExitEvent EventType = iota + 1
PausedEvent
CreateEvent
StartEvent
OOMEvent
ExecAddEvent
)
type Event struct {
Timestamp time.Time
Type EventType
Runtime string
ID string
Pid uint32
ExitStatus uint32
}
type EventWriter interface {
Write(*Event) error
}
type EventFilter func(*Event) bool
// NewFilterEventWriter returns an EventWriter that runs the provided filters on the events.
// If all the filters pass then the event is written to the wrapped EventWriter
func NewFilterEventWriter(w EventWriter, filters ...EventFilter) EventWriter {
return &filteredEventWriter{
w: w,
filters: filters,
}
}
type filteredEventWriter struct {
w EventWriter
filters []EventFilter
}
func (f *filteredEventWriter) Write(e *Event) error {
for _, filter := range f.filters {
if !filter(e) {
return nil
}
}
return f.w.Write(e)
}

View file

@ -1,179 +0,0 @@
package execution
import (
"context"
"io/ioutil"
"os"
"path/filepath"
"sync"
"github.com/docker/containerd/log"
"github.com/pkg/errors"
)
const (
InitProcessID = "init"
processesDirName = "processes"
bundleFileName = "bundle"
)
func LoadContainer(ctx context.Context, stateDir, id string) (c *Container, err error) {
c = &Container{
id: id,
stateDir: stateDir,
processes: make(map[string]Process, 1),
ctx: ctx,
status: Unknown,
}
data, err := ioutil.ReadFile(filepath.Join(stateDir, bundleFileName))
if err != nil {
err = errors.Wrapf(err, "failed to read bundle path")
return
}
c.bundle = string(data)
return
}
func NewContainer(ctx context.Context, stateDir, id, bundle string) (c *Container, err error) {
c = &Container{
id: id,
stateDir: stateDir,
bundle: bundle,
processes: make(map[string]Process, 1),
status: Created,
ctx: ctx,
}
defer func() {
if err != nil {
c.Cleanup()
c = nil
}
}()
if err = os.Mkdir(stateDir, 0700); err != nil {
err = errors.Wrap(err, "failed to create container state dir")
return
}
bundleFile := filepath.Join(stateDir, bundleFileName)
if err = ioutil.WriteFile(bundleFile, []byte(bundle), 0600); err != nil {
err = errors.Wrap(err, "failed to store bundle path")
return
}
processesDir := filepath.Join(stateDir, processesDirName)
if err = os.Mkdir(processesDir, 0700); err != nil {
err = errors.Wrap(err, "failed to create processes statedir")
return
}
return
}
type Container struct {
id string
stateDir string
bundle string
processes map[string]Process
status Status
ctx context.Context
mu sync.Mutex
}
func (c *Container) ID() string {
return c.id
}
func (c *Container) Bundle() string {
return c.bundle
}
func (c *Container) Wait() (uint32, error) {
initProcess := c.GetProcess(InitProcessID)
return initProcess.Wait()
}
func (c *Container) Status() Status {
initProcess := c.GetProcess(InitProcessID)
return initProcess.Status()
}
func (c *Container) AddProcess(p Process) {
c.mu.Lock()
c.processes[p.ID()] = p
c.mu.Unlock()
}
func (c *Container) RemoveProcess(id string) error {
if _, ok := c.processes[id]; !ok {
return errors.Errorf("no such process %s", id)
}
c.mu.Lock()
delete(c.processes, id)
c.mu.Unlock()
processStateDir := filepath.Join(c.stateDir, processesDirName, id)
err := os.RemoveAll(processStateDir)
if err != nil {
return errors.Wrap(err, "failed to remove process state dir")
}
return nil
}
func (c *Container) GetProcess(id string) Process {
c.mu.Lock()
defer c.mu.Unlock()
return c.processes[id]
}
func (c *Container) Processes() []Process {
var procs []Process
c.mu.Lock()
for _, p := range c.processes {
procs = append(procs, p)
}
c.mu.Unlock()
return procs
}
// ProcessStateDir returns the path of the state dir for a given
// process id. The process doesn't have to exist for this to succeed.
func (c *Container) ProcessStateDir(id string) string {
return filepath.Join(c.stateDir, processesDirName, id)
}
// ProcessesStateDir returns a map matching process ids to their state
// directory
func (c *Container) ProcessesStateDir() (map[string]string, error) {
root := filepath.Join(c.stateDir, processesDirName)
dirs, err := ioutil.ReadDir(root)
if err != nil {
return nil, errors.Wrapf(err, "failed to list processes state dirs")
}
procs := make(map[string]string, 1)
for _, d := range dirs {
if d.IsDir() {
procs[d.Name()] = filepath.Join(root, d.Name())
}
}
return procs, nil
}
func (c *Container) Cleanup() {
if err := os.RemoveAll(c.stateDir); err != nil {
log.G(c.ctx).Warnf("failed to remove container state dir: %v", err)
}
}
func (c *Container) Context() context.Context {
return c.ctx
}

View file

@ -1,10 +0,0 @@
package execution
import "fmt"
var (
ErrProcessNotFound = fmt.Errorf("process not found")
ErrProcessNotExited = fmt.Errorf("process has not exited")
ErrContainerNotFound = fmt.Errorf("container not found")
ErrContainerExists = fmt.Errorf("container already exists")
)

View file

@ -1,28 +0,0 @@
package execution
import "time"
const (
ExitEvent = "exit"
OOMEvent = "oom"
CreateEvent = "create"
StartEvent = "start"
ExecEvent = "exec-added9"
)
type ContainerEvent struct {
Timestamp time.Time
ID string
Type string
Pid uint32
ExitStatus uint32
}
const (
ContainersEventsSubjectSubscriber = "containerd.execution.container.>"
)
const (
containerEventsTopicFormat = "container.%s"
containerProcessEventsTopicFormat = "container.%s.%s"
)

View file

@ -1,39 +0,0 @@
package execution
import (
"context"
"os"
"github.com/opencontainers/runtime-spec/specs-go"
)
type CreateOpts struct {
Bundle string
Console bool
Stdin string
Stdout string
Stderr string
}
type StartProcessOpts struct {
ID string
Spec specs.Process
Console bool
Stdin string
Stdout string
Stderr string
}
type Executor interface {
Create(ctx context.Context, id string, o CreateOpts) (*Container, error)
Pause(context.Context, *Container) error
Resume(context.Context, *Container) error
List(context.Context) ([]*Container, error)
Load(ctx context.Context, id string) (*Container, error)
Delete(context.Context, *Container) error
Start(context.Context, *Container) error
StartProcess(context.Context, *Container, StartProcessOpts) (Process, error)
SignalProcess(ctx context.Context, c *Container, id string, sig os.Signal) error
DeleteProcess(ctx context.Context, c *Container, id string) error
}

View file

@ -1,12 +0,0 @@
package execution
import "os"
type Process interface {
ID() string
Pid() int64
//Spec() *specs.Process
Wait() (uint32, error)
Signal(os.Signal) error
Status() Status
}

View file

@ -1,15 +0,0 @@
package execution
type Status string
const (
Created Status = "created"
Paused Status = "paused"
Pausing Status = "pausing"
Running Status = "running"
Stopped Status = "stopped"
Deleted Status = "deleted"
Unknown Status = "unknown"
UnknownStatusCode = 255
)

48
linux/container.go Normal file
View file

@ -0,0 +1,48 @@
package linux
import (
"github.com/docker/containerd"
"github.com/docker/containerd/api/services/shim"
"golang.org/x/net/context"
)
type State struct {
pid uint32
status containerd.ContainerStatus
}
func (s State) Pid() uint32 {
return s.pid
}
func (s State) Status() containerd.ContainerStatus {
return s.status
}
type Container struct {
id string
shim shim.ShimClient
}
func (c *Container) Info() containerd.ContainerInfo {
return containerd.ContainerInfo{
ID: c.id,
Runtime: runtimeName,
}
}
func (c *Container) Start(ctx context.Context) error {
_, err := c.shim.Start(ctx, &shim.StartRequest{})
return err
}
func (c *Container) State(ctx context.Context) (containerd.State, error) {
response, err := c.shim.State(ctx, &shim.StateRequest{})
if err != nil {
return nil, err
}
return &State{
pid: response.Pid,
}, nil
}

196
linux/runtime.go Normal file
View file

@ -0,0 +1,196 @@
package linux
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"time"
"github.com/docker/containerd"
"github.com/docker/containerd/api/services/shim"
"github.com/docker/containerd/api/types/container"
"github.com/docker/containerd/api/types/mount"
"github.com/docker/containerd/log"
"golang.org/x/net/context"
)
const (
runtimeName = "linux"
configFilename = "config.json"
)
func init() {
containerd.RegisterRuntime(runtimeName, New)
}
func New(root string) (containerd.Runtime, error) {
if err := os.MkdirAll(root, 0700); err != nil {
return nil, err
}
c, cancel := context.WithCancel(context.Background())
return &Runtime{
root: root,
events: make(chan *containerd.Event, 2048),
eventsContext: c,
eventsCancel: cancel,
}, nil
}
type Runtime struct {
root string
events chan *containerd.Event
eventsContext context.Context
eventsCancel func()
}
func (r *Runtime) Create(ctx context.Context, id string, opts containerd.CreateOpts) (containerd.Container, error) {
path, err := r.newBundle(id, opts.Spec)
if err != nil {
return nil, err
}
s, err := newShim(path)
if err != nil {
os.RemoveAll(path)
return nil, err
}
if err := r.handleEvents(s); err != nil {
os.RemoveAll(path)
return nil, err
}
sopts := &shim.CreateRequest{
ID: id,
Bundle: path,
Runtime: "runc",
Stdin: opts.IO.Stdin,
Stdout: opts.IO.Stdout,
Stderr: opts.IO.Stderr,
Terminal: opts.IO.Terminal,
}
for _, m := range opts.Rootfs {
sopts.Rootfs = append(sopts.Rootfs, &mount.Mount{
Type: m.Type,
Source: m.Source,
Options: m.Options,
})
}
if _, err := s.Create(ctx, sopts); err != nil {
os.RemoveAll(path)
return nil, err
}
return &Container{
id: id,
shim: s,
}, nil
}
func (r *Runtime) Delete(ctx context.Context, c containerd.Container) error {
lc, ok := c.(*Container)
if !ok {
return fmt.Errorf("container cannot be cast as *linux.Container")
}
if _, err := lc.shim.Delete(ctx, &shim.DeleteRequest{}); err != nil {
return err
}
lc.shim.Exit(ctx, &shim.ExitRequest{})
return r.deleteBundle(lc.id)
}
func (r *Runtime) Containers() ([]containerd.Container, error) {
dir, err := ioutil.ReadDir(r.root)
if err != nil {
return nil, err
}
var o []containerd.Container
for _, fi := range dir {
if !fi.IsDir() {
continue
}
c, err := r.loadContainer(fi.Name())
if err != nil {
return nil, err
}
o = append(o, c)
}
return o, nil
}
func (r *Runtime) Events(ctx context.Context) <-chan *containerd.Event {
return r.events
}
func (r *Runtime) handleEvents(s shim.ShimClient) error {
events, err := s.Events(r.eventsContext, &shim.EventsRequest{})
if err != nil {
return err
}
go r.forward(events)
return nil
}
func (r *Runtime) forward(events shim.Shim_EventsClient) {
for {
e, err := events.Recv()
if err != nil {
log.G(r.eventsContext).WithError(err).Error("get event from shim")
return
}
var et containerd.EventType
switch e.Type {
case container.Event_CREATE:
et = containerd.CreateEvent
case container.Event_EXEC_ADDED:
et = containerd.ExecAddEvent
case container.Event_EXIT:
et = containerd.ExitEvent
case container.Event_OOM:
et = containerd.OOMEvent
case container.Event_START:
et = containerd.StartEvent
}
r.events <- &containerd.Event{
Timestamp: time.Now(),
Runtime: runtimeName,
Type: et,
Pid: e.Pid,
ID: e.ID,
ExitStatus: e.ExitStatus,
}
}
}
func (r *Runtime) newBundle(id string, spec []byte) (string, error) {
path := filepath.Join(r.root, id)
if err := os.Mkdir(path, 0700); err != nil {
return "", err
}
if err := os.Mkdir(filepath.Join(path, "rootfs"), 0700); err != nil {
return "", err
}
f, err := os.Create(filepath.Join(path, configFilename))
if err != nil {
return "", err
}
_, err = io.Copy(f, bytes.NewReader(spec))
return path, err
}
func (r *Runtime) deleteBundle(id string) error {
return os.RemoveAll(filepath.Join(r.root, id))
}
func (r *Runtime) loadContainer(path string) (*Container, error) {
id := filepath.Base(path)
s, err := loadShim(path)
if err != nil {
return nil, err
}
return &Container{
id: id,
shim: s,
}, nil
}

76
linux/shim.go Normal file
View file

@ -0,0 +1,76 @@
package linux
import (
"fmt"
"io/ioutil"
"log"
"net"
"os/exec"
"path/filepath"
"syscall"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
"github.com/docker/containerd/api/services/shim"
"github.com/docker/containerd/utils"
"github.com/pkg/errors"
)
func newShim(path string) (shim.ShimClient, error) {
socket := filepath.Join(path, "shim.sock")
l, err := utils.CreateUnixSocket(socket)
if err != nil {
return nil, err
}
cmd := exec.Command("containerd-shim")
cmd.Dir = path
f, err := l.(*net.UnixListener).File()
if err != nil {
return nil, err
}
cmd.ExtraFiles = append(cmd.ExtraFiles, f)
// make sure the shim can be re-parented to system init
// and is cloned in a new mount namespace because the overlay/filesystems
// will be mounted by the shim
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWNS,
Setpgid: true,
}
if err := cmd.Start(); err != nil {
return nil, errors.Wrapf(err, "failed to start shim")
}
// close our side of the socket, do not close the listener as it will
// remove the socket from disk
f.Close()
// since we are currently the parent go ahead and make sure we wait on the shim
go cmd.Wait()
return connectShim(socket)
}
func loadShim(path string) (shim.ShimClient, error) {
socket := filepath.Join(path, "shim.sock")
return connectShim(socket)
// TODO: failed to connect to the shim, check if it's alive
// - if it is kill it
// - in both case call runc killall and runc delete on the id
}
func connectShim(socket string) (shim.ShimClient, error) {
// reset the logger for grpc to log to dev/null so that it does not mess with our stdio
grpclog.SetLogger(log.New(ioutil.Discard, "", log.LstdFlags))
dialOpts := []grpc.DialOption{grpc.WithInsecure(), grpc.WithTimeout(100 * time.Second)}
dialOpts = append(dialOpts,
grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
return net.DialTimeout("unix", socket, timeout)
}),
grpc.WithBlock(),
grpc.WithTimeout(2*time.Second),
)
conn, err := grpc.Dial(fmt.Sprintf("unix://%s", socket), dialOpts...)
if err != nil {
return nil, errors.Wrapf(err, "failed to connect to shim via \"%s\"", fmt.Sprintf("unix://%s", socket))
}
return shim.NewShimClient(conn), nil
}

View file

@ -3,9 +3,6 @@ package containerd
import (
"strings"
"syscall"
"github.com/Sirupsen/logrus"
"github.com/docker/containerd/log"
)
// Mount is the lingua franca of containerd. A mount represents a
@ -23,13 +20,6 @@ type Mount struct {
func (m *Mount) Mount(target string) error {
flags, data := parseMountOptions(m.Options)
lfields := logrus.Fields{"target": target, "source": m.Source}
if data != "" {
lfields["data"] = data
}
log.L.WithFields(lfields).Debug("syscall.Mount")
return syscall.Mount(m.Source, target, m.Type, uintptr(flags), data)
}

79
runtime.go Normal file
View file

@ -0,0 +1,79 @@
package containerd
import (
"fmt"
"sync"
"golang.org/x/net/context"
)
// NewRuntimeFunc is the runtime's constructor
type NewRuntimeFunc func(root string) (Runtime, error)
var runtimeRegistration = struct {
mu sync.Mutex
runtimes map[string]NewRuntimeFunc
}{
runtimes: make(map[string]NewRuntimeFunc),
}
// RegisterRuntime is not external packages registers Runtimes for use with containerd
func RegisterRuntime(name string, f NewRuntimeFunc) {
runtimeRegistration.mu.Lock()
defer runtimeRegistration.mu.Unlock()
if _, ok := runtimeRegistration.runtimes[name]; ok {
panic(fmt.Errorf("runtime already registered as %q", name))
}
runtimeRegistration.runtimes[name] = f
}
// Runtimes returns a slice of all registered runtime names for containerd
func Runtimes() (o []string) {
runtimeRegistration.mu.Lock()
defer runtimeRegistration.mu.Unlock()
for k := range runtimeRegistration.runtimes {
o = append(o, k)
}
return o
}
// NewRuntime calls the runtime's constructor with the provided root
func NewRuntime(name, root string) (Runtime, error) {
runtimeRegistration.mu.Lock()
defer runtimeRegistration.mu.Unlock()
f, ok := runtimeRegistration.runtimes[name]
if !ok {
return nil, ErrRuntimeNotExist
}
return f(root)
}
type IO struct {
Stdin string
Stdout string
Stderr string
Terminal bool
}
type CreateOpts struct {
// Spec is the OCI runtime spec
Spec []byte
// Rootfs mounts to perform to gain access to the container's filesystem
Rootfs []Mount
// IO for the container's main process
IO IO
}
// Runtime is responsible for the creation of containers for a certain platform,
// arch, or custom usage.
type Runtime interface {
// Create creates a container with the provided id and options
Create(ctx context.Context, id string, opts CreateOpts) (Container, error)
// Containers returns all the current containers for the runtime
Containers() ([]Container, error)
// Delete removes the container in the runtime
Delete(ctx context.Context, c Container) error
// Events returns events for the runtime and all containers created by the runtime
Events(context.Context) <-chan *Event
}

View file

@ -0,0 +1,137 @@
package execution
import (
"github.com/docker/containerd"
api "github.com/docker/containerd/api/services/execution"
"github.com/docker/containerd/api/types/container"
google_protobuf "github.com/golang/protobuf/ptypes/empty"
"golang.org/x/net/context"
)
var (
_ = (api.ContainerServiceServer)(&Service{})
empty = &google_protobuf.Empty{}
)
// New creates a new GRPC service for the ContainerService
func New(s *containerd.Supervisor) *Service {
return &Service{
s: s,
}
}
type Service struct {
s *containerd.Supervisor
}
func (s *Service) Create(ctx context.Context, r *api.CreateRequest) (*api.CreateResponse, error) {
opts := containerd.CreateOpts{
Spec: r.Spec.Value,
IO: containerd.IO{
Stdin: r.Stdin,
Stdout: r.Stdout,
Stderr: r.Stderr,
Terminal: r.Terminal,
},
}
for _, m := range r.Rootfs {
opts.Rootfs = append(opts.Rootfs, containerd.Mount{
Type: m.Type,
Source: m.Source,
Options: m.Options,
})
}
c, err := s.s.Create(ctx, r.ID, r.Runtime, opts)
if err != nil {
return nil, err
}
state, err := c.State(ctx)
if err != nil {
s.s.Delete(ctx, r.ID)
return nil, err
}
return &api.CreateResponse{
ID: r.ID,
Pid: state.Pid(),
}, nil
}
func (s *Service) Start(ctx context.Context, r *api.StartRequest) (*google_protobuf.Empty, error) {
c, err := s.s.Get(r.ID)
if err != nil {
return nil, err
}
if err := c.Start(ctx); err != nil {
return nil, err
}
return empty, nil
}
func (s *Service) Delete(ctx context.Context, r *api.DeleteRequest) (*google_protobuf.Empty, error) {
if err := s.s.Delete(ctx, r.ID); err != nil {
return nil, err
}
return empty, nil
}
func (s *Service) List(ctx context.Context, r *api.ListRequest) (*api.ListResponse, error) {
resp := &api.ListResponse{}
for _, c := range s.s.Containers() {
state, err := c.State(ctx)
if err != nil {
return nil, err
}
var status container.Status
switch state.Status() {
case containerd.CreatedStatus:
status = container.Status_CREATED
case containerd.RunningStatus:
status = container.Status_RUNNING
case containerd.StoppedStatus:
status = container.Status_STOPPED
case containerd.PausedStatus:
status = container.Status_PAUSED
}
resp.Containers = append(resp.Containers, &container.Container{
ID: c.Info().ID,
Pid: state.Pid(),
Status: status,
})
}
return resp, nil
}
func (s *Service) Events(r *api.EventsRequest, server api.ContainerService_EventsServer) error {
w := &grpcEventWriter{
server: server,
}
return s.s.ForwardEvents(w)
}
type grpcEventWriter struct {
server api.ContainerService_EventsServer
}
func (g *grpcEventWriter) Write(e *containerd.Event) error {
var t container.Event_EventType
switch e.Type {
case containerd.ExitEvent:
t = container.Event_EXIT
case containerd.ExecAddEvent:
t = container.Event_EXEC_ADDED
case containerd.PausedEvent:
t = container.Event_PAUSED
case containerd.CreateEvent:
t = container.Event_CREATE
case containerd.StartEvent:
t = container.Event_START
case containerd.OOMEvent:
t = container.Event_OOM
}
return g.server.Send(&container.Event{
Type: t,
ID: e.ID,
Pid: e.Pid,
ExitStatus: e.ExitStatus,
})
}

View file

@ -9,6 +9,7 @@ import (
"github.com/crosbymichael/console"
runc "github.com/crosbymichael/go-runc"
"github.com/docker/containerd"
shimapi "github.com/docker/containerd/api/services/shim"
)
@ -29,6 +30,16 @@ func newInitProcess(context context.Context, r *shimapi.CreateRequest) (*initPro
if err != nil {
return nil, err
}
for _, rm := range r.Rootfs {
m := &containerd.Mount{
Type: rm.Type,
Source: rm.Source,
Options: rm.Options,
}
if err := m.Mount(filepath.Join(cwd, "rootfs")); err != nil {
return nil, err
}
}
runtime := &runc.Runc{
Command: r.Runtime,
Log: filepath.Join(cwd, "log.json"),

View file

@ -1,26 +1,26 @@
package shim
import (
"os"
"sync"
"syscall"
"github.com/crosbymichael/console"
shimapi "github.com/docker/containerd/api/services/shim"
processapi "github.com/docker/containerd/api/types/process"
stateapi "github.com/docker/containerd/api/types/state"
"github.com/docker/containerd/api/types/container"
"github.com/docker/containerd/utils"
google_protobuf "github.com/golang/protobuf/ptypes/empty"
"github.com/pkg/errors"
"golang.org/x/net/context"
)
var emptyResponse = &google_protobuf.Empty{}
var empty = &google_protobuf.Empty{}
// New returns a new shim service that can be used via GRPC
func New() *Service {
return &Service{
processes: make(map[int]process),
events: make(chan *shimapi.Event, 4096),
events: make(chan *container.Event, 4096),
}
}
@ -30,7 +30,7 @@ type Service struct {
bundle string
mu sync.Mutex
processes map[int]process
events chan *shimapi.Event
events chan *container.Event
execID int
}
@ -46,8 +46,8 @@ func (s *Service) Create(ctx context.Context, r *shimapi.CreateRequest) (*shimap
pid := process.Pid()
s.processes[pid] = process
s.mu.Unlock()
s.events <- &shimapi.Event{
Type: shimapi.EventType_CREATE,
s.events <- &container.Event{
Type: container.Event_CREATE,
ID: r.ID,
Pid: uint32(pid),
}
@ -60,12 +60,12 @@ func (s *Service) Start(ctx context.Context, r *shimapi.StartRequest) (*google_p
if err := s.initProcess.Start(ctx); err != nil {
return nil, err
}
s.events <- &shimapi.Event{
Type: shimapi.EventType_START,
s.events <- &container.Event{
Type: container.Event_START,
ID: s.id,
Pid: uint32(s.initProcess.Pid()),
}
return emptyResponse, nil
return empty, nil
}
func (s *Service) Delete(ctx context.Context, r *shimapi.DeleteRequest) (*shimapi.DeleteResponse, error) {
@ -73,7 +73,7 @@ func (s *Service) Delete(ctx context.Context, r *shimapi.DeleteRequest) (*shimap
p, ok := s.processes[int(r.Pid)]
s.mu.Unlock()
if !ok {
return nil, errors.Errorf("process does not exist %d", r.Pid)
p = s.initProcess
}
if err := p.Delete(ctx); err != nil {
return nil, err
@ -96,8 +96,8 @@ func (s *Service) Exec(ctx context.Context, r *shimapi.ExecRequest) (*shimapi.Ex
}
pid := process.Pid()
s.processes[pid] = process
s.events <- &shimapi.Event{
Type: shimapi.EventType_EXEC_ADDED,
s.events <- &container.Event{
Type: container.Event_EXEC_ADDED,
ID: s.id,
Pid: uint32(pid),
}
@ -123,7 +123,7 @@ func (s *Service) Pty(ctx context.Context, r *shimapi.PtyRequest) (*google_proto
if err := p.Resize(ws); err != nil {
return nil, err
}
return emptyResponse, nil
return empty, nil
}
func (s *Service) Events(r *shimapi.EventsRequest, stream shimapi.Shim_EventsServer) error {
@ -139,22 +139,22 @@ func (s *Service) State(ctx context.Context, r *shimapi.StateRequest) (*shimapi.
o := &shimapi.StateResponse{
ID: s.id,
Bundle: s.bundle,
InitPid: uint32(s.initProcess.Pid()),
Processes: []*processapi.Process{},
Pid: uint32(s.initProcess.Pid()),
Processes: []*container.Process{},
}
s.mu.Lock()
defer s.mu.Unlock()
for _, p := range s.processes {
state := stateapi.State_RUNNING
status := container.Status_RUNNING
if err := syscall.Kill(p.Pid(), 0); err != nil {
if err != syscall.ESRCH {
return nil, err
}
state = stateapi.State_STOPPED
status = container.Status_STOPPED
}
o.Processes = append(o.Processes, &processapi.Process{
Pid: uint32(p.Pid()),
State: state,
o.Processes = append(o.Processes, &container.Process{
Pid: uint32(p.Pid()),
Status: status,
})
}
return o, nil
@ -164,22 +164,30 @@ func (s *Service) Pause(ctx context.Context, r *shimapi.PauseRequest) (*google_p
if err := s.initProcess.Pause(ctx); err != nil {
return nil, err
}
return emptyResponse, nil
return empty, nil
}
func (s *Service) Resume(ctx context.Context, r *shimapi.ResumeRequest) (*google_protobuf.Empty, error) {
if err := s.initProcess.Resume(ctx); err != nil {
return nil, err
}
return emptyResponse, nil
return empty, nil
}
func (s *Service) Exit(ctx context.Context, r *shimapi.ExitRequest) (*google_protobuf.Empty, error) {
// signal ourself to exit
if err := syscall.Kill(os.Getpid(), syscall.SIGTERM); err != nil {
return nil, err
}
return empty, nil
}
func (s *Service) ProcessExit(e utils.Exit) error {
s.mu.Lock()
if p, ok := s.processes[e.Pid]; ok {
p.Exited(e.Status)
s.events <- &shimapi.Event{
Type: shimapi.EventType_EXIT,
s.events <- &container.Event{
Type: container.Event_EXIT,
ID: s.id,
Pid: uint32(p.Pid()),
ExitStatus: uint32(e.Status),

View file

@ -1,70 +0,0 @@
package specification
import (
"runtime"
"github.com/docker/containerd"
"github.com/opencontainers/runtime-spec/specs-go"
)
var rwm = "rwm"
func Default(config containerd.Config, mounts []containerd.Mount) *specs.Spec {
s := &specs.Spec{
Version: specs.Version,
Platform: specs.Platform{
OS: runtime.GOOS,
Arch: runtime.GOARCH,
},
Root: specs.Root{
Path: "rootfs",
Readonly: false,
},
Process: specs.Process{
Args: config.Process.Args,
Env: config.Process.Env,
Terminal: config.Process.TTY,
Cwd: config.Process.Cwd,
NoNewPrivileges: true,
},
Hostname: config.Hostname,
Linux: &specs.Linux{
Resources: &specs.LinuxResources{
Devices: []specs.LinuxDeviceCgroup{
{
Allow: false,
Access: &rwm,
},
},
},
Namespaces: []specs.LinuxNamespace{
{
Type: "pid",
},
{
Type: "ipc",
},
{
Type: "uts",
},
{
Type: "mount",
},
{
Type: "network",
},
},
},
Annotations: config.Labels,
}
// apply snapshot mounts
for _, m := range mounts {
s.Mounts = append(s.Mounts, specs.Mount{
Source: m.Source,
Destination: "/",
Type: m.Type,
Options: m.Options,
})
}
return s
}

100
supervisor.go Normal file
View file

@ -0,0 +1,100 @@
package containerd
import (
"sync"
"golang.org/x/net/context"
)
func NewSupervisor(ctx context.Context, runtimes map[string]Runtime) (*Supervisor, error) {
c, err := newCollector(ctx, runtimes)
if err != nil {
return nil, err
}
s := &Supervisor{
containers: make(map[string]Container),
runtimes: runtimes,
collector: c,
}
for _, r := range runtimes {
containers, err := r.Containers()
if err != nil {
return nil, err
}
for _, c := range containers {
s.containers[c.Info().ID] = c
}
}
return s, nil
}
// Supervisor supervises containers and events from multiple runtimes
type Supervisor struct {
mu sync.Mutex
containers map[string]Container
runtimes map[string]Runtime
collector *collector
}
// ForwardEvents is a blocking method that will forward all events from the supervisor
// to the EventWriter provided by the caller
func (s *Supervisor) ForwardEvents(w EventWriter) error {
return s.collector.forward(w)
}
// Create creates a new container with the provided runtime
func (s *Supervisor) Create(ctx context.Context, id, runtime string, opts CreateOpts) (Container, error) {
r, ok := s.runtimes[runtime]
if !ok {
return nil, ErrUnknownRuntime
}
// check to make sure the container's id is unique across the entire system
s.mu.Lock()
defer s.mu.Unlock()
if _, ok := s.containers[id]; ok {
return nil, ErrContainerExists
}
c, err := r.Create(ctx, id, opts)
if err != nil {
return nil, err
}
s.containers[c.Info().ID] = c
return c, nil
}
// Delete deletes the container
func (s *Supervisor) Delete(ctx context.Context, id string) error {
s.mu.Lock()
defer s.mu.Unlock()
c, ok := s.containers[id]
if !ok {
return ErrContainerNotExist
}
err := s.runtimes[c.Info().Runtime].Delete(ctx, c)
if err != nil {
return err
}
delete(s.containers, id)
return nil
}
// Containers returns all the containers for the supervisor
func (s *Supervisor) Containers() (o []Container) {
s.mu.Lock()
defer s.mu.Unlock()
for _, c := range s.containers {
o = append(o, c)
}
return o
}
func (s *Supervisor) Get(id string) (Container, error) {
s.mu.Lock()
c, ok := s.containers[id]
s.mu.Unlock()
if !ok {
return nil, ErrContainerNotExist
}
return c, nil
}

View file

@ -1,354 +0,0 @@
package supervisor
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"sync"
"time"
executionapi "github.com/docker/containerd/api/services/execution"
"github.com/docker/containerd/api/services/shim"
"github.com/docker/containerd/api/types/container"
"github.com/docker/containerd/api/types/process"
"github.com/docker/containerd/events"
"github.com/docker/containerd/execution"
"github.com/docker/containerd/log"
google_protobuf "github.com/golang/protobuf/ptypes/empty"
"github.com/pkg/errors"
"golang.org/x/net/context"
)
var (
_ = (executionapi.ExecutionServiceServer)(&Service{})
empty = &google_protobuf.Empty{}
)
// New creates a new GRPC services for execution
func New(ctx context.Context, root string) (*Service, error) {
ctx = log.WithModule(ctx, "supervisor")
log.G(ctx).WithField("root", root).Debugf("New()")
if err := os.MkdirAll(root, 0700); err != nil {
return nil, errors.Wrapf(err, "unable to create root directory %q", root)
}
clients, err := loadClients(ctx, root)
if err != nil {
return nil, err
}
s := &Service{
root: root,
shims: clients,
ctx: ctx,
}
for _, c := range clients {
if err := s.monitor(events.GetPoster(ctx), c); err != nil {
return nil, err
}
}
return s, nil
}
type Service struct {
mu sync.Mutex
ctx context.Context
root string
shims map[string]*shimClient
}
func (s *Service) propagateRuntimeLog(client *shimClient, entries int) {
logs, err := client.readRuntimeLogEntries(entries)
if err != nil {
log.G(s.ctx).WithError(err).WithField("container", client.id).
Warnf("failed to read shim log")
return
}
log.G(s.ctx).WithField("container", client.id).
Warnf("shim log (last %d entry): %v", entries, logs)
}
func (s *Service) CreateContainer(ctx context.Context, r *executionapi.CreateContainerRequest) (*executionapi.CreateContainerResponse, error) {
client, err := s.newShim(r.ID)
if err != nil {
return nil, err
}
defer func() {
if err != nil {
s.propagateRuntimeLog(client, 1)
s.removeShim(r.ID)
}
}()
if err := s.monitor(events.GetPoster(ctx), client); err != nil {
return nil, err
}
createResponse, err := client.Create(ctx, &shim.CreateRequest{
ID: r.ID,
Bundle: r.BundlePath,
Terminal: r.Console,
Stdin: r.Stdin,
Stdout: r.Stdout,
Stderr: r.Stderr,
})
if err != nil {
return nil, errors.Wrapf(err, "shim create request failed")
}
client.initPid = createResponse.Pid
return &executionapi.CreateContainerResponse{
Container: &container.Container{
ID: r.ID,
},
InitProcess: &process.Process{
Pid: createResponse.Pid,
},
}, nil
}
func (s *Service) StartContainer(ctx context.Context, r *executionapi.StartContainerRequest) (*google_protobuf.Empty, error) {
client, err := s.getShim(r.ID)
if err != nil {
return nil, err
}
if _, err := client.Start(ctx, &shim.StartRequest{}); err != nil {
return nil, err
}
return empty, nil
}
func (s *Service) DeleteContainer(ctx context.Context, r *executionapi.DeleteContainerRequest) (*google_protobuf.Empty, error) {
client, err := s.getShim(r.ID)
if err != nil {
return nil, err
}
_, err = client.Delete(ctx, &shim.DeleteRequest{
Pid: client.initPid,
})
if err != nil {
return nil, err
}
s.removeShim(r.ID)
return empty, nil
}
func (s *Service) ListContainers(ctx context.Context, r *executionapi.ListContainersRequest) (*executionapi.ListContainersResponse, error) {
resp := &executionapi.ListContainersResponse{}
for _, client := range s.shims {
status, err := client.State(ctx, &shim.StateRequest{})
if err != nil {
return nil, err
}
resp.Containers = append(resp.Containers, &container.Container{
ID: status.ID,
Bundle: status.Bundle,
})
}
return resp, nil
}
func (s *Service) GetContainer(ctx context.Context, r *executionapi.GetContainerRequest) (*executionapi.GetContainerResponse, error) {
client, err := s.getShim(r.ID)
if err != nil {
return nil, err
}
state, err := client.State(ctx, &shim.StateRequest{})
if err != nil {
return nil, err
}
return &executionapi.GetContainerResponse{
Container: &container.Container{
ID: state.ID,
Bundle: state.Bundle,
// TODO: add processes
},
}, nil
}
func (s *Service) UpdateContainer(ctx context.Context, r *executionapi.UpdateContainerRequest) (*google_protobuf.Empty, error) {
panic("not implemented")
return empty, nil
}
func (s *Service) PauseContainer(ctx context.Context, r *executionapi.PauseContainerRequest) (*google_protobuf.Empty, error) {
client, err := s.getShim(r.ID)
if err != nil {
return nil, err
}
return client.Pause(ctx, &shim.PauseRequest{})
}
func (s *Service) ResumeContainer(ctx context.Context, r *executionapi.ResumeContainerRequest) (*google_protobuf.Empty, error) {
client, err := s.getShim(r.ID)
if err != nil {
return nil, err
}
return client.Resume(ctx, &shim.ResumeRequest{})
}
func (s *Service) StartProcess(ctx context.Context, r *executionapi.StartProcessRequest) (*executionapi.StartProcessResponse, error) {
client, err := s.getShim(r.ContainerID)
if err != nil {
return nil, err
}
er := &shim.ExecRequest{
Terminal: r.Console,
Stdin: r.Stdin,
Stdout: r.Stdout,
Stderr: r.Stderr,
Args: r.Process.Args,
Env: r.Process.Env,
Cwd: r.Process.Cwd,
}
if r.Process.User != nil {
er.User.Uid = r.Process.User.Uid
er.User.Gid = r.Process.User.Gid
er.User.AdditionalGids = r.Process.User.AdditionalGids
}
resp, err := client.Exec(ctx, er)
if err != nil {
return nil, errors.Wrapf(err, "failed to exec into container %q", r.ContainerID)
}
r.Process.Pid = resp.Pid
return &executionapi.StartProcessResponse{
Process: r.Process,
}, nil
}
// containerd managed execs + system pids forked in container
func (s *Service) GetProcess(ctx context.Context, r *executionapi.GetProcessRequest) (*executionapi.GetProcessResponse, error) {
panic("not implemented")
}
func (s *Service) SignalProcess(ctx context.Context, r *executionapi.SignalProcessRequest) (*google_protobuf.Empty, error) {
panic("not implemented")
}
func (s *Service) DeleteProcess(ctx context.Context, r *executionapi.DeleteProcessRequest) (*google_protobuf.Empty, error) {
client, err := s.getShim(r.ContainerID)
if err != nil {
return nil, err
}
_, err = client.Delete(ctx, &shim.DeleteRequest{
Pid: r.Pid,
})
if err != nil {
return nil, err
}
if r.Pid == client.initPid {
s.removeShim(r.ContainerID)
}
return empty, nil
}
func (s *Service) ListProcesses(ctx context.Context, r *executionapi.ListProcessesRequest) (*executionapi.ListProcessesResponse, error) {
panic("not implemented")
}
// monitor monitors the shim's event rpc and forwards container and process
// events to callers
func (s *Service) monitor(poster events.Poster, client *shimClient) error {
// we use the service context here because we don't want to be
// tied to the Create rpc call
stream, err := client.Events(s.ctx, &shim.EventsRequest{})
if err != nil {
return errors.Wrapf(err, "failed to get events stream for client at %q", client.root)
}
go func() {
for {
e, err := stream.Recv()
if err != nil {
if err.Error() == "EOF" || strings.Contains(err.Error(), "transport is closing") {
break
}
log.G(s.ctx).WithError(err).WithField("container", client.id).
Warnf("event stream for client at %q got terminated", client.root)
break
}
var topic string
if e.Type == shim.EventType_CREATE {
topic = "containers"
} else {
topic = fmt.Sprintf("containers.%s", e.ID)
}
ctx := events.WithTopic(s.ctx, topic)
poster.Post(ctx, execution.ContainerEvent{
Timestamp: time.Now(),
ID: e.ID,
Type: toExecutionEventType(e.Type),
Pid: e.Pid,
ExitStatus: e.ExitStatus,
})
}
}()
return nil
}
func (s *Service) newShim(id string) (*shimClient, error) {
s.mu.Lock()
defer s.mu.Unlock()
if _, ok := s.shims[id]; ok {
return nil, errors.Errorf("container %q already exists", id)
}
client, err := newShimClient(filepath.Join(s.root, id), id)
if err != nil {
return nil, err
}
s.shims[id] = client
return client, nil
}
func (s *Service) getShim(id string) (*shimClient, error) {
s.mu.Lock()
defer s.mu.Unlock()
client, ok := s.shims[id]
if !ok {
return nil, fmt.Errorf("container does not exist %q", id)
}
return client, nil
}
func (s *Service) removeShim(id string) {
s.mu.Lock()
defer s.mu.Unlock()
client, ok := s.shims[id]
if ok {
client.stop()
delete(s.shims, id)
}
}
func loadClients(ctx context.Context, root string) (map[string]*shimClient, error) {
files, err := ioutil.ReadDir(root)
if err != nil {
return nil, err
}
out := make(map[string]*shimClient)
for _, f := range files {
if !f.IsDir() {
continue
}
//
id := f.Name()
client, err := loadShimClient(filepath.Join(root, id), id)
if err != nil {
log.G(ctx).WithError(err).WithField("id", id).Warn("failed to load container")
// TODO: send an exit event with 255 as exit status
continue
}
out[f.Name()] = client
}
return out, nil
}
func toExecutionEventType(et shim.EventType) string {
return strings.Replace(strings.ToLower(et.String()), "_", "-", -1)
}

View file

@ -1,160 +0,0 @@
package supervisor
import (
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"net"
"os"
"os/exec"
"path/filepath"
"strings"
"syscall"
"time"
"github.com/docker/containerd/api/services/shim"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
)
func newShimClient(root, id string) (*shimClient, error) {
if err := os.Mkdir(root, 0700); err != nil {
return nil, errors.Wrap(err, "failed to create shim working dir")
}
cmd := exec.Command("containerd-shim")
cmd.Dir = root
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}
if err := cmd.Start(); err != nil {
return nil, errors.Wrapf(err, "failed to start shim")
}
socket := filepath.Join(root, "shim.sock")
sc, err := connectToShim(socket)
if err != nil {
syscall.Kill(cmd.Process.Pid, syscall.SIGKILL)
cmd.Wait()
return nil, err
}
s := &shimClient{
ShimClient: sc,
shimCmd: cmd,
syncCh: make(chan struct{}),
root: root,
id: id,
}
go func() {
cmd.Wait()
close(s.syncCh)
}()
return s, nil
}
func loadShimClient(root, id string) (*shimClient, error) {
socket := filepath.Join(root, "shim.sock")
client, err := connectToShim(socket)
if err != nil {
// TODO: failed to connect to the shim, check if it's alive
// - if it is kill it
// - in both case call runc killall and runc delete on the id
return nil, err
}
resp, err := client.State(context.Background(), &shim.StateRequest{})
if err != nil {
return nil, errors.Wrapf(err, "failed to fetch state for container %s", id)
}
return &shimClient{
ShimClient: client,
root: root,
id: id,
initPid: resp.InitPid,
}, nil
}
type shimClient struct {
shim.ShimClient
shimCmd *exec.Cmd
syncCh chan struct{}
root string
id string
initPid uint32
}
func (s *shimClient) stop() {
if s.shimCmd != nil {
select {
case <-s.syncCh:
default:
syscall.Kill(s.shimCmd.Process.Pid, syscall.SIGTERM)
select {
case <-s.syncCh:
case <-time.After(10 * time.Second):
syscall.Kill(s.shimCmd.Process.Pid, syscall.SIGKILL)
}
}
}
os.RemoveAll(s.root)
}
func (s *shimClient) readRuntimeLogEntries(lastEntries int) ([]map[string]interface{}, error) {
f, err := os.Open(filepath.Join(s.root, "log.json"))
if err != nil {
return nil, err
}
defer f.Close()
return parseRuntimeLog(f, lastEntries)
}
// parseRuntimeLog parses log.json.
// If lastEntries is greater than 0, only some last entries are returned.
func parseRuntimeLog(r io.Reader, lastEntries int) ([]map[string]interface{}, error) {
b, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
lines := strings.Split(string(b), "\n")
if lastEntries > 0 {
lines = lines[len(lines)-lastEntries-1 : len(lines)]
}
var entries []map[string]interface{}
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" {
continue
}
var entry map[string]interface{}
if err := json.Unmarshal([]byte(line), &entry); err != nil {
return nil, errors.Wrapf(err, "cannot unmarshal JSON string %q", line)
}
entries = append(entries, entry)
}
return entries, nil
}
func connectToShim(socket string) (shim.ShimClient, error) {
// reset the logger for grpc to log to dev/null so that it does not mess with our stdio
grpclog.SetLogger(log.New(ioutil.Discard, "", log.LstdFlags))
dialOpts := []grpc.DialOption{grpc.WithInsecure(), grpc.WithTimeout(100 * time.Second)}
dialOpts = append(dialOpts,
grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
return net.DialTimeout("unix", socket, timeout)
}),
grpc.WithBlock(),
grpc.WithTimeout(2*time.Second),
)
conn, err := grpc.Dial(fmt.Sprintf("unix://%s", socket), dialOpts...)
if err != nil {
return nil, errors.Wrapf(err, "failed to connect to shim via \"%s\"", fmt.Sprintf("unix://%s", socket))
}
return shim.NewShimClient(conn), nil
}

View file

@ -1,47 +0,0 @@
package supervisor
import (
"reflect"
"strings"
"testing"
)
func TestParseRuntimeLog(t *testing.T) {
s := `{"level": "error", "msg": "foo\n", "time": "2017-01-01T00:00:42Z"}
{"level": "error", "msg": "bar\n", "time": "2017-01-01T00:00:43Z"}
`
testCases := []struct {
entries int
expected []map[string]interface{}
}{
{
entries: 0,
expected: []map[string]interface{}{
map[string]interface{}{"level": "error", "msg": "foo\n", "time": "2017-01-01T00:00:42Z"},
map[string]interface{}{"level": "error", "msg": "bar\n", "time": "2017-01-01T00:00:43Z"},
},
},
{
entries: 1,
expected: []map[string]interface{}{
map[string]interface{}{"level": "error", "msg": "bar\n", "time": "2017-01-01T00:00:43Z"}},
},
{
entries: 2,
expected: []map[string]interface{}{
map[string]interface{}{"level": "error", "msg": "foo\n", "time": "2017-01-01T00:00:42Z"},
map[string]interface{}{"level": "error", "msg": "bar\n", "time": "2017-01-01T00:00:43Z"},
},
},
}
for _, tc := range testCases {
got, err := parseRuntimeLog(strings.NewReader(s), tc.entries)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(tc.expected, got) {
t.Fatalf("expected %v, got %v", tc.expected, got)
}
}
}

View file

@ -1,66 +0,0 @@
package term
import (
"fmt"
"strings"
)
// ASCII list the possible supported ASCII key sequence
var ASCII = []string{
"ctrl-@",
"ctrl-a",
"ctrl-b",
"ctrl-c",
"ctrl-d",
"ctrl-e",
"ctrl-f",
"ctrl-g",
"ctrl-h",
"ctrl-i",
"ctrl-j",
"ctrl-k",
"ctrl-l",
"ctrl-m",
"ctrl-n",
"ctrl-o",
"ctrl-p",
"ctrl-q",
"ctrl-r",
"ctrl-s",
"ctrl-t",
"ctrl-u",
"ctrl-v",
"ctrl-w",
"ctrl-x",
"ctrl-y",
"ctrl-z",
"ctrl-[",
"ctrl-\\",
"ctrl-]",
"ctrl-^",
"ctrl-_",
}
// ToBytes converts a string representing a suite of key-sequence to the corresponding ASCII code.
func ToBytes(keys string) ([]byte, error) {
codes := []byte{}
next:
for _, key := range strings.Split(keys, ",") {
if len(key) != 1 {
for code, ctrl := range ASCII {
if ctrl == key {
codes = append(codes, byte(code))
continue next
}
}
if key == "DEL" {
codes = append(codes, 127)
} else {
return nil, fmt.Errorf("Unknown character: '%s'", key)
}
} else {
codes = append(codes, byte(key[0]))
}
}
return codes, nil
}

View file

@ -1,50 +0,0 @@
// +build linux,cgo
package term
import (
"syscall"
"unsafe"
)
// #include <termios.h>
import "C"
// Termios is the Unix API for terminal I/O.
// It is passthrough for syscall.Termios in order to make it portable with
// other platforms where it is not available or handled differently.
type Termios syscall.Termios
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd uintptr) (*State, error) {
var oldState State
if err := tcget(fd, &oldState.termios); err != 0 {
return nil, err
}
newState := oldState.termios
C.cfmakeraw((*C.struct_termios)(unsafe.Pointer(&newState)))
if err := tcset(fd, &newState); err != 0 {
return nil, err
}
return &oldState, nil
}
func tcget(fd uintptr, p *Termios) syscall.Errno {
ret, err := C.tcgetattr(C.int(fd), (*C.struct_termios)(unsafe.Pointer(p)))
if ret != 0 {
return err.(syscall.Errno)
}
return 0
}
func tcset(fd uintptr, p *Termios) syscall.Errno {
ret, err := C.tcsetattr(C.int(fd), C.TCSANOW, (*C.struct_termios)(unsafe.Pointer(p)))
if ret != 0 {
return err.(syscall.Errno)
}
return 0
}

View file

@ -1,20 +0,0 @@
// +build !windows
// +build !linux !cgo
// +build !solaris !cgo
package term
import (
"syscall"
"unsafe"
)
func tcget(fd uintptr, p *Termios) syscall.Errno {
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(p)))
return err
}
func tcset(fd uintptr, p *Termios) syscall.Errno {
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(p)))
return err
}

View file

@ -1,63 +0,0 @@
// +build solaris,cgo
package term
import (
"syscall"
"unsafe"
)
// #include <termios.h>
import "C"
// Termios is the Unix API for terminal I/O.
// It is passthrough for syscall.Termios in order to make it portable with
// other platforms where it is not available or handled differently.
type Termios syscall.Termios
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd uintptr) (*State, error) {
var oldState State
if err := tcget(fd, &oldState.termios); err != 0 {
return nil, err
}
newState := oldState.termios
newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON | syscall.IXANY)
newState.Oflag &^= syscall.OPOST
newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN)
newState.Cflag &^= (syscall.CSIZE | syscall.PARENB)
newState.Cflag |= syscall.CS8
/*
VMIN is the minimum number of characters that needs to be read in non-canonical mode for it to be returned
Since VMIN is overloaded with another element in canonical mode when we switch modes it defaults to 4. It
needs to be explicitly set to 1.
*/
newState.Cc[C.VMIN] = 1
newState.Cc[C.VTIME] = 0
if err := tcset(fd, &newState); err != 0 {
return nil, err
}
return &oldState, nil
}
func tcget(fd uintptr, p *Termios) syscall.Errno {
ret, err := C.tcgetattr(C.int(fd), (*C.struct_termios)(unsafe.Pointer(p)))
if ret != 0 {
return err.(syscall.Errno)
}
return 0
}
func tcset(fd uintptr, p *Termios) syscall.Errno {
ret, err := C.tcsetattr(C.int(fd), C.TCSANOW, (*C.struct_termios)(unsafe.Pointer(p)))
if ret != 0 {
return err.(syscall.Errno)
}
return 0
}

View file

@ -1,123 +0,0 @@
// +build !windows
// Package term provides structures and helper functions to work with
// terminal (state, sizes).
package term
import (
"errors"
"fmt"
"io"
"os"
"os/signal"
"syscall"
)
var (
// ErrInvalidState is returned if the state of the terminal is invalid.
ErrInvalidState = errors.New("Invalid terminal state")
)
// State represents the state of the terminal.
type State struct {
termios Termios
}
// Winsize represents the size of the terminal window.
type Winsize struct {
Height uint16
Width uint16
x uint16
y uint16
}
// StdStreams returns the standard streams (stdin, stdout, stedrr).
func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
return os.Stdin, os.Stdout, os.Stderr
}
// GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal.
func GetFdInfo(in interface{}) (uintptr, bool) {
var inFd uintptr
var isTerminalIn bool
if file, ok := in.(*os.File); ok {
inFd = file.Fd()
isTerminalIn = IsTerminal(inFd)
}
return inFd, isTerminalIn
}
// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd uintptr) bool {
var termios Termios
return tcget(fd, &termios) == 0
}
// RestoreTerminal restores the terminal connected to the given file descriptor
// to a previous state.
func RestoreTerminal(fd uintptr, state *State) error {
if state == nil {
return ErrInvalidState
}
if err := tcset(fd, &state.termios); err != 0 {
return err
}
return nil
}
// SaveState saves the state of the terminal connected to the given file descriptor.
func SaveState(fd uintptr) (*State, error) {
var oldState State
if err := tcget(fd, &oldState.termios); err != 0 {
return nil, err
}
return &oldState, nil
}
// DisableEcho applies the specified state to the terminal connected to the file
// descriptor, with echo disabled.
func DisableEcho(fd uintptr, state *State) error {
newState := state.termios
newState.Lflag &^= syscall.ECHO
if err := tcset(fd, &newState); err != 0 {
return err
}
handleInterrupt(fd, state)
return nil
}
// SetRawTerminal puts the terminal connected to the given file descriptor into
// raw mode and returns the previous state. On UNIX, this puts both the input
// and output into raw mode. On Windows, it only puts the input into raw mode.
func SetRawTerminal(fd uintptr) (*State, error) {
oldState, err := MakeRaw(fd)
if err != nil {
return nil, err
}
handleInterrupt(fd, oldState)
return oldState, err
}
// SetRawTerminalOutput puts the output of terminal connected to the given file
// descriptor into raw mode. On UNIX, this does nothing and returns nil for the
// state. On Windows, it disables LF -> CRLF translation.
func SetRawTerminalOutput(fd uintptr) (*State, error) {
return nil, nil
}
func handleInterrupt(fd uintptr, state *State) {
sigchan := make(chan os.Signal, 1)
signal.Notify(sigchan, os.Interrupt)
go func() {
for range sigchan {
// quit cleanly and the new terminal item is on a new line
fmt.Println()
signal.Stop(sigchan)
close(sigchan)
RestoreTerminal(fd, state)
os.Exit(1)
}
}()
}

View file

@ -1,41 +0,0 @@
// +build solaris
package term
import (
"syscall"
"unsafe"
)
/*
#include <unistd.h>
#include <stropts.h>
#include <termios.h>
// Small wrapper to get rid of variadic args of ioctl()
int my_ioctl(int fd, int cmd, struct winsize *ws) {
return ioctl(fd, cmd, ws);
}
*/
import "C"
// GetWinsize returns the window size based on the specified file descriptor.
func GetWinsize(fd uintptr) (*Winsize, error) {
ws := &Winsize{}
ret, err := C.my_ioctl(C.int(fd), C.int(syscall.TIOCGWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
// Skip retval = 0
if ret == 0 {
return ws, nil
}
return ws, err
}
// SetWinsize tries to set the specified window size for the specified file descriptor.
func SetWinsize(fd uintptr, ws *Winsize) error {
ret, err := C.my_ioctl(C.int(fd), C.int(syscall.TIOCSWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
// Skip retval = 0
if ret == 0 {
return nil
}
return err
}

View file

@ -1,29 +0,0 @@
// +build !solaris,!windows
package term
import (
"syscall"
"unsafe"
)
// GetWinsize returns the window size based on the specified file descriptor.
func GetWinsize(fd uintptr) (*Winsize, error) {
ws := &Winsize{}
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(ws)))
// Skipp errno = 0
if err == 0 {
return ws, nil
}
return ws, err
}
// SetWinsize tries to set the specified window size for the specified file descriptor.
func SetWinsize(fd uintptr, ws *Winsize) error {
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(ws)))
// Skipp errno = 0
if err == 0 {
return nil
}
return err
}

View file

@ -1,233 +0,0 @@
// +build windows
package term
import (
"io"
"os"
"os/signal"
"syscall"
"github.com/Azure/go-ansiterm/winterm"
"github.com/docker/docker/pkg/term/windows"
)
// State holds the console mode for the terminal.
type State struct {
mode uint32
}
// Winsize is used for window size.
type Winsize struct {
Height uint16
Width uint16
}
const (
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx
enableVirtualTerminalInput = 0x0200
enableVirtualTerminalProcessing = 0x0004
disableNewlineAutoReturn = 0x0008
)
// vtInputSupported is true if enableVirtualTerminalInput is supported by the console
var vtInputSupported bool
// StdStreams returns the standard streams (stdin, stdout, stedrr).
func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
// Turn on VT handling on all std handles, if possible. This might
// fail, in which case we will fall back to terminal emulation.
var emulateStdin, emulateStdout, emulateStderr bool
fd := os.Stdin.Fd()
if mode, err := winterm.GetConsoleMode(fd); err == nil {
// Validate that enableVirtualTerminalInput is supported, but do not set it.
if err = winterm.SetConsoleMode(fd, mode|enableVirtualTerminalInput); err != nil {
emulateStdin = true
} else {
vtInputSupported = true
}
// Unconditionally set the console mode back even on failure because SetConsoleMode
// remembers invalid bits on input handles.
winterm.SetConsoleMode(fd, mode)
}
fd = os.Stdout.Fd()
if mode, err := winterm.GetConsoleMode(fd); err == nil {
// Validate disableNewlineAutoReturn is supported, but do not set it.
if err = winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing|disableNewlineAutoReturn); err != nil {
emulateStdout = true
} else {
winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing)
}
}
fd = os.Stderr.Fd()
if mode, err := winterm.GetConsoleMode(fd); err == nil {
// Validate disableNewlineAutoReturn is supported, but do not set it.
if err = winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing|disableNewlineAutoReturn); err != nil {
emulateStderr = true
} else {
winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing)
}
}
if os.Getenv("ConEmuANSI") == "ON" || os.Getenv("ConsoleZVersion") != "" {
// The ConEmu and ConsoleZ terminals emulate ANSI on output streams well.
emulateStdin = true
emulateStdout = false
emulateStderr = false
}
if emulateStdin {
stdIn = windows.NewAnsiReader(syscall.STD_INPUT_HANDLE)
} else {
stdIn = os.Stdin
}
if emulateStdout {
stdOut = windows.NewAnsiWriter(syscall.STD_OUTPUT_HANDLE)
} else {
stdOut = os.Stdout
}
if emulateStderr {
stdErr = windows.NewAnsiWriter(syscall.STD_ERROR_HANDLE)
} else {
stdErr = os.Stderr
}
return
}
// GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal.
func GetFdInfo(in interface{}) (uintptr, bool) {
return windows.GetHandleInfo(in)
}
// GetWinsize returns the window size based on the specified file descriptor.
func GetWinsize(fd uintptr) (*Winsize, error) {
info, err := winterm.GetConsoleScreenBufferInfo(fd)
if err != nil {
return nil, err
}
winsize := &Winsize{
Width: uint16(info.Window.Right - info.Window.Left + 1),
Height: uint16(info.Window.Bottom - info.Window.Top + 1),
}
return winsize, nil
}
// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd uintptr) bool {
return windows.IsConsole(fd)
}
// RestoreTerminal restores the terminal connected to the given file descriptor
// to a previous state.
func RestoreTerminal(fd uintptr, state *State) error {
return winterm.SetConsoleMode(fd, state.mode)
}
// SaveState saves the state of the terminal connected to the given file descriptor.
func SaveState(fd uintptr) (*State, error) {
mode, e := winterm.GetConsoleMode(fd)
if e != nil {
return nil, e
}
return &State{mode: mode}, nil
}
// DisableEcho disables echo for the terminal connected to the given file descriptor.
// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx
func DisableEcho(fd uintptr, state *State) error {
mode := state.mode
mode &^= winterm.ENABLE_ECHO_INPUT
mode |= winterm.ENABLE_PROCESSED_INPUT | winterm.ENABLE_LINE_INPUT
err := winterm.SetConsoleMode(fd, mode)
if err != nil {
return err
}
// Register an interrupt handler to catch and restore prior state
restoreAtInterrupt(fd, state)
return nil
}
// SetRawTerminal puts the terminal connected to the given file descriptor into
// raw mode and returns the previous state. On UNIX, this puts both the input
// and output into raw mode. On Windows, it only puts the input into raw mode.
func SetRawTerminal(fd uintptr) (*State, error) {
state, err := MakeRaw(fd)
if err != nil {
return nil, err
}
// Register an interrupt handler to catch and restore prior state
restoreAtInterrupt(fd, state)
return state, err
}
// SetRawTerminalOutput puts the output of terminal connected to the given file
// descriptor into raw mode. On UNIX, this does nothing and returns nil for the
// state. On Windows, it disables LF -> CRLF translation.
func SetRawTerminalOutput(fd uintptr) (*State, error) {
state, err := SaveState(fd)
if err != nil {
return nil, err
}
// Ignore failures, since disableNewlineAutoReturn might not be supported on this
// version of Windows.
winterm.SetConsoleMode(fd, state.mode|disableNewlineAutoReturn)
return state, err
}
// MakeRaw puts the terminal (Windows Console) connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be restored.
func MakeRaw(fd uintptr) (*State, error) {
state, err := SaveState(fd)
if err != nil {
return nil, err
}
mode := state.mode
// See
// -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
// -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx
// Disable these modes
mode &^= winterm.ENABLE_ECHO_INPUT
mode &^= winterm.ENABLE_LINE_INPUT
mode &^= winterm.ENABLE_MOUSE_INPUT
mode &^= winterm.ENABLE_WINDOW_INPUT
mode &^= winterm.ENABLE_PROCESSED_INPUT
// Enable these modes
mode |= winterm.ENABLE_EXTENDED_FLAGS
mode |= winterm.ENABLE_INSERT_MODE
mode |= winterm.ENABLE_QUICK_EDIT_MODE
if vtInputSupported {
mode |= enableVirtualTerminalInput
}
err = winterm.SetConsoleMode(fd, mode)
if err != nil {
return nil, err
}
return state, nil
}
func restoreAtInterrupt(fd uintptr, state *State) {
sigchan := make(chan os.Signal, 1)
signal.Notify(sigchan, os.Interrupt)
go func() {
_ = <-sigchan
RestoreTerminal(fd, state)
os.Exit(0)
}()
}

View file

@ -1,69 +0,0 @@
package term
import (
"syscall"
"unsafe"
)
const (
getTermios = syscall.TIOCGETA
setTermios = syscall.TIOCSETA
)
// Termios magic numbers, passthrough to the ones defined in syscall.
const (
IGNBRK = syscall.IGNBRK
PARMRK = syscall.PARMRK
INLCR = syscall.INLCR
IGNCR = syscall.IGNCR
ECHONL = syscall.ECHONL
CSIZE = syscall.CSIZE
ICRNL = syscall.ICRNL
ISTRIP = syscall.ISTRIP
PARENB = syscall.PARENB
ECHO = syscall.ECHO
ICANON = syscall.ICANON
ISIG = syscall.ISIG
IXON = syscall.IXON
BRKINT = syscall.BRKINT
INPCK = syscall.INPCK
OPOST = syscall.OPOST
CS8 = syscall.CS8
IEXTEN = syscall.IEXTEN
)
// Termios is the Unix API for terminal I/O.
type Termios struct {
Iflag uint64
Oflag uint64
Cflag uint64
Lflag uint64
Cc [20]byte
Ispeed uint64
Ospeed uint64
}
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd uintptr) (*State, error) {
var oldState State
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
return nil, err
}
newState := oldState.termios
newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
newState.Oflag &^= OPOST
newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
newState.Cflag &^= (CSIZE | PARENB)
newState.Cflag |= CS8
newState.Cc[syscall.VMIN] = 1
newState.Cc[syscall.VTIME] = 0
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
return nil, err
}
return &oldState, nil
}

View file

@ -1,69 +0,0 @@
package term
import (
"syscall"
"unsafe"
)
const (
getTermios = syscall.TIOCGETA
setTermios = syscall.TIOCSETA
)
// Termios magic numbers, passthrough to the ones defined in syscall.
const (
IGNBRK = syscall.IGNBRK
PARMRK = syscall.PARMRK
INLCR = syscall.INLCR
IGNCR = syscall.IGNCR
ECHONL = syscall.ECHONL
CSIZE = syscall.CSIZE
ICRNL = syscall.ICRNL
ISTRIP = syscall.ISTRIP
PARENB = syscall.PARENB
ECHO = syscall.ECHO
ICANON = syscall.ICANON
ISIG = syscall.ISIG
IXON = syscall.IXON
BRKINT = syscall.BRKINT
INPCK = syscall.INPCK
OPOST = syscall.OPOST
CS8 = syscall.CS8
IEXTEN = syscall.IEXTEN
)
// Termios is the Unix API for terminal I/O.
type Termios struct {
Iflag uint32
Oflag uint32
Cflag uint32
Lflag uint32
Cc [20]byte
Ispeed uint32
Ospeed uint32
}
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd uintptr) (*State, error) {
var oldState State
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
return nil, err
}
newState := oldState.termios
newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
newState.Oflag &^= OPOST
newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
newState.Cflag &^= (CSIZE | PARENB)
newState.Cflag |= CS8
newState.Cc[syscall.VMIN] = 1
newState.Cc[syscall.VTIME] = 0
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
return nil, err
}
return &oldState, nil
}

View file

@ -1,47 +0,0 @@
// +build !cgo
package term
import (
"syscall"
"unsafe"
)
const (
getTermios = syscall.TCGETS
setTermios = syscall.TCSETS
)
// Termios is the Unix API for terminal I/O.
type Termios struct {
Iflag uint32
Oflag uint32
Cflag uint32
Lflag uint32
Cc [20]byte
Ispeed uint32
Ospeed uint32
}
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd uintptr) (*State, error) {
var oldState State
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
return nil, err
}
newState := oldState.termios
newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON)
newState.Oflag &^= syscall.OPOST
newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN)
newState.Cflag &^= (syscall.CSIZE | syscall.PARENB)
newState.Cflag |= syscall.CS8
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
return nil, err
}
return &oldState, nil
}

View file

@ -1,69 +0,0 @@
package term
import (
"syscall"
"unsafe"
)
const (
getTermios = syscall.TIOCGETA
setTermios = syscall.TIOCSETA
)
// Termios magic numbers, passthrough to the ones defined in syscall.
const (
IGNBRK = syscall.IGNBRK
PARMRK = syscall.PARMRK
INLCR = syscall.INLCR
IGNCR = syscall.IGNCR
ECHONL = syscall.ECHONL
CSIZE = syscall.CSIZE
ICRNL = syscall.ICRNL
ISTRIP = syscall.ISTRIP
PARENB = syscall.PARENB
ECHO = syscall.ECHO
ICANON = syscall.ICANON
ISIG = syscall.ISIG
IXON = syscall.IXON
BRKINT = syscall.BRKINT
INPCK = syscall.INPCK
OPOST = syscall.OPOST
CS8 = syscall.CS8
IEXTEN = syscall.IEXTEN
)
// Termios is the Unix API for terminal I/O.
type Termios struct {
Iflag uint32
Oflag uint32
Cflag uint32
Lflag uint32
Cc [20]byte
Ispeed uint32
Ospeed uint32
}
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd uintptr) (*State, error) {
var oldState State
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
return nil, err
}
newState := oldState.termios
newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
newState.Oflag &^= OPOST
newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
newState.Cflag &^= (CSIZE | PARENB)
newState.Cflag |= CS8
newState.Cc[syscall.VMIN] = 1
newState.Cc[syscall.VTIME] = 0
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
return nil, err
}
return &oldState, nil
}

View file

@ -1,263 +0,0 @@
// +build windows
package windows
import (
"bytes"
"errors"
"fmt"
"io"
"os"
"strings"
"unsafe"
ansiterm "github.com/Azure/go-ansiterm"
"github.com/Azure/go-ansiterm/winterm"
)
const (
escapeSequence = ansiterm.KEY_ESC_CSI
)
// ansiReader wraps a standard input file (e.g., os.Stdin) providing ANSI sequence translation.
type ansiReader struct {
file *os.File
fd uintptr
buffer []byte
cbBuffer int
command []byte
}
// NewAnsiReader returns an io.ReadCloser that provides VT100 terminal emulation on top of a
// Windows console input handle.
func NewAnsiReader(nFile int) io.ReadCloser {
initLogger()
file, fd := winterm.GetStdFile(nFile)
return &ansiReader{
file: file,
fd: fd,
command: make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH),
buffer: make([]byte, 0),
}
}
// Close closes the wrapped file.
func (ar *ansiReader) Close() (err error) {
return ar.file.Close()
}
// Fd returns the file descriptor of the wrapped file.
func (ar *ansiReader) Fd() uintptr {
return ar.fd
}
// Read reads up to len(p) bytes of translated input events into p.
func (ar *ansiReader) Read(p []byte) (int, error) {
if len(p) == 0 {
return 0, nil
}
// Previously read bytes exist, read as much as we can and return
if len(ar.buffer) > 0 {
logger.Debugf("Reading previously cached bytes")
originalLength := len(ar.buffer)
copiedLength := copy(p, ar.buffer)
if copiedLength == originalLength {
ar.buffer = make([]byte, 0, len(p))
} else {
ar.buffer = ar.buffer[copiedLength:]
}
logger.Debugf("Read from cache p[%d]: % x", copiedLength, p)
return copiedLength, nil
}
// Read and translate key events
events, err := readInputEvents(ar.fd, len(p))
if err != nil {
return 0, err
} else if len(events) == 0 {
logger.Debug("No input events detected")
return 0, nil
}
keyBytes := translateKeyEvents(events, []byte(escapeSequence))
// Save excess bytes and right-size keyBytes
if len(keyBytes) > len(p) {
logger.Debugf("Received %d keyBytes, only room for %d bytes", len(keyBytes), len(p))
ar.buffer = keyBytes[len(p):]
keyBytes = keyBytes[:len(p)]
} else if len(keyBytes) == 0 {
logger.Debug("No key bytes returned from the translator")
return 0, nil
}
copiedLength := copy(p, keyBytes)
if copiedLength != len(keyBytes) {
return 0, errors.New("unexpected copy length encountered")
}
logger.Debugf("Read p[%d]: % x", copiedLength, p)
logger.Debugf("Read keyBytes[%d]: % x", copiedLength, keyBytes)
return copiedLength, nil
}
// readInputEvents polls until at least one event is available.
func readInputEvents(fd uintptr, maxBytes int) ([]winterm.INPUT_RECORD, error) {
// Determine the maximum number of records to retrieve
// -- Cast around the type system to obtain the size of a single INPUT_RECORD.
// unsafe.Sizeof requires an expression vs. a type-reference; the casting
// tricks the type system into believing it has such an expression.
recordSize := int(unsafe.Sizeof(*((*winterm.INPUT_RECORD)(unsafe.Pointer(&maxBytes)))))
countRecords := maxBytes / recordSize
if countRecords > ansiterm.MAX_INPUT_EVENTS {
countRecords = ansiterm.MAX_INPUT_EVENTS
} else if countRecords == 0 {
countRecords = 1
}
logger.Debugf("[windows] readInputEvents: Reading %v records (buffer size %v, record size %v)", countRecords, maxBytes, recordSize)
// Wait for and read input events
events := make([]winterm.INPUT_RECORD, countRecords)
nEvents := uint32(0)
eventsExist, err := winterm.WaitForSingleObject(fd, winterm.WAIT_INFINITE)
if err != nil {
return nil, err
}
if eventsExist {
err = winterm.ReadConsoleInput(fd, events, &nEvents)
if err != nil {
return nil, err
}
}
// Return a slice restricted to the number of returned records
logger.Debugf("[windows] readInputEvents: Read %v events", nEvents)
return events[:nEvents], nil
}
// KeyEvent Translation Helpers
var arrowKeyMapPrefix = map[uint16]string{
winterm.VK_UP: "%s%sA",
winterm.VK_DOWN: "%s%sB",
winterm.VK_RIGHT: "%s%sC",
winterm.VK_LEFT: "%s%sD",
}
var keyMapPrefix = map[uint16]string{
winterm.VK_UP: "\x1B[%sA",
winterm.VK_DOWN: "\x1B[%sB",
winterm.VK_RIGHT: "\x1B[%sC",
winterm.VK_LEFT: "\x1B[%sD",
winterm.VK_HOME: "\x1B[1%s~", // showkey shows ^[[1
winterm.VK_END: "\x1B[4%s~", // showkey shows ^[[4
winterm.VK_INSERT: "\x1B[2%s~",
winterm.VK_DELETE: "\x1B[3%s~",
winterm.VK_PRIOR: "\x1B[5%s~",
winterm.VK_NEXT: "\x1B[6%s~",
winterm.VK_F1: "",
winterm.VK_F2: "",
winterm.VK_F3: "\x1B[13%s~",
winterm.VK_F4: "\x1B[14%s~",
winterm.VK_F5: "\x1B[15%s~",
winterm.VK_F6: "\x1B[17%s~",
winterm.VK_F7: "\x1B[18%s~",
winterm.VK_F8: "\x1B[19%s~",
winterm.VK_F9: "\x1B[20%s~",
winterm.VK_F10: "\x1B[21%s~",
winterm.VK_F11: "\x1B[23%s~",
winterm.VK_F12: "\x1B[24%s~",
}
// translateKeyEvents converts the input events into the appropriate ANSI string.
func translateKeyEvents(events []winterm.INPUT_RECORD, escapeSequence []byte) []byte {
var buffer bytes.Buffer
for _, event := range events {
if event.EventType == winterm.KEY_EVENT && event.KeyEvent.KeyDown != 0 {
buffer.WriteString(keyToString(&event.KeyEvent, escapeSequence))
}
}
return buffer.Bytes()
}
// keyToString maps the given input event record to the corresponding string.
func keyToString(keyEvent *winterm.KEY_EVENT_RECORD, escapeSequence []byte) string {
if keyEvent.UnicodeChar == 0 {
return formatVirtualKey(keyEvent.VirtualKeyCode, keyEvent.ControlKeyState, escapeSequence)
}
_, alt, control := getControlKeys(keyEvent.ControlKeyState)
if control {
// TODO(azlinux): Implement following control sequences
// <Ctrl>-D Signals the end of input from the keyboard; also exits current shell.
// <Ctrl>-H Deletes the first character to the left of the cursor. Also called the ERASE key.
// <Ctrl>-Q Restarts printing after it has been stopped with <Ctrl>-s.
// <Ctrl>-S Suspends printing on the screen (does not stop the program).
// <Ctrl>-U Deletes all characters on the current line. Also called the KILL key.
// <Ctrl>-E Quits current command and creates a core
}
// <Alt>+Key generates ESC N Key
if !control && alt {
return ansiterm.KEY_ESC_N + strings.ToLower(string(keyEvent.UnicodeChar))
}
return string(keyEvent.UnicodeChar)
}
// formatVirtualKey converts a virtual key (e.g., up arrow) into the appropriate ANSI string.
func formatVirtualKey(key uint16, controlState uint32, escapeSequence []byte) string {
shift, alt, control := getControlKeys(controlState)
modifier := getControlKeysModifier(shift, alt, control)
if format, ok := arrowKeyMapPrefix[key]; ok {
return fmt.Sprintf(format, escapeSequence, modifier)
}
if format, ok := keyMapPrefix[key]; ok {
return fmt.Sprintf(format, modifier)
}
return ""
}
// getControlKeys extracts the shift, alt, and ctrl key states.
func getControlKeys(controlState uint32) (shift, alt, control bool) {
shift = 0 != (controlState & winterm.SHIFT_PRESSED)
alt = 0 != (controlState & (winterm.LEFT_ALT_PRESSED | winterm.RIGHT_ALT_PRESSED))
control = 0 != (controlState & (winterm.LEFT_CTRL_PRESSED | winterm.RIGHT_CTRL_PRESSED))
return shift, alt, control
}
// getControlKeysModifier returns the ANSI modifier for the given combination of control keys.
func getControlKeysModifier(shift, alt, control bool) string {
if shift && alt && control {
return ansiterm.KEY_CONTROL_PARAM_8
}
if alt && control {
return ansiterm.KEY_CONTROL_PARAM_7
}
if shift && control {
return ansiterm.KEY_CONTROL_PARAM_6
}
if control {
return ansiterm.KEY_CONTROL_PARAM_5
}
if shift && alt {
return ansiterm.KEY_CONTROL_PARAM_4
}
if alt {
return ansiterm.KEY_CONTROL_PARAM_3
}
if shift {
return ansiterm.KEY_CONTROL_PARAM_2
}
return ""
}

View file

@ -1,64 +0,0 @@
// +build windows
package windows
import (
"io"
"os"
ansiterm "github.com/Azure/go-ansiterm"
"github.com/Azure/go-ansiterm/winterm"
)
// ansiWriter wraps a standard output file (e.g., os.Stdout) providing ANSI sequence translation.
type ansiWriter struct {
file *os.File
fd uintptr
infoReset *winterm.CONSOLE_SCREEN_BUFFER_INFO
command []byte
escapeSequence []byte
inAnsiSequence bool
parser *ansiterm.AnsiParser
}
// NewAnsiWriter returns an io.Writer that provides VT100 terminal emulation on top of a
// Windows console output handle.
func NewAnsiWriter(nFile int) io.Writer {
initLogger()
file, fd := winterm.GetStdFile(nFile)
info, err := winterm.GetConsoleScreenBufferInfo(fd)
if err != nil {
return nil
}
parser := ansiterm.CreateParser("Ground", winterm.CreateWinEventHandler(fd, file))
logger.Infof("newAnsiWriter: parser %p", parser)
aw := &ansiWriter{
file: file,
fd: fd,
infoReset: info,
command: make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH),
escapeSequence: []byte(ansiterm.KEY_ESC_CSI),
parser: parser,
}
logger.Infof("newAnsiWriter: aw.parser %p", aw.parser)
logger.Infof("newAnsiWriter: %v", aw)
return aw
}
func (aw *ansiWriter) Fd() uintptr {
return aw.fd
}
// Write writes len(p) bytes from p to the underlying data stream.
func (aw *ansiWriter) Write(p []byte) (total int, err error) {
if len(p) == 0 {
return 0, nil
}
logger.Infof("Write: % x", p)
logger.Infof("Write: %s", string(p))
return aw.parser.Parse(p)
}

View file

@ -1,35 +0,0 @@
// +build windows
package windows
import (
"os"
"github.com/Azure/go-ansiterm/winterm"
)
// GetHandleInfo returns file descriptor and bool indicating whether the file is a console.
func GetHandleInfo(in interface{}) (uintptr, bool) {
switch t := in.(type) {
case *ansiReader:
return t.Fd(), true
case *ansiWriter:
return t.Fd(), true
}
var inFd uintptr
var isTerminal bool
if file, ok := in.(*os.File); ok {
inFd = file.Fd()
isTerminal = IsConsole(inFd)
}
return inFd, isTerminal
}
// IsConsole returns true if the given file descriptor is a Windows Console.
// The code assumes that GetConsoleMode will return an error for file descriptors that are not a console.
func IsConsole(fd uintptr) bool {
_, e := winterm.GetConsoleMode(fd)
return e == nil
}

View file

@ -1,33 +0,0 @@
// These files implement ANSI-aware input and output streams for use by the Docker Windows client.
// When asked for the set of standard streams (e.g., stdin, stdout, stderr), the code will create
// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls.
package windows
import (
"io/ioutil"
"os"
"sync"
ansiterm "github.com/Azure/go-ansiterm"
"github.com/Sirupsen/logrus"
)
var logger *logrus.Logger
var initOnce sync.Once
func initLogger() {
initOnce.Do(func() {
logFile := ioutil.Discard
if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" {
logFile, _ = os.Create("ansiReaderWriter.log")
}
logger = &logrus.Logger{
Out: logFile,
Formatter: new(logrus.TextFormatter),
Level: logrus.DebugLevel,
}
})
}

101
vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go generated vendored Normal file
View file

@ -0,0 +1,101 @@
// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
// http://github.com/gogo/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package sortkeys
import (
"sort"
)
func Strings(l []string) {
sort.Strings(l)
}
func Float64s(l []float64) {
sort.Float64s(l)
}
func Float32s(l []float32) {
sort.Sort(Float32Slice(l))
}
func Int64s(l []int64) {
sort.Sort(Int64Slice(l))
}
func Int32s(l []int32) {
sort.Sort(Int32Slice(l))
}
func Uint64s(l []uint64) {
sort.Sort(Uint64Slice(l))
}
func Uint32s(l []uint32) {
sort.Sort(Uint32Slice(l))
}
func Bools(l []bool) {
sort.Sort(BoolSlice(l))
}
type BoolSlice []bool
func (p BoolSlice) Len() int { return len(p) }
func (p BoolSlice) Less(i, j int) bool { return p[j] }
func (p BoolSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
type Int64Slice []int64
func (p Int64Slice) Len() int { return len(p) }
func (p Int64Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p Int64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
type Int32Slice []int32
func (p Int32Slice) Len() int { return len(p) }
func (p Int32Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p Int32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
type Uint64Slice []uint64
func (p Uint64Slice) Len() int { return len(p) }
func (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p Uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
type Uint32Slice []uint32
func (p Uint32Slice) Len() int { return len(p) }
func (p Uint32Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p Uint32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
type Float32Slice []float32
func (p Float32Slice) Len() int { return len(p) }
func (p Float32Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p Float32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }

135
vendor/github.com/gogo/protobuf/types/any.go generated vendored Normal file
View file

@ -0,0 +1,135 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package types
// This file implements functions to marshal proto.Message to/from
// google.protobuf.Any message.
import (
"fmt"
"reflect"
"strings"
"github.com/gogo/protobuf/proto"
)
const googleApis = "type.googleapis.com/"
// AnyMessageName returns the name of the message contained in a google.protobuf.Any message.
//
// Note that regular type assertions should be done using the Is
// function. AnyMessageName is provided for less common use cases like filtering a
// sequence of Any messages based on a set of allowed message type names.
func AnyMessageName(any *Any) (string, error) {
slash := strings.LastIndex(any.TypeUrl, "/")
if slash < 0 {
return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl)
}
return any.TypeUrl[slash+1:], nil
}
// MarshalAny takes the protocol buffer and encodes it into google.protobuf.Any.
func MarshalAny(pb proto.Message) (*Any, error) {
value, err := proto.Marshal(pb)
if err != nil {
return nil, err
}
return &Any{TypeUrl: googleApis + proto.MessageName(pb), Value: value}, nil
}
// DynamicAny is a value that can be passed to UnmarshalAny to automatically
// allocate a proto.Message for the type specified in a google.protobuf.Any
// message. The allocated message is stored in the embedded proto.Message.
//
// Example:
//
// var x ptypes.DynamicAny
// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... }
// fmt.Printf("unmarshaled message: %v", x.Message)
type DynamicAny struct {
proto.Message
}
// Empty returns a new proto.Message of the type specified in a
// google.protobuf.Any message. It returns an error if corresponding message
// type isn't linked in.
func EmptyAny(any *Any) (proto.Message, error) {
aname, err := AnyMessageName(any)
if err != nil {
return nil, err
}
t := proto.MessageType(aname)
if t == nil {
return nil, fmt.Errorf("any: message type %q isn't linked in", aname)
}
return reflect.New(t.Elem()).Interface().(proto.Message), nil
}
// UnmarshalAny parses the protocol buffer representation in a google.protobuf.Any
// message and places the decoded result in pb. It returns an error if type of
// contents of Any message does not match type of pb message.
//
// pb can be a proto.Message, or a *DynamicAny.
func UnmarshalAny(any *Any, pb proto.Message) error {
if d, ok := pb.(*DynamicAny); ok {
if d.Message == nil {
var err error
d.Message, err = EmptyAny(any)
if err != nil {
return err
}
}
return UnmarshalAny(any, d.Message)
}
aname, err := AnyMessageName(any)
if err != nil {
return err
}
mname := proto.MessageName(pb)
if aname != mname {
return fmt.Errorf("mismatched message type: got %q want %q", aname, mname)
}
return proto.Unmarshal(any.Value, pb)
}
// Is returns true if any value contains a given message type.
func Is(any *Any, pb proto.Message) bool {
aname, err := AnyMessageName(any)
if err != nil {
return false
}
return aname == proto.MessageName(pb)
}

687
vendor/github.com/gogo/protobuf/types/any.pb.go generated vendored Normal file
View file

@ -0,0 +1,687 @@
// Code generated by protoc-gen-gogo.
// source: any.proto
// DO NOT EDIT!
/*
Package types is a generated protocol buffer package.
It is generated from these files:
any.proto
It has these top-level messages:
Any
*/
package types
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import bytes "bytes"
import strings "strings"
import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto"
import sort "sort"
import strconv "strconv"
import reflect "reflect"
import io "io"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
// `Any` contains an arbitrary serialized protocol buffer message along with a
// URL that describes the type of the serialized message.
//
// Protobuf library provides support to pack/unpack Any values in the form
// of utility functions or additional generated methods of the Any type.
//
// Example 1: Pack and unpack a message in C++.
//
// Foo foo = ...;
// Any any;
// any.PackFrom(foo);
// ...
// if (any.UnpackTo(&foo)) {
// ...
// }
//
// Example 2: Pack and unpack a message in Java.
//
// Foo foo = ...;
// Any any = Any.pack(foo);
// ...
// if (any.is(Foo.class)) {
// foo = any.unpack(Foo.class);
// }
//
// Example 3: Pack and unpack a message in Python.
//
// foo = Foo(...)
// any = Any()
// any.Pack(foo)
// ...
// if any.Is(Foo.DESCRIPTOR):
// any.Unpack(foo)
// ...
//
// The pack methods provided by protobuf library will by default use
// 'type.googleapis.com/full.type.name' as the type URL and the unpack
// methods only use the fully qualified type name after the last '/'
// in the type URL, for example "foo.bar.com/x/y.z" will yield type
// name "y.z".
//
//
// JSON
// ====
// The JSON representation of an `Any` value uses the regular
// representation of the deserialized, embedded message, with an
// additional field `@type` which contains the type URL. Example:
//
// package google.profile;
// message Person {
// string first_name = 1;
// string last_name = 2;
// }
//
// {
// "@type": "type.googleapis.com/google.profile.Person",
// "firstName": <string>,
// "lastName": <string>
// }
//
// If the embedded message type is well-known and has a custom JSON
// representation, that representation will be embedded adding a field
// `value` which holds the custom JSON in addition to the `@type`
// field. Example (for message [google.protobuf.Duration][]):
//
// {
// "@type": "type.googleapis.com/google.protobuf.Duration",
// "value": "1.212s"
// }
//
type Any struct {
// A URL/resource name whose content describes the type of the
// serialized protocol buffer message.
//
// For URLs which use the scheme `http`, `https`, or no scheme, the
// following restrictions and interpretations apply:
//
// * If no scheme is provided, `https` is assumed.
// * The last segment of the URL's path must represent the fully
// qualified name of the type (as in `path/google.protobuf.Duration`).
// The name should be in a canonical form (e.g., leading "." is
// not accepted).
// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
// value in binary format, or produce an error.
// * Applications are allowed to cache lookup results based on the
// URL, or have them precompiled into a binary to avoid any
// lookup. Therefore, binary compatibility needs to be preserved
// on changes to types. (Use versioned type names to manage
// breaking changes.)
//
// Schemes other than `http`, `https` (or the empty scheme) might be
// used with implementation specific semantics.
//
TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"`
// Must be a valid serialized protocol buffer of the above specified type.
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
}
func (m *Any) Reset() { *m = Any{} }
func (*Any) ProtoMessage() {}
func (*Any) Descriptor() ([]byte, []int) { return fileDescriptorAny, []int{0} }
func (*Any) XXX_WellKnownType() string { return "Any" }
func (m *Any) GetTypeUrl() string {
if m != nil {
return m.TypeUrl
}
return ""
}
func (m *Any) GetValue() []byte {
if m != nil {
return m.Value
}
return nil
}
func init() {
proto.RegisterType((*Any)(nil), "google.protobuf.Any")
}
func (this *Any) Compare(that interface{}) int {
if that == nil {
if this == nil {
return 0
}
return 1
}
that1, ok := that.(*Any)
if !ok {
that2, ok := that.(Any)
if ok {
that1 = &that2
} else {
return 1
}
}
if that1 == nil {
if this == nil {
return 0
}
return 1
} else if this == nil {
return -1
}
if this.TypeUrl != that1.TypeUrl {
if this.TypeUrl < that1.TypeUrl {
return -1
}
return 1
}
if c := bytes.Compare(this.Value, that1.Value); c != 0 {
return c
}
return 0
}
func (this *Any) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*Any)
if !ok {
that2, ok := that.(Any)
if ok {
that1 = &that2
} else {
return false
}
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
if this.TypeUrl != that1.TypeUrl {
return false
}
if !bytes.Equal(this.Value, that1.Value) {
return false
}
return true
}
func (this *Any) GoString() string {
if this == nil {
return "nil"
}
s := make([]string, 0, 6)
s = append(s, "&types.Any{")
s = append(s, "TypeUrl: "+fmt.Sprintf("%#v", this.TypeUrl)+",\n")
s = append(s, "Value: "+fmt.Sprintf("%#v", this.Value)+",\n")
s = append(s, "}")
return strings.Join(s, "")
}
func valueToGoStringAny(v interface{}, typ string) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func extensionToGoStringAny(m github_com_gogo_protobuf_proto.Message) string {
e := github_com_gogo_protobuf_proto.GetUnsafeExtensionsMap(m)
if e == nil {
return "nil"
}
s := "proto.NewUnsafeXXX_InternalExtensions(map[int32]proto.Extension{"
keys := make([]int, 0, len(e))
for k := range e {
keys = append(keys, int(k))
}
sort.Ints(keys)
ss := []string{}
for _, k := range keys {
ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString())
}
s += strings.Join(ss, ",") + "})"
return s
}
func (m *Any) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Any) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.TypeUrl) > 0 {
dAtA[i] = 0xa
i++
i = encodeVarintAny(dAtA, i, uint64(len(m.TypeUrl)))
i += copy(dAtA[i:], m.TypeUrl)
}
if len(m.Value) > 0 {
dAtA[i] = 0x12
i++
i = encodeVarintAny(dAtA, i, uint64(len(m.Value)))
i += copy(dAtA[i:], m.Value)
}
return i, nil
}
func encodeFixed64Any(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Any(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintAny(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
}
func NewPopulatedAny(r randyAny, easy bool) *Any {
this := &Any{}
this.TypeUrl = string(randStringAny(r))
v1 := r.Intn(100)
this.Value = make([]byte, v1)
for i := 0; i < v1; i++ {
this.Value[i] = byte(r.Intn(256))
}
if !easy && r.Intn(10) != 0 {
}
return this
}
type randyAny interface {
Float32() float32
Float64() float64
Int63() int64
Int31() int32
Uint32() uint32
Intn(n int) int
}
func randUTF8RuneAny(r randyAny) rune {
ru := r.Intn(62)
if ru < 10 {
return rune(ru + 48)
} else if ru < 36 {
return rune(ru + 55)
}
return rune(ru + 61)
}
func randStringAny(r randyAny) string {
v2 := r.Intn(100)
tmps := make([]rune, v2)
for i := 0; i < v2; i++ {
tmps[i] = randUTF8RuneAny(r)
}
return string(tmps)
}
func randUnrecognizedAny(r randyAny, maxFieldNumber int) (dAtA []byte) {
l := r.Intn(5)
for i := 0; i < l; i++ {
wire := r.Intn(4)
if wire == 3 {
wire = 5
}
fieldNumber := maxFieldNumber + r.Intn(100)
dAtA = randFieldAny(dAtA, r, fieldNumber, wire)
}
return dAtA
}
func randFieldAny(dAtA []byte, r randyAny, fieldNumber int, wire int) []byte {
key := uint32(fieldNumber)<<3 | uint32(wire)
switch wire {
case 0:
dAtA = encodeVarintPopulateAny(dAtA, uint64(key))
v3 := r.Int63()
if r.Intn(2) == 0 {
v3 *= -1
}
dAtA = encodeVarintPopulateAny(dAtA, uint64(v3))
case 1:
dAtA = encodeVarintPopulateAny(dAtA, uint64(key))
dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
case 2:
dAtA = encodeVarintPopulateAny(dAtA, uint64(key))
ll := r.Intn(100)
dAtA = encodeVarintPopulateAny(dAtA, uint64(ll))
for j := 0; j < ll; j++ {
dAtA = append(dAtA, byte(r.Intn(256)))
}
default:
dAtA = encodeVarintPopulateAny(dAtA, uint64(key))
dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
}
return dAtA
}
func encodeVarintPopulateAny(dAtA []byte, v uint64) []byte {
for v >= 1<<7 {
dAtA = append(dAtA, uint8(uint64(v)&0x7f|0x80))
v >>= 7
}
dAtA = append(dAtA, uint8(v))
return dAtA
}
func (m *Any) Size() (n int) {
var l int
_ = l
l = len(m.TypeUrl)
if l > 0 {
n += 1 + l + sovAny(uint64(l))
}
l = len(m.Value)
if l > 0 {
n += 1 + l + sovAny(uint64(l))
}
return n
}
func sovAny(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozAny(x uint64) (n int) {
return sovAny(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (this *Any) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&Any{`,
`TypeUrl:` + fmt.Sprintf("%v", this.TypeUrl) + `,`,
`Value:` + fmt.Sprintf("%v", this.Value) + `,`,
`}`,
}, "")
return s
}
func valueToStringAny(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("*%v", pv)
}
func (m *Any) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAny
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Any: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Any: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field TypeUrl", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAny
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthAny
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.TypeUrl = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAny
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthAny
}
postIndex := iNdEx + byteLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...)
if m.Value == nil {
m.Value = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipAny(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthAny
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipAny(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowAny
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowAny
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
return iNdEx, nil
case 1:
iNdEx += 8
return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowAny
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthAny
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowAny
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
innerWire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
innerWireType := int(innerWire & 0x7)
if innerWireType == 4 {
break
}
next, err := skipAny(dAtA[start:])
if err != nil {
return 0, err
}
iNdEx = start + next
}
return iNdEx, nil
case 4:
return iNdEx, nil
case 5:
iNdEx += 4
return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
}
panic("unreachable")
}
var (
ErrInvalidLengthAny = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowAny = fmt.Errorf("proto: integer overflow")
)
func init() { proto.RegisterFile("any.proto", fileDescriptorAny) }
var fileDescriptorAny = []byte{
// 208 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x4c, 0xcc, 0xab, 0xd4,
0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x4f, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0x85, 0xf0, 0x92,
0x4a, 0xd3, 0x94, 0xcc, 0xb8, 0x98, 0x1d, 0xf3, 0x2a, 0x85, 0x24, 0xb9, 0x38, 0x4a, 0x2a, 0x0b,
0x52, 0xe3, 0x4b, 0x8b, 0x72, 0x24, 0x18, 0x15, 0x18, 0x35, 0x38, 0x83, 0xd8, 0x41, 0xfc, 0xd0,
0xa2, 0x1c, 0x21, 0x11, 0x2e, 0xd6, 0xb2, 0xc4, 0x9c, 0xd2, 0x54, 0x09, 0x26, 0x05, 0x46, 0x0d,
0x9e, 0x20, 0x08, 0xc7, 0xa9, 0x89, 0xf1, 0xc2, 0x43, 0x39, 0x86, 0x1b, 0x0f, 0xe5, 0x18, 0x3e,
0x3c, 0x94, 0x63, 0xfc, 0xf1, 0x50, 0x8e, 0xb1, 0xe1, 0x91, 0x1c, 0xe3, 0x8a, 0x47, 0x72, 0x8c,
0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x8b, 0x47, 0x72,
0x0c, 0x1f, 0x40, 0xe2, 0x8f, 0xe5, 0x18, 0xb9, 0x84, 0x93, 0xf3, 0x73, 0xf5, 0xd0, 0xec, 0x77,
0xe2, 0x70, 0xcc, 0xab, 0x0c, 0x00, 0x71, 0x02, 0x18, 0xa3, 0x58, 0x41, 0x56, 0x16, 0x2f, 0x60,
0x64, 0x5c, 0xc4, 0xc4, 0xec, 0x1e, 0xe0, 0xb4, 0x8a, 0x49, 0xce, 0x1d, 0xa2, 0x3a, 0x00, 0xaa,
0x5a, 0x2f, 0x3c, 0x35, 0x27, 0xc7, 0x3b, 0x2f, 0xbf, 0x3c, 0x2f, 0x04, 0xa4, 0x32, 0x89, 0x0d,
0x6c, 0x8c, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x63, 0x5d, 0x2d, 0x27, 0xe1, 0x00, 0x00, 0x00,
}

35
vendor/github.com/gogo/protobuf/types/doc.go generated vendored Normal file
View file

@ -0,0 +1,35 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/*
Package types contains code for interacting with well-known types.
*/
package types

100
vendor/github.com/gogo/protobuf/types/duration.go generated vendored Normal file
View file

@ -0,0 +1,100 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package types
// This file implements conversions between google.protobuf.Duration
// and time.Duration.
import (
"errors"
"fmt"
"time"
)
const (
// Range of a Duration in seconds, as specified in
// google/protobuf/duration.proto. This is about 10,000 years in seconds.
maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
minSeconds = -maxSeconds
)
// validateDuration determines whether the Duration is valid according to the
// definition in google/protobuf/duration.proto. A valid Duration
// may still be too large to fit into a time.Duration (the range of Duration
// is about 10,000 years, and the range of time.Duration is about 290).
func validateDuration(d *Duration) error {
if d == nil {
return errors.New("duration: nil Duration")
}
if d.Seconds < minSeconds || d.Seconds > maxSeconds {
return fmt.Errorf("duration: %#v: seconds out of range", d)
}
if d.Nanos <= -1e9 || d.Nanos >= 1e9 {
return fmt.Errorf("duration: %#v: nanos out of range", d)
}
// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) {
return fmt.Errorf("duration: %#v: seconds and nanos have different signs", d)
}
return nil
}
// DurationFromProto converts a Duration to a time.Duration. DurationFromProto
// returns an error if the Duration is invalid or is too large to be
// represented in a time.Duration.
func DurationFromProto(p *Duration) (time.Duration, error) {
if err := validateDuration(p); err != nil {
return 0, err
}
d := time.Duration(p.Seconds) * time.Second
if int64(d/time.Second) != p.Seconds {
return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p)
}
if p.Nanos != 0 {
d += time.Duration(p.Nanos)
if (d < 0) != (p.Nanos < 0) {
return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p)
}
}
return d, nil
}
// DurationProto converts a time.Duration to a Duration.
func DurationProto(d time.Duration) *Duration {
nanos := d.Nanoseconds()
secs := nanos / 1e9
nanos -= secs * 1e9
return &Duration{
Seconds: secs,
Nanos: int32(nanos),
}
}

515
vendor/github.com/gogo/protobuf/types/duration.pb.go generated vendored Normal file
View file

@ -0,0 +1,515 @@
// Code generated by protoc-gen-gogo.
// source: duration.proto
// DO NOT EDIT!
/*
Package types is a generated protocol buffer package.
It is generated from these files:
duration.proto
It has these top-level messages:
Duration
*/
package types
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import strings "strings"
import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto"
import sort "sort"
import strconv "strconv"
import reflect "reflect"
import io "io"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
// A Duration represents a signed, fixed-length span of time represented
// as a count of seconds and fractions of seconds at nanosecond
// resolution. It is independent of any calendar and concepts like "day"
// or "month". It is related to Timestamp in that the difference between
// two Timestamp values is a Duration and it can be added or subtracted
// from a Timestamp. Range is approximately +-10,000 years.
//
// Example 1: Compute Duration from two Timestamps in pseudo code.
//
// Timestamp start = ...;
// Timestamp end = ...;
// Duration duration = ...;
//
// duration.seconds = end.seconds - start.seconds;
// duration.nanos = end.nanos - start.nanos;
//
// if (duration.seconds < 0 && duration.nanos > 0) {
// duration.seconds += 1;
// duration.nanos -= 1000000000;
// } else if (durations.seconds > 0 && duration.nanos < 0) {
// duration.seconds -= 1;
// duration.nanos += 1000000000;
// }
//
// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
//
// Timestamp start = ...;
// Duration duration = ...;
// Timestamp end = ...;
//
// end.seconds = start.seconds + duration.seconds;
// end.nanos = start.nanos + duration.nanos;
//
// if (end.nanos < 0) {
// end.seconds -= 1;
// end.nanos += 1000000000;
// } else if (end.nanos >= 1000000000) {
// end.seconds += 1;
// end.nanos -= 1000000000;
// }
//
//
type Duration struct {
// Signed seconds of the span of time. Must be from -315,576,000,000
// to +315,576,000,000 inclusive.
Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
// Signed fractions of a second at nanosecond resolution of the span
// of time. Durations less than one second are represented with a 0
// `seconds` field and a positive or negative `nanos` field. For durations
// of one second or more, a non-zero value for the `nanos` field must be
// of the same sign as the `seconds` field. Must be from -999,999,999
// to +999,999,999 inclusive.
Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
}
func (m *Duration) Reset() { *m = Duration{} }
func (*Duration) ProtoMessage() {}
func (*Duration) Descriptor() ([]byte, []int) { return fileDescriptorDuration, []int{0} }
func (*Duration) XXX_WellKnownType() string { return "Duration" }
func (m *Duration) GetSeconds() int64 {
if m != nil {
return m.Seconds
}
return 0
}
func (m *Duration) GetNanos() int32 {
if m != nil {
return m.Nanos
}
return 0
}
func init() {
proto.RegisterType((*Duration)(nil), "google.protobuf.Duration")
}
func (this *Duration) Compare(that interface{}) int {
if that == nil {
if this == nil {
return 0
}
return 1
}
that1, ok := that.(*Duration)
if !ok {
that2, ok := that.(Duration)
if ok {
that1 = &that2
} else {
return 1
}
}
if that1 == nil {
if this == nil {
return 0
}
return 1
} else if this == nil {
return -1
}
if this.Seconds != that1.Seconds {
if this.Seconds < that1.Seconds {
return -1
}
return 1
}
if this.Nanos != that1.Nanos {
if this.Nanos < that1.Nanos {
return -1
}
return 1
}
return 0
}
func (this *Duration) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*Duration)
if !ok {
that2, ok := that.(Duration)
if ok {
that1 = &that2
} else {
return false
}
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
if this.Seconds != that1.Seconds {
return false
}
if this.Nanos != that1.Nanos {
return false
}
return true
}
func (this *Duration) GoString() string {
if this == nil {
return "nil"
}
s := make([]string, 0, 6)
s = append(s, "&types.Duration{")
s = append(s, "Seconds: "+fmt.Sprintf("%#v", this.Seconds)+",\n")
s = append(s, "Nanos: "+fmt.Sprintf("%#v", this.Nanos)+",\n")
s = append(s, "}")
return strings.Join(s, "")
}
func valueToGoStringDuration(v interface{}, typ string) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func extensionToGoStringDuration(m github_com_gogo_protobuf_proto.Message) string {
e := github_com_gogo_protobuf_proto.GetUnsafeExtensionsMap(m)
if e == nil {
return "nil"
}
s := "proto.NewUnsafeXXX_InternalExtensions(map[int32]proto.Extension{"
keys := make([]int, 0, len(e))
for k := range e {
keys = append(keys, int(k))
}
sort.Ints(keys)
ss := []string{}
for _, k := range keys {
ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString())
}
s += strings.Join(ss, ",") + "})"
return s
}
func (m *Duration) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Duration) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.Seconds != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintDuration(dAtA, i, uint64(m.Seconds))
}
if m.Nanos != 0 {
dAtA[i] = 0x10
i++
i = encodeVarintDuration(dAtA, i, uint64(m.Nanos))
}
return i, nil
}
func encodeFixed64Duration(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Duration(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintDuration(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
}
func (m *Duration) Size() (n int) {
var l int
_ = l
if m.Seconds != 0 {
n += 1 + sovDuration(uint64(m.Seconds))
}
if m.Nanos != 0 {
n += 1 + sovDuration(uint64(m.Nanos))
}
return n
}
func sovDuration(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozDuration(x uint64) (n int) {
return sovDuration(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *Duration) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowDuration
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Duration: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Duration: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Seconds", wireType)
}
m.Seconds = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowDuration
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Seconds |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Nanos", wireType)
}
m.Nanos = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowDuration
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Nanos |= (int32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipDuration(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthDuration
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipDuration(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowDuration
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowDuration
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
return iNdEx, nil
case 1:
iNdEx += 8
return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowDuration
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthDuration
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowDuration
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
innerWire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
innerWireType := int(innerWire & 0x7)
if innerWireType == 4 {
break
}
next, err := skipDuration(dAtA[start:])
if err != nil {
return 0, err
}
iNdEx = start + next
}
return iNdEx, nil
case 4:
return iNdEx, nil
case 5:
iNdEx += 4
return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
}
panic("unreachable")
}
var (
ErrInvalidLengthDuration = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowDuration = fmt.Errorf("proto: integer overflow")
)
func init() { proto.RegisterFile("duration.proto", fileDescriptorDuration) }
var fileDescriptorDuration = []byte{
// 203 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0x29, 0x2d, 0x4a,
0x2c, 0xc9, 0xcc, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x4f, 0xcf, 0xcf, 0x4f,
0xcf, 0x49, 0x85, 0xf0, 0x92, 0x4a, 0xd3, 0x94, 0xac, 0xb8, 0x38, 0x5c, 0xa0, 0x4a, 0x84, 0x24,
0xb8, 0xd8, 0x8b, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25, 0x18, 0x15, 0x18, 0x35, 0x98, 0x83,
0x60, 0x5c, 0x21, 0x11, 0x2e, 0xd6, 0xbc, 0xc4, 0xbc, 0xfc, 0x62, 0x09, 0x26, 0x05, 0x46, 0x0d,
0xd6, 0x20, 0x08, 0xc7, 0xa9, 0xfe, 0xc2, 0x43, 0x39, 0x86, 0x1b, 0x0f, 0xe5, 0x18, 0x3e, 0x3c,
0x94, 0x63, 0x5c, 0xf1, 0x48, 0x8e, 0xf1, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f,
0x3c, 0x92, 0x63, 0x7c, 0xf1, 0x48, 0x8e, 0xe1, 0xc3, 0x23, 0x39, 0xc6, 0x15, 0x8f, 0xe5, 0x18,
0xb9, 0x84, 0x93, 0xf3, 0x73, 0xf5, 0xd0, 0xac, 0x76, 0xe2, 0x85, 0x59, 0x1c, 0x00, 0x12, 0x09,
0x60, 0x8c, 0x62, 0x2d, 0xa9, 0x2c, 0x48, 0x2d, 0x5e, 0xc0, 0xc8, 0xb8, 0x88, 0x89, 0xd9, 0x3d,
0xc0, 0x69, 0x15, 0x93, 0x9c, 0x3b, 0x44, 0x4b, 0x00, 0x54, 0x8b, 0x5e, 0x78, 0x6a, 0x4e, 0x8e,
0x77, 0x5e, 0x7e, 0x79, 0x5e, 0x08, 0x48, 0x65, 0x12, 0x1b, 0xd8, 0x2c, 0x63, 0x40, 0x00, 0x00,
0x00, 0xff, 0xff, 0xba, 0xfb, 0x15, 0xc9, 0xe6, 0x00, 0x00, 0x00,
}

100
vendor/github.com/gogo/protobuf/types/duration_gogo.go generated vendored Normal file
View file

@ -0,0 +1,100 @@
// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2016, The GoGo Authors. All rights reserved.
// http://github.com/gogo/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package types
import (
"fmt"
"time"
)
func NewPopulatedDuration(r interface {
Int63() int64
}, easy bool) *Duration {
this := &Duration{}
maxSecs := time.Hour.Nanoseconds() / 1e9
max := 2 * maxSecs
s := int64(r.Int63()) % max
s -= maxSecs
neg := int64(1)
if s < 0 {
neg = -1
}
this.Seconds = s
this.Nanos = int32(neg * (r.Int63() % 1e9))
return this
}
func (d *Duration) String() string {
td, err := DurationFromProto(d)
if err != nil {
return fmt.Sprintf("(%v)", err)
}
return td.String()
}
func NewPopulatedStdDuration(r interface {
Int63() int64
}, easy bool) *time.Duration {
dur := NewPopulatedDuration(r, easy)
d, err := DurationFromProto(dur)
if err != nil {
return nil
}
return &d
}
func SizeOfStdDuration(d time.Duration) int {
dur := DurationProto(d)
return dur.Size()
}
func StdDurationMarshal(d time.Duration) ([]byte, error) {
size := SizeOfStdDuration(d)
buf := make([]byte, size)
_, err := StdDurationMarshalTo(d, buf)
return buf, err
}
func StdDurationMarshalTo(d time.Duration, data []byte) (int, error) {
dur := DurationProto(d)
return dur.MarshalTo(data)
}
func StdDurationUnmarshal(d *time.Duration, data []byte) error {
dur := &Duration{}
if err := dur.Unmarshal(data); err != nil {
return err
}
dd, err := DurationFromProto(dur)
if err != nil {
return err
}
*d = dd
return nil
}

478
vendor/github.com/gogo/protobuf/types/empty.pb.go generated vendored Normal file
View file

@ -0,0 +1,478 @@
// Code generated by protoc-gen-gogo.
// source: empty.proto
// DO NOT EDIT!
/*
Package types is a generated protocol buffer package.
It is generated from these files:
empty.proto
It has these top-level messages:
Empty
*/
package types
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import strings "strings"
import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto"
import sort "sort"
import strconv "strconv"
import reflect "reflect"
import io "io"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
// A generic empty message that you can re-use to avoid defining duplicated
// empty messages in your APIs. A typical example is to use it as the request
// or the response type of an API method. For instance:
//
// service Foo {
// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
// }
//
// The JSON representation for `Empty` is empty JSON object `{}`.
type Empty struct {
}
func (m *Empty) Reset() { *m = Empty{} }
func (*Empty) ProtoMessage() {}
func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptorEmpty, []int{0} }
func (*Empty) XXX_WellKnownType() string { return "Empty" }
func init() {
proto.RegisterType((*Empty)(nil), "google.protobuf.Empty")
}
func (this *Empty) Compare(that interface{}) int {
if that == nil {
if this == nil {
return 0
}
return 1
}
that1, ok := that.(*Empty)
if !ok {
that2, ok := that.(Empty)
if ok {
that1 = &that2
} else {
return 1
}
}
if that1 == nil {
if this == nil {
return 0
}
return 1
} else if this == nil {
return -1
}
return 0
}
func (this *Empty) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*Empty)
if !ok {
that2, ok := that.(Empty)
if ok {
that1 = &that2
} else {
return false
}
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
return true
}
func (this *Empty) GoString() string {
if this == nil {
return "nil"
}
s := make([]string, 0, 4)
s = append(s, "&types.Empty{")
s = append(s, "}")
return strings.Join(s, "")
}
func valueToGoStringEmpty(v interface{}, typ string) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func extensionToGoStringEmpty(m github_com_gogo_protobuf_proto.Message) string {
e := github_com_gogo_protobuf_proto.GetUnsafeExtensionsMap(m)
if e == nil {
return "nil"
}
s := "proto.NewUnsafeXXX_InternalExtensions(map[int32]proto.Extension{"
keys := make([]int, 0, len(e))
for k := range e {
keys = append(keys, int(k))
}
sort.Ints(keys)
ss := []string{}
for _, k := range keys {
ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString())
}
s += strings.Join(ss, ",") + "})"
return s
}
func (m *Empty) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Empty) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
return i, nil
}
func encodeFixed64Empty(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Empty(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintEmpty(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
}
func NewPopulatedEmpty(r randyEmpty, easy bool) *Empty {
this := &Empty{}
if !easy && r.Intn(10) != 0 {
}
return this
}
type randyEmpty interface {
Float32() float32
Float64() float64
Int63() int64
Int31() int32
Uint32() uint32
Intn(n int) int
}
func randUTF8RuneEmpty(r randyEmpty) rune {
ru := r.Intn(62)
if ru < 10 {
return rune(ru + 48)
} else if ru < 36 {
return rune(ru + 55)
}
return rune(ru + 61)
}
func randStringEmpty(r randyEmpty) string {
v1 := r.Intn(100)
tmps := make([]rune, v1)
for i := 0; i < v1; i++ {
tmps[i] = randUTF8RuneEmpty(r)
}
return string(tmps)
}
func randUnrecognizedEmpty(r randyEmpty, maxFieldNumber int) (dAtA []byte) {
l := r.Intn(5)
for i := 0; i < l; i++ {
wire := r.Intn(4)
if wire == 3 {
wire = 5
}
fieldNumber := maxFieldNumber + r.Intn(100)
dAtA = randFieldEmpty(dAtA, r, fieldNumber, wire)
}
return dAtA
}
func randFieldEmpty(dAtA []byte, r randyEmpty, fieldNumber int, wire int) []byte {
key := uint32(fieldNumber)<<3 | uint32(wire)
switch wire {
case 0:
dAtA = encodeVarintPopulateEmpty(dAtA, uint64(key))
v2 := r.Int63()
if r.Intn(2) == 0 {
v2 *= -1
}
dAtA = encodeVarintPopulateEmpty(dAtA, uint64(v2))
case 1:
dAtA = encodeVarintPopulateEmpty(dAtA, uint64(key))
dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
case 2:
dAtA = encodeVarintPopulateEmpty(dAtA, uint64(key))
ll := r.Intn(100)
dAtA = encodeVarintPopulateEmpty(dAtA, uint64(ll))
for j := 0; j < ll; j++ {
dAtA = append(dAtA, byte(r.Intn(256)))
}
default:
dAtA = encodeVarintPopulateEmpty(dAtA, uint64(key))
dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
}
return dAtA
}
func encodeVarintPopulateEmpty(dAtA []byte, v uint64) []byte {
for v >= 1<<7 {
dAtA = append(dAtA, uint8(uint64(v)&0x7f|0x80))
v >>= 7
}
dAtA = append(dAtA, uint8(v))
return dAtA
}
func (m *Empty) Size() (n int) {
var l int
_ = l
return n
}
func sovEmpty(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozEmpty(x uint64) (n int) {
return sovEmpty(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (this *Empty) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&Empty{`,
`}`,
}, "")
return s
}
func valueToStringEmpty(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("*%v", pv)
}
func (m *Empty) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEmpty
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Empty: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Empty: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
default:
iNdEx = preIndex
skippy, err := skipEmpty(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthEmpty
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipEmpty(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowEmpty
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowEmpty
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
return iNdEx, nil
case 1:
iNdEx += 8
return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowEmpty
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthEmpty
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowEmpty
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
innerWire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
innerWireType := int(innerWire & 0x7)
if innerWireType == 4 {
break
}
next, err := skipEmpty(dAtA[start:])
if err != nil {
return 0, err
}
iNdEx = start + next
}
return iNdEx, nil
case 4:
return iNdEx, nil
case 5:
iNdEx += 4
return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
}
panic("unreachable")
}
var (
ErrInvalidLengthEmpty = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowEmpty = fmt.Errorf("proto: integer overflow")
)
func init() { proto.RegisterFile("empty.proto", fileDescriptorEmpty) }
var fileDescriptorEmpty = []byte{
// 172 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x4e, 0xcd, 0x2d, 0x28,
0xa9, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x4f, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0x85,
0xf0, 0x92, 0x4a, 0xd3, 0x94, 0xd8, 0xb9, 0x58, 0x5d, 0x41, 0xf2, 0x4e, 0xed, 0x8c, 0x17, 0x1e,
0xca, 0x31, 0xdc, 0x78, 0x28, 0xc7, 0xf0, 0xe1, 0xa1, 0x1c, 0xe3, 0x8f, 0x87, 0x72, 0x8c, 0x0d,
0x8f, 0xe4, 0x18, 0x57, 0x3c, 0x92, 0x63, 0x3c, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6,
0x07, 0x8f, 0xe4, 0x18, 0x5f, 0x3c, 0x92, 0x63, 0xf8, 0x00, 0x12, 0x7f, 0x2c, 0xc7, 0xc8, 0x25,
0x9c, 0x9c, 0x9f, 0xab, 0x87, 0x66, 0xa0, 0x13, 0x17, 0xd8, 0xb8, 0x00, 0x10, 0x37, 0x80, 0x31,
0x8a, 0xb5, 0xa4, 0xb2, 0x20, 0xb5, 0x78, 0x01, 0x23, 0xe3, 0x0f, 0x46, 0xc6, 0x45, 0x4c, 0xcc,
0xee, 0x01, 0x4e, 0xab, 0x98, 0xe4, 0xdc, 0x21, 0x5a, 0x02, 0xa0, 0x5a, 0xf4, 0xc2, 0x53, 0x73,
0x72, 0xbc, 0xf3, 0xf2, 0xcb, 0xf3, 0x42, 0x40, 0x8a, 0x93, 0xd8, 0xc0, 0x66, 0x19, 0x03, 0x02,
0x00, 0x00, 0xff, 0xff, 0x97, 0x6c, 0x95, 0xdd, 0xb9, 0x00, 0x00, 0x00,
}

759
vendor/github.com/gogo/protobuf/types/field_mask.pb.go generated vendored Normal file
View file

@ -0,0 +1,759 @@
// Code generated by protoc-gen-gogo.
// source: field_mask.proto
// DO NOT EDIT!
/*
Package types is a generated protocol buffer package.
It is generated from these files:
field_mask.proto
It has these top-level messages:
FieldMask
*/
package types
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import strings "strings"
import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto"
import sort "sort"
import strconv "strconv"
import reflect "reflect"
import io "io"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
// `FieldMask` represents a set of symbolic field paths, for example:
//
// paths: "f.a"
// paths: "f.b.d"
//
// Here `f` represents a field in some root message, `a` and `b`
// fields in the message found in `f`, and `d` a field found in the
// message in `f.b`.
//
// Field masks are used to specify a subset of fields that should be
// returned by a get operation or modified by an update operation.
// Field masks also have a custom JSON encoding (see below).
//
// # Field Masks in Projections
//
// When used in the context of a projection, a response message or
// sub-message is filtered by the API to only contain those fields as
// specified in the mask. For example, if the mask in the previous
// example is applied to a response message as follows:
//
// f {
// a : 22
// b {
// d : 1
// x : 2
// }
// y : 13
// }
// z: 8
//
// The result will not contain specific values for fields x,y and z
// (their value will be set to the default, and omitted in proto text
// output):
//
//
// f {
// a : 22
// b {
// d : 1
// }
// }
//
// A repeated field is not allowed except at the last position of a
// field mask.
//
// If a FieldMask object is not present in a get operation, the
// operation applies to all fields (as if a FieldMask of all fields
// had been specified).
//
// Note that a field mask does not necessarily apply to the
// top-level response message. In case of a REST get operation, the
// field mask applies directly to the response, but in case of a REST
// list operation, the mask instead applies to each individual message
// in the returned resource list. In case of a REST custom method,
// other definitions may be used. Where the mask applies will be
// clearly documented together with its declaration in the API. In
// any case, the effect on the returned resource/resources is required
// behavior for APIs.
//
// # Field Masks in Update Operations
//
// A field mask in update operations specifies which fields of the
// targeted resource are going to be updated. The API is required
// to only change the values of the fields as specified in the mask
// and leave the others untouched. If a resource is passed in to
// describe the updated values, the API ignores the values of all
// fields not covered by the mask.
//
// If a repeated field is specified for an update operation, the existing
// repeated values in the target resource will be overwritten by the new values.
// Note that a repeated field is only allowed in the last position of a field
// mask.
//
// If a sub-message is specified in the last position of the field mask for an
// update operation, then the existing sub-message in the target resource is
// overwritten. Given the target message:
//
// f {
// b {
// d : 1
// x : 2
// }
// c : 1
// }
//
// And an update message:
//
// f {
// b {
// d : 10
// }
// }
//
// then if the field mask is:
//
// paths: "f.b"
//
// then the result will be:
//
// f {
// b {
// d : 10
// }
// c : 1
// }
//
// However, if the update mask was:
//
// paths: "f.b.d"
//
// then the result would be:
//
// f {
// b {
// d : 10
// x : 2
// }
// c : 1
// }
//
// In order to reset a field's value to the default, the field must
// be in the mask and set to the default value in the provided resource.
// Hence, in order to reset all fields of a resource, provide a default
// instance of the resource and set all fields in the mask, or do
// not provide a mask as described below.
//
// If a field mask is not present on update, the operation applies to
// all fields (as if a field mask of all fields has been specified).
// Note that in the presence of schema evolution, this may mean that
// fields the client does not know and has therefore not filled into
// the request will be reset to their default. If this is unwanted
// behavior, a specific service may require a client to always specify
// a field mask, producing an error if not.
//
// As with get operations, the location of the resource which
// describes the updated values in the request message depends on the
// operation kind. In any case, the effect of the field mask is
// required to be honored by the API.
//
// ## Considerations for HTTP REST
//
// The HTTP kind of an update operation which uses a field mask must
// be set to PATCH instead of PUT in order to satisfy HTTP semantics
// (PUT must only be used for full updates).
//
// # JSON Encoding of Field Masks
//
// In JSON, a field mask is encoded as a single string where paths are
// separated by a comma. Fields name in each path are converted
// to/from lower-camel naming conventions.
//
// As an example, consider the following message declarations:
//
// message Profile {
// User user = 1;
// Photo photo = 2;
// }
// message User {
// string display_name = 1;
// string address = 2;
// }
//
// In proto a field mask for `Profile` may look as such:
//
// mask {
// paths: "user.display_name"
// paths: "photo"
// }
//
// In JSON, the same mask is represented as below:
//
// {
// mask: "user.displayName,photo"
// }
//
// # Field Masks and Oneof Fields
//
// Field masks treat fields in oneofs just as regular fields. Consider the
// following message:
//
// message SampleMessage {
// oneof test_oneof {
// string name = 4;
// SubMessage sub_message = 9;
// }
// }
//
// The field mask can be:
//
// mask {
// paths: "name"
// }
//
// Or:
//
// mask {
// paths: "sub_message"
// }
//
// Note that oneof type names ("test_oneof" in this case) cannot be used in
// paths.
type FieldMask struct {
// The set of field mask paths.
Paths []string `protobuf:"bytes,1,rep,name=paths" json:"paths,omitempty"`
}
func (m *FieldMask) Reset() { *m = FieldMask{} }
func (*FieldMask) ProtoMessage() {}
func (*FieldMask) Descriptor() ([]byte, []int) { return fileDescriptorFieldMask, []int{0} }
func (m *FieldMask) GetPaths() []string {
if m != nil {
return m.Paths
}
return nil
}
func init() {
proto.RegisterType((*FieldMask)(nil), "google.protobuf.FieldMask")
}
func (this *FieldMask) Compare(that interface{}) int {
if that == nil {
if this == nil {
return 0
}
return 1
}
that1, ok := that.(*FieldMask)
if !ok {
that2, ok := that.(FieldMask)
if ok {
that1 = &that2
} else {
return 1
}
}
if that1 == nil {
if this == nil {
return 0
}
return 1
} else if this == nil {
return -1
}
if len(this.Paths) != len(that1.Paths) {
if len(this.Paths) < len(that1.Paths) {
return -1
}
return 1
}
for i := range this.Paths {
if this.Paths[i] != that1.Paths[i] {
if this.Paths[i] < that1.Paths[i] {
return -1
}
return 1
}
}
return 0
}
func (this *FieldMask) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*FieldMask)
if !ok {
that2, ok := that.(FieldMask)
if ok {
that1 = &that2
} else {
return false
}
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
if len(this.Paths) != len(that1.Paths) {
return false
}
for i := range this.Paths {
if this.Paths[i] != that1.Paths[i] {
return false
}
}
return true
}
func (this *FieldMask) GoString() string {
if this == nil {
return "nil"
}
s := make([]string, 0, 5)
s = append(s, "&types.FieldMask{")
s = append(s, "Paths: "+fmt.Sprintf("%#v", this.Paths)+",\n")
s = append(s, "}")
return strings.Join(s, "")
}
func valueToGoStringFieldMask(v interface{}, typ string) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func extensionToGoStringFieldMask(m github_com_gogo_protobuf_proto.Message) string {
e := github_com_gogo_protobuf_proto.GetUnsafeExtensionsMap(m)
if e == nil {
return "nil"
}
s := "proto.NewUnsafeXXX_InternalExtensions(map[int32]proto.Extension{"
keys := make([]int, 0, len(e))
for k := range e {
keys = append(keys, int(k))
}
sort.Ints(keys)
ss := []string{}
for _, k := range keys {
ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString())
}
s += strings.Join(ss, ",") + "})"
return s
}
func (m *FieldMask) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *FieldMask) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.Paths) > 0 {
for _, s := range m.Paths {
dAtA[i] = 0xa
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
}
}
return i, nil
}
func encodeFixed64FieldMask(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32FieldMask(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintFieldMask(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
}
func NewPopulatedFieldMask(r randyFieldMask, easy bool) *FieldMask {
this := &FieldMask{}
v1 := r.Intn(10)
this.Paths = make([]string, v1)
for i := 0; i < v1; i++ {
this.Paths[i] = string(randStringFieldMask(r))
}
if !easy && r.Intn(10) != 0 {
}
return this
}
type randyFieldMask interface {
Float32() float32
Float64() float64
Int63() int64
Int31() int32
Uint32() uint32
Intn(n int) int
}
func randUTF8RuneFieldMask(r randyFieldMask) rune {
ru := r.Intn(62)
if ru < 10 {
return rune(ru + 48)
} else if ru < 36 {
return rune(ru + 55)
}
return rune(ru + 61)
}
func randStringFieldMask(r randyFieldMask) string {
v2 := r.Intn(100)
tmps := make([]rune, v2)
for i := 0; i < v2; i++ {
tmps[i] = randUTF8RuneFieldMask(r)
}
return string(tmps)
}
func randUnrecognizedFieldMask(r randyFieldMask, maxFieldNumber int) (dAtA []byte) {
l := r.Intn(5)
for i := 0; i < l; i++ {
wire := r.Intn(4)
if wire == 3 {
wire = 5
}
fieldNumber := maxFieldNumber + r.Intn(100)
dAtA = randFieldFieldMask(dAtA, r, fieldNumber, wire)
}
return dAtA
}
func randFieldFieldMask(dAtA []byte, r randyFieldMask, fieldNumber int, wire int) []byte {
key := uint32(fieldNumber)<<3 | uint32(wire)
switch wire {
case 0:
dAtA = encodeVarintPopulateFieldMask(dAtA, uint64(key))
v3 := r.Int63()
if r.Intn(2) == 0 {
v3 *= -1
}
dAtA = encodeVarintPopulateFieldMask(dAtA, uint64(v3))
case 1:
dAtA = encodeVarintPopulateFieldMask(dAtA, uint64(key))
dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
case 2:
dAtA = encodeVarintPopulateFieldMask(dAtA, uint64(key))
ll := r.Intn(100)
dAtA = encodeVarintPopulateFieldMask(dAtA, uint64(ll))
for j := 0; j < ll; j++ {
dAtA = append(dAtA, byte(r.Intn(256)))
}
default:
dAtA = encodeVarintPopulateFieldMask(dAtA, uint64(key))
dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
}
return dAtA
}
func encodeVarintPopulateFieldMask(dAtA []byte, v uint64) []byte {
for v >= 1<<7 {
dAtA = append(dAtA, uint8(uint64(v)&0x7f|0x80))
v >>= 7
}
dAtA = append(dAtA, uint8(v))
return dAtA
}
func (m *FieldMask) Size() (n int) {
var l int
_ = l
if len(m.Paths) > 0 {
for _, s := range m.Paths {
l = len(s)
n += 1 + l + sovFieldMask(uint64(l))
}
}
return n
}
func sovFieldMask(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozFieldMask(x uint64) (n int) {
return sovFieldMask(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (this *FieldMask) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&FieldMask{`,
`Paths:` + fmt.Sprintf("%v", this.Paths) + `,`,
`}`,
}, "")
return s
}
func valueToStringFieldMask(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("*%v", pv)
}
func (m *FieldMask) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFieldMask
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: FieldMask: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: FieldMask: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Paths", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFieldMask
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthFieldMask
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Paths = append(m.Paths, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipFieldMask(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthFieldMask
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipFieldMask(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowFieldMask
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowFieldMask
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
return iNdEx, nil
case 1:
iNdEx += 8
return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowFieldMask
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthFieldMask
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowFieldMask
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
innerWire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
innerWireType := int(innerWire & 0x7)
if innerWireType == 4 {
break
}
next, err := skipFieldMask(dAtA[start:])
if err != nil {
return 0, err
}
iNdEx = start + next
}
return iNdEx, nil
case 4:
return iNdEx, nil
case 5:
iNdEx += 4
return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
}
panic("unreachable")
}
var (
ErrInvalidLengthFieldMask = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowFieldMask = fmt.Errorf("proto: integer overflow")
)
func init() { proto.RegisterFile("field_mask.proto", fileDescriptorFieldMask) }
var fileDescriptorFieldMask = []byte{
// 196 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0x48, 0xcb, 0x4c, 0xcd,
0x49, 0x89, 0xcf, 0x4d, 0x2c, 0xce, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x4f, 0xcf,
0xcf, 0x4f, 0xcf, 0x49, 0x85, 0xf0, 0x92, 0x4a, 0xd3, 0x94, 0x14, 0xb9, 0x38, 0xdd, 0x40, 0x8a,
0x7c, 0x13, 0x8b, 0xb3, 0x85, 0x44, 0xb8, 0x58, 0x0b, 0x12, 0x4b, 0x32, 0x8a, 0x25, 0x18, 0x15,
0x98, 0x35, 0x38, 0x83, 0x20, 0x1c, 0xa7, 0x0e, 0xc6, 0x0b, 0x0f, 0xe5, 0x18, 0x6e, 0x3c, 0x94,
0x63, 0xf8, 0xf0, 0x50, 0x8e, 0xf1, 0xc7, 0x43, 0x39, 0xc6, 0x86, 0x47, 0x72, 0x8c, 0x2b, 0x1e,
0xc9, 0x31, 0x9e, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x2f,
0x1e, 0xc9, 0x31, 0x7c, 0x00, 0x89, 0x3f, 0x96, 0x63, 0xe4, 0x12, 0x4e, 0xce, 0xcf, 0xd5, 0x43,
0xb3, 0xca, 0x89, 0x0f, 0x6e, 0x51, 0x00, 0x48, 0x28, 0x80, 0x31, 0x8a, 0xb5, 0xa4, 0xb2, 0x20,
0xb5, 0x78, 0x01, 0x23, 0xe3, 0x22, 0x26, 0x66, 0xf7, 0x00, 0xa7, 0x55, 0x4c, 0x72, 0xee, 0x10,
0x3d, 0x01, 0x50, 0x3d, 0x7a, 0xe1, 0xa9, 0x39, 0x39, 0xde, 0x79, 0xf9, 0xe5, 0x79, 0x21, 0x20,
0x95, 0x49, 0x6c, 0x60, 0xc3, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xea, 0xb1, 0x3a, 0xd5,
0xd9, 0x00, 0x00, 0x00,
}

1908
vendor/github.com/gogo/protobuf/types/struct.pb.go generated vendored Normal file

File diff suppressed because it is too large Load diff

123
vendor/github.com/gogo/protobuf/types/timestamp.go generated vendored Normal file
View file

@ -0,0 +1,123 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package types
// This file implements operations on google.protobuf.Timestamp.
import (
"errors"
"fmt"
"time"
)
const (
// Seconds field of the earliest valid Timestamp.
// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
minValidSeconds = -62135596800
// Seconds field just after the latest valid Timestamp.
// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
maxValidSeconds = 253402300800
)
// validateTimestamp determines whether a Timestamp is valid.
// A valid timestamp represents a time in the range
// [0001-01-01, 10000-01-01) and has a Nanos field
// in the range [0, 1e9).
//
// If the Timestamp is valid, validateTimestamp returns nil.
// Otherwise, it returns an error that describes
// the problem.
//
// Every valid Timestamp can be represented by a time.Time, but the converse is not true.
func validateTimestamp(ts *Timestamp) error {
if ts == nil {
return errors.New("timestamp: nil Timestamp")
}
if ts.Seconds < minValidSeconds {
return fmt.Errorf("timestamp: %#v before 0001-01-01", ts)
}
if ts.Seconds >= maxValidSeconds {
return fmt.Errorf("timestamp: %#v after 10000-01-01", ts)
}
if ts.Nanos < 0 || ts.Nanos >= 1e9 {
return fmt.Errorf("timestamp: %#v: nanos not in range [0, 1e9)", ts)
}
return nil
}
// TimestampFromProto converts a google.protobuf.Timestamp proto to a time.Time.
// It returns an error if the argument is invalid.
//
// Unlike most Go functions, if Timestamp returns an error, the first return value
// is not the zero time.Time. Instead, it is the value obtained from the
// time.Unix function when passed the contents of the Timestamp, in the UTC
// locale. This may or may not be a meaningful time; many invalid Timestamps
// do map to valid time.Times.
//
// A nil Timestamp returns an error. The first return value in that case is
// undefined.
func TimestampFromProto(ts *Timestamp) (time.Time, error) {
// Don't return the zero value on error, because corresponds to a valid
// timestamp. Instead return whatever time.Unix gives us.
var t time.Time
if ts == nil {
t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
} else {
t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()
}
return t, validateTimestamp(ts)
}
// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
// It returns an error if the resulting Timestamp is invalid.
func TimestampProto(t time.Time) (*Timestamp, error) {
seconds := t.Unix()
nanos := int32(t.Sub(time.Unix(seconds, 0)))
ts := &Timestamp{
Seconds: seconds,
Nanos: nanos,
}
if err := validateTimestamp(ts); err != nil {
return nil, err
}
return ts, nil
}
// TimestampString returns the RFC 3339 string for valid Timestamps. For invalid
// Timestamps, it returns an error message in parentheses.
func TimestampString(ts *Timestamp) string {
t, err := TimestampFromProto(ts)
if err != nil {
return fmt.Sprintf("(%v)", err)
}
return t.Format(time.RFC3339Nano)
}

527
vendor/github.com/gogo/protobuf/types/timestamp.pb.go generated vendored Normal file
View file

@ -0,0 +1,527 @@
// Code generated by protoc-gen-gogo.
// source: timestamp.proto
// DO NOT EDIT!
/*
Package types is a generated protocol buffer package.
It is generated from these files:
timestamp.proto
It has these top-level messages:
Timestamp
*/
package types
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import strings "strings"
import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto"
import sort "sort"
import strconv "strconv"
import reflect "reflect"
import io "io"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
// A Timestamp represents a point in time independent of any time zone
// or calendar, represented as seconds and fractions of seconds at
// nanosecond resolution in UTC Epoch time. It is encoded using the
// Proleptic Gregorian Calendar which extends the Gregorian calendar
// backwards to year one. It is encoded assuming all minutes are 60
// seconds long, i.e. leap seconds are "smeared" so that no leap second
// table is needed for interpretation. Range is from
// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
// By restricting to that range, we ensure that we can convert to
// and from RFC 3339 date strings.
// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
//
// Example 1: Compute Timestamp from POSIX `time()`.
//
// Timestamp timestamp;
// timestamp.set_seconds(time(NULL));
// timestamp.set_nanos(0);
//
// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
//
// struct timeval tv;
// gettimeofday(&tv, NULL);
//
// Timestamp timestamp;
// timestamp.set_seconds(tv.tv_sec);
// timestamp.set_nanos(tv.tv_usec * 1000);
//
// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
//
// FILETIME ft;
// GetSystemTimeAsFileTime(&ft);
// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
//
// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
// Timestamp timestamp;
// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
//
// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
//
// long millis = System.currentTimeMillis();
//
// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
// .setNanos((int) ((millis % 1000) * 1000000)).build();
//
//
// Example 5: Compute Timestamp from current time in Python.
//
// now = time.time()
// seconds = int(now)
// nanos = int((now - seconds) * 10**9)
// timestamp = Timestamp(seconds=seconds, nanos=nanos)
//
//
type Timestamp struct {
// Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive.
Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
// Non-negative fractions of a second at nanosecond resolution. Negative
// second values with fractions must still have non-negative nanos values
// that count forward in time. Must be from 0 to 999,999,999
// inclusive.
Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
}
func (m *Timestamp) Reset() { *m = Timestamp{} }
func (*Timestamp) ProtoMessage() {}
func (*Timestamp) Descriptor() ([]byte, []int) { return fileDescriptorTimestamp, []int{0} }
func (*Timestamp) XXX_WellKnownType() string { return "Timestamp" }
func (m *Timestamp) GetSeconds() int64 {
if m != nil {
return m.Seconds
}
return 0
}
func (m *Timestamp) GetNanos() int32 {
if m != nil {
return m.Nanos
}
return 0
}
func init() {
proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp")
}
func (this *Timestamp) Compare(that interface{}) int {
if that == nil {
if this == nil {
return 0
}
return 1
}
that1, ok := that.(*Timestamp)
if !ok {
that2, ok := that.(Timestamp)
if ok {
that1 = &that2
} else {
return 1
}
}
if that1 == nil {
if this == nil {
return 0
}
return 1
} else if this == nil {
return -1
}
if this.Seconds != that1.Seconds {
if this.Seconds < that1.Seconds {
return -1
}
return 1
}
if this.Nanos != that1.Nanos {
if this.Nanos < that1.Nanos {
return -1
}
return 1
}
return 0
}
func (this *Timestamp) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*Timestamp)
if !ok {
that2, ok := that.(Timestamp)
if ok {
that1 = &that2
} else {
return false
}
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
if this.Seconds != that1.Seconds {
return false
}
if this.Nanos != that1.Nanos {
return false
}
return true
}
func (this *Timestamp) GoString() string {
if this == nil {
return "nil"
}
s := make([]string, 0, 6)
s = append(s, "&types.Timestamp{")
s = append(s, "Seconds: "+fmt.Sprintf("%#v", this.Seconds)+",\n")
s = append(s, "Nanos: "+fmt.Sprintf("%#v", this.Nanos)+",\n")
s = append(s, "}")
return strings.Join(s, "")
}
func valueToGoStringTimestamp(v interface{}, typ string) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func extensionToGoStringTimestamp(m github_com_gogo_protobuf_proto.Message) string {
e := github_com_gogo_protobuf_proto.GetUnsafeExtensionsMap(m)
if e == nil {
return "nil"
}
s := "proto.NewUnsafeXXX_InternalExtensions(map[int32]proto.Extension{"
keys := make([]int, 0, len(e))
for k := range e {
keys = append(keys, int(k))
}
sort.Ints(keys)
ss := []string{}
for _, k := range keys {
ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString())
}
s += strings.Join(ss, ",") + "})"
return s
}
func (m *Timestamp) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Timestamp) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.Seconds != 0 {
dAtA[i] = 0x8
i++
i = encodeVarintTimestamp(dAtA, i, uint64(m.Seconds))
}
if m.Nanos != 0 {
dAtA[i] = 0x10
i++
i = encodeVarintTimestamp(dAtA, i, uint64(m.Nanos))
}
return i, nil
}
func encodeFixed64Timestamp(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Timestamp(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintTimestamp(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
}
func (m *Timestamp) Size() (n int) {
var l int
_ = l
if m.Seconds != 0 {
n += 1 + sovTimestamp(uint64(m.Seconds))
}
if m.Nanos != 0 {
n += 1 + sovTimestamp(uint64(m.Nanos))
}
return n
}
func sovTimestamp(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozTimestamp(x uint64) (n int) {
return sovTimestamp(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *Timestamp) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimestamp
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Timestamp: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Timestamp: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Seconds", wireType)
}
m.Seconds = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimestamp
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Seconds |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Nanos", wireType)
}
m.Nanos = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimestamp
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Nanos |= (int32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipTimestamp(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthTimestamp
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipTimestamp(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTimestamp
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTimestamp
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
return iNdEx, nil
case 1:
iNdEx += 8
return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTimestamp
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthTimestamp
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTimestamp
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
innerWire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
innerWireType := int(innerWire & 0x7)
if innerWireType == 4 {
break
}
next, err := skipTimestamp(dAtA[start:])
if err != nil {
return 0, err
}
iNdEx = start + next
}
return iNdEx, nil
case 4:
return iNdEx, nil
case 5:
iNdEx += 4
return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
}
panic("unreachable")
}
var (
ErrInvalidLengthTimestamp = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowTimestamp = fmt.Errorf("proto: integer overflow")
)
func init() { proto.RegisterFile("timestamp.proto", fileDescriptorTimestamp) }
var fileDescriptorTimestamp = []byte{
// 208 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x2f, 0xc9, 0xcc, 0x4d,
0x2d, 0x2e, 0x49, 0xcc, 0x2d, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x4f, 0xcf, 0xcf,
0x4f, 0xcf, 0x49, 0x85, 0xf0, 0x92, 0x4a, 0xd3, 0x94, 0xac, 0xb9, 0x38, 0x43, 0x60, 0x6a, 0x84,
0x24, 0xb8, 0xd8, 0x8b, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25, 0x18, 0x15, 0x18, 0x35, 0x98,
0x83, 0x60, 0x5c, 0x21, 0x11, 0x2e, 0xd6, 0xbc, 0xc4, 0xbc, 0xfc, 0x62, 0x09, 0x26, 0x05, 0x46,
0x0d, 0xd6, 0x20, 0x08, 0xc7, 0xa9, 0x99, 0xf1, 0xc2, 0x43, 0x39, 0x86, 0x1b, 0x0f, 0xe5, 0x18,
0x3e, 0x3c, 0x94, 0x63, 0x5c, 0xf1, 0x48, 0x8e, 0xf1, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4,
0x18, 0x1f, 0x3c, 0x92, 0x63, 0x7c, 0xf1, 0x48, 0x8e, 0xe1, 0xc3, 0x23, 0x39, 0xc6, 0x15, 0x8f,
0xe5, 0x18, 0xb9, 0x84, 0x93, 0xf3, 0x73, 0xf5, 0xd0, 0x2c, 0x77, 0xe2, 0x83, 0x5b, 0x1d, 0x00,
0x12, 0x0a, 0x60, 0x8c, 0x62, 0x2d, 0xa9, 0x2c, 0x48, 0x2d, 0x5e, 0xc0, 0xc8, 0xf8, 0x83, 0x91,
0x71, 0x11, 0x13, 0xb3, 0x7b, 0x80, 0xd3, 0x2a, 0x26, 0x39, 0x77, 0x88, 0xb6, 0x00, 0xa8, 0x36,
0xbd, 0xf0, 0xd4, 0x9c, 0x1c, 0xef, 0xbc, 0xfc, 0xf2, 0xbc, 0x10, 0x90, 0xe2, 0x24, 0x36, 0xb0,
0x79, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7c, 0x4d, 0xbd, 0x9c, 0xed, 0x00, 0x00, 0x00,
}

View file

@ -0,0 +1,94 @@
// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2016, The GoGo Authors. All rights reserved.
// http://github.com/gogo/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package types
import (
"time"
)
func NewPopulatedTimestamp(r interface {
Int63() int64
}, easy bool) *Timestamp {
this := &Timestamp{}
ns := int64(r.Int63())
this.Seconds = ns / 1e9
this.Nanos = int32(ns % 1e9)
return this
}
func (ts *Timestamp) String() string {
return TimestampString(ts)
}
func NewPopulatedStdTime(r interface {
Int63() int64
}, easy bool) *time.Time {
timestamp := NewPopulatedTimestamp(r, easy)
t, err := TimestampFromProto(timestamp)
if err != nil {
return nil
}
return &t
}
func SizeOfStdTime(t time.Time) int {
ts, err := TimestampProto(t)
if err != nil {
return 0
}
return ts.Size()
}
func StdTimeMarshal(t time.Time) ([]byte, error) {
size := SizeOfStdTime(t)
buf := make([]byte, size)
_, err := StdTimeMarshalTo(t, buf)
return buf, err
}
func StdTimeMarshalTo(t time.Time, data []byte) (int, error) {
ts, err := TimestampProto(t)
if err != nil {
return 0, err
}
return ts.MarshalTo(data)
}
func StdTimeUnmarshal(t *time.Time, data []byte) error {
ts := &Timestamp{}
if err := ts.Unmarshal(data); err != nil {
return err
}
tt, err := TimestampFromProto(ts)
if err != nil {
return err
}
*t = tt
return nil
}

2280
vendor/github.com/gogo/protobuf/types/wrappers.pb.go generated vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,20 +0,0 @@
The MIT License (MIT)
Copyright (c) 2012-2016 Apcera Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -1,45 +0,0 @@
// Copyright 2016 Apcera Inc. All rights reserved.
package auth
import (
"github.com/nats-io/gnatsd/server"
"golang.org/x/crypto/bcrypt"
)
// Plain authentication is a basic username and password
type MultiUser struct {
users map[string]*server.User
}
// Create a new multi-user
func NewMultiUser(users []*server.User) *MultiUser {
m := &MultiUser{users: make(map[string]*server.User)}
for _, u := range users {
m.users[u.Username] = u
}
return m
}
// Check authenticates the client using a username and password against a list of multiple users.
func (m *MultiUser) Check(c server.ClientAuth) bool {
opts := c.GetOpts()
user, ok := m.users[opts.Username]
if !ok {
return false
}
pass := user.Password
// Check to see if the password is a bcrypt hash
if isBcrypt(pass) {
if err := bcrypt.CompareHashAndPassword([]byte(pass), []byte(opts.Password)); err != nil {
return false
}
} else if pass != opts.Password {
return false
}
c.RegisterUser(user)
return true
}

View file

@ -1,40 +0,0 @@
// Copyright 2014-2015 Apcera Inc. All rights reserved.
package auth
import (
"strings"
"github.com/nats-io/gnatsd/server"
"golang.org/x/crypto/bcrypt"
)
const bcryptPrefix = "$2a$"
func isBcrypt(password string) bool {
return strings.HasPrefix(password, bcryptPrefix)
}
// Plain authentication is a basic username and password
type Plain struct {
Username string
Password string
}
// Check authenticates the client using a username and password
func (p *Plain) Check(c server.ClientAuth) bool {
opts := c.GetOpts()
if p.Username != opts.Username {
return false
}
// Check to see if the password is a bcrypt hash
if isBcrypt(p.Password) {
if err := bcrypt.CompareHashAndPassword([]byte(p.Password), []byte(opts.Password)); err != nil {
return false
}
} else if p.Password != opts.Password {
return false
}
return true
}

View file

@ -1,26 +0,0 @@
package auth
import (
"github.com/nats-io/gnatsd/server"
"golang.org/x/crypto/bcrypt"
)
// Token holds a string token used for authentication
type Token struct {
Token string
}
// Check authenticates a client from a token
func (p *Token) Check(c server.ClientAuth) bool {
opts := c.GetOpts()
// Check to see if the token is a bcrypt hash
if isBcrypt(p.Token) {
if err := bcrypt.CompareHashAndPassword([]byte(p.Token), []byte(opts.Authorization)); err != nil {
return false
}
} else if p.Token != opts.Authorization {
return false
}
return true
}

File diff suppressed because it is too large Load diff

View file

@ -1,284 +0,0 @@
// Copyright 2013-2016 Apcera Inc. All rights reserved.
// Package conf supports a configuration file format used by gnatsd. It is
// a flexible format that combines the best of traditional
// configuration formats and newer styles such as JSON and YAML.
package conf
// The format supported is less restrictive than today's formats.
// Supports mixed Arrays [], nested Maps {}, multiple comment types (# and //)
// Also supports key value assigments using '=' or ':' or whiteSpace()
// e.g. foo = 2, foo : 2, foo 2
// maps can be assigned with no key separator as well
// semicolons as value terminators in key/value assignments are optional
//
// see parse_test.go for more examples.
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"unicode"
)
type parser struct {
mapping map[string]interface{}
lx *lexer
// The current scoped context, can be array or map
ctx interface{}
// stack of contexts, either map or array/slice stack
ctxs []interface{}
// Keys stack
keys []string
// The config file path, empty by default.
fp string
}
// Parse will return a map of keys to interface{}, although concrete types
// underly them. The values supported are string, bool, int64, float64, DateTime.
// Arrays and nested Maps are also supported.
func Parse(data string) (map[string]interface{}, error) {
p, err := parse(data, "")
if err != nil {
return nil, err
}
return p.mapping, nil
}
// ParseFile is a helper to open file, etc. and parse the contents.
func ParseFile(fp string) (map[string]interface{}, error) {
data, err := ioutil.ReadFile(fp)
if err != nil {
return nil, fmt.Errorf("error opening config file: %v", err)
}
p, err := parse(string(data), filepath.Dir(fp))
if err != nil {
return nil, err
}
return p.mapping, nil
}
func parse(data, fp string) (p *parser, err error) {
p = &parser{
mapping: make(map[string]interface{}),
lx: lex(data),
ctxs: make([]interface{}, 0, 4),
keys: make([]string, 0, 4),
fp: fp,
}
p.pushContext(p.mapping)
for {
it := p.next()
if it.typ == itemEOF {
break
}
if err := p.processItem(it); err != nil {
return nil, err
}
}
return p, nil
}
func (p *parser) next() item {
return p.lx.nextItem()
}
func (p *parser) pushContext(ctx interface{}) {
p.ctxs = append(p.ctxs, ctx)
p.ctx = ctx
}
func (p *parser) popContext() interface{} {
if len(p.ctxs) == 0 {
panic("BUG in parser, context stack empty")
}
li := len(p.ctxs) - 1
last := p.ctxs[li]
p.ctxs = p.ctxs[0:li]
p.ctx = p.ctxs[len(p.ctxs)-1]
return last
}
func (p *parser) pushKey(key string) {
p.keys = append(p.keys, key)
}
func (p *parser) popKey() string {
if len(p.keys) == 0 {
panic("BUG in parser, keys stack empty")
}
li := len(p.keys) - 1
last := p.keys[li]
p.keys = p.keys[0:li]
return last
}
func (p *parser) processItem(it item) error {
switch it.typ {
case itemError:
return fmt.Errorf("Parse error on line %d: '%s'", it.line, it.val)
case itemKey:
p.pushKey(it.val)
case itemMapStart:
newCtx := make(map[string]interface{})
p.pushContext(newCtx)
case itemMapEnd:
p.setValue(p.popContext())
case itemString:
p.setValue(it.val) // FIXME(dlc) sanitize string?
case itemInteger:
lastDigit := 0
for _, r := range it.val {
if !unicode.IsDigit(r) {
break
}
lastDigit++
}
numStr := it.val[:lastDigit]
num, err := strconv.ParseInt(numStr, 10, 64)
if err != nil {
if e, ok := err.(*strconv.NumError); ok &&
e.Err == strconv.ErrRange {
return fmt.Errorf("Integer '%s' is out of the range.", it.val)
}
return fmt.Errorf("Expected integer, but got '%s'.", it.val)
}
// Process a suffix
suffix := strings.ToLower(strings.TrimSpace(it.val[lastDigit:]))
switch suffix {
case "":
p.setValue(num)
case "k":
p.setValue(num * 1000)
case "kb":
p.setValue(num * 1024)
case "m":
p.setValue(num * 1000 * 1000)
case "mb":
p.setValue(num * 1024 * 1024)
case "g":
p.setValue(num * 1000 * 1000 * 1000)
case "gb":
p.setValue(num * 1024 * 1024 * 1024)
}
case itemFloat:
num, err := strconv.ParseFloat(it.val, 64)
if err != nil {
if e, ok := err.(*strconv.NumError); ok &&
e.Err == strconv.ErrRange {
return fmt.Errorf("Float '%s' is out of the range.", it.val)
}
return fmt.Errorf("Expected float, but got '%s'.", it.val)
}
p.setValue(num)
case itemBool:
switch strings.ToLower(it.val) {
case "true", "yes", "on":
p.setValue(true)
case "false", "no", "off":
p.setValue(false)
default:
return fmt.Errorf("Expected boolean value, but got '%s'.", it.val)
}
case itemDatetime:
dt, err := time.Parse("2006-01-02T15:04:05Z", it.val)
if err != nil {
return fmt.Errorf(
"Expected Zulu formatted DateTime, but got '%s'.", it.val)
}
p.setValue(dt)
case itemArrayStart:
var array = make([]interface{}, 0)
p.pushContext(array)
case itemArrayEnd:
array := p.ctx
p.popContext()
p.setValue(array)
case itemVariable:
if value, ok := p.lookupVariable(it.val); ok {
p.setValue(value)
} else {
return fmt.Errorf("Variable reference for '%s' on line %d can not be found.",
it.val, it.line)
}
case itemInclude:
m, err := ParseFile(filepath.Join(p.fp, it.val))
if err != nil {
return fmt.Errorf("Error parsing include file '%s', %v.", it.val, err)
}
for k, v := range m {
p.pushKey(k)
p.setValue(v)
}
}
return nil
}
// Used to map an environment value into a temporary map to pass to secondary Parse call.
const pkey = "pk"
// We special case raw strings here that are bcrypt'd. This allows us not to force quoting the strings
const bcryptPrefix = "2a$"
// lookupVariable will lookup a variable reference. It will use block scoping on keys
// it has seen before, with the top level scoping being the environment variables. We
// ignore array contexts and only process the map contexts..
//
// Returns true for ok if it finds something, similar to map.
func (p *parser) lookupVariable(varReference string) (interface{}, bool) {
// Do special check to see if it is a raw bcrypt string.
if strings.HasPrefix(varReference, bcryptPrefix) {
return "$" + varReference, true
}
// Loop through contexts currently on the stack.
for i := len(p.ctxs) - 1; i >= 0; i -= 1 {
ctx := p.ctxs[i]
// Process if it is a map context
if m, ok := ctx.(map[string]interface{}); ok {
if v, ok := m[varReference]; ok {
return v, ok
}
}
}
// If we are here, we have exhausted our context maps and still not found anything.
// Parse from the environment.
if vStr, ok := os.LookupEnv(varReference); ok {
// Everything we get here will be a string value, so we need to process as a parser would.
if vmap, err := Parse(fmt.Sprintf("%s=%s", pkey, vStr)); err == nil {
v, ok := vmap[pkey]
return v, ok
}
}
return nil, false
}
func (p *parser) setValue(val interface{}) {
// Test to see if we are on an array or a map
// Array processing
if ctx, ok := p.ctx.([]interface{}); ok {
p.ctx = append(ctx, val)
p.ctxs[len(p.ctxs)-1] = p.ctx
}
// Map processing
if ctx, ok := p.ctx.(map[string]interface{}); ok {
key := p.popKey()
// FIXME(dlc), make sure to error if redefining same key?
ctx[key] = val
}
}

View file

@ -1,128 +0,0 @@
// Copyright 2012-2015 Apcera Inc. All rights reserved.
//Package logger provides logging facilities for the NATS server
package logger
import (
"fmt"
"log"
"os"
)
// Logger is the server logger
type Logger struct {
logger *log.Logger
debug bool
trace bool
infoLabel string
errorLabel string
fatalLabel string
debugLabel string
traceLabel string
}
// NewStdLogger creates a logger with output directed to Stderr
func NewStdLogger(time, debug, trace, colors, pid bool) *Logger {
flags := 0
if time {
flags = log.LstdFlags | log.Lmicroseconds
}
pre := ""
if pid {
pre = pidPrefix()
}
l := &Logger{
logger: log.New(os.Stderr, pre, flags),
debug: debug,
trace: trace,
}
if colors {
setColoredLabelFormats(l)
} else {
setPlainLabelFormats(l)
}
return l
}
// NewFileLogger creates a logger with output directed to a file
func NewFileLogger(filename string, time, debug, trace, pid bool) *Logger {
fileflags := os.O_WRONLY | os.O_APPEND | os.O_CREATE
f, err := os.OpenFile(filename, fileflags, 0660)
if err != nil {
log.Fatalf("error opening file: %v", err)
}
flags := 0
if time {
flags = log.LstdFlags | log.Lmicroseconds
}
pre := ""
if pid {
pre = pidPrefix()
}
l := &Logger{
logger: log.New(f, pre, flags),
debug: debug,
trace: trace,
}
setPlainLabelFormats(l)
return l
}
// Generate the pid prefix string
func pidPrefix() string {
return fmt.Sprintf("[%d] ", os.Getpid())
}
func setPlainLabelFormats(l *Logger) {
l.infoLabel = "[INF] "
l.debugLabel = "[DBG] "
l.errorLabel = "[ERR] "
l.fatalLabel = "[FTL] "
l.traceLabel = "[TRC] "
}
func setColoredLabelFormats(l *Logger) {
colorFormat := "[\x1b[%dm%s\x1b[0m] "
l.infoLabel = fmt.Sprintf(colorFormat, 32, "INF")
l.debugLabel = fmt.Sprintf(colorFormat, 36, "DBG")
l.errorLabel = fmt.Sprintf(colorFormat, 31, "ERR")
l.fatalLabel = fmt.Sprintf(colorFormat, 31, "FTL")
l.traceLabel = fmt.Sprintf(colorFormat, 33, "TRC")
}
// Noticef logs a notice statement
func (l *Logger) Noticef(format string, v ...interface{}) {
l.logger.Printf(l.infoLabel+format, v...)
}
// Errorf logs an error statement
func (l *Logger) Errorf(format string, v ...interface{}) {
l.logger.Printf(l.errorLabel+format, v...)
}
// Fatalf logs a fatal error
func (l *Logger) Fatalf(format string, v ...interface{}) {
l.logger.Fatalf(l.fatalLabel+format, v...)
}
// Debugf logs a debug statement
func (l *Logger) Debugf(format string, v ...interface{}) {
if l.debug {
l.logger.Printf(l.debugLabel+format, v...)
}
}
// Tracef logs a trace statement
func (l *Logger) Tracef(format string, v ...interface{}) {
if l.trace {
l.logger.Printf(l.traceLabel+format, v...)
}
}

View file

@ -1,112 +0,0 @@
// Copyright 2012-2014 Apcera Inc. All rights reserved.
// +build !windows
package logger
import (
"fmt"
"log"
"log/syslog"
"net/url"
"os"
"strings"
)
// SysLogger provides a system logger facility
type SysLogger struct {
writer *syslog.Writer
debug bool
trace bool
}
// GetSysLoggerTag generates the tag name for use in syslog statements. If
// the executable is linked, the name of the link will be used as the tag,
// otherwise, the name of the executable is used. "gnatsd" is the default
// for the NATS server.
func GetSysLoggerTag() string {
procName := os.Args[0]
if strings.ContainsRune(procName, os.PathSeparator) {
parts := strings.FieldsFunc(procName, func(c rune) bool {
return c == os.PathSeparator
})
procName = parts[len(parts)-1]
}
return procName
}
// NewSysLogger creates a new system logger
func NewSysLogger(debug, trace bool) *SysLogger {
w, err := syslog.New(syslog.LOG_DAEMON|syslog.LOG_NOTICE, GetSysLoggerTag())
if err != nil {
log.Fatalf("error connecting to syslog: %q", err.Error())
}
return &SysLogger{
writer: w,
debug: debug,
trace: trace,
}
}
// NewRemoteSysLogger creates a new remote system logger
func NewRemoteSysLogger(fqn string, debug, trace bool) *SysLogger {
network, addr := getNetworkAndAddr(fqn)
w, err := syslog.Dial(network, addr, syslog.LOG_DEBUG, GetSysLoggerTag())
if err != nil {
log.Fatalf("error connecting to syslog: %q", err.Error())
}
return &SysLogger{
writer: w,
debug: debug,
trace: trace,
}
}
func getNetworkAndAddr(fqn string) (network, addr string) {
u, err := url.Parse(fqn)
if err != nil {
log.Fatal(err)
}
network = u.Scheme
if network == "udp" || network == "tcp" {
addr = u.Host
} else if network == "unix" {
addr = u.Path
} else {
log.Fatalf("error invalid network type: %q", u.Scheme)
}
return
}
// Noticef logs a notice statement
func (l *SysLogger) Noticef(format string, v ...interface{}) {
l.writer.Notice(fmt.Sprintf(format, v...))
}
// Fatalf logs a fatal error
func (l *SysLogger) Fatalf(format string, v ...interface{}) {
l.writer.Crit(fmt.Sprintf(format, v...))
}
// Errorf logs an error statement
func (l *SysLogger) Errorf(format string, v ...interface{}) {
l.writer.Err(fmt.Sprintf(format, v...))
}
// Debugf logs a debug statement
func (l *SysLogger) Debugf(format string, v ...interface{}) {
if l.debug {
l.writer.Debug(fmt.Sprintf(format, v...))
}
}
// Tracef logs a trace statement
func (l *SysLogger) Tracef(format string, v ...interface{}) {
if l.trace {
l.writer.Notice(fmt.Sprintf(format, v...))
}
}

View file

@ -1,52 +0,0 @@
// Copyright 2012-2014 Apcera Inc. All rights reserved.
package logger
import (
"fmt"
"log"
"os"
)
type SysLogger struct {
writer *log.Logger
debug bool
trace bool
}
func NewSysLogger(debug, trace bool) *SysLogger {
w := log.New(os.Stdout, "gnatsd", log.LstdFlags)
return &SysLogger{
writer: w,
debug: debug,
trace: trace,
}
}
func NewRemoteSysLogger(fqn string, debug, trace bool) *SysLogger {
return NewSysLogger(debug, trace)
}
func (l *SysLogger) Noticef(format string, v ...interface{}) {
l.writer.Println("NOTICE", fmt.Sprintf(format, v...))
}
func (l *SysLogger) Fatalf(format string, v ...interface{}) {
l.writer.Println("CRITICAL", fmt.Sprintf(format, v...))
}
func (l *SysLogger) Errorf(format string, v ...interface{}) {
l.writer.Println("ERROR", fmt.Sprintf(format, v...))
}
func (l *SysLogger) Debugf(format string, v ...interface{}) {
if l.debug {
l.writer.Println("DEBUG", fmt.Sprintf(format, v...))
}
}
func (l *SysLogger) Tracef(format string, v ...interface{}) {
if l.trace {
l.writer.Println("NOTICE", fmt.Sprintf(format, v...))
}
}

View file

@ -1,17 +0,0 @@
// Copyright 2012-2014 Apcera Inc. All rights reserved.
package server
// Auth is an interface for implementing authentication
type Auth interface {
// Check if a client is authorized to connect
Check(c ClientAuth) bool
}
// ClientAuth is an interface for client authentication
type ClientAuth interface {
// Get options associated with a client
GetOpts() *clientOpts
// Optionally map a user after auth.
RegisterUser(*User)
}

View file

@ -1,33 +0,0 @@
// Copyright 2015 Apcera Inc. All rights reserved.
// +build go1.4,!go1.5
package server
import (
"crypto/tls"
)
// Where we maintain all of the available 1.4 ciphers
var cipherMap = map[string]uint16{
"TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA,
"TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
"TLS_RSA_WITH_AES_128_CBC_SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA,
"TLS_RSA_WITH_AES_256_CBC_SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA,
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
"TLS_ECDHE_RSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
}
func defaultCipherSuites() []uint16 {
return []uint16{
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
}
}

View file

@ -1,38 +0,0 @@
// Copyright 2015 Apcera Inc. All rights reserved.
// +build go1.5
package server
import (
"crypto/tls"
)
// Where we maintain all of the available 1.5 ciphers
var cipherMap = map[string]uint16{
"TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA,
"TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
"TLS_RSA_WITH_AES_128_CBC_SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA,
"TLS_RSA_WITH_AES_256_CBC_SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA,
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
"TLS_ECDHE_RSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
}
func defaultCipherSuites() []uint16 {
return []uint16{
// The SHA384 versions are only in Go1.5
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,82 +0,0 @@
// Copyright 2012-2016 Apcera Inc. All rights reserved.
package server
import (
"time"
)
const (
// VERSION is the current version for the server.
VERSION = "0.9.6"
// DEFAULT_PORT is the default port for client connections.
DEFAULT_PORT = 4222
// RANDOM_PORT is the value for port that, when supplied, will cause the
// server to listen on a randomly-chosen available port. The resolved port
// is available via the Addr() method.
RANDOM_PORT = -1
// DEFAULT_HOST defaults to all interfaces.
DEFAULT_HOST = "0.0.0.0"
// MAX_CONTROL_LINE_SIZE is the maximum allowed protocol control line size.
// 1k should be plenty since payloads sans connect string are separate
MAX_CONTROL_LINE_SIZE = 1024
// MAX_PAYLOAD_SIZE is the maximum allowed payload size. Should be using
// something different if > 1MB payloads are needed.
MAX_PAYLOAD_SIZE = (1024 * 1024)
// DEFAULT_MAX_CONNECTIONS is the default maximum connections allowed.
DEFAULT_MAX_CONNECTIONS = (64 * 1024)
// TLS_TIMEOUT is the TLS wait time.
TLS_TIMEOUT = 500 * time.Millisecond
// AUTH_TIMEOUT is the authorization wait time.
AUTH_TIMEOUT = 2 * TLS_TIMEOUT
// DEFAULT_PING_INTERVAL is how often pings are sent to clients and routes.
DEFAULT_PING_INTERVAL = 2 * time.Minute
// DEFAULT_PING_MAX_OUT is maximum allowed pings outstanding before disconnect.
DEFAULT_PING_MAX_OUT = 2
// CR_LF string
CR_LF = "\r\n"
// LEN_CR_LF hold onto the computed size.
LEN_CR_LF = len(CR_LF)
// DEFAULT_FLUSH_DEADLINE is the write/flush deadlines.
DEFAULT_FLUSH_DEADLINE = 2 * time.Second
// DEFAULT_HTTP_PORT is the default monitoring port.
DEFAULT_HTTP_PORT = 8222
// ACCEPT_MIN_SLEEP is the minimum acceptable sleep times on temporary errors.
ACCEPT_MIN_SLEEP = 10 * time.Millisecond
// ACCEPT_MAX_SLEEP is the maximum acceptable sleep times on temporary errors
ACCEPT_MAX_SLEEP = 1 * time.Second
// DEFAULT_ROUTE_CONNECT Route solicitation intervals.
DEFAULT_ROUTE_CONNECT = 1 * time.Second
// DEFAULT_ROUTE_RECONNECT Route reconnect intervals.
DEFAULT_ROUTE_RECONNECT = 1 * time.Second
// DEFAULT_ROUTE_DIAL Route dial timeout.
DEFAULT_ROUTE_DIAL = 1 * time.Second
// PROTO_SNIPPET_SIZE is the default size of proto to print on parse errors.
PROTO_SNIPPET_SIZE = 32
// MAX_MSG_ARGS Maximum possible number of arguments from MSG proto.
MAX_MSG_ARGS = 4
// MAX_PUB_ARGS Maximum possible number of arguments from PUB proto.
MAX_PUB_ARGS = 3
)

View file

@ -1,32 +0,0 @@
// Copyright 2012-2016 Apcera Inc. All rights reserved.
package server
import "errors"
var (
// ErrConnectionClosed represents an error condition on a closed connection.
ErrConnectionClosed = errors.New("Connection Closed")
// ErrAuthorization represents an error condition on failed authorization.
ErrAuthorization = errors.New("Authorization Error")
// ErrAuthTimeout represents an error condition on failed authorization due to timeout.
ErrAuthTimeout = errors.New("Authorization Timeout")
// ErrMaxPayload represents an error condition when the payload is too big.
ErrMaxPayload = errors.New("Maximum Payload Exceeded")
// ErrMaxControlLine represents an error condition when the control line is too big.
ErrMaxControlLine = errors.New("Maximum Control Line Exceeded")
// ErrReservedPublishSubject represents an error condition when sending to a reserved subject, e.g. _SYS.>
ErrReservedPublishSubject = errors.New("Reserved Internal Subject")
// ErrBadClientProtocol signals a client requested an invalud client protocol.
ErrBadClientProtocol = errors.New("Invalid Client Protocol")
// ErrTooManyConnections signals a client that the maximum number of connections supported by the
// server has been reached.
ErrTooManyConnections = errors.New("Maximum Connections Exceeded")
)

View file

@ -1,132 +0,0 @@
// Copyright 2012-2016 Apcera Inc. All rights reserved.
package server
import (
"sync"
"sync/atomic"
"github.com/nats-io/gnatsd/logger"
)
// Package globals for performance checks
var trace int32
var debug int32
var log = struct {
sync.Mutex
logger Logger
}{}
// Logger interface of the NATS Server
type Logger interface {
// Log a notice statement
Noticef(format string, v ...interface{})
// Log a fatal error
Fatalf(format string, v ...interface{})
// Log an error
Errorf(format string, v ...interface{})
// Log a debug statement
Debugf(format string, v ...interface{})
// Log a trace statement
Tracef(format string, v ...interface{})
}
// SetLogger sets the logger of the server
func (s *Server) SetLogger(logger Logger, debugFlag, traceFlag bool) {
if debugFlag {
atomic.StoreInt32(&debug, 1)
} else {
atomic.StoreInt32(&debug, 0)
}
if traceFlag {
atomic.StoreInt32(&trace, 1)
} else {
atomic.StoreInt32(&trace, 0)
}
log.Lock()
log.logger = logger
log.Unlock()
}
// If the logger is a file based logger, close and re-open the file.
// This allows for file rotation by 'mv'ing the file then signalling
// the process to trigger this function.
func (s *Server) ReOpenLogFile() {
// Check to make sure this is a file logger.
log.Lock()
ll := log.logger
log.Unlock()
if ll == nil {
Noticef("File log re-open ignored, no logger")
return
}
if s.opts.LogFile == "" {
Noticef("File log re-open ignored, not a file logger")
} else {
fileLog := logger.NewFileLogger(s.opts.LogFile,
s.opts.Logtime, s.opts.Debug, s.opts.Trace, true)
s.SetLogger(fileLog, s.opts.Debug, s.opts.Trace)
Noticef("File log re-opened")
}
}
// Noticef logs a notice statement
func Noticef(format string, v ...interface{}) {
executeLogCall(func(logger Logger, format string, v ...interface{}) {
logger.Noticef(format, v...)
}, format, v...)
}
// Errorf logs an error
func Errorf(format string, v ...interface{}) {
executeLogCall(func(logger Logger, format string, v ...interface{}) {
logger.Errorf(format, v...)
}, format, v...)
}
// Fatalf logs a fatal error
func Fatalf(format string, v ...interface{}) {
executeLogCall(func(logger Logger, format string, v ...interface{}) {
logger.Fatalf(format, v...)
}, format, v...)
}
// Debugf logs a debug statement
func Debugf(format string, v ...interface{}) {
if atomic.LoadInt32(&debug) == 0 {
return
}
executeLogCall(func(logger Logger, format string, v ...interface{}) {
logger.Debugf(format, v...)
}, format, v...)
}
// Tracef logs a trace statement
func Tracef(format string, v ...interface{}) {
if atomic.LoadInt32(&trace) == 0 {
return
}
executeLogCall(func(logger Logger, format string, v ...interface{}) {
logger.Tracef(format, v...)
}, format, v...)
}
func executeLogCall(f func(logger Logger, format string, v ...interface{}), format string, args ...interface{}) {
log.Lock()
defer log.Unlock()
if log.logger == nil {
return
}
f(log.logger, format, args...)
}

View file

@ -1,526 +0,0 @@
// Copyright 2013-2015 Apcera Inc. All rights reserved.
package server
import (
"crypto/tls"
"encoding/json"
"fmt"
"net"
"net/http"
"runtime"
"sort"
"strconv"
"sync/atomic"
"time"
"github.com/nats-io/gnatsd/server/pse"
)
// Snapshot this
var numCores int
func init() {
numCores = runtime.NumCPU()
}
// Connz represents detailed information on current client connections.
type Connz struct {
Now time.Time `json:"now"`
NumConns int `json:"num_connections"`
Total int `json:"total"`
Offset int `json:"offset"`
Limit int `json:"limit"`
Conns []ConnInfo `json:"connections"`
}
// ConnInfo has detailed information on a per connection basis.
type ConnInfo struct {
Cid uint64 `json:"cid"`
IP string `json:"ip"`
Port int `json:"port"`
Start time.Time `json:"start"`
LastActivity time.Time `json:"last_activity"`
Uptime string `json:"uptime"`
Idle string `json:"idle"`
Pending int `json:"pending_bytes"`
InMsgs int64 `json:"in_msgs"`
OutMsgs int64 `json:"out_msgs"`
InBytes int64 `json:"in_bytes"`
OutBytes int64 `json:"out_bytes"`
NumSubs uint32 `json:"subscriptions"`
Name string `json:"name,omitempty"`
Lang string `json:"lang,omitempty"`
Version string `json:"version,omitempty"`
TLSVersion string `json:"tls_version,omitempty"`
TLSCipher string `json:"tls_cipher_suite,omitempty"`
AuthorizedUser string `json:"authorized_user,omitempty"`
Subs []string `json:"subscriptions_list,omitempty"`
}
// DefaultConnListSize is the default size of the connection list.
const DefaultConnListSize = 1024
const defaultStackBufSize = 10000
// HandleConnz process HTTP requests for connection information.
func (s *Server) HandleConnz(w http.ResponseWriter, r *http.Request) {
sortOpt := SortOpt(r.URL.Query().Get("sort"))
// If no sort option given or sort is by uptime, then sort by cid
if sortOpt == "" || sortOpt == byUptime {
sortOpt = byCid
} else if !sortOpt.IsValid() {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(fmt.Sprintf("Invalid sorting option: %s", sortOpt)))
return
}
c := &Connz{}
c.Now = time.Now()
auth, _ := strconv.Atoi(r.URL.Query().Get("auth"))
subs, _ := strconv.Atoi(r.URL.Query().Get("subs"))
c.Offset, _ = strconv.Atoi(r.URL.Query().Get("offset"))
c.Limit, _ = strconv.Atoi(r.URL.Query().Get("limit"))
if c.Limit == 0 {
c.Limit = DefaultConnListSize
}
// Walk the list
s.mu.Lock()
s.httpReqStats[ConnzPath]++
tlsRequired := s.info.TLSRequired
// number total of clients. The resulting ConnInfo array
// may be smaller if pagination is used.
totalClients := len(s.clients)
c.Total = totalClients
i := 0
pairs := make(Pairs, totalClients)
for _, client := range s.clients {
client.mu.Lock()
switch sortOpt {
case byCid:
pairs[i] = Pair{Key: client, Val: int64(client.cid)}
case bySubs:
pairs[i] = Pair{Key: client, Val: int64(len(client.subs))}
case byPending:
pairs[i] = Pair{Key: client, Val: int64(client.bw.Buffered())}
case byOutMsgs:
pairs[i] = Pair{Key: client, Val: client.outMsgs}
case byInMsgs:
pairs[i] = Pair{Key: client, Val: atomic.LoadInt64(&client.inMsgs)}
case byOutBytes:
pairs[i] = Pair{Key: client, Val: client.outBytes}
case byInBytes:
pairs[i] = Pair{Key: client, Val: atomic.LoadInt64(&client.inBytes)}
case byLast:
pairs[i] = Pair{Key: client, Val: client.last.UnixNano()}
case byIdle:
pairs[i] = Pair{Key: client, Val: c.Now.Sub(client.last).Nanoseconds()}
}
client.mu.Unlock()
i++
}
s.mu.Unlock()
if totalClients > 0 {
if sortOpt == byCid {
// Return in ascending order
sort.Sort(pairs)
} else {
// Return in descending order
sort.Sort(sort.Reverse(pairs))
}
}
minoff := c.Offset
maxoff := c.Offset + c.Limit
// Make sure these are sane.
if minoff > totalClients {
minoff = totalClients
}
if maxoff > totalClients {
maxoff = totalClients
}
pairs = pairs[minoff:maxoff]
// Now we have the real number of ConnInfo objects, we can set c.NumConns
// and allocate the array
c.NumConns = len(pairs)
c.Conns = make([]ConnInfo, c.NumConns)
i = 0
for _, pair := range pairs {
client := pair.Key
client.mu.Lock()
// First, fill ConnInfo with current client's values. We will
// then overwrite the field used for the sort with what was stored
// in 'pair'.
ci := &c.Conns[i]
ci.Cid = client.cid
ci.Start = client.start
ci.LastActivity = client.last
ci.Uptime = myUptime(c.Now.Sub(client.start))
ci.Idle = myUptime(c.Now.Sub(client.last))
ci.OutMsgs = client.outMsgs
ci.OutBytes = client.outBytes
ci.NumSubs = uint32(len(client.subs))
ci.Pending = client.bw.Buffered()
ci.Name = client.opts.Name
ci.Lang = client.opts.Lang
ci.Version = client.opts.Version
// inMsgs and inBytes are updated outside of the client's lock, so
// we need to use atomic here.
ci.InMsgs = atomic.LoadInt64(&client.inMsgs)
ci.InBytes = atomic.LoadInt64(&client.inBytes)
// Now overwrite the field that was used as the sort key, so results
// still look sorted even if the value has changed since sort occurred.
sortValue := pair.Val
switch sortOpt {
case bySubs:
ci.NumSubs = uint32(sortValue)
case byPending:
ci.Pending = int(sortValue)
case byOutMsgs:
ci.OutMsgs = sortValue
case byInMsgs:
ci.InMsgs = sortValue
case byOutBytes:
ci.OutBytes = sortValue
case byInBytes:
ci.InBytes = sortValue
case byLast:
ci.LastActivity = time.Unix(0, sortValue)
case byIdle:
ci.Idle = myUptime(time.Duration(sortValue))
}
// If the connection is gone, too bad, we won't set TLSVersion and TLSCipher.
if tlsRequired && client.nc != nil {
conn := client.nc.(*tls.Conn)
cs := conn.ConnectionState()
ci.TLSVersion = tlsVersion(cs.Version)
ci.TLSCipher = tlsCipher(cs.CipherSuite)
}
switch conn := client.nc.(type) {
case *net.TCPConn, *tls.Conn:
addr := conn.RemoteAddr().(*net.TCPAddr)
ci.Port = addr.Port
ci.IP = addr.IP.String()
}
// Fill in subscription data if requested.
if subs == 1 {
sublist := make([]*subscription, 0, len(client.subs))
for _, sub := range client.subs {
sublist = append(sublist, sub)
}
ci.Subs = castToSliceString(sublist)
}
// Fill in user if auth requested.
if auth == 1 {
ci.AuthorizedUser = client.opts.Username
}
client.mu.Unlock()
i++
}
b, err := json.MarshalIndent(c, "", " ")
if err != nil {
Errorf("Error marshalling response to /connz request: %v", err)
}
// Handle response
ResponseHandler(w, r, b)
}
func castToSliceString(input []*subscription) []string {
output := make([]string, 0, len(input))
for _, line := range input {
output = append(output, string(line.subject))
}
return output
}
// Subsz represents detail information on current connections.
type Subsz struct {
*SublistStats
}
// Routez represents detailed information on current client connections.
type Routez struct {
Now time.Time `json:"now"`
NumRoutes int `json:"num_routes"`
Routes []*RouteInfo `json:"routes"`
}
// RouteInfo has detailed information on a per connection basis.
type RouteInfo struct {
Rid uint64 `json:"rid"`
RemoteID string `json:"remote_id"`
DidSolicit bool `json:"did_solicit"`
IsConfigured bool `json:"is_configured"`
IP string `json:"ip"`
Port int `json:"port"`
Pending int `json:"pending_size"`
InMsgs int64 `json:"in_msgs"`
OutMsgs int64 `json:"out_msgs"`
InBytes int64 `json:"in_bytes"`
OutBytes int64 `json:"out_bytes"`
NumSubs uint32 `json:"subscriptions"`
Subs []string `json:"subscriptions_list,omitempty"`
}
// HandleRoutez process HTTP requests for route information.
func (s *Server) HandleRoutez(w http.ResponseWriter, r *http.Request) {
rs := &Routez{Routes: []*RouteInfo{}}
rs.Now = time.Now()
subs, _ := strconv.Atoi(r.URL.Query().Get("subs"))
// Walk the list
s.mu.Lock()
s.httpReqStats[RoutezPath]++
rs.NumRoutes = len(s.routes)
for _, r := range s.routes {
r.mu.Lock()
ri := &RouteInfo{
Rid: r.cid,
RemoteID: r.route.remoteID,
DidSolicit: r.route.didSolicit,
IsConfigured: r.route.routeType == Explicit,
InMsgs: atomic.LoadInt64(&r.inMsgs),
OutMsgs: r.outMsgs,
InBytes: atomic.LoadInt64(&r.inBytes),
OutBytes: r.outBytes,
NumSubs: uint32(len(r.subs)),
}
if subs == 1 {
sublist := make([]*subscription, 0, len(r.subs))
for _, sub := range r.subs {
sublist = append(sublist, sub)
}
ri.Subs = castToSliceString(sublist)
}
r.mu.Unlock()
if ip, ok := r.nc.(*net.TCPConn); ok {
addr := ip.RemoteAddr().(*net.TCPAddr)
ri.Port = addr.Port
ri.IP = addr.IP.String()
}
rs.Routes = append(rs.Routes, ri)
}
s.mu.Unlock()
b, err := json.MarshalIndent(rs, "", " ")
if err != nil {
Errorf("Error marshalling response to /routez request: %v", err)
}
// Handle response
ResponseHandler(w, r, b)
}
// HandleSubsz processes HTTP requests for subjects stats.
func (s *Server) HandleSubsz(w http.ResponseWriter, r *http.Request) {
s.mu.Lock()
s.httpReqStats[SubszPath]++
s.mu.Unlock()
st := &Subsz{s.sl.Stats()}
b, err := json.MarshalIndent(st, "", " ")
if err != nil {
Errorf("Error marshalling response to /subscriptionsz request: %v", err)
}
// Handle response
ResponseHandler(w, r, b)
}
// HandleStacksz processes HTTP requests for getting stacks
func (s *Server) HandleStacksz(w http.ResponseWriter, r *http.Request) {
// Do not get any lock here that would prevent getting the stacks
// if we were to have a deadlock somewhere.
var defaultBuf [defaultStackBufSize]byte
size := defaultStackBufSize
buf := defaultBuf[:size]
n := 0
for {
n = runtime.Stack(buf, true)
if n < size {
break
}
size *= 2
buf = make([]byte, size)
}
// Handle response
ResponseHandler(w, r, buf[:n])
}
// Varz will output server information on the monitoring port at /varz.
type Varz struct {
*Info
*Options
Port int `json:"port"`
MaxPayload int `json:"max_payload"`
Start time.Time `json:"start"`
Now time.Time `json:"now"`
Uptime string `json:"uptime"`
Mem int64 `json:"mem"`
Cores int `json:"cores"`
CPU float64 `json:"cpu"`
Connections int `json:"connections"`
TotalConnections uint64 `json:"total_connections"`
Routes int `json:"routes"`
Remotes int `json:"remotes"`
InMsgs int64 `json:"in_msgs"`
OutMsgs int64 `json:"out_msgs"`
InBytes int64 `json:"in_bytes"`
OutBytes int64 `json:"out_bytes"`
SlowConsumers int64 `json:"slow_consumers"`
Subscriptions uint32 `json:"subscriptions"`
HTTPReqStats map[string]uint64 `json:"http_req_stats"`
}
type usage struct {
CPU float32
Cores int
Mem int64
}
func myUptime(d time.Duration) string {
// Just use total seconds for uptime, and display days / years
tsecs := d / time.Second
tmins := tsecs / 60
thrs := tmins / 60
tdays := thrs / 24
tyrs := tdays / 365
if tyrs > 0 {
return fmt.Sprintf("%dy%dd%dh%dm%ds", tyrs, tdays%365, thrs%24, tmins%60, tsecs%60)
}
if tdays > 0 {
return fmt.Sprintf("%dd%dh%dm%ds", tdays, thrs%24, tmins%60, tsecs%60)
}
if thrs > 0 {
return fmt.Sprintf("%dh%dm%ds", thrs, tmins%60, tsecs%60)
}
if tmins > 0 {
return fmt.Sprintf("%dm%ds", tmins, tsecs%60)
}
return fmt.Sprintf("%ds", tsecs)
}
// HandleRoot will show basic info and links to others handlers.
func (s *Server) HandleRoot(w http.ResponseWriter, r *http.Request) {
// This feels dumb to me, but is required: https://code.google.com/p/go/issues/detail?id=4799
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
s.mu.Lock()
s.httpReqStats[RootPath]++
s.mu.Unlock()
fmt.Fprintf(w, `<html lang="en">
<head>
<link rel="shortcut icon" href="http://nats.io/img/favicon.ico">
<style type="text/css">
body { font-family: "Century Gothic", CenturyGothic, AppleGothic, sans-serif; font-size: 22; }
a { margin-left: 32px; }
</style>
</head>
<body>
<img src="http://nats.io/img/logo.png" alt="NATS">
<br/>
<a href=/varz>varz</a><br/>
<a href=/connz>connz</a><br/>
<a href=/routez>routez</a><br/>
<a href=/subsz>subsz</a><br/>
<br/>
<a href=http://nats.io/documentation/server/gnatsd-monitoring/>help</a>
</body>
</html>`)
}
// HandleVarz will process HTTP requests for server information.
func (s *Server) HandleVarz(w http.ResponseWriter, r *http.Request) {
v := &Varz{Info: &s.info, Options: s.opts, MaxPayload: s.opts.MaxPayload, Start: s.start}
v.Now = time.Now()
v.Uptime = myUptime(time.Since(s.start))
v.Port = v.Info.Port
updateUsage(v)
s.mu.Lock()
v.Connections = len(s.clients)
v.TotalConnections = s.totalClients
v.Routes = len(s.routes)
v.Remotes = len(s.remotes)
v.InMsgs = s.inMsgs
v.InBytes = s.inBytes
v.OutMsgs = s.outMsgs
v.OutBytes = s.outBytes
v.SlowConsumers = s.slowConsumers
v.Subscriptions = s.sl.Count()
s.httpReqStats[VarzPath]++
// Need a copy here since s.httpReqStas can change while doing
// the marshaling down below.
v.HTTPReqStats = make(map[string]uint64, len(s.httpReqStats))
for key, val := range s.httpReqStats {
v.HTTPReqStats[key] = val
}
s.mu.Unlock()
b, err := json.MarshalIndent(v, "", " ")
if err != nil {
Errorf("Error marshalling response to /varz request: %v", err)
}
// Handle response
ResponseHandler(w, r, b)
}
// Grab RSS and PCPU
func updateUsage(v *Varz) {
var rss, vss int64
var pcpu float64
pse.ProcUsage(&pcpu, &rss, &vss)
v.Mem = rss
v.CPU = pcpu
v.Cores = numCores
}
// ResponseHandler handles responses for monitoring routes
func ResponseHandler(w http.ResponseWriter, r *http.Request, data []byte) {
// Get callback from request
callback := r.URL.Query().Get("callback")
// If callback is not empty then
if callback != "" {
// Response for JSONP
w.Header().Set("Content-Type", "application/javascript")
fmt.Fprintf(w, "%s(%s)", callback, data)
} else {
// Otherwise JSON
w.Header().Set("Content-Type", "application/json")
w.Write(data)
}
}

View file

@ -1,50 +0,0 @@
// Copyright 2013-2016 Apcera Inc. All rights reserved.
package server
// SortOpt is a helper type to sort by ConnInfo values
type SortOpt string
const (
byCid SortOpt = "cid"
bySubs = "subs"
byPending = "pending"
byOutMsgs = "msgs_to"
byInMsgs = "msgs_from"
byOutBytes = "bytes_to"
byInBytes = "bytes_from"
byLast = "last"
byIdle = "idle"
byUptime = "uptime"
)
// IsValid determines if a sort option is valid
func (s SortOpt) IsValid() bool {
switch s {
case "", byCid, bySubs, byPending, byOutMsgs, byInMsgs, byOutBytes, byInBytes, byLast, byIdle, byUptime:
return true
default:
return false
}
}
// Pair type is internally used.
type Pair struct {
Key *client
Val int64
}
// Pairs type is internally used.
type Pairs []Pair
func (d Pairs) Len() int {
return len(d)
}
func (d Pairs) Swap(i, j int) {
d[i], d[j] = d[j], d[i]
}
func (d Pairs) Less(i, j int) bool {
return d[i].Val < d[j].Val
}

View file

@ -1,802 +0,0 @@
// Copyright 2012-2016 Apcera Inc. All rights reserved.
package server
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"net"
"net/url"
"os"
"strconv"
"strings"
"time"
"github.com/nats-io/gnatsd/conf"
)
// For multiple accounts/users.
type User struct {
Username string `json:"user"`
Password string `json:"password"`
Permissions *Permissions `json:"permissions"`
}
// Authorization are the allowed subjects on a per
// publish or subscribe basis.
type Permissions struct {
Publish []string `json:"publish"`
Subscribe []string `json:"subscribe"`
}
// Options for clusters.
type ClusterOpts struct {
Host string `json:"addr"`
Port int `json:"cluster_port"`
Username string `json:"-"`
Password string `json:"-"`
AuthTimeout float64 `json:"auth_timeout"`
TLSTimeout float64 `json:"-"`
TLSConfig *tls.Config `json:"-"`
ListenStr string `json:"-"`
NoAdvertise bool `json:"-"`
}
// Options block for gnatsd server.
type Options struct {
Host string `json:"addr"`
Port int `json:"port"`
Trace bool `json:"-"`
Debug bool `json:"-"`
NoLog bool `json:"-"`
NoSigs bool `json:"-"`
Logtime bool `json:"-"`
MaxConn int `json:"max_connections"`
Users []*User `json:"-"`
Username string `json:"-"`
Password string `json:"-"`
Authorization string `json:"-"`
PingInterval time.Duration `json:"ping_interval"`
MaxPingsOut int `json:"ping_max"`
HTTPHost string `json:"http_host"`
HTTPPort int `json:"http_port"`
HTTPSPort int `json:"https_port"`
AuthTimeout float64 `json:"auth_timeout"`
MaxControlLine int `json:"max_control_line"`
MaxPayload int `json:"max_payload"`
Cluster ClusterOpts `json:"cluster"`
ProfPort int `json:"-"`
PidFile string `json:"-"`
LogFile string `json:"-"`
Syslog bool `json:"-"`
RemoteSyslog string `json:"-"`
Routes []*url.URL `json:"-"`
RoutesStr string `json:"-"`
TLSTimeout float64 `json:"tls_timeout"`
TLS bool `json:"-"`
TLSVerify bool `json:"-"`
TLSCert string `json:"-"`
TLSKey string `json:"-"`
TLSCaCert string `json:"-"`
TLSConfig *tls.Config `json:"-"`
}
// Configuration file authorization section.
type authorization struct {
// Singles
user string
pass string
// Multiple Users
users []*User
timeout float64
defaultPermissions *Permissions
}
// TLSConfigOpts holds the parsed tls config information,
// used with flag parsing
type TLSConfigOpts struct {
CertFile string
KeyFile string
CaFile string
Verify bool
Timeout float64
Ciphers []uint16
}
var tlsUsage = `
TLS configuration is specified in the tls section of a configuration file:
e.g.
tls {
cert_file: "./certs/server-cert.pem"
key_file: "./certs/server-key.pem"
ca_file: "./certs/ca.pem"
verify: true
cipher_suites: [
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
]
}
Available cipher suites include:
`
// ProcessConfigFile processes a configuration file.
// FIXME(dlc): Hacky
func ProcessConfigFile(configFile string) (*Options, error) {
opts := &Options{}
if configFile == "" {
return opts, nil
}
m, err := conf.ParseFile(configFile)
if err != nil {
return nil, err
}
for k, v := range m {
switch strings.ToLower(k) {
case "listen":
hp, err := parseListen(v)
if err != nil {
return nil, err
}
opts.Host = hp.host
opts.Port = hp.port
case "port":
opts.Port = int(v.(int64))
case "host", "net":
opts.Host = v.(string)
case "debug":
opts.Debug = v.(bool)
case "trace":
opts.Trace = v.(bool)
case "logtime":
opts.Logtime = v.(bool)
case "authorization":
am := v.(map[string]interface{})
auth, err := parseAuthorization(am)
if err != nil {
return nil, err
}
opts.Username = auth.user
opts.Password = auth.pass
opts.AuthTimeout = auth.timeout
// Check for multiple users defined
if auth.users != nil {
if auth.user != "" {
return nil, fmt.Errorf("Can not have a single user/pass and a users array")
}
opts.Users = auth.users
}
case "http":
hp, err := parseListen(v)
if err != nil {
return nil, err
}
opts.HTTPHost = hp.host
opts.HTTPPort = hp.port
case "https":
hp, err := parseListen(v)
if err != nil {
return nil, err
}
opts.HTTPHost = hp.host
opts.HTTPSPort = hp.port
case "http_port", "monitor_port":
opts.HTTPPort = int(v.(int64))
case "https_port":
opts.HTTPSPort = int(v.(int64))
case "cluster":
cm := v.(map[string]interface{})
if err := parseCluster(cm, opts); err != nil {
return nil, err
}
case "logfile", "log_file":
opts.LogFile = v.(string)
case "syslog":
opts.Syslog = v.(bool)
case "remote_syslog":
opts.RemoteSyslog = v.(string)
case "pidfile", "pid_file":
opts.PidFile = v.(string)
case "prof_port":
opts.ProfPort = int(v.(int64))
case "max_control_line":
opts.MaxControlLine = int(v.(int64))
case "max_payload":
opts.MaxPayload = int(v.(int64))
case "max_connections", "max_conn":
opts.MaxConn = int(v.(int64))
case "ping_interval":
opts.PingInterval = time.Duration(int(v.(int64))) * time.Second
case "ping_max":
opts.MaxPingsOut = int(v.(int64))
case "tls":
tlsm := v.(map[string]interface{})
tc, err := parseTLS(tlsm)
if err != nil {
return nil, err
}
if opts.TLSConfig, err = GenTLSConfig(tc); err != nil {
return nil, err
}
opts.TLSTimeout = tc.Timeout
}
}
return opts, nil
}
// hostPort is simple struct to hold parsed listen/addr strings.
type hostPort struct {
host string
port int
}
// parseListen will parse listen option which is replacing host/net and port
func parseListen(v interface{}) (*hostPort, error) {
hp := &hostPort{}
switch v.(type) {
// Only a port
case int64:
hp.port = int(v.(int64))
case string:
host, port, err := net.SplitHostPort(v.(string))
if err != nil {
return nil, fmt.Errorf("Could not parse address string %q", v)
}
hp.port, err = strconv.Atoi(port)
if err != nil {
return nil, fmt.Errorf("Could not parse port %q", port)
}
hp.host = host
}
return hp, nil
}
// parseCluster will parse the cluster config.
func parseCluster(cm map[string]interface{}, opts *Options) error {
for mk, mv := range cm {
switch strings.ToLower(mk) {
case "listen":
hp, err := parseListen(mv)
if err != nil {
return err
}
opts.Cluster.Host = hp.host
opts.Cluster.Port = hp.port
case "port":
opts.Cluster.Port = int(mv.(int64))
case "host", "net":
opts.Cluster.Host = mv.(string)
case "authorization":
am := mv.(map[string]interface{})
auth, err := parseAuthorization(am)
if err != nil {
return err
}
if auth.users != nil {
return fmt.Errorf("Cluster authorization does not allow multiple users")
}
opts.Cluster.Username = auth.user
opts.Cluster.Password = auth.pass
opts.Cluster.AuthTimeout = auth.timeout
case "routes":
ra := mv.([]interface{})
opts.Routes = make([]*url.URL, 0, len(ra))
for _, r := range ra {
routeURL := r.(string)
url, err := url.Parse(routeURL)
if err != nil {
return fmt.Errorf("error parsing route url [%q]", routeURL)
}
opts.Routes = append(opts.Routes, url)
}
case "tls":
tlsm := mv.(map[string]interface{})
tc, err := parseTLS(tlsm)
if err != nil {
return err
}
if opts.Cluster.TLSConfig, err = GenTLSConfig(tc); err != nil {
return err
}
// For clusters, we will force strict verification. We also act
// as both client and server, so will mirror the rootCA to the
// clientCA pool.
opts.Cluster.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert
opts.Cluster.TLSConfig.RootCAs = opts.Cluster.TLSConfig.ClientCAs
opts.Cluster.TLSTimeout = tc.Timeout
case "no_advertise":
opts.Cluster.NoAdvertise = mv.(bool)
}
}
return nil
}
// Helper function to parse Authorization configs.
func parseAuthorization(am map[string]interface{}) (*authorization, error) {
auth := &authorization{}
for mk, mv := range am {
switch strings.ToLower(mk) {
case "user", "username":
auth.user = mv.(string)
case "pass", "password":
auth.pass = mv.(string)
case "timeout":
at := float64(1)
switch mv.(type) {
case int64:
at = float64(mv.(int64))
case float64:
at = mv.(float64)
}
auth.timeout = at
case "users":
users, err := parseUsers(mv)
if err != nil {
return nil, err
}
auth.users = users
case "default_permission", "default_permissions":
pm, ok := mv.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("Expected default permissions to be a map/struct, got %+v", mv)
}
permissions, err := parseUserPermissions(pm)
if err != nil {
return nil, err
}
auth.defaultPermissions = permissions
}
// Now check for permission defaults with multiple users, etc.
if auth.users != nil && auth.defaultPermissions != nil {
for _, user := range auth.users {
if user.Permissions == nil {
user.Permissions = auth.defaultPermissions
}
}
}
}
return auth, nil
}
// Helper function to parse multiple users array with optional permissions.
func parseUsers(mv interface{}) ([]*User, error) {
// Make sure we have an array
uv, ok := mv.([]interface{})
if !ok {
return nil, fmt.Errorf("Expected users field to be an array, got %v", mv)
}
users := []*User{}
for _, u := range uv {
// Check its a map/struct
um, ok := u.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("Expected user entry to be a map/struct, got %v", u)
}
user := &User{}
for k, v := range um {
switch strings.ToLower(k) {
case "user", "username":
user.Username = v.(string)
case "pass", "password":
user.Password = v.(string)
case "permission", "permissions", "authroization":
pm, ok := v.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("Expected user permissions to be a map/struct, got %+v", v)
}
permissions, err := parseUserPermissions(pm)
if err != nil {
return nil, err
}
user.Permissions = permissions
}
}
// Check to make sure we have at least username and password
if user.Username == "" || user.Password == "" {
return nil, fmt.Errorf("User entry requires a user and a password")
}
users = append(users, user)
}
return users, nil
}
// Helper function to parse user/account permissions
func parseUserPermissions(pm map[string]interface{}) (*Permissions, error) {
p := &Permissions{}
for k, v := range pm {
switch strings.ToLower(k) {
case "pub", "publish":
subjects, err := parseSubjects(v)
if err != nil {
return nil, err
}
p.Publish = subjects
case "sub", "subscribe":
subjects, err := parseSubjects(v)
if err != nil {
return nil, err
}
p.Subscribe = subjects
default:
return nil, fmt.Errorf("Unknown field %s parsing permissions", k)
}
}
return p, nil
}
// Helper function to parse subject singeltons and/or arrays
func parseSubjects(v interface{}) ([]string, error) {
var subjects []string
switch v.(type) {
case string:
subjects = append(subjects, v.(string))
case []string:
subjects = v.([]string)
case []interface{}:
for _, i := range v.([]interface{}) {
subject, ok := i.(string)
if !ok {
return nil, fmt.Errorf("Subject in permissions array cannot be cast to string")
}
subjects = append(subjects, subject)
}
default:
return nil, fmt.Errorf("Expected subject permissions to be a subject, or array of subjects, got %T", v)
}
return checkSubjectArray(subjects)
}
// Helper function to validate subjects, etc for account permissioning.
func checkSubjectArray(sa []string) ([]string, error) {
for _, s := range sa {
if !IsValidSubject(s) {
return nil, fmt.Errorf("Subject %q is not a valid subject", s)
}
}
return sa, nil
}
// PrintTLSHelpAndDie prints TLS usage and exits.
func PrintTLSHelpAndDie() {
fmt.Printf("%s\n", tlsUsage)
for k := range cipherMap {
fmt.Printf(" %s\n", k)
}
fmt.Printf("\n")
os.Exit(0)
}
func parseCipher(cipherName string) (uint16, error) {
cipher, exists := cipherMap[cipherName]
if !exists {
return 0, fmt.Errorf("Unrecognized cipher %s", cipherName)
}
return cipher, nil
}
// Helper function to parse TLS configs.
func parseTLS(tlsm map[string]interface{}) (*TLSConfigOpts, error) {
tc := TLSConfigOpts{}
for mk, mv := range tlsm {
switch strings.ToLower(mk) {
case "cert_file":
certFile, ok := mv.(string)
if !ok {
return nil, fmt.Errorf("error parsing tls config, expected 'cert_file' to be filename")
}
tc.CertFile = certFile
case "key_file":
keyFile, ok := mv.(string)
if !ok {
return nil, fmt.Errorf("error parsing tls config, expected 'key_file' to be filename")
}
tc.KeyFile = keyFile
case "ca_file":
caFile, ok := mv.(string)
if !ok {
return nil, fmt.Errorf("error parsing tls config, expected 'ca_file' to be filename")
}
tc.CaFile = caFile
case "verify":
verify, ok := mv.(bool)
if !ok {
return nil, fmt.Errorf("error parsing tls config, expected 'verify' to be a boolean")
}
tc.Verify = verify
case "cipher_suites":
ra := mv.([]interface{})
if len(ra) == 0 {
return nil, fmt.Errorf("error parsing tls config, 'cipher_suites' cannot be empty")
}
tc.Ciphers = make([]uint16, 0, len(ra))
for _, r := range ra {
cipher, err := parseCipher(r.(string))
if err != nil {
return nil, err
}
tc.Ciphers = append(tc.Ciphers, cipher)
}
case "timeout":
at := float64(0)
switch mv.(type) {
case int64:
at = float64(mv.(int64))
case float64:
at = mv.(float64)
}
tc.Timeout = at
default:
return nil, fmt.Errorf("error parsing tls config, unknown field [%q]", mk)
}
}
// If cipher suites were not specified then use the defaults
if tc.Ciphers == nil {
tc.Ciphers = defaultCipherSuites()
}
return &tc, nil
}
// GenTLSConfig loads TLS related configuration parameters.
func GenTLSConfig(tc *TLSConfigOpts) (*tls.Config, error) {
// Now load in cert and private key
cert, err := tls.LoadX509KeyPair(tc.CertFile, tc.KeyFile)
if err != nil {
return nil, fmt.Errorf("error parsing X509 certificate/key pair: %v", err)
}
cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
if err != nil {
return nil, fmt.Errorf("error parsing certificate: %v", err)
}
// Create TLSConfig
// We will determine the cipher suites that we prefer.
config := tls.Config{
Certificates: []tls.Certificate{cert},
PreferServerCipherSuites: true,
MinVersion: tls.VersionTLS12,
CipherSuites: tc.Ciphers,
}
// Require client certificates as needed
if tc.Verify {
config.ClientAuth = tls.RequireAndVerifyClientCert
}
// Add in CAs if applicable.
if tc.CaFile != "" {
rootPEM, err := ioutil.ReadFile(tc.CaFile)
if err != nil || rootPEM == nil {
return nil, err
}
pool := x509.NewCertPool()
ok := pool.AppendCertsFromPEM([]byte(rootPEM))
if !ok {
return nil, fmt.Errorf("failed to parse root ca certificate")
}
config.ClientCAs = pool
}
return &config, nil
}
// MergeOptions will merge two options giving preference to the flagOpts
// if the item is present.
func MergeOptions(fileOpts, flagOpts *Options) *Options {
if fileOpts == nil {
return flagOpts
}
if flagOpts == nil {
return fileOpts
}
// Merge the two, flagOpts override
opts := *fileOpts
if flagOpts.Port != 0 {
opts.Port = flagOpts.Port
}
if flagOpts.Host != "" {
opts.Host = flagOpts.Host
}
if flagOpts.Username != "" {
opts.Username = flagOpts.Username
}
if flagOpts.Password != "" {
opts.Password = flagOpts.Password
}
if flagOpts.Authorization != "" {
opts.Authorization = flagOpts.Authorization
}
if flagOpts.HTTPPort != 0 {
opts.HTTPPort = flagOpts.HTTPPort
}
if flagOpts.Debug {
opts.Debug = true
}
if flagOpts.Trace {
opts.Trace = true
}
if flagOpts.Logtime {
opts.Logtime = true
}
if flagOpts.LogFile != "" {
opts.LogFile = flagOpts.LogFile
}
if flagOpts.PidFile != "" {
opts.PidFile = flagOpts.PidFile
}
if flagOpts.ProfPort != 0 {
opts.ProfPort = flagOpts.ProfPort
}
if flagOpts.Cluster.ListenStr != "" {
opts.Cluster.ListenStr = flagOpts.Cluster.ListenStr
}
if flagOpts.Cluster.NoAdvertise {
opts.Cluster.NoAdvertise = true
}
if flagOpts.RoutesStr != "" {
mergeRoutes(&opts, flagOpts)
}
return &opts
}
// RoutesFromStr parses route URLs from a string
func RoutesFromStr(routesStr string) []*url.URL {
routes := strings.Split(routesStr, ",")
if len(routes) == 0 {
return nil
}
routeUrls := []*url.URL{}
for _, r := range routes {
r = strings.TrimSpace(r)
u, _ := url.Parse(r)
routeUrls = append(routeUrls, u)
}
return routeUrls
}
// This will merge the flag routes and override anything that was present.
func mergeRoutes(opts, flagOpts *Options) {
routeUrls := RoutesFromStr(flagOpts.RoutesStr)
if routeUrls == nil {
return
}
opts.Routes = routeUrls
opts.RoutesStr = flagOpts.RoutesStr
}
// RemoveSelfReference removes this server from an array of routes
func RemoveSelfReference(clusterPort int, routes []*url.URL) ([]*url.URL, error) {
var cleanRoutes []*url.URL
cport := strconv.Itoa(clusterPort)
selfIPs := getInterfaceIPs()
for _, r := range routes {
host, port, err := net.SplitHostPort(r.Host)
if err != nil {
return nil, err
}
if cport == port && isIPInList(selfIPs, getURLIP(host)) {
Noticef("Self referencing IP found: ", r)
continue
}
cleanRoutes = append(cleanRoutes, r)
}
return cleanRoutes, nil
}
func isIPInList(list1 []net.IP, list2 []net.IP) bool {
for _, ip1 := range list1 {
for _, ip2 := range list2 {
if ip1.Equal(ip2) {
return true
}
}
}
return false
}
func getURLIP(ipStr string) []net.IP {
ipList := []net.IP{}
ip := net.ParseIP(ipStr)
if ip != nil {
ipList = append(ipList, ip)
return ipList
}
hostAddr, err := net.LookupHost(ipStr)
if err != nil {
Errorf("Error looking up host with route hostname: %v", err)
return ipList
}
for _, addr := range hostAddr {
ip = net.ParseIP(addr)
if ip != nil {
ipList = append(ipList, ip)
}
}
return ipList
}
func getInterfaceIPs() []net.IP {
var localIPs []net.IP
interfaceAddr, err := net.InterfaceAddrs()
if err != nil {
Errorf("Error getting self referencing address: %v", err)
return localIPs
}
for i := 0; i < len(interfaceAddr); i++ {
interfaceIP, _, _ := net.ParseCIDR(interfaceAddr[i].String())
if net.ParseIP(interfaceIP.String()) != nil {
localIPs = append(localIPs, interfaceIP)
} else {
Errorf("Error parsing self referencing address: %v", err)
}
}
return localIPs
}
func processOptions(opts *Options) {
// Setup non-standard Go defaults
if opts.Host == "" {
opts.Host = DEFAULT_HOST
}
if opts.HTTPHost == "" {
// Default to same bind from server if left undefined
opts.HTTPHost = opts.Host
}
if opts.Port == 0 {
opts.Port = DEFAULT_PORT
} else if opts.Port == RANDOM_PORT {
// Choose randomly inside of net.Listen
opts.Port = 0
}
if opts.MaxConn == 0 {
opts.MaxConn = DEFAULT_MAX_CONNECTIONS
}
if opts.PingInterval == 0 {
opts.PingInterval = DEFAULT_PING_INTERVAL
}
if opts.MaxPingsOut == 0 {
opts.MaxPingsOut = DEFAULT_PING_MAX_OUT
}
if opts.TLSTimeout == 0 {
opts.TLSTimeout = float64(TLS_TIMEOUT) / float64(time.Second)
}
if opts.AuthTimeout == 0 {
opts.AuthTimeout = float64(AUTH_TIMEOUT) / float64(time.Second)
}
if opts.Cluster.Host == "" {
opts.Cluster.Host = DEFAULT_HOST
}
if opts.Cluster.TLSTimeout == 0 {
opts.Cluster.TLSTimeout = float64(TLS_TIMEOUT) / float64(time.Second)
}
if opts.Cluster.AuthTimeout == 0 {
opts.Cluster.AuthTimeout = float64(AUTH_TIMEOUT) / float64(time.Second)
}
if opts.MaxControlLine == 0 {
opts.MaxControlLine = MAX_CONTROL_LINE_SIZE
}
if opts.MaxPayload == 0 {
opts.MaxPayload = MAX_PAYLOAD_SIZE
}
}

View file

@ -1,738 +0,0 @@
// Copyright 2012-2014 Apcera Inc. All rights reserved.
package server
import (
"fmt"
)
type pubArg struct {
subject []byte
reply []byte
sid []byte
szb []byte
size int
}
type parseState struct {
state int
as int
drop int
pa pubArg
argBuf []byte
msgBuf []byte
scratch [MAX_CONTROL_LINE_SIZE]byte
}
// Parser constants
const (
OP_START = iota
OP_PLUS
OP_PLUS_O
OP_PLUS_OK
OP_MINUS
OP_MINUS_E
OP_MINUS_ER
OP_MINUS_ERR
OP_MINUS_ERR_SPC
MINUS_ERR_ARG
OP_C
OP_CO
OP_CON
OP_CONN
OP_CONNE
OP_CONNEC
OP_CONNECT
CONNECT_ARG
OP_P
OP_PU
OP_PUB
OP_PUB_SPC
PUB_ARG
OP_PI
OP_PIN
OP_PING
OP_PO
OP_PON
OP_PONG
MSG_PAYLOAD
MSG_END
OP_S
OP_SU
OP_SUB
OP_SUB_SPC
SUB_ARG
OP_U
OP_UN
OP_UNS
OP_UNSU
OP_UNSUB
OP_UNSUB_SPC
UNSUB_ARG
OP_M
OP_MS
OP_MSG
OP_MSG_SPC
MSG_ARG
OP_I
OP_IN
OP_INF
OP_INFO
INFO_ARG
)
func (c *client) parse(buf []byte) error {
var i int
var b byte
mcl := MAX_CONTROL_LINE_SIZE
if c.srv != nil && c.srv.opts != nil {
mcl = c.srv.opts.MaxControlLine
}
// snapshot this, and reset when we receive a
// proper CONNECT if needed.
authSet := c.isAuthTimerSet()
// Move to loop instead of range syntax to allow jumping of i
for i = 0; i < len(buf); i++ {
b = buf[i]
switch c.state {
case OP_START:
if b != 'C' && b != 'c' && authSet {
goto authErr
}
switch b {
case 'P', 'p':
c.state = OP_P
case 'S', 's':
c.state = OP_S
case 'U', 'u':
c.state = OP_U
case 'M', 'm':
if c.typ == CLIENT {
goto parseErr
} else {
c.state = OP_M
}
case 'C', 'c':
c.state = OP_C
case 'I', 'i':
c.state = OP_I
case '+':
c.state = OP_PLUS
case '-':
c.state = OP_MINUS
default:
goto parseErr
}
case OP_P:
switch b {
case 'U', 'u':
c.state = OP_PU
case 'I', 'i':
c.state = OP_PI
case 'O', 'o':
c.state = OP_PO
default:
goto parseErr
}
case OP_PU:
switch b {
case 'B', 'b':
c.state = OP_PUB
default:
goto parseErr
}
case OP_PUB:
switch b {
case ' ', '\t':
c.state = OP_PUB_SPC
default:
goto parseErr
}
case OP_PUB_SPC:
switch b {
case ' ', '\t':
continue
default:
c.state = PUB_ARG
c.as = i
}
case PUB_ARG:
switch b {
case '\r':
c.drop = 1
case '\n':
var arg []byte
if c.argBuf != nil {
arg = c.argBuf
} else {
arg = buf[c.as : i-c.drop]
}
if err := c.processPub(arg); err != nil {
return err
}
c.drop, c.as, c.state = OP_START, i+1, MSG_PAYLOAD
// If we don't have a saved buffer then jump ahead with
// the index. If this overruns what is left we fall out
// and process split buffer.
if c.msgBuf == nil {
i = c.as + c.pa.size - LEN_CR_LF
}
default:
if c.argBuf != nil {
c.argBuf = append(c.argBuf, b)
}
}
case MSG_PAYLOAD:
if c.msgBuf != nil {
// copy as much as we can to the buffer and skip ahead.
toCopy := c.pa.size - len(c.msgBuf)
avail := len(buf) - i
if avail < toCopy {
toCopy = avail
}
if toCopy > 0 {
start := len(c.msgBuf)
// This is needed for copy to work.
c.msgBuf = c.msgBuf[:start+toCopy]
copy(c.msgBuf[start:], buf[i:i+toCopy])
// Update our index
i = (i + toCopy) - 1
} else {
// Fall back to append if needed.
c.msgBuf = append(c.msgBuf, b)
}
if len(c.msgBuf) >= c.pa.size {
c.state = MSG_END
}
} else if i-c.as >= c.pa.size {
c.state = MSG_END
}
case MSG_END:
switch b {
case '\n':
if c.msgBuf != nil {
c.msgBuf = append(c.msgBuf, b)
} else {
c.msgBuf = buf[c.as : i+1]
}
// strict check for proto
if len(c.msgBuf) != c.pa.size+LEN_CR_LF {
goto parseErr
}
c.processMsg(c.msgBuf)
c.argBuf, c.msgBuf = nil, nil
c.drop, c.as, c.state = 0, i+1, OP_START
default:
if c.msgBuf != nil {
c.msgBuf = append(c.msgBuf, b)
}
continue
}
case OP_S:
switch b {
case 'U', 'u':
c.state = OP_SU
default:
goto parseErr
}
case OP_SU:
switch b {
case 'B', 'b':
c.state = OP_SUB
default:
goto parseErr
}
case OP_SUB:
switch b {
case ' ', '\t':
c.state = OP_SUB_SPC
default:
goto parseErr
}
case OP_SUB_SPC:
switch b {
case ' ', '\t':
continue
default:
c.state = SUB_ARG
c.as = i
}
case SUB_ARG:
switch b {
case '\r':
c.drop = 1
case '\n':
var arg []byte
if c.argBuf != nil {
arg = c.argBuf
c.argBuf = nil
} else {
arg = buf[c.as : i-c.drop]
}
if err := c.processSub(arg); err != nil {
return err
}
c.drop, c.as, c.state = 0, i+1, OP_START
default:
if c.argBuf != nil {
c.argBuf = append(c.argBuf, b)
}
}
case OP_U:
switch b {
case 'N', 'n':
c.state = OP_UN
default:
goto parseErr
}
case OP_UN:
switch b {
case 'S', 's':
c.state = OP_UNS
default:
goto parseErr
}
case OP_UNS:
switch b {
case 'U', 'u':
c.state = OP_UNSU
default:
goto parseErr
}
case OP_UNSU:
switch b {
case 'B', 'b':
c.state = OP_UNSUB
default:
goto parseErr
}
case OP_UNSUB:
switch b {
case ' ', '\t':
c.state = OP_UNSUB_SPC
default:
goto parseErr
}
case OP_UNSUB_SPC:
switch b {
case ' ', '\t':
continue
default:
c.state = UNSUB_ARG
c.as = i
}
case UNSUB_ARG:
switch b {
case '\r':
c.drop = 1
case '\n':
var arg []byte
if c.argBuf != nil {
arg = c.argBuf
c.argBuf = nil
} else {
arg = buf[c.as : i-c.drop]
}
if err := c.processUnsub(arg); err != nil {
return err
}
c.drop, c.as, c.state = 0, i+1, OP_START
default:
if c.argBuf != nil {
c.argBuf = append(c.argBuf, b)
}
}
case OP_PI:
switch b {
case 'N', 'n':
c.state = OP_PIN
default:
goto parseErr
}
case OP_PIN:
switch b {
case 'G', 'g':
c.state = OP_PING
default:
goto parseErr
}
case OP_PING:
switch b {
case '\n':
c.processPing()
c.drop, c.state = 0, OP_START
}
case OP_PO:
switch b {
case 'N', 'n':
c.state = OP_PON
default:
goto parseErr
}
case OP_PON:
switch b {
case 'G', 'g':
c.state = OP_PONG
default:
goto parseErr
}
case OP_PONG:
switch b {
case '\n':
c.processPong()
c.drop, c.state = 0, OP_START
}
case OP_C:
switch b {
case 'O', 'o':
c.state = OP_CO
default:
goto parseErr
}
case OP_CO:
switch b {
case 'N', 'n':
c.state = OP_CON
default:
goto parseErr
}
case OP_CON:
switch b {
case 'N', 'n':
c.state = OP_CONN
default:
goto parseErr
}
case OP_CONN:
switch b {
case 'E', 'e':
c.state = OP_CONNE
default:
goto parseErr
}
case OP_CONNE:
switch b {
case 'C', 'c':
c.state = OP_CONNEC
default:
goto parseErr
}
case OP_CONNEC:
switch b {
case 'T', 't':
c.state = OP_CONNECT
default:
goto parseErr
}
case OP_CONNECT:
switch b {
case ' ', '\t':
continue
default:
c.state = CONNECT_ARG
c.as = i
}
case CONNECT_ARG:
switch b {
case '\r':
c.drop = 1
case '\n':
var arg []byte
if c.argBuf != nil {
arg = c.argBuf
c.argBuf = nil
} else {
arg = buf[c.as : i-c.drop]
}
if err := c.processConnect(arg); err != nil {
return err
}
c.drop, c.state = 0, OP_START
// Reset notion on authSet
authSet = c.isAuthTimerSet()
default:
if c.argBuf != nil {
c.argBuf = append(c.argBuf, b)
}
}
case OP_M:
switch b {
case 'S', 's':
c.state = OP_MS
default:
goto parseErr
}
case OP_MS:
switch b {
case 'G', 'g':
c.state = OP_MSG
default:
goto parseErr
}
case OP_MSG:
switch b {
case ' ', '\t':
c.state = OP_MSG_SPC
default:
goto parseErr
}
case OP_MSG_SPC:
switch b {
case ' ', '\t':
continue
default:
c.state = MSG_ARG
c.as = i
}
case MSG_ARG:
switch b {
case '\r':
c.drop = 1
case '\n':
var arg []byte
if c.argBuf != nil {
arg = c.argBuf
} else {
arg = buf[c.as : i-c.drop]
}
if err := c.processMsgArgs(arg); err != nil {
return err
}
c.drop, c.as, c.state = 0, i+1, MSG_PAYLOAD
// jump ahead with the index. If this overruns
// what is left we fall out and process split
// buffer.
i = c.as + c.pa.size - 1
default:
if c.argBuf != nil {
c.argBuf = append(c.argBuf, b)
}
}
case OP_I:
switch b {
case 'N', 'n':
c.state = OP_IN
default:
goto parseErr
}
case OP_IN:
switch b {
case 'F', 'f':
c.state = OP_INF
default:
goto parseErr
}
case OP_INF:
switch b {
case 'O', 'o':
c.state = OP_INFO
default:
goto parseErr
}
case OP_INFO:
switch b {
case ' ', '\t':
continue
default:
c.state = INFO_ARG
c.as = i
}
case INFO_ARG:
switch b {
case '\r':
c.drop = 1
case '\n':
var arg []byte
if c.argBuf != nil {
arg = c.argBuf
c.argBuf = nil
} else {
arg = buf[c.as : i-c.drop]
}
if err := c.processInfo(arg); err != nil {
return err
}
c.drop, c.as, c.state = 0, i+1, OP_START
default:
if c.argBuf != nil {
c.argBuf = append(c.argBuf, b)
}
}
case OP_PLUS:
switch b {
case 'O', 'o':
c.state = OP_PLUS_O
default:
goto parseErr
}
case OP_PLUS_O:
switch b {
case 'K', 'k':
c.state = OP_PLUS_OK
default:
goto parseErr
}
case OP_PLUS_OK:
switch b {
case '\n':
c.drop, c.state = 0, OP_START
}
case OP_MINUS:
switch b {
case 'E', 'e':
c.state = OP_MINUS_E
default:
goto parseErr
}
case OP_MINUS_E:
switch b {
case 'R', 'r':
c.state = OP_MINUS_ER
default:
goto parseErr
}
case OP_MINUS_ER:
switch b {
case 'R', 'r':
c.state = OP_MINUS_ERR
default:
goto parseErr
}
case OP_MINUS_ERR:
switch b {
case ' ', '\t':
c.state = OP_MINUS_ERR_SPC
default:
goto parseErr
}
case OP_MINUS_ERR_SPC:
switch b {
case ' ', '\t':
continue
default:
c.state = MINUS_ERR_ARG
c.as = i
}
case MINUS_ERR_ARG:
switch b {
case '\r':
c.drop = 1
case '\n':
var arg []byte
if c.argBuf != nil {
arg = c.argBuf
c.argBuf = nil
} else {
arg = buf[c.as : i-c.drop]
}
c.processErr(string(arg))
c.drop, c.as, c.state = 0, i+1, OP_START
default:
if c.argBuf != nil {
c.argBuf = append(c.argBuf, b)
}
}
default:
goto parseErr
}
}
// Check for split buffer scenarios for any ARG state.
if c.state == SUB_ARG || c.state == UNSUB_ARG || c.state == PUB_ARG ||
c.state == MSG_ARG || c.state == MINUS_ERR_ARG ||
c.state == CONNECT_ARG || c.state == INFO_ARG {
// Setup a holder buffer to deal with split buffer scenario.
if c.argBuf == nil {
c.argBuf = c.scratch[:0]
c.argBuf = append(c.argBuf, buf[c.as:i-c.drop]...)
}
// Check for violations of control line length here. Note that this is not
// exact at all but the performance hit is too great to be precise, and
// catching here should prevent memory exhaustion attacks.
if len(c.argBuf) > mcl {
c.sendErr("Maximum Control Line Exceeded")
c.closeConnection()
return ErrMaxControlLine
}
}
// Check for split msg
if (c.state == MSG_PAYLOAD || c.state == MSG_END) && c.msgBuf == nil {
// We need to clone the pubArg if it is still referencing the
// read buffer and we are not able to process the msg.
if c.argBuf == nil {
// Works also for MSG_ARG, when message comes from ROUTE.
c.clonePubArg()
}
// If we will overflow the scratch buffer, just create a
// new buffer to hold the split message.
if c.pa.size > cap(c.scratch)-len(c.argBuf) {
lrem := len(buf[c.as:])
// Consider it a protocol error when the remaining payload
// is larger than the reported size for PUB. It can happen
// when processing incomplete messages from rogue clients.
if lrem > c.pa.size+LEN_CR_LF {
goto parseErr
}
c.msgBuf = make([]byte, lrem, c.pa.size+LEN_CR_LF)
copy(c.msgBuf, buf[c.as:])
} else {
c.msgBuf = c.scratch[len(c.argBuf):len(c.argBuf)]
c.msgBuf = append(c.msgBuf, (buf[c.as:])...)
}
}
return nil
authErr:
c.authViolation()
return ErrAuthorization
parseErr:
c.sendErr("Unknown Protocol Operation")
snip := protoSnippet(i, buf)
err := fmt.Errorf("%s Parser ERROR, state=%d, i=%d: proto='%s...'",
c.typeString(), c.state, i, snip)
return err
}
func protoSnippet(start int, buf []byte) string {
stop := start + PROTO_SNIPPET_SIZE
bufSize := len(buf)
if start >= bufSize {
return `""`
}
if stop > bufSize {
stop = bufSize - 1
}
return fmt.Sprintf("%q", buf[start:stop])
}
// clonePubArg is used when the split buffer scenario has the pubArg in the existing read buffer, but
// we need to hold onto it into the next read.
func (c *client) clonePubArg() {
c.argBuf = c.scratch[:0]
c.argBuf = append(c.argBuf, c.pa.subject...)
c.argBuf = append(c.argBuf, c.pa.reply...)
c.argBuf = append(c.argBuf, c.pa.sid...)
c.argBuf = append(c.argBuf, c.pa.szb...)
c.pa.subject = c.argBuf[:len(c.pa.subject)]
if c.pa.reply != nil {
c.pa.reply = c.argBuf[len(c.pa.subject) : len(c.pa.subject)+len(c.pa.reply)]
}
if c.pa.sid != nil {
c.pa.sid = c.argBuf[len(c.pa.subject)+len(c.pa.reply) : len(c.pa.subject)+len(c.pa.reply)+len(c.pa.sid)]
}
c.pa.szb = c.argBuf[len(c.pa.subject)+len(c.pa.reply)+len(c.pa.sid):]
}

View file

@ -1,23 +0,0 @@
// Copyright 2015-2016 Apcera Inc. All rights reserved.
package pse
import (
"errors"
"fmt"
"os"
"os/exec"
)
func ProcUsage(pcpu *float64, rss, vss *int64) error {
pidStr := fmt.Sprintf("%d", os.Getpid())
out, err := exec.Command("ps", "o", "pcpu=,rss=,vsz=", "-p", pidStr).Output()
if err != nil {
*rss, *vss = -1, -1
return errors.New(fmt.Sprintf("ps call failed:%v", err))
}
fmt.Sscanf(string(out), "%f %d %d", pcpu, rss, vss)
*rss *= 1024 // 1k blocks, want bytes.
*vss *= 1024 // 1k blocks, want bytes.
return nil
}

Some files were not shown because too many files have changed in this diff Show more