snapshot: replace "readonly" with View snapshot type
What started out as a simple PR to remove the "Readonly" column became an adventure to add a proper type for a "View" snapshot. The short story here is that we now get the following output: ``` $ sudo ctr snapshot ls ID PARENT KIND sha256:08c2295a7fa5c220b0f60c994362d290429ad92f6e0235509db91582809442f3 Committed testing4 sha256:08c2295a7fa5c220b0f60c994362d290429ad92f6e0235509db91582809442f3 Active ``` In pursuing this output, it was found that the idea of having "readonly" as an attribute on all snapshots was redundant. For committed, they are always readonly, as they are not accessible without an active snapshot. For active snapshots that were views, we'd have to check the type before interpreting "readonly". With this PR, this is baked fully into the kind of snapshot. When `Snapshotter.View` is called, the kind of snapshot is `KindView`, and the storage system reflects this end to end. Unfortunately, this will break existing users. There is no migration, so they will have to wipe `/var/lib/containerd` and recreate everything. However, this is deemed worthwhile at this point, as we won't have to judge validity of the "Readonly" field when new snapshot types are added. Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
parent
a9ab45fb77
commit
863784f991
@ -58,17 +58,23 @@ const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
|||||||
type Kind int32
|
type Kind int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
KindActive Kind = 0
|
KindUnknown Kind = 0
|
||||||
KindCommitted Kind = 1
|
KindView Kind = 1
|
||||||
|
KindActive Kind = 2
|
||||||
|
KindCommitted Kind = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
var Kind_name = map[int32]string{
|
var Kind_name = map[int32]string{
|
||||||
0: "ACTIVE",
|
0: "UNKNOWN",
|
||||||
1: "COMMITTED",
|
1: "VIEW",
|
||||||
|
2: "ACTIVE",
|
||||||
|
3: "COMMITTED",
|
||||||
}
|
}
|
||||||
var Kind_value = map[string]int32{
|
var Kind_value = map[string]int32{
|
||||||
"ACTIVE": 0,
|
"UNKNOWN": 0,
|
||||||
"COMMITTED": 1,
|
"VIEW": 1,
|
||||||
|
"ACTIVE": 2,
|
||||||
|
"COMMITTED": 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x Kind) String() string {
|
func (x Kind) String() string {
|
||||||
@ -158,10 +164,9 @@ func (*StatSnapshotRequest) ProtoMessage() {}
|
|||||||
func (*StatSnapshotRequest) Descriptor() ([]byte, []int) { return fileDescriptorSnapshots, []int{8} }
|
func (*StatSnapshotRequest) Descriptor() ([]byte, []int) { return fileDescriptorSnapshots, []int{8} }
|
||||||
|
|
||||||
type Info struct {
|
type Info struct {
|
||||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
Parent string `protobuf:"bytes,2,opt,name=parent,proto3" json:"parent,omitempty"`
|
Parent string `protobuf:"bytes,2,opt,name=parent,proto3" json:"parent,omitempty"`
|
||||||
Kind Kind `protobuf:"varint,3,opt,name=kind,proto3,enum=containerd.services.snapshots.v1.Kind" json:"kind,omitempty"`
|
Kind Kind `protobuf:"varint,3,opt,name=kind,proto3,enum=containerd.services.snapshots.v1.Kind" json:"kind,omitempty"`
|
||||||
Readonly bool `protobuf:"varint,4,opt,name=readonly,proto3" json:"readonly,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Info) Reset() { *m = Info{} }
|
func (m *Info) Reset() { *m = Info{} }
|
||||||
@ -880,16 +885,6 @@ func (m *Info) MarshalTo(dAtA []byte) (int, error) {
|
|||||||
i++
|
i++
|
||||||
i = encodeVarintSnapshots(dAtA, i, uint64(m.Kind))
|
i = encodeVarintSnapshots(dAtA, i, uint64(m.Kind))
|
||||||
}
|
}
|
||||||
if m.Readonly {
|
|
||||||
dAtA[i] = 0x20
|
|
||||||
i++
|
|
||||||
if m.Readonly {
|
|
||||||
dAtA[i] = 1
|
|
||||||
} else {
|
|
||||||
dAtA[i] = 0
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1204,9 +1199,6 @@ func (m *Info) Size() (n int) {
|
|||||||
if m.Kind != 0 {
|
if m.Kind != 0 {
|
||||||
n += 1 + sovSnapshots(uint64(m.Kind))
|
n += 1 + sovSnapshots(uint64(m.Kind))
|
||||||
}
|
}
|
||||||
if m.Readonly {
|
|
||||||
n += 2
|
|
||||||
}
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1386,7 +1378,6 @@ func (this *Info) String() string {
|
|||||||
`Name:` + fmt.Sprintf("%v", this.Name) + `,`,
|
`Name:` + fmt.Sprintf("%v", this.Name) + `,`,
|
||||||
`Parent:` + fmt.Sprintf("%v", this.Parent) + `,`,
|
`Parent:` + fmt.Sprintf("%v", this.Parent) + `,`,
|
||||||
`Kind:` + fmt.Sprintf("%v", this.Kind) + `,`,
|
`Kind:` + fmt.Sprintf("%v", this.Kind) + `,`,
|
||||||
`Readonly:` + fmt.Sprintf("%v", this.Readonly) + `,`,
|
|
||||||
`}`,
|
`}`,
|
||||||
}, "")
|
}, "")
|
||||||
return s
|
return s
|
||||||
@ -2535,26 +2526,6 @@ func (m *Info) Unmarshal(dAtA []byte) error {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 4:
|
|
||||||
if wireType != 0 {
|
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field Readonly", wireType)
|
|
||||||
}
|
|
||||||
var v int
|
|
||||||
for shift := uint(0); ; shift += 7 {
|
|
||||||
if shift >= 64 {
|
|
||||||
return ErrIntOverflowSnapshots
|
|
||||||
}
|
|
||||||
if iNdEx >= l {
|
|
||||||
return io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
b := dAtA[iNdEx]
|
|
||||||
iNdEx++
|
|
||||||
v |= (int(b) & 0x7F) << shift
|
|
||||||
if b < 0x80 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m.Readonly = bool(v != 0)
|
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipSnapshots(dAtA[iNdEx:])
|
skippy, err := skipSnapshots(dAtA[iNdEx:])
|
||||||
@ -3122,52 +3093,53 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fileDescriptorSnapshots = []byte{
|
var fileDescriptorSnapshots = []byte{
|
||||||
// 738 bytes of a gzipped FileDescriptorProto
|
// 766 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x5d, 0x4f, 0xd4, 0x4c,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xcd, 0x4e, 0xdb, 0x4a,
|
||||||
0x18, 0xdd, 0xd2, 0xbe, 0x0b, 0x3c, 0x7c, 0x84, 0x77, 0x58, 0x60, 0xd3, 0x37, 0xe9, 0xdb, 0xf4,
|
0x18, 0x8d, 0xb1, 0x6f, 0xb8, 0x7c, 0x01, 0x6e, 0xee, 0x10, 0x42, 0xe4, 0x7b, 0xe5, 0x6b, 0x79,
|
||||||
0xc2, 0x10, 0x2f, 0x5a, 0xc0, 0x08, 0x28, 0x37, 0xb2, 0x2b, 0x31, 0x2b, 0x12, 0x4d, 0x41, 0x22,
|
0x71, 0x85, 0xba, 0xb0, 0x81, 0xaa, 0x40, 0xcb, 0xa6, 0x24, 0x8d, 0xaa, 0x94, 0x02, 0x95, 0xf9,
|
||||||
0xc6, 0xc4, 0x94, 0xed, 0xb0, 0x34, 0xd0, 0x4e, 0xed, 0xcc, 0xae, 0x59, 0x2f, 0x8c, 0xde, 0x19,
|
0x2b, 0x55, 0xa5, 0xca, 0x24, 0x43, 0xb0, 0xd2, 0xcc, 0xa4, 0xf1, 0x24, 0x28, 0x5d, 0x54, 0xed,
|
||||||
0xfe, 0x03, 0x57, 0xfa, 0x2b, 0xfc, 0x05, 0x5c, 0x7a, 0xe9, 0x95, 0x91, 0xfd, 0x25, 0xa6, 0xd3,
|
0x0e, 0xe5, 0x1d, 0xb2, 0x6a, 0x9f, 0xa2, 0x4f, 0xc0, 0xb2, 0xcb, 0xae, 0xaa, 0x92, 0x27, 0xa9,
|
||||||
0xd9, 0x0f, 0xa4, 0x66, 0xcb, 0x82, 0x77, 0xcf, 0x7c, 0x9c, 0xf3, 0x9c, 0x9d, 0xd3, 0x39, 0xb3,
|
0x66, 0xec, 0xfc, 0x50, 0x52, 0xc5, 0x04, 0xba, 0xfb, 0x3c, 0xdf, 0x9c, 0xf3, 0x9d, 0xcc, 0xb1,
|
||||||
0x50, 0xa9, 0x79, 0xec, 0xb0, 0xbe, 0x6f, 0x56, 0x89, 0x6f, 0x55, 0x49, 0xc0, 0x1c, 0x2f, 0xc0,
|
0xcf, 0x04, 0x72, 0x45, 0x97, 0x9d, 0xd4, 0x8e, 0xcc, 0x3c, 0x2d, 0x5b, 0x79, 0x4a, 0x98, 0xe3,
|
||||||
0x91, 0xdb, 0x5b, 0x3a, 0xa1, 0x67, 0x51, 0x1c, 0x35, 0xbc, 0x2a, 0xa6, 0x16, 0x0d, 0x9c, 0x90,
|
0x12, 0x5c, 0x2d, 0xf4, 0x97, 0x4e, 0xc5, 0xb5, 0x3c, 0x5c, 0xad, 0xbb, 0x79, 0xec, 0x59, 0x1e,
|
||||||
0x1e, 0x12, 0x66, 0x35, 0x16, 0x3b, 0x35, 0x35, 0xc3, 0x88, 0x30, 0x82, 0xf4, 0x2e, 0xc8, 0x6c,
|
0x71, 0x2a, 0xde, 0x09, 0x65, 0x56, 0x7d, 0xb1, 0x5b, 0x7b, 0x66, 0xa5, 0x4a, 0x19, 0x45, 0x7a,
|
||||||
0x03, 0xcc, 0xee, 0xa6, 0xc6, 0xa2, 0x5a, 0xa8, 0x91, 0x1a, 0xe1, 0x9b, 0xad, 0xb8, 0x4a, 0x70,
|
0x0f, 0x64, 0x76, 0x00, 0x66, 0x6f, 0x53, 0x7d, 0x51, 0x4d, 0x14, 0x69, 0x91, 0x8a, 0xcd, 0x16,
|
||||||
0xea, 0x7f, 0x35, 0x42, 0x6a, 0xc7, 0xd8, 0xe2, 0xa3, 0xfd, 0xfa, 0x81, 0x85, 0xfd, 0x90, 0x35,
|
0xaf, 0x7c, 0x9c, 0xfa, 0x4f, 0x91, 0xd2, 0xe2, 0x6b, 0x6c, 0x89, 0xa7, 0xa3, 0xda, 0xb1, 0x85,
|
||||||
0xc5, 0xe2, 0x72, 0x26, 0x7d, 0xac, 0x19, 0x62, 0x6a, 0xf9, 0xa4, 0x1e, 0xb0, 0x04, 0x67, 0xb8,
|
0xcb, 0x15, 0xd6, 0x08, 0x9a, 0xcb, 0xa1, 0xf4, 0xb1, 0x46, 0x05, 0x7b, 0x56, 0x99, 0xd6, 0x08,
|
||||||
0x30, 0xfb, 0x2c, 0xc2, 0xa1, 0x13, 0xe1, 0x6d, 0xa1, 0xc0, 0xc6, 0x6f, 0xea, 0x98, 0x32, 0xa4,
|
0xf3, 0x71, 0x46, 0x01, 0x92, 0xcf, 0xaa, 0xb8, 0xe2, 0x54, 0xf1, 0x4e, 0xa0, 0xc0, 0xc6, 0x6f,
|
||||||
0xc3, 0x58, 0x5b, 0x14, 0xc3, 0x51, 0x51, 0xd2, 0xa5, 0xf9, 0x51, 0xbb, 0x77, 0x0a, 0x4d, 0x81,
|
0x6a, 0xd8, 0x63, 0x48, 0x87, 0x58, 0x47, 0x14, 0xc3, 0xd5, 0x94, 0xa4, 0x4b, 0xf3, 0x13, 0x76,
|
||||||
0x7c, 0x84, 0x9b, 0xc5, 0x21, 0xbe, 0x12, 0x97, 0x68, 0x16, 0xf2, 0x31, 0x55, 0xc0, 0x8a, 0x32,
|
0xff, 0x12, 0x8a, 0x83, 0x5c, 0xc2, 0x8d, 0xd4, 0x98, 0xe8, 0xf0, 0x12, 0x25, 0x21, 0xca, 0xa9,
|
||||||
0x9f, 0x14, 0x23, 0xe3, 0x31, 0xcc, 0x5d, 0xea, 0x42, 0x43, 0x12, 0x50, 0x8c, 0x2c, 0xc8, 0x73,
|
0x08, 0x4b, 0xc9, 0x62, 0x31, 0x78, 0x32, 0x9e, 0xc0, 0xdc, 0x95, 0x29, 0x5e, 0x85, 0x12, 0x0f,
|
||||||
0x3d, 0xb4, 0x28, 0xe9, 0xf2, 0xfc, 0xd8, 0xd2, 0x9c, 0xd9, 0x73, 0x3c, 0x5c, 0xaf, 0xb9, 0x15,
|
0x23, 0x0b, 0xa2, 0x42, 0x8f, 0x97, 0x92, 0x74, 0x79, 0x3e, 0xb6, 0x34, 0x67, 0xf6, 0x1d, 0x8f,
|
||||||
0xaf, 0xdb, 0x62, 0x9b, 0xe1, 0xc0, 0xf4, 0xae, 0x87, 0xdf, 0xfe, 0x4d, 0xb9, 0x8f, 0xa0, 0x70,
|
0xd0, 0x6b, 0x6e, 0xf2, 0xbe, 0x1d, 0x6c, 0x33, 0x1c, 0x98, 0xd9, 0x77, 0xf1, 0xe9, 0xef, 0x94,
|
||||||
0xb1, 0xc5, 0xa0, 0x5a, 0xcb, 0x30, 0xc1, 0x27, 0xe8, 0x35, 0x54, 0x1a, 0xeb, 0x30, 0xd9, 0x26,
|
0xfb, 0x18, 0x12, 0x97, 0x47, 0x8c, 0xaa, 0x35, 0x03, 0x53, 0x62, 0xc1, 0xbb, 0x81, 0x4a, 0x63,
|
||||||
0x19, 0x54, 0xc7, 0x26, 0xcc, 0xd8, 0xd8, 0x27, 0x8d, 0x9b, 0x30, 0xd9, 0x78, 0x0d, 0x33, 0x65,
|
0x1d, 0xa6, 0x3b, 0x24, 0xa3, 0xea, 0xd8, 0x80, 0x59, 0x1b, 0x97, 0x69, 0xfd, 0x36, 0x4c, 0x36,
|
||||||
0xe2, 0xfb, 0x1e, 0xbb, 0x3a, 0x19, 0x02, 0x25, 0x70, 0x7c, 0x2c, 0xd8, 0x78, 0xdd, 0x6e, 0x20,
|
0x5e, 0xc1, 0x6c, 0x86, 0x96, 0xcb, 0x2e, 0xbb, 0x3e, 0x19, 0x02, 0x85, 0x38, 0x65, 0x1c, 0xb0,
|
||||||
0x77, 0x1b, 0x54, 0x60, 0x7a, 0x9b, 0x39, 0xec, 0x26, 0xb4, 0x9e, 0x48, 0xa0, 0x54, 0x82, 0x03,
|
0x89, 0xba, 0x33, 0x40, 0xee, 0x0d, 0xc8, 0xc1, 0xcc, 0x0e, 0x73, 0xd8, 0x6d, 0x68, 0x25, 0xa0,
|
||||||
0xd2, 0xe9, 0x2c, 0xf5, 0x74, 0xee, 0xda, 0x3f, 0xd4, 0x6b, 0x3f, 0xba, 0x0f, 0xca, 0x91, 0x17,
|
0xe4, 0xc8, 0x31, 0xed, 0x0e, 0x96, 0xfa, 0x06, 0xf7, 0xdc, 0x1f, 0xeb, 0x77, 0x1f, 0x3d, 0x00,
|
||||||
0xb8, 0x5c, 0xd2, 0xe4, 0xd2, 0x2d, 0xb3, 0xdf, 0x7d, 0x35, 0x37, 0xbd, 0xc0, 0xb5, 0x39, 0x06,
|
0xa5, 0xe4, 0x92, 0x82, 0x50, 0x34, 0xbd, 0xf4, 0xbf, 0x39, 0xec, 0x73, 0x35, 0x37, 0x5c, 0x52,
|
||||||
0xa9, 0x30, 0x12, 0x61, 0xc7, 0x25, 0xc1, 0x71, 0xb3, 0xa8, 0xe8, 0xd2, 0xfc, 0x88, 0xdd, 0x19,
|
0xb0, 0x05, 0xc6, 0x78, 0x0e, 0x89, 0xcb, 0xd2, 0x03, 0xc7, 0x1e, 0x82, 0xe2, 0x92, 0x63, 0x2a,
|
||||||
0x1b, 0x2f, 0xa0, 0x70, 0xf1, 0x77, 0x09, 0x3b, 0x1f, 0x80, 0xe2, 0x05, 0x07, 0x84, 0x6b, 0x1b,
|
0xe6, 0xc7, 0xc2, 0x70, 0x72, 0xd5, 0x69, 0xe5, 0xfc, 0xdb, 0x7f, 0x11, 0x5b, 0x20, 0x8d, 0x55,
|
||||||
0xcb, 0xd2, 0x2f, 0xfe, 0x45, 0x25, 0xe5, 0xec, 0xc7, 0xff, 0x39, 0x9b, 0x23, 0x8d, 0x55, 0x28,
|
0x48, 0x3c, 0x75, 0xbd, 0x2e, 0x73, 0xf8, 0x37, 0xca, 0x38, 0x84, 0xd9, 0x9f, 0x90, 0x57, 0x44,
|
||||||
0x3c, 0xf1, 0x68, 0x87, 0x39, 0xfb, 0xe7, 0x66, 0xec, 0xc1, 0xcc, 0x6f, 0xc8, 0x4b, 0xa2, 0xe4,
|
0xc9, 0x23, 0x8a, 0x4a, 0xc3, 0xe4, 0x9e, 0xe7, 0x14, 0xf1, 0x4d, 0x2c, 0x5a, 0x83, 0xa9, 0x80,
|
||||||
0x01, 0x45, 0x95, 0x60, 0xfc, 0x39, 0x75, 0x6a, 0xf8, 0x3a, 0xfe, 0xad, 0xc1, 0x84, 0xe0, 0x10,
|
0x23, 0x90, 0x85, 0x40, 0xf1, 0xdc, 0xb7, 0xbe, 0x57, 0xb2, 0x2d, 0x6a, 0xee, 0x95, 0x4b, 0x68,
|
||||||
0xb2, 0x10, 0x28, 0xd4, 0x7b, 0x97, 0xf8, 0x28, 0xdb, 0xbc, 0x8e, 0x7d, 0xf4, 0x02, 0xe2, 0x62,
|
0x01, 0x7b, 0x02, 0x29, 0xdb, 0xc1, 0xd3, 0x9d, 0x33, 0x09, 0x14, 0x7e, 0xfc, 0xe8, 0x5f, 0x18,
|
||||||
0xca, 0x91, 0xb2, 0x2d, 0x46, 0xb7, 0x6d, 0x50, 0x36, 0x13, 0x4f, 0xf2, 0xeb, 0xe5, 0x9d, 0xca,
|
0xdf, 0xdb, 0xda, 0xd8, 0xda, 0x3e, 0xd8, 0x8a, 0x47, 0xd4, 0xbf, 0x9a, 0x2d, 0x3d, 0xc6, 0x97,
|
||||||
0xee, 0xc6, 0x54, 0x4e, 0x9d, 0x3c, 0x39, 0xd5, 0x21, 0x9e, 0x5d, 0xaf, 0x32, 0xaf, 0x81, 0x91,
|
0xf7, 0x48, 0x89, 0xd0, 0x53, 0x82, 0x92, 0xa0, 0xec, 0xe7, 0xb2, 0x07, 0x71, 0x49, 0x9d, 0x6c,
|
||||||
0x0e, 0xa3, 0xe5, 0xa7, 0x5b, 0x5b, 0x95, 0x9d, 0x9d, 0x8d, 0x87, 0x53, 0x92, 0xfa, 0xef, 0xc9,
|
0xb6, 0xf4, 0x3f, 0x79, 0x8b, 0x7f, 0xe0, 0x48, 0x85, 0xe8, 0x7a, 0x66, 0x37, 0xb7, 0x9f, 0x8d,
|
||||||
0xa9, 0x3e, 0x11, 0x2f, 0x27, 0x5f, 0x38, 0xc3, 0xae, 0x3a, 0xfe, 0xe9, 0xb3, 0x96, 0xfb, 0xfa,
|
0x8f, 0xa9, 0xd3, 0xcd, 0x96, 0x0e, 0xbc, 0xb3, 0x9e, 0x67, 0x6e, 0x1d, 0x23, 0x1d, 0x26, 0x32,
|
||||||
0x45, 0xe3, 0x5c, 0x4b, 0x1f, 0x87, 0x61, 0xb4, 0x73, 0x58, 0xe8, 0x3d, 0x0c, 0x8b, 0x5c, 0x43,
|
0xdb, 0x9b, 0x9b, 0xb9, 0xdd, 0xdd, 0xec, 0xa3, 0xb8, 0xac, 0xfe, 0xdd, 0x6c, 0xe9, 0x53, 0xbc,
|
||||||
0xab, 0xfd, 0x4f, 0x28, 0x3d, 0x68, 0xd5, 0x7b, 0x03, 0x20, 0xc5, 0x69, 0xd4, 0x41, 0x89, 0x83,
|
0xed, 0xbf, 0xfb, 0x0c, 0x17, 0xd4, 0xc9, 0xb3, 0x8f, 0x5a, 0xe4, 0xf3, 0x27, 0x4d, 0x28, 0x58,
|
||||||
0x0a, 0xdd, 0xed, 0x4f, 0x91, 0x92, 0x99, 0xea, 0xf2, 0x55, 0x61, 0xa2, 0xed, 0x11, 0xe4, 0x93,
|
0xfa, 0x30, 0x0e, 0x13, 0xdd, 0x33, 0x46, 0xef, 0x60, 0x3c, 0x48, 0x3c, 0xb4, 0x3a, 0xfc, 0x60,
|
||||||
0x44, 0x42, 0x56, 0x7f, 0x86, 0x0b, 0x01, 0xa8, 0x2e, 0x64, 0x07, 0x88, 0x66, 0x7b, 0x90, 0x4f,
|
0x07, 0x47, 0xb0, 0x7a, 0x7f, 0x04, 0x64, 0x70, 0x88, 0x35, 0x50, 0xc4, 0x2f, 0xbc, 0x37, 0x9c,
|
||||||
0xcc, 0x40, 0x2b, 0xfd, 0xb1, 0xa9, 0xc1, 0xa4, 0xce, 0x9a, 0xc9, 0xd3, 0x69, 0xb6, 0x9f, 0x4e,
|
0x62, 0x40, 0x9a, 0xaa, 0xcb, 0xd7, 0x85, 0x05, 0x63, 0x4b, 0x10, 0xf5, 0xb3, 0x0a, 0x59, 0xc3,
|
||||||
0x73, 0x23, 0x7e, 0x3a, 0x63, 0xea, 0x24, 0x16, 0xb3, 0x50, 0xa7, 0x06, 0xe8, 0x1f, 0xa9, 0xeb,
|
0x19, 0x2e, 0x45, 0xa3, 0xba, 0x10, 0x1e, 0x10, 0x0c, 0x3b, 0x84, 0xa8, 0x6f, 0x06, 0x5a, 0x19,
|
||||||
0xa0, 0xc4, 0x77, 0x3d, 0x8b, 0x33, 0x29, 0x59, 0x97, 0xc5, 0x99, 0xd4, 0x28, 0x69, 0x82, 0x12,
|
0x8e, 0x1d, 0x18, 0x59, 0x6a, 0xd2, 0xf4, 0x2f, 0x55, 0xb3, 0x73, 0xa9, 0x9a, 0x59, 0x7e, 0xa9,
|
||||||
0x5f, 0x67, 0x94, 0x01, 0x9f, 0x16, 0x18, 0xea, 0xca, 0x95, 0x71, 0x49, 0xe3, 0x05, 0x09, 0x1d,
|
0x72, 0x6a, 0x3f, 0x30, 0xc3, 0x50, 0x0f, 0x8c, 0xd6, 0x5f, 0x52, 0xd7, 0x40, 0xe1, 0x11, 0x11,
|
||||||
0xc2, 0x3f, 0xfc, 0xaa, 0x22, 0xb3, 0x3f, 0x47, 0x6f, 0x2e, 0xa8, 0x56, 0xe6, 0xfd, 0x49, 0xaf,
|
0xc6, 0x99, 0x01, 0x29, 0x18, 0xc6, 0x99, 0x81, 0x09, 0xd4, 0x00, 0x85, 0xa7, 0x00, 0x0a, 0x81,
|
||||||
0xd2, 0xab, 0xb3, 0x73, 0x2d, 0xf7, 0xfd, 0x5c, 0xcb, 0x7d, 0x68, 0x69, 0xd2, 0x59, 0x4b, 0x93,
|
0x1f, 0x94, 0x33, 0xea, 0xca, 0xb5, 0x71, 0xfe, 0xe0, 0x05, 0x09, 0x9d, 0xc0, 0x1f, 0xe2, 0x0b,
|
||||||
0xbe, 0xb5, 0x34, 0xe9, 0x67, 0x4b, 0x93, 0x5e, 0x96, 0x06, 0xfe, 0x97, 0xb6, 0xd6, 0xae, 0xf7,
|
0x47, 0xe6, 0x70, 0x8e, 0xfe, 0x38, 0x51, 0xad, 0xd0, 0xfb, 0xfd, 0x59, 0xe9, 0x97, 0xe7, 0x17,
|
||||||
0xf3, 0xdc, 0xc9, 0x3b, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x62, 0xfd, 0xaf, 0x9e, 0xf2, 0x09,
|
0x5a, 0xe4, 0xeb, 0x85, 0x16, 0x79, 0xdf, 0xd6, 0xa4, 0xf3, 0xb6, 0x26, 0x7d, 0x69, 0x6b, 0xd2,
|
||||||
0x00, 0x00,
|
0xf7, 0xb6, 0x26, 0xbd, 0x48, 0x8f, 0xfc, 0xff, 0x6d, 0xad, 0x53, 0x1f, 0x45, 0x85, 0x93, 0x77,
|
||||||
|
0x7f, 0x04, 0x00, 0x00, 0xff, 0xff, 0x51, 0x4b, 0x27, 0x3b, 0x0c, 0x0a, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
@ -69,16 +69,16 @@ enum Kind {
|
|||||||
option (gogoproto.goproto_enum_prefix) = false;
|
option (gogoproto.goproto_enum_prefix) = false;
|
||||||
option (gogoproto.enum_customname) = "Kind";
|
option (gogoproto.enum_customname) = "Kind";
|
||||||
|
|
||||||
ACTIVE = 0 [(gogoproto.enumvalue_customname) = "KindActive"];
|
UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "KindUnknown"];
|
||||||
|
VIEW = 1 [(gogoproto.enumvalue_customname) = "KindView"];
|
||||||
COMMITTED = 1 [(gogoproto.enumvalue_customname) = "KindCommitted"];
|
ACTIVE = 2 [(gogoproto.enumvalue_customname) = "KindActive"];
|
||||||
|
COMMITTED = 3 [(gogoproto.enumvalue_customname) = "KindCommitted"];
|
||||||
}
|
}
|
||||||
|
|
||||||
message Info {
|
message Info {
|
||||||
string name = 1;
|
string name = 1;
|
||||||
string parent = 2;
|
string parent = 2;
|
||||||
Kind kind = 3;
|
Kind kind = 3;
|
||||||
bool readonly = 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message StatSnapshotResponse {
|
message StatSnapshotResponse {
|
||||||
|
@ -89,10 +89,13 @@ var listSnapshotCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
tw := tabwriter.NewWriter(os.Stdout, 1, 8, 1, ' ', 0)
|
tw := tabwriter.NewWriter(os.Stdout, 1, 8, 1, ' ', 0)
|
||||||
fmt.Fprintln(tw, "ID\tParent\tState\tReadonly\t")
|
fmt.Fprintln(tw, "ID\tPARENT\tKIND\t")
|
||||||
|
|
||||||
if err := snapshotter.Walk(ctx, func(ctx context.Context, info snapshot.Info) error {
|
if err := snapshotter.Walk(ctx, func(ctx context.Context, info snapshot.Info) error {
|
||||||
fmt.Fprintf(tw, "%v\t%v\t%v\t%t\t\n", info.Name, info.Parent, state(info.Kind), info.Readonly)
|
fmt.Fprintf(tw, "%v\t%v\t%v\t\n",
|
||||||
|
info.Name,
|
||||||
|
info.Parent,
|
||||||
|
info.Kind)
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -102,17 +105,6 @@ var listSnapshotCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func state(k snapshot.Kind) string {
|
|
||||||
switch k {
|
|
||||||
case snapshot.KindActive:
|
|
||||||
return "active"
|
|
||||||
case snapshot.KindCommitted:
|
|
||||||
return "committed"
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var usageSnapshotCommand = cli.Command{
|
var usageSnapshotCommand = cli.Command{
|
||||||
Name: "usage",
|
Name: "usage",
|
||||||
Usage: "Usage snapshots",
|
Usage: "Usage snapshots",
|
||||||
|
@ -135,10 +135,9 @@ func toKind(kind snapshotapi.Kind) snapshot.Kind {
|
|||||||
|
|
||||||
func toInfo(info snapshotapi.Info) snapshot.Info {
|
func toInfo(info snapshotapi.Info) snapshot.Info {
|
||||||
return snapshot.Info{
|
return snapshot.Info{
|
||||||
Name: info.Name,
|
Name: info.Name,
|
||||||
Parent: info.Parent,
|
Parent: info.Parent,
|
||||||
Kind: toKind(info.Kind),
|
Kind: toKind(info.Kind),
|
||||||
Readonly: info.Readonly,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,10 +269,9 @@ func fromKind(kind snapshot.Kind) snapshotapi.Kind {
|
|||||||
|
|
||||||
func fromInfo(info snapshot.Info) snapshotapi.Info {
|
func fromInfo(info snapshot.Info) snapshotapi.Info {
|
||||||
return snapshotapi.Info{
|
return snapshotapi.Info{
|
||||||
Name: info.Name,
|
Name: info.Name,
|
||||||
Parent: info.Parent,
|
Parent: info.Parent,
|
||||||
Kind: fromKind(info.Kind),
|
Kind: fromKind(info.Kind),
|
||||||
Readonly: info.Readonly,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/containerd/btrfs"
|
"github.com/containerd/btrfs"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
@ -58,11 +59,13 @@ func NewSnapshotter(root string) (snapshot.Snapshotter, error) {
|
|||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
active = filepath.Join(root, "active")
|
active = filepath.Join(root, "active")
|
||||||
|
view = filepath.Join(root, "view")
|
||||||
snapshots = filepath.Join(root, "snapshots")
|
snapshots = filepath.Join(root, "snapshots")
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, path := range []string{
|
for _, path := range []string{
|
||||||
active,
|
active,
|
||||||
|
view,
|
||||||
snapshots,
|
snapshots,
|
||||||
} {
|
} {
|
||||||
if err := os.Mkdir(path, 0755); err != nil && !os.IsExist(err) {
|
if err := os.Mkdir(path, 0755); err != nil && !os.IsExist(err) {
|
||||||
@ -127,14 +130,14 @@ func (b *snapshotter) Walk(ctx context.Context, fn func(context.Context, snapsho
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *snapshotter) Prepare(ctx context.Context, key, parent string) ([]mount.Mount, error) {
|
func (b *snapshotter) Prepare(ctx context.Context, key, parent string) ([]mount.Mount, error) {
|
||||||
return b.makeActive(ctx, key, parent, false)
|
return b.makeSnapshot(ctx, snapshot.KindActive, key, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *snapshotter) View(ctx context.Context, key, parent string) ([]mount.Mount, error) {
|
func (b *snapshotter) View(ctx context.Context, key, parent string) ([]mount.Mount, error) {
|
||||||
return b.makeActive(ctx, key, parent, true)
|
return b.makeSnapshot(ctx, snapshot.KindView, key, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *snapshotter) makeActive(ctx context.Context, key, parent string, readonly bool) ([]mount.Mount, error) {
|
func (b *snapshotter) makeSnapshot(ctx context.Context, kind snapshot.Kind, key, parent string) ([]mount.Mount, error) {
|
||||||
ctx, t, err := b.ms.TransactionContext(ctx, true)
|
ctx, t, err := b.ms.TransactionContext(ctx, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -147,23 +150,29 @@ func (b *snapshotter) makeActive(ctx context.Context, key, parent string, readon
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
a, err := storage.CreateActive(ctx, key, parent, readonly)
|
s, err := storage.CreateSnapshot(ctx, kind, key, parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
target := filepath.Join(b.root, "active", a.ID)
|
target := filepath.Join(b.root, strings.ToLower(s.Kind.String()), s.ID)
|
||||||
|
|
||||||
if len(a.ParentIDs) == 0 {
|
if len(s.ParentIDs) == 0 {
|
||||||
// create new subvolume
|
// create new subvolume
|
||||||
// btrfs subvolume create /dir
|
// btrfs subvolume create /dir
|
||||||
if err = btrfs.SubvolCreate(target); err != nil {
|
if err = btrfs.SubvolCreate(target); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
parentp := filepath.Join(b.root, "snapshots", a.ParentIDs[0])
|
parentp := filepath.Join(b.root, "snapshots", s.ParentIDs[0])
|
||||||
|
|
||||||
|
var readonly bool
|
||||||
|
if kind == snapshot.KindView {
|
||||||
|
readonly = true
|
||||||
|
}
|
||||||
|
|
||||||
// btrfs subvolume snapshot /parent /subvol
|
// btrfs subvolume snapshot /parent /subvol
|
||||||
if err = btrfs.SubvolSnapshot(target, parentp, a.Readonly); err != nil {
|
if err = btrfs.SubvolSnapshot(target, parentp, readonly); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,12 +265,13 @@ func (b *snapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount, er
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
a, err := storage.GetActive(ctx, key)
|
s, err := storage.GetSnapshot(ctx, key)
|
||||||
t.Rollback()
|
t.Rollback()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to get active snapshot")
|
return nil, errors.Wrap(err, "failed to get active snapshot")
|
||||||
}
|
}
|
||||||
dir := filepath.Join(b.root, "active", a.ID)
|
|
||||||
|
dir := filepath.Join(b.root, strings.ToLower(s.Kind.String()), s.ID)
|
||||||
return b.mounts(dir)
|
return b.mounts(dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,18 +306,15 @@ func (b *snapshotter) Remove(ctx context.Context, key string) (err error) {
|
|||||||
return errors.Wrap(err, "failed to remove snapshot")
|
return errors.Wrap(err, "failed to remove snapshot")
|
||||||
}
|
}
|
||||||
|
|
||||||
if k == snapshot.KindActive {
|
switch k {
|
||||||
|
case snapshot.KindView:
|
||||||
|
source = filepath.Join(b.root, "view", id)
|
||||||
|
removed = filepath.Join(b.root, "view", "rm-"+id)
|
||||||
|
readonly = true
|
||||||
|
case snapshot.KindActive:
|
||||||
source = filepath.Join(b.root, "active", id)
|
source = filepath.Join(b.root, "active", id)
|
||||||
|
|
||||||
info, err := btrfs.SubvolInfo(source)
|
|
||||||
if err != nil {
|
|
||||||
source = ""
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly = info.Readonly
|
|
||||||
removed = filepath.Join(b.root, "active", "rm-"+id)
|
removed = filepath.Join(b.root, "active", "rm-"+id)
|
||||||
} else {
|
case snapshot.KindCommitted:
|
||||||
source = filepath.Join(b.root, "snapshots", id)
|
source = filepath.Join(b.root, "snapshots", id)
|
||||||
removed = filepath.Join(b.root, "snapshots", "rm-"+id)
|
removed = filepath.Join(b.root, "snapshots", "rm-"+id)
|
||||||
readonly = true
|
readonly = true
|
||||||
|
@ -94,11 +94,11 @@ func (o *snapshotter) Usage(ctx context.Context, key string) (snapshot.Usage, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *snapshotter) Prepare(ctx context.Context, key, parent string) ([]mount.Mount, error) {
|
func (o *snapshotter) Prepare(ctx context.Context, key, parent string) ([]mount.Mount, error) {
|
||||||
return o.createActive(ctx, key, parent, false)
|
return o.createSnapshot(ctx, snapshot.KindActive, key, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *snapshotter) View(ctx context.Context, key, parent string) ([]mount.Mount, error) {
|
func (o *snapshotter) View(ctx context.Context, key, parent string) ([]mount.Mount, error) {
|
||||||
return o.createActive(ctx, key, parent, true)
|
return o.createSnapshot(ctx, snapshot.KindView, key, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mounts returns the mounts for the transaction identified by key. Can be
|
// Mounts returns the mounts for the transaction identified by key. Can be
|
||||||
@ -110,12 +110,12 @@ func (o *snapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount, er
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
active, err := storage.GetActive(ctx, key)
|
s, err := storage.GetSnapshot(ctx, key)
|
||||||
t.Rollback()
|
t.Rollback()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to get active mount")
|
return nil, errors.Wrap(err, "failed to get snapshot mount")
|
||||||
}
|
}
|
||||||
return o.mounts(active), nil
|
return o.mounts(s), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *snapshotter) Commit(ctx context.Context, name, key string) error {
|
func (o *snapshotter) Commit(ctx context.Context, name, key string) error {
|
||||||
@ -203,13 +203,13 @@ func (o *snapshotter) Walk(ctx context.Context, fn func(context.Context, snapsho
|
|||||||
return storage.WalkInfo(ctx, fn)
|
return storage.WalkInfo(ctx, fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *snapshotter) createActive(ctx context.Context, key, parent string, readonly bool) ([]mount.Mount, error) {
|
func (o *snapshotter) createSnapshot(ctx context.Context, kind snapshot.Kind, key, parent string) ([]mount.Mount, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
path, td string
|
path, td string
|
||||||
)
|
)
|
||||||
|
|
||||||
if !readonly || parent == "" {
|
if kind == snapshot.KindActive || parent == "" {
|
||||||
td, err = ioutil.TempDir(filepath.Join(o.root, "snapshots"), "new-")
|
td, err = ioutil.TempDir(filepath.Join(o.root, "snapshots"), "new-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to create temp dir")
|
return nil, errors.Wrap(err, "failed to create temp dir")
|
||||||
@ -235,23 +235,23 @@ func (o *snapshotter) createActive(ctx context.Context, key, parent string, read
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
active, err := storage.CreateActive(ctx, key, parent, readonly)
|
s, err := storage.CreateSnapshot(ctx, kind, key, parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if rerr := t.Rollback(); rerr != nil {
|
if rerr := t.Rollback(); rerr != nil {
|
||||||
log.G(ctx).WithError(rerr).Warn("Failure rolling back transaction")
|
log.G(ctx).WithError(rerr).Warn("Failure rolling back transaction")
|
||||||
}
|
}
|
||||||
return nil, errors.Wrap(err, "failed to create active")
|
return nil, errors.Wrap(err, "failed to create snapshot")
|
||||||
}
|
}
|
||||||
|
|
||||||
if td != "" {
|
if td != "" {
|
||||||
if len(active.ParentIDs) > 0 {
|
if len(s.ParentIDs) > 0 {
|
||||||
parent := o.getSnapshotDir(active.ParentIDs[0])
|
parent := o.getSnapshotDir(s.ParentIDs[0])
|
||||||
if err := fs.CopyDir(td, parent); err != nil {
|
if err := fs.CopyDir(td, parent); err != nil {
|
||||||
return nil, errors.Wrap(err, "copying of parent failed")
|
return nil, errors.Wrap(err, "copying of parent failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
path = o.getSnapshotDir(active.ID)
|
path = o.getSnapshotDir(s.ID)
|
||||||
if err := os.Rename(td, path); err != nil {
|
if err := os.Rename(td, path); err != nil {
|
||||||
if rerr := t.Rollback(); rerr != nil {
|
if rerr := t.Rollback(); rerr != nil {
|
||||||
log.G(ctx).WithError(rerr).Warn("Failure rolling back transaction")
|
log.G(ctx).WithError(rerr).Warn("Failure rolling back transaction")
|
||||||
@ -265,29 +265,29 @@ func (o *snapshotter) createActive(ctx context.Context, key, parent string, read
|
|||||||
return nil, errors.Wrap(err, "commit failed")
|
return nil, errors.Wrap(err, "commit failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
return o.mounts(active), nil
|
return o.mounts(s), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *snapshotter) getSnapshotDir(id string) string {
|
func (o *snapshotter) getSnapshotDir(id string) string {
|
||||||
return filepath.Join(o.root, "snapshots", id)
|
return filepath.Join(o.root, "snapshots", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *snapshotter) mounts(active storage.Active) []mount.Mount {
|
func (o *snapshotter) mounts(s storage.Snapshot) []mount.Mount {
|
||||||
var (
|
var (
|
||||||
roFlag string
|
roFlag string
|
||||||
source string
|
source string
|
||||||
)
|
)
|
||||||
|
|
||||||
if active.Readonly {
|
if s.Kind == snapshot.KindView {
|
||||||
roFlag = "ro"
|
roFlag = "ro"
|
||||||
} else {
|
} else {
|
||||||
roFlag = "rw"
|
roFlag = "rw"
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(active.ParentIDs) == 0 || !active.Readonly {
|
if len(s.ParentIDs) == 0 || s.Kind == snapshot.KindActive {
|
||||||
source = o.getSnapshotDir(active.ID)
|
source = o.getSnapshotDir(s.ID)
|
||||||
} else {
|
} else {
|
||||||
source = o.getSnapshotDir(active.ParentIDs[0])
|
source = o.getSnapshotDir(s.ParentIDs[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
return []mount.Mount{
|
return []mount.Mount{
|
||||||
|
@ -122,11 +122,11 @@ func (o *snapshotter) Usage(ctx context.Context, key string) (snapshot.Usage, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *snapshotter) Prepare(ctx context.Context, key, parent string) ([]mount.Mount, error) {
|
func (o *snapshotter) Prepare(ctx context.Context, key, parent string) ([]mount.Mount, error) {
|
||||||
return o.createActive(ctx, key, parent, false)
|
return o.createSnapshot(ctx, snapshot.KindActive, key, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *snapshotter) View(ctx context.Context, key, parent string) ([]mount.Mount, error) {
|
func (o *snapshotter) View(ctx context.Context, key, parent string) ([]mount.Mount, error) {
|
||||||
return o.createActive(ctx, key, parent, true)
|
return o.createSnapshot(ctx, snapshot.KindView, key, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mounts returns the mounts for the transaction identified by key. Can be
|
// Mounts returns the mounts for the transaction identified by key. Can be
|
||||||
@ -138,12 +138,12 @@ func (o *snapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount, er
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
active, err := storage.GetActive(ctx, key)
|
s, err := storage.GetSnapshot(ctx, key)
|
||||||
t.Rollback()
|
t.Rollback()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to get active mount")
|
return nil, errors.Wrap(err, "failed to get active mount")
|
||||||
}
|
}
|
||||||
return o.mounts(active), nil
|
return o.mounts(s), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *snapshotter) Commit(ctx context.Context, name, key string) error {
|
func (o *snapshotter) Commit(ctx context.Context, name, key string) error {
|
||||||
@ -230,7 +230,7 @@ func (o *snapshotter) Walk(ctx context.Context, fn func(context.Context, snapsho
|
|||||||
return storage.WalkInfo(ctx, fn)
|
return storage.WalkInfo(ctx, fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *snapshotter) createActive(ctx context.Context, key, parent string, readonly bool) ([]mount.Mount, error) {
|
func (o *snapshotter) createSnapshot(ctx context.Context, kind snapshot.Kind, key, parent string) ([]mount.Mount, error) {
|
||||||
var (
|
var (
|
||||||
path string
|
path string
|
||||||
snapshotDir = filepath.Join(o.root, "snapshots")
|
snapshotDir = filepath.Join(o.root, "snapshots")
|
||||||
@ -258,7 +258,8 @@ func (o *snapshotter) createActive(ctx context.Context, key, parent string, read
|
|||||||
if err = os.MkdirAll(filepath.Join(td, "fs"), 0711); err != nil {
|
if err = os.MkdirAll(filepath.Join(td, "fs"), 0711); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !readonly {
|
|
||||||
|
if kind == snapshot.KindActive {
|
||||||
if err = os.MkdirAll(filepath.Join(td, "work"), 0700); err != nil {
|
if err = os.MkdirAll(filepath.Join(td, "work"), 0700); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -269,7 +270,7 @@ func (o *snapshotter) createActive(ctx context.Context, key, parent string, read
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
active, err := storage.CreateActive(ctx, key, parent, readonly)
|
s, err := storage.CreateSnapshot(ctx, kind, key, parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if rerr := t.Rollback(); rerr != nil {
|
if rerr := t.Rollback(); rerr != nil {
|
||||||
log.G(ctx).WithError(rerr).Warn("Failure rolling back transaction")
|
log.G(ctx).WithError(rerr).Warn("Failure rolling back transaction")
|
||||||
@ -277,7 +278,7 @@ func (o *snapshotter) createActive(ctx context.Context, key, parent string, read
|
|||||||
return nil, errors.Wrap(err, "failed to create active")
|
return nil, errors.Wrap(err, "failed to create active")
|
||||||
}
|
}
|
||||||
|
|
||||||
path = filepath.Join(snapshotDir, active.ID)
|
path = filepath.Join(snapshotDir, s.ID)
|
||||||
if err = os.Rename(td, path); err != nil {
|
if err = os.Rename(td, path); err != nil {
|
||||||
if rerr := t.Rollback(); rerr != nil {
|
if rerr := t.Rollback(); rerr != nil {
|
||||||
log.G(ctx).WithError(rerr).Warn("Failure rolling back transaction")
|
log.G(ctx).WithError(rerr).Warn("Failure rolling back transaction")
|
||||||
@ -290,21 +291,21 @@ func (o *snapshotter) createActive(ctx context.Context, key, parent string, read
|
|||||||
return nil, errors.Wrap(err, "commit failed")
|
return nil, errors.Wrap(err, "commit failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
return o.mounts(active), nil
|
return o.mounts(s), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *snapshotter) mounts(active storage.Active) []mount.Mount {
|
func (o *snapshotter) mounts(s storage.Snapshot) []mount.Mount {
|
||||||
if len(active.ParentIDs) == 0 {
|
if len(s.ParentIDs) == 0 {
|
||||||
// if we only have one layer/no parents then just return a bind mount as overlay
|
// if we only have one layer/no parents then just return a bind mount as overlay
|
||||||
// will not work
|
// will not work
|
||||||
roFlag := "rw"
|
roFlag := "rw"
|
||||||
if active.Readonly {
|
if s.Kind == snapshot.KindView {
|
||||||
roFlag = "ro"
|
roFlag = "ro"
|
||||||
}
|
}
|
||||||
|
|
||||||
return []mount.Mount{
|
return []mount.Mount{
|
||||||
{
|
{
|
||||||
Source: o.upperPath(active.ID),
|
Source: o.upperPath(s.ID),
|
||||||
Type: "bind",
|
Type: "bind",
|
||||||
Options: []string{
|
Options: []string{
|
||||||
roFlag,
|
roFlag,
|
||||||
@ -315,15 +316,15 @@ func (o *snapshotter) mounts(active storage.Active) []mount.Mount {
|
|||||||
}
|
}
|
||||||
var options []string
|
var options []string
|
||||||
|
|
||||||
if !active.Readonly {
|
if s.Kind == snapshot.KindActive {
|
||||||
options = append(options,
|
options = append(options,
|
||||||
fmt.Sprintf("workdir=%s", o.workPath(active.ID)),
|
fmt.Sprintf("workdir=%s", o.workPath(s.ID)),
|
||||||
fmt.Sprintf("upperdir=%s", o.upperPath(active.ID)),
|
fmt.Sprintf("upperdir=%s", o.upperPath(s.ID)),
|
||||||
)
|
)
|
||||||
} else if len(active.ParentIDs) == 1 {
|
} else if len(s.ParentIDs) == 1 {
|
||||||
return []mount.Mount{
|
return []mount.Mount{
|
||||||
{
|
{
|
||||||
Source: o.upperPath(active.ParentIDs[0]),
|
Source: o.upperPath(s.ParentIDs[0]),
|
||||||
Type: "bind",
|
Type: "bind",
|
||||||
Options: []string{
|
Options: []string{
|
||||||
"ro",
|
"ro",
|
||||||
@ -333,9 +334,9 @@ func (o *snapshotter) mounts(active storage.Active) []mount.Mount {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parentPaths := make([]string, len(active.ParentIDs))
|
parentPaths := make([]string, len(s.ParentIDs))
|
||||||
for i := range active.ParentIDs {
|
for i := range s.ParentIDs {
|
||||||
parentPaths[i] = o.upperPath(active.ParentIDs[i])
|
parentPaths[i] = o.upperPath(s.ParentIDs[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
options = append(options, fmt.Sprintf("lowerdir=%s", strings.Join(parentPaths, ":")))
|
options = append(options, fmt.Sprintf("lowerdir=%s", strings.Join(parentPaths, ":")))
|
||||||
|
@ -158,12 +158,12 @@ func getBasePath(ctx context.Context, sn snapshot.Snapshotter, root, key string)
|
|||||||
}
|
}
|
||||||
defer t.Rollback()
|
defer t.Rollback()
|
||||||
|
|
||||||
active, err := storage.GetActive(ctx, key)
|
s, err := storage.GetSnapshot(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return filepath.Join(root, "snapshots", active.ID)
|
return filepath.Join(root, "snapshots", s.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getParents(ctx context.Context, sn snapshot.Snapshotter, root, key string) []string {
|
func getParents(ctx context.Context, sn snapshot.Snapshotter, root, key string) []string {
|
||||||
@ -173,13 +173,13 @@ func getParents(ctx context.Context, sn snapshot.Snapshotter, root, key string)
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
defer t.Rollback()
|
defer t.Rollback()
|
||||||
active, err := storage.GetActive(ctx, key)
|
s, err := storage.GetSnapshot(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
parents := make([]string, len(active.ParentIDs))
|
parents := make([]string, len(s.ParentIDs))
|
||||||
for i := range active.ParentIDs {
|
for i := range s.ParentIDs {
|
||||||
parents[i] = filepath.Join(root, "snapshots", active.ParentIDs[i], "fs")
|
parents[i] = filepath.Join(root, "snapshots", s.ParentIDs[i], "fs")
|
||||||
}
|
}
|
||||||
return parents
|
return parents
|
||||||
}
|
}
|
||||||
|
@ -11,16 +11,29 @@ type Kind int
|
|||||||
|
|
||||||
// definitions of snapshot kinds
|
// definitions of snapshot kinds
|
||||||
const (
|
const (
|
||||||
KindActive Kind = iota
|
KindView Kind = iota + 1
|
||||||
|
KindActive
|
||||||
KindCommitted
|
KindCommitted
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (k Kind) String() string {
|
||||||
|
switch k {
|
||||||
|
case KindView:
|
||||||
|
return "View"
|
||||||
|
case KindActive:
|
||||||
|
return "Active"
|
||||||
|
case KindCommitted:
|
||||||
|
return "Committed"
|
||||||
|
default:
|
||||||
|
return "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Info provides information about a particular snapshot.
|
// Info provides information about a particular snapshot.
|
||||||
type Info struct {
|
type Info struct {
|
||||||
Name string // name or key of snapshot
|
Kind Kind // active or committed snapshot
|
||||||
Parent string // name of parent snapshot
|
Name string // name or key of snapshot
|
||||||
Kind Kind // active or committed snapshot
|
Parent string // name of parent snapshot
|
||||||
Readonly bool // true if readonly, only valid for active
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Usage defines statistics for disk resources consumed by the snapshot.
|
// Usage defines statistics for disk resources consumed by the snapshot.
|
||||||
|
@ -79,10 +79,9 @@ func GetInfo(ctx context.Context, key string) (string, snapshot.Info, snapshot.U
|
|||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprint(ss.ID), snapshot.Info{
|
return fmt.Sprint(ss.ID), snapshot.Info{
|
||||||
Name: key,
|
Name: key,
|
||||||
Parent: ss.Parent,
|
Parent: ss.Parent,
|
||||||
Kind: fromProtoKind(ss.Kind),
|
Kind: snapshot.Kind(ss.Kind),
|
||||||
Readonly: ss.Readonly,
|
|
||||||
}, usage, nil
|
}, usage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,22 +101,64 @@ func WalkInfo(ctx context.Context, fn func(context.Context, snapshot.Info) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
info := snapshot.Info{
|
info := snapshot.Info{
|
||||||
Name: string(k),
|
Name: string(k),
|
||||||
Parent: ss.Parent,
|
Parent: ss.Parent,
|
||||||
Kind: fromProtoKind(ss.Kind),
|
Kind: snapshot.Kind(ss.Kind),
|
||||||
Readonly: ss.Readonly,
|
|
||||||
}
|
}
|
||||||
return fn(ctx, info)
|
return fn(ctx, info)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateActive creates a new active snapshot transaction referenced by
|
// GetSnapshot returns the metadata for the active or view snapshot transaction
|
||||||
// the provided key. The new active snapshot will have the provided
|
// referenced by the given key. Requires a context with a storage transaction.
|
||||||
// parent. If the readonly option is given, the active snapshot will be
|
func GetSnapshot(ctx context.Context, key string) (s Snapshot, err error) {
|
||||||
// marked as readonly and can only be removed, and not committed. The
|
err = withBucket(ctx, func(ctx context.Context, bkt, pbkt *bolt.Bucket) error {
|
||||||
// provided context must contain a writable transaction.
|
b := bkt.Get([]byte(key))
|
||||||
func CreateActive(ctx context.Context, key, parent string, readonly bool) (a Active, err error) {
|
if len(b) == 0 {
|
||||||
|
return errors.Wrapf(errdefs.ErrNotFound, "snapshot %v", key)
|
||||||
|
}
|
||||||
|
|
||||||
|
var ss db.Snapshot
|
||||||
|
if err := proto.Unmarshal(b, &ss); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to unmarshal snapshot")
|
||||||
|
}
|
||||||
|
|
||||||
|
if ss.Kind != db.KindActive && ss.Kind != db.KindView {
|
||||||
|
return errors.Wrapf(errdefs.ErrFailedPrecondition, "requested snapshot %v not active or view", key)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.ID = fmt.Sprintf("%d", ss.ID)
|
||||||
|
s.Kind = snapshot.Kind(ss.Kind)
|
||||||
|
|
||||||
|
if ss.Parent != "" {
|
||||||
|
var parent db.Snapshot
|
||||||
|
if err := getSnapshot(bkt, ss.Parent, &parent); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to get parent snapshot")
|
||||||
|
}
|
||||||
|
|
||||||
|
s.ParentIDs, err = parents(bkt, &parent)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to get parent chain")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return Snapshot{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSnapshot inserts a record for an active or view snapshot with the provided parent.
|
||||||
|
func CreateSnapshot(ctx context.Context, kind snapshot.Kind, key, parent string) (s Snapshot, err error) {
|
||||||
|
switch kind {
|
||||||
|
case snapshot.KindActive, snapshot.KindView:
|
||||||
|
default:
|
||||||
|
return Snapshot{}, errors.Wrapf(errdefs.ErrInvalidArgument, "snapshot type %v invalid; only snapshots of type Active or View can be created", kind)
|
||||||
|
}
|
||||||
|
|
||||||
err = createBucketIfNotExists(ctx, func(ctx context.Context, bkt, pbkt *bolt.Bucket) error {
|
err = createBucketIfNotExists(ctx, func(ctx context.Context, bkt, pbkt *bolt.Bucket) error {
|
||||||
var (
|
var (
|
||||||
parentS *db.Snapshot
|
parentS *db.Snapshot
|
||||||
@ -143,10 +184,9 @@ func CreateActive(ctx context.Context, key, parent string, readonly bool) (a Act
|
|||||||
}
|
}
|
||||||
|
|
||||||
ss := db.Snapshot{
|
ss := db.Snapshot{
|
||||||
ID: id,
|
ID: id,
|
||||||
Parent: parent,
|
Parent: parent,
|
||||||
Kind: db.KindActive,
|
Kind: db.Kind(kind),
|
||||||
Readonly: readonly,
|
|
||||||
}
|
}
|
||||||
if err := putSnapshot(bkt, key, &ss); err != nil {
|
if err := putSnapshot(bkt, key, &ss); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -159,59 +199,18 @@ func CreateActive(ctx context.Context, key, parent string, readonly bool) (a Act
|
|||||||
return errors.Wrap(err, "failed to write parent link")
|
return errors.Wrap(err, "failed to write parent link")
|
||||||
}
|
}
|
||||||
|
|
||||||
a.ParentIDs, err = parents(bkt, parentS)
|
s.ParentIDs, err = parents(bkt, parentS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to get parent chain")
|
return errors.Wrap(err, "failed to get parent chain")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a.ID = fmt.Sprintf("%d", id)
|
s.ID = fmt.Sprintf("%d", id)
|
||||||
a.Readonly = readonly
|
s.Kind = kind
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Active{}, err
|
return Snapshot{}, err
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetActive returns the metadata for the active snapshot transaction referenced
|
|
||||||
// by the given key. Requires a context with a storage transaction.
|
|
||||||
func GetActive(ctx context.Context, key string) (a Active, err error) {
|
|
||||||
err = withBucket(ctx, func(ctx context.Context, bkt, pbkt *bolt.Bucket) error {
|
|
||||||
b := bkt.Get([]byte(key))
|
|
||||||
if len(b) == 0 {
|
|
||||||
return errors.Wrapf(errdefs.ErrNotFound, "snapshot %v", key)
|
|
||||||
}
|
|
||||||
|
|
||||||
var ss db.Snapshot
|
|
||||||
if err := proto.Unmarshal(b, &ss); err != nil {
|
|
||||||
return errors.Wrap(err, "failed to unmarshal snapshot")
|
|
||||||
}
|
|
||||||
if ss.Kind != db.KindActive {
|
|
||||||
return errors.Wrapf(errdefs.ErrFailedPrecondition, "requested snapshot %v not active", key)
|
|
||||||
}
|
|
||||||
|
|
||||||
a.ID = fmt.Sprintf("%d", ss.ID)
|
|
||||||
a.Readonly = ss.Readonly
|
|
||||||
|
|
||||||
if ss.Parent != "" {
|
|
||||||
var parent db.Snapshot
|
|
||||||
if err := getSnapshot(bkt, ss.Parent, &parent); err != nil {
|
|
||||||
return errors.Wrap(err, "failed to get parent snapshot")
|
|
||||||
}
|
|
||||||
|
|
||||||
a.ParentIDs, err = parents(bkt, &parent)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "failed to get parent chain")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return Active{}, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
@ -255,7 +254,7 @@ func Remove(ctx context.Context, key string) (id string, k snapshot.Kind, err er
|
|||||||
}
|
}
|
||||||
|
|
||||||
id = fmt.Sprintf("%d", ss.ID)
|
id = fmt.Sprintf("%d", ss.ID)
|
||||||
k = fromProtoKind(ss.Kind)
|
k = snapshot.Kind(ss.Kind)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -283,12 +282,8 @@ func CommitActive(ctx context.Context, key, name string, usage snapshot.Usage) (
|
|||||||
if ss.Kind != db.KindActive {
|
if ss.Kind != db.KindActive {
|
||||||
return errors.Wrapf(errdefs.ErrFailedPrecondition, "snapshot %v is not active", name)
|
return errors.Wrapf(errdefs.ErrFailedPrecondition, "snapshot %v is not active", name)
|
||||||
}
|
}
|
||||||
if ss.Readonly {
|
|
||||||
return errors.Errorf("active snapshot is readonly")
|
|
||||||
}
|
|
||||||
|
|
||||||
ss.Kind = db.KindCommitted
|
ss.Kind = db.KindCommitted
|
||||||
ss.Readonly = true
|
|
||||||
ss.Inodes = usage.Inodes
|
ss.Inodes = usage.Inodes
|
||||||
ss.Size_ = usage.Size
|
ss.Size_ = usage.Size
|
||||||
|
|
||||||
@ -354,13 +349,6 @@ func createBucketIfNotExists(ctx context.Context, fn func(context.Context, *bolt
|
|||||||
return fn(ctx, sbkt, pbkt)
|
return fn(ctx, sbkt, pbkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromProtoKind(k db.Kind) snapshot.Kind {
|
|
||||||
if k == db.KindActive {
|
|
||||||
return snapshot.KindActive
|
|
||||||
}
|
|
||||||
return snapshot.KindCommitted
|
|
||||||
}
|
|
||||||
|
|
||||||
func parents(bkt *bolt.Bucket, parent *db.Snapshot) (parents []string, err error) {
|
func parents(bkt *bolt.Bucket, parent *db.Snapshot) (parents []string, err error) {
|
||||||
for {
|
for {
|
||||||
parents = append(parents, fmt.Sprintf("%d", parent.ID))
|
parents = append(parents, fmt.Sprintf("%d", parent.ID))
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
// Does not require root but flag must be defined for snapshot tests
|
// Does not require root but flag must be defined for snapshot tests
|
||||||
|
"github.com/containerd/containerd/snapshot"
|
||||||
|
"github.com/containerd/containerd/snapshot/storage/proto"
|
||||||
_ "github.com/containerd/containerd/testutil"
|
_ "github.com/containerd/containerd/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,6 +16,21 @@ func TestMetastore(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestKidnConversion ensures we can blindly cast from protobuf types.
|
||||||
|
func TestKindConversion(t *testing.T) {
|
||||||
|
for _, testcase := range []snapshot.Kind{
|
||||||
|
snapshot.KindView,
|
||||||
|
snapshot.KindActive,
|
||||||
|
snapshot.KindCommitted,
|
||||||
|
} {
|
||||||
|
cast := proto.Kind(testcase)
|
||||||
|
uncast := snapshot.Kind(cast)
|
||||||
|
if uncast != testcase {
|
||||||
|
t.Fatalf("kind value cast failed: %v != %v", uncast, testcase)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkSuite(b *testing.B) {
|
func BenchmarkSuite(b *testing.B) {
|
||||||
Benchmarks(b, "BoltDBBench", func(root string) (*MetaStore, error) {
|
Benchmarks(b, "BoltDBBench", func(root string) (*MetaStore, error) {
|
||||||
return NewMetaStore(filepath.Join(root, "metadata.db"))
|
return NewMetaStore(filepath.Join(root, "metadata.db"))
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/boltdb/bolt"
|
"github.com/boltdb/bolt"
|
||||||
|
"github.com/containerd/containerd/snapshot"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,15 +27,16 @@ type Transactor interface {
|
|||||||
Rollback() error
|
Rollback() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Active hold the metadata for an active snapshot transaction. The ParentIDs
|
// Snapshot hold the metadata for an active or view snapshot transaction. The
|
||||||
// hold the snapshot identifiers for the committed snapshots this active is
|
// ParentIDs hold the snapshot identifiers for the committed snapshots this
|
||||||
// based on. The ParentIDs are ordered from the lowest base to highest, meaning
|
// active or view is based on. The ParentIDs are ordered from the lowest base
|
||||||
// they should be applied in order from the first index to the last index. The
|
// to highest, meaning they should be applied in order from the first index to
|
||||||
// last index should always be considered the active snapshots immediate parent.
|
// the last index. The last index should always be considered the active
|
||||||
type Active struct {
|
// snapshots immediate parent.
|
||||||
|
type Snapshot struct {
|
||||||
|
Kind snapshot.Kind
|
||||||
ID string
|
ID string
|
||||||
ParentIDs []string
|
ParentIDs []string
|
||||||
Readonly bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MetaStore is used to store metadata related to a snapshot driver. The
|
// MetaStore is used to store metadata related to a snapshot driver. The
|
||||||
|
@ -106,14 +106,14 @@ func openCloseReadonly(b *testing.B, name string, metaFn metaFactory) func(b *te
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createActiveFromBase(ctx context.Context, ms *MetaStore, active, base string) error {
|
func createActiveFromBase(ctx context.Context, ms *MetaStore, active, base string) error {
|
||||||
if _, err := CreateActive(ctx, "bottom", "", false); err != nil {
|
if _, err := CreateSnapshot(ctx, snapshot.KindActive, "bottom", ""); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := CommitActive(ctx, "bottom", base, snapshot.Usage{}); err != nil {
|
if _, err := CommitActive(ctx, "bottom", base, snapshot.Usage{}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := CreateActive(ctx, active, base, false)
|
_, err := CreateSnapshot(ctx, snapshot.KindActive, active, base)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +150,7 @@ func statCommittedBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) {
|
|||||||
|
|
||||||
func createActiveBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) {
|
func createActiveBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
if _, err := CreateActive(ctx, "active", "", false); err != nil {
|
if _, err := CreateSnapshot(ctx, snapshot.KindActive, "active", ""); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
@ -164,7 +164,7 @@ func createActiveBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) {
|
|||||||
func removeBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) {
|
func removeBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
if _, err := CreateActive(ctx, "active", "", false); err != nil {
|
if _, err := CreateSnapshot(ctx, snapshot.KindActive, "active", ""); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
b.StartTimer()
|
b.StartTimer()
|
||||||
@ -177,7 +177,7 @@ func removeBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) {
|
|||||||
func commitBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) {
|
func commitBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) {
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
if _, err := CreateActive(ctx, "active", "", false); err != nil {
|
if _, err := CreateSnapshot(ctx, snapshot.KindActive, "active", ""); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
b.StartTimer()
|
b.StartTimer()
|
||||||
@ -194,7 +194,7 @@ func commitBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) {
|
|||||||
func getActiveBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) {
|
func getActiveBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) {
|
||||||
var base string
|
var base string
|
||||||
for i := 1; i <= 10; i++ {
|
for i := 1; i <= 10; i++ {
|
||||||
if _, err := CreateActive(ctx, "tmp", base, false); err != nil {
|
if _, err := CreateSnapshot(ctx, snapshot.KindActive, "tmp", base); err != nil {
|
||||||
b.Fatalf("create active failed: %+v", err)
|
b.Fatalf("create active failed: %+v", err)
|
||||||
}
|
}
|
||||||
base = fmt.Sprintf("base-%d", i)
|
base = fmt.Sprintf("base-%d", i)
|
||||||
@ -204,13 +204,13 @@ func getActiveBenchmark(ctx context.Context, b *testing.B, ms *MetaStore) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := CreateActive(ctx, "active", base, false); err != nil {
|
if _, err := CreateSnapshot(ctx, snapshot.KindActive, "active", base); err != nil {
|
||||||
b.Fatalf("create active failed: %+v", err)
|
b.Fatalf("create active failed: %+v", err)
|
||||||
}
|
}
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
if _, err := GetActive(ctx, "active"); err != nil {
|
if _, err := GetSnapshot(ctx, "active"); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,10 +24,10 @@ func MetaStoreSuite(t *testing.T, name string, meta func(root string) (*MetaStor
|
|||||||
t.Run("GetInfoNotExist", makeTest(t, name, meta, inReadTransaction(testGetInfoNotExist, basePopulate)))
|
t.Run("GetInfoNotExist", makeTest(t, name, meta, inReadTransaction(testGetInfoNotExist, basePopulate)))
|
||||||
t.Run("GetInfoEmptyDB", makeTest(t, name, meta, inReadTransaction(testGetInfoNotExist, nil)))
|
t.Run("GetInfoEmptyDB", makeTest(t, name, meta, inReadTransaction(testGetInfoNotExist, nil)))
|
||||||
t.Run("Walk", makeTest(t, name, meta, inReadTransaction(testWalk, basePopulate)))
|
t.Run("Walk", makeTest(t, name, meta, inReadTransaction(testWalk, basePopulate)))
|
||||||
t.Run("GetActive", makeTest(t, name, meta, testGetActive))
|
t.Run("GetSnapshot", makeTest(t, name, meta, testGetSnapshot))
|
||||||
t.Run("GetActiveNotExist", makeTest(t, name, meta, inReadTransaction(testGetActiveNotExist, basePopulate)))
|
t.Run("GetSnapshotNotExist", makeTest(t, name, meta, inReadTransaction(testGetSnapshotNotExist, basePopulate)))
|
||||||
t.Run("GetActiveCommitted", makeTest(t, name, meta, inReadTransaction(testGetActiveCommitted, basePopulate)))
|
t.Run("GetSnapshotCommitted", makeTest(t, name, meta, inReadTransaction(testGetSnapshotCommitted, basePopulate)))
|
||||||
t.Run("GetActiveEmptyDB", makeTest(t, name, meta, inReadTransaction(testGetActiveNotExist, basePopulate)))
|
t.Run("GetSnapshotEmptyDB", makeTest(t, name, meta, inReadTransaction(testGetSnapshotNotExist, basePopulate)))
|
||||||
t.Run("CreateActive", makeTest(t, name, meta, inWriteTransaction(testCreateActive)))
|
t.Run("CreateActive", makeTest(t, name, meta, inWriteTransaction(testCreateActive)))
|
||||||
t.Run("CreateActiveNotExist", makeTest(t, name, meta, inWriteTransaction(testCreateActiveNotExist)))
|
t.Run("CreateActiveNotExist", makeTest(t, name, meta, inWriteTransaction(testCreateActiveNotExist)))
|
||||||
t.Run("CreateActiveExist", makeTest(t, name, meta, inWriteTransaction(testCreateActiveExist)))
|
t.Run("CreateActiveExist", makeTest(t, name, meta, inWriteTransaction(testCreateActiveExist)))
|
||||||
@ -36,7 +36,7 @@ func MetaStoreSuite(t *testing.T, name string, meta func(root string) (*MetaStor
|
|||||||
t.Run("CommitNotExist", makeTest(t, name, meta, inWriteTransaction(testCommitExist)))
|
t.Run("CommitNotExist", makeTest(t, name, meta, inWriteTransaction(testCommitExist)))
|
||||||
t.Run("CommitExist", makeTest(t, name, meta, inWriteTransaction(testCommitExist)))
|
t.Run("CommitExist", makeTest(t, name, meta, inWriteTransaction(testCommitExist)))
|
||||||
t.Run("CommitCommitted", makeTest(t, name, meta, inWriteTransaction(testCommitCommitted)))
|
t.Run("CommitCommitted", makeTest(t, name, meta, inWriteTransaction(testCommitCommitted)))
|
||||||
t.Run("CommitReadonly", makeTest(t, name, meta, inWriteTransaction(testCommitReadonly)))
|
t.Run("CommitViewFails", makeTest(t, name, meta, inWriteTransaction(testCommitViewFails)))
|
||||||
t.Run("Remove", makeTest(t, name, meta, inWriteTransaction(testRemove)))
|
t.Run("Remove", makeTest(t, name, meta, inWriteTransaction(testRemove)))
|
||||||
t.Run("RemoveNotExist", makeTest(t, name, meta, inWriteTransaction(testRemoveNotExist)))
|
t.Run("RemoveNotExist", makeTest(t, name, meta, inWriteTransaction(testRemoveNotExist)))
|
||||||
t.Run("RemoveWithChildren", makeTest(t, name, meta, inWriteTransaction(testRemoveWithChildren)))
|
t.Run("RemoveWithChildren", makeTest(t, name, meta, inWriteTransaction(testRemoveWithChildren)))
|
||||||
@ -126,31 +126,31 @@ func inWriteTransaction(fn testFunc) testFunc {
|
|||||||
// - "active-4": readonly active without parent"
|
// - "active-4": readonly active without parent"
|
||||||
// - "active-5": readonly active with parent "committed-2"
|
// - "active-5": readonly active with parent "committed-2"
|
||||||
func basePopulate(ctx context.Context, ms *MetaStore) error {
|
func basePopulate(ctx context.Context, ms *MetaStore) error {
|
||||||
if _, err := CreateActive(ctx, "committed-tmp-1", "", false); err != nil {
|
if _, err := CreateSnapshot(ctx, snapshot.KindActive, "committed-tmp-1", ""); err != nil {
|
||||||
return errors.Wrap(err, "failed to create active")
|
return errors.Wrap(err, "failed to create active")
|
||||||
}
|
}
|
||||||
if _, err := CommitActive(ctx, "committed-tmp-1", "committed-1", snapshot.Usage{Size: 1}); err != nil {
|
if _, err := CommitActive(ctx, "committed-tmp-1", "committed-1", snapshot.Usage{Size: 1}); err != nil {
|
||||||
return errors.Wrap(err, "failed to create active")
|
return errors.Wrap(err, "failed to create active")
|
||||||
}
|
}
|
||||||
if _, err := CreateActive(ctx, "committed-tmp-2", "committed-1", false); err != nil {
|
if _, err := CreateSnapshot(ctx, snapshot.KindActive, "committed-tmp-2", "committed-1"); err != nil {
|
||||||
return errors.Wrap(err, "failed to create active")
|
return errors.Wrap(err, "failed to create active")
|
||||||
}
|
}
|
||||||
if _, err := CommitActive(ctx, "committed-tmp-2", "committed-2", snapshot.Usage{Size: 2}); err != nil {
|
if _, err := CommitActive(ctx, "committed-tmp-2", "committed-2", snapshot.Usage{Size: 2}); err != nil {
|
||||||
return errors.Wrap(err, "failed to create active")
|
return errors.Wrap(err, "failed to create active")
|
||||||
}
|
}
|
||||||
if _, err := CreateActive(ctx, "active-1", "", false); err != nil {
|
if _, err := CreateSnapshot(ctx, snapshot.KindActive, "active-1", ""); err != nil {
|
||||||
return errors.Wrap(err, "failed to create active")
|
return errors.Wrap(err, "failed to create active")
|
||||||
}
|
}
|
||||||
if _, err := CreateActive(ctx, "active-2", "committed-1", false); err != nil {
|
if _, err := CreateSnapshot(ctx, snapshot.KindActive, "active-2", "committed-1"); err != nil {
|
||||||
return errors.Wrap(err, "failed to create active")
|
return errors.Wrap(err, "failed to create active")
|
||||||
}
|
}
|
||||||
if _, err := CreateActive(ctx, "active-3", "committed-2", false); err != nil {
|
if _, err := CreateSnapshot(ctx, snapshot.KindActive, "active-3", "committed-2"); err != nil {
|
||||||
return errors.Wrap(err, "failed to create active")
|
return errors.Wrap(err, "failed to create active")
|
||||||
}
|
}
|
||||||
if _, err := CreateActive(ctx, "active-4", "", true); err != nil {
|
if _, err := CreateSnapshot(ctx, snapshot.KindView, "view-1", ""); err != nil {
|
||||||
return errors.Wrap(err, "failed to create active")
|
return errors.Wrap(err, "failed to create active")
|
||||||
}
|
}
|
||||||
if _, err := CreateActive(ctx, "active-5", "committed-2", true); err != nil {
|
if _, err := CreateSnapshot(ctx, snapshot.KindView, "view-2", "committed-2"); err != nil {
|
||||||
return errors.Wrap(err, "failed to create active")
|
return errors.Wrap(err, "failed to create active")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -158,46 +158,39 @@ func basePopulate(ctx context.Context, ms *MetaStore) error {
|
|||||||
|
|
||||||
var baseInfo = map[string]snapshot.Info{
|
var baseInfo = map[string]snapshot.Info{
|
||||||
"committed-1": {
|
"committed-1": {
|
||||||
Name: "committed-1",
|
Name: "committed-1",
|
||||||
Parent: "",
|
Parent: "",
|
||||||
Kind: snapshot.KindCommitted,
|
Kind: snapshot.KindCommitted,
|
||||||
Readonly: true,
|
|
||||||
},
|
},
|
||||||
"committed-2": {
|
"committed-2": {
|
||||||
Name: "committed-2",
|
Name: "committed-2",
|
||||||
Parent: "committed-1",
|
Parent: "committed-1",
|
||||||
Kind: snapshot.KindCommitted,
|
Kind: snapshot.KindCommitted,
|
||||||
Readonly: true,
|
|
||||||
},
|
},
|
||||||
"active-1": {
|
"active-1": {
|
||||||
Name: "active-1",
|
Name: "active-1",
|
||||||
Parent: "",
|
Parent: "",
|
||||||
Kind: snapshot.KindActive,
|
Kind: snapshot.KindActive,
|
||||||
Readonly: false,
|
|
||||||
},
|
},
|
||||||
"active-2": {
|
"active-2": {
|
||||||
Name: "active-2",
|
Name: "active-2",
|
||||||
Parent: "committed-1",
|
Parent: "committed-1",
|
||||||
Kind: snapshot.KindActive,
|
Kind: snapshot.KindActive,
|
||||||
Readonly: false,
|
|
||||||
},
|
},
|
||||||
"active-3": {
|
"active-3": {
|
||||||
Name: "active-3",
|
Name: "active-3",
|
||||||
Parent: "committed-2",
|
Parent: "committed-2",
|
||||||
Kind: snapshot.KindActive,
|
Kind: snapshot.KindActive,
|
||||||
Readonly: false,
|
|
||||||
},
|
},
|
||||||
"active-4": {
|
"view-1": {
|
||||||
Name: "active-4",
|
Name: "view-1",
|
||||||
Parent: "",
|
Parent: "",
|
||||||
Kind: snapshot.KindActive,
|
Kind: snapshot.KindView,
|
||||||
Readonly: true,
|
|
||||||
},
|
},
|
||||||
"active-5": {
|
"view-2": {
|
||||||
Name: "active-5",
|
Name: "view-2",
|
||||||
Parent: "committed-2",
|
Parent: "committed-2",
|
||||||
Kind: snapshot.KindActive,
|
Kind: snapshot.KindView,
|
||||||
Readonly: true,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,10 +260,10 @@ func testWalk(ctx context.Context, t *testing.T, ms *MetaStore) {
|
|||||||
assert.Equal(t, baseInfo, found)
|
assert.Equal(t, baseInfo, found)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetActive(ctx context.Context, t *testing.T, ms *MetaStore) {
|
func testGetSnapshot(ctx context.Context, t *testing.T, ms *MetaStore) {
|
||||||
activeMap := map[string]Active{}
|
snapshotMap := map[string]Snapshot{}
|
||||||
populate := func(ctx context.Context, ms *MetaStore) error {
|
populate := func(ctx context.Context, ms *MetaStore) error {
|
||||||
if _, err := CreateActive(ctx, "committed-tmp-1", "", false); err != nil {
|
if _, err := CreateSnapshot(ctx, snapshot.KindActive, "committed-tmp-1", ""); err != nil {
|
||||||
return errors.Wrap(err, "failed to create active")
|
return errors.Wrap(err, "failed to create active")
|
||||||
}
|
}
|
||||||
if _, err := CommitActive(ctx, "committed-tmp-1", "committed-1", snapshot.Usage{}); err != nil {
|
if _, err := CommitActive(ctx, "committed-tmp-1", "committed-1", snapshot.Usage{}); err != nil {
|
||||||
@ -278,77 +271,79 @@ func testGetActive(ctx context.Context, t *testing.T, ms *MetaStore) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, opts := range []struct {
|
for _, opts := range []struct {
|
||||||
Name string
|
Kind snapshot.Kind
|
||||||
Parent string
|
Name string
|
||||||
Readonly bool
|
Parent string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
Name: "active-1",
|
Name: "active-1",
|
||||||
|
Kind: snapshot.KindActive,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "active-2",
|
Name: "active-2",
|
||||||
Parent: "committed-1",
|
Parent: "committed-1",
|
||||||
|
Kind: snapshot.KindActive,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "active-3",
|
Name: "view-1",
|
||||||
Readonly: true,
|
Kind: snapshot.KindView,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "active-4",
|
Name: "view-2",
|
||||||
Parent: "committed-1",
|
Parent: "committed-1",
|
||||||
Readonly: true,
|
Kind: snapshot.KindView,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
active, err := CreateActive(ctx, opts.Name, opts.Parent, opts.Readonly)
|
active, err := CreateSnapshot(ctx, opts.Kind, opts.Name, opts.Parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to create active")
|
return errors.Wrap(err, "failed to create active")
|
||||||
}
|
}
|
||||||
activeMap[opts.Name] = active
|
snapshotMap[opts.Name] = active
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
test := func(ctx context.Context, t *testing.T, ms *MetaStore) {
|
test := func(ctx context.Context, t *testing.T, ms *MetaStore) {
|
||||||
for key, expected := range activeMap {
|
for key, expected := range snapshotMap {
|
||||||
active, err := GetActive(ctx, key)
|
s, err := GetSnapshot(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to get active: %+v", err)
|
t.Fatalf("Failed to get active: %+v", err)
|
||||||
}
|
}
|
||||||
assert.Equal(t, expected, active)
|
assert.Equal(t, expected, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inReadTransaction(test, populate)(ctx, t, ms)
|
inReadTransaction(test, populate)(ctx, t, ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetActiveCommitted(ctx context.Context, t *testing.T, ms *MetaStore) {
|
func testGetSnapshotCommitted(ctx context.Context, t *testing.T, ms *MetaStore) {
|
||||||
_, err := GetActive(ctx, "committed-1")
|
_, err := GetSnapshot(ctx, "committed-1")
|
||||||
assertNotActive(t, err)
|
assertNotActive(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testGetActiveNotExist(ctx context.Context, t *testing.T, ms *MetaStore) {
|
func testGetSnapshotNotExist(ctx context.Context, t *testing.T, ms *MetaStore) {
|
||||||
_, err := GetActive(ctx, "active-not-exist")
|
_, err := GetSnapshot(ctx, "active-not-exist")
|
||||||
assertNotExist(t, err)
|
assertNotExist(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateActive(ctx context.Context, t *testing.T, ms *MetaStore) {
|
func testCreateActive(ctx context.Context, t *testing.T, ms *MetaStore) {
|
||||||
a1, err := CreateActive(ctx, "active-1", "", false)
|
a1, err := CreateSnapshot(ctx, snapshot.KindActive, "active-1", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if a1.Readonly {
|
if a1.Kind != snapshot.KindActive {
|
||||||
t.Fatal("Expected writable active")
|
t.Fatal("Expected writable active")
|
||||||
}
|
}
|
||||||
|
|
||||||
a2, err := CreateActive(ctx, "active-2", "", true)
|
a2, err := CreateSnapshot(ctx, snapshot.KindView, "view-1", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if a2.ID == a1.ID {
|
if a2.ID == a1.ID {
|
||||||
t.Fatal("Returned active identifiers must be unique")
|
t.Fatal("Returned active identifiers must be unique")
|
||||||
}
|
}
|
||||||
if !a2.Readonly {
|
if a2.Kind != snapshot.KindView {
|
||||||
t.Fatal("Expected readonly active")
|
t.Fatal("Expected a view")
|
||||||
}
|
}
|
||||||
|
|
||||||
commitID, err := CommitActive(ctx, "active-1", "committed-1", snapshot.Usage{})
|
commitID, err := CommitActive(ctx, "active-1", "committed-1", snapshot.Usage{})
|
||||||
@ -359,7 +354,7 @@ func testCreateActive(ctx context.Context, t *testing.T, ms *MetaStore) {
|
|||||||
t.Fatal("Snapshot identifier must not change on commit")
|
t.Fatal("Snapshot identifier must not change on commit")
|
||||||
}
|
}
|
||||||
|
|
||||||
a3, err := CreateActive(ctx, "active-3", "committed-1", false)
|
a3, err := CreateSnapshot(ctx, snapshot.KindActive, "active-3", "committed-1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -372,11 +367,11 @@ func testCreateActive(ctx context.Context, t *testing.T, ms *MetaStore) {
|
|||||||
if a3.ParentIDs[0] != commitID {
|
if a3.ParentIDs[0] != commitID {
|
||||||
t.Fatal("Expected active parent to be same as commit ID")
|
t.Fatal("Expected active parent to be same as commit ID")
|
||||||
}
|
}
|
||||||
if a3.Readonly {
|
if a3.Kind != snapshot.KindActive {
|
||||||
t.Fatal("Expected writable active")
|
t.Fatal("Expected writable active")
|
||||||
}
|
}
|
||||||
|
|
||||||
a4, err := CreateActive(ctx, "active-4", "committed-1", true)
|
a4, err := CreateSnapshot(ctx, snapshot.KindView, "view-2", "committed-1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -389,8 +384,8 @@ func testCreateActive(ctx context.Context, t *testing.T, ms *MetaStore) {
|
|||||||
if a3.ParentIDs[0] != commitID {
|
if a3.ParentIDs[0] != commitID {
|
||||||
t.Fatal("Expected active parent to be same as commit ID")
|
t.Fatal("Expected active parent to be same as commit ID")
|
||||||
}
|
}
|
||||||
if !a4.Readonly {
|
if a4.Kind != snapshot.KindView {
|
||||||
t.Fatal("Expected readonly active")
|
t.Fatal("Expected a view")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,14 +393,14 @@ func testCreateActiveExist(ctx context.Context, t *testing.T, ms *MetaStore) {
|
|||||||
if err := basePopulate(ctx, ms); err != nil {
|
if err := basePopulate(ctx, ms); err != nil {
|
||||||
t.Fatalf("Populate failed: %+v", err)
|
t.Fatalf("Populate failed: %+v", err)
|
||||||
}
|
}
|
||||||
_, err := CreateActive(ctx, "active-1", "", false)
|
_, err := CreateSnapshot(ctx, snapshot.KindActive, "active-1", "")
|
||||||
assertExist(t, err)
|
assertExist(t, err)
|
||||||
_, err = CreateActive(ctx, "committed-1", "", false)
|
_, err = CreateSnapshot(ctx, snapshot.KindActive, "committed-1", "")
|
||||||
assertExist(t, err)
|
assertExist(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateActiveNotExist(ctx context.Context, t *testing.T, ms *MetaStore) {
|
func testCreateActiveNotExist(ctx context.Context, t *testing.T, ms *MetaStore) {
|
||||||
_, err := CreateActive(ctx, "active-1", "does-not-exist", false)
|
_, err := CreateSnapshot(ctx, snapshot.KindActive, "active-1", "does-not-exist")
|
||||||
assertNotExist(t, err)
|
assertNotExist(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,16 +408,16 @@ func testCreateActiveFromActive(ctx context.Context, t *testing.T, ms *MetaStore
|
|||||||
if err := basePopulate(ctx, ms); err != nil {
|
if err := basePopulate(ctx, ms); err != nil {
|
||||||
t.Fatalf("Populate failed: %+v", err)
|
t.Fatalf("Populate failed: %+v", err)
|
||||||
}
|
}
|
||||||
_, err := CreateActive(ctx, "active-new", "active-1", false)
|
_, err := CreateSnapshot(ctx, snapshot.KindActive, "active-new", "active-1")
|
||||||
assertNotCommitted(t, err)
|
assertNotCommitted(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCommit(ctx context.Context, t *testing.T, ms *MetaStore) {
|
func testCommit(ctx context.Context, t *testing.T, ms *MetaStore) {
|
||||||
a1, err := CreateActive(ctx, "active-1", "", false)
|
a1, err := CreateSnapshot(ctx, snapshot.KindActive, "active-1", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if a1.Readonly {
|
if a1.Kind != snapshot.KindActive {
|
||||||
t.Fatal("Expected writable active")
|
t.Fatal("Expected writable active")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,9 +429,9 @@ func testCommit(ctx context.Context, t *testing.T, ms *MetaStore) {
|
|||||||
t.Fatal("Snapshot identifier must not change on commit")
|
t.Fatal("Snapshot identifier must not change on commit")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = GetActive(ctx, "active-1")
|
_, err = GetSnapshot(ctx, "active-1")
|
||||||
assertNotExist(t, err)
|
assertNotExist(t, err)
|
||||||
_, err = GetActive(ctx, "committed-1")
|
_, err = GetSnapshot(ctx, "committed-1")
|
||||||
assertNotActive(t, err)
|
assertNotActive(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,18 +456,18 @@ func testCommitCommitted(ctx context.Context, t *testing.T, ms *MetaStore) {
|
|||||||
assertNotActive(t, err)
|
assertNotActive(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCommitReadonly(ctx context.Context, t *testing.T, ms *MetaStore) {
|
func testCommitViewFails(ctx context.Context, t *testing.T, ms *MetaStore) {
|
||||||
if err := basePopulate(ctx, ms); err != nil {
|
if err := basePopulate(ctx, ms); err != nil {
|
||||||
t.Fatalf("Populate failed: %+v", err)
|
t.Fatalf("Populate failed: %+v", err)
|
||||||
}
|
}
|
||||||
_, err := CommitActive(ctx, "active-5", "committed-3", snapshot.Usage{})
|
_, err := CommitActive(ctx, "view-1", "committed-3", snapshot.Usage{})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("Expected error committing readonly active")
|
t.Fatal("Expected error committing readonly active")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRemove(ctx context.Context, t *testing.T, ms *MetaStore) {
|
func testRemove(ctx context.Context, t *testing.T, ms *MetaStore) {
|
||||||
a1, err := CreateActive(ctx, "active-1", "", false)
|
a1, err := CreateSnapshot(ctx, snapshot.KindActive, "active-1", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -485,12 +480,12 @@ func testRemove(ctx context.Context, t *testing.T, ms *MetaStore) {
|
|||||||
t.Fatal("Snapshot identifier must not change on commit")
|
t.Fatal("Snapshot identifier must not change on commit")
|
||||||
}
|
}
|
||||||
|
|
||||||
a2, err := CreateActive(ctx, "active-2", "committed-1", true)
|
a2, err := CreateSnapshot(ctx, snapshot.KindView, "view-1", "committed-1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
a3, err := CreateActive(ctx, "active-3", "committed-1", true)
|
a3, err := CreateSnapshot(ctx, snapshot.KindView, "view-2", "committed-1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -498,26 +493,26 @@ func testRemove(ctx context.Context, t *testing.T, ms *MetaStore) {
|
|||||||
_, _, err = Remove(ctx, "active-1")
|
_, _, err = Remove(ctx, "active-1")
|
||||||
assertNotExist(t, err)
|
assertNotExist(t, err)
|
||||||
|
|
||||||
r3, k3, err := Remove(ctx, "active-3")
|
r3, k3, err := Remove(ctx, "view-2")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if r3 != a3.ID {
|
if r3 != a3.ID {
|
||||||
t.Fatal("Expected remove ID to match create ID")
|
t.Fatal("Expected remove ID to match create ID")
|
||||||
}
|
}
|
||||||
if k3 != snapshot.KindActive {
|
if k3 != snapshot.KindView {
|
||||||
t.Fatalf("Expected active kind, got %v", k3)
|
t.Fatalf("Expected view kind, got %v", k3)
|
||||||
}
|
}
|
||||||
|
|
||||||
r2, k2, err := Remove(ctx, "active-2")
|
r2, k2, err := Remove(ctx, "view-1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if r2 != a2.ID {
|
if r2 != a2.ID {
|
||||||
t.Fatal("Expected remove ID to match create ID")
|
t.Fatal("Expected remove ID to match create ID")
|
||||||
}
|
}
|
||||||
if k2 != snapshot.KindActive {
|
if k2 != snapshot.KindView {
|
||||||
t.Fatalf("Expected active kind, got %v", k2)
|
t.Fatalf("Expected view kind, got %v", k2)
|
||||||
}
|
}
|
||||||
|
|
||||||
r1, k1, err := Remove(ctx, "committed-1")
|
r1, k1, err := Remove(ctx, "committed-1")
|
||||||
|
@ -34,23 +34,26 @@ var _ = math.Inf
|
|||||||
// proto package needs to be updated.
|
// proto package needs to be updated.
|
||||||
const _ = proto1.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
const _ = proto1.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
||||||
|
|
||||||
// Kind defines the kind of snapshot.
|
|
||||||
type Kind int32
|
type Kind int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// KindActive represents an active snapshot
|
KindUnknown Kind = 0
|
||||||
KindActive Kind = 0
|
KindView Kind = 1
|
||||||
// KindCommitted represents a committed immutable snapshot
|
KindActive Kind = 2
|
||||||
KindCommitted Kind = 1
|
KindCommitted Kind = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
var Kind_name = map[int32]string{
|
var Kind_name = map[int32]string{
|
||||||
0: "ACTIVE",
|
0: "UNKNOWN",
|
||||||
1: "COMMITTED",
|
1: "VIEW",
|
||||||
|
2: "ACTIVE",
|
||||||
|
3: "COMMITTED",
|
||||||
}
|
}
|
||||||
var Kind_value = map[string]int32{
|
var Kind_value = map[string]int32{
|
||||||
"ACTIVE": 0,
|
"UNKNOWN": 0,
|
||||||
"COMMITTED": 1,
|
"VIEW": 1,
|
||||||
|
"ACTIVE": 2,
|
||||||
|
"COMMITTED": 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x Kind) String() string {
|
func (x Kind) String() string {
|
||||||
@ -61,10 +64,9 @@ func (Kind) EnumDescriptor() ([]byte, []int) { return fileDescriptorRecord, []in
|
|||||||
// Snapshot defines the storage type for a snapshot in the
|
// Snapshot defines the storage type for a snapshot in the
|
||||||
// metadata store.
|
// metadata store.
|
||||||
type Snapshot struct {
|
type Snapshot struct {
|
||||||
ID uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
ID uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||||
Parent string `protobuf:"bytes,2,opt,name=parent,proto3" json:"parent,omitempty"`
|
Parent string `protobuf:"bytes,2,opt,name=parent,proto3" json:"parent,omitempty"`
|
||||||
Kind Kind `protobuf:"varint,4,opt,name=kind,proto3,enum=containerd.snapshot.v1.Kind" json:"kind,omitempty"`
|
Kind Kind `protobuf:"varint,4,opt,name=kind,proto3,enum=containerd.snapshot.v1.Kind" json:"kind,omitempty"`
|
||||||
Readonly bool `protobuf:"varint,5,opt,name=readonly,proto3" json:"readonly,omitempty"`
|
|
||||||
// inodes stores the number inodes in use for the snapshot.
|
// inodes stores the number inodes in use for the snapshot.
|
||||||
//
|
//
|
||||||
// Only valid for committed snapshots.
|
// Only valid for committed snapshots.
|
||||||
@ -115,16 +117,6 @@ func (m *Snapshot) MarshalTo(dAtA []byte) (int, error) {
|
|||||||
i++
|
i++
|
||||||
i = encodeVarintRecord(dAtA, i, uint64(m.Kind))
|
i = encodeVarintRecord(dAtA, i, uint64(m.Kind))
|
||||||
}
|
}
|
||||||
if m.Readonly {
|
|
||||||
dAtA[i] = 0x28
|
|
||||||
i++
|
|
||||||
if m.Readonly {
|
|
||||||
dAtA[i] = 1
|
|
||||||
} else {
|
|
||||||
dAtA[i] = 0
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if m.Inodes != 0 {
|
if m.Inodes != 0 {
|
||||||
dAtA[i] = 0x30
|
dAtA[i] = 0x30
|
||||||
i++
|
i++
|
||||||
@ -178,9 +170,6 @@ func (m *Snapshot) Size() (n int) {
|
|||||||
if m.Kind != 0 {
|
if m.Kind != 0 {
|
||||||
n += 1 + sovRecord(uint64(m.Kind))
|
n += 1 + sovRecord(uint64(m.Kind))
|
||||||
}
|
}
|
||||||
if m.Readonly {
|
|
||||||
n += 2
|
|
||||||
}
|
|
||||||
if m.Inodes != 0 {
|
if m.Inodes != 0 {
|
||||||
n += 1 + sovRecord(uint64(m.Inodes))
|
n += 1 + sovRecord(uint64(m.Inodes))
|
||||||
}
|
}
|
||||||
@ -211,7 +200,6 @@ func (this *Snapshot) String() string {
|
|||||||
`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
|
`ID:` + fmt.Sprintf("%v", this.ID) + `,`,
|
||||||
`Parent:` + fmt.Sprintf("%v", this.Parent) + `,`,
|
`Parent:` + fmt.Sprintf("%v", this.Parent) + `,`,
|
||||||
`Kind:` + fmt.Sprintf("%v", this.Kind) + `,`,
|
`Kind:` + fmt.Sprintf("%v", this.Kind) + `,`,
|
||||||
`Readonly:` + fmt.Sprintf("%v", this.Readonly) + `,`,
|
|
||||||
`Inodes:` + fmt.Sprintf("%v", this.Inodes) + `,`,
|
`Inodes:` + fmt.Sprintf("%v", this.Inodes) + `,`,
|
||||||
`Size_:` + fmt.Sprintf("%v", this.Size_) + `,`,
|
`Size_:` + fmt.Sprintf("%v", this.Size_) + `,`,
|
||||||
`}`,
|
`}`,
|
||||||
@ -322,26 +310,6 @@ func (m *Snapshot) Unmarshal(dAtA []byte) error {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 5:
|
|
||||||
if wireType != 0 {
|
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field Readonly", wireType)
|
|
||||||
}
|
|
||||||
var v int
|
|
||||||
for shift := uint(0); ; shift += 7 {
|
|
||||||
if shift >= 64 {
|
|
||||||
return ErrIntOverflowRecord
|
|
||||||
}
|
|
||||||
if iNdEx >= l {
|
|
||||||
return io.ErrUnexpectedEOF
|
|
||||||
}
|
|
||||||
b := dAtA[iNdEx]
|
|
||||||
iNdEx++
|
|
||||||
v |= (int(b) & 0x7F) << shift
|
|
||||||
if b < 0x80 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m.Readonly = bool(v != 0)
|
|
||||||
case 6:
|
case 6:
|
||||||
if wireType != 0 {
|
if wireType != 0 {
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field Inodes", wireType)
|
return fmt.Errorf("proto: wrong wireType = %d for field Inodes", wireType)
|
||||||
@ -511,26 +479,28 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var fileDescriptorRecord = []byte{
|
var fileDescriptorRecord = []byte{
|
||||||
// 334 bytes of a gzipped FileDescriptorProto
|
// 364 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xbb, 0x4e, 0xf3, 0x30,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xbb, 0xae, 0xd3, 0x30,
|
||||||
0x1c, 0xc5, 0xe3, 0x7c, 0xf9, 0x42, 0x6b, 0x41, 0x55, 0x2c, 0x54, 0x59, 0x11, 0x32, 0x16, 0x53,
|
0x18, 0xc7, 0xe3, 0x9c, 0x28, 0xe7, 0xd4, 0x94, 0x12, 0x2c, 0x14, 0x45, 0x51, 0x65, 0x2c, 0xa6,
|
||||||
0xc4, 0x90, 0x70, 0x79, 0x82, 0xde, 0x86, 0xaa, 0xaa, 0x90, 0x42, 0xc5, 0x9e, 0xc6, 0x56, 0x6a,
|
0x88, 0x21, 0xe1, 0xf2, 0x04, 0xbd, 0x0d, 0x51, 0xd5, 0x56, 0x0a, 0xbd, 0xcc, 0x69, 0x6c, 0xa5,
|
||||||
0x41, 0xed, 0xca, 0x31, 0x95, 0x60, 0x62, 0x44, 0x7d, 0x87, 0x4e, 0xf0, 0x08, 0x4c, 0x3c, 0x41,
|
0x56, 0x55, 0xbb, 0x4a, 0x4c, 0x2b, 0x31, 0x31, 0x56, 0x79, 0x02, 0x96, 0x4c, 0xf0, 0x14, 0x3c,
|
||||||
0x47, 0x46, 0x26, 0x44, 0xf3, 0x24, 0x28, 0x69, 0xb9, 0x0c, 0x6c, 0xe7, 0xf7, 0xf7, 0x4f, 0xe7,
|
0x41, 0x47, 0x46, 0x26, 0x44, 0xf3, 0x24, 0x28, 0x69, 0x11, 0x0c, 0x67, 0xfb, 0x5f, 0x7e, 0xf6,
|
||||||
0x48, 0x86, 0x9d, 0x54, 0x98, 0xf1, 0xcd, 0x28, 0x48, 0xd4, 0x24, 0x4c, 0x94, 0x34, 0xb1, 0x90,
|
0xf7, 0xe9, 0x83, 0xc3, 0x94, 0xab, 0xcd, 0xc7, 0xb5, 0x9f, 0xc8, 0x5d, 0x90, 0x48, 0xa1, 0x62,
|
||||||
0x5c, 0xb3, 0xdf, 0x31, 0x93, 0xf1, 0x34, 0x1b, 0x2b, 0x13, 0x66, 0x46, 0xe9, 0x38, 0xe5, 0xe1,
|
0x2e, 0x58, 0x46, 0xff, 0x97, 0xb9, 0x88, 0xf7, 0xf9, 0x46, 0xaa, 0x20, 0x57, 0x32, 0x8b, 0x53,
|
||||||
0x54, 0x2b, 0xa3, 0x42, 0xcd, 0x13, 0xa5, 0x59, 0x50, 0x02, 0x6a, 0xfc, 0xf8, 0xc1, 0x97, 0x1f,
|
0x16, 0xec, 0x33, 0xa9, 0x64, 0x90, 0xb1, 0x44, 0x66, 0xd4, 0x6f, 0x0c, 0xb2, 0xff, 0xf1, 0xfe,
|
||||||
0xcc, 0x4e, 0xbc, 0xbd, 0x54, 0xa5, 0x6a, 0xed, 0x17, 0x69, 0x6d, 0x1f, 0x3e, 0x03, 0x58, 0xb9,
|
0x5f, 0xde, 0x3f, 0xbc, 0x75, 0x5f, 0xa4, 0x32, 0x95, 0x57, 0xbe, 0x56, 0x57, 0xfa, 0xd5, 0x17,
|
||||||
0xd8, 0x58, 0xa8, 0x01, 0x6d, 0xc1, 0x30, 0xa0, 0xc0, 0x77, 0x5a, 0x6e, 0xfe, 0x7e, 0x60, 0xf7,
|
0x00, 0x1f, 0x3e, 0xdc, 0x28, 0x64, 0x43, 0x9d, 0x53, 0x07, 0x10, 0xe0, 0x19, 0x7d, 0xb3, 0xfa,
|
||||||
0x3a, 0x91, 0x2d, 0x18, 0x6a, 0x40, 0x77, 0x1a, 0x6b, 0x2e, 0x0d, 0xb6, 0x29, 0xf0, 0xab, 0xd1,
|
0xf5, 0x52, 0x0f, 0x87, 0x91, 0xce, 0x29, 0xb2, 0xa1, 0xb9, 0x8f, 0x33, 0x26, 0x94, 0xa3, 0x13,
|
||||||
0x86, 0xd0, 0x31, 0x74, 0xae, 0x84, 0x64, 0xd8, 0xa1, 0xc0, 0xaf, 0x9d, 0xee, 0x07, 0x7f, 0x2f,
|
0xe0, 0xb5, 0xa2, 0x9b, 0x43, 0x6f, 0xa0, 0xb1, 0xe5, 0x82, 0x3a, 0x06, 0x01, 0x5e, 0xe7, 0x5d,
|
||||||
0x07, 0x7d, 0x21, 0x59, 0x54, 0x9a, 0xc8, 0x83, 0x15, 0xcd, 0x63, 0xa6, 0xe4, 0xf5, 0x2d, 0xfe,
|
0xd7, 0x7f, 0x7c, 0xb2, 0x3f, 0xe6, 0x82, 0x46, 0x0d, 0x59, 0xff, 0xc4, 0x85, 0xa4, 0x2c, 0x77,
|
||||||
0x4f, 0x81, 0x5f, 0x89, 0xbe, 0xb9, 0x58, 0x11, 0x52, 0x31, 0x9e, 0x61, 0x97, 0x02, 0xff, 0x5f,
|
0x4c, 0x02, 0xbc, 0xbb, 0xe8, 0xe6, 0x10, 0x82, 0x46, 0xce, 0x3f, 0x31, 0xe7, 0xbe, 0x49, 0x1b,
|
||||||
0xb4, 0x21, 0x84, 0xa0, 0x93, 0x89, 0x3b, 0x8e, 0xb7, 0xca, 0x6b, 0x99, 0x8f, 0x22, 0xe8, 0xf4,
|
0xfd, 0xfa, 0x04, 0xa0, 0x51, 0x3f, 0x45, 0x5d, 0x78, 0xbf, 0x98, 0x8e, 0xa7, 0xb3, 0xd5, 0xd4,
|
||||||
0xd7, 0x7d, 0x6e, 0xb3, 0x3d, 0xec, 0x5d, 0x76, 0xeb, 0x96, 0x57, 0x9b, 0x2f, 0x28, 0x2c, 0xae,
|
0xd2, 0xdc, 0x67, 0x45, 0x49, 0x9e, 0xd4, 0xf1, 0x42, 0x6c, 0x85, 0x3c, 0x0a, 0x64, 0x43, 0x63,
|
||||||
0xcd, 0xc4, 0x88, 0x19, 0x47, 0x14, 0x56, 0xdb, 0xe7, 0x83, 0x41, 0x6f, 0x38, 0xec, 0x76, 0xea,
|
0x19, 0x8e, 0x56, 0x16, 0x70, 0xdb, 0x45, 0x49, 0x1e, 0xea, 0x6a, 0xc9, 0xd9, 0x11, 0xb9, 0xd0,
|
||||||
0xc0, 0xdb, 0x9d, 0x2f, 0xe8, 0x4e, 0xf1, 0xdc, 0x56, 0x93, 0x89, 0x30, 0x86, 0x33, 0x6f, 0xfb,
|
0xec, 0x0d, 0xe6, 0xe1, 0x72, 0x64, 0xe9, 0x6e, 0xa7, 0x28, 0x09, 0xac, 0x9b, 0x5e, 0xa2, 0xf8,
|
||||||
0xe1, 0x91, 0x58, 0x2f, 0x4f, 0xa4, 0xec, 0x6a, 0xe1, 0xe5, 0x8a, 0x58, 0x6f, 0x2b, 0x62, 0xdd,
|
0x81, 0x21, 0x02, 0x5b, 0x83, 0xd9, 0x64, 0x12, 0xce, 0xe7, 0xa3, 0xa1, 0x75, 0xe7, 0x3e, 0x2f,
|
||||||
0xe7, 0x04, 0x2c, 0x73, 0x02, 0x5e, 0x73, 0x02, 0x3e, 0x72, 0x02, 0x46, 0x6e, 0xf9, 0x57, 0x67,
|
0x4a, 0xf2, 0xb4, 0xae, 0x07, 0x72, 0xb7, 0xe3, 0x4a, 0x31, 0xea, 0xb6, 0x4f, 0x5f, 0xb1, 0xf6,
|
||||||
0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xae, 0x6e, 0x6e, 0xcd, 0xa1, 0x01, 0x00, 0x00,
|
0xfd, 0x1b, 0x6e, 0x36, 0xe8, 0x3b, 0xe7, 0x0b, 0xd6, 0x7e, 0x5e, 0xb0, 0xf6, 0xb9, 0xc2, 0xe0,
|
||||||
|
0x5c, 0x61, 0xf0, 0xa3, 0xc2, 0xe0, 0x77, 0x85, 0xc1, 0xda, 0x6c, 0xce, 0xf8, 0xfe, 0x4f, 0x00,
|
||||||
|
0x00, 0x00, 0xff, 0xff, 0x61, 0xef, 0x92, 0x3d, 0xbc, 0x01, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,14 @@ package containerd.snapshot.v1;
|
|||||||
|
|
||||||
import "gogoproto/gogo.proto";
|
import "gogoproto/gogo.proto";
|
||||||
|
|
||||||
// Kind defines the kind of snapshot.
|
|
||||||
enum Kind {
|
enum Kind {
|
||||||
option (gogoproto.goproto_enum_prefix) = false;
|
option (gogoproto.goproto_enum_prefix) = false;
|
||||||
option (gogoproto.enum_customname) = "Kind";
|
option (gogoproto.enum_customname) = "Kind";
|
||||||
|
|
||||||
// KindActive represents an active snapshot
|
UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "KindUnknown"];
|
||||||
ACTIVE = 0 [(gogoproto.enumvalue_customname) = "KindActive"];
|
VIEW = 1 [(gogoproto.enumvalue_customname) = "KindView"];
|
||||||
|
ACTIVE = 2 [(gogoproto.enumvalue_customname) = "KindActive"];
|
||||||
// KindCommitted represents a committed immutable snapshot
|
COMMITTED = 3 [(gogoproto.enumvalue_customname) = "KindCommitted"];
|
||||||
COMMITTED = 1 [(gogoproto.enumvalue_customname) = "KindCommitted"];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Snapshot defines the storage type for a snapshot in the
|
// Snapshot defines the storage type for a snapshot in the
|
||||||
@ -22,7 +20,6 @@ message Snapshot {
|
|||||||
uint64 id = 1;
|
uint64 id = 1;
|
||||||
string parent = 2;
|
string parent = 2;
|
||||||
Kind kind = 4;
|
Kind kind = 4;
|
||||||
bool readonly = 5;
|
|
||||||
|
|
||||||
// inodes stores the number inodes in use for the snapshot.
|
// inodes stores the number inodes in use for the snapshot.
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user