From 169d7550cf61ce1e2991d78385d4f4a7e164a574 Mon Sep 17 00:00:00 2001 From: Julio Montes Date: Wed, 12 Dec 2018 09:03:34 -0600 Subject: [PATCH] protocols/grpc: implement function to copy files CopyFileRequest can be used to copy files from the host to the workload rootfs (guest), this request is intended to copy "static" and small files like resolv.conf and hosts, but any other file can be copied. fixes #432 Signed-off-by: Julio Montes --- grpc.go | 76 +++ grpc_test.go | 50 ++ protocols/grpc/agent.pb.go | 755 +++++++++++++++++++++++------ protocols/grpc/agent.proto | 23 + protocols/mockserver/mockserver.go | 6 + 5 files changed, 753 insertions(+), 157 deletions(-) diff --git a/grpc.go b/grpc.go index 50f793b75e..71581bec09 100644 --- a/grpc.go +++ b/grpc.go @@ -53,6 +53,7 @@ var ( sysfsMemOnlinePath = "/sys/devices/system/memory" sysfsMemoryBlockSizePath = "/sys/devices/system/memory/block_size_bytes" sysfsConnectedCPUsPath = filepath.Join(sysfsCPUOnlinePath, "online") + containersRootfsPath = "/run" ) type onlineResource struct { @@ -1450,3 +1451,78 @@ func (a *agentGRPC) SetGuestDateTime(ctx context.Context, req *pb.SetGuestDateTi } return &gpb.Empty{}, nil } + +// CopyFile copies files form host to container's rootfs (guest). Files can be copied by parts, for example +// a file which size is 2MB, can be copied calling CopyFile 2 times, in the first call req.Offset is 0, +// req.FileSize is 2MB and req.Data contains the first half of the file, in the seconds call req.Offset is 1MB, +// req.FileSize is 2MB and req.Data contains the second half of the file. For security reason all write operations +// are made in a temporary file, once temporary file reaches the expected size (req.FileSize), it's moved to +// destination file (req.Path). +func (a *agentGRPC) CopyFile(ctx context.Context, req *pb.CopyFileRequest) (*gpb.Empty, error) { + // get absolute path, to avoid paths like '/run/../sbin/init' + path, err := filepath.Abs(req.Path) + if err != nil { + return emptyResp, err + } + + // container's rootfs is mounted at /run, in order to avoid overwrite guest's rootfs files, only + // is possible to copy files to /run + if !strings.HasPrefix(path, containersRootfsPath) { + return emptyResp, fmt.Errorf("Only is possible to copy files into the %s directory", containersRootfsPath) + } + + if err := os.MkdirAll(filepath.Dir(path), os.FileMode(req.DirMode)); err != nil { + return emptyResp, err + } + + // create a temporary file and write the content. + tmpPath := path + ".tmp" + tmpFile, err := os.OpenFile(tmpPath, os.O_WRONLY|os.O_CREATE, 0600) + if err != nil { + return emptyResp, err + } + + if _, err := tmpFile.WriteAt(req.Data, req.Offset); err != nil { + tmpFile.Close() + return emptyResp, err + } + tmpFile.Close() + + // get temporary file information + st, err := os.Stat(tmpPath) + if err != nil { + return emptyResp, err + } + + agentLog.WithFields(logrus.Fields{ + "tmp-file-size": st.Size(), + "expected-size": req.FileSize, + }).Debugf("Checking temporary file size") + + // if file size is not equal to the expected size means that copy file operation has not finished. + // CopyFile should be called again with new content and a different offset. + if st.Size() != req.FileSize { + return emptyResp, nil + } + + if err := os.Chmod(tmpPath, os.FileMode(req.FileMode)); err != nil { + return emptyResp, err + } + + if err := os.Chown(tmpPath, int(req.Uid), int(req.Gid)); err != nil { + return emptyResp, err + } + + // At this point temoporary file has the expected size, atomically move it overwriting + // the destination. + agentLog.WithFields(logrus.Fields{ + "tmp-path": tmpPath, + "des-path": path, + }).Debugf("Moving temporary file") + + if err := os.Rename(tmpPath, path); err != nil { + return emptyResp, err + } + + return emptyResp, nil +} diff --git a/grpc_test.go b/grpc_test.go index e0d97d72f5..b82d02dd07 100644 --- a/grpc_test.go +++ b/grpc_test.go @@ -786,3 +786,53 @@ func TestPosixRlimitsToRlimits(t *testing.T) { assert.Equal(rlimits, expectedRlimits) } + +func TestCopyFile(t *testing.T) { + assert := assert.New(t) + + oldContainersRootfsPath := containersRootfsPath + containersRootfsPath = "/tmp" + defer func() { + containersRootfsPath = oldContainersRootfsPath + }() + + a := &agentGRPC{} + req := &pb.CopyFileRequest{ + DirMode: 0755, + FileMode: 0755, + Uid: int32(os.Getuid()), + Gid: int32(os.Getgid()), + } + + _, err := a.CopyFile(context.Background(), req) + assert.Error(err) + + dir, err := ioutil.TempDir("", "copy") + assert.NoError(err) + defer os.RemoveAll(dir) + + req.Path = filepath.Join(dir, "file") + + part1 := []byte("hello") + part2 := []byte("world") + req.FileSize = int64(len(part1) + len(part2)) + + // send first part + req.Offset = 0 + req.Data = part1 + _, err = a.CopyFile(context.Background(), req) + assert.NoError(err) + + // send second part + req.Offset = int64(len(part1)) + req.Data = part2 + _, err = a.CopyFile(context.Background(), req) + assert.NoError(err) + + // check file exist + assert.FileExists(req.Path) + content, err := ioutil.ReadFile(req.Path) + assert.NoError(err) + // check file's content + assert.Equal(content, append(part1, part2...)) +} diff --git a/protocols/grpc/agent.pb.go b/protocols/grpc/agent.pb.go index 3a21850656..43dd213ab3 100644 --- a/protocols/grpc/agent.pb.go +++ b/protocols/grpc/agent.pb.go @@ -59,6 +59,7 @@ Storage Device StringUser + CopyFileRequest CheckRequest HealthCheckResponse VersionCheckResponse @@ -1602,6 +1603,89 @@ func (m *StringUser) GetAdditionalGids() []string { return nil } +type CopyFileRequest struct { + // Path is the destination file in the guest. It must be absolute, + // canonical and below /run. + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + // FileSize is the expected file size, for security reasons write operations + // are made in a temporary file, once it has the expected size, it's moved + // to the destination path. + FileSize int64 `protobuf:"varint,2,opt,name=file_size,json=fileSize,proto3" json:"file_size,omitempty"` + // FileMode is the file mode. + FileMode uint32 `protobuf:"varint,3,opt,name=file_mode,json=fileMode,proto3" json:"file_mode,omitempty"` + // DirMode is the mode for the parent directories of destination path. + DirMode uint32 `protobuf:"varint,4,opt,name=dir_mode,json=dirMode,proto3" json:"dir_mode,omitempty"` + // Uid is the numeric user id. + Uid int32 `protobuf:"varint,5,opt,name=uid,proto3" json:"uid,omitempty"` + // Gid is the numeric group id. + Gid int32 `protobuf:"varint,6,opt,name=gid,proto3" json:"gid,omitempty"` + // Offset for the next write operation. + Offset int64 `protobuf:"varint,7,opt,name=offset,proto3" json:"offset,omitempty"` + // Data to write in the destination file. + Data []byte `protobuf:"bytes,8,opt,name=data,proto3" json:"data,omitempty"` +} + +func (m *CopyFileRequest) Reset() { *m = CopyFileRequest{} } +func (m *CopyFileRequest) String() string { return proto.CompactTextString(m) } +func (*CopyFileRequest) ProtoMessage() {} +func (*CopyFileRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{49} } + +func (m *CopyFileRequest) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func (m *CopyFileRequest) GetFileSize() int64 { + if m != nil { + return m.FileSize + } + return 0 +} + +func (m *CopyFileRequest) GetFileMode() uint32 { + if m != nil { + return m.FileMode + } + return 0 +} + +func (m *CopyFileRequest) GetDirMode() uint32 { + if m != nil { + return m.DirMode + } + return 0 +} + +func (m *CopyFileRequest) GetUid() int32 { + if m != nil { + return m.Uid + } + return 0 +} + +func (m *CopyFileRequest) GetGid() int32 { + if m != nil { + return m.Gid + } + return 0 +} + +func (m *CopyFileRequest) GetOffset() int64 { + if m != nil { + return m.Offset + } + return 0 +} + +func (m *CopyFileRequest) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + func init() { proto.RegisterType((*CreateContainerRequest)(nil), "grpc.CreateContainerRequest") proto.RegisterType((*StartContainerRequest)(nil), "grpc.StartContainerRequest") @@ -1652,6 +1736,7 @@ func init() { proto.RegisterType((*Storage)(nil), "grpc.Storage") proto.RegisterType((*Device)(nil), "grpc.Device") proto.RegisterType((*StringUser)(nil), "grpc.StringUser") + proto.RegisterType((*CopyFileRequest)(nil), "grpc.CopyFileRequest") } // Reference imports to suppress errors if they are not otherwise used. @@ -1703,6 +1788,7 @@ type AgentServiceClient interface { ReseedRandomDev(ctx context.Context, in *ReseedRandomDevRequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error) GetGuestDetails(ctx context.Context, in *GuestDetailsRequest, opts ...grpc1.CallOption) (*GuestDetailsResponse, error) SetGuestDateTime(ctx context.Context, in *SetGuestDateTimeRequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error) + CopyFile(ctx context.Context, in *CopyFileRequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error) } type agentServiceClient struct { @@ -1965,6 +2051,15 @@ func (c *agentServiceClient) SetGuestDateTime(ctx context.Context, in *SetGuestD return out, nil } +func (c *agentServiceClient) CopyFile(ctx context.Context, in *CopyFileRequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error) { + out := new(google_protobuf2.Empty) + err := grpc1.Invoke(ctx, "/grpc.AgentService/CopyFile", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for AgentService service type AgentServiceServer interface { @@ -2006,6 +2101,7 @@ type AgentServiceServer interface { ReseedRandomDev(context.Context, *ReseedRandomDevRequest) (*google_protobuf2.Empty, error) GetGuestDetails(context.Context, *GuestDetailsRequest) (*GuestDetailsResponse, error) SetGuestDateTime(context.Context, *SetGuestDateTimeRequest) (*google_protobuf2.Empty, error) + CopyFile(context.Context, *CopyFileRequest) (*google_protobuf2.Empty, error) } func RegisterAgentServiceServer(s *grpc1.Server, srv AgentServiceServer) { @@ -2516,6 +2612,24 @@ func _AgentService_SetGuestDateTime_Handler(srv interface{}, ctx context.Context return interceptor(ctx, in, info, handler) } +func _AgentService_CopyFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc1.UnaryServerInterceptor) (interface{}, error) { + in := new(CopyFileRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AgentServiceServer).CopyFile(ctx, in) + } + info := &grpc1.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.AgentService/CopyFile", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AgentServiceServer).CopyFile(ctx, req.(*CopyFileRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _AgentService_serviceDesc = grpc1.ServiceDesc{ ServiceName: "grpc.AgentService", HandlerType: (*AgentServiceServer)(nil), @@ -2632,6 +2746,10 @@ var _AgentService_serviceDesc = grpc1.ServiceDesc{ MethodName: "SetGuestDateTime", Handler: _AgentService_SetGuestDateTime_Handler, }, + { + MethodName: "CopyFile", + Handler: _AgentService_CopyFile_Handler, + }, }, Streams: []grpc1.StreamDesc{}, Metadata: "agent.proto", @@ -4544,6 +4662,66 @@ func (m *StringUser) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *CopyFileRequest) 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 *CopyFileRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Path) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintAgent(dAtA, i, uint64(len(m.Path))) + i += copy(dAtA[i:], m.Path) + } + if m.FileSize != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintAgent(dAtA, i, uint64(m.FileSize)) + } + if m.FileMode != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintAgent(dAtA, i, uint64(m.FileMode)) + } + if m.DirMode != 0 { + dAtA[i] = 0x20 + i++ + i = encodeVarintAgent(dAtA, i, uint64(m.DirMode)) + } + if m.Uid != 0 { + dAtA[i] = 0x28 + i++ + i = encodeVarintAgent(dAtA, i, uint64(m.Uid)) + } + if m.Gid != 0 { + dAtA[i] = 0x30 + i++ + i = encodeVarintAgent(dAtA, i, uint64(m.Gid)) + } + if m.Offset != 0 { + dAtA[i] = 0x38 + i++ + i = encodeVarintAgent(dAtA, i, uint64(m.Offset)) + } + if len(m.Data) > 0 { + dAtA[i] = 0x42 + i++ + i = encodeVarintAgent(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) + } + return i, nil +} + func encodeVarintAgent(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) @@ -5367,6 +5545,38 @@ func (m *StringUser) Size() (n int) { return n } +func (m *CopyFileRequest) Size() (n int) { + var l int + _ = l + l = len(m.Path) + if l > 0 { + n += 1 + l + sovAgent(uint64(l)) + } + if m.FileSize != 0 { + n += 1 + sovAgent(uint64(m.FileSize)) + } + if m.FileMode != 0 { + n += 1 + sovAgent(uint64(m.FileMode)) + } + if m.DirMode != 0 { + n += 1 + sovAgent(uint64(m.DirMode)) + } + if m.Uid != 0 { + n += 1 + sovAgent(uint64(m.Uid)) + } + if m.Gid != 0 { + n += 1 + sovAgent(uint64(m.Gid)) + } + if m.Offset != 0 { + n += 1 + sovAgent(uint64(m.Offset)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovAgent(uint64(l)) + } + return n +} + func sovAgent(x uint64) (n int) { for { n++ @@ -11402,6 +11612,230 @@ func (m *StringUser) Unmarshal(dAtA []byte) error { } return nil } +func (m *CopyFileRequest) 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 ErrIntOverflowAgent + } + 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: CopyFileRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CopyFileRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAgent + } + 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 ErrInvalidLengthAgent + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field FileSize", wireType) + } + m.FileSize = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAgent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.FileSize |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field FileMode", wireType) + } + m.FileMode = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAgent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.FileMode |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DirMode", wireType) + } + m.DirMode = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAgent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DirMode |= (uint32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + 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 ErrIntOverflowAgent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Uid |= (int32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + 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 ErrIntOverflowAgent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Gid |= (int32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Offset", wireType) + } + m.Offset = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAgent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Offset |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAgent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAgent + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAgent(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthAgent + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipAgent(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 @@ -11510,161 +11944,168 @@ var ( func init() { proto.RegisterFile("agent.proto", fileDescriptorAgent) } var fileDescriptorAgent = []byte{ - // 2493 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x58, 0x5b, 0x6f, 0x1b, 0xc7, - 0xf5, 0x07, 0x2f, 0xba, 0xf0, 0x90, 0x14, 0xc5, 0x91, 0x2c, 0x33, 0x74, 0xe2, 0xbf, 0xb2, 0xce, - 0xdf, 0x56, 0x9a, 0x86, 0x6a, 0xe4, 0xa0, 0x09, 0x6c, 0xa4, 0x86, 0x75, 0x81, 0xa4, 0x26, 0xae, - 0xd5, 0xa5, 0x05, 0x17, 0x28, 0x8a, 0xc5, 0x6a, 0x77, 0x4c, 0x4e, 0xc4, 0xdd, 0xd9, 0xec, 0xcc, - 0xca, 0x62, 0x0a, 0x14, 0x7d, 0x6a, 0x3f, 0x45, 0xbf, 0x40, 0xd1, 0xb7, 0x7e, 0x85, 0x3e, 0xe4, - 0xb1, 0xef, 0x05, 0x8a, 0xc2, 0x1f, 0xa1, 0x9f, 0xa0, 0x98, 0xdb, 0x5e, 0x78, 0x91, 0x53, 0x45, - 0x40, 0x5f, 0x16, 0x7b, 0xce, 0x9c, 0xf9, 0x9d, 0xcb, 0xcc, 0x9c, 0x39, 0x73, 0xa0, 0xee, 0x0e, - 0x70, 0xc8, 0x7b, 0x51, 0x4c, 0x39, 0x45, 0xd5, 0x41, 0x1c, 0x79, 0xdd, 0x1a, 0xf5, 0x88, 0x62, - 0x74, 0x7f, 0x3a, 0x20, 0x7c, 0x98, 0x9c, 0xf5, 0x3c, 0x1a, 0x6c, 0x9f, 0xbb, 0xdc, 0xfd, 0xd8, - 0xa3, 0x21, 0x77, 0x49, 0x88, 0x63, 0xb6, 0x2d, 0x27, 0x6e, 0x47, 0xe7, 0x83, 0x6d, 0x3e, 0x8e, - 0x30, 0x53, 0x5f, 0x3d, 0xef, 0xce, 0x80, 0xd2, 0xc1, 0x08, 0x6f, 0x4b, 0xea, 0x2c, 0x79, 0xb5, - 0x8d, 0x83, 0x88, 0x8f, 0xd5, 0xa0, 0xf5, 0xa7, 0x32, 0x6c, 0xec, 0xc5, 0xd8, 0xe5, 0x78, 0xcf, - 0xa0, 0xd9, 0xf8, 0x9b, 0x04, 0x33, 0x8e, 0xde, 0x87, 0x46, 0xaa, 0xc1, 0x21, 0x7e, 0xa7, 0xb4, - 0x59, 0xda, 0xaa, 0xd9, 0xf5, 0x94, 0x77, 0xec, 0xa3, 0xdb, 0xb0, 0x84, 0x2f, 0xb1, 0x27, 0x46, - 0xcb, 0x72, 0x74, 0x51, 0x90, 0xc7, 0x3e, 0xfa, 0x04, 0xea, 0x8c, 0xc7, 0x24, 0x1c, 0x38, 0x09, - 0xc3, 0x71, 0xa7, 0xb2, 0x59, 0xda, 0xaa, 0xef, 0xac, 0xf6, 0x84, 0x4b, 0xbd, 0xbe, 0x1c, 0x38, - 0x65, 0x38, 0xb6, 0x81, 0xa5, 0xff, 0xe8, 0x3e, 0x2c, 0xf9, 0xf8, 0x82, 0x78, 0x98, 0x75, 0xaa, - 0x9b, 0x95, 0xad, 0xfa, 0x4e, 0x43, 0x89, 0xef, 0x4b, 0xa6, 0x6d, 0x06, 0xd1, 0x87, 0xb0, 0xcc, - 0x38, 0x8d, 0xdd, 0x01, 0x66, 0x9d, 0x05, 0x29, 0xd8, 0x34, 0xb8, 0x92, 0x6b, 0xa7, 0xc3, 0xe8, - 0x5d, 0xa8, 0x3c, 0xdf, 0x3b, 0xee, 0x2c, 0x4a, 0xed, 0xa0, 0xa5, 0x22, 0xec, 0xd9, 0x82, 0x8d, - 0xee, 0x41, 0x93, 0xb9, 0xa1, 0x7f, 0x46, 0x2f, 0x9d, 0x88, 0xf8, 0x21, 0xeb, 0x2c, 0x6d, 0x96, - 0xb6, 0x96, 0xed, 0x86, 0x66, 0x9e, 0x08, 0x9e, 0xf5, 0x08, 0x6e, 0xf5, 0xb9, 0x1b, 0xf3, 0x6b, - 0x44, 0xc7, 0x3a, 0x85, 0x0d, 0x1b, 0x07, 0xf4, 0xe2, 0x5a, 0xa1, 0xed, 0xc0, 0x12, 0x27, 0x01, - 0xa6, 0x09, 0x97, 0xa1, 0x6d, 0xda, 0x86, 0xb4, 0xfe, 0x52, 0x02, 0x74, 0x70, 0x89, 0xbd, 0x93, - 0x98, 0x7a, 0x98, 0xb1, 0xff, 0xd1, 0x72, 0x3d, 0x80, 0xa5, 0x48, 0x19, 0xd0, 0xa9, 0x4a, 0x71, - 0xbd, 0x0a, 0xc6, 0x2a, 0x33, 0x6a, 0x7d, 0x0d, 0xeb, 0x7d, 0x32, 0x08, 0xdd, 0xd1, 0x0d, 0xda, - 0xbb, 0x01, 0x8b, 0x4c, 0x62, 0x4a, 0x53, 0x9b, 0xb6, 0xa6, 0xac, 0x13, 0x40, 0x2f, 0x5d, 0xc2, - 0x6f, 0x4e, 0x93, 0xf5, 0x31, 0xac, 0x15, 0x10, 0x59, 0x44, 0x43, 0x86, 0xa5, 0x01, 0xdc, 0xe5, - 0x09, 0x93, 0x60, 0x0b, 0xb6, 0xa6, 0x2c, 0x0c, 0xeb, 0x5f, 0x11, 0x66, 0xc4, 0xf1, 0x7f, 0x63, - 0xc2, 0x06, 0x2c, 0xbe, 0xa2, 0x71, 0xe0, 0x72, 0x63, 0x81, 0xa2, 0x10, 0x82, 0xaa, 0x1b, 0x0f, - 0x58, 0xa7, 0xb2, 0x59, 0xd9, 0xaa, 0xd9, 0xf2, 0x5f, 0xec, 0xca, 0x09, 0x35, 0xda, 0xae, 0xf7, - 0xa1, 0xa1, 0xe3, 0xee, 0x8c, 0x08, 0xe3, 0x52, 0x4f, 0xc3, 0xae, 0x6b, 0x9e, 0x98, 0x63, 0x51, - 0xd8, 0x38, 0x8d, 0xfc, 0x6b, 0x1e, 0xf8, 0x1d, 0xa8, 0xc5, 0x98, 0xd1, 0x24, 0x16, 0xc7, 0xb4, - 0x2c, 0xd7, 0x7d, 0x5d, 0xad, 0xfb, 0x57, 0x24, 0x4c, 0x2e, 0x6d, 0x33, 0x66, 0x67, 0x62, 0xfa, - 0x08, 0x71, 0x76, 0x9d, 0x23, 0xf4, 0x08, 0x6e, 0x9d, 0xb8, 0x09, 0xbb, 0x8e, 0xad, 0xd6, 0x63, - 0x71, 0xfc, 0x58, 0x12, 0x5c, 0x6b, 0xf2, 0x9f, 0x4b, 0xb0, 0xbc, 0x17, 0x25, 0xa7, 0xcc, 0x1d, - 0x60, 0xf4, 0x7f, 0x50, 0xe7, 0x94, 0xbb, 0x23, 0x27, 0x11, 0xa4, 0x14, 0xaf, 0xda, 0x20, 0x59, - 0x4a, 0x40, 0x84, 0x1d, 0xc7, 0x5e, 0x94, 0x68, 0x89, 0xf2, 0x66, 0x65, 0xab, 0x6a, 0xd7, 0x15, - 0x4f, 0x89, 0xf4, 0x60, 0x4d, 0x8e, 0x39, 0x24, 0x74, 0xce, 0x71, 0x1c, 0xe2, 0x51, 0x40, 0x7d, - 0x2c, 0xf7, 0x6f, 0xd5, 0x6e, 0xcb, 0xa1, 0xe3, 0xf0, 0xcb, 0x74, 0x00, 0xfd, 0x08, 0xda, 0xa9, - 0xbc, 0x38, 0x94, 0x52, 0xba, 0x2a, 0xa5, 0x5b, 0x5a, 0xfa, 0x54, 0xb3, 0xad, 0xdf, 0xc1, 0xca, - 0x8b, 0x61, 0x4c, 0x39, 0x1f, 0x91, 0x70, 0xb0, 0xef, 0x72, 0x57, 0x64, 0x8f, 0x08, 0xc7, 0x84, - 0xfa, 0x4c, 0x5b, 0x6b, 0x48, 0xf4, 0x11, 0xb4, 0xb9, 0x92, 0xc5, 0xbe, 0x63, 0x64, 0xca, 0x52, - 0x66, 0x35, 0x1d, 0x38, 0xd1, 0xc2, 0xff, 0x0f, 0x2b, 0x99, 0xb0, 0xc8, 0x3f, 0xda, 0xde, 0x66, - 0xca, 0x7d, 0x41, 0x02, 0x6c, 0x5d, 0xc8, 0x58, 0xc9, 0x45, 0x46, 0x1f, 0x41, 0x2d, 0x8b, 0x43, - 0x49, 0xee, 0x90, 0x15, 0xb5, 0x43, 0x4c, 0x38, 0xed, 0xe5, 0x34, 0x28, 0x5f, 0x40, 0x8b, 0xa7, - 0x86, 0x3b, 0xbe, 0xcb, 0xdd, 0xe2, 0xa6, 0x2a, 0x7a, 0x65, 0xaf, 0xf0, 0x02, 0x6d, 0x3d, 0x86, - 0xda, 0x09, 0xf1, 0x99, 0x52, 0xdc, 0x81, 0x25, 0x2f, 0x89, 0x63, 0x1c, 0x72, 0xe3, 0xb2, 0x26, - 0xd1, 0x3a, 0x2c, 0x8c, 0x48, 0x40, 0xb8, 0x76, 0x53, 0x11, 0x16, 0x05, 0x78, 0x86, 0x03, 0x1a, - 0x8f, 0x65, 0xc0, 0xd6, 0x61, 0x21, 0xbf, 0xb8, 0x8a, 0x40, 0x77, 0xa0, 0x16, 0xb8, 0x97, 0xe9, - 0xa2, 0x8a, 0x91, 0xe5, 0xc0, 0xbd, 0x54, 0xc6, 0x77, 0x60, 0xe9, 0x95, 0x4b, 0x46, 0x5e, 0xc8, - 0x75, 0x54, 0x0c, 0x99, 0x29, 0xac, 0xe6, 0x15, 0xfe, 0xad, 0x0c, 0x75, 0xa5, 0x51, 0x19, 0xbc, - 0x0e, 0x0b, 0x9e, 0xeb, 0x0d, 0x53, 0x95, 0x92, 0x40, 0xf7, 0x8d, 0x21, 0xe5, 0x7c, 0x12, 0xce, - 0x2c, 0x35, 0xa6, 0x6d, 0x03, 0xb0, 0xd7, 0x6e, 0xa4, 0x6d, 0xab, 0xcc, 0x11, 0xae, 0x09, 0x19, - 0x65, 0xee, 0x43, 0x68, 0xa8, 0x7d, 0xa7, 0xa7, 0x54, 0xe7, 0x4c, 0xa9, 0x2b, 0x29, 0x35, 0xe9, - 0x1e, 0x34, 0x13, 0x86, 0x9d, 0x21, 0xc1, 0xb1, 0x1b, 0x7b, 0xc3, 0x71, 0x67, 0x41, 0xdd, 0x91, - 0x09, 0xc3, 0x47, 0x86, 0x87, 0x76, 0x60, 0x41, 0xa4, 0x3f, 0xd6, 0x59, 0x94, 0xd7, 0xf1, 0xbb, - 0x79, 0x48, 0xe9, 0x6a, 0x4f, 0x7e, 0x0f, 0x42, 0x1e, 0x8f, 0x6d, 0x25, 0xda, 0xfd, 0x1c, 0x20, - 0x63, 0xa2, 0x55, 0xa8, 0x9c, 0xe3, 0xb1, 0x3e, 0x87, 0xe2, 0x57, 0x04, 0xe7, 0xc2, 0x1d, 0x25, - 0x26, 0xea, 0x8a, 0x78, 0x54, 0xfe, 0xbc, 0x64, 0x79, 0xd0, 0xda, 0x1d, 0x9d, 0x13, 0x9a, 0x9b, - 0xbe, 0x0e, 0x0b, 0x81, 0xfb, 0x35, 0x8d, 0x4d, 0x24, 0x25, 0x21, 0xb9, 0x24, 0xa4, 0xb1, 0x81, - 0x90, 0x04, 0x5a, 0x81, 0x32, 0x8d, 0x64, 0xbc, 0x6a, 0x76, 0x99, 0x46, 0x99, 0xa2, 0x6a, 0x4e, - 0x91, 0xf5, 0xcf, 0x2a, 0x40, 0xa6, 0x05, 0xd9, 0xd0, 0x25, 0xd4, 0x61, 0x38, 0x16, 0x25, 0x88, - 0x73, 0x36, 0xe6, 0x98, 0x39, 0x31, 0xf6, 0x92, 0x98, 0x91, 0x0b, 0xb1, 0x7e, 0xc2, 0xed, 0x5b, - 0xca, 0xed, 0x09, 0xdb, 0xec, 0xdb, 0x84, 0xf6, 0xd5, 0xbc, 0x5d, 0x31, 0xcd, 0x36, 0xb3, 0xd0, - 0x31, 0xdc, 0xca, 0x30, 0xfd, 0x1c, 0x5c, 0xf9, 0x2a, 0xb8, 0xb5, 0x14, 0xce, 0xcf, 0xa0, 0x0e, - 0x60, 0x8d, 0x50, 0xe7, 0x9b, 0x04, 0x27, 0x05, 0xa0, 0xca, 0x55, 0x40, 0x6d, 0x42, 0x7f, 0x29, - 0x27, 0x64, 0x30, 0x27, 0xf0, 0x4e, 0xce, 0x4b, 0x71, 0xdc, 0x73, 0x60, 0xd5, 0xab, 0xc0, 0x36, - 0x52, 0xab, 0x44, 0x3e, 0xc8, 0x10, 0x7f, 0x0e, 0x1b, 0x84, 0x3a, 0xaf, 0x5d, 0xc2, 0x27, 0xe1, - 0x16, 0xde, 0xe2, 0xa4, 0xb8, 0x74, 0x8b, 0x58, 0xca, 0xc9, 0x00, 0xc7, 0x83, 0x82, 0x93, 0x8b, - 0x6f, 0x71, 0xf2, 0x99, 0x9c, 0x90, 0xc1, 0x3c, 0x85, 0x36, 0xa1, 0x93, 0xd6, 0x2c, 0x5d, 0x05, - 0xd2, 0x22, 0xb4, 0x68, 0xc9, 0x2e, 0xb4, 0x19, 0xf6, 0x38, 0x8d, 0xf3, 0x9b, 0x60, 0xf9, 0x2a, - 0x88, 0x55, 0x2d, 0x9f, 0x62, 0x58, 0xbf, 0x86, 0xc6, 0x51, 0x32, 0xc0, 0x7c, 0x74, 0x96, 0x26, - 0x83, 0x1b, 0xcb, 0x3f, 0xd6, 0xbf, 0xcb, 0x50, 0xdf, 0x1b, 0xc4, 0x34, 0x89, 0x0a, 0x39, 0x59, - 0x1d, 0xd2, 0xc9, 0x9c, 0x2c, 0x45, 0x64, 0x4e, 0x56, 0xc2, 0x9f, 0x42, 0x23, 0x90, 0x47, 0x57, - 0xcb, 0xab, 0x3c, 0xd4, 0x9e, 0x3a, 0xd4, 0x76, 0x3d, 0xc8, 0x25, 0xb3, 0x1e, 0x40, 0x44, 0x7c, - 0xa6, 0xe7, 0xa8, 0x74, 0xd4, 0xd2, 0x15, 0xa1, 0x49, 0xd1, 0x76, 0x2d, 0x4a, 0xb3, 0xf5, 0x27, - 0x50, 0x3f, 0x13, 0x41, 0xd2, 0x13, 0x0a, 0xc9, 0x28, 0x8b, 0x9e, 0x0d, 0x67, 0xd9, 0x21, 0x3c, - 0x82, 0xe6, 0x50, 0x85, 0x4c, 0x4f, 0x52, 0x7b, 0xe8, 0x9e, 0xf6, 0x24, 0xf3, 0xb7, 0x97, 0x8f, - 0xac, 0x5a, 0x80, 0xc6, 0x30, 0xc7, 0xea, 0xf6, 0xa1, 0x3d, 0x25, 0x32, 0x23, 0x07, 0x6d, 0xe5, - 0x73, 0x50, 0x7d, 0x07, 0x29, 0x45, 0xf9, 0x99, 0xf9, 0xbc, 0xf4, 0x0b, 0xd8, 0x98, 0x2c, 0x73, - 0x74, 0x51, 0xf6, 0x29, 0x34, 0x3c, 0x69, 0x5d, 0x61, 0x05, 0xda, 0x53, 0x76, 0xdb, 0x75, 0x2f, - 0x23, 0x2c, 0x1f, 0xd0, 0xcb, 0x98, 0x70, 0xdc, 0xe7, 0x31, 0x76, 0x83, 0x9b, 0xa8, 0x9a, 0x11, - 0x54, 0xe5, 0x15, 0x5b, 0x91, 0x45, 0xa1, 0xfc, 0xb7, 0x1e, 0xc0, 0x5a, 0x41, 0x8b, 0x36, 0x79, - 0x15, 0x2a, 0x23, 0x1c, 0x4a, 0xf4, 0xa6, 0x2d, 0x7e, 0x2d, 0x17, 0xda, 0x36, 0x76, 0xfd, 0x9b, - 0xb3, 0x46, 0xab, 0xa8, 0x64, 0x2a, 0xb6, 0x00, 0xe5, 0x55, 0x68, 0x53, 0x8c, 0xd5, 0xa5, 0x9c, - 0xd5, 0xcf, 0xa1, 0xbd, 0x37, 0xa2, 0x0c, 0xf7, 0xb9, 0x4f, 0xc2, 0x9b, 0x28, 0xf3, 0x7f, 0x0b, - 0x6b, 0x2f, 0xf8, 0xf8, 0xa5, 0x00, 0x63, 0xe4, 0x5b, 0x7c, 0x43, 0xfe, 0xc5, 0xf4, 0xb5, 0xf1, - 0x2f, 0xa6, 0xaf, 0x45, 0x85, 0xef, 0xd1, 0x51, 0x12, 0x84, 0x72, 0xbb, 0x37, 0x6d, 0x4d, 0x59, - 0xff, 0x28, 0xc1, 0xba, 0x7a, 0x83, 0xf7, 0xd5, 0xd3, 0xd3, 0xa8, 0xef, 0xc2, 0xf2, 0x90, 0x32, - 0x1e, 0xba, 0x01, 0xd6, 0xaa, 0x53, 0x5a, 0xc0, 0x8b, 0x37, 0x6b, 0x59, 0xbe, 0x0a, 0xc4, 0x6f, - 0xe1, 0x61, 0x5c, 0xb9, 0xfa, 0x61, 0x3c, 0xf5, 0xf4, 0xad, 0x4e, 0x3f, 0x7d, 0xd1, 0x7b, 0x00, - 0x46, 0x88, 0xf8, 0xf2, 0xe2, 0xaf, 0xd9, 0x35, 0xcd, 0x39, 0xf6, 0xd1, 0x7d, 0x68, 0x0d, 0x84, - 0x95, 0xce, 0x90, 0xd2, 0x73, 0x27, 0x72, 0xf9, 0x50, 0x3e, 0xb4, 0x6b, 0x76, 0x53, 0xb2, 0x8f, - 0x28, 0x3d, 0x3f, 0x71, 0xf9, 0xd0, 0xba, 0x0d, 0xb7, 0xf6, 0x31, 0xe3, 0x31, 0x1d, 0x17, 0xbd, - 0xb3, 0x7e, 0x06, 0x70, 0x1c, 0x72, 0x1c, 0xbf, 0x72, 0xc5, 0xb3, 0xfe, 0x27, 0x79, 0x4a, 0x5f, - 0xa9, 0xab, 0x3d, 0xd5, 0xc7, 0x48, 0x07, 0xec, 0x9c, 0x8c, 0xd5, 0x83, 0x45, 0x9b, 0x26, 0x1c, - 0x33, 0xf4, 0x81, 0xf9, 0xd3, 0xf3, 0x1a, 0x7a, 0x9e, 0x64, 0xda, 0x7a, 0xcc, 0x3a, 0x32, 0x0f, - 0x9f, 0x0c, 0x4e, 0xc7, 0xb9, 0x07, 0x35, 0x62, 0x78, 0xfa, 0x74, 0x4e, 0xab, 0xce, 0x44, 0xac, - 0x03, 0x58, 0x7b, 0xea, 0xfb, 0x3f, 0x18, 0xe6, 0xc8, 0xf4, 0x07, 0x7e, 0x30, 0xd2, 0x63, 0x58, - 0x53, 0xae, 0x29, 0x57, 0x0d, 0xcc, 0x07, 0xb0, 0x18, 0x9b, 0xb8, 0x94, 0xb2, 0x8e, 0x8a, 0x16, - 0xd2, 0x63, 0x62, 0x81, 0xc4, 0xc3, 0x30, 0x8b, 0xac, 0x59, 0xa0, 0x35, 0x68, 0x8b, 0x81, 0x02, - 0xa6, 0xf5, 0x1b, 0x58, 0x7b, 0x1e, 0x8e, 0x48, 0x88, 0xf7, 0x4e, 0x4e, 0x9f, 0xe1, 0x34, 0x13, - 0x20, 0xa8, 0x8a, 0x6b, 0x5e, 0x2a, 0x5a, 0xb6, 0xe5, 0xbf, 0x38, 0x1a, 0xe1, 0x99, 0xe3, 0x45, - 0x09, 0xd3, 0x2d, 0x8c, 0xc5, 0xf0, 0x6c, 0x2f, 0x4a, 0x18, 0x7a, 0x07, 0xc4, 0x75, 0xe3, 0xd0, - 0x70, 0x34, 0x96, 0xe7, 0x63, 0xd9, 0x5e, 0xf2, 0xa2, 0xe4, 0x79, 0x38, 0x1a, 0x5b, 0x3f, 0x96, - 0x8f, 0x36, 0x8c, 0x7d, 0xdb, 0x0d, 0x7d, 0x1a, 0xec, 0xe3, 0x8b, 0x9c, 0x86, 0xf4, 0x81, 0x60, - 0xf2, 0xc0, 0x77, 0x25, 0x68, 0x3c, 0x1d, 0xe0, 0x90, 0xef, 0x63, 0xee, 0x92, 0x91, 0x7c, 0x04, - 0x5c, 0xe0, 0x98, 0x11, 0x1a, 0xea, 0x03, 0x63, 0x48, 0xf1, 0x86, 0x23, 0x21, 0xe1, 0x8e, 0xef, - 0xe2, 0x80, 0x86, 0x12, 0x65, 0xd9, 0x06, 0xc1, 0xda, 0x97, 0x1c, 0xf4, 0x00, 0x5a, 0xaa, 0xc5, - 0xe4, 0x0c, 0xdd, 0xd0, 0x1f, 0xe1, 0xd8, 0x3c, 0xb9, 0x57, 0x14, 0xfb, 0x48, 0x73, 0xd1, 0x87, - 0xb0, 0xaa, 0x0f, 0x52, 0x26, 0x59, 0x95, 0x92, 0x2d, 0xcd, 0x2f, 0x88, 0x26, 0x51, 0x44, 0x63, - 0xce, 0x1c, 0x86, 0x3d, 0x8f, 0x06, 0x91, 0xae, 0xa0, 0x5b, 0x86, 0xdf, 0x57, 0x6c, 0xb1, 0x84, - 0x87, 0xc2, 0x4f, 0xed, 0x49, 0xb6, 0x84, 0x2b, 0x01, 0x0e, 0x9c, 0xb3, 0x11, 0xf5, 0xce, 0x1d, - 0x91, 0x9a, 0x74, 0x84, 0xc5, 0x1d, 0xbd, 0x2b, 0x98, 0x7d, 0xf2, 0x2d, 0xb6, 0x7e, 0x5f, 0x82, - 0xf5, 0xe2, 0x6c, 0x9d, 0x3c, 0xb7, 0x61, 0xbd, 0x38, 0x5d, 0x15, 0xaf, 0xba, 0xca, 0x68, 0xe7, - 0x41, 0x64, 0x79, 0x8a, 0x3e, 0x83, 0xa6, 0xec, 0x25, 0x3a, 0xbe, 0x42, 0x2a, 0xde, 0x7d, 0xf9, - 0x58, 0xdb, 0x0d, 0x37, 0x47, 0x59, 0x4f, 0xe0, 0x76, 0x1f, 0x73, 0x65, 0x84, 0xcb, 0x75, 0x1d, - 0xa8, 0x7c, 0x58, 0x85, 0x4a, 0x1f, 0x7b, 0x52, 0x67, 0xc5, 0x16, 0xbf, 0x62, 0x2d, 0x4f, 0x19, - 0xf6, 0x24, 0x78, 0xc5, 0x96, 0xff, 0xd6, 0x5f, 0x4b, 0xb0, 0xa4, 0x33, 0x95, 0xc8, 0x94, 0x7e, - 0x4c, 0x2e, 0x70, 0xac, 0x57, 0x51, 0x53, 0xe2, 0x3d, 0xaa, 0xfe, 0x1c, 0x1a, 0x71, 0x42, 0xd3, - 0xfc, 0xd7, 0x54, 0xdc, 0xe7, 0x8a, 0x29, 0xbb, 0x33, 0xb2, 0xf9, 0xa0, 0xeb, 0x7c, 0x4d, 0xc9, - 0x16, 0x0b, 0x13, 0xc7, 0x48, 0xe6, 0xbb, 0x9a, 0xad, 0x29, 0xb1, 0x6b, 0x0c, 0xde, 0x82, 0xc4, - 0x33, 0xa4, 0xd8, 0x35, 0x01, 0x4d, 0x42, 0xee, 0x44, 0x94, 0x84, 0x5c, 0x27, 0x38, 0x90, 0xac, - 0x13, 0xc1, 0xb1, 0xfe, 0x50, 0x82, 0x45, 0xd5, 0xa1, 0x14, 0x2f, 0x8b, 0xf4, 0x8a, 0x28, 0x13, - 0x79, 0xdd, 0x4a, 0x5d, 0xea, 0x5a, 0x90, 0xff, 0xe2, 0x48, 0x5c, 0x04, 0x2a, 0x59, 0x6a, 0xd3, - 0x2e, 0x02, 0x91, 0x25, 0x85, 0x67, 0xd9, 0x4d, 0x23, 0xc7, 0x95, 0x89, 0xcd, 0x94, 0x2b, 0xc5, - 0xe6, 0x5a, 0x6a, 0xfd, 0x4a, 0x3c, 0xa8, 0xd2, 0xee, 0xdc, 0x2a, 0x54, 0x92, 0xd4, 0x18, 0xf1, - 0x2b, 0x38, 0x83, 0xf4, 0x8e, 0x12, 0xbf, 0xe8, 0x3e, 0xac, 0xb8, 0xbe, 0x4f, 0xc4, 0x74, 0x77, - 0x74, 0x48, 0xfc, 0x74, 0xbf, 0x17, 0xb9, 0x3b, 0x7f, 0x6c, 0xe9, 0x43, 0xa6, 0x4b, 0x7c, 0x74, - 0x08, 0xad, 0x89, 0x96, 0x31, 0xd2, 0x6f, 0xbe, 0xd9, 0x9d, 0xe4, 0xee, 0x46, 0x4f, 0xb5, 0xa0, - 0x7b, 0xa6, 0x05, 0xdd, 0x3b, 0x08, 0x22, 0x3e, 0x46, 0x07, 0xb0, 0x52, 0x6c, 0xae, 0xa2, 0x3b, - 0xe6, 0xc6, 0x9a, 0xd1, 0x72, 0x9d, 0x0b, 0x73, 0x08, 0xad, 0x89, 0x3e, 0xab, 0xb1, 0x67, 0x76, - 0xfb, 0x75, 0x2e, 0xd0, 0x13, 0xa8, 0xe7, 0x1a, 0xab, 0xa8, 0xa3, 0x40, 0xa6, 0x7b, 0xad, 0x73, - 0x01, 0xf6, 0xa0, 0x59, 0xe8, 0x75, 0xa2, 0xae, 0xf6, 0x67, 0x46, 0x03, 0x74, 0x2e, 0xc8, 0x2e, - 0xd4, 0x73, 0x2d, 0x47, 0x63, 0xc5, 0x74, 0x5f, 0xb3, 0xfb, 0xce, 0x8c, 0x11, 0x7d, 0xee, 0x8f, - 0xa0, 0x59, 0x68, 0x10, 0x1a, 0x43, 0x66, 0x35, 0x27, 0xbb, 0x77, 0x66, 0x8e, 0x69, 0xa4, 0x43, - 0x68, 0x4d, 0xb4, 0x0b, 0x4d, 0x70, 0x67, 0x77, 0x11, 0xe7, 0xba, 0xf5, 0xa5, 0x5c, 0xec, 0x5c, - 0x7d, 0x9c, 0x5b, 0xec, 0xe9, 0xe6, 0x60, 0xf7, 0xdd, 0xd9, 0x83, 0xda, 0xaa, 0x03, 0x58, 0x29, - 0xf6, 0x05, 0x0d, 0xd8, 0xcc, 0x6e, 0xe1, 0xd5, 0x3b, 0xa7, 0xd0, 0x22, 0xcc, 0x76, 0xce, 0xac, - 0xce, 0xe1, 0x5c, 0xa0, 0xa7, 0x00, 0xba, 0x8c, 0xf6, 0x49, 0x98, 0x2e, 0xd9, 0x54, 0xf9, 0x9e, - 0x2e, 0xd9, 0x8c, 0x92, 0xfb, 0x09, 0x80, 0xaa, 0x7e, 0x7d, 0x9a, 0x70, 0x74, 0xdb, 0x98, 0x31, - 0x51, 0x72, 0x77, 0x3b, 0xd3, 0x03, 0x53, 0x00, 0x38, 0x8e, 0xaf, 0x03, 0xf0, 0x05, 0x40, 0x56, - 0x55, 0x1b, 0x80, 0xa9, 0x3a, 0xfb, 0x8a, 0x18, 0x34, 0xf2, 0x35, 0x34, 0xd2, 0xbe, 0xce, 0xa8, - 0xab, 0xe7, 0x42, 0x3c, 0x86, 0x46, 0xbe, 0xb0, 0x32, 0x10, 0x33, 0x8a, 0xad, 0xee, 0x54, 0x3d, - 0x84, 0x9e, 0x9a, 0x9d, 0x9a, 0xb1, 0x0a, 0x3b, 0xf5, 0xfb, 0x41, 0x4c, 0x54, 0x64, 0xc5, 0x4c, - 0xf2, 0x3d, 0x20, 0x3e, 0x83, 0x46, 0xbe, 0x14, 0x33, 0x2e, 0xcc, 0x28, 0xcf, 0xba, 0x85, 0x72, - 0x0c, 0x3d, 0x81, 0x95, 0x62, 0x19, 0x86, 0x72, 0xe7, 0x72, 0xaa, 0x38, 0xeb, 0xea, 0xb7, 0x72, - 0x4e, 0xfc, 0x21, 0x40, 0x56, 0xae, 0x99, 0xe5, 0x9b, 0x2a, 0xe0, 0x26, 0xb4, 0xee, 0x41, 0xb3, - 0xf0, 0xf4, 0x30, 0x89, 0x62, 0xd6, 0x7b, 0xe4, 0xaa, 0x3c, 0x5e, 0x2c, 0xf1, 0x8d, 0xe9, 0x33, - 0x0b, 0xff, 0xab, 0x36, 0x50, 0xbe, 0xb4, 0x34, 0xa1, 0x9b, 0x51, 0x6e, 0xbe, 0xe5, 0x40, 0xe7, - 0xcb, 0xc7, 0xdc, 0x81, 0x9e, 0x51, 0x55, 0xce, 0x05, 0x3a, 0x82, 0xd6, 0xa1, 0x29, 0x67, 0x74, - 0x6d, 0xa9, 0xcd, 0x99, 0x51, 0xa5, 0x75, 0xbb, 0xb3, 0x86, 0xf4, 0xa9, 0x3a, 0x86, 0xd5, 0xc9, - 0xc2, 0x08, 0xbd, 0xa7, 0x93, 0xdb, 0xec, 0x82, 0x69, 0x9e, 0x51, 0xbb, 0x8d, 0xef, 0xde, 0xdc, - 0x2d, 0xfd, 0xfd, 0xcd, 0xdd, 0xd2, 0xbf, 0xde, 0xdc, 0x2d, 0x9d, 0x2d, 0xca, 0xd1, 0x87, 0xff, - 0x09, 0x00, 0x00, 0xff, 0xff, 0x0c, 0x58, 0x87, 0x08, 0x36, 0x1e, 0x00, 0x00, + // 2596 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x58, 0x5f, 0x6f, 0x24, 0x47, + 0x11, 0xd7, 0xfe, 0xf1, 0x7a, 0xb7, 0x76, 0xd7, 0xeb, 0x6d, 0xfb, 0x7c, 0x9b, 0xbd, 0x24, 0x5c, + 0x26, 0xe1, 0xe2, 0x10, 0xb2, 0x26, 0x97, 0x88, 0x84, 0x9c, 0xc2, 0xe9, 0xce, 0x67, 0xce, 0x26, + 0x39, 0xce, 0x8c, 0x63, 0x05, 0x09, 0xa1, 0xd1, 0x78, 0xa6, 0xbd, 0xee, 0x78, 0x67, 0x7a, 0xd2, + 0xdd, 0xe3, 0xbb, 0x0d, 0x12, 0xe2, 0x89, 0x6f, 0xc1, 0x17, 0x40, 0xbc, 0xf1, 0x0d, 0x10, 0x0f, + 0x11, 0x4f, 0xbc, 0x23, 0x21, 0x94, 0x8f, 0xc0, 0x27, 0x40, 0xfd, 0x6f, 0xfe, 0xec, 0x1f, 0x5f, + 0x70, 0x2c, 0xf1, 0x32, 0x9a, 0xaa, 0xae, 0xfe, 0x75, 0x55, 0x75, 0x77, 0x75, 0x55, 0x41, 0xdb, + 0x1f, 0xe3, 0x58, 0x8c, 0x12, 0x46, 0x05, 0x45, 0xf5, 0x31, 0x4b, 0x82, 0x61, 0x8b, 0x06, 0x44, + 0x33, 0x86, 0x3f, 0x1e, 0x13, 0x71, 0x96, 0x9e, 0x8c, 0x02, 0x1a, 0xed, 0x9c, 0xfb, 0xc2, 0x7f, + 0x27, 0xa0, 0xb1, 0xf0, 0x49, 0x8c, 0x19, 0xdf, 0x51, 0x13, 0x77, 0x92, 0xf3, 0xf1, 0x8e, 0x98, + 0x26, 0x98, 0xeb, 0xaf, 0x99, 0x77, 0x6b, 0x4c, 0xe9, 0x78, 0x82, 0x77, 0x14, 0x75, 0x92, 0x9e, + 0xee, 0xe0, 0x28, 0x11, 0x53, 0x3d, 0xe8, 0xfc, 0xb1, 0x0a, 0x5b, 0xbb, 0x0c, 0xfb, 0x02, 0xef, + 0x5a, 0x34, 0x17, 0x7f, 0x99, 0x62, 0x2e, 0xd0, 0x6b, 0xd0, 0xc9, 0x56, 0xf0, 0x48, 0x38, 0xa8, + 0xdc, 0xae, 0x6c, 0xb7, 0xdc, 0x76, 0xc6, 0x3b, 0x08, 0xd1, 0x4d, 0x58, 0xc5, 0xcf, 0x71, 0x20, + 0x47, 0xab, 0x6a, 0xb4, 0x21, 0xc9, 0x83, 0x10, 0xbd, 0x0b, 0x6d, 0x2e, 0x18, 0x89, 0xc7, 0x5e, + 0xca, 0x31, 0x1b, 0xd4, 0x6e, 0x57, 0xb6, 0xdb, 0x77, 0xd7, 0x47, 0xd2, 0xa4, 0xd1, 0x91, 0x1a, + 0x38, 0xe6, 0x98, 0xb9, 0xc0, 0xb3, 0x7f, 0x74, 0x07, 0x56, 0x43, 0x7c, 0x41, 0x02, 0xcc, 0x07, + 0xf5, 0xdb, 0xb5, 0xed, 0xf6, 0xdd, 0x8e, 0x16, 0x7f, 0xa4, 0x98, 0xae, 0x1d, 0x44, 0x6f, 0x41, + 0x93, 0x0b, 0xca, 0xfc, 0x31, 0xe6, 0x83, 0x15, 0x25, 0xd8, 0xb5, 0xb8, 0x8a, 0xeb, 0x66, 0xc3, + 0xe8, 0x65, 0xa8, 0x3d, 0xdd, 0x3d, 0x18, 0x34, 0xd4, 0xea, 0x60, 0xa4, 0x12, 0x1c, 0xb8, 0x92, + 0x8d, 0x5e, 0x87, 0x2e, 0xf7, 0xe3, 0xf0, 0x84, 0x3e, 0xf7, 0x12, 0x12, 0xc6, 0x7c, 0xb0, 0x7a, + 0xbb, 0xb2, 0xdd, 0x74, 0x3b, 0x86, 0x79, 0x28, 0x79, 0xce, 0x47, 0x70, 0xe3, 0x48, 0xf8, 0x4c, + 0x5c, 0xc1, 0x3b, 0xce, 0x31, 0x6c, 0xb9, 0x38, 0xa2, 0x17, 0x57, 0x72, 0xed, 0x00, 0x56, 0x05, + 0x89, 0x30, 0x4d, 0x85, 0x72, 0x6d, 0xd7, 0xb5, 0xa4, 0xf3, 0xe7, 0x0a, 0xa0, 0xbd, 0xe7, 0x38, + 0x38, 0x64, 0x34, 0xc0, 0x9c, 0xff, 0x9f, 0xb6, 0xeb, 0x4d, 0x58, 0x4d, 0xb4, 0x02, 0x83, 0xba, + 0x12, 0x37, 0xbb, 0x60, 0xb5, 0xb2, 0xa3, 0xce, 0x17, 0xb0, 0x79, 0x44, 0xc6, 0xb1, 0x3f, 0xb9, + 0x46, 0x7d, 0xb7, 0xa0, 0xc1, 0x15, 0xa6, 0x52, 0xb5, 0xeb, 0x1a, 0xca, 0x39, 0x04, 0xf4, 0xb9, + 0x4f, 0xc4, 0xf5, 0xad, 0xe4, 0xbc, 0x03, 0x1b, 0x25, 0x44, 0x9e, 0xd0, 0x98, 0x63, 0xa5, 0x80, + 0xf0, 0x45, 0xca, 0x15, 0xd8, 0x8a, 0x6b, 0x28, 0x07, 0xc3, 0xe6, 0xa7, 0x84, 0x5b, 0x71, 0xfc, + 0xbf, 0xa8, 0xb0, 0x05, 0x8d, 0x53, 0xca, 0x22, 0x5f, 0x58, 0x0d, 0x34, 0x85, 0x10, 0xd4, 0x7d, + 0x36, 0xe6, 0x83, 0xda, 0xed, 0xda, 0x76, 0xcb, 0x55, 0xff, 0xf2, 0x54, 0xce, 0x2c, 0x63, 0xf4, + 0x7a, 0x0d, 0x3a, 0xc6, 0xef, 0xde, 0x84, 0x70, 0xa1, 0xd6, 0xe9, 0xb8, 0x6d, 0xc3, 0x93, 0x73, + 0x1c, 0x0a, 0x5b, 0xc7, 0x49, 0x78, 0xc5, 0x0b, 0x7f, 0x17, 0x5a, 0x0c, 0x73, 0x9a, 0x32, 0x79, + 0x4d, 0xab, 0x6a, 0xdf, 0x37, 0xf5, 0xbe, 0x7f, 0x4a, 0xe2, 0xf4, 0xb9, 0x6b, 0xc7, 0xdc, 0x5c, + 0xcc, 0x5c, 0x21, 0xc1, 0xaf, 0x72, 0x85, 0x3e, 0x82, 0x1b, 0x87, 0x7e, 0xca, 0xaf, 0xa2, 0xab, + 0x73, 0x4f, 0x5e, 0x3f, 0x9e, 0x46, 0x57, 0x9a, 0xfc, 0xa7, 0x0a, 0x34, 0x77, 0x93, 0xf4, 0x98, + 0xfb, 0x63, 0x8c, 0xbe, 0x07, 0x6d, 0x41, 0x85, 0x3f, 0xf1, 0x52, 0x49, 0x2a, 0xf1, 0xba, 0x0b, + 0x8a, 0xa5, 0x05, 0xa4, 0xdb, 0x31, 0x0b, 0x92, 0xd4, 0x48, 0x54, 0x6f, 0xd7, 0xb6, 0xeb, 0x6e, + 0x5b, 0xf3, 0xb4, 0xc8, 0x08, 0x36, 0xd4, 0x98, 0x47, 0x62, 0xef, 0x1c, 0xb3, 0x18, 0x4f, 0x22, + 0x1a, 0x62, 0x75, 0x7e, 0xeb, 0x6e, 0x5f, 0x0d, 0x1d, 0xc4, 0x9f, 0x64, 0x03, 0xe8, 0x07, 0xd0, + 0xcf, 0xe4, 0xe5, 0xa5, 0x54, 0xd2, 0x75, 0x25, 0xdd, 0x33, 0xd2, 0xc7, 0x86, 0xed, 0xfc, 0x0e, + 0xd6, 0x3e, 0x3b, 0x63, 0x54, 0x88, 0x09, 0x89, 0xc7, 0x8f, 0x7c, 0xe1, 0xcb, 0xe8, 0x91, 0x60, + 0x46, 0x68, 0xc8, 0x8d, 0xb6, 0x96, 0x44, 0x6f, 0x43, 0x5f, 0x68, 0x59, 0x1c, 0x7a, 0x56, 0xa6, + 0xaa, 0x64, 0xd6, 0xb3, 0x81, 0x43, 0x23, 0xfc, 0x7d, 0x58, 0xcb, 0x85, 0x65, 0xfc, 0x31, 0xfa, + 0x76, 0x33, 0xee, 0x67, 0x24, 0xc2, 0xce, 0x85, 0xf2, 0x95, 0xda, 0x64, 0xf4, 0x36, 0xb4, 0x72, + 0x3f, 0x54, 0xd4, 0x09, 0x59, 0xd3, 0x27, 0xc4, 0xba, 0xd3, 0x6d, 0x66, 0x4e, 0xf9, 0x18, 0x7a, + 0x22, 0x53, 0xdc, 0x0b, 0x7d, 0xe1, 0x97, 0x0f, 0x55, 0xd9, 0x2a, 0x77, 0x4d, 0x94, 0x68, 0xe7, + 0x1e, 0xb4, 0x0e, 0x49, 0xc8, 0xf5, 0xc2, 0x03, 0x58, 0x0d, 0x52, 0xc6, 0x70, 0x2c, 0xac, 0xc9, + 0x86, 0x44, 0x9b, 0xb0, 0x32, 0x21, 0x11, 0x11, 0xc6, 0x4c, 0x4d, 0x38, 0x14, 0xe0, 0x09, 0x8e, + 0x28, 0x9b, 0x2a, 0x87, 0x6d, 0xc2, 0x4a, 0x71, 0x73, 0x35, 0x81, 0x6e, 0x41, 0x2b, 0xf2, 0x9f, + 0x67, 0x9b, 0x2a, 0x47, 0x9a, 0x91, 0xff, 0x5c, 0x2b, 0x3f, 0x80, 0xd5, 0x53, 0x9f, 0x4c, 0x82, + 0x58, 0x18, 0xaf, 0x58, 0x32, 0x5f, 0xb0, 0x5e, 0x5c, 0xf0, 0x6f, 0x55, 0x68, 0xeb, 0x15, 0xb5, + 0xc2, 0x9b, 0xb0, 0x12, 0xf8, 0xc1, 0x59, 0xb6, 0xa4, 0x22, 0xd0, 0x1d, 0xab, 0x48, 0xb5, 0x18, + 0x84, 0x73, 0x4d, 0xad, 0x6a, 0x3b, 0x00, 0xfc, 0x99, 0x9f, 0x18, 0xdd, 0x6a, 0x4b, 0x84, 0x5b, + 0x52, 0x46, 0xab, 0xfb, 0x1e, 0x74, 0xf4, 0xb9, 0x33, 0x53, 0xea, 0x4b, 0xa6, 0xb4, 0xb5, 0x94, + 0x9e, 0xf4, 0x3a, 0x74, 0x53, 0x8e, 0xbd, 0x33, 0x82, 0x99, 0xcf, 0x82, 0xb3, 0xe9, 0x60, 0x45, + 0xbf, 0x91, 0x29, 0xc7, 0xfb, 0x96, 0x87, 0xee, 0xc2, 0x8a, 0x0c, 0x7f, 0x7c, 0xd0, 0x50, 0xcf, + 0xf1, 0xcb, 0x45, 0x48, 0x65, 0xea, 0x48, 0x7d, 0xf7, 0x62, 0xc1, 0xa6, 0xae, 0x16, 0x1d, 0x7e, + 0x08, 0x90, 0x33, 0xd1, 0x3a, 0xd4, 0xce, 0xf1, 0xd4, 0xdc, 0x43, 0xf9, 0x2b, 0x9d, 0x73, 0xe1, + 0x4f, 0x52, 0xeb, 0x75, 0x4d, 0x7c, 0x54, 0xfd, 0xb0, 0xe2, 0x04, 0xd0, 0x7b, 0x38, 0x39, 0x27, + 0xb4, 0x30, 0x7d, 0x13, 0x56, 0x22, 0xff, 0x0b, 0xca, 0xac, 0x27, 0x15, 0xa1, 0xb8, 0x24, 0xa6, + 0xcc, 0x42, 0x28, 0x02, 0xad, 0x41, 0x95, 0x26, 0xca, 0x5f, 0x2d, 0xb7, 0x4a, 0x93, 0x7c, 0xa1, + 0x7a, 0x61, 0x21, 0xe7, 0x5f, 0x75, 0x80, 0x7c, 0x15, 0xe4, 0xc2, 0x90, 0x50, 0x8f, 0x63, 0x26, + 0x53, 0x10, 0xef, 0x64, 0x2a, 0x30, 0xf7, 0x18, 0x0e, 0x52, 0xc6, 0xc9, 0x85, 0xdc, 0x3f, 0x69, + 0xf6, 0x0d, 0x6d, 0xf6, 0x8c, 0x6e, 0xee, 0x4d, 0x42, 0x8f, 0xf4, 0xbc, 0x87, 0x72, 0x9a, 0x6b, + 0x67, 0xa1, 0x03, 0xb8, 0x91, 0x63, 0x86, 0x05, 0xb8, 0xea, 0x65, 0x70, 0x1b, 0x19, 0x5c, 0x98, + 0x43, 0xed, 0xc1, 0x06, 0xa1, 0xde, 0x97, 0x29, 0x4e, 0x4b, 0x40, 0xb5, 0xcb, 0x80, 0xfa, 0x84, + 0xfe, 0x52, 0x4d, 0xc8, 0x61, 0x0e, 0xe1, 0xa5, 0x82, 0x95, 0xf2, 0xba, 0x17, 0xc0, 0xea, 0x97, + 0x81, 0x6d, 0x65, 0x5a, 0xc9, 0x78, 0x90, 0x23, 0xfe, 0x1c, 0xb6, 0x08, 0xf5, 0x9e, 0xf9, 0x44, + 0xcc, 0xc2, 0xad, 0xbc, 0xc0, 0x48, 0xf9, 0xe8, 0x96, 0xb1, 0xb4, 0x91, 0x11, 0x66, 0xe3, 0x92, + 0x91, 0x8d, 0x17, 0x18, 0xf9, 0x44, 0x4d, 0xc8, 0x61, 0x1e, 0x40, 0x9f, 0xd0, 0x59, 0x6d, 0x56, + 0x2f, 0x03, 0xe9, 0x11, 0x5a, 0xd6, 0xe4, 0x21, 0xf4, 0x39, 0x0e, 0x04, 0x65, 0xc5, 0x43, 0xd0, + 0xbc, 0x0c, 0x62, 0xdd, 0xc8, 0x67, 0x18, 0xce, 0xaf, 0xa1, 0xb3, 0x9f, 0x8e, 0xb1, 0x98, 0x9c, + 0x64, 0xc1, 0xe0, 0xda, 0xe2, 0x8f, 0xf3, 0x9f, 0x2a, 0xb4, 0x77, 0xc7, 0x8c, 0xa6, 0x49, 0x29, + 0x26, 0xeb, 0x4b, 0x3a, 0x1b, 0x93, 0x95, 0x88, 0x8a, 0xc9, 0x5a, 0xf8, 0x7d, 0xe8, 0x44, 0xea, + 0xea, 0x1a, 0x79, 0x1d, 0x87, 0xfa, 0x73, 0x97, 0xda, 0x6d, 0x47, 0x85, 0x60, 0x36, 0x02, 0x48, + 0x48, 0xc8, 0xcd, 0x1c, 0x1d, 0x8e, 0x7a, 0x26, 0x23, 0xb4, 0x21, 0xda, 0x6d, 0x25, 0x59, 0xb4, + 0x7e, 0x17, 0xda, 0x27, 0xd2, 0x49, 0x66, 0x42, 0x29, 0x18, 0xe5, 0xde, 0x73, 0xe1, 0x24, 0xbf, + 0x84, 0xfb, 0xd0, 0x3d, 0xd3, 0x2e, 0x33, 0x93, 0xf4, 0x19, 0x7a, 0xdd, 0x58, 0x92, 0xdb, 0x3b, + 0x2a, 0x7a, 0x56, 0x6f, 0x40, 0xe7, 0xac, 0xc0, 0x1a, 0x1e, 0x41, 0x7f, 0x4e, 0x64, 0x41, 0x0c, + 0xda, 0x2e, 0xc6, 0xa0, 0xf6, 0x5d, 0xa4, 0x17, 0x2a, 0xce, 0x2c, 0xc6, 0xa5, 0x5f, 0xc0, 0xd6, + 0x6c, 0x9a, 0x63, 0x92, 0xb2, 0xf7, 0xa1, 0x13, 0x28, 0xed, 0x4a, 0x3b, 0xd0, 0x9f, 0xd3, 0xdb, + 0x6d, 0x07, 0x39, 0xe1, 0x84, 0x80, 0x3e, 0x67, 0x44, 0xe0, 0x23, 0xc1, 0xb0, 0x1f, 0x5d, 0x47, + 0xd6, 0x8c, 0xa0, 0xae, 0x9e, 0xd8, 0x9a, 0x4a, 0x0a, 0xd5, 0xbf, 0xf3, 0x26, 0x6c, 0x94, 0x56, + 0x31, 0x2a, 0xaf, 0x43, 0x6d, 0x82, 0x63, 0x85, 0xde, 0x75, 0xe5, 0xaf, 0xe3, 0x43, 0xdf, 0xc5, + 0x7e, 0x78, 0x7d, 0xda, 0x98, 0x25, 0x6a, 0xf9, 0x12, 0xdb, 0x80, 0x8a, 0x4b, 0x18, 0x55, 0xac, + 0xd6, 0x95, 0x82, 0xd6, 0x4f, 0xa1, 0xbf, 0x3b, 0xa1, 0x1c, 0x1f, 0x89, 0x90, 0xc4, 0xd7, 0x91, + 0xe6, 0xff, 0x16, 0x36, 0x3e, 0x13, 0xd3, 0xcf, 0x25, 0x18, 0x27, 0x5f, 0xe1, 0x6b, 0xb2, 0x8f, + 0xd1, 0x67, 0xd6, 0x3e, 0x46, 0x9f, 0xc9, 0x0c, 0x3f, 0xa0, 0x93, 0x34, 0x8a, 0xd5, 0x71, 0xef, + 0xba, 0x86, 0x72, 0xfe, 0x59, 0x81, 0x4d, 0x5d, 0x83, 0x1f, 0xe9, 0xd2, 0xd3, 0x2e, 0x3f, 0x84, + 0xe6, 0x19, 0xe5, 0x22, 0xf6, 0x23, 0x6c, 0x96, 0xce, 0x68, 0x09, 0x2f, 0x6b, 0xd6, 0xaa, 0xaa, + 0x0a, 0xe4, 0x6f, 0xa9, 0x30, 0xae, 0x5d, 0x5e, 0x18, 0xcf, 0x95, 0xbe, 0xf5, 0xf9, 0xd2, 0x17, + 0xbd, 0x02, 0x60, 0x85, 0x48, 0xa8, 0x1e, 0xfe, 0x96, 0xdb, 0x32, 0x9c, 0x83, 0x10, 0xdd, 0x81, + 0xde, 0x58, 0x6a, 0xe9, 0x9d, 0x51, 0x7a, 0xee, 0x25, 0xbe, 0x38, 0x53, 0x85, 0x76, 0xcb, 0xed, + 0x2a, 0xf6, 0x3e, 0xa5, 0xe7, 0x87, 0xbe, 0x38, 0x73, 0x6e, 0xc2, 0x8d, 0x47, 0x98, 0x0b, 0x46, + 0xa7, 0x65, 0xeb, 0x9c, 0x9f, 0x02, 0x1c, 0xc4, 0x02, 0xb3, 0x53, 0x5f, 0x96, 0xf5, 0x3f, 0x2a, + 0x52, 0xe6, 0x49, 0x5d, 0x1f, 0xe9, 0x3e, 0x46, 0x36, 0xe0, 0x16, 0x64, 0x9c, 0x11, 0x34, 0x5c, + 0x9a, 0x0a, 0xcc, 0xd1, 0x1b, 0xf6, 0xcf, 0xcc, 0xeb, 0x98, 0x79, 0x8a, 0xe9, 0x9a, 0x31, 0x67, + 0xdf, 0x16, 0x3e, 0x39, 0x9c, 0xf1, 0xf3, 0x08, 0x5a, 0xc4, 0xf2, 0xcc, 0xed, 0x9c, 0x5f, 0x3a, + 0x17, 0x71, 0xf6, 0x60, 0xe3, 0x41, 0x18, 0x7e, 0x67, 0x98, 0x7d, 0xdb, 0x1f, 0xf8, 0xce, 0x48, + 0xf7, 0x60, 0x43, 0x9b, 0xa6, 0x4d, 0xb5, 0x30, 0x6f, 0x40, 0x83, 0x59, 0xbf, 0x54, 0xf2, 0x8e, + 0x8a, 0x11, 0x32, 0x63, 0x72, 0x83, 0x64, 0x61, 0x98, 0x7b, 0xd6, 0x6e, 0xd0, 0x06, 0xf4, 0xe5, + 0x40, 0x09, 0xd3, 0xf9, 0x0d, 0x6c, 0x3c, 0x8d, 0x27, 0x24, 0xc6, 0xbb, 0x87, 0xc7, 0x4f, 0x70, + 0x16, 0x09, 0x10, 0xd4, 0xe5, 0x33, 0xaf, 0x16, 0x6a, 0xba, 0xea, 0x5f, 0x5e, 0x8d, 0xf8, 0xc4, + 0x0b, 0x92, 0x94, 0x9b, 0x16, 0x46, 0x23, 0x3e, 0xd9, 0x4d, 0x52, 0x8e, 0x5e, 0x02, 0xf9, 0xdc, + 0x78, 0x34, 0x9e, 0x4c, 0xd5, 0xfd, 0x68, 0xba, 0xab, 0x41, 0x92, 0x3e, 0x8d, 0x27, 0x53, 0xe7, + 0x87, 0xaa, 0x68, 0xc3, 0x38, 0x74, 0xfd, 0x38, 0xa4, 0xd1, 0x23, 0x7c, 0x51, 0x58, 0x21, 0x2b, + 0x10, 0x6c, 0x1c, 0xf8, 0xba, 0x02, 0x9d, 0x07, 0x63, 0x1c, 0x8b, 0x47, 0x58, 0xf8, 0x64, 0xa2, + 0x8a, 0x80, 0x0b, 0xcc, 0x38, 0xa1, 0xb1, 0xb9, 0x30, 0x96, 0x94, 0x35, 0x1c, 0x89, 0x89, 0xf0, + 0x42, 0x1f, 0x47, 0x34, 0x56, 0x28, 0x4d, 0x17, 0x24, 0xeb, 0x91, 0xe2, 0xa0, 0x37, 0xa1, 0xa7, + 0x5b, 0x4c, 0xde, 0x99, 0x1f, 0x87, 0x13, 0xcc, 0x6c, 0xc9, 0xbd, 0xa6, 0xd9, 0xfb, 0x86, 0x8b, + 0xde, 0x82, 0x75, 0x73, 0x91, 0x72, 0xc9, 0xba, 0x92, 0xec, 0x19, 0x7e, 0x49, 0x34, 0x4d, 0x12, + 0xca, 0x04, 0xf7, 0x38, 0x0e, 0x02, 0x1a, 0x25, 0x26, 0x83, 0xee, 0x59, 0xfe, 0x91, 0x66, 0xcb, + 0x2d, 0x7c, 0x2c, 0xed, 0x34, 0x96, 0xe4, 0x5b, 0xb8, 0x16, 0xe1, 0xc8, 0x3b, 0x99, 0xd0, 0xe0, + 0xdc, 0x93, 0xa1, 0xc9, 0x78, 0x58, 0xbe, 0xd1, 0x0f, 0x25, 0xf3, 0x88, 0x7c, 0x85, 0x9d, 0xdf, + 0x57, 0x60, 0xb3, 0x3c, 0xdb, 0x04, 0xcf, 0x1d, 0xd8, 0x2c, 0x4f, 0xd7, 0xc9, 0xab, 0xc9, 0x32, + 0xfa, 0x45, 0x10, 0x95, 0x9e, 0xa2, 0x0f, 0xa0, 0xab, 0x7a, 0x89, 0x5e, 0xa8, 0x91, 0xca, 0x6f, + 0x5f, 0xd1, 0xd7, 0x6e, 0xc7, 0x2f, 0x50, 0xce, 0x7d, 0xb8, 0x79, 0x84, 0x85, 0x56, 0xc2, 0x17, + 0x26, 0x0f, 0xd4, 0x36, 0xac, 0x43, 0xed, 0x08, 0x07, 0x6a, 0xcd, 0x9a, 0x2b, 0x7f, 0xe5, 0x5e, + 0x1e, 0x73, 0x1c, 0x28, 0xf0, 0x9a, 0xab, 0xfe, 0x9d, 0xbf, 0x54, 0x60, 0xd5, 0x44, 0x2a, 0x19, + 0x29, 0x43, 0x46, 0x2e, 0x30, 0x33, 0xbb, 0x68, 0x28, 0x59, 0x8f, 0xea, 0x3f, 0x8f, 0x26, 0x82, + 0xd0, 0x2c, 0xfe, 0x75, 0x35, 0xf7, 0xa9, 0x66, 0xaa, 0xee, 0x8c, 0x6a, 0x3e, 0x98, 0x3c, 0xdf, + 0x50, 0xaa, 0xc5, 0xc2, 0xe5, 0x35, 0x52, 0xf1, 0xae, 0xe5, 0x1a, 0x4a, 0x9e, 0x1a, 0x8b, 0xb7, + 0xa2, 0xf0, 0x2c, 0x29, 0x4f, 0x4d, 0x44, 0xd3, 0x58, 0x78, 0x09, 0x25, 0xb1, 0x30, 0x01, 0x0e, + 0x14, 0xeb, 0x50, 0x72, 0x9c, 0x3f, 0x54, 0xa0, 0xa1, 0x3b, 0x94, 0xb2, 0xb2, 0xc8, 0x9e, 0x88, + 0x2a, 0x51, 0xcf, 0xad, 0x5a, 0x4b, 0x3f, 0x0b, 0xea, 0x5f, 0x5e, 0x89, 0x8b, 0x48, 0x07, 0x4b, + 0xa3, 0xda, 0x45, 0x24, 0xa3, 0xa4, 0xb4, 0x2c, 0x7f, 0x69, 0xd4, 0xb8, 0x56, 0xb1, 0x9b, 0x71, + 0x95, 0xd8, 0x52, 0x4d, 0x9d, 0x5f, 0xc9, 0x82, 0x2a, 0xeb, 0xce, 0xad, 0x43, 0x2d, 0xcd, 0x94, + 0x91, 0xbf, 0x92, 0x33, 0xce, 0xde, 0x28, 0xf9, 0x8b, 0xee, 0xc0, 0x9a, 0x1f, 0x86, 0x44, 0x4e, + 0xf7, 0x27, 0x8f, 0x49, 0x98, 0x9d, 0xf7, 0x32, 0xd7, 0xf9, 0x7b, 0x05, 0x7a, 0xbb, 0x34, 0x99, + 0xfe, 0x8c, 0x4c, 0x70, 0xe1, 0x32, 0x2a, 0x25, 0xf5, 0x02, 0xea, 0x5f, 0x26, 0xab, 0xa7, 0x64, + 0x82, 0xf5, 0x29, 0xd5, 0x3b, 0xdb, 0x94, 0x0c, 0x79, 0xb8, 0xb2, 0xc1, 0xac, 0xe9, 0xd1, 0xd5, + 0x83, 0x4f, 0x68, 0x88, 0x65, 0x3c, 0x08, 0x09, 0xf3, 0xb2, 0x16, 0x47, 0xd7, 0x5d, 0x0d, 0x09, + 0x53, 0x43, 0xc6, 0x90, 0x15, 0xd5, 0x65, 0x2b, 0x1a, 0xd2, 0xd0, 0x1c, 0x69, 0xc8, 0x16, 0x34, + 0xe8, 0xe9, 0x29, 0xc7, 0x42, 0x75, 0x70, 0x6b, 0xae, 0xa1, 0xb2, 0x88, 0xd1, 0xcc, 0x23, 0xc6, + 0xdd, 0xbf, 0xf6, 0x4c, 0xc4, 0x30, 0xf5, 0x0a, 0x7a, 0x0c, 0xbd, 0x99, 0xfe, 0x37, 0x32, 0x05, + 0xec, 0xe2, 0xb6, 0xf8, 0x70, 0x6b, 0xa4, 0xfb, 0xe9, 0x23, 0xdb, 0x4f, 0x1f, 0xed, 0x45, 0x89, + 0x98, 0xa2, 0x3d, 0x58, 0x2b, 0x77, 0x8a, 0xd1, 0x2d, 0xfb, 0xfc, 0x2e, 0xe8, 0x1f, 0x2f, 0x85, + 0x79, 0x0c, 0xbd, 0x99, 0xa6, 0xb1, 0xd5, 0x67, 0x71, 0x2f, 0x79, 0x29, 0xd0, 0x7d, 0x68, 0x17, + 0xba, 0xc4, 0x68, 0xa0, 0x41, 0xe6, 0x1b, 0xc7, 0x4b, 0x01, 0x76, 0xa1, 0x5b, 0x6a, 0xdc, 0xa2, + 0xa1, 0xb1, 0x67, 0x41, 0x37, 0x77, 0x29, 0xc8, 0x43, 0x68, 0x17, 0xfa, 0xa7, 0x56, 0x8b, 0xf9, + 0x26, 0xed, 0xf0, 0xa5, 0x05, 0x23, 0x26, 0x88, 0xed, 0x43, 0xb7, 0xd4, 0xed, 0xb4, 0x8a, 0x2c, + 0xea, 0xb4, 0x0e, 0x6f, 0x2d, 0x1c, 0x33, 0x48, 0x8f, 0xa1, 0x37, 0xd3, 0xfb, 0xb4, 0xce, 0x5d, + 0xdc, 0x12, 0x5d, 0x6a, 0xd6, 0x27, 0x6a, 0xb3, 0x0b, 0xc9, 0x7e, 0x61, 0xb3, 0xe7, 0x3b, 0x9d, + 0xc3, 0x97, 0x17, 0x0f, 0x1a, 0xad, 0xf6, 0x60, 0xad, 0xdc, 0xe4, 0xb4, 0x60, 0x0b, 0x5b, 0x9f, + 0x97, 0x9f, 0x9c, 0x52, 0xbf, 0x33, 0x3f, 0x39, 0x8b, 0xda, 0xa0, 0x4b, 0x81, 0x1e, 0x00, 0x98, + 0x9a, 0x20, 0x24, 0x71, 0xb6, 0x65, 0x73, 0xb5, 0x48, 0xb6, 0x65, 0x0b, 0xea, 0x87, 0xfb, 0x00, + 0x3a, 0x95, 0x0f, 0x69, 0x2a, 0xd0, 0x4d, 0xab, 0xc6, 0x4c, 0xfd, 0x30, 0x1c, 0xcc, 0x0f, 0xcc, + 0x01, 0x60, 0xc6, 0xae, 0x02, 0xf0, 0x31, 0x40, 0x5e, 0x22, 0x58, 0x80, 0xb9, 0xa2, 0xe1, 0x12, + 0x1f, 0x74, 0x8a, 0x05, 0x01, 0x32, 0xb6, 0x2e, 0x28, 0x12, 0x96, 0x42, 0xdc, 0x83, 0x4e, 0x31, + 0x4b, 0xb4, 0x10, 0x0b, 0x32, 0xc7, 0xe1, 0x5c, 0x72, 0x87, 0x1e, 0xd8, 0x93, 0x9a, 0xb3, 0x4a, + 0x27, 0xf5, 0xdb, 0x41, 0xcc, 0xa4, 0x97, 0xe5, 0x48, 0xf2, 0x2d, 0x20, 0x3e, 0x80, 0x4e, 0x31, + 0xaf, 0xb4, 0x26, 0x2c, 0xc8, 0x35, 0x87, 0xa5, 0xdc, 0x12, 0xdd, 0x87, 0xb5, 0x72, 0x4e, 0x89, + 0x0a, 0xf7, 0x72, 0x2e, 0xd3, 0x1c, 0x9a, 0xc2, 0xbf, 0x20, 0xfe, 0x1e, 0x40, 0x9e, 0x7b, 0xda, + 0xed, 0x9b, 0xcb, 0x46, 0x67, 0x56, 0xdd, 0x85, 0x6e, 0xa9, 0x8e, 0xb2, 0x81, 0x62, 0x51, 0x71, + 0x75, 0x59, 0x1c, 0x2f, 0xd7, 0x2b, 0x56, 0xf5, 0x85, 0x55, 0xcc, 0x65, 0x07, 0xa8, 0x98, 0x27, + 0x5b, 0xd7, 0x2d, 0xc8, 0x9d, 0x5f, 0x70, 0xa1, 0x8b, 0xb9, 0x70, 0xe1, 0x42, 0x2f, 0x48, 0x91, + 0x97, 0x02, 0xed, 0x43, 0xef, 0xb1, 0xcd, 0xcd, 0x4c, 0xa2, 0x6c, 0xd4, 0x59, 0x90, 0x72, 0x0e, + 0x87, 0x8b, 0x86, 0xcc, 0xad, 0x3a, 0x80, 0xf5, 0xd9, 0x2c, 0x0f, 0xbd, 0x62, 0x82, 0xdb, 0xe2, + 0xec, 0x6f, 0xa9, 0x52, 0x3f, 0x81, 0xa6, 0xcd, 0x2a, 0x90, 0x69, 0x9b, 0xcd, 0x64, 0x19, 0xcb, + 0xa6, 0x3e, 0xec, 0x7c, 0xfd, 0xcd, 0xab, 0x95, 0x7f, 0x7c, 0xf3, 0x6a, 0xe5, 0xdf, 0xdf, 0xbc, + 0x5a, 0x39, 0x69, 0xa8, 0xd1, 0xf7, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x44, 0x3b, 0xc9, 0x9d, + 0x3e, 0x1f, 0x00, 0x00, } diff --git a/protocols/grpc/agent.proto b/protocols/grpc/agent.proto index 6bb92964b8..adb540b075 100644 --- a/protocols/grpc/agent.proto +++ b/protocols/grpc/agent.proto @@ -56,6 +56,7 @@ service AgentService { rpc ReseedRandomDev(ReseedRandomDevRequest) returns (google.protobuf.Empty); rpc GetGuestDetails(GuestDetailsRequest) returns (GuestDetailsResponse); rpc SetGuestDateTime(SetGuestDateTimeRequest) returns (google.protobuf.Empty); + rpc CopyFile(CopyFileRequest) returns (google.protobuf.Empty); } message CreateContainerRequest { @@ -434,3 +435,25 @@ message StringUser { string gid = 2; repeated string additionalGids = 3; } + +message CopyFileRequest { + // Path is the destination file in the guest. It must be absolute, + // canonical and below /run. + string path = 1; + // FileSize is the expected file size, for security reasons write operations + // are made in a temporary file, once it has the expected size, it's moved + // to the destination path. + int64 file_size = 2; + // FileMode is the file mode. + uint32 file_mode = 3; + // DirMode is the mode for the parent directories of destination path. + uint32 dir_mode = 4; + // Uid is the numeric user id. + int32 uid = 5; + // Gid is the numeric group id. + int32 gid = 6; + // Offset for the next write operation. + int64 offset = 7; + // Data to write in the destination file. + bytes data = 8; +} diff --git a/protocols/mockserver/mockserver.go b/protocols/mockserver/mockserver.go index 73d1e3c788..7847c4641d 100644 --- a/protocols/mockserver/mockserver.go +++ b/protocols/mockserver/mockserver.go @@ -424,3 +424,9 @@ func (m *mockServer) GetGuestDetails(ctx context.Context, req *pb.GuestDetailsRe func (m *mockServer) SetGuestDateTime(ctx context.Context, req *pb.SetGuestDateTimeRequest) (*types.Empty, error) { return &types.Empty{}, nil } + +func (m *mockServer) CopyFile(ctx context.Context, req *pb.CopyFileRequest) (*types.Empty, error) { + mockLock.RLock() + defer mockLock.RUnlock() + return nil, m.podExist() +}