nested llb builds support

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
docker-18.09
Tonis Tiigi 2017-07-21 10:58:24 -07:00
parent f006bb6942
commit 93757aef7f
23 changed files with 1168 additions and 80 deletions

View File

@ -237,6 +237,7 @@ type Vertex struct {
Started *time.Time `protobuf:"bytes,5,opt,name=started,stdtime" json:"started,omitempty"`
Completed *time.Time `protobuf:"bytes,6,opt,name=completed,stdtime" json:"completed,omitempty"`
Error string `protobuf:"bytes,7,opt,name=error,proto3" json:"error,omitempty"`
Parent github_com_opencontainers_go_digest.Digest `protobuf:"bytes,8,opt,name=parent,proto3,customtype=github.com/opencontainers/go-digest.Digest" json:"parent"`
}
func (m *Vertex) Reset() { *m = Vertex{} }
@ -983,6 +984,12 @@ func (m *Vertex) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintControl(dAtA, i, uint64(len(m.Error)))
i += copy(dAtA[i:], m.Error)
}
if len(m.Parent) > 0 {
dAtA[i] = 0x42
i++
i = encodeVarintControl(dAtA, i, uint64(len(m.Parent)))
i += copy(dAtA[i:], m.Parent)
}
return i, nil
}
@ -1301,6 +1308,10 @@ func (m *Vertex) Size() (n int) {
if l > 0 {
n += 1 + l + sovControl(uint64(l))
}
l = len(m.Parent)
if l > 0 {
n += 1 + l + sovControl(uint64(l))
}
return n
}
@ -2465,6 +2476,35 @@ func (m *Vertex) Unmarshal(dAtA []byte) error {
}
m.Error = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 8:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Parent", 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.Parent = github_com_opencontainers_go_digest.Digest(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipControl(dAtA[iNdEx:])
@ -3105,57 +3145,58 @@ var (
func init() { proto.RegisterFile("control.proto", fileDescriptorControl) }
var fileDescriptorControl = []byte{
// 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,
// 844 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x55, 0xdd, 0x8e, 0xdb, 0x44,
0x14, 0x66, 0xec, 0xac, 0x93, 0x9c, 0xcd, 0x56, 0xcb, 0x08, 0x55, 0x96, 0x11, 0x49, 0x30, 0x37,
0x51, 0xa5, 0x7a, 0xdb, 0x00, 0x12, 0x5a, 0x24, 0x04, 0x21, 0x95, 0xd8, 0x15, 0x7b, 0x33, 0xdb,
0xc2, 0xb5, 0x93, 0x9c, 0x75, 0xad, 0x75, 0x3c, 0x61, 0x66, 0x1c, 0x6d, 0x78, 0x0a, 0x78, 0x0d,
0x6e, 0x79, 0x06, 0x44, 0x2f, 0xb9, 0xe6, 0xa2, 0xa0, 0x7d, 0x00, 0x9e, 0x01, 0xcd, 0x8c, 0x9d,
0x7a, 0x9b, 0x4d, 0x7f, 0xd2, 0x2b, 0xcf, 0x19, 0x7f, 0xe7, 0xef, 0x3b, 0x3f, 0x03, 0x07, 0x53,
0x9e, 0x2b, 0xc1, 0xb3, 0x68, 0x21, 0xb8, 0xe2, 0xf4, 0x70, 0xce, 0x27, 0xab, 0x68, 0x52, 0xa4,
0xd9, 0xec, 0x32, 0x55, 0xd1, 0xf2, 0x61, 0x70, 0x3f, 0x49, 0xd5, 0xd3, 0x62, 0x12, 0x4d, 0xf9,
0xfc, 0x28, 0xe1, 0x09, 0x3f, 0x32, 0xc0, 0x49, 0x71, 0x61, 0x24, 0x23, 0x98, 0x93, 0x35, 0x10,
0xf4, 0x12, 0xce, 0x93, 0x0c, 0x5f, 0xa0, 0x54, 0x3a, 0x47, 0xa9, 0xe2, 0xf9, 0xc2, 0x02, 0x42,
0x0a, 0x87, 0xe3, 0x54, 0x5e, 0x3e, 0x91, 0x71, 0x82, 0x0c, 0x7f, 0x2a, 0x50, 0xaa, 0xf0, 0x14,
0xde, 0xaf, 0xdd, 0xc9, 0x05, 0xcf, 0x25, 0xd2, 0xcf, 0xc1, 0x13, 0x38, 0xe5, 0x62, 0xe6, 0x93,
0xbe, 0x3b, 0xd8, 0x1f, 0x7e, 0x14, 0xbd, 0x1c, 0x5b, 0x54, 0x2a, 0x68, 0x10, 0x2b, 0xc1, 0x61,
0x0c, 0xfb, 0xb5, 0x6b, 0x7a, 0x07, 0x9c, 0x93, 0xb1, 0x4f, 0xfa, 0x64, 0xd0, 0x66, 0xce, 0xc9,
0x98, 0xfa, 0xd0, 0x3c, 0x2b, 0x54, 0x3c, 0xc9, 0xd0, 0x77, 0xfa, 0x64, 0xd0, 0x62, 0x95, 0x48,
0x3f, 0x80, 0xbd, 0x93, 0xfc, 0x89, 0x44, 0xdf, 0x35, 0xf7, 0x56, 0xa0, 0x14, 0x1a, 0xe7, 0xe9,
0xcf, 0xe8, 0x37, 0xfa, 0x64, 0xe0, 0x32, 0x73, 0x0e, 0x7f, 0x75, 0xa0, 0x73, 0xce, 0xb3, 0x65,
0x15, 0x3f, 0x3d, 0x04, 0x97, 0xe1, 0x45, 0xe9, 0x45, 0x1f, 0x69, 0x17, 0x60, 0x8c, 0x17, 0x69,
0x9e, 0xaa, 0x94, 0xe7, 0xbe, 0xd3, 0x77, 0x07, 0x1d, 0x56, 0xbb, 0xa1, 0x01, 0xb4, 0x1e, 0x5d,
0x2d, 0xb8, 0x50, 0x28, 0x8c, 0xbf, 0x36, 0x5b, 0xcb, 0xf4, 0x47, 0x38, 0xa8, 0xce, 0xdf, 0x28,
0x25, 0xa4, 0xdf, 0x30, 0xf9, 0x3f, 0xdc, 0xcc, 0xbf, 0x1e, 0x44, 0x74, 0x43, 0xe7, 0x51, 0xae,
0xc4, 0x8a, 0xdd, 0xb4, 0xa3, 0x73, 0x3f, 0x47, 0x29, 0x75, 0x44, 0x7b, 0xc6, 0x67, 0x25, 0x06,
0x5f, 0x03, 0xdd, 0x54, 0xd7, 0x69, 0x5d, 0xe2, 0xaa, 0x4a, 0xeb, 0x12, 0x57, 0x9a, 0xa3, 0x65,
0x9c, 0x15, 0x96, 0xbb, 0x36, 0xb3, 0xc2, 0xb1, 0xf3, 0x05, 0x09, 0xbf, 0x84, 0x83, 0x32, 0x9a,
0xb2, 0x7c, 0xf7, 0xc0, 0x5d, 0xaa, 0xab, 0xb2, 0x76, 0xfe, 0x66, 0xec, 0x3f, 0xa0, 0x50, 0x78,
0xc5, 0x34, 0x28, 0xfc, 0x18, 0x0e, 0xce, 0x55, 0xac, 0x0a, 0xb9, 0x95, 0xd0, 0xf0, 0x77, 0x02,
0x77, 0x2a, 0x4c, 0xe9, 0xe1, 0x33, 0x68, 0x2d, 0x8d, 0x11, 0x94, 0xaf, 0x75, 0xb3, 0x46, 0xd2,
0x63, 0x68, 0x49, 0x63, 0x07, 0xa5, 0xa9, 0xcb, 0xfe, 0xb0, 0xbb, 0x4d, 0xab, 0xf4, 0xb7, 0xc6,
0xd3, 0x23, 0x68, 0x64, 0x3c, 0x91, 0xbe, 0x6b, 0xf4, 0x3e, 0xdc, 0xa6, 0xf7, 0x3d, 0x4f, 0x98,
0x01, 0x86, 0xbf, 0xb9, 0xe0, 0xd9, 0x3b, 0x7a, 0x0a, 0xde, 0x2c, 0x4d, 0x50, 0x2a, 0x9b, 0xd5,
0x68, 0xf8, 0xec, 0x79, 0xef, 0xbd, 0xbf, 0x9f, 0xf7, 0xee, 0xd5, 0xe6, 0x8b, 0x2f, 0x30, 0xd7,
0xf3, 0x18, 0xa7, 0x39, 0x0a, 0x79, 0x94, 0xf0, 0xfb, 0x56, 0x25, 0x1a, 0x9b, 0x0f, 0x2b, 0x2d,
0x68, 0x5b, 0x69, 0xbe, 0x28, 0x94, 0xcd, 0x60, 0x47, 0x5b, 0xd6, 0x82, 0x6e, 0xf0, 0x3c, 0x9e,
0x63, 0xd9, 0x85, 0xe6, 0x4c, 0xef, 0x82, 0x37, 0x8d, 0xa7, 0x4f, 0x71, 0x66, 0xda, 0xbe, 0xc5,
0x4a, 0x89, 0x1e, 0x43, 0x53, 0xaa, 0x58, 0x28, 0x9c, 0x99, 0x06, 0xda, 0x1f, 0x06, 0x91, 0x1d,
0xf7, 0xa8, 0x1a, 0xf7, 0xe8, 0x71, 0x35, 0xee, 0xa3, 0xc6, 0x2f, 0xff, 0xf4, 0x08, 0xab, 0x14,
0xe8, 0x57, 0xd0, 0x9e, 0xf2, 0xf9, 0x22, 0x43, 0xad, 0xed, 0xbd, 0xa1, 0xf6, 0x0b, 0x15, 0xdd,
0x7a, 0x28, 0x04, 0x17, 0x7e, 0xd3, 0xb6, 0x9e, 0x11, 0x34, 0x13, 0x8b, 0x58, 0x60, 0xae, 0xfc,
0xd6, 0xee, 0xac, 0x5a, 0x0b, 0xe1, 0x7f, 0x0e, 0x74, 0xea, 0x85, 0xdf, 0xd8, 0x1d, 0xa7, 0xe0,
0xd9, 0x36, 0xb2, 0xed, 0xbf, 0x9b, 0x33, 0x6b, 0xe1, 0x56, 0xda, 0x7d, 0x68, 0x4e, 0x0b, 0x61,
0xb2, 0xb1, 0xeb, 0xa6, 0x12, 0x75, 0xf2, 0x8a, 0xab, 0x38, 0x33, 0xb4, 0xbb, 0xcc, 0x0a, 0x74,
0x04, 0xed, 0xf5, 0x76, 0x7d, 0x03, 0x4a, 0x5b, 0x3a, 0x5c, 0x4b, 0xeb, 0x5a, 0xad, 0x5e, 0xd2,
0xe6, 0x3b, 0x95, 0xb4, 0xf5, 0xd6, 0x25, 0x0d, 0xff, 0x20, 0xd0, 0x5e, 0x4f, 0x4c, 0x8d, 0x5d,
0xf2, 0xce, 0xec, 0xde, 0x60, 0xc6, 0xd9, 0x8d, 0x99, 0xbb, 0xe0, 0x49, 0x25, 0x30, 0x9e, 0x9b,
0x1a, 0xb9, 0xac, 0x94, 0xf4, 0x6e, 0x9a, 0xcb, 0xc4, 0x54, 0xa8, 0xc3, 0xf4, 0x31, 0x0c, 0xa1,
0x33, 0x5a, 0x29, 0x94, 0x67, 0x28, 0xf5, 0xcb, 0xa3, 0x6b, 0x3b, 0x8b, 0x55, 0x6c, 0xf2, 0xe8,
0x30, 0x73, 0x1e, 0xfe, 0xe9, 0x40, 0xf3, 0x5b, 0xfb, 0xd4, 0xd2, 0xc7, 0xd0, 0x5e, 0x3f, 0x77,
0x34, 0xdc, 0xdc, 0x22, 0x2f, 0xbf, 0x8f, 0xc1, 0x27, 0xaf, 0xc4, 0x94, 0xeb, 0xf0, 0x3b, 0xd8,
0x33, 0x1b, 0x98, 0x76, 0x5f, 0xfd, 0x50, 0x04, 0xbd, 0xad, 0xff, 0x4b, 0x4b, 0x67, 0xe0, 0x95,
0x13, 0x70, 0x1b, 0xb4, 0xbe, 0xa8, 0x83, 0xfe, 0x76, 0x80, 0x35, 0xf6, 0x80, 0xd0, 0xb3, 0xf5,
0xb3, 0x73, 0x5b, 0x68, 0x75, 0xe6, 0x82, 0xd7, 0xfc, 0x1f, 0x90, 0x07, 0x64, 0xd4, 0x79, 0x76,
0xdd, 0x25, 0x7f, 0x5d, 0x77, 0xc9, 0xbf, 0xd7, 0x5d, 0x32, 0xf1, 0x4c, 0x39, 0x3f, 0xfd, 0x3f,
0x00, 0x00, 0xff, 0xff, 0x03, 0x3d, 0x42, 0x9c, 0xc8, 0x08, 0x00, 0x00,
}

View File

@ -60,6 +60,7 @@ message Vertex {
google.protobuf.Timestamp started = 5 [(gogoproto.stdtime) = true ];
google.protobuf.Timestamp completed = 6 [(gogoproto.stdtime) = true ];
string error = 7; // typed errors?
string parent = 8 [(gogoproto.customtype) = "github.com/opencontainers/go-digest.Digest", (gogoproto.nullable) = false];
}
message VertexStatus {

View File

@ -14,6 +14,7 @@ type Vertex struct {
Completed *time.Time
Cached bool
Error string
Parent digest.Digest
}
type VertexStatus struct {

View File

@ -0,0 +1,92 @@
package llbbuild
import (
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/solver/pb"
digest "github.com/opencontainers/go-digest"
)
func Build(opt ...BuildOption) llb.StateOption {
return func(s llb.State) llb.State {
return s.WithOutput(NewBuildOp(s.Output(), opt...).Output())
}
}
func NewBuildOp(source llb.Output, opt ...BuildOption) llb.Vertex {
info := &BuildInfo{}
for _, o := range opt {
o(info)
}
return &build{source: source, info: info}
}
type build struct {
source llb.Output
info *BuildInfo
}
func (b *build) ToInput() (*pb.Input, error) {
dt, err := b.Marshal()
if err != nil {
return nil, err
}
dgst := digest.FromBytes(dt)
return &pb.Input{Digest: dgst, Index: pb.OutputIndex(0)}, nil
}
func (b *build) Vertex() llb.Vertex {
return b
}
func (b *build) Validate() error {
return nil
}
func (b *build) Marshal() ([]byte, error) {
pbo := &pb.BuildOp{
Builder: pb.LLBBuilder,
Inputs: map[string]*pb.BuildInput{
pb.LLBDefinitionInput: {pb.InputIndex(0)}},
}
pbo.Attrs = map[string]string{}
if b.info.DefinitionFilename != "" {
pbo.Attrs[pb.AttrLLBDefinitionFilename] = b.info.DefinitionFilename
}
pop := &pb.Op{
Op: &pb.Op_Build{
Build: pbo,
},
}
inp, err := b.source.ToInput()
if err != nil {
return nil, err
}
pop.Inputs = append(pop.Inputs, inp)
return pop.Marshal()
}
func (b *build) Output() llb.Output {
return b
}
func (b *build) Inputs() []llb.Output {
return []llb.Output{b.source}
}
type BuildInfo struct {
DefinitionFilename string
}
type BuildOption func(*BuildInfo)
func WithFilename(fn string) BuildOption {
return func(b *BuildInfo) {
b.DefinitionFilename = fn
}
}

View File

@ -0,0 +1,49 @@
package llbbuild
import (
"testing"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/solver/pb"
digest "github.com/opencontainers/go-digest"
"github.com/stretchr/testify/require"
)
func TestMarshal(t *testing.T) {
b := NewBuildOp(newDummyOutput("foobar"), WithFilename("myfilename"))
dt, err := b.Marshal()
require.NoError(t, err)
var op pb.Op
err = op.Unmarshal(dt)
require.NoError(t, err)
buildop := op.GetBuild()
require.NotEqual(t, buildop, nil)
require.Equal(t, len(op.Inputs), 1)
require.Equal(t, buildop.Builder, pb.LLBBuilder)
require.Equal(t, len(buildop.Inputs), 1)
require.Equal(t, buildop.Inputs[pb.LLBDefinitionInput], &pb.BuildInput{pb.InputIndex(0)})
require.Equal(t, buildop.Attrs[pb.AttrLLBDefinitionFilename], "myfilename")
}
func newDummyOutput(key string) llb.Output {
dgst := digest.FromBytes([]byte(key))
return &dummyOutput{dgst: dgst}
}
type dummyOutput struct {
dgst digest.Digest
}
func (d *dummyOutput) ToInput() (*pb.Input, error) {
return &pb.Input{
Digest: d.dgst,
Index: pb.OutputIndex(7), // random constant
}, nil
}
func (d *dummyOutput) Vertex() llb.Vertex {
return nil
}

View File

@ -116,6 +116,7 @@ func (c *Client) Solve(ctx context.Context, r io.Reader, opt SolveOpt, statusCha
Completed: v.Completed,
Error: v.Error,
Cached: v.Cached,
Parent: v.Parent,
})
}
for _, v := range resp.Statuses {

View File

@ -106,6 +106,8 @@ func attr(dgst digest.Digest, op pb.Op) (string, string) {
return op.Source.Identifier, "ellipse"
case *pb.Op_Exec:
return strings.Join(op.Exec.Meta.Args, " "), "box"
case *pb.Op_Build:
return "build", "box3d"
default:
return dgst.String(), "plaintext"
}

View File

@ -122,6 +122,7 @@ func (c *Controller) Status(req *controlapi.StatusRequest, stream controlapi.Con
Completed: v.Completed,
Error: v.Error,
Cached: v.Cached,
Parent: v.Parent,
})
}
for _, v := range ss.Statuses {

View File

@ -0,0 +1,39 @@
package main
import (
"os"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/client/llb/llbbuild"
"github.com/moby/buildkit/util/system"
)
const url = "https://gist.githubusercontent.com/tonistiigi/03b4049f8cc3de059bd2a1a1d8643714/raw/b5960995d570d8c6d94db527e805edc6d5854268/buildprs.go"
func main() {
build := goBuildBase().
Run(llb.Shlex("apk add --no-cache curl")).
Run(llb.Shlexf("curl -o /buildprs.go \"%s\"", url))
buildkitRepo := "github.com/moby/buildkit"
build = build.Run(llb.Shlex("sh -c \"go run /buildprs.go > /out/buildkit.llb.definition\""))
build.AddMount("/go/src/"+buildkitRepo, llb.Git(buildkitRepo, "master"))
pb := build.AddMount("/out", llb.Scratch())
built := pb.With(llbbuild.Build())
dt, err := llb.Image("docker.io/library/alpine:latest").Run(llb.Shlex("ls -l /out"), llb.AddMount("/out", built, llb.Readonly)).Marshal()
if err != nil {
panic(err)
}
llb.WriteTo(dt, os.Stdout)
}
func goBuildBase() llb.State {
goAlpine := llb.Image("docker.io/library/golang:1.8-alpine")
return goAlpine.
AddEnv("PATH", "/usr/local/go/bin:"+system.DefaultPathEnv).
AddEnv("GOPATH", "/go").
Run(llb.Shlex("apk add --no-cache g++ linux-headers make")).Root()
}

141
solver/build.go Normal file
View File

@ -0,0 +1,141 @@
package solver
import (
"encoding/json"
"os"
"path/filepath"
"github.com/docker/docker/pkg/symlink"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/snapshot"
"github.com/moby/buildkit/solver/pb"
"github.com/moby/buildkit/util/progress"
digest "github.com/opencontainers/go-digest"
"github.com/pkg/errors"
"golang.org/x/net/context"
)
type buildOp struct {
op *pb.BuildOp
s *Solver
v Vertex
}
func newBuildOp(v Vertex, op *pb.Op_Build, s *Solver) (Op, error) {
return &buildOp{
op: op.Build,
s: s,
v: v,
}, nil
}
func (b *buildOp) CacheKey(ctx context.Context, inputs []string) (string, int, error) {
dt, err := json.Marshal(struct {
Inputs []string
Exec *pb.BuildOp
}{
Inputs: inputs,
Exec: b.op,
})
if err != nil {
return "", 0, err
}
return digest.FromBytes(dt).String(), 1, nil // TODO: other builders should support many outputs
}
func (b *buildOp) Run(ctx context.Context, inputs []Reference) (outputs []Reference, retErr error) {
if b.op.Builder != pb.LLBBuilder {
return nil, errors.Errorf("only llb builder is currently allowed")
}
builderInputs := b.op.Inputs
llbDef, ok := builderInputs[pb.LLBDefinitionInput]
if !ok {
return nil, errors.Errorf("no llb definition input %s found", pb.LLBDefinitionInput)
}
i := int(llbDef.Input)
if i >= len(inputs) {
return nil, errors.Errorf("invalid index %v", i) // TODO: this should be validated before
}
inp := inputs[i]
ref, ok := toImmutableRef(inp)
if !ok {
return nil, errors.Errorf("invalid reference for build %T", inp)
}
mount, err := ref.Mount(ctx, false)
if err != nil {
return nil, err
}
lm := snapshot.LocalMounter(mount)
root, err := lm.Mount()
if err != nil {
return nil, err
}
defer func() {
if retErr != nil && lm != nil {
lm.Unmount()
}
}()
fn := pb.LLBDefaultDefinitionFile
if override, ok := b.op.Attrs[pb.AttrLLBDefinitionFilename]; ok {
fn = override
}
newfn, err := symlink.FollowSymlinkInScope(filepath.Join(root, fn), root)
if err != nil {
return nil, errors.Wrapf(err, "working dir %s points to invalid target", fn)
}
f, err := os.Open(newfn)
if err != nil {
return nil, errors.Wrapf(err, "failed to open %s", newfn)
}
def, err := llb.ReadFrom(f)
if err != nil {
f.Close()
return nil, err
}
f.Close()
lm.Unmount()
lm = nil
v, err := LoadLLB(def)
if err != nil {
return nil, err
}
if len(v.Inputs()) == 0 {
return nil, errors.New("required vertex needs to have inputs")
}
index := v.Inputs()[0].Index
v = v.Inputs()[0].Vertex
vv := toInternalVertex(v)
pw, _, ctx := progress.FromContext(ctx, progress.WithMetadata("parentVertex", b.v.Digest()))
defer pw.Close()
refs, err := b.s.getRefs(ctx, vv)
// filer out only the required ref
var out Reference
for i, r := range refs {
if i == index {
out = r
} else {
go r.Release(context.TODO())
}
}
return []Reference{out}, err
}

View File

@ -19,7 +19,7 @@ type execOp struct {
w worker.Worker
}
func newExecOp(op *pb.Op_Exec, cm cache.Manager, w worker.Worker) (Op, error) {
func newExecOp(_ Vertex, op *pb.Op_Exec, cm cache.Manager, w worker.Worker) (Op, error) {
return &execOp{
op: op.Exec,
cm: cm,

View File

@ -13,6 +13,10 @@ import (
"github.com/pkg/errors"
)
type jobKeyT string
var jobKey = jobKeyT("buildkit/solver/job")
type jobList struct {
mu sync.RWMutex
refs map[string]*job
@ -27,12 +31,12 @@ func newJobList() *jobList {
return jl
}
func (jl *jobList) new(ctx context.Context, id string, g *vertex, pr progress.Reader) (*job, error) {
func (jl *jobList) new(ctx context.Context, id string, g *vertex, pr progress.Reader) (context.Context, *job, error) {
jl.mu.Lock()
defer jl.mu.Unlock()
if _, ok := jl.refs[id]; ok {
return nil, errors.Errorf("id %s exists", id)
return nil, nil, errors.Errorf("id %s exists", id)
}
j := &job{g: g, pr: progress.NewMultiReader(pr)}
jl.refs[id] = j
@ -44,7 +48,7 @@ func (jl *jobList) new(ctx context.Context, id string, g *vertex, pr progress.Re
delete(jl.refs, id)
}()
return jl.refs[id], nil
return context.WithValue(ctx, jobKey, jl.refs[id]), jl.refs[id], nil
}
func (jl *jobList) get(id string) (*job, error) {
@ -104,6 +108,10 @@ func (j *job) pipe(ctx context.Context, ch chan *client.SolveStatus) error {
for _, p := range p {
switch v := p.Sys.(type) {
case client.Vertex:
vtx, ok := p.Meta("parentVertex")
if ok {
v.Parent = vtx.(digest.Digest)
}
ss.Vertexes = append(ss.Vertexes, &v)
case progress.Status:

View File

@ -83,6 +83,8 @@ func llbOpName(op *pb.Op) string {
return op.Source.Identifier
case *pb.Op_Exec:
return strings.Join(op.Exec.Meta.Args, " ")
case *pb.Op_Build:
return "build"
default:
return "unknown"
}

View File

@ -2,3 +2,4 @@ package pb
const AttrKeepGitDir = "git.keepgitdir"
const AttrLocalSessionID = "local.session"
const AttrLLBDefinitionFilename = "llbbuild.filename"

View File

@ -6,3 +6,7 @@ type OutputIndex int64
const RootMount = "/"
const SkipOutput OutputIndex = -1
const Empty InputIndex = -1
const LLBBuilder InputIndex = -1
const LLBDefinitionInput = "buildkit.llb.definition"
const LLBDefaultDefinitionFile = LLBDefinitionInput

View File

@ -17,6 +17,8 @@
CopyOp
CopySource
SourceOp
BuildOp
BuildInput
*/
package pb
@ -27,6 +29,8 @@ import _ "github.com/gogo/protobuf/gogoproto"
import github_com_opencontainers_go_digest "github.com/opencontainers/go-digest"
import errors "errors"
import io "io"
// Reference imports to suppress errors if they are not otherwise used.
@ -40,6 +44,7 @@ type Op struct {
// *Op_Exec
// *Op_Source
// *Op_Copy
// *Op_Build
Op isOp_Op `protobuf_oneof:"op"`
}
@ -62,10 +67,14 @@ type Op_Source struct {
type Op_Copy struct {
Copy *CopyOp `protobuf:"bytes,4,opt,name=copy,oneof"`
}
type Op_Build struct {
Build *BuildOp `protobuf:"bytes,5,opt,name=build,oneof"`
}
func (*Op_Exec) isOp_Op() {}
func (*Op_Source) isOp_Op() {}
func (*Op_Copy) isOp_Op() {}
func (*Op_Build) isOp_Op() {}
func (m *Op) GetOp() isOp_Op {
if m != nil {
@ -102,12 +111,20 @@ func (m *Op) GetCopy() *CopyOp {
return nil
}
func (m *Op) GetBuild() *BuildOp {
if x, ok := m.GetOp().(*Op_Build); ok {
return x.Build
}
return nil
}
// XXX_OneofFuncs is for the internal use of the proto package.
func (*Op) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), []interface{}) {
return _Op_OneofMarshaler, _Op_OneofUnmarshaler, []interface{}{
(*Op_Exec)(nil),
(*Op_Source)(nil),
(*Op_Copy)(nil),
(*Op_Build)(nil),
}
}
@ -130,6 +147,11 @@ func _Op_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
if err := b.EncodeMessage(x.Copy); err != nil {
return err
}
case *Op_Build:
_ = b.EncodeVarint(5<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Build); err != nil {
return err
}
case nil:
default:
return fmt.Errorf("Op.Op has unexpected type %T", x)
@ -164,6 +186,14 @@ func _Op_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bo
err := b.DecodeMessage(msg)
m.Op = &Op_Copy{msg}
return true, err
case 5: // op.build
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(BuildOp)
err := b.DecodeMessage(msg)
m.Op = &Op_Build{msg}
return true, err
default:
return false, nil
}
@ -265,6 +295,39 @@ func (m *SourceOp) GetAttrs() map[string]string {
return nil
}
type BuildOp struct {
Builder InputIndex `protobuf:"varint,1,opt,name=builder,proto3,customtype=InputIndex" json:"builder"`
Inputs map[string]*BuildInput `protobuf:"bytes,2,rep,name=inputs" json:"inputs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value"`
Def [][]byte `protobuf:"bytes,3,rep,name=def" json:"def,omitempty"`
Attrs map[string]string `protobuf:"bytes,4,rep,name=attrs" json:"attrs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (m *BuildOp) Reset() { *m = BuildOp{} }
func (m *BuildOp) String() string { return proto.CompactTextString(m) }
func (*BuildOp) ProtoMessage() {}
func (m *BuildOp) GetInputs() map[string]*BuildInput {
if m != nil {
return m.Inputs
}
return nil
}
func (m *BuildOp) GetAttrs() map[string]string {
if m != nil {
return m.Attrs
}
return nil
}
type BuildInput struct {
Input InputIndex `protobuf:"varint,1,opt,name=input,proto3,customtype=InputIndex" json:"input"`
}
func (m *BuildInput) Reset() { *m = BuildInput{} }
func (m *BuildInput) String() string { return proto.CompactTextString(m) }
func (*BuildInput) ProtoMessage() {}
func init() {
proto.RegisterType((*Op)(nil), "pb.Op")
proto.RegisterType((*Input)(nil), "pb.Input")
@ -274,6 +337,8 @@ func init() {
proto.RegisterType((*CopyOp)(nil), "pb.CopyOp")
proto.RegisterType((*CopySource)(nil), "pb.CopySource")
proto.RegisterType((*SourceOp)(nil), "pb.SourceOp")
proto.RegisterType((*BuildOp)(nil), "pb.BuildOp")
proto.RegisterType((*BuildInput)(nil), "pb.BuildInput")
}
func (m *Op) Marshal() (data []byte, err error) {
size := m.Size()
@ -354,6 +419,20 @@ func (m *Op_Copy) MarshalTo(data []byte) (int, error) {
}
return i, nil
}
func (m *Op_Build) MarshalTo(data []byte) (int, error) {
i := 0
if m.Build != nil {
data[i] = 0x2a
i++
i = encodeVarintOps(data, i, uint64(m.Build.Size()))
n5, err := m.Build.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n5
}
return i, nil
}
func (m *Input) Marshal() (data []byte, err error) {
size := m.Size()
data = make([]byte, size)
@ -402,11 +481,11 @@ func (m *ExecOp) MarshalTo(data []byte) (int, error) {
data[i] = 0xa
i++
i = encodeVarintOps(data, i, uint64(m.Meta.Size()))
n5, err := m.Meta.MarshalTo(data[i:])
n6, err := m.Meta.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n5
i += n6
}
if len(m.Mounts) > 0 {
for _, msg := range m.Mounts {
@ -633,6 +712,102 @@ func (m *SourceOp) MarshalTo(data []byte) (int, error) {
return i, nil
}
func (m *BuildOp) 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 *BuildOp) MarshalTo(data []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.Builder != 0 {
data[i] = 0x8
i++
i = encodeVarintOps(data, i, uint64(m.Builder))
}
if len(m.Inputs) > 0 {
for k, _ := range m.Inputs {
data[i] = 0x12
i++
v := m.Inputs[k]
if v == nil {
return 0, errors.New("proto: map has nil element")
}
msgSize := v.Size()
mapSize := 1 + len(k) + sovOps(uint64(len(k))) + 1 + msgSize + sovOps(uint64(msgSize))
i = encodeVarintOps(data, i, uint64(mapSize))
data[i] = 0xa
i++
i = encodeVarintOps(data, i, uint64(len(k)))
i += copy(data[i:], k)
data[i] = 0x12
i++
i = encodeVarintOps(data, i, uint64(v.Size()))
n7, err := v.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n7
}
}
if len(m.Def) > 0 {
for _, b := range m.Def {
data[i] = 0x1a
i++
i = encodeVarintOps(data, i, uint64(len(b)))
i += copy(data[i:], b)
}
}
if len(m.Attrs) > 0 {
for k, _ := range m.Attrs {
data[i] = 0x22
i++
v := m.Attrs[k]
mapSize := 1 + len(k) + sovOps(uint64(len(k))) + 1 + len(v) + sovOps(uint64(len(v)))
i = encodeVarintOps(data, i, uint64(mapSize))
data[i] = 0xa
i++
i = encodeVarintOps(data, i, uint64(len(k)))
i += copy(data[i:], k)
data[i] = 0x12
i++
i = encodeVarintOps(data, i, uint64(len(v)))
i += copy(data[i:], v)
}
}
return i, nil
}
func (m *BuildInput) 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 *BuildInput) MarshalTo(data []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.Input != 0 {
data[i] = 0x8
i++
i = encodeVarintOps(data, i, uint64(m.Input))
}
return i, nil
}
func encodeFixed64Ops(data []byte, offset int, v uint64) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
@ -702,6 +877,15 @@ func (m *Op_Copy) Size() (n int) {
}
return n
}
func (m *Op_Build) Size() (n int) {
var l int
_ = l
if m.Build != nil {
l = m.Build.Size()
n += 1 + l + sovOps(uint64(l))
}
return n
}
func (m *Input) Size() (n int) {
var l int
_ = l
@ -823,6 +1007,50 @@ func (m *SourceOp) Size() (n int) {
return n
}
func (m *BuildOp) Size() (n int) {
var l int
_ = l
if m.Builder != 0 {
n += 1 + sovOps(uint64(m.Builder))
}
if len(m.Inputs) > 0 {
for k, v := range m.Inputs {
_ = k
_ = v
l = 0
if v != nil {
l = v.Size()
}
mapEntrySize := 1 + len(k) + sovOps(uint64(len(k))) + 1 + l + sovOps(uint64(l))
n += mapEntrySize + 1 + sovOps(uint64(mapEntrySize))
}
}
if len(m.Def) > 0 {
for _, b := range m.Def {
l = len(b)
n += 1 + l + sovOps(uint64(l))
}
}
if len(m.Attrs) > 0 {
for k, v := range m.Attrs {
_ = k
_ = v
mapEntrySize := 1 + len(k) + sovOps(uint64(len(k))) + 1 + len(v) + sovOps(uint64(len(v)))
n += mapEntrySize + 1 + sovOps(uint64(mapEntrySize))
}
}
return n
}
func (m *BuildInput) Size() (n int) {
var l int
_ = l
if m.Input != 0 {
n += 1 + sovOps(uint64(m.Input))
}
return n
}
func sovOps(x uint64) (n int) {
for {
n++
@ -992,6 +1220,38 @@ func (m *Op) Unmarshal(data []byte) error {
}
m.Op = &Op_Copy{v}
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Build", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowOps
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthOps
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
v := &BuildOp{}
if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil {
return err
}
m.Op = &Op_Build{v}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipOps(data[iNdEx:])
@ -1926,6 +2186,400 @@ func (m *SourceOp) Unmarshal(data []byte) error {
}
return nil
}
func (m *BuildOp) 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 ErrIntOverflowOps
}
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: BuildOp: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: BuildOp: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Builder", wireType)
}
m.Builder = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowOps
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
m.Builder |= (InputIndex(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Inputs", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowOps
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthOps
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
var keykey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowOps
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
keykey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowOps
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
stringLenmapkey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthOps
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey := string(data[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
var valuekey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowOps
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
valuekey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
var mapmsglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowOps
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
mapmsglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if mapmsglen < 0 {
return ErrInvalidLengthOps
}
postmsgIndex := iNdEx + mapmsglen
if mapmsglen < 0 {
return ErrInvalidLengthOps
}
if postmsgIndex > l {
return io.ErrUnexpectedEOF
}
mapvalue := &BuildInput{}
if err := mapvalue.Unmarshal(data[iNdEx:postmsgIndex]); err != nil {
return err
}
iNdEx = postmsgIndex
if m.Inputs == nil {
m.Inputs = make(map[string]*BuildInput)
}
m.Inputs[mapkey] = mapvalue
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Def", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowOps
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
byteLen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthOps
}
postIndex := iNdEx + byteLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Def = append(m.Def, make([]byte, postIndex-iNdEx))
copy(m.Def[len(m.Def)-1], data[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Attrs", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowOps
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthOps
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
var keykey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowOps
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
keykey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowOps
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
stringLenmapkey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthOps
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey := string(data[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
var valuekey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowOps
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
valuekey |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
var stringLenmapvalue uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowOps
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
stringLenmapvalue |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapvalue := int(stringLenmapvalue)
if intStringLenmapvalue < 0 {
return ErrInvalidLengthOps
}
postStringIndexmapvalue := iNdEx + intStringLenmapvalue
if postStringIndexmapvalue > l {
return io.ErrUnexpectedEOF
}
mapvalue := string(data[iNdEx:postStringIndexmapvalue])
iNdEx = postStringIndexmapvalue
if m.Attrs == nil {
m.Attrs = make(map[string]string)
}
m.Attrs[mapkey] = mapvalue
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipOps(data[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthOps
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *BuildInput) 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 ErrIntOverflowOps
}
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: BuildInput: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: BuildInput: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Input", wireType)
}
m.Input = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowOps
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
m.Input |= (InputIndex(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipOps(data[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthOps
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipOps(data []byte) (n int, err error) {
l := len(data)
iNdEx := 0

View File

@ -10,6 +10,7 @@ message Op {
ExecOp exec = 2;
SourceOp source = 3;
CopyOp copy = 4;
BuildOp build = 5;
}
}
@ -52,3 +53,15 @@ message SourceOp {
string identifier = 1;
map<string, string> attrs = 2;
}
message BuildOp {
int64 builder = 1 [(gogoproto.customtype) = "InputIndex", (gogoproto.nullable) = false];
map<string, BuildInput> inputs = 2;
repeated bytes def = 3;
map<string, string> attrs = 4;
// outputs
}
message BuildInput {
int64 input = 1 [(gogoproto.customtype) = "InputIndex", (gogoproto.nullable) = false];
}

View File

@ -24,16 +24,20 @@ type LLBOpt struct {
}
func NewLLBSolver(opt LLBOpt) *Solver {
return New(func(v Vertex) (Op, error) {
var s *Solver
s = New(func(v Vertex) (Op, error) {
switch op := v.Sys().(type) {
case *pb.Op_Source:
return newSourceOp(op, opt.SourceManager)
return newSourceOp(v, op, opt.SourceManager)
case *pb.Op_Exec:
return newExecOp(op, opt.CacheManager, opt.Worker)
return newExecOp(v, op, opt.CacheManager, opt.Worker)
case *pb.Op_Build:
return newBuildOp(v, op, s)
default:
return nil, errors.Errorf("invalid op type %T", op)
}
}, opt.InstructionCache)
return s
}
// ResolveOpFunc finds an Op implementation for a vertex
@ -76,10 +80,13 @@ func (s *Solver) Solve(ctx context.Context, id string, v Vertex, exp exporter.Ex
defer closeProgressWriter()
if len(v.Inputs()) > 0 { // TODO: detect op_return better
v = v.Inputs()[0].Vertex
if len(v.Inputs()) == 0 {
return errors.New("required vertex needs to have inputs")
}
index := v.Inputs()[0].Index
v = v.Inputs()[0].Vertex
vv := toInternalVertex(v)
solveVertex := vv
@ -89,12 +96,12 @@ func (s *Solver) Solve(ctx context.Context, id string, v Vertex, exp exporter.Ex
vv.initClientVertex()
}
j, err := s.jobs.new(ctx, id, vv, pr)
ctx, j, err := s.jobs.new(ctx, id, vv, pr)
if err != nil {
return err
}
refs, err := s.getRefs(ctx, j, solveVertex)
refs, err := s.getRefs(ctx, solveVertex)
s.activeState.cancel(j)
if err != nil {
return err
@ -117,9 +124,10 @@ func (s *Solver) Solve(ctx context.Context, id string, v Vertex, exp exporter.Ex
}
if exp != nil {
immutable, ok := toImmutableRef(refs[0])
r := refs[int(index)]
immutable, ok := toImmutableRef(r)
if !ok {
return errors.Errorf("invalid reference for exporting: %T", refs[0])
return errors.Errorf("invalid reference for exporting: %T", r)
}
vv.notifyStarted(ctx)
pw, _, ctx := progress.FromContext(ctx, progress.WithMetadata("vertex", vv.Digest()))
@ -142,8 +150,8 @@ func (s *Solver) Status(ctx context.Context, id string, statusChan chan *client.
return j.pipe(ctx, statusChan)
}
func (s *Solver) getCacheKey(ctx context.Context, j *job, g *vertex) (cacheKey string, numRefs int, retErr error) {
state, err := s.activeState.vertexState(j, g.digest, func() (Op, error) {
func (s *Solver) getCacheKey(ctx context.Context, g *vertex) (cacheKey string, numRefs int, retErr error) {
state, err := s.activeState.vertexState(ctx, g.digest, func() (Op, error) {
return s.resolve(g)
})
if err != nil {
@ -156,7 +164,7 @@ func (s *Solver) getCacheKey(ctx context.Context, j *job, g *vertex) (cacheKey s
for i, in := range g.inputs {
func(i int, in *vertex, index int) {
eg.Go(func() error {
k, _, err := s.getCacheKey(ctx, j, in)
k, _, err := s.getCacheKey(ctx, in)
if err != nil {
return err
}
@ -185,8 +193,8 @@ func (s *Solver) getCacheKey(ctx context.Context, j *job, g *vertex) (cacheKey s
})
}
func (s *Solver) getRefs(ctx context.Context, j *job, g *vertex) (retRef []Reference, retErr error) {
state, err := s.activeState.vertexState(j, g.digest, func() (Op, error) {
func (s *Solver) getRefs(ctx context.Context, g *vertex) (retRef []Reference, retErr error) {
state, err := s.activeState.vertexState(ctx, g.digest, func() (Op, error) {
return s.resolve(g)
})
if err != nil {
@ -197,7 +205,7 @@ func (s *Solver) getRefs(ctx context.Context, j *job, g *vertex) (retRef []Refer
if s.cache != nil {
var err error
var numRefs int
cacheKey, numRefs, err = s.getCacheKey(ctx, j, g)
cacheKey, numRefs, err = s.getCacheKey(ctx, g)
if err != nil {
return nil, err
}
@ -230,7 +238,7 @@ func (s *Solver) getRefs(ctx context.Context, j *job, g *vertex) (retRef []Refer
func(i int, in *vertex, index int) {
eg.Go(func() error {
if s.cache != nil {
k, numRefs, err := s.getCacheKey(ctx, j, in)
k, numRefs, err := s.getCacheKey(ctx, in)
if err != nil {
return err
}
@ -249,7 +257,7 @@ func (s *Solver) getRefs(ctx context.Context, j *job, g *vertex) (retRef []Refer
}
// execute input vertex
r, err := s.getRefs(ctx, j, in)
r, err := s.getRefs(ctx, in)
if err != nil {
return err
}

View File

@ -15,7 +15,7 @@ type sourceOp struct {
src source.SourceInstance
}
func newSourceOp(op *pb.Op_Source, sm *source.Manager) (Op, error) {
func newSourceOp(_ Vertex, op *pb.Op_Source, sm *source.Manager) (Op, error) {
return &sourceOp{
op: op,
sm: sm,

View File

@ -7,6 +7,7 @@ import (
"github.com/moby/buildkit/util/flightcontrol"
"github.com/moby/buildkit/util/progress"
digest "github.com/opencontainers/go-digest"
"github.com/pkg/errors"
"golang.org/x/net/context"
)
@ -31,7 +32,13 @@ type state struct {
cacheCtx context.Context
}
func (s *activeState) vertexState(j *job, key digest.Digest, cb func() (Op, error)) (*state, error) {
func (s *activeState) vertexState(ctx context.Context, key digest.Digest, cb func() (Op, error)) (*state, error) {
jv := ctx.Value(jobKey)
if jv == nil {
return nil, errors.Errorf("can't get vertex state without active job")
}
j := jv.(*job)
s.mu.Lock()
defer s.mu.Unlock()

View File

@ -226,6 +226,8 @@ func (gs *gitSourceHandler) Snapshot(ctx context.Context) (out cache.ImmutableRe
return gs.cache.Get(ctx, sis[0].ID())
}
gs.locker.Lock(gs.src.Remote)
defer gs.locker.Unlock(gs.src.Remote)
gitDir, unmountGitDir, err := gs.mountRemote(ctx, gs.src.Remote)
if err != nil {
return nil, err

View File

@ -192,7 +192,19 @@ func (pw *progressWriter) Write(id string, v interface{}) error {
}
func (pw *progressWriter) WriteRawProgress(p *Progress) error {
p.meta = pw.meta
meta := p.meta
if len(pw.meta) > 0 {
meta = map[string]interface{}{}
for k, v := range p.meta {
meta[k] = v
}
for k, v := range pw.meta {
if _, ok := meta[k]; !ok {
meta[k] = v
}
}
}
p.meta = meta
return pw.writeRawProgress(p)
}

View File

@ -80,6 +80,7 @@ type vertex struct {
statuses []*status
byID map[string]*status
logs []*client.VertexLog
indent string
}
type status struct {
@ -99,6 +100,10 @@ func (t *trace) update(s *client.SolveStatus) {
t.byDigest[v.Digest] = &vertex{
byID: make(map[string]*status),
}
} else {
if prev.Parent != v.Parent { // skip vertexes already in list for other parents
continue
}
}
if v.Started != nil && (prev == nil || prev.Started == nil) {
if t.localTimeDiff == 0 {
@ -107,6 +112,9 @@ func (t *trace) update(s *client.SolveStatus) {
t.vertexes = append(t.vertexes, t.byDigest[v.Digest])
}
t.byDigest[v.Digest].Vertex = v
if v.Parent != "" {
t.byDigest[v.Digest].indent = t.byDigest[v.Parent].indent + "=> "
}
}
for _, s := range s.Statuses {
v, ok := t.byDigest[s.Vertex]
@ -179,12 +187,13 @@ func (t *trace) displayInfo() (d displayInfo) {
if v.Cached {
j.name = "CACHED " + j.name
}
j.name = v.indent + j.name
d.jobs = append(d.jobs, j)
for _, s := range v.statuses {
j := job{
startTime: addTime(s.Started, t.localTimeDiff),
completedTime: addTime(s.Completed, t.localTimeDiff),
name: "=> " + s.ID,
name: v.indent + "=> " + s.ID,
}
if s.Total != 0 {
j.status = units.HumanSize(float64(s.Current)) + " / " + units.HumanSize(float64(s.Total))