source: add local file source fundamentals

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
Tonis Tiigi
2017-07-11 10:12:12 -07:00
parent fed5c1d9ce
commit 5c2e675d18
21 changed files with 780 additions and 63 deletions

View File

@@ -19,6 +19,7 @@
Vertex
VertexStatus
VertexLog
BytesMessage
*/
package moby_buildkit_v1
@@ -121,6 +122,7 @@ type SolveRequest struct {
Definition [][]byte `protobuf:"bytes,2,rep,name=Definition" json:"Definition,omitempty"`
Exporter string `protobuf:"bytes,3,opt,name=Exporter,proto3" json:"Exporter,omitempty"`
ExporterAttrs map[string]string `protobuf:"bytes,4,rep,name=ExporterAttrs" json:"ExporterAttrs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Session string `protobuf:"bytes,5,opt,name=Session,proto3" json:"Session,omitempty"`
}
func (m *SolveRequest) Reset() { *m = SolveRequest{} }
@@ -156,6 +158,13 @@ func (m *SolveRequest) GetExporterAttrs() map[string]string {
return nil
}
func (m *SolveRequest) GetSession() string {
if m != nil {
return m.Session
}
return ""
}
type SolveResponse struct {
Vtx []*Vertex `protobuf:"bytes,1,rep,name=vtx" json:"vtx,omitempty"`
}
@@ -369,6 +378,22 @@ func (m *VertexLog) GetMsg() []byte {
return nil
}
type BytesMessage struct {
Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
}
func (m *BytesMessage) Reset() { *m = BytesMessage{} }
func (m *BytesMessage) String() string { return proto.CompactTextString(m) }
func (*BytesMessage) ProtoMessage() {}
func (*BytesMessage) Descriptor() ([]byte, []int) { return fileDescriptorControl, []int{10} }
func (m *BytesMessage) GetData() []byte {
if m != nil {
return m.Data
}
return nil
}
func init() {
proto.RegisterType((*DiskUsageRequest)(nil), "moby.buildkit.v1.DiskUsageRequest")
proto.RegisterType((*DiskUsageResponse)(nil), "moby.buildkit.v1.DiskUsageResponse")
@@ -380,6 +405,7 @@ func init() {
proto.RegisterType((*Vertex)(nil), "moby.buildkit.v1.Vertex")
proto.RegisterType((*VertexStatus)(nil), "moby.buildkit.v1.VertexStatus")
proto.RegisterType((*VertexLog)(nil), "moby.buildkit.v1.VertexLog")
proto.RegisterType((*BytesMessage)(nil), "moby.buildkit.v1.BytesMessage")
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -396,6 +422,7 @@ type ControlClient interface {
DiskUsage(ctx context.Context, in *DiskUsageRequest, opts ...grpc.CallOption) (*DiskUsageResponse, error)
Solve(ctx context.Context, in *SolveRequest, opts ...grpc.CallOption) (*SolveResponse, error)
Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (Control_StatusClient, error)
Session(ctx context.Context, opts ...grpc.CallOption) (Control_SessionClient, error)
}
type controlClient struct {
@@ -456,12 +483,44 @@ func (x *controlStatusClient) Recv() (*StatusResponse, error) {
return m, nil
}
func (c *controlClient) Session(ctx context.Context, opts ...grpc.CallOption) (Control_SessionClient, error) {
stream, err := grpc.NewClientStream(ctx, &_Control_serviceDesc.Streams[1], c.cc, "/moby.buildkit.v1.Control/Session", opts...)
if err != nil {
return nil, err
}
x := &controlSessionClient{stream}
return x, nil
}
type Control_SessionClient interface {
Send(*BytesMessage) error
Recv() (*BytesMessage, error)
grpc.ClientStream
}
type controlSessionClient struct {
grpc.ClientStream
}
func (x *controlSessionClient) Send(m *BytesMessage) error {
return x.ClientStream.SendMsg(m)
}
func (x *controlSessionClient) Recv() (*BytesMessage, error) {
m := new(BytesMessage)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// Server API for Control service
type ControlServer interface {
DiskUsage(context.Context, *DiskUsageRequest) (*DiskUsageResponse, error)
Solve(context.Context, *SolveRequest) (*SolveResponse, error)
Status(*StatusRequest, Control_StatusServer) error
Session(Control_SessionServer) error
}
func RegisterControlServer(s *grpc.Server, srv ControlServer) {
@@ -525,6 +584,32 @@ func (x *controlStatusServer) Send(m *StatusResponse) error {
return x.ServerStream.SendMsg(m)
}
func _Control_Session_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(ControlServer).Session(&controlSessionServer{stream})
}
type Control_SessionServer interface {
Send(*BytesMessage) error
Recv() (*BytesMessage, error)
grpc.ServerStream
}
type controlSessionServer struct {
grpc.ServerStream
}
func (x *controlSessionServer) Send(m *BytesMessage) error {
return x.ServerStream.SendMsg(m)
}
func (x *controlSessionServer) Recv() (*BytesMessage, error) {
m := new(BytesMessage)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
var _Control_serviceDesc = grpc.ServiceDesc{
ServiceName: "moby.buildkit.v1.Control",
HandlerType: (*ControlServer)(nil),
@@ -544,6 +629,12 @@ var _Control_serviceDesc = grpc.ServiceDesc{
Handler: _Control_Status_Handler,
ServerStreams: true,
},
{
StreamName: "Session",
Handler: _Control_Session_Handler,
ServerStreams: true,
ClientStreams: true,
},
},
Metadata: "control.proto",
}
@@ -697,6 +788,12 @@ func (m *SolveRequest) MarshalTo(dAtA []byte) (int, error) {
i += copy(dAtA[i:], v)
}
}
if len(m.Session) > 0 {
dAtA[i] = 0x2a
i++
i = encodeVarintControl(dAtA, i, uint64(len(m.Session)))
i += copy(dAtA[i:], m.Session)
}
return i, nil
}
@@ -1006,6 +1103,30 @@ func (m *VertexLog) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *BytesMessage) 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 *BytesMessage) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if len(m.Data) > 0 {
dAtA[i] = 0xa
i++
i = encodeVarintControl(dAtA, i, uint64(len(m.Data)))
i += copy(dAtA[i:], m.Data)
}
return i, nil
}
func encodeFixed64Control(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
@@ -1095,6 +1216,10 @@ func (m *SolveRequest) Size() (n int) {
n += mapEntrySize + 1 + sovControl(uint64(mapEntrySize))
}
}
l = len(m.Session)
if l > 0 {
n += 1 + l + sovControl(uint64(l))
}
return n
}
@@ -1232,6 +1357,16 @@ func (m *VertexLog) Size() (n int) {
return n
}
func (m *BytesMessage) Size() (n int) {
var l int
_ = l
l = len(m.Data)
if l > 0 {
n += 1 + l + sovControl(uint64(l))
}
return n
}
func sovControl(x uint64) (n int) {
for {
n++
@@ -1746,6 +1881,35 @@ func (m *SolveRequest) Unmarshal(dAtA []byte) error {
m.ExporterAttrs[mapkey] = mapvalue
}
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Session", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowControl
}
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 ErrInvalidLengthControl
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Session = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipControl(dAtA[iNdEx:])
@@ -2752,6 +2916,87 @@ func (m *VertexLog) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *BytesMessage) 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 ErrIntOverflowControl
}
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: BytesMessage: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: BytesMessage: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
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 ErrIntOverflowControl
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthControl
}
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 := skipControl(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthControl
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipControl(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
@@ -2860,55 +3105,57 @@ var (
func init() { proto.RegisterFile("control.proto", fileDescriptorControl) }
var fileDescriptorControl = []byte{
// 785 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x55, 0x4f, 0x6f, 0xe3, 0x44,
0x14, 0x67, 0xec, 0xd4, 0x49, 0x5e, 0x92, 0x55, 0x19, 0xa1, 0x95, 0x65, 0x44, 0x12, 0xcc, 0x25,
0x5a, 0x69, 0x1d, 0x36, 0x80, 0x84, 0x8a, 0x84, 0x20, 0x64, 0x25, 0x5a, 0xb1, 0x97, 0xe9, 0x16,
0xce, 0x4e, 0x32, 0x75, 0xad, 0xd8, 0x9e, 0x30, 0x33, 0x8e, 0x1a, 0x3e, 0x05, 0xdf, 0x85, 0xcf,
0x80, 0xd4, 0x23, 0x67, 0x0e, 0x05, 0xf5, 0x03, 0x70, 0x85, 0x23, 0xf2, 0xcc, 0x38, 0x75, 0x9b,
0xa6, 0x94, 0xf6, 0x94, 0x79, 0x93, 0xdf, 0xfb, 0xbd, 0x37, 0xbf, 0xf7, 0xc7, 0xd0, 0x99, 0xb1,
0x4c, 0x72, 0x96, 0x04, 0x4b, 0xce, 0x24, 0xc3, 0xfb, 0x29, 0x9b, 0xae, 0x83, 0x69, 0x1e, 0x27,
0xf3, 0x45, 0x2c, 0x83, 0xd5, 0x2b, 0xef, 0x65, 0x14, 0xcb, 0xb3, 0x7c, 0x1a, 0xcc, 0x58, 0x3a,
0x8c, 0x58, 0xc4, 0x86, 0x0a, 0x38, 0xcd, 0x4f, 0x95, 0xa5, 0x0c, 0x75, 0xd2, 0x04, 0x5e, 0x2f,
0x62, 0x2c, 0x4a, 0xe8, 0x35, 0x4a, 0xc6, 0x29, 0x15, 0x32, 0x4c, 0x97, 0x1a, 0xe0, 0x63, 0xd8,
0x9f, 0xc4, 0x62, 0x71, 0x22, 0xc2, 0x88, 0x12, 0xfa, 0x63, 0x4e, 0x85, 0xf4, 0x8f, 0xe0, 0xdd,
0xca, 0x9d, 0x58, 0xb2, 0x4c, 0x50, 0xfc, 0x19, 0x38, 0x9c, 0xce, 0x18, 0x9f, 0xbb, 0xa8, 0x6f,
0x0f, 0x5a, 0xa3, 0x0f, 0x82, 0xdb, 0xb9, 0x05, 0xc6, 0xa1, 0x00, 0x11, 0x03, 0xf6, 0x43, 0x68,
0x55, 0xae, 0xf1, 0x33, 0xb0, 0x0e, 0x27, 0x2e, 0xea, 0xa3, 0x41, 0x93, 0x58, 0x87, 0x13, 0xec,
0x42, 0xfd, 0x4d, 0x2e, 0xc3, 0x69, 0x42, 0x5d, 0xab, 0x8f, 0x06, 0x0d, 0x52, 0x9a, 0xf8, 0x3d,
0xd8, 0x3b, 0xcc, 0x4e, 0x04, 0x75, 0x6d, 0x75, 0xaf, 0x0d, 0x8c, 0xa1, 0x76, 0x1c, 0xff, 0x44,
0xdd, 0x5a, 0x1f, 0x0d, 0x6c, 0xa2, 0xce, 0xfe, 0xdf, 0x08, 0xda, 0xc7, 0x2c, 0x59, 0x95, 0xf9,
0xe3, 0x7d, 0xb0, 0x09, 0x3d, 0x35, 0x51, 0x8a, 0x23, 0xee, 0x02, 0x4c, 0xe8, 0x69, 0x9c, 0xc5,
0x32, 0x66, 0x99, 0x6b, 0xf5, 0xed, 0x41, 0x9b, 0x54, 0x6e, 0xb0, 0x07, 0x8d, 0xd7, 0xe7, 0x4b,
0xc6, 0x25, 0xe5, 0x2a, 0x5e, 0x93, 0x6c, 0x6c, 0xfc, 0x03, 0x74, 0xca, 0xf3, 0xd7, 0x52, 0x72,
0xe1, 0xd6, 0xd4, 0xfb, 0x5f, 0x6d, 0xbf, 0xbf, 0x9a, 0x44, 0x70, 0xc3, 0xe7, 0x75, 0x26, 0xf9,
0x9a, 0xdc, 0xe4, 0xf1, 0xbe, 0x02, 0xbc, 0x0d, 0x2a, 0x92, 0x5f, 0xd0, 0x75, 0x99, 0xfc, 0x82,
0xae, 0x0b, 0x25, 0x56, 0x61, 0x92, 0x6b, 0x85, 0x9a, 0x44, 0x1b, 0x07, 0xd6, 0xe7, 0xc8, 0xff,
0x02, 0x3a, 0x26, 0xa6, 0x29, 0xd2, 0x0b, 0xb0, 0x57, 0xf2, 0xdc, 0x54, 0xc8, 0xdd, 0xce, 0xf0,
0x7b, 0xca, 0x25, 0x3d, 0x27, 0x05, 0xc8, 0xff, 0x10, 0x3a, 0xc7, 0x32, 0x94, 0xb9, 0xd8, 0x29,
0x9b, 0xff, 0x0b, 0x82, 0x67, 0x25, 0xc6, 0x44, 0xf8, 0x14, 0x1a, 0x2b, 0x45, 0x42, 0xc5, 0x7f,
0x86, 0xd9, 0x20, 0xf1, 0x01, 0x34, 0x84, 0xe2, 0xa1, 0x42, 0xa9, 0xdf, 0x1a, 0x75, 0x77, 0x79,
0x99, 0x78, 0x1b, 0x3c, 0x1e, 0x42, 0x2d, 0x61, 0x91, 0x70, 0x6d, 0xe5, 0xf7, 0xfe, 0x2e, 0xbf,
0xef, 0x58, 0x44, 0x14, 0xd0, 0xbf, 0xb4, 0xc0, 0xd1, 0x77, 0xf8, 0x08, 0x9c, 0x79, 0x1c, 0x51,
0x21, 0xf5, 0xab, 0xc6, 0xa3, 0x8b, 0xcb, 0xde, 0x3b, 0xbf, 0x5f, 0xf6, 0x5e, 0x54, 0xa6, 0x88,
0x2d, 0x69, 0x56, 0x4c, 0x5d, 0x18, 0x67, 0x94, 0x8b, 0x61, 0xc4, 0x5e, 0x6a, 0x97, 0x60, 0xa2,
0x7e, 0x88, 0x61, 0x28, 0xb8, 0xe2, 0x6c, 0x99, 0x4b, 0xfd, 0x82, 0x47, 0x72, 0x69, 0x86, 0xa2,
0x8d, 0xb3, 0x30, 0xa5, 0xa6, 0xd7, 0xd4, 0x19, 0x3f, 0x07, 0x67, 0x16, 0xce, 0xce, 0xe8, 0x5c,
0x35, 0x77, 0x83, 0x18, 0x0b, 0x1f, 0x40, 0x5d, 0xc8, 0x90, 0x4b, 0x3a, 0x77, 0xf7, 0xfa, 0x68,
0xd0, 0x1a, 0x79, 0x81, 0x1e, 0xea, 0xa0, 0x1c, 0xea, 0xe0, 0x6d, 0x39, 0xd4, 0xe3, 0xda, 0xcf,
0x7f, 0xf4, 0x10, 0x29, 0x1d, 0xf0, 0x97, 0xd0, 0x9c, 0xb1, 0x74, 0x99, 0xd0, 0xc2, 0xdb, 0x79,
0xa0, 0xf7, 0xb5, 0x4b, 0xd1, 0x7a, 0x94, 0x73, 0xc6, 0xdd, 0xba, 0x6e, 0x3d, 0x65, 0xf8, 0x7f,
0x59, 0xd0, 0xae, 0x16, 0x6b, 0x6b, 0xaa, 0x8f, 0xc0, 0xd1, 0xa5, 0xd7, 0x2d, 0xfb, 0x38, 0xa9,
0x34, 0xc3, 0x9d, 0x52, 0xb9, 0x50, 0x9f, 0xe5, 0x9c, 0xd3, 0x4c, 0x9a, 0x45, 0x50, 0x9a, 0x45,
0xc2, 0x92, 0xc9, 0x30, 0x51, 0x52, 0xd9, 0x44, 0x1b, 0x78, 0x0c, 0xcd, 0xcd, 0xde, 0x7b, 0x80,
0x0c, 0x8d, 0x22, 0x5d, 0x2d, 0xc5, 0xc6, 0xad, 0x5a, 0x86, 0xfa, 0x93, 0xca, 0xd0, 0xf8, 0xdf,
0x65, 0xf0, 0x7f, 0x45, 0xd0, 0xdc, 0x74, 0x79, 0x45, 0x5d, 0xf4, 0x64, 0x75, 0x6f, 0x28, 0x63,
0x3d, 0x4e, 0x99, 0xe7, 0xe0, 0x08, 0xc9, 0x69, 0x98, 0xaa, 0x1a, 0xd9, 0xc4, 0x58, 0xc5, 0x3e,
0x49, 0x45, 0xa4, 0x2a, 0xd4, 0x26, 0xc5, 0x71, 0xf4, 0x0f, 0x82, 0xfa, 0x37, 0xfa, 0x03, 0x87,
0xdf, 0x42, 0x73, 0xf3, 0x91, 0xc1, 0xfe, 0xf6, 0x54, 0xdf, 0xfe, 0x2a, 0x79, 0x1f, 0xdd, 0x8b,
0x31, 0xeb, 0xe9, 0x5b, 0xd8, 0x53, 0x1b, 0x11, 0x77, 0xef, 0x5f, 0xcf, 0x5e, 0x6f, 0xe7, 0xff,
0x86, 0xe9, 0x0d, 0x38, 0xa6, 0xbb, 0xef, 0x82, 0x56, 0x17, 0xa7, 0xd7, 0xdf, 0x0d, 0xd0, 0x64,
0x1f, 0xa3, 0x71, 0xfb, 0xe2, 0xaa, 0x8b, 0x7e, 0xbb, 0xea, 0xa2, 0x3f, 0xaf, 0xba, 0x68, 0xea,
0x28, 0x6d, 0x3f, 0xf9, 0x37, 0x00, 0x00, 0xff, 0xff, 0x97, 0xc3, 0x70, 0xc2, 0xef, 0x07, 0x00,
0x00,
// 832 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x55, 0x5f, 0x8f, 0xdb, 0x44,
0x10, 0xc7, 0x76, 0xce, 0x49, 0xe6, 0x72, 0xd5, 0xb1, 0x42, 0x95, 0x65, 0x44, 0x12, 0xcc, 0x4b,
0x54, 0xa9, 0xbe, 0x36, 0x80, 0x84, 0x0e, 0x09, 0x41, 0x48, 0x25, 0xee, 0xc4, 0xbd, 0xec, 0xb5,
0xf0, 0xec, 0x24, 0x73, 0xae, 0x15, 0xc7, 0x1b, 0x76, 0xd7, 0xd1, 0x85, 0x4f, 0x01, 0x9f, 0x85,
0xcf, 0x80, 0xe8, 0x23, 0xcf, 0x3c, 0x1c, 0xe8, 0x3e, 0x00, 0x9f, 0x01, 0xed, 0x1f, 0xa7, 0xbe,
0xe6, 0xd2, 0x96, 0xeb, 0x93, 0x67, 0xd6, 0xbf, 0x99, 0x9d, 0xf9, 0xcd, 0x9f, 0x85, 0x83, 0x29,
0x2b, 0x24, 0x67, 0x79, 0xbc, 0xe4, 0x4c, 0x32, 0x72, 0xb8, 0x60, 0x93, 0x75, 0x3c, 0x29, 0xb3,
0x7c, 0x36, 0xcf, 0x64, 0xbc, 0x7a, 0x1c, 0x3e, 0x4c, 0x33, 0xf9, 0xbc, 0x9c, 0xc4, 0x53, 0xb6,
0x38, 0x4a, 0x59, 0xca, 0x8e, 0x34, 0x70, 0x52, 0x5e, 0x68, 0x4d, 0x2b, 0x5a, 0x32, 0x0e, 0xc2,
0x5e, 0xca, 0x58, 0x9a, 0xe3, 0x4b, 0x94, 0xcc, 0x16, 0x28, 0x64, 0xb2, 0x58, 0x1a, 0x40, 0x44,
0xe0, 0x70, 0x9c, 0x89, 0xf9, 0x33, 0x91, 0xa4, 0x48, 0xf1, 0xa7, 0x12, 0x85, 0x8c, 0x4e, 0xe1,
0xfd, 0xda, 0x99, 0x58, 0xb2, 0x42, 0x20, 0xf9, 0x1c, 0x7c, 0x8e, 0x53, 0xc6, 0x67, 0x81, 0xd3,
0xf7, 0x06, 0xfb, 0xc3, 0x8f, 0xe2, 0x57, 0x63, 0x8b, 0xad, 0x81, 0x02, 0x51, 0x0b, 0x8e, 0x12,
0xd8, 0xaf, 0x1d, 0x93, 0x7b, 0xe0, 0x9e, 0x8c, 0x03, 0xa7, 0xef, 0x0c, 0xda, 0xd4, 0x3d, 0x19,
0x93, 0x00, 0x9a, 0x67, 0xa5, 0x4c, 0x26, 0x39, 0x06, 0x6e, 0xdf, 0x19, 0xb4, 0x68, 0xa5, 0x92,
0x0f, 0x60, 0xef, 0xa4, 0x78, 0x26, 0x30, 0xf0, 0xf4, 0xb9, 0x51, 0x08, 0x81, 0xc6, 0x79, 0xf6,
0x33, 0x06, 0x8d, 0xbe, 0x33, 0xf0, 0xa8, 0x96, 0xa3, 0x5f, 0x5d, 0xe8, 0x9c, 0xb3, 0x7c, 0x55,
0xc5, 0x4f, 0x0e, 0xc1, 0xa3, 0x78, 0x61, 0x6f, 0x51, 0x22, 0xe9, 0x02, 0x8c, 0xf1, 0x22, 0x2b,
0x32, 0x99, 0xb1, 0x22, 0x70, 0xfb, 0xde, 0xa0, 0x43, 0x6b, 0x27, 0x24, 0x84, 0xd6, 0x93, 0xcb,
0x25, 0xe3, 0x12, 0xb9, 0xbe, 0xaf, 0x4d, 0x37, 0x3a, 0xf9, 0x11, 0x0e, 0x2a, 0xf9, 0x1b, 0x29,
0xb9, 0x08, 0x1a, 0x3a, 0xff, 0xc7, 0xdb, 0xf9, 0xd7, 0x83, 0x88, 0x6f, 0xd8, 0x3c, 0x29, 0x24,
0x5f, 0xd3, 0x9b, 0x7e, 0x54, 0xee, 0xe7, 0x28, 0x84, 0x8a, 0x68, 0x4f, 0xdf, 0x59, 0xa9, 0xe1,
0xd7, 0x40, 0xb6, 0xcd, 0x55, 0x5a, 0x73, 0x5c, 0x57, 0x69, 0xcd, 0x71, 0xad, 0x38, 0x5a, 0x25,
0x79, 0x69, 0xb8, 0x6b, 0x53, 0xa3, 0x1c, 0xbb, 0x5f, 0x38, 0xd1, 0x97, 0x70, 0x60, 0xa3, 0xb1,
0xe5, 0x7b, 0x00, 0xde, 0x4a, 0x5e, 0xda, 0xda, 0x05, 0xdb, 0xb1, 0xff, 0x80, 0x5c, 0xe2, 0x25,
0x55, 0xa0, 0xe8, 0x63, 0x38, 0x38, 0x97, 0x89, 0x2c, 0xc5, 0x4e, 0x42, 0xa3, 0xdf, 0x1c, 0xb8,
0x57, 0x61, 0xec, 0x0d, 0x9f, 0x41, 0x6b, 0xa5, 0x9d, 0xa0, 0x78, 0xe3, 0x35, 0x1b, 0x24, 0x39,
0x86, 0x96, 0xd0, 0x7e, 0x50, 0xe8, 0xba, 0xec, 0x0f, 0xbb, 0xbb, 0xac, 0xec, 0x7d, 0x1b, 0x3c,
0x39, 0x82, 0x46, 0xce, 0x52, 0x11, 0x78, 0xda, 0xee, 0xc3, 0x5d, 0x76, 0xdf, 0xb3, 0x94, 0x6a,
0x60, 0x74, 0xe5, 0x82, 0x6f, 0xce, 0xc8, 0x29, 0xf8, 0xb3, 0x2c, 0x45, 0x21, 0x4d, 0x56, 0xa3,
0xe1, 0x8b, 0xab, 0xde, 0x7b, 0x7f, 0x5d, 0xf5, 0x1e, 0xd4, 0xe6, 0x8b, 0x2d, 0xb1, 0x50, 0xf3,
0x98, 0x64, 0x05, 0x72, 0x71, 0x94, 0xb2, 0x87, 0xc6, 0x24, 0x1e, 0xeb, 0x0f, 0xb5, 0x1e, 0x94,
0xaf, 0xac, 0x58, 0x96, 0xd2, 0x64, 0x70, 0x47, 0x5f, 0xc6, 0x83, 0x6a, 0xf0, 0x22, 0x59, 0xa0,
0xed, 0x42, 0x2d, 0x93, 0xfb, 0xe0, 0x4f, 0x93, 0xe9, 0x73, 0x9c, 0xe9, 0xb6, 0x6f, 0x51, 0xab,
0x91, 0x63, 0x68, 0x0a, 0x99, 0x70, 0x89, 0x33, 0xdd, 0x40, 0xfb, 0xc3, 0x30, 0x36, 0xe3, 0x1e,
0x57, 0xe3, 0x1e, 0x3f, 0xad, 0xc6, 0x7d, 0xd4, 0xf8, 0xe5, 0xef, 0x9e, 0x43, 0x2b, 0x03, 0xf2,
0x15, 0xb4, 0xa7, 0x6c, 0xb1, 0xcc, 0x51, 0x59, 0xfb, 0x6f, 0x69, 0xfd, 0xd2, 0x44, 0xb5, 0x1e,
0x72, 0xce, 0x78, 0xd0, 0x34, 0xad, 0xa7, 0x95, 0xe8, 0x5f, 0x17, 0x3a, 0xf5, 0x62, 0x6d, 0xcd,
0xfb, 0x29, 0xf8, 0xa6, 0xf4, 0xa6, 0x65, 0xef, 0x46, 0x95, 0xf1, 0x70, 0x2b, 0x55, 0x01, 0x34,
0xa7, 0x25, 0xe7, 0x58, 0x48, 0xbb, 0x22, 0x2a, 0x55, 0x05, 0x2c, 0x99, 0x4c, 0x72, 0x4d, 0x95,
0x47, 0x8d, 0x42, 0x46, 0xd0, 0xde, 0x6c, 0xc4, 0xb7, 0xa0, 0xa1, 0xa5, 0xc2, 0x35, 0x54, 0x6c,
0xcc, 0xea, 0x65, 0x68, 0xbe, 0x53, 0x19, 0x5a, 0xff, 0xbb, 0x0c, 0xd1, 0xef, 0x0e, 0xb4, 0x37,
0x5d, 0x5e, 0x63, 0xd7, 0x79, 0x67, 0x76, 0x6f, 0x30, 0xe3, 0xde, 0x8d, 0x99, 0xfb, 0xe0, 0x0b,
0xc9, 0x31, 0x59, 0xe8, 0x1a, 0x79, 0xd4, 0x6a, 0x6a, 0x9f, 0x2c, 0x44, 0xaa, 0x2b, 0xd4, 0xa1,
0x4a, 0x8c, 0x22, 0xe8, 0x8c, 0xd6, 0x12, 0xc5, 0x19, 0x0a, 0xf5, 0x5a, 0xa8, 0xda, 0xce, 0x12,
0x99, 0xe8, 0x3c, 0x3a, 0x54, 0xcb, 0xc3, 0x3f, 0x5c, 0x68, 0x7e, 0x6b, 0x9e, 0x47, 0xf2, 0x14,
0xda, 0x9b, 0x27, 0x8a, 0x44, 0xdb, 0x93, 0xff, 0xea, 0x9b, 0x16, 0x7e, 0xf2, 0x5a, 0x8c, 0x5d,
0x61, 0xdf, 0xc1, 0x9e, 0xde, 0x9a, 0xa4, 0xfb, 0xfa, 0xe5, 0x1e, 0xf6, 0x76, 0xfe, 0xb7, 0x9e,
0xce, 0xc0, 0xb7, 0x13, 0x70, 0x1b, 0xb4, 0xbe, 0x5c, 0xc3, 0xfe, 0x6e, 0x80, 0x71, 0xf6, 0xc8,
0x21, 0x67, 0x9b, 0xa7, 0xe2, 0xb6, 0xd0, 0xea, 0xcc, 0x85, 0x6f, 0xf8, 0x3f, 0x70, 0x1e, 0x39,
0xa3, 0xce, 0x8b, 0xeb, 0xae, 0xf3, 0xe7, 0x75, 0xd7, 0xf9, 0xe7, 0xba, 0xeb, 0x4c, 0x7c, 0x5d,
0xce, 0x4f, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xc9, 0xc1, 0x1a, 0x81, 0x7c, 0x08, 0x00, 0x00,
}

View File

@@ -13,6 +13,7 @@ service Control {
rpc DiskUsage(DiskUsageRequest) returns (DiskUsageResponse);
rpc Solve(SolveRequest) returns (SolveResponse);
rpc Status(StatusRequest) returns (stream StatusResponse);
rpc Session(stream BytesMessage) returns (stream BytesMessage);
}
message DiskUsageRequest {
@@ -34,6 +35,7 @@ message SolveRequest {
repeated bytes Definition = 2; // TODO: remove repeated
string Exporter = 3;
map<string, string> ExporterAttrs = 4;
string Session = 5;
}
message SolveResponse {
@@ -78,3 +80,7 @@ message VertexLog {
int64 stream = 3;
bytes msg = 4;
}
message BytesMessage {
bytes data = 1;
}

View File

@@ -106,6 +106,6 @@ func testBuildMultiMount(t *testing.T, address string) {
err = llb.WriteTo(dt, buf)
assert.Nil(t, err)
err = c.Solve(context.TODO(), buf, nil, "", nil)
err = c.Solve(context.TODO(), buf, nil, "", nil, "")
assert.Nil(t, err)
}

View File

@@ -78,6 +78,18 @@ func Scratch() *State {
return s
}
func Local(name string) *State {
return Source("local://" + name)
}
type LocalOption func(*source)
func SessionID(id string) LocalOption {
return func(s *source) {
s.attrs[pb.AttrLocalSessionID] = id
}
}
type exec struct {
meta Meta
mounts []*mount

5
client/local.go Normal file
View File

@@ -0,0 +1,5 @@
package client
func getSharedKey(dir string) (string, error) {
return dir, nil // not implemented
}

View File

@@ -5,15 +5,29 @@ import (
"crypto/rand"
"encoding/hex"
"io"
"os"
"path/filepath"
"strings"
"time"
"github.com/Sirupsen/logrus"
controlapi "github.com/moby/buildkit/api/services/control"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/filesync"
"github.com/moby/buildkit/session/grpchijack"
"github.com/moby/buildkit/solver/pb"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
)
func (c *Client) Solve(ctx context.Context, r io.Reader, statusChan chan *SolveStatus, exporter string, exporterAttrs map[string]string) error {
func (c *Client) Solve(ctx context.Context, r io.Reader, statusChan chan *SolveStatus, exporter string, exporterAttrs map[string]string, localDir string) error {
defer func() {
if statusChan != nil {
close(statusChan)
}
}()
def, err := llb.ReadFrom(r)
if err != nil {
return errors.Wrap(err, "failed to parse input")
@@ -23,10 +37,34 @@ func (c *Client) Solve(ctx context.Context, r io.Reader, statusChan chan *SolveS
return errors.New("invalid empty definition")
}
if err := validateLocals(def, localDir); err != nil {
return err
}
ref := generateID()
eg, ctx := errgroup.WithContext(ctx)
statusContext, cancelStatus := context.WithCancel(context.Background())
defer cancelStatus()
sharedKey, err := getSharedKey(localDir)
if err != nil {
return errors.Wrap(err, "failed to get build shared key")
}
s, err := session.NewSession(filepath.Base(localDir), sharedKey)
if err != nil {
return errors.Wrap(err, "failed to create session")
}
if localDir != "" {
_, dir, _ := parseLocalDir(localDir)
workdirProvider := filesync.NewFSSyncProvider(dir, nil)
s.Allow(workdirProvider)
}
eg.Go(func() error {
return s.Run(ctx, grpchijack.Dialer(c.controlClient()))
})
eg.Go(func() error {
defer func() { // make sure the Status ends cleanly on build errors
@@ -34,12 +72,15 @@ func (c *Client) Solve(ctx context.Context, r io.Reader, statusChan chan *SolveS
<-time.After(3 * time.Second)
cancelStatus()
}()
logrus.Debugf("stopping session")
s.Close()
}()
_, err = c.controlClient().Solve(ctx, &controlapi.SolveRequest{
Ref: ref,
Definition: def,
Exporter: exporter,
ExporterAttrs: exporterAttrs,
Session: s.UUID(),
})
if err != nil {
return errors.Wrap(err, "failed to solve")
@@ -100,12 +141,6 @@ func (c *Client) Solve(ctx context.Context, r io.Reader, statusChan chan *SolveS
}
})
defer func() {
if statusChan != nil {
close(statusChan)
}
}()
return eg.Wait()
}
@@ -116,3 +151,44 @@ func generateID() string {
}
return hex.EncodeToString(b)
}
func validateLocals(defs [][]byte, localDir string) error {
k, _, err := parseLocalDir(localDir)
if err != nil {
return err
}
for _, dt := range defs {
var op pb.Op
if err := (&op).Unmarshal(dt); err != nil {
return errors.Wrap(err, "failed to parse llb proto op")
}
if src := op.GetSource(); src != nil {
if strings.HasPrefix(src.Identifier, "local://") { // TODO: just make a type property
name := strings.TrimPrefix(src.Identifier, "local://")
if name != k {
return errors.Errorf("local directory %s not enabled", name)
}
}
}
}
return nil
}
func parseLocalDir(str string) (string, string, error) {
if str == "" {
return "", "", nil
}
parts := strings.SplitN(str, "=", 2)
if len(parts) != 2 {
return "", "", errors.Errorf("invalid local indentifier %q, need name=dir", str)
}
fi, err := os.Stat(parts[1])
if err != nil {
return "", "", errors.Wrapf(err, "could not find %s", parts[1])
}
if !fi.IsDir() {
return "", "", errors.Errorf("%s not a directory", parts[1])
}
return parts[0], parts[1], nil
}

View File

@@ -33,6 +33,10 @@ var buildCommand = cli.Command{
Name: "no-progress",
Usage: "Don't show interactive progress",
},
cli.StringFlag{
Name: "local",
Usage: "Allow build access to the local directory",
},
},
}
@@ -61,7 +65,7 @@ func build(clicontext *cli.Context) error {
}
eg.Go(func() error {
return c.Solve(ctx, os.Stdin, ch, clicontext.String("exporter"), exporterAttrs)
return c.Solve(ctx, os.Stdin, ch, clicontext.String("exporter"), exporterAttrs, clicontext.String("local"))
})
eg.Go(func() error {

View File

@@ -1,11 +1,14 @@
package control
import (
"github.com/Sirupsen/logrus"
"github.com/containerd/containerd/snapshot"
controlapi "github.com/moby/buildkit/api/services/control"
"github.com/moby/buildkit/cache"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/exporter"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/grpchijack"
"github.com/moby/buildkit/solver"
"github.com/moby/buildkit/source"
"github.com/moby/buildkit/worker"
@@ -22,6 +25,7 @@ type Opt struct {
SourceManager *source.Manager
InstructionCache solver.InstructionCache
Exporters map[string]exporter.Exporter
SessionManager *session.Manager
}
type Controller struct { // TODO: ControlService
@@ -83,6 +87,8 @@ func (c *Controller) Solve(ctx context.Context, req *controlapi.SolveRequest) (*
}
}
ctx = session.NewContext(ctx, req.Session)
if err := c.solver.Solve(ctx, req.Ref, v, expi); err != nil {
return nil, err
}
@@ -147,3 +153,12 @@ func (c *Controller) Status(req *controlapi.StatusRequest, stream controlapi.Con
return eg.Wait()
}
func (c *Controller) Session(stream controlapi.Control_SessionServer) error {
logrus.Debugf("session started")
conn, opts := grpchijack.Hijack(stream)
defer conn.Close()
err := c.opt.SessionManager.HandleConn(stream.Context(), conn, opts)
logrus.Debugf("session finished: %v", err)
return err
}

View File

@@ -14,10 +14,12 @@ import (
"github.com/moby/buildkit/cache/metadata"
"github.com/moby/buildkit/exporter"
imageexporter "github.com/moby/buildkit/exporter/containerimage"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/snapshot/blobmapping"
"github.com/moby/buildkit/source"
"github.com/moby/buildkit/source/containerimage"
"github.com/moby/buildkit/source/git"
"github.com/moby/buildkit/source/local"
)
const keyImageExporter = "image"
@@ -85,6 +87,20 @@ func defaultControllerOpts(root string, pd pullDeps) (*Opt, error) {
sm.Register(gs)
sessm, err := session.NewManager()
if err != nil {
return nil, err
}
ss, err := local.NewSource(local.Opt{
SessionManager: sessm,
CacheAccessor: cm,
})
if err != nil {
return nil, err
}
sm.Register(ss)
exporters := map[string]exporter.Exporter{}
imageExporter, err := imageexporter.New(imageexporter.Opt{
@@ -105,5 +121,6 @@ func defaultControllerOpts(root string, pd pullDeps) (*Opt, error) {
SourceManager: sm,
InstructionCache: ic,
Exporters: exporters,
SessionManager: sessm,
}, nil
}

22
session/context.go Normal file
View File

@@ -0,0 +1,22 @@
package session
import "context"
type contextKeyT string
var contextKey = contextKeyT("buildkit/session-uuid")
func NewContext(ctx context.Context, uuid string) context.Context {
if uuid != "" {
return context.WithValue(ctx, contextKey, uuid)
}
return ctx
}
func FromContext(ctx context.Context) string {
v := ctx.Value(contextKey)
if v == nil {
return ""
}
return v.(string)
}

View File

@@ -3,10 +3,9 @@ package filesync
import (
"time"
"google.golang.org/grpc"
"github.com/Sirupsen/logrus"
"github.com/tonistiigi/fsutil"
"google.golang.org/grpc"
)
func sendDiffCopy(stream grpc.Stream, dir string, includes, excludes []string, progress progressCb) error {

View File

@@ -1,6 +1,7 @@
package filesync
import (
"fmt"
"os"
"strings"
@@ -177,6 +178,8 @@ func FSSync(ctx context.Context, c session.Caller, opt FSSendRequestOpt) error {
return err
}
stream = cc
default:
panic(fmt.Sprintf("invalid protocol: %q", pr.name))
}
return pr.recvFn(stream, opt.DestDir, opt.CacheUpdater)

123
session/grpchijack/dial.go Normal file
View File

@@ -0,0 +1,123 @@
package grpchijack
import (
"net"
"strings"
"sync"
"time"
controlapi "github.com/moby/buildkit/api/services/control"
"github.com/moby/buildkit/session"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
)
var bufPool = sync.Pool{
New: func() interface{} {
return make([]byte, 32*1<<10)
},
}
func Dialer(api controlapi.ControlClient) session.Dialer {
return func(ctx context.Context, proto string, meta map[string][]string) (net.Conn, error) {
meta = lowerHeaders(meta)
md := metadata.MD(meta)
ctx = metadata.NewContext(context.Background(), md)
stream, err := api.Session(ctx)
if err != nil {
return nil, err
}
return streamToConn(stream), nil
}
}
func streamToConn(stream grpc.Stream) net.Conn {
return &conn{stream: stream, buf: make([]byte, 32*1<<10)}
}
type conn struct {
stream grpc.Stream
buf []byte
lastBuf []byte
}
func (c *conn) Read(b []byte) (int, error) {
if c.lastBuf != nil {
n := copy(b, c.lastBuf)
c.lastBuf = c.lastBuf[n:]
if len(c.lastBuf) == 0 {
c.lastBuf = nil
}
return n, nil
}
m := new(controlapi.BytesMessage)
m.Data = c.buf
if err := c.stream.RecvMsg(m); err != nil {
return 0, err
}
c.buf = m.Data[:cap(m.Data)]
n := copy(b, m.Data)
if n < len(m.Data) {
c.lastBuf = m.Data[n:]
}
return n, nil
}
func (c *conn) Write(b []byte) (int, error) {
m := &controlapi.BytesMessage{Data: b}
if err := c.stream.SendMsg(m); err != nil {
return 0, err
}
return len(b), nil
}
func (s *conn) Close() error {
if cs, ok := s.stream.(grpc.ClientStream); ok {
return cs.CloseSend()
}
return nil
}
func (s *conn) LocalAddr() net.Addr {
return dummyAddr{}
}
func (s *conn) RemoteAddr() net.Addr {
return dummyAddr{}
}
func (s *conn) SetDeadline(t time.Time) error {
return nil
}
func (s *conn) SetReadDeadline(t time.Time) error {
return nil
}
func (s *conn) SetWriteDeadline(t time.Time) error {
return nil
}
type dummyAddr struct {
}
func (d dummyAddr) Network() string {
return "tcp"
}
func (d dummyAddr) String() string {
return "localhost"
}
func lowerHeaders(in map[string][]string) map[string][]string {
out := map[string][]string{}
for k := range in {
out[strings.ToLower(k)] = in[k]
}
return out
}

View File

@@ -0,0 +1,13 @@
package grpchijack
import (
"net"
controlapi "github.com/moby/buildkit/api/services/control"
"google.golang.org/grpc/metadata"
)
func Hijack(stream controlapi.Control_SessionServer) (net.Conn, map[string][]string) {
md, _ := metadata.FromContext(stream.Context())
return streamToConn(stream), md
}

View File

@@ -102,6 +102,8 @@ func (sm *Manager) handleConn(ctx context.Context, conn net.Conn, opts map[strin
ctx, cancel := context.WithCancel(ctx)
defer cancel()
opts = canonicalHeaders(opts)
h := http.Header(opts)
uuid := h.Get(headerSessionUUID)
name := h.Get(headerSessionName)
@@ -200,3 +202,11 @@ func (c *client) Supports(url string) bool {
func (c *client) Conn() *grpc.ClientConn {
return c.cc
}
func canonicalHeaders(in map[string][]string) map[string][]string {
out := map[string][]string{}
for k := range in {
out[http.CanonicalHeaderKey(k)] = in[k]
}
return out
}

View File

@@ -92,6 +92,7 @@ func (s *Session) Run(ctx context.Context, dialer Dialer) error {
// Close closes the session
func (s *Session) Close() error {
if s.cancelCtx != nil && s.done != nil {
s.grpcServer.Stop()
s.cancelCtx()
<-s.done
}

View File

@@ -1,3 +1,4 @@
package pb
const AttrKeepGitDir = "git.keepgitdir"
const AttrLocalSessionID = "local.session"

View File

@@ -42,6 +42,14 @@ func (s *sourceOp) instance(ctx context.Context) (source.SourceInstance, error)
}
}
}
if id, ok := id.(*source.LocalIdentifier); ok {
for k, v := range s.op.Source.Attrs {
switch k {
case pb.AttrLocalSessionID:
id.SessionID = v
}
}
}
src, err := s.sm.Resolve(ctx, id)
if err != nil {
return nil, err

View File

@@ -83,6 +83,7 @@ func (v *vertex) notifyStarted(ctx context.Context) {
defer pw.Close()
now := time.Now()
v.clientVertex.Started = &now
v.clientVertex.Completed = nil
pw.Write(v.Digest().String(), v.clientVertex)
}

View File

@@ -15,6 +15,7 @@ var (
const (
DockerImageScheme = "docker-image"
GitScheme = "git"
LocalScheme = "local"
)
type Identifier interface {
@@ -33,6 +34,8 @@ func FromString(s string) (Identifier, error) {
return NewImageIdentifier(parts[1])
case GitScheme:
return NewGitIdentifier(parts[1])
case LocalScheme:
return NewLocalIdentifier(parts[1])
default:
return nil, errors.Wrapf(errNotFound, "unknown schema %s", parts[0])
}
@@ -54,6 +57,19 @@ func NewImageIdentifier(str string) (*ImageIdentifier, error) {
return &ImageIdentifier{Reference: ref}, nil
}
func (i *ImageIdentifier) ID() string {
func (_ *ImageIdentifier) ID() string {
return DockerImageScheme
}
type LocalIdentifier struct {
Name string
SessionID string
}
func NewLocalIdentifier(str string) (*LocalIdentifier, error) {
return &LocalIdentifier{Name: str}, nil
}
func (_ *LocalIdentifier) ID() string {
return LocalScheme
}

138
source/local/local.go Normal file
View File

@@ -0,0 +1,138 @@
package local
import (
"time"
"github.com/moby/buildkit/cache"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/filesync"
"github.com/moby/buildkit/snapshot"
"github.com/moby/buildkit/source"
"github.com/pkg/errors"
"golang.org/x/net/context"
)
type Opt struct {
SessionManager *session.Manager
CacheAccessor cache.Accessor
}
func NewSource(opt Opt) (source.Source, error) {
ls := &localSource{
sm: opt.SessionManager,
cm: opt.CacheAccessor,
}
return ls, nil
}
type localSource struct {
sm *session.Manager
cm cache.Accessor
}
func (ls *localSource) ID() string {
return source.LocalScheme
}
func (ls *localSource) Resolve(ctx context.Context, id source.Identifier) (source.SourceInstance, error) {
localIdentifier, ok := id.(*source.LocalIdentifier)
if !ok {
return nil, errors.Errorf("invalid local identifier %v", id)
}
return &localSourceHandler{
src: *localIdentifier,
localSource: ls,
}, nil
}
type localSourceHandler struct {
src source.LocalIdentifier
*localSource
}
func (ls *localSourceHandler) CacheKey(ctx context.Context) (string, error) {
sessionID := ls.src.SessionID
if sessionID == "" {
uuid := session.FromContext(ctx)
if uuid == "" {
return "", errors.New("could not access local files without session")
}
sessionID = uuid
}
return "session:" + ls.src.Name + ":" + sessionID, nil
}
func (ls *localSourceHandler) Snapshot(ctx context.Context) (out cache.ImmutableRef, retErr error) {
uuid := session.FromContext(ctx)
if uuid == "" {
return nil, errors.New("could not access local files without session")
}
timeoutCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
caller, err := ls.sm.Get(timeoutCtx, uuid)
if err != nil {
return nil, err
}
mutable, err := ls.cm.New(ctx, nil)
if err != nil {
return nil, err
}
defer func() {
if retErr != nil && mutable != nil {
s, err := mutable.Freeze()
if err == nil {
go s.Release(context.TODO())
}
}
}()
mount, err := mutable.Mount(ctx)
if err != nil {
return nil, err
}
lm := snapshot.LocalMounter(mount)
dest, err := lm.Mount()
if err != nil {
return nil, err
}
defer func() {
if retErr != nil && lm != nil {
lm.Unmount()
}
}()
opt := filesync.FSSendRequestOpt{
IncludePatterns: nil,
OverrideExcludes: false,
DestDir: dest,
CacheUpdater: nil,
}
if err := filesync.FSSync(ctx, caller, opt); err != nil {
return nil, err
}
if err := lm.Unmount(); err != nil {
return nil, err
}
lm = nil
snap, err := mutable.ReleaseAndCommit(ctx)
if err != nil {
return nil, err
}
mutable = nil
return snap, err
}