commit
ab8b2f3c06
|
@ -247,12 +247,15 @@ func (m *Vertex) GetCompleted() *time.Time {
|
||||||
}
|
}
|
||||||
|
|
||||||
type VertexStatus struct {
|
type VertexStatus struct {
|
||||||
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
||||||
Vertex github_com_opencontainers_go_digest.Digest `protobuf:"bytes,2,opt,name=vertex,proto3,customtype=github.com/opencontainers/go-digest.Digest" json:"vertex"`
|
Vertex github_com_opencontainers_go_digest.Digest `protobuf:"bytes,2,opt,name=vertex,proto3,customtype=github.com/opencontainers/go-digest.Digest" json:"vertex"`
|
||||||
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
|
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
Current int64 `protobuf:"varint,4,opt,name=current,proto3" json:"current,omitempty"`
|
Current int64 `protobuf:"varint,4,opt,name=current,proto3" json:"current,omitempty"`
|
||||||
Total int64 `protobuf:"varint,5,opt,name=total,proto3" json:"total,omitempty"`
|
Total int64 `protobuf:"varint,5,opt,name=total,proto3" json:"total,omitempty"`
|
||||||
Timestamp time.Time `protobuf:"bytes,6,opt,name=timestamp,stdtime" json:"timestamp"`
|
// TODO: add started, completed
|
||||||
|
Timestamp time.Time `protobuf:"bytes,6,opt,name=timestamp,stdtime" json:"timestamp"`
|
||||||
|
Started *time.Time `protobuf:"bytes,7,opt,name=started,stdtime" json:"started,omitempty"`
|
||||||
|
Completed *time.Time `protobuf:"bytes,8,opt,name=completed,stdtime" json:"completed,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *VertexStatus) Reset() { *m = VertexStatus{} }
|
func (m *VertexStatus) Reset() { *m = VertexStatus{} }
|
||||||
|
@ -295,6 +298,20 @@ func (m *VertexStatus) GetTimestamp() time.Time {
|
||||||
return time.Time{}
|
return time.Time{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *VertexStatus) GetStarted() *time.Time {
|
||||||
|
if m != nil {
|
||||||
|
return m.Started
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *VertexStatus) GetCompleted() *time.Time {
|
||||||
|
if m != nil {
|
||||||
|
return m.Completed
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type VertexLog struct {
|
type VertexLog struct {
|
||||||
Vertex github_com_opencontainers_go_digest.Digest `protobuf:"bytes,1,opt,name=vertex,proto3,customtype=github.com/opencontainers/go-digest.Digest" json:"vertex"`
|
Vertex github_com_opencontainers_go_digest.Digest `protobuf:"bytes,1,opt,name=vertex,proto3,customtype=github.com/opencontainers/go-digest.Digest" json:"vertex"`
|
||||||
Timestamp time.Time `protobuf:"bytes,2,opt,name=timestamp,stdtime" json:"timestamp"`
|
Timestamp time.Time `protobuf:"bytes,2,opt,name=timestamp,stdtime" json:"timestamp"`
|
||||||
|
@ -870,6 +887,26 @@ func (m *VertexStatus) MarshalTo(dAtA []byte) (int, error) {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
i += n3
|
i += n3
|
||||||
|
if m.Started != nil {
|
||||||
|
dAtA[i] = 0x3a
|
||||||
|
i++
|
||||||
|
i = encodeVarintControl(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(*m.Started)))
|
||||||
|
n4, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Started, dAtA[i:])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
i += n4
|
||||||
|
}
|
||||||
|
if m.Completed != nil {
|
||||||
|
dAtA[i] = 0x42
|
||||||
|
i++
|
||||||
|
i = encodeVarintControl(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(*m.Completed)))
|
||||||
|
n5, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Completed, dAtA[i:])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
i += n5
|
||||||
|
}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -897,11 +934,11 @@ func (m *VertexLog) MarshalTo(dAtA []byte) (int, error) {
|
||||||
dAtA[i] = 0x12
|
dAtA[i] = 0x12
|
||||||
i++
|
i++
|
||||||
i = encodeVarintControl(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp)))
|
i = encodeVarintControl(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp)))
|
||||||
n4, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i:])
|
n6, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
i += n4
|
i += n6
|
||||||
if m.Stream != 0 {
|
if m.Stream != 0 {
|
||||||
dAtA[i] = 0x18
|
dAtA[i] = 0x18
|
||||||
i++
|
i++
|
||||||
|
@ -1096,6 +1133,14 @@ func (m *VertexStatus) Size() (n int) {
|
||||||
}
|
}
|
||||||
l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp)
|
l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp)
|
||||||
n += 1 + l + sovControl(uint64(l))
|
n += 1 + l + sovControl(uint64(l))
|
||||||
|
if m.Started != nil {
|
||||||
|
l = github_com_gogo_protobuf_types.SizeOfStdTime(*m.Started)
|
||||||
|
n += 1 + l + sovControl(uint64(l))
|
||||||
|
}
|
||||||
|
if m.Completed != nil {
|
||||||
|
l = github_com_gogo_protobuf_types.SizeOfStdTime(*m.Completed)
|
||||||
|
n += 1 + l + sovControl(uint64(l))
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2218,6 +2263,72 @@ func (m *VertexStatus) Unmarshal(dAtA []byte) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
|
case 7:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Started", wireType)
|
||||||
|
}
|
||||||
|
var msglen int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowControl
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
msglen |= (int(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if msglen < 0 {
|
||||||
|
return ErrInvalidLengthControl
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + msglen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
if m.Started == nil {
|
||||||
|
m.Started = new(time.Time)
|
||||||
|
}
|
||||||
|
if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(m.Started, dAtA[iNdEx:postIndex]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
iNdEx = postIndex
|
||||||
|
case 8:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Completed", wireType)
|
||||||
|
}
|
||||||
|
var msglen int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowControl
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
msglen |= (int(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if msglen < 0 {
|
||||||
|
return ErrInvalidLengthControl
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + msglen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
if m.Completed == nil {
|
||||||
|
m.Completed = new(time.Time)
|
||||||
|
}
|
||||||
|
if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(m.Completed, dAtA[iNdEx:postIndex]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipControl(dAtA[iNdEx:])
|
skippy, err := skipControl(dAtA[iNdEx:])
|
||||||
|
@ -2506,49 +2617,49 @@ var (
|
||||||
func init() { proto.RegisterFile("control.proto", fileDescriptorControl) }
|
func init() { proto.RegisterFile("control.proto", fileDescriptorControl) }
|
||||||
|
|
||||||
var fileDescriptorControl = []byte{
|
var fileDescriptorControl = []byte{
|
||||||
// 689 bytes of a gzipped FileDescriptorProto
|
// 699 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x54, 0xc1, 0x6e, 0xd3, 0x4c,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x55, 0x41, 0x6f, 0xd3, 0x30,
|
||||||
0x10, 0xfe, 0x37, 0x4e, 0x9d, 0x64, 0x92, 0x56, 0xfd, 0x57, 0x08, 0x59, 0x41, 0x24, 0xc6, 0x5c,
|
0x14, 0xc6, 0x4d, 0x97, 0xb6, 0xaf, 0xdd, 0x34, 0x2c, 0x34, 0x45, 0x45, 0xb4, 0x21, 0x5c, 0xaa,
|
||||||
0xa2, 0x4a, 0x75, 0x20, 0xc0, 0xa5, 0x48, 0x08, 0x85, 0x1c, 0x68, 0x45, 0x2f, 0xdb, 0x96, 0xbb,
|
0x49, 0x4b, 0xa1, 0xc0, 0x65, 0x48, 0x08, 0x95, 0x1e, 0xd8, 0xc4, 0x2e, 0xde, 0xc6, 0x3d, 0x4d,
|
||||||
0xe3, 0x6c, 0x5d, 0xab, 0xb6, 0x37, 0x78, 0xd7, 0x51, 0xe1, 0x29, 0x78, 0x17, 0x9e, 0x01, 0xa9,
|
0xbd, 0x2c, 0x5a, 0x12, 0x97, 0xd8, 0xa9, 0x06, 0xbf, 0x82, 0xff, 0xc2, 0x6f, 0x40, 0xda, 0x91,
|
||||||
0x47, 0xce, 0x1c, 0x0a, 0xea, 0x23, 0x70, 0xe2, 0x88, 0xbc, 0xbb, 0x76, 0x4d, 0xdb, 0x40, 0x55,
|
0x33, 0x87, 0x81, 0xf6, 0x03, 0x38, 0x73, 0x44, 0xb1, 0x9d, 0x2e, 0x6c, 0x2b, 0x8c, 0xed, 0x54,
|
||||||
0x4e, 0xd9, 0xd9, 0x7c, 0xf3, 0xed, 0x7c, 0xe3, 0xf9, 0x06, 0x56, 0x7d, 0x96, 0x88, 0x94, 0x45,
|
0x3f, 0xf7, 0xfb, 0x3e, 0xfb, 0x7d, 0x7e, 0xef, 0x05, 0x96, 0x7d, 0x96, 0x88, 0x94, 0x45, 0xee,
|
||||||
0xee, 0x3c, 0x65, 0x82, 0xe1, 0xf5, 0x98, 0x4d, 0xdf, 0xbb, 0xd3, 0x2c, 0x8c, 0x66, 0xc7, 0xa1,
|
0x34, 0x65, 0x82, 0xe1, 0xd5, 0x98, 0x8d, 0x3f, 0xb8, 0xe3, 0x2c, 0x8c, 0x26, 0x47, 0xa1, 0x70,
|
||||||
0x70, 0x17, 0x8f, 0xbb, 0x9b, 0x41, 0x28, 0x8e, 0xb2, 0xa9, 0xeb, 0xb3, 0x78, 0x18, 0xb0, 0x80,
|
0x67, 0x4f, 0xda, 0x1b, 0x41, 0x28, 0x0e, 0xb3, 0xb1, 0xeb, 0xb3, 0xb8, 0x1f, 0xb0, 0x80, 0xf5,
|
||||||
0x0d, 0x25, 0x70, 0x9a, 0x1d, 0xca, 0x48, 0x06, 0xf2, 0xa4, 0x08, 0xba, 0xfd, 0x80, 0xb1, 0x20,
|
0x25, 0x70, 0x9c, 0x1d, 0xc8, 0x48, 0x06, 0x72, 0xa5, 0x04, 0xda, 0xdd, 0x80, 0xb1, 0x20, 0xa2,
|
||||||
0xa2, 0x17, 0x28, 0x11, 0xc6, 0x94, 0x0b, 0x2f, 0x9e, 0x2b, 0x80, 0x83, 0x61, 0x7d, 0x12, 0xf2,
|
0xe7, 0x28, 0x11, 0xc6, 0x94, 0x0b, 0x2f, 0x9e, 0x2a, 0x80, 0x83, 0x61, 0x75, 0x14, 0xf2, 0xa3,
|
||||||
0xe3, 0x03, 0xee, 0x05, 0x94, 0xd0, 0x77, 0x19, 0xe5, 0xc2, 0xd9, 0x81, 0xff, 0x2b, 0x77, 0x7c,
|
0x7d, 0xee, 0x05, 0x94, 0xd0, 0xf7, 0x19, 0xe5, 0xc2, 0xd9, 0x86, 0xbb, 0xa5, 0x3d, 0x3e, 0x65,
|
||||||
0xce, 0x12, 0x4e, 0xf1, 0x33, 0x30, 0x53, 0xea, 0xb3, 0x74, 0x66, 0x21, 0xdb, 0x18, 0xb4, 0x47,
|
0x09, 0xa7, 0xf8, 0x39, 0x98, 0x29, 0xf5, 0x59, 0x3a, 0xb1, 0x90, 0x6d, 0xf4, 0x9a, 0x83, 0x07,
|
||||||
0xf7, 0xdd, 0xcb, 0xb5, 0xb9, 0x3a, 0x21, 0x07, 0x11, 0x0d, 0x76, 0x3c, 0x68, 0x57, 0xae, 0xf1,
|
0xee, 0xc5, 0xbb, 0xb9, 0x9a, 0x90, 0x83, 0x88, 0x06, 0x3b, 0x1e, 0x34, 0x4b, 0xdb, 0x78, 0x05,
|
||||||
0x1a, 0xd4, 0xb6, 0x27, 0x16, 0xb2, 0xd1, 0xa0, 0x45, 0x6a, 0xdb, 0x13, 0x6c, 0x41, 0x63, 0x37,
|
0x2a, 0x5b, 0x23, 0x0b, 0xd9, 0xa8, 0xd7, 0x20, 0x95, 0xad, 0x11, 0xb6, 0xa0, 0xb6, 0x93, 0x09,
|
||||||
0x13, 0xde, 0x34, 0xa2, 0x56, 0xcd, 0x46, 0x83, 0x26, 0x29, 0x42, 0x7c, 0x07, 0x56, 0xb6, 0x93,
|
0x6f, 0x1c, 0x51, 0xab, 0x62, 0xa3, 0x5e, 0x9d, 0x14, 0x21, 0xbe, 0x07, 0x4b, 0x5b, 0xc9, 0x3e,
|
||||||
0x03, 0x4e, 0x2d, 0x43, 0xde, 0xab, 0x00, 0x63, 0xa8, 0xef, 0x85, 0x1f, 0xa8, 0x55, 0xb7, 0xd1,
|
0xa7, 0x96, 0x21, 0xf7, 0x55, 0x80, 0x31, 0x54, 0x77, 0xc3, 0x8f, 0xd4, 0xaa, 0xda, 0xa8, 0x67,
|
||||||
0xc0, 0x20, 0xf2, 0xec, 0xbc, 0x84, 0xce, 0x1e, 0x8b, 0x16, 0x45, 0xf9, 0x78, 0x1d, 0x0c, 0x42,
|
0x10, 0xb9, 0x76, 0x5e, 0x41, 0x6b, 0x97, 0x45, 0xb3, 0xe2, 0xfa, 0x78, 0x15, 0x0c, 0x42, 0x0f,
|
||||||
0x0f, 0xf5, 0x23, 0xf9, 0x11, 0xf7, 0x00, 0x26, 0xf4, 0x30, 0x4c, 0x42, 0x11, 0xb2, 0xc4, 0xaa,
|
0xf4, 0x21, 0xf9, 0x12, 0x77, 0x00, 0x46, 0xf4, 0x20, 0x4c, 0x42, 0x11, 0xb2, 0xc4, 0xaa, 0xd8,
|
||||||
0xd9, 0xc6, 0xa0, 0x43, 0x2a, 0x37, 0xce, 0x73, 0x58, 0xd5, 0x0c, 0x5a, 0xec, 0x06, 0x18, 0x0b,
|
0x46, 0xaf, 0x45, 0x4a, 0x3b, 0xce, 0x0b, 0x58, 0xd6, 0x0a, 0x3a, 0xd9, 0x75, 0x30, 0x66, 0xe2,
|
||||||
0x71, 0xa2, 0x95, 0x5a, 0x57, 0x95, 0xbe, 0xa5, 0xa9, 0xa0, 0x27, 0x24, 0x07, 0x39, 0x0f, 0x60,
|
0x58, 0x67, 0x6a, 0x5d, 0xce, 0xf4, 0x1d, 0x4d, 0x05, 0x3d, 0x26, 0x39, 0xc8, 0x79, 0x08, 0xcb,
|
||||||
0x75, 0x4f, 0x78, 0x22, 0xe3, 0x4b, 0xdf, 0x77, 0x3e, 0x21, 0x58, 0x2b, 0x30, 0xfa, 0x85, 0xa7,
|
0xbb, 0xc2, 0x13, 0x19, 0x5f, 0x78, 0xbe, 0xf3, 0x19, 0xc1, 0x4a, 0x81, 0xd1, 0x27, 0x3c, 0x83,
|
||||||
0xd0, 0x5c, 0x48, 0x12, 0xca, 0xff, 0xfa, 0x4c, 0x89, 0xc4, 0x5b, 0xd0, 0xe4, 0x92, 0x87, 0x72,
|
0xfa, 0x4c, 0x8a, 0x50, 0xfe, 0xcf, 0x63, 0xe6, 0x48, 0xbc, 0x09, 0x75, 0x2e, 0x75, 0x28, 0x97,
|
||||||
0x29, 0xa3, 0x3d, 0xea, 0x2d, 0xcb, 0xd2, 0xef, 0x95, 0x78, 0x3c, 0x84, 0x7a, 0xc4, 0x02, 0x6e,
|
0x69, 0x34, 0x07, 0x9d, 0x45, 0x2c, 0x7d, 0xde, 0x1c, 0x8f, 0xfb, 0x50, 0x8d, 0x58, 0xc0, 0x2d,
|
||||||
0x19, 0x32, 0xef, 0xde, 0xb2, 0xbc, 0x37, 0x2c, 0x20, 0x12, 0xe8, 0x9c, 0xd6, 0xc0, 0x54, 0x77,
|
0x43, 0xf2, 0xee, 0x2f, 0xe2, 0xbd, 0x65, 0x01, 0x91, 0x40, 0xe7, 0xa4, 0x02, 0xa6, 0xda, 0xc3,
|
||||||
0x78, 0x07, 0xcc, 0x59, 0x18, 0x50, 0x2e, 0x94, 0xaa, 0xf1, 0xe8, 0xf4, 0xac, 0xff, 0xdf, 0xd7,
|
0xdb, 0x60, 0x4e, 0xc2, 0x80, 0x72, 0xa1, 0xb2, 0x1a, 0x0e, 0x4e, 0x4e, 0xbb, 0x77, 0xbe, 0x9d,
|
||||||
0xb3, 0xfe, 0x46, 0x65, 0x1a, 0xd9, 0x9c, 0x26, 0xf9, 0xf4, 0x7a, 0x61, 0x42, 0x53, 0x3e, 0x0c,
|
0x76, 0xd7, 0x4b, 0xd5, 0xc8, 0xa6, 0x34, 0xc9, 0xab, 0xd7, 0x0b, 0x13, 0x9a, 0xf2, 0x7e, 0xc0,
|
||||||
0xd8, 0xa6, 0x4a, 0x71, 0x27, 0xf2, 0x87, 0x68, 0x86, 0x9c, 0x2b, 0x4c, 0xe6, 0x99, 0x50, 0x0a,
|
0x36, 0x14, 0xc5, 0x1d, 0xc9, 0x1f, 0xa2, 0x15, 0x72, 0xad, 0x30, 0x99, 0x66, 0x42, 0x65, 0x70,
|
||||||
0x6e, 0xc9, 0xa5, 0x18, 0xf2, 0x71, 0x48, 0xbc, 0x58, 0xcd, 0x48, 0x8b, 0xc8, 0x33, 0xbe, 0x0b,
|
0x43, 0x2d, 0xa5, 0x90, 0x97, 0x43, 0xe2, 0xc5, 0xaa, 0x46, 0x1a, 0x44, 0xae, 0xf1, 0x1a, 0x98,
|
||||||
0xa6, 0xef, 0xf9, 0x47, 0x74, 0x26, 0x87, 0xa4, 0x49, 0x74, 0x84, 0xb7, 0xa0, 0xc1, 0x85, 0x97,
|
0xbe, 0xe7, 0x1f, 0xd2, 0x89, 0x2c, 0x92, 0x3a, 0xd1, 0x11, 0xde, 0x84, 0x1a, 0x17, 0x5e, 0x2a,
|
||||||
0x0a, 0x3a, 0xb3, 0x56, 0x6c, 0x34, 0x68, 0x8f, 0xba, 0xae, 0x32, 0x87, 0x5b, 0x98, 0xc3, 0xdd,
|
0xe8, 0xc4, 0x5a, 0xb2, 0x51, 0xaf, 0x39, 0x68, 0xbb, 0xaa, 0x39, 0xdc, 0xa2, 0x39, 0xdc, 0xbd,
|
||||||
0x2f, 0xcc, 0x31, 0xae, 0x7f, 0xfc, 0xd6, 0x47, 0xa4, 0x48, 0xc0, 0x2f, 0xa0, 0xe5, 0xb3, 0x78,
|
0xa2, 0x39, 0x86, 0xd5, 0x4f, 0xdf, 0xbb, 0x88, 0x14, 0x04, 0xfc, 0x12, 0x1a, 0x3e, 0x8b, 0xa7,
|
||||||
0x1e, 0xd1, 0x3c, 0xdb, 0xbc, 0x61, 0xf6, 0x45, 0x8a, 0xf3, 0x03, 0x41, 0xa7, 0xfa, 0x59, 0xae,
|
0x11, 0xcd, 0xd9, 0xe6, 0x35, 0xd9, 0xe7, 0x14, 0xe7, 0x67, 0x05, 0x5a, 0xe5, 0x67, 0xb9, 0xd4,
|
||||||
0xf8, 0x60, 0x07, 0x4c, 0xf5, 0x91, 0xa5, 0x0d, 0x6e, 0xd9, 0x14, 0xc5, 0x70, 0x6d, 0x53, 0x2c,
|
0x07, 0xdb, 0x60, 0xaa, 0x47, 0x96, 0x6d, 0x70, 0x43, 0x53, 0x94, 0xc2, 0x95, 0xa6, 0x58, 0x50,
|
||||||
0x68, 0xf8, 0x59, 0x9a, 0xd2, 0x44, 0x68, 0xeb, 0x14, 0x61, 0xee, 0x33, 0xc1, 0x84, 0x17, 0xc9,
|
0xf3, 0xb3, 0x34, 0xa5, 0x89, 0xd0, 0xad, 0x53, 0x84, 0x79, 0x9f, 0x09, 0x26, 0xbc, 0x48, 0x9a,
|
||||||
0xa6, 0x18, 0x44, 0x05, 0x78, 0x0c, 0xad, 0x72, 0x53, 0xdc, 0x40, 0x70, 0x33, 0x2f, 0x57, 0x89,
|
0x62, 0x10, 0x15, 0xe0, 0x21, 0x34, 0xe6, 0x93, 0xe2, 0x1a, 0x09, 0xd7, 0xf3, 0xeb, 0xaa, 0xa4,
|
||||||
0x2e, 0xd3, 0x9c, 0xcf, 0x08, 0x5a, 0xe5, 0x4c, 0x55, 0x14, 0xa2, 0x7f, 0x56, 0xf8, 0x5b, 0x75,
|
0xe7, 0xb4, 0xb2, 0xe1, 0xb5, 0x5b, 0x19, 0x5e, 0xff, 0x7f, 0xc3, 0xbf, 0x20, 0x68, 0xcc, 0xeb,
|
||||||
0xb5, 0x5b, 0x55, 0x97, 0x8f, 0x09, 0x17, 0x29, 0xf5, 0x62, 0xd9, 0x27, 0x83, 0xe8, 0x28, 0x77,
|
0xb9, 0xe4, 0x2e, 0xba, 0xb5, 0xbb, 0x7f, 0x38, 0x53, 0xb9, 0x99, 0x33, 0x6b, 0x60, 0x72, 0x91,
|
||||||
0x6f, 0xcc, 0x03, 0xd9, 0xa5, 0x0e, 0xc9, 0x8f, 0xa3, 0x9f, 0x08, 0x1a, 0xaf, 0xd4, 0x5a, 0xc6,
|
0x52, 0x2f, 0x96, 0x6f, 0x64, 0x10, 0x1d, 0xe5, 0x93, 0x23, 0xe6, 0x81, 0x7c, 0xa1, 0x16, 0xc9,
|
||||||
0xfb, 0xd0, 0x2a, 0x57, 0x23, 0x76, 0xae, 0x7a, 0xe8, 0xf2, 0x2e, 0xed, 0x3e, 0xfc, 0x23, 0x46,
|
0x97, 0x83, 0x5f, 0x08, 0x6a, 0xaf, 0xd5, 0x27, 0x01, 0xef, 0x41, 0x63, 0x3e, 0x96, 0xb1, 0x73,
|
||||||
0x2f, 0x83, 0xd7, 0xb0, 0x22, 0xf7, 0x0f, 0xbe, 0xc6, 0xcd, 0xd5, 0xd5, 0xd6, 0xed, 0x2f, 0xfd,
|
0xb9, 0x7f, 0x2f, 0xce, 0xf1, 0xf6, 0xa3, 0xbf, 0x62, 0xf4, 0x20, 0x7a, 0x03, 0x4b, 0x72, 0xf6,
|
||||||
0x5f, 0x33, 0xed, 0x82, 0xa9, 0x27, 0xec, 0x3a, 0x68, 0x75, 0x4d, 0x75, 0xed, 0xe5, 0x00, 0x45,
|
0xe1, 0x2b, 0x26, 0x49, 0x79, 0xac, 0xb6, 0xbb, 0x0b, 0xff, 0xd7, 0x4a, 0x3b, 0x60, 0xea, 0xea,
|
||||||
0xf6, 0x08, 0x8d, 0x3b, 0xa7, 0xe7, 0x3d, 0xf4, 0xe5, 0xbc, 0x87, 0xbe, 0x9f, 0xf7, 0xd0, 0xd4,
|
0xbe, 0x0a, 0x5a, 0x1e, 0x91, 0x6d, 0x7b, 0x31, 0x40, 0x89, 0x3d, 0x46, 0xc3, 0xd6, 0xc9, 0x59,
|
||||||
0x94, 0xbd, 0x7d, 0xf2, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x08, 0xd7, 0xbb, 0xa9, 0xa5, 0x06, 0x00,
|
0x07, 0x7d, 0x3d, 0xeb, 0xa0, 0x1f, 0x67, 0x1d, 0x34, 0x36, 0xa5, 0xb7, 0x4f, 0x7f, 0x07, 0x00,
|
||||||
0x00,
|
0x00, 0xff, 0xff, 0xea, 0xc1, 0xcc, 0x7c, 0x21, 0x07, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,10 @@ message VertexStatus {
|
||||||
string name = 3;
|
string name = 3;
|
||||||
int64 current = 4;
|
int64 current = 4;
|
||||||
int64 total = 5;
|
int64 total = 5;
|
||||||
|
// TODO: add started, completed
|
||||||
google.protobuf.Timestamp timestamp = 6 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
|
google.protobuf.Timestamp timestamp = 6 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
|
||||||
|
google.protobuf.Timestamp started = 7 [(gogoproto.stdtime) = true ];
|
||||||
|
google.protobuf.Timestamp completed = 8 [(gogoproto.stdtime) = true ];
|
||||||
}
|
}
|
||||||
|
|
||||||
message VertexLog {
|
message VertexLog {
|
||||||
|
|
|
@ -20,9 +20,11 @@ type VertexStatus struct {
|
||||||
ID string
|
ID string
|
||||||
Vertex digest.Digest
|
Vertex digest.Digest
|
||||||
Name string
|
Name string
|
||||||
Total int
|
Total int64
|
||||||
Current int
|
Current int64
|
||||||
Timestamp time.Time
|
Timestamp time.Time
|
||||||
|
Started *time.Time
|
||||||
|
Completed *time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type VertexLog struct {
|
type VertexLog struct {
|
||||||
|
|
|
@ -22,8 +22,8 @@ type SourceOp struct {
|
||||||
|
|
||||||
type ExecOp struct {
|
type ExecOp struct {
|
||||||
meta Meta
|
meta Meta
|
||||||
mounts []*mount
|
mounts []*Mount
|
||||||
root *mount
|
root *Mount
|
||||||
}
|
}
|
||||||
|
|
||||||
type Meta struct {
|
type Meta struct {
|
||||||
|
@ -32,10 +32,10 @@ type Meta struct {
|
||||||
Cwd string
|
Cwd string
|
||||||
}
|
}
|
||||||
|
|
||||||
type mount struct {
|
type Mount struct {
|
||||||
op *ExecOp
|
op *ExecOp
|
||||||
dest string
|
dest string
|
||||||
mount *mount
|
mount *Mount
|
||||||
src *SourceOp
|
src *SourceOp
|
||||||
output bool
|
output bool
|
||||||
}
|
}
|
||||||
|
@ -81,11 +81,11 @@ func Image(ref string) *SourceOp {
|
||||||
return Source("docker-image://" + ref) // controversial
|
return Source("docker-image://" + ref) // controversial
|
||||||
}
|
}
|
||||||
|
|
||||||
func newExec(meta Meta, src *SourceOp, m *mount) *ExecOp {
|
func newExec(meta Meta, src *SourceOp, m *Mount) *ExecOp {
|
||||||
exec := &ExecOp{
|
exec := &ExecOp{
|
||||||
meta: meta,
|
meta: meta,
|
||||||
mounts: []*mount{},
|
mounts: []*Mount{},
|
||||||
root: &mount{
|
root: &Mount{
|
||||||
dest: "/",
|
dest: "/",
|
||||||
src: src,
|
src: src,
|
||||||
mount: m,
|
mount: m,
|
||||||
|
@ -97,6 +97,28 @@ func newExec(meta Meta, src *SourceOp, m *mount) *ExecOp {
|
||||||
return exec
|
return exec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (eo *ExecOp) AddMount(dest string, src interface{}) *Mount {
|
||||||
|
var s *SourceOp
|
||||||
|
var m *Mount
|
||||||
|
switch v := src.(type) {
|
||||||
|
case *SourceOp:
|
||||||
|
s = v
|
||||||
|
case *Mount:
|
||||||
|
m = v
|
||||||
|
case *ExecOp:
|
||||||
|
m = v.root
|
||||||
|
default:
|
||||||
|
panic("invalid input")
|
||||||
|
}
|
||||||
|
eo.mounts = append(eo.mounts, &Mount{
|
||||||
|
dest: dest,
|
||||||
|
src: s,
|
||||||
|
mount: m,
|
||||||
|
output: true, // TODO: should be set only if something inherits
|
||||||
|
})
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
func (eo *ExecOp) Validate() error {
|
func (eo *ExecOp) Validate() error {
|
||||||
for _, m := range eo.mounts {
|
for _, m := range eo.mounts {
|
||||||
if m.src != nil {
|
if m.src != nil {
|
||||||
|
|
|
@ -6,14 +6,13 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
controlapi "github.com/tonistiigi/buildkit_poc/api/services/control"
|
controlapi "github.com/tonistiigi/buildkit_poc/api/services/control"
|
||||||
"github.com/tonistiigi/buildkit_poc/client/llb"
|
"github.com/tonistiigi/buildkit_poc/client/llb"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Client) Solve(ctx context.Context, r io.Reader) error {
|
func (c *Client) Solve(ctx context.Context, r io.Reader, statusChan chan *SolveStatus) error {
|
||||||
def, err := llb.ReadFrom(r)
|
def, err := llb.ReadFrom(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to parse input")
|
return errors.Wrap(err, "failed to parse input")
|
||||||
|
@ -52,10 +51,40 @@ func (c *Client) Solve(ctx context.Context, r io.Reader) error {
|
||||||
}
|
}
|
||||||
return errors.Wrap(err, "failed to receive status")
|
return errors.Wrap(err, "failed to receive status")
|
||||||
}
|
}
|
||||||
logrus.Debugf("status: %+v", resp)
|
s := SolveStatus{}
|
||||||
|
for _, v := range resp.Vertexes {
|
||||||
|
s.Vertexes = append(s.Vertexes, &Vertex{
|
||||||
|
Digest: v.Digest,
|
||||||
|
Inputs: v.Inputs,
|
||||||
|
Name: v.Name,
|
||||||
|
Started: v.Started,
|
||||||
|
Completed: v.Completed,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for _, v := range resp.Statuses {
|
||||||
|
s.Statuses = append(s.Statuses, &VertexStatus{
|
||||||
|
ID: v.ID,
|
||||||
|
Vertex: v.Vertex,
|
||||||
|
Name: v.Name,
|
||||||
|
Total: v.Total,
|
||||||
|
Current: v.Current,
|
||||||
|
Timestamp: v.Timestamp,
|
||||||
|
Started: v.Started,
|
||||||
|
Completed: v.Completed,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if statusChan != nil {
|
||||||
|
statusChan <- &s
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if statusChan != nil {
|
||||||
|
close(statusChan)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
return eg.Wait()
|
return eg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,13 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
"github.com/tonistiigi/buildkit_poc/client"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
var buildCommand = cli.Command{
|
var buildCommand = cli.Command{
|
||||||
|
@ -14,9 +18,29 @@ var buildCommand = cli.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
func build(clicontext *cli.Context) error {
|
func build(clicontext *cli.Context) error {
|
||||||
client, err := resolveClient(clicontext)
|
c, err := resolveClient(clicontext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return client.Solve(context.TODO(), os.Stdin)
|
|
||||||
|
ch := make(chan *client.SolveStatus)
|
||||||
|
eg, ctx := errgroup.WithContext(context.TODO()) // TODO: define appContext
|
||||||
|
|
||||||
|
eg.Go(func() error {
|
||||||
|
return c.Solve(ctx, os.Stdin, ch)
|
||||||
|
})
|
||||||
|
|
||||||
|
eg.Go(func() error {
|
||||||
|
for s := range ch {
|
||||||
|
for _, v := range s.Vertexes {
|
||||||
|
log.Print(spew.Sdump(v))
|
||||||
|
}
|
||||||
|
for _, v := range s.Statuses {
|
||||||
|
log.Print(spew.Sdump(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
return eg.Wait()
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,18 @@ func (c *Controller) Status(req *controlapi.StatusRequest, stream controlapi.Con
|
||||||
Completed: v.Completed,
|
Completed: v.Completed,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
for _, v := range ss.Statuses {
|
||||||
|
sr.Statuses = append(sr.Statuses, &controlapi.VertexStatus{
|
||||||
|
ID: v.ID,
|
||||||
|
Vertex: v.Vertex,
|
||||||
|
Name: v.Name,
|
||||||
|
Current: v.Current,
|
||||||
|
Total: v.Total,
|
||||||
|
Timestamp: v.Timestamp,
|
||||||
|
Started: v.Started,
|
||||||
|
Completed: v.Completed,
|
||||||
|
})
|
||||||
|
}
|
||||||
if err := stream.SendMsg(&sr); err != nil {
|
if err := stream.SendMsg(&sr); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,12 @@ func main() {
|
||||||
busybox := llb.Image("docker.io/library/busybox:latest")
|
busybox := llb.Image("docker.io/library/busybox:latest")
|
||||||
mod1 := busybox.Run(llb.Meta{Args: []string{"/bin/sleep", "1"}, Cwd: "/"})
|
mod1 := busybox.Run(llb.Meta{Args: []string{"/bin/sleep", "1"}, Cwd: "/"})
|
||||||
mod2 := mod1.Run(llb.Meta{Args: []string{"/bin/sh", "-c", "echo foo > /bar"}, Cwd: "/"})
|
mod2 := mod1.Run(llb.Meta{Args: []string{"/bin/sh", "-c", "echo foo > /bar"}, Cwd: "/"})
|
||||||
mod3 := mod2.Run(llb.Meta{Args: []string{"/bin/ls", "-l", "/"}, Cwd: "/"})
|
alpine := llb.Image("docker.io/library/alpine:latest")
|
||||||
|
mod3 := mod2.Run(llb.Meta{Args: []string{"/bin/cp", "-a", "/alpine/etc/passwd", "baz"}, Cwd: "/"})
|
||||||
|
mod3.AddMount("/alpine", alpine)
|
||||||
|
mod4 := mod3.Run(llb.Meta{Args: []string{"/bin/ls", "-l", "/"}, Cwd: "/"})
|
||||||
|
|
||||||
res := mod3
|
res := mod4
|
||||||
dt, err := res.Marshal()
|
dt, err := res.Marshal()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package solver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@ func (j *job) pipe(ctx context.Context, ch chan *client.SolveStatus) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
p, err := pr.Read(ctx) // add cancelling
|
p, err := pr.Read(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -105,6 +106,24 @@ func (j *job) pipe(ctx context.Context, ch chan *client.SolveStatus) error {
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
case ch <- ss:
|
case ch <- ss:
|
||||||
}
|
}
|
||||||
|
case progress.Status:
|
||||||
|
i := strings.Index(p.ID, ".")
|
||||||
|
vs := &client.VertexStatus{
|
||||||
|
ID: p.ID[i+1:],
|
||||||
|
Vertex: digest.Digest(p.ID[:i]), // TODO: this needs to be handled better
|
||||||
|
Name: v.Action,
|
||||||
|
Total: int64(v.Total),
|
||||||
|
Current: int64(v.Current),
|
||||||
|
Timestamp: p.Timestamp,
|
||||||
|
Started: v.Started,
|
||||||
|
Completed: v.Completed,
|
||||||
|
}
|
||||||
|
ss := &client.SolveStatus{Statuses: []*client.VertexStatus{vs}}
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
case ch <- ss:
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,12 +125,14 @@ func (g *opVertex) solve(ctx context.Context, opt Opt) (retErr error) {
|
||||||
eg, ctx := errgroup.WithContext(ctx)
|
eg, ctx := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
for _, in := range g.inputs {
|
for _, in := range g.inputs {
|
||||||
eg.Go(func() error {
|
func(in *opVertex) {
|
||||||
if err := in.solve(ctx, opt); err != nil {
|
eg.Go(func() error {
|
||||||
return err
|
if err := in.solve(ctx, opt); err != nil {
|
||||||
}
|
return err
|
||||||
return nil
|
}
|
||||||
})
|
return nil
|
||||||
|
})
|
||||||
|
}(in)
|
||||||
}
|
}
|
||||||
err := eg.Wait()
|
err := eg.Wait()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
"github.com/containerd/containerd/images"
|
"github.com/containerd/containerd/images"
|
||||||
|
@ -17,6 +19,7 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/tonistiigi/buildkit_poc/cache"
|
"github.com/tonistiigi/buildkit_poc/cache"
|
||||||
"github.com/tonistiigi/buildkit_poc/source"
|
"github.com/tonistiigi/buildkit_poc/source"
|
||||||
|
"github.com/tonistiigi/buildkit_poc/util/progress"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: break apart containerd specifics like contentstore so the resolver
|
// TODO: break apart containerd specifics like contentstore so the resolver
|
||||||
|
@ -67,12 +70,21 @@ func (is *imageSource) Pull(ctx context.Context, id source.Identifier) (cache.Im
|
||||||
return nil, errors.New("invalid identifier")
|
return nil, errors.New("invalid identifier")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resolveProgressDone := oneOffProgress(ctx, "resolve "+imageIdentifier.Reference.String())
|
||||||
ref, desc, err := is.resolver.Resolve(ctx, imageIdentifier.Reference.String())
|
ref, desc, err := is.resolver.Resolve(ctx, imageIdentifier.Reference.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, resolveProgressDone(err)
|
||||||
}
|
}
|
||||||
|
resolveProgressDone(nil)
|
||||||
|
|
||||||
|
ongoing := newJobs(ref)
|
||||||
|
pctx, stopProgress := context.WithCancel(ctx)
|
||||||
|
|
||||||
|
go showProgress(pctx, ongoing, is.ContentStore)
|
||||||
|
|
||||||
fetcher, err := is.resolver.Fetcher(ctx, ref)
|
fetcher, err := is.resolver.Fetcher(ctx, ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
stopProgress()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,17 +92,25 @@ func (is *imageSource) Pull(ctx context.Context, id source.Identifier) (cache.Im
|
||||||
// and snapshots as 1) buildkit shouldn't have a dependency on contentstore
|
// and snapshots as 1) buildkit shouldn't have a dependency on contentstore
|
||||||
// or 2) cachemanager should manage the contentstore
|
// or 2) cachemanager should manage the contentstore
|
||||||
handlers := []images.Handler{
|
handlers := []images.Handler{
|
||||||
|
images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
||||||
|
ongoing.add(ctx, desc)
|
||||||
|
return nil, nil
|
||||||
|
}),
|
||||||
remotes.FetchHandler(is.ContentStore, fetcher),
|
remotes.FetchHandler(is.ContentStore, fetcher),
|
||||||
images.ChildrenHandler(is.ContentStore),
|
images.ChildrenHandler(is.ContentStore),
|
||||||
}
|
}
|
||||||
if err := images.Dispatch(ctx, images.Handlers(handlers...), desc); err != nil {
|
if err := images.Dispatch(ctx, images.Handlers(handlers...), desc); err != nil {
|
||||||
|
stopProgress()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
stopProgress()
|
||||||
|
|
||||||
|
unpackProgressDone := oneOffProgress(ctx, "unpacking "+imageIdentifier.Reference.String())
|
||||||
chainid, err := is.unpack(ctx, desc)
|
chainid, err := is.unpack(ctx, desc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, unpackProgressDone(err)
|
||||||
}
|
}
|
||||||
|
unpackProgressDone(nil)
|
||||||
|
|
||||||
return is.CacheAccessor.Get(ctx, chainid)
|
return is.CacheAccessor.Get(ctx, chainid)
|
||||||
}
|
}
|
||||||
|
@ -153,3 +173,181 @@ func getLayers(ctx context.Context, provider content.Provider, desc ocispec.Desc
|
||||||
}
|
}
|
||||||
return layers, nil
|
return layers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func showProgress(ctx context.Context, ongoing *jobs, cs content.Store) {
|
||||||
|
var (
|
||||||
|
ticker = time.NewTicker(100 * time.Millisecond)
|
||||||
|
// fw = progress.NewWriter(out)
|
||||||
|
statuses = map[string]statusInfo{}
|
||||||
|
done bool
|
||||||
|
)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
case <-ctx.Done():
|
||||||
|
done = true
|
||||||
|
}
|
||||||
|
// fw.Flush()
|
||||||
|
|
||||||
|
// tw := tabwriter.NewWriter(fw, 1, 8, 1, ' ', 0)
|
||||||
|
|
||||||
|
resolved := "resolved"
|
||||||
|
if !ongoing.isResolved() {
|
||||||
|
resolved = "resolving"
|
||||||
|
}
|
||||||
|
statuses[ongoing.name] = statusInfo{
|
||||||
|
Ref: ongoing.name,
|
||||||
|
Status: resolved,
|
||||||
|
}
|
||||||
|
// keys := []string{ongoing.name}
|
||||||
|
|
||||||
|
actives := make(map[string]statusInfo)
|
||||||
|
|
||||||
|
if !done {
|
||||||
|
active, err := cs.Status(ctx, "")
|
||||||
|
if err != nil {
|
||||||
|
// log.G(ctx).WithError(err).Error("active check failed")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// update status of active entries!
|
||||||
|
for _, active := range active {
|
||||||
|
actives[active.Ref] = statusInfo{
|
||||||
|
Ref: active.Ref,
|
||||||
|
Status: "downloading",
|
||||||
|
Offset: active.Offset,
|
||||||
|
Total: active.Total,
|
||||||
|
StartedAt: active.StartedAt,
|
||||||
|
UpdatedAt: active.UpdatedAt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now, update the items in jobs that are not in active
|
||||||
|
for _, j := range ongoing.jobs() {
|
||||||
|
refKey := remotes.MakeRefKey(ctx, j.Descriptor)
|
||||||
|
if a, ok := actives[refKey]; ok {
|
||||||
|
j.Write(progress.Status{
|
||||||
|
Action: a.Status,
|
||||||
|
Total: int(a.Total),
|
||||||
|
Current: int(a.Offset),
|
||||||
|
Started: &j.started,
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !j.done {
|
||||||
|
info, err := cs.Info(ctx, j.Digest)
|
||||||
|
if err != nil {
|
||||||
|
if content.IsNotFound(err) {
|
||||||
|
j.Write(progress.Status{
|
||||||
|
Action: "waiting",
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
j.done = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if done || j.done {
|
||||||
|
j.Write(progress.Status{
|
||||||
|
Action: "done",
|
||||||
|
Current: int(info.Size),
|
||||||
|
Total: int(info.Size),
|
||||||
|
Completed: &info.CommittedAt,
|
||||||
|
Started: &j.started,
|
||||||
|
})
|
||||||
|
j.Done()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if done {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// jobs provides a way of identifying the download keys for a particular task
|
||||||
|
// encountering during the pull walk.
|
||||||
|
//
|
||||||
|
// This is very minimal and will probably be replaced with something more
|
||||||
|
// featured.
|
||||||
|
type jobs struct {
|
||||||
|
name string
|
||||||
|
added map[digest.Digest]job
|
||||||
|
mu sync.Mutex
|
||||||
|
resolved bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type job struct {
|
||||||
|
ocispec.Descriptor
|
||||||
|
progress.ProgressWriter
|
||||||
|
done bool
|
||||||
|
started time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func newJobs(name string) *jobs {
|
||||||
|
return &jobs{
|
||||||
|
name: name,
|
||||||
|
added: make(map[digest.Digest]job),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j *jobs) add(ctx context.Context, desc ocispec.Descriptor) {
|
||||||
|
j.mu.Lock()
|
||||||
|
defer j.mu.Unlock()
|
||||||
|
|
||||||
|
if _, ok := j.added[desc.Digest]; ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pw, _, _ := progress.FromContext(ctx, desc.Digest.String())
|
||||||
|
j.added[desc.Digest] = job{
|
||||||
|
Descriptor: desc,
|
||||||
|
ProgressWriter: pw,
|
||||||
|
started: time.Now(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j *jobs) jobs() []job {
|
||||||
|
j.mu.Lock()
|
||||||
|
defer j.mu.Unlock()
|
||||||
|
|
||||||
|
descs := make([]job, 0, len(j.added))
|
||||||
|
for _, j := range j.added {
|
||||||
|
descs = append(descs, j)
|
||||||
|
}
|
||||||
|
return descs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j *jobs) isResolved() bool {
|
||||||
|
j.mu.Lock()
|
||||||
|
defer j.mu.Unlock()
|
||||||
|
return j.resolved
|
||||||
|
}
|
||||||
|
|
||||||
|
type statusInfo struct {
|
||||||
|
Ref string
|
||||||
|
Status string
|
||||||
|
Offset int64
|
||||||
|
Total int64
|
||||||
|
StartedAt time.Time
|
||||||
|
UpdatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func oneOffProgress(ctx context.Context, id string) func(err error) error {
|
||||||
|
pw, _, _ := progress.FromContext(ctx, id)
|
||||||
|
now := time.Now()
|
||||||
|
st := progress.Status{
|
||||||
|
Started: &now,
|
||||||
|
}
|
||||||
|
pw.Write(st)
|
||||||
|
return func(err error) error {
|
||||||
|
// TODO: set error on status
|
||||||
|
now := time.Now()
|
||||||
|
st.Completed = &now
|
||||||
|
pw.Write(st)
|
||||||
|
pw.Done()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -47,9 +47,11 @@ type Progress struct {
|
||||||
|
|
||||||
type Status struct {
|
type Status struct {
|
||||||
// ...progress of an action
|
// ...progress of an action
|
||||||
Action string
|
Action string
|
||||||
Current int
|
Current int
|
||||||
Total int
|
Total int
|
||||||
|
Started *time.Time
|
||||||
|
Completed *time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type progressReader struct {
|
type progressReader struct {
|
||||||
|
|
Loading…
Reference in New Issue