Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
| ... | ... |
@@ -14,7 +14,7 @@ github.com/sirupsen/logrus v1.0.6 |
| 14 | 14 |
github.com/tchap/go-patricia v2.2.6 |
| 15 | 15 |
github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3 |
| 16 | 16 |
golang.org/x/net a680a1efc54dd51c040b3b5ce4939ea3cf2ea0d1 |
| 17 |
-golang.org/x/sys 41f3e6584952bb034a481797859f6ab34b6803bd |
|
| 17 |
+golang.org/x/sys d455e41777fca6e8a5a79e34a14b8368bc11d9ba |
|
| 18 | 18 |
github.com/docker/go-units 47565b4f722fb6ceae66b95f853feed578a4a51c # v0.3.3 |
| 19 | 19 |
github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0 |
| 20 | 20 |
golang.org/x/text f21a4dfb5e38f5895301dc265a8def02365cc3d0 # v0.3.0 |
| ... | ... |
@@ -119,14 +119,14 @@ github.com/googleapis/gax-go v2.0.0 |
| 119 | 119 |
google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9 |
| 120 | 120 |
|
| 121 | 121 |
# containerd |
| 122 |
-github.com/containerd/containerd bb71b10fd8f58240ca47fbb579b9d1028eea7c84 # v1.2.5 |
|
| 122 |
+github.com/containerd/containerd a15b6e2097c48b632dbdc63254bad4c62b69e709 |
|
| 123 | 123 |
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c |
| 124 | 124 |
github.com/containerd/continuity 004b46473808b3e7a4a3049c20e4376c91eb966d |
| 125 | 125 |
github.com/containerd/cgroups dbea6f2bd41658b84b00417ceefa416b979cbf10 |
| 126 | 126 |
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23 |
| 127 | 127 |
github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3 |
| 128 | 128 |
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40 |
| 129 |
-github.com/containerd/ttrpc 2a805f71863501300ae1976d29f0454ae003e85a |
|
| 129 |
+github.com/containerd/ttrpc f02858b1457c5ca3aaec3a0803eb0d59f96e41d6 |
|
| 130 | 130 |
github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef |
| 131 | 131 |
|
| 132 | 132 |
# cluster |
| ... | ... |
@@ -172,11 +172,9 @@ checkpoint, err := task.Checkpoint(context) |
| 172 | 172 |
err := client.Push(context, "myregistry/checkpoints/redis:master", checkpoint) |
| 173 | 173 |
|
| 174 | 174 |
// on a new machine pull the checkpoint and restore the redis container |
| 175 |
-image, err := client.Pull(context, "myregistry/checkpoints/redis:master") |
|
| 175 |
+checkpoint, err := client.Pull(context, "myregistry/checkpoints/redis:master") |
|
| 176 | 176 |
|
| 177 |
-checkpoint := image.Target() |
|
| 178 |
- |
|
| 179 |
-redis, err = client.NewContainer(context, "redis-master", containerd.WithCheckpoint(checkpoint, "redis-rootfs")) |
|
| 177 |
+redis, err = client.NewContainer(context, "redis-master", containerd.WithNewSnapshot("redis-rootfs", checkpoint))
|
|
| 180 | 178 |
defer container.Delete(context) |
| 181 | 179 |
|
| 182 | 180 |
task, err = redis.NewTask(context, cio.Stdio, containerd.WithTaskCheckpoint(checkpoint)) |
| ... | ... |
@@ -212,11 +210,6 @@ See [PLUGINS.md](PLUGINS.md) for how to create plugins |
| 212 | 212 |
Please see [RELEASES.md](RELEASES.md) for details on versioning and stability |
| 213 | 213 |
of containerd components. |
| 214 | 214 |
|
| 215 |
-### Development reports. |
|
| 216 |
- |
|
| 217 |
-Weekly summary on the progress and what is being worked on. |
|
| 218 |
-https://github.com/containerd/containerd/tree/master/reports |
|
| 219 |
- |
|
| 220 | 215 |
### Communication |
| 221 | 216 |
|
| 222 | 217 |
For async communication and long running discussions please use issues and pull requests on the github repo. |
| ... | ... |
@@ -224,7 +217,12 @@ This will be the best place to discuss design and implementation. |
| 224 | 224 |
|
| 225 | 225 |
For sync communication we have a community slack with a #containerd channel that everyone is welcome to join and chat about development. |
| 226 | 226 |
|
| 227 |
-**Slack:** https://join.slack.com/t/dockercommunity/shared_invite/enQtNDM4NjAwNDMyOTUwLWZlMDZmYWRjZjk4Zjc5ZGQ5NWZkOWI1Yjk2NGE3ZWVlYjYxM2VhYjczOWIyZDFhZTE3NTUwZWQzMjhmNGYyZTg |
|
| 227 |
+**Slack:** Catch us in the #containerd and #containerd-dev channels on dockercommunity.slack.com. |
|
| 228 |
+[Click here for an invite to docker community slack.](https://join.slack.com/t/dockercommunity/shared_invite/enQtNDY4MDc1Mzc0MzIwLTgxZDBlMmM4ZGEyNDc1N2FkMzlhODJkYmE1YTVkYjM1MDE3ZjAwZjBkOGFlOTJkZjRmZGYzNjYyY2M3ZTUxYzQ) |
|
| 229 |
+ |
|
| 230 |
+### Security audit |
|
| 231 |
+ |
|
| 232 |
+A third party security audit was performed by Cure53 in 4Q2018; the [full report](docs/SECURITY_AUDIT.pdf) is available in our docs/ directory. |
|
| 228 | 233 |
|
| 229 | 234 |
### Reporting security issues |
| 230 | 235 |
|
| ... | ... |
@@ -249,3 +247,8 @@ Please find all these core project documents, including the: |
| 249 | 249 |
* and [Contributing guidelines](https://github.com/containerd/project/blob/master/CONTRIBUTING.md) |
| 250 | 250 |
|
| 251 | 251 |
information in our [`containerd/project`](https://github.com/containerd/project) repository. |
| 252 |
+ |
|
| 253 |
+## Adoption |
|
| 254 |
+ |
|
| 255 |
+Interested to see who is using containerd? Are you using containerd in a project? |
|
| 256 |
+Please add yourself via pull request to our [ADOPTERS.md](./ADOPTERS.md) file. |
| ... | ... |
@@ -55,6 +55,9 @@ type TaskDelete struct {
|
| 55 | 55 |
Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"` |
| 56 | 56 |
ExitStatus uint32 `protobuf:"varint,3,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"` |
| 57 | 57 |
ExitedAt time.Time `protobuf:"bytes,4,opt,name=exited_at,json=exitedAt,stdtime" json:"exited_at"` |
| 58 |
+ // id is the specific exec. By default if omitted will be `""` thus matches |
|
| 59 |
+ // the init exec of the task matching `container_id`. |
|
| 60 |
+ ID string `protobuf:"bytes,5,opt,name=id,proto3" json:"id,omitempty"` |
|
| 58 | 61 |
} |
| 59 | 62 |
|
| 60 | 63 |
func (m *TaskDelete) Reset() { *m = TaskDelete{} }
|
| ... | ... |
@@ -210,6 +213,8 @@ func (m *TaskDelete) Field(fieldpath []string) (string, bool) {
|
| 210 | 210 |
// unhandled: exited_at |
| 211 | 211 |
case "container_id": |
| 212 | 212 |
return string(m.ContainerID), len(m.ContainerID) > 0 |
| 213 |
+ case "id": |
|
| 214 |
+ return string(m.ID), len(m.ID) > 0 |
|
| 213 | 215 |
} |
| 214 | 216 |
return "", false |
| 215 | 217 |
} |
| ... | ... |
@@ -474,6 +479,12 @@ func (m *TaskDelete) MarshalTo(dAtA []byte) (int, error) {
|
| 474 | 474 |
return 0, err |
| 475 | 475 |
} |
| 476 | 476 |
i += n2 |
| 477 |
+ if len(m.ID) > 0 {
|
|
| 478 |
+ dAtA[i] = 0x2a |
|
| 479 |
+ i++ |
|
| 480 |
+ i = encodeVarintTask(dAtA, i, uint64(len(m.ID))) |
|
| 481 |
+ i += copy(dAtA[i:], m.ID) |
|
| 482 |
+ } |
|
| 477 | 483 |
return i, nil |
| 478 | 484 |
} |
| 479 | 485 |
|
| ... | ... |
@@ -806,6 +817,10 @@ func (m *TaskDelete) Size() (n int) {
|
| 806 | 806 |
} |
| 807 | 807 |
l = types.SizeOfStdTime(m.ExitedAt) |
| 808 | 808 |
n += 1 + l + sovTask(uint64(l)) |
| 809 |
+ l = len(m.ID) |
|
| 810 |
+ if l > 0 {
|
|
| 811 |
+ n += 1 + l + sovTask(uint64(l)) |
|
| 812 |
+ } |
|
| 809 | 813 |
return n |
| 810 | 814 |
} |
| 811 | 815 |
|
| ... | ... |
@@ -975,6 +990,7 @@ func (this *TaskDelete) String() string {
|
| 975 | 975 |
`Pid:` + fmt.Sprintf("%v", this.Pid) + `,`,
|
| 976 | 976 |
`ExitStatus:` + fmt.Sprintf("%v", this.ExitStatus) + `,`,
|
| 977 | 977 |
`ExitedAt:` + strings.Replace(strings.Replace(this.ExitedAt.String(), "Timestamp", "google_protobuf2.Timestamp", 1), `&`, ``, 1) + `,`, |
| 978 |
+ `ID:` + fmt.Sprintf("%v", this.ID) + `,`,
|
|
| 978 | 979 |
`}`, |
| 979 | 980 |
}, "") |
| 980 | 981 |
return s |
| ... | ... |
@@ -1522,6 +1538,35 @@ func (m *TaskDelete) Unmarshal(dAtA []byte) error {
|
| 1522 | 1522 |
return err |
| 1523 | 1523 |
} |
| 1524 | 1524 |
iNdEx = postIndex |
| 1525 |
+ case 5: |
|
| 1526 |
+ if wireType != 2 {
|
|
| 1527 |
+ return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
|
|
| 1528 |
+ } |
|
| 1529 |
+ var stringLen uint64 |
|
| 1530 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1531 |
+ if shift >= 64 {
|
|
| 1532 |
+ return ErrIntOverflowTask |
|
| 1533 |
+ } |
|
| 1534 |
+ if iNdEx >= l {
|
|
| 1535 |
+ return io.ErrUnexpectedEOF |
|
| 1536 |
+ } |
|
| 1537 |
+ b := dAtA[iNdEx] |
|
| 1538 |
+ iNdEx++ |
|
| 1539 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 1540 |
+ if b < 0x80 {
|
|
| 1541 |
+ break |
|
| 1542 |
+ } |
|
| 1543 |
+ } |
|
| 1544 |
+ intStringLen := int(stringLen) |
|
| 1545 |
+ if intStringLen < 0 {
|
|
| 1546 |
+ return ErrInvalidLengthTask |
|
| 1547 |
+ } |
|
| 1548 |
+ postIndex := iNdEx + intStringLen |
|
| 1549 |
+ if postIndex > l {
|
|
| 1550 |
+ return io.ErrUnexpectedEOF |
|
| 1551 |
+ } |
|
| 1552 |
+ m.ID = string(dAtA[iNdEx:postIndex]) |
|
| 1553 |
+ iNdEx = postIndex |
|
| 1525 | 1554 |
default: |
| 1526 | 1555 |
iNdEx = preIndex |
| 1527 | 1556 |
skippy, err := skipTask(dAtA[iNdEx:]) |
| ... | ... |
@@ -2566,45 +2611,46 @@ func init() {
|
| 2566 | 2566 |
} |
| 2567 | 2567 |
|
| 2568 | 2568 |
var fileDescriptorTask = []byte{
|
| 2569 |
- // 637 bytes of a gzipped FileDescriptorProto |
|
| 2569 |
+ // 644 bytes of a gzipped FileDescriptorProto |
|
| 2570 | 2570 |
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x95, 0xcd, 0x6e, 0xd3, 0x40, |
| 2571 |
- 0x10, 0xc7, 0x63, 0xa7, 0x75, 0x93, 0x09, 0x55, 0x8b, 0x55, 0x41, 0xc8, 0xc1, 0x8e, 0xcc, 0x25, |
|
| 2572 |
- 0x27, 0x5b, 0x04, 0x89, 0x0b, 0x42, 0x6a, 0xd2, 0x70, 0xc8, 0xa1, 0x4a, 0x71, 0x7b, 0xa8, 0xb8, |
|
| 2573 |
- 0x44, 0x4e, 0x76, 0x93, 0x2c, 0x8d, 0xbd, 0x96, 0x3d, 0x46, 0x45, 0xe2, 0xc0, 0x23, 0xf0, 0x08, |
|
| 2574 |
- 0x3c, 0x05, 0xcf, 0xd0, 0x03, 0x07, 0x8e, 0x9c, 0x02, 0xf5, 0x03, 0x70, 0xe2, 0x01, 0xd0, 0x7a, |
|
| 2575 |
- 0x1d, 0xb7, 0x50, 0xf1, 0x65, 0x89, 0x53, 0x76, 0x66, 0x67, 0xff, 0x33, 0xf3, 0xdb, 0xc9, 0x1a, |
|
| 2576 |
- 0x1e, 0xcd, 0x19, 0x2e, 0x92, 0x89, 0x3d, 0xe5, 0xbe, 0x33, 0xe5, 0x01, 0x7a, 0x2c, 0xa0, 0x11, |
|
| 2577 |
- 0xb9, 0xbe, 0xf4, 0x42, 0xe6, 0xd0, 0x97, 0x34, 0xc0, 0xd8, 0x41, 0x2f, 0x3e, 0xb3, 0xc3, 0x88, |
|
| 2578 |
- 0x23, 0xd7, 0x6f, 0x5f, 0x45, 0xd8, 0x72, 0xb7, 0xb5, 0x37, 0xe7, 0x73, 0x9e, 0xed, 0x3a, 0x62, |
|
| 2579 |
- 0x25, 0x03, 0x5b, 0xe6, 0x9c, 0xf3, 0xf9, 0x92, 0x3a, 0x99, 0x35, 0x49, 0x66, 0x0e, 0x32, 0x9f, |
|
| 2580 |
- 0xc6, 0xe8, 0xf9, 0x61, 0x1e, 0xf0, 0x77, 0x15, 0xe0, 0xab, 0x90, 0xc6, 0x8e, 0xcf, 0x93, 0x00, |
|
| 2581 |
- 0xf3, 0x73, 0xfb, 0x7f, 0x3c, 0x57, 0xa4, 0x0c, 0x97, 0xc9, 0x9c, 0x05, 0xce, 0x8c, 0xd1, 0x25, |
|
| 2582 |
- 0x09, 0x3d, 0x5c, 0x48, 0x05, 0xeb, 0xab, 0x02, 0x70, 0xe2, 0xc5, 0x67, 0x07, 0x11, 0xf5, 0x90, |
|
| 2583 |
- 0xea, 0x5d, 0xb8, 0x55, 0x1c, 0x1e, 0x33, 0xd2, 0x54, 0xda, 0x4a, 0xa7, 0xde, 0xdf, 0x49, 0x57, |
|
| 2584 |
- 0x66, 0xe3, 0x60, 0xed, 0x1f, 0x0e, 0xdc, 0x46, 0x11, 0x34, 0x24, 0xfa, 0x1d, 0xd0, 0x26, 0x49, |
|
| 2585 |
- 0x40, 0x96, 0xb4, 0xa9, 0x8a, 0x68, 0x37, 0xb7, 0x74, 0x07, 0xb4, 0x88, 0x73, 0x9c, 0xc5, 0xcd, |
|
| 2586 |
- 0x6a, 0xbb, 0xda, 0x69, 0x74, 0xef, 0xda, 0xd7, 0x78, 0x65, 0xbd, 0xd8, 0x87, 0xa2, 0x17, 0x37, |
|
| 2587 |
- 0x0f, 0xd3, 0x1f, 0x80, 0xca, 0x78, 0x73, 0xa3, 0xad, 0x74, 0x1a, 0xdd, 0x7b, 0xf6, 0x0d, 0xb8, |
|
| 2588 |
- 0xb6, 0xa8, 0x73, 0x38, 0xea, 0x6b, 0xe9, 0xca, 0x54, 0x87, 0x23, 0x57, 0x65, 0x5c, 0x37, 0x00, |
|
| 2589 |
- 0xa6, 0x0b, 0x3a, 0x3d, 0x0b, 0x39, 0x0b, 0xb0, 0xb9, 0x99, 0xe5, 0xbf, 0xe6, 0xd1, 0x77, 0xa1, |
|
| 2590 |
- 0x1a, 0x32, 0xd2, 0xd4, 0xda, 0x4a, 0x67, 0xdb, 0x15, 0x4b, 0xeb, 0x19, 0xd4, 0x85, 0xce, 0x31, |
|
| 2591 |
- 0x7a, 0x11, 0x96, 0x6a, 0x37, 0x97, 0x54, 0xaf, 0x24, 0xdf, 0xe7, 0x0c, 0x07, 0x74, 0x49, 0x4b, |
|
| 2592 |
- 0x32, 0xbc, 0x21, 0xaa, 0x9b, 0xd0, 0xa0, 0xe7, 0x0c, 0xc7, 0x31, 0x7a, 0x98, 0x08, 0x84, 0x62, |
|
| 2593 |
- 0x07, 0x84, 0xeb, 0x38, 0xf3, 0xe8, 0x3d, 0xa8, 0x0b, 0x8b, 0x92, 0xb1, 0x87, 0x39, 0xb4, 0x96, |
|
| 2594 |
- 0x2d, 0x07, 0xcd, 0x5e, 0xdf, 0xba, 0x7d, 0xb2, 0x1e, 0xb4, 0x7e, 0xed, 0x62, 0x65, 0x56, 0xde, |
|
| 2595 |
- 0x7e, 0x36, 0x15, 0xb7, 0x26, 0x8f, 0xf5, 0xd0, 0x7a, 0x01, 0x9a, 0x64, 0xaa, 0xef, 0xc1, 0x66, |
|
| 2596 |
- 0x8c, 0x84, 0x05, 0xb2, 0x58, 0x57, 0x1a, 0xe2, 0x66, 0x63, 0x24, 0x3c, 0xc1, 0xf5, 0xcd, 0x4a, |
|
| 2597 |
- 0x2b, 0xf7, 0xd3, 0x28, 0xca, 0xca, 0x92, 0x7e, 0x1a, 0x45, 0x7a, 0x0b, 0x6a, 0x48, 0x23, 0x9f, |
|
| 2598 |
- 0x05, 0xde, 0x32, 0xab, 0xa8, 0xe6, 0x16, 0xb6, 0xf5, 0x41, 0x81, 0x9a, 0x48, 0xf6, 0xf4, 0x9c, |
|
| 2599 |
- 0x61, 0xc9, 0x31, 0x53, 0x73, 0x42, 0xf5, 0x7c, 0x04, 0x06, 0xae, 0xca, 0x0a, 0x74, 0xd5, 0x5f, |
|
| 2600 |
- 0xa2, 0xdb, 0xf8, 0x3d, 0xba, 0xcd, 0x52, 0xe8, 0x9e, 0xc0, 0x96, 0xe8, 0x66, 0x34, 0x3a, 0x2c, |
|
| 2601 |
- 0xd3, 0x8c, 0xb5, 0x80, 0x6d, 0x09, 0x83, 0x4e, 0x7b, 0x84, 0x50, 0x52, 0x8a, 0xc8, 0x7d, 0xd8, |
|
| 2602 |
- 0xa2, 0xe7, 0x74, 0x3a, 0x2e, 0xb0, 0x40, 0xba, 0x32, 0x35, 0xa1, 0x39, 0x1c, 0xb8, 0x9a, 0xd8, |
|
| 2603 |
- 0x1a, 0x12, 0xeb, 0x35, 0xec, 0xac, 0x33, 0x65, 0x33, 0xff, 0x1f, 0x73, 0xdd, 0xbc, 0x0a, 0x6b, |
|
| 2604 |
- 0x5f, 0xfe, 0x33, 0x8e, 0xbc, 0x24, 0x2e, 0x97, 0xd8, 0xea, 0x41, 0x43, 0x28, 0xb8, 0x34, 0x4e, |
|
| 2605 |
- 0xfc, 0x92, 0x12, 0x33, 0xd8, 0xcd, 0x9e, 0xb8, 0xe2, 0x59, 0x28, 0xc9, 0xe0, 0xc7, 0xc7, 0x46, |
|
| 2606 |
- 0xfd, 0xf9, 0xb1, 0xe9, 0x1f, 0x5d, 0x5c, 0x1a, 0x95, 0x4f, 0x97, 0x46, 0xe5, 0x4d, 0x6a, 0x28, |
|
| 2607 |
- 0x17, 0xa9, 0xa1, 0x7c, 0x4c, 0x0d, 0xe5, 0x4b, 0x6a, 0x28, 0xef, 0xbe, 0x19, 0xca, 0xf3, 0xee, |
|
| 2608 |
- 0x3f, 0x7c, 0x65, 0x1e, 0xcb, 0x9f, 0xd3, 0xca, 0x69, 0x75, 0xa2, 0x65, 0x13, 0xf9, 0xf0, 0x7b, |
|
| 2609 |
- 0x00, 0x00, 0x00, 0xff, 0xff, 0x07, 0x69, 0x62, 0x9d, 0xa6, 0x06, 0x00, 0x00, |
|
| 2571 |
+ 0x10, 0xc7, 0x63, 0xa7, 0x75, 0xd3, 0x09, 0x55, 0x8b, 0x55, 0x95, 0x90, 0x83, 0x1d, 0x99, 0x4b, |
|
| 2572 |
+ 0x4e, 0xb6, 0x08, 0x12, 0x17, 0x84, 0xd4, 0xa4, 0xe1, 0x90, 0x43, 0x95, 0xe2, 0xf6, 0x50, 0x71, |
|
| 2573 |
+ 0x89, 0x36, 0xd9, 0x4d, 0xb2, 0x34, 0xf1, 0x5a, 0xf6, 0x18, 0x15, 0x89, 0x03, 0x8f, 0xc0, 0x23, |
|
| 2574 |
+ 0xf0, 0x38, 0x3d, 0x20, 0xc4, 0x91, 0x53, 0xa0, 0x7e, 0x00, 0x4e, 0x3c, 0x00, 0x5a, 0xaf, 0x93, |
|
| 2575 |
+ 0xb6, 0x54, 0x7c, 0x59, 0xe2, 0x94, 0x9d, 0xd9, 0xd9, 0xff, 0xec, 0xfc, 0x76, 0x3c, 0x81, 0xc7, |
|
| 2576 |
+ 0x13, 0x8e, 0xd3, 0x64, 0xe8, 0x8e, 0xc4, 0xdc, 0x1b, 0x89, 0x00, 0x09, 0x0f, 0x58, 0x44, 0xaf, |
|
| 2577 |
+ 0x2f, 0x49, 0xc8, 0x3d, 0xf6, 0x8a, 0x05, 0x18, 0x7b, 0x48, 0xe2, 0x33, 0x37, 0x8c, 0x04, 0x0a, |
|
| 2578 |
+ 0xf3, 0xee, 0x55, 0x84, 0xab, 0x76, 0xeb, 0xbb, 0x13, 0x31, 0x11, 0xd9, 0xae, 0x27, 0x57, 0x2a, |
|
| 2579 |
+ 0xb0, 0x6e, 0x4f, 0x84, 0x98, 0xcc, 0x98, 0x97, 0x59, 0xc3, 0x64, 0xec, 0x21, 0x9f, 0xb3, 0x18, |
|
| 2580 |
+ 0xc9, 0x3c, 0xcc, 0x03, 0xfe, 0xee, 0x06, 0xf8, 0x3a, 0x64, 0xb1, 0x37, 0x17, 0x49, 0x80, 0xf9, |
|
| 2581 |
+ 0xb9, 0xfd, 0x3f, 0x9e, 0x5b, 0xa5, 0x0c, 0x67, 0xc9, 0x84, 0x07, 0xde, 0x98, 0xb3, 0x19, 0x0d, |
|
| 2582 |
+ 0x09, 0x4e, 0x95, 0x82, 0xf3, 0x4d, 0x03, 0x38, 0x21, 0xf1, 0xd9, 0x41, 0xc4, 0x08, 0x32, 0xb3, |
|
| 2583 |
+ 0x05, 0x77, 0x56, 0x87, 0x07, 0x9c, 0xd6, 0xb4, 0x86, 0xd6, 0xdc, 0xec, 0x6c, 0xa7, 0x0b, 0xbb, |
|
| 2584 |
+ 0x7a, 0xb0, 0xf4, 0xf7, 0xba, 0x7e, 0x75, 0x15, 0xd4, 0xa3, 0xe6, 0x1e, 0x18, 0xc3, 0x24, 0xa0, |
|
| 2585 |
+ 0x33, 0x56, 0xd3, 0x65, 0xb4, 0x9f, 0x5b, 0xa6, 0x07, 0x46, 0x24, 0x04, 0x8e, 0xe3, 0x5a, 0xb9, |
|
| 2586 |
+ 0x51, 0x6e, 0x56, 0x5b, 0xf7, 0xdc, 0x6b, 0xbc, 0xb2, 0x5a, 0xdc, 0x43, 0x59, 0x8b, 0x9f, 0x87, |
|
| 2587 |
+ 0x99, 0x0f, 0x41, 0xe7, 0xa2, 0xb6, 0xd6, 0xd0, 0x9a, 0xd5, 0xd6, 0x7d, 0xf7, 0x16, 0x5c, 0x57, |
|
| 2588 |
+ 0xde, 0xb3, 0xd7, 0xef, 0x18, 0xe9, 0xc2, 0xd6, 0x7b, 0x7d, 0x5f, 0xe7, 0xc2, 0xb4, 0x00, 0x46, |
|
| 2589 |
+ 0x53, 0x36, 0x3a, 0x0b, 0x05, 0x0f, 0xb0, 0xb6, 0x9e, 0xe5, 0xbf, 0xe6, 0x31, 0x77, 0xa0, 0x1c, |
|
| 2590 |
+ 0x72, 0x5a, 0x33, 0x1a, 0x5a, 0x73, 0xcb, 0x97, 0x4b, 0xe7, 0x39, 0x6c, 0x4a, 0x9d, 0x63, 0x24, |
|
| 2591 |
+ 0x11, 0x16, 0x2a, 0x37, 0x97, 0xd4, 0xaf, 0x24, 0x3f, 0xe6, 0x0c, 0xbb, 0x6c, 0xc6, 0x0a, 0x32, |
|
| 2592 |
+ 0xbc, 0x25, 0x6a, 0xda, 0x50, 0x65, 0xe7, 0x1c, 0x07, 0x31, 0x12, 0x4c, 0x24, 0x42, 0xb9, 0x03, |
|
| 2593 |
+ 0xd2, 0x75, 0x9c, 0x79, 0xcc, 0x36, 0x6c, 0x4a, 0x8b, 0xd1, 0x01, 0xc1, 0x1c, 0x5a, 0xdd, 0x55, |
|
| 2594 |
+ 0x8d, 0xe6, 0x2e, 0x5f, 0xdd, 0x3d, 0x59, 0x36, 0x5a, 0xa7, 0x72, 0xb1, 0xb0, 0x4b, 0xef, 0xbe, |
|
| 2595 |
+ 0xd8, 0x9a, 0x5f, 0x51, 0xc7, 0xda, 0x68, 0xee, 0x81, 0xce, 0xa9, 0xa2, 0x96, 0x53, 0xed, 0xfa, |
|
| 2596 |
+ 0x3a, 0xa7, 0xce, 0x4b, 0x30, 0x14, 0x6b, 0x73, 0x17, 0xd6, 0x63, 0xa4, 0x3c, 0x50, 0x45, 0xf8, |
|
| 2597 |
+ 0xca, 0x90, 0x2f, 0x1e, 0x23, 0x15, 0x09, 0x2e, 0x5f, 0x5c, 0x59, 0xb9, 0x9f, 0x45, 0x51, 0x76, |
|
| 2598 |
+ 0x5d, 0xe5, 0x67, 0x51, 0x64, 0xd6, 0xa1, 0x82, 0x2c, 0x9a, 0xf3, 0x80, 0xcc, 0xb2, 0x9b, 0x56, |
|
| 2599 |
+ 0xfc, 0x95, 0xed, 0x7c, 0xd0, 0xa0, 0x22, 0x93, 0x3d, 0x3b, 0xe7, 0x58, 0xb0, 0xfd, 0xf4, 0x9c, |
|
| 2600 |
+ 0xdc, 0x8d, 0x22, 0x96, 0x48, 0xcb, 0xbf, 0x44, 0xba, 0xf6, 0x7b, 0xa4, 0xeb, 0x45, 0x90, 0x3a, |
|
| 2601 |
+ 0x4f, 0x61, 0x43, 0x56, 0xd3, 0xef, 0x1f, 0x16, 0x29, 0xc6, 0x99, 0xc2, 0x96, 0x82, 0xc1, 0x46, |
|
| 2602 |
+ 0x6d, 0x4a, 0x19, 0x2d, 0x44, 0xe4, 0x01, 0x6c, 0xb0, 0x73, 0x36, 0x1a, 0xac, 0xb0, 0x40, 0xba, |
|
| 2603 |
+ 0xb0, 0x0d, 0xa9, 0xd9, 0xeb, 0xfa, 0x86, 0xdc, 0xea, 0x51, 0xe7, 0x0d, 0x6c, 0x2f, 0x33, 0x65, |
|
| 2604 |
+ 0xdf, 0xc2, 0x7f, 0xcc, 0x75, 0xfb, 0x29, 0x9c, 0x7d, 0xf5, 0xc5, 0x1c, 0x91, 0x24, 0x2e, 0x96, |
|
| 2605 |
+ 0xd8, 0x69, 0x43, 0x55, 0x2a, 0xf8, 0x2c, 0x4e, 0xe6, 0x05, 0x25, 0xc6, 0xb0, 0x93, 0x8d, 0xbe, |
|
| 2606 |
+ 0xd5, 0xb8, 0x28, 0xc8, 0xe0, 0xe6, 0x10, 0xd2, 0x7f, 0x1e, 0x42, 0x9d, 0xa3, 0x8b, 0x4b, 0xab, |
|
| 2607 |
+ 0xf4, 0xf9, 0xd2, 0x2a, 0xbd, 0x4d, 0x2d, 0xed, 0x22, 0xb5, 0xb4, 0x4f, 0xa9, 0xa5, 0x7d, 0x4d, |
|
| 2608 |
+ 0x2d, 0xed, 0xfd, 0x77, 0x4b, 0x7b, 0xd1, 0xfa, 0x87, 0x7f, 0x9f, 0x27, 0xea, 0xe7, 0xb4, 0x74, |
|
| 2609 |
+ 0x5a, 0x1e, 0x1a, 0x59, 0x47, 0x3e, 0xfa, 0x11, 0x00, 0x00, 0xff, 0xff, 0xc5, 0x58, 0x0f, 0xec, |
|
| 2610 |
+ 0xbe, 0x06, 0x00, 0x00, |
|
| 2610 | 2611 |
} |
| ... | ... |
@@ -29,6 +29,9 @@ message TaskDelete {
|
| 29 | 29 |
uint32 pid = 2; |
| 30 | 30 |
uint32 exit_status = 3; |
| 31 | 31 |
google.protobuf.Timestamp exited_at = 4 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; |
| 32 |
+ // id is the specific exec. By default if omitted will be `""` thus matches |
|
| 33 |
+ // the init exec of the task matching `container_id`. |
|
| 34 |
+ string id = 5; |
|
| 32 | 35 |
} |
| 33 | 36 |
|
| 34 | 37 |
message TaskIO {
|
| 35 | 38 |
deleted file mode 100644 |
| ... | ... |
@@ -1,30 +0,0 @@ |
| 1 |
-/* |
|
| 2 |
- Copyright The containerd Authors. |
|
| 3 |
- |
|
| 4 |
- Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
- you may not use this file except in compliance with the License. |
|
| 6 |
- You may obtain a copy of the License at |
|
| 7 |
- |
|
| 8 |
- http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
- |
|
| 10 |
- Unless required by applicable law or agreed to in writing, software |
|
| 11 |
- distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
- See the License for the specific language governing permissions and |
|
| 14 |
- limitations under the License. |
|
| 15 |
-*/ |
|
| 16 |
- |
|
| 17 |
-package archive |
|
| 18 |
- |
|
| 19 |
-import ( |
|
| 20 |
- "time" |
|
| 21 |
- |
|
| 22 |
- "github.com/pkg/errors" |
|
| 23 |
-) |
|
| 24 |
- |
|
| 25 |
-// as at MacOS 10.12 there is apparently no way to set timestamps |
|
| 26 |
-// with nanosecond precision. We could fall back to utimes/lutimes |
|
| 27 |
-// and lose the precision as a temporary workaround. |
|
| 28 |
-func chtimes(path string, atime, mtime time.Time) error {
|
|
| 29 |
- return errors.New("OSX missing UtimesNanoAt")
|
|
| 30 |
-} |
| ... | ... |
@@ -31,11 +31,15 @@ const pipeRoot = `\\.\pipe` |
| 31 | 31 |
|
| 32 | 32 |
// NewFIFOSetInDir returns a new set of fifos for the task |
| 33 | 33 |
func NewFIFOSetInDir(_, id string, terminal bool) (*FIFOSet, error) {
|
| 34 |
+ stderrPipe := "" |
|
| 35 |
+ if !terminal {
|
|
| 36 |
+ stderrPipe = fmt.Sprintf(`%s\ctr-%s-stderr`, pipeRoot, id) |
|
| 37 |
+ } |
|
| 34 | 38 |
return NewFIFOSet(Config{
|
| 35 | 39 |
Terminal: terminal, |
| 36 | 40 |
Stdin: fmt.Sprintf(`%s\ctr-%s-stdin`, pipeRoot, id), |
| 37 | 41 |
Stdout: fmt.Sprintf(`%s\ctr-%s-stdout`, pipeRoot, id), |
| 38 |
- Stderr: fmt.Sprintf(`%s\ctr-%s-stderr`, pipeRoot, id), |
|
| 42 |
+ Stderr: stderrPipe, |
|
| 39 | 43 |
}, nil), nil |
| 40 | 44 |
} |
| 41 | 45 |
|
| ... | ... |
@@ -17,11 +17,14 @@ |
| 17 | 17 |
package containerd |
| 18 | 18 |
|
| 19 | 19 |
import ( |
| 20 |
+ "bytes" |
|
| 20 | 21 |
"context" |
| 22 |
+ "encoding/json" |
|
| 21 | 23 |
"fmt" |
| 22 | 24 |
"net/http" |
| 23 | 25 |
"runtime" |
| 24 | 26 |
"strconv" |
| 27 |
+ "strings" |
|
| 25 | 28 |
"sync" |
| 26 | 29 |
"time" |
| 27 | 30 |
|
| ... | ... |
@@ -40,7 +43,6 @@ import ( |
| 40 | 40 |
"github.com/containerd/containerd/content" |
| 41 | 41 |
contentproxy "github.com/containerd/containerd/content/proxy" |
| 42 | 42 |
"github.com/containerd/containerd/defaults" |
| 43 |
- "github.com/containerd/containerd/errdefs" |
|
| 44 | 43 |
"github.com/containerd/containerd/events" |
| 45 | 44 |
"github.com/containerd/containerd/images" |
| 46 | 45 |
"github.com/containerd/containerd/leases" |
| ... | ... |
@@ -51,7 +53,6 @@ import ( |
| 51 | 51 |
"github.com/containerd/containerd/plugin" |
| 52 | 52 |
"github.com/containerd/containerd/remotes" |
| 53 | 53 |
"github.com/containerd/containerd/remotes/docker" |
| 54 |
- "github.com/containerd/containerd/remotes/docker/schema1" |
|
| 55 | 54 |
"github.com/containerd/containerd/snapshots" |
| 56 | 55 |
snproxy "github.com/containerd/containerd/snapshots/proxy" |
| 57 | 56 |
"github.com/containerd/typeurl" |
| ... | ... |
@@ -280,6 +281,12 @@ type RemoteContext struct {
|
| 280 | 280 |
// handlers. |
| 281 | 281 |
BaseHandlers []images.Handler |
| 282 | 282 |
|
| 283 |
+ // HandlerWrapper wraps the handler which gets sent to dispatch. |
|
| 284 |
+ // Unlike BaseHandlers, this can run before and after the built |
|
| 285 |
+ // in handlers, allowing operations to run on the descriptor |
|
| 286 |
+ // after it has completed transferring. |
|
| 287 |
+ HandlerWrapper func(images.Handler) images.Handler |
|
| 288 |
+ |
|
| 283 | 289 |
// ConvertSchema1 is whether to convert Docker registry schema 1 |
| 284 | 290 |
// manifests. If this option is false then any image which resolves |
| 285 | 291 |
// to schema 1 will return an error since schema 1 is not supported. |
| ... | ... |
@@ -290,6 +297,9 @@ type RemoteContext struct {
|
| 290 | 290 |
// platforms will be used to create a PlatformMatcher with no ordering |
| 291 | 291 |
// preference. |
| 292 | 292 |
Platforms []string |
| 293 |
+ |
|
| 294 |
+ // MaxConcurrentDownloads is the max concurrent content downloads for each pull. |
|
| 295 |
+ MaxConcurrentDownloads int |
|
| 293 | 296 |
} |
| 294 | 297 |
|
| 295 | 298 |
func defaultRemoteContext() *RemoteContext {
|
| ... | ... |
@@ -341,157 +351,6 @@ func (c *Client) Fetch(ctx context.Context, ref string, opts ...RemoteOpt) (imag |
| 341 | 341 |
return c.fetch(ctx, fetchCtx, ref, 0) |
| 342 | 342 |
} |
| 343 | 343 |
|
| 344 |
-// Pull downloads the provided content into containerd's content store |
|
| 345 |
-// and returns a platform specific image object |
|
| 346 |
-func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image, error) {
|
|
| 347 |
- pullCtx := defaultRemoteContext() |
|
| 348 |
- for _, o := range opts {
|
|
| 349 |
- if err := o(c, pullCtx); err != nil {
|
|
| 350 |
- return nil, err |
|
| 351 |
- } |
|
| 352 |
- } |
|
| 353 |
- |
|
| 354 |
- if pullCtx.PlatformMatcher == nil {
|
|
| 355 |
- if len(pullCtx.Platforms) > 1 {
|
|
| 356 |
- return nil, errors.New("cannot pull multiplatform image locally, try Fetch")
|
|
| 357 |
- } else if len(pullCtx.Platforms) == 0 {
|
|
| 358 |
- pullCtx.PlatformMatcher = platforms.Default() |
|
| 359 |
- } else {
|
|
| 360 |
- p, err := platforms.Parse(pullCtx.Platforms[0]) |
|
| 361 |
- if err != nil {
|
|
| 362 |
- return nil, errors.Wrapf(err, "invalid platform %s", pullCtx.Platforms[0]) |
|
| 363 |
- } |
|
| 364 |
- |
|
| 365 |
- pullCtx.PlatformMatcher = platforms.Only(p) |
|
| 366 |
- } |
|
| 367 |
- } |
|
| 368 |
- |
|
| 369 |
- ctx, done, err := c.WithLease(ctx) |
|
| 370 |
- if err != nil {
|
|
| 371 |
- return nil, err |
|
| 372 |
- } |
|
| 373 |
- defer done(ctx) |
|
| 374 |
- |
|
| 375 |
- img, err := c.fetch(ctx, pullCtx, ref, 1) |
|
| 376 |
- if err != nil {
|
|
| 377 |
- return nil, err |
|
| 378 |
- } |
|
| 379 |
- |
|
| 380 |
- i := NewImageWithPlatform(c, img, pullCtx.PlatformMatcher) |
|
| 381 |
- |
|
| 382 |
- if pullCtx.Unpack {
|
|
| 383 |
- if err := i.Unpack(ctx, pullCtx.Snapshotter); err != nil {
|
|
| 384 |
- return nil, errors.Wrapf(err, "failed to unpack image on snapshotter %s", pullCtx.Snapshotter) |
|
| 385 |
- } |
|
| 386 |
- } |
|
| 387 |
- |
|
| 388 |
- return i, nil |
|
| 389 |
-} |
|
| 390 |
- |
|
| 391 |
-func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, limit int) (images.Image, error) {
|
|
| 392 |
- store := c.ContentStore() |
|
| 393 |
- name, desc, err := rCtx.Resolver.Resolve(ctx, ref) |
|
| 394 |
- if err != nil {
|
|
| 395 |
- return images.Image{}, errors.Wrapf(err, "failed to resolve reference %q", ref)
|
|
| 396 |
- } |
|
| 397 |
- |
|
| 398 |
- fetcher, err := rCtx.Resolver.Fetcher(ctx, name) |
|
| 399 |
- if err != nil {
|
|
| 400 |
- return images.Image{}, errors.Wrapf(err, "failed to get fetcher for %q", name)
|
|
| 401 |
- } |
|
| 402 |
- |
|
| 403 |
- var ( |
|
| 404 |
- handler images.Handler |
|
| 405 |
- |
|
| 406 |
- isConvertible bool |
|
| 407 |
- converterFunc func(context.Context, ocispec.Descriptor) (ocispec.Descriptor, error) |
|
| 408 |
- ) |
|
| 409 |
- |
|
| 410 |
- if desc.MediaType == images.MediaTypeDockerSchema1Manifest && rCtx.ConvertSchema1 {
|
|
| 411 |
- schema1Converter := schema1.NewConverter(store, fetcher) |
|
| 412 |
- |
|
| 413 |
- handler = images.Handlers(append(rCtx.BaseHandlers, schema1Converter)...) |
|
| 414 |
- |
|
| 415 |
- isConvertible = true |
|
| 416 |
- |
|
| 417 |
- converterFunc = func(ctx context.Context, _ ocispec.Descriptor) (ocispec.Descriptor, error) {
|
|
| 418 |
- return schema1Converter.Convert(ctx) |
|
| 419 |
- } |
|
| 420 |
- } else {
|
|
| 421 |
- // Get all the children for a descriptor |
|
| 422 |
- childrenHandler := images.ChildrenHandler(store) |
|
| 423 |
- // Set any children labels for that content |
|
| 424 |
- childrenHandler = images.SetChildrenLabels(store, childrenHandler) |
|
| 425 |
- // Filter children by platforms |
|
| 426 |
- childrenHandler = images.FilterPlatforms(childrenHandler, rCtx.PlatformMatcher) |
|
| 427 |
- // Sort and limit manifests if a finite number is needed |
|
| 428 |
- if limit > 0 {
|
|
| 429 |
- childrenHandler = images.LimitManifests(childrenHandler, rCtx.PlatformMatcher, limit) |
|
| 430 |
- } |
|
| 431 |
- |
|
| 432 |
- // set isConvertible to true if there is application/octet-stream media type |
|
| 433 |
- convertibleHandler := images.HandlerFunc( |
|
| 434 |
- func(_ context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
|
| 435 |
- if desc.MediaType == docker.LegacyConfigMediaType {
|
|
| 436 |
- isConvertible = true |
|
| 437 |
- } |
|
| 438 |
- |
|
| 439 |
- return []ocispec.Descriptor{}, nil
|
|
| 440 |
- }, |
|
| 441 |
- ) |
|
| 442 |
- |
|
| 443 |
- handler = images.Handlers(append(rCtx.BaseHandlers, |
|
| 444 |
- remotes.FetchHandler(store, fetcher), |
|
| 445 |
- convertibleHandler, |
|
| 446 |
- childrenHandler, |
|
| 447 |
- )...) |
|
| 448 |
- |
|
| 449 |
- converterFunc = func(ctx context.Context, desc ocispec.Descriptor) (ocispec.Descriptor, error) {
|
|
| 450 |
- return docker.ConvertManifest(ctx, store, desc) |
|
| 451 |
- } |
|
| 452 |
- } |
|
| 453 |
- |
|
| 454 |
- if err := images.Dispatch(ctx, handler, desc); err != nil {
|
|
| 455 |
- return images.Image{}, err
|
|
| 456 |
- } |
|
| 457 |
- |
|
| 458 |
- if isConvertible {
|
|
| 459 |
- if desc, err = converterFunc(ctx, desc); err != nil {
|
|
| 460 |
- return images.Image{}, err
|
|
| 461 |
- } |
|
| 462 |
- } |
|
| 463 |
- |
|
| 464 |
- img := images.Image{
|
|
| 465 |
- Name: name, |
|
| 466 |
- Target: desc, |
|
| 467 |
- Labels: rCtx.Labels, |
|
| 468 |
- } |
|
| 469 |
- |
|
| 470 |
- is := c.ImageService() |
|
| 471 |
- for {
|
|
| 472 |
- if created, err := is.Create(ctx, img); err != nil {
|
|
| 473 |
- if !errdefs.IsAlreadyExists(err) {
|
|
| 474 |
- return images.Image{}, err
|
|
| 475 |
- } |
|
| 476 |
- |
|
| 477 |
- updated, err := is.Update(ctx, img) |
|
| 478 |
- if err != nil {
|
|
| 479 |
- // if image was removed, try create again |
|
| 480 |
- if errdefs.IsNotFound(err) {
|
|
| 481 |
- continue |
|
| 482 |
- } |
|
| 483 |
- return images.Image{}, err
|
|
| 484 |
- } |
|
| 485 |
- |
|
| 486 |
- img = updated |
|
| 487 |
- } else {
|
|
| 488 |
- img = created |
|
| 489 |
- } |
|
| 490 |
- |
|
| 491 |
- return img, nil |
|
| 492 |
- } |
|
| 493 |
-} |
|
| 494 |
- |
|
| 495 | 344 |
// Push uploads the provided content to a remote resource |
| 496 | 345 |
func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor, opts ...RemoteOpt) error {
|
| 497 | 346 |
pushCtx := defaultRemoteContext() |
| ... | ... |
@@ -521,7 +380,21 @@ func (c *Client) Push(ctx context.Context, ref string, desc ocispec.Descriptor, |
| 521 | 521 |
return err |
| 522 | 522 |
} |
| 523 | 523 |
|
| 524 |
- return remotes.PushContent(ctx, pusher, desc, c.ContentStore(), pushCtx.PlatformMatcher, pushCtx.BaseHandlers...) |
|
| 524 |
+ var wrapper func(images.Handler) images.Handler |
|
| 525 |
+ |
|
| 526 |
+ if len(pushCtx.BaseHandlers) > 0 {
|
|
| 527 |
+ wrapper = func(h images.Handler) images.Handler {
|
|
| 528 |
+ h = images.Handlers(append(pushCtx.BaseHandlers, h)...) |
|
| 529 |
+ if pushCtx.HandlerWrapper != nil {
|
|
| 530 |
+ h = pushCtx.HandlerWrapper(h) |
|
| 531 |
+ } |
|
| 532 |
+ return h |
|
| 533 |
+ } |
|
| 534 |
+ } else if pushCtx.HandlerWrapper != nil {
|
|
| 535 |
+ wrapper = pushCtx.HandlerWrapper |
|
| 536 |
+ } |
|
| 537 |
+ |
|
| 538 |
+ return remotes.PushContent(ctx, pusher, desc, c.ContentStore(), pushCtx.PlatformMatcher, wrapper) |
|
| 525 | 539 |
} |
| 526 | 540 |
|
| 527 | 541 |
// GetImage returns an existing image |
| ... | ... |
@@ -546,6 +419,45 @@ func (c *Client) ListImages(ctx context.Context, filters ...string) ([]Image, er |
| 546 | 546 |
return images, nil |
| 547 | 547 |
} |
| 548 | 548 |
|
| 549 |
+// Restore restores a container from a checkpoint |
|
| 550 |
+func (c *Client) Restore(ctx context.Context, id string, checkpoint Image, opts ...RestoreOpts) (Container, error) {
|
|
| 551 |
+ store := c.ContentStore() |
|
| 552 |
+ index, err := decodeIndex(ctx, store, checkpoint.Target()) |
|
| 553 |
+ if err != nil {
|
|
| 554 |
+ return nil, err |
|
| 555 |
+ } |
|
| 556 |
+ |
|
| 557 |
+ ctx, done, err := c.WithLease(ctx) |
|
| 558 |
+ if err != nil {
|
|
| 559 |
+ return nil, err |
|
| 560 |
+ } |
|
| 561 |
+ defer done(ctx) |
|
| 562 |
+ |
|
| 563 |
+ copts := []NewContainerOpts{}
|
|
| 564 |
+ for _, o := range opts {
|
|
| 565 |
+ copts = append(copts, o(ctx, id, c, checkpoint, index)) |
|
| 566 |
+ } |
|
| 567 |
+ |
|
| 568 |
+ ctr, err := c.NewContainer(ctx, id, copts...) |
|
| 569 |
+ if err != nil {
|
|
| 570 |
+ return nil, err |
|
| 571 |
+ } |
|
| 572 |
+ |
|
| 573 |
+ return ctr, nil |
|
| 574 |
+} |
|
| 575 |
+ |
|
| 576 |
+func writeIndex(ctx context.Context, index *ocispec.Index, client *Client, ref string) (d ocispec.Descriptor, err error) {
|
|
| 577 |
+ labels := map[string]string{}
|
|
| 578 |
+ for i, m := range index.Manifests {
|
|
| 579 |
+ labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i)] = m.Digest.String()
|
|
| 580 |
+ } |
|
| 581 |
+ data, err := json.Marshal(index) |
|
| 582 |
+ if err != nil {
|
|
| 583 |
+ return ocispec.Descriptor{}, err
|
|
| 584 |
+ } |
|
| 585 |
+ return writeContent(ctx, client.ContentStore(), ocispec.MediaTypeImageIndex, ref, bytes.NewReader(data), content.WithLabels(labels)) |
|
| 586 |
+} |
|
| 587 |
+ |
|
| 549 | 588 |
// Subscribe to events that match one or more of the provided filters. |
| 550 | 589 |
// |
| 551 | 590 |
// Callers should listen on both the envelope and errs channels. If the errs |
| ... | ... |
@@ -703,3 +615,20 @@ func (c *Client) Version(ctx context.Context) (Version, error) {
|
| 703 | 703 |
Revision: response.Revision, |
| 704 | 704 |
}, nil |
| 705 | 705 |
} |
| 706 |
+ |
|
| 707 |
+// CheckRuntime returns true if the current runtime matches the expected |
|
| 708 |
+// runtime. Providing various parts of the runtime schema will match those |
|
| 709 |
+// parts of the expected runtime |
|
| 710 |
+func CheckRuntime(current, expected string) bool {
|
|
| 711 |
+ cp := strings.Split(current, ".") |
|
| 712 |
+ l := len(cp) |
|
| 713 |
+ for i, p := range strings.Split(expected, ".") {
|
|
| 714 |
+ if i > l {
|
|
| 715 |
+ return false |
|
| 716 |
+ } |
|
| 717 |
+ if p != cp[i] {
|
|
| 718 |
+ return false |
|
| 719 |
+ } |
|
| 720 |
+ } |
|
| 721 |
+ return true |
|
| 722 |
+} |
| ... | ... |
@@ -178,3 +178,19 @@ func WithImageHandler(h images.Handler) RemoteOpt {
|
| 178 | 178 |
return nil |
| 179 | 179 |
} |
| 180 | 180 |
} |
| 181 |
+ |
|
| 182 |
+// WithImageHandlerWrapper wraps the handlers to be called on dispatch. |
|
| 183 |
+func WithImageHandlerWrapper(w func(images.Handler) images.Handler) RemoteOpt {
|
|
| 184 |
+ return func(client *Client, c *RemoteContext) error {
|
|
| 185 |
+ c.HandlerWrapper = w |
|
| 186 |
+ return nil |
|
| 187 |
+ } |
|
| 188 |
+} |
|
| 189 |
+ |
|
| 190 |
+// WithMaxConcurrentDownloads sets max concurrent download limit. |
|
| 191 |
+func WithMaxConcurrentDownloads(max int) RemoteOpt {
|
|
| 192 |
+ return func(client *Client, c *RemoteContext) error {
|
|
| 193 |
+ c.MaxConcurrentDownloads = max |
|
| 194 |
+ return nil |
|
| 195 |
+ } |
|
| 196 |
+} |
| ... | ... |
@@ -28,12 +28,22 @@ import ( |
| 28 | 28 |
"github.com/containerd/containerd/cio" |
| 29 | 29 |
"github.com/containerd/containerd/containers" |
| 30 | 30 |
"github.com/containerd/containerd/errdefs" |
| 31 |
+ "github.com/containerd/containerd/images" |
|
| 31 | 32 |
"github.com/containerd/containerd/oci" |
| 33 |
+ "github.com/containerd/containerd/runtime/v2/runc/options" |
|
| 32 | 34 |
"github.com/containerd/typeurl" |
| 33 | 35 |
prototypes "github.com/gogo/protobuf/types" |
| 36 |
+ ver "github.com/opencontainers/image-spec/specs-go" |
|
| 37 |
+ ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 34 | 38 |
"github.com/pkg/errors" |
| 35 | 39 |
) |
| 36 | 40 |
|
| 41 |
+const ( |
|
| 42 |
+ checkpointImageNameLabel = "org.opencontainers.image.ref.name" |
|
| 43 |
+ checkpointRuntimeNameLabel = "io.containerd.checkpoint.runtime" |
|
| 44 |
+ checkpointSnapshotterNameLabel = "io.containerd.checkpoint.snapshotter" |
|
| 45 |
+) |
|
| 46 |
+ |
|
| 37 | 47 |
// Container is a metadata object for container resources and task creation |
| 38 | 48 |
type Container interface {
|
| 39 | 49 |
// ID identifies the container |
| ... | ... |
@@ -64,6 +74,8 @@ type Container interface {
|
| 64 | 64 |
Extensions(context.Context) (map[string]prototypes.Any, error) |
| 65 | 65 |
// Update a container |
| 66 | 66 |
Update(context.Context, ...UpdateContainerOpts) error |
| 67 |
+ // Checkpoint creates a checkpoint image of the current container |
|
| 68 |
+ Checkpoint(context.Context, string, ...CheckpointOpts) (Image, error) |
|
| 67 | 69 |
} |
| 68 | 70 |
|
| 69 | 71 |
func containerFromRecord(client *Client, c containers.Container) *container {
|
| ... | ... |
@@ -217,7 +229,9 @@ func (c *container) NewTask(ctx context.Context, ioCreate cio.Creator, opts ...N |
| 217 | 217 |
}) |
| 218 | 218 |
} |
| 219 | 219 |
} |
| 220 |
- var info TaskInfo |
|
| 220 |
+ info := TaskInfo{
|
|
| 221 |
+ runtime: r.Runtime.Name, |
|
| 222 |
+ } |
|
| 221 | 223 |
for _, o := range opts {
|
| 222 | 224 |
if err := o(ctx, c.client, &info); err != nil {
|
| 223 | 225 |
return nil, err |
| ... | ... |
@@ -272,6 +286,70 @@ func (c *container) Update(ctx context.Context, opts ...UpdateContainerOpts) err |
| 272 | 272 |
return nil |
| 273 | 273 |
} |
| 274 | 274 |
|
| 275 |
+func (c *container) Checkpoint(ctx context.Context, ref string, opts ...CheckpointOpts) (Image, error) {
|
|
| 276 |
+ index := &ocispec.Index{
|
|
| 277 |
+ Versioned: ver.Versioned{
|
|
| 278 |
+ SchemaVersion: 2, |
|
| 279 |
+ }, |
|
| 280 |
+ Annotations: make(map[string]string), |
|
| 281 |
+ } |
|
| 282 |
+ copts := &options.CheckpointOptions{
|
|
| 283 |
+ Exit: false, |
|
| 284 |
+ OpenTcp: false, |
|
| 285 |
+ ExternalUnixSockets: false, |
|
| 286 |
+ Terminal: false, |
|
| 287 |
+ FileLocks: true, |
|
| 288 |
+ EmptyNamespaces: nil, |
|
| 289 |
+ } |
|
| 290 |
+ info, err := c.Info(ctx) |
|
| 291 |
+ if err != nil {
|
|
| 292 |
+ return nil, err |
|
| 293 |
+ } |
|
| 294 |
+ |
|
| 295 |
+ img, err := c.Image(ctx) |
|
| 296 |
+ if err != nil {
|
|
| 297 |
+ return nil, err |
|
| 298 |
+ } |
|
| 299 |
+ |
|
| 300 |
+ ctx, done, err := c.client.WithLease(ctx) |
|
| 301 |
+ if err != nil {
|
|
| 302 |
+ return nil, err |
|
| 303 |
+ } |
|
| 304 |
+ defer done(ctx) |
|
| 305 |
+ |
|
| 306 |
+ // add image name to manifest |
|
| 307 |
+ index.Annotations[checkpointImageNameLabel] = img.Name() |
|
| 308 |
+ // add runtime info to index |
|
| 309 |
+ index.Annotations[checkpointRuntimeNameLabel] = info.Runtime.Name |
|
| 310 |
+ // add snapshotter info to index |
|
| 311 |
+ index.Annotations[checkpointSnapshotterNameLabel] = info.Snapshotter |
|
| 312 |
+ |
|
| 313 |
+ // process remaining opts |
|
| 314 |
+ for _, o := range opts {
|
|
| 315 |
+ if err := o(ctx, c.client, &info, index, copts); err != nil {
|
|
| 316 |
+ err = errdefs.FromGRPC(err) |
|
| 317 |
+ if !errdefs.IsAlreadyExists(err) {
|
|
| 318 |
+ return nil, err |
|
| 319 |
+ } |
|
| 320 |
+ } |
|
| 321 |
+ } |
|
| 322 |
+ |
|
| 323 |
+ desc, err := writeIndex(ctx, index, c.client, c.ID()+"index") |
|
| 324 |
+ if err != nil {
|
|
| 325 |
+ return nil, err |
|
| 326 |
+ } |
|
| 327 |
+ i := images.Image{
|
|
| 328 |
+ Name: ref, |
|
| 329 |
+ Target: desc, |
|
| 330 |
+ } |
|
| 331 |
+ checkpoint, err := c.client.ImageService().Create(ctx, i) |
|
| 332 |
+ if err != nil {
|
|
| 333 |
+ return nil, err |
|
| 334 |
+ } |
|
| 335 |
+ |
|
| 336 |
+ return NewImage(c.client, checkpoint), nil |
|
| 337 |
+} |
|
| 338 |
+ |
|
| 275 | 339 |
func (c *container) loadTask(ctx context.Context, ioAttach cio.Attach) (Task, error) {
|
| 276 | 340 |
response, err := c.client.TaskService().Get(ctx, &tasks.GetRequest{
|
| 277 | 341 |
ContainerID: c.id, |
| 278 | 342 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,155 @@ |
| 0 |
+/* |
|
| 1 |
+ Copyright The containerd Authors. |
|
| 2 |
+ |
|
| 3 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
+ you may not use this file except in compliance with the License. |
|
| 5 |
+ You may obtain a copy of the License at |
|
| 6 |
+ |
|
| 7 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
+ |
|
| 9 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 10 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
+ See the License for the specific language governing permissions and |
|
| 13 |
+ limitations under the License. |
|
| 14 |
+*/ |
|
| 15 |
+ |
|
| 16 |
+package containerd |
|
| 17 |
+ |
|
| 18 |
+import ( |
|
| 19 |
+ "bytes" |
|
| 20 |
+ "context" |
|
| 21 |
+ "fmt" |
|
| 22 |
+ "runtime" |
|
| 23 |
+ |
|
| 24 |
+ tasks "github.com/containerd/containerd/api/services/tasks/v1" |
|
| 25 |
+ "github.com/containerd/containerd/containers" |
|
| 26 |
+ "github.com/containerd/containerd/diff" |
|
| 27 |
+ "github.com/containerd/containerd/images" |
|
| 28 |
+ "github.com/containerd/containerd/platforms" |
|
| 29 |
+ "github.com/containerd/containerd/rootfs" |
|
| 30 |
+ "github.com/containerd/containerd/runtime/v2/runc/options" |
|
| 31 |
+ "github.com/containerd/typeurl" |
|
| 32 |
+ imagespec "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 33 |
+ "github.com/pkg/errors" |
|
| 34 |
+) |
|
| 35 |
+ |
|
| 36 |
+var ( |
|
| 37 |
+ // ErrCheckpointRWUnsupported is returned if the container runtime does not support checkpoint |
|
| 38 |
+ ErrCheckpointRWUnsupported = errors.New("rw checkpoint is only supported on v2 runtimes")
|
|
| 39 |
+ // ErrMediaTypeNotFound returns an error when a media type in the manifest is unknown |
|
| 40 |
+ ErrMediaTypeNotFound = errors.New("media type not found")
|
|
| 41 |
+) |
|
| 42 |
+ |
|
| 43 |
+// CheckpointOpts are options to manage the checkpoint operation |
|
| 44 |
+type CheckpointOpts func(context.Context, *Client, *containers.Container, *imagespec.Index, *options.CheckpointOptions) error |
|
| 45 |
+ |
|
| 46 |
+// WithCheckpointImage includes the container image in the checkpoint |
|
| 47 |
+func WithCheckpointImage(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error {
|
|
| 48 |
+ ir, err := client.ImageService().Get(ctx, c.Image) |
|
| 49 |
+ if err != nil {
|
|
| 50 |
+ return err |
|
| 51 |
+ } |
|
| 52 |
+ index.Manifests = append(index.Manifests, ir.Target) |
|
| 53 |
+ return nil |
|
| 54 |
+} |
|
| 55 |
+ |
|
| 56 |
+// WithCheckpointTask includes the running task |
|
| 57 |
+func WithCheckpointTask(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error {
|
|
| 58 |
+ any, err := typeurl.MarshalAny(copts) |
|
| 59 |
+ if err != nil {
|
|
| 60 |
+ return nil |
|
| 61 |
+ } |
|
| 62 |
+ task, err := client.TaskService().Checkpoint(ctx, &tasks.CheckpointTaskRequest{
|
|
| 63 |
+ ContainerID: c.ID, |
|
| 64 |
+ Options: any, |
|
| 65 |
+ }) |
|
| 66 |
+ if err != nil {
|
|
| 67 |
+ return err |
|
| 68 |
+ } |
|
| 69 |
+ for _, d := range task.Descriptors {
|
|
| 70 |
+ platformSpec := platforms.DefaultSpec() |
|
| 71 |
+ index.Manifests = append(index.Manifests, imagespec.Descriptor{
|
|
| 72 |
+ MediaType: d.MediaType, |
|
| 73 |
+ Size: d.Size_, |
|
| 74 |
+ Digest: d.Digest, |
|
| 75 |
+ Platform: &platformSpec, |
|
| 76 |
+ }) |
|
| 77 |
+ } |
|
| 78 |
+ // save copts |
|
| 79 |
+ data, err := any.Marshal() |
|
| 80 |
+ if err != nil {
|
|
| 81 |
+ return err |
|
| 82 |
+ } |
|
| 83 |
+ r := bytes.NewReader(data) |
|
| 84 |
+ desc, err := writeContent(ctx, client.ContentStore(), images.MediaTypeContainerd1CheckpointOptions, c.ID+"-checkpoint-options", r) |
|
| 85 |
+ if err != nil {
|
|
| 86 |
+ return err |
|
| 87 |
+ } |
|
| 88 |
+ desc.Platform = &imagespec.Platform{
|
|
| 89 |
+ OS: runtime.GOOS, |
|
| 90 |
+ Architecture: runtime.GOARCH, |
|
| 91 |
+ } |
|
| 92 |
+ index.Manifests = append(index.Manifests, desc) |
|
| 93 |
+ return nil |
|
| 94 |
+} |
|
| 95 |
+ |
|
| 96 |
+// WithCheckpointRuntime includes the container runtime info |
|
| 97 |
+func WithCheckpointRuntime(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error {
|
|
| 98 |
+ if c.Runtime.Options != nil {
|
|
| 99 |
+ data, err := c.Runtime.Options.Marshal() |
|
| 100 |
+ if err != nil {
|
|
| 101 |
+ return err |
|
| 102 |
+ } |
|
| 103 |
+ r := bytes.NewReader(data) |
|
| 104 |
+ desc, err := writeContent(ctx, client.ContentStore(), images.MediaTypeContainerd1CheckpointRuntimeOptions, c.ID+"-runtime-options", r) |
|
| 105 |
+ if err != nil {
|
|
| 106 |
+ return err |
|
| 107 |
+ } |
|
| 108 |
+ desc.Platform = &imagespec.Platform{
|
|
| 109 |
+ OS: runtime.GOOS, |
|
| 110 |
+ Architecture: runtime.GOARCH, |
|
| 111 |
+ } |
|
| 112 |
+ index.Manifests = append(index.Manifests, desc) |
|
| 113 |
+ } |
|
| 114 |
+ return nil |
|
| 115 |
+} |
|
| 116 |
+ |
|
| 117 |
+// WithCheckpointRW includes the rw in the checkpoint |
|
| 118 |
+func WithCheckpointRW(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error {
|
|
| 119 |
+ diffOpts := []diff.Opt{
|
|
| 120 |
+ diff.WithReference(fmt.Sprintf("checkpoint-rw-%s", c.SnapshotKey)),
|
|
| 121 |
+ } |
|
| 122 |
+ rw, err := rootfs.CreateDiff(ctx, |
|
| 123 |
+ c.SnapshotKey, |
|
| 124 |
+ client.SnapshotService(c.Snapshotter), |
|
| 125 |
+ client.DiffService(), |
|
| 126 |
+ diffOpts..., |
|
| 127 |
+ ) |
|
| 128 |
+ if err != nil {
|
|
| 129 |
+ return err |
|
| 130 |
+ |
|
| 131 |
+ } |
|
| 132 |
+ rw.Platform = &imagespec.Platform{
|
|
| 133 |
+ OS: runtime.GOOS, |
|
| 134 |
+ Architecture: runtime.GOARCH, |
|
| 135 |
+ } |
|
| 136 |
+ index.Manifests = append(index.Manifests, rw) |
|
| 137 |
+ return nil |
|
| 138 |
+} |
|
| 139 |
+ |
|
| 140 |
+// WithCheckpointTaskExit causes the task to exit after checkpoint |
|
| 141 |
+func WithCheckpointTaskExit(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error {
|
|
| 142 |
+ copts.Exit = true |
|
| 143 |
+ return nil |
|
| 144 |
+} |
|
| 145 |
+ |
|
| 146 |
+// GetIndexByMediaType returns the index in a manifest for the specified media type |
|
| 147 |
+func GetIndexByMediaType(index *imagespec.Index, mt string) (*imagespec.Descriptor, error) {
|
|
| 148 |
+ for _, d := range index.Manifests {
|
|
| 149 |
+ if d.MediaType == mt {
|
|
| 150 |
+ return &d, nil |
|
| 151 |
+ } |
|
| 152 |
+ } |
|
| 153 |
+ return nil, ErrMediaTypeNotFound |
|
| 154 |
+} |
| ... | ... |
@@ -23,6 +23,7 @@ import ( |
| 23 | 23 |
"github.com/containerd/containerd/errdefs" |
| 24 | 24 |
"github.com/containerd/containerd/oci" |
| 25 | 25 |
"github.com/containerd/containerd/platforms" |
| 26 |
+ "github.com/containerd/containerd/snapshots" |
|
| 26 | 27 |
"github.com/containerd/typeurl" |
| 27 | 28 |
"github.com/gogo/protobuf/types" |
| 28 | 29 |
"github.com/opencontainers/image-spec/identity" |
| ... | ... |
@@ -118,7 +119,7 @@ func WithSnapshot(id string) NewContainerOpts {
|
| 118 | 118 |
|
| 119 | 119 |
// WithNewSnapshot allocates a new snapshot to be used by the container as the |
| 120 | 120 |
// root filesystem in read-write mode |
| 121 |
-func WithNewSnapshot(id string, i Image) NewContainerOpts {
|
|
| 121 |
+func WithNewSnapshot(id string, i Image, opts ...snapshots.Opt) NewContainerOpts {
|
|
| 122 | 122 |
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
| 123 | 123 |
diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default()) |
| 124 | 124 |
if err != nil {
|
| ... | ... |
@@ -126,7 +127,7 @@ func WithNewSnapshot(id string, i Image) NewContainerOpts {
|
| 126 | 126 |
} |
| 127 | 127 |
setSnapshotterIfEmpty(c) |
| 128 | 128 |
parent := identity.ChainID(diffIDs).String() |
| 129 |
- if _, err := client.SnapshotService(c.Snapshotter).Prepare(ctx, id, parent); err != nil {
|
|
| 129 |
+ if _, err := client.SnapshotService(c.Snapshotter).Prepare(ctx, id, parent, opts...); err != nil {
|
|
| 130 | 130 |
return err |
| 131 | 131 |
} |
| 132 | 132 |
c.SnapshotKey = id |
| ... | ... |
@@ -148,7 +149,7 @@ func WithSnapshotCleanup(ctx context.Context, client *Client, c containers.Conta |
| 148 | 148 |
|
| 149 | 149 |
// WithNewSnapshotView allocates a new snapshot to be used by the container as the |
| 150 | 150 |
// root filesystem in read-only mode |
| 151 |
-func WithNewSnapshotView(id string, i Image) NewContainerOpts {
|
|
| 151 |
+func WithNewSnapshotView(id string, i Image, opts ...snapshots.Opt) NewContainerOpts {
|
|
| 152 | 152 |
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
| 153 | 153 |
diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default()) |
| 154 | 154 |
if err != nil {
|
| ... | ... |
@@ -156,7 +157,7 @@ func WithNewSnapshotView(id string, i Image) NewContainerOpts {
|
| 156 | 156 |
} |
| 157 | 157 |
setSnapshotterIfEmpty(c) |
| 158 | 158 |
parent := identity.ChainID(diffIDs).String() |
| 159 |
- if _, err := client.SnapshotService(c.Snapshotter).View(ctx, id, parent); err != nil {
|
|
| 159 |
+ if _, err := client.SnapshotService(c.Snapshotter).View(ctx, id, parent, opts...); err != nil {
|
|
| 160 | 160 |
return err |
| 161 | 161 |
} |
| 162 | 162 |
c.SnapshotKey = id |
| ... | ... |
@@ -26,81 +26,12 @@ import ( |
| 26 | 26 |
"syscall" |
| 27 | 27 |
|
| 28 | 28 |
"github.com/containerd/containerd/containers" |
| 29 |
- "github.com/containerd/containerd/content" |
|
| 30 | 29 |
"github.com/containerd/containerd/errdefs" |
| 31 |
- "github.com/containerd/containerd/images" |
|
| 32 | 30 |
"github.com/containerd/containerd/mount" |
| 33 | 31 |
"github.com/containerd/containerd/platforms" |
| 34 |
- "github.com/gogo/protobuf/proto" |
|
| 35 |
- protobuf "github.com/gogo/protobuf/types" |
|
| 36 | 32 |
"github.com/opencontainers/image-spec/identity" |
| 37 |
- "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 38 |
- "github.com/pkg/errors" |
|
| 39 | 33 |
) |
| 40 | 34 |
|
| 41 |
-// WithCheckpoint allows a container to be created from the checkpointed information |
|
| 42 |
-// provided by the descriptor. The image, snapshot, and runtime specifications are |
|
| 43 |
-// restored on the container |
|
| 44 |
-func WithCheckpoint(im Image, snapshotKey string) NewContainerOpts {
|
|
| 45 |
- // set image and rw, and spec |
|
| 46 |
- return func(ctx context.Context, client *Client, c *containers.Container) error {
|
|
| 47 |
- var ( |
|
| 48 |
- desc = im.Target() |
|
| 49 |
- store = client.ContentStore() |
|
| 50 |
- ) |
|
| 51 |
- index, err := decodeIndex(ctx, store, desc) |
|
| 52 |
- if err != nil {
|
|
| 53 |
- return err |
|
| 54 |
- } |
|
| 55 |
- var rw *v1.Descriptor |
|
| 56 |
- for _, m := range index.Manifests {
|
|
| 57 |
- switch m.MediaType {
|
|
| 58 |
- case v1.MediaTypeImageLayer: |
|
| 59 |
- fk := m |
|
| 60 |
- rw = &fk |
|
| 61 |
- case images.MediaTypeDockerSchema2Manifest, images.MediaTypeDockerSchema2ManifestList: |
|
| 62 |
- config, err := images.Config(ctx, store, m, platforms.Default()) |
|
| 63 |
- if err != nil {
|
|
| 64 |
- return errors.Wrap(err, "unable to resolve image config") |
|
| 65 |
- } |
|
| 66 |
- diffIDs, err := images.RootFS(ctx, store, config) |
|
| 67 |
- if err != nil {
|
|
| 68 |
- return errors.Wrap(err, "unable to get rootfs") |
|
| 69 |
- } |
|
| 70 |
- setSnapshotterIfEmpty(c) |
|
| 71 |
- if _, err := client.SnapshotService(c.Snapshotter).Prepare(ctx, snapshotKey, identity.ChainID(diffIDs).String()); err != nil {
|
|
| 72 |
- if !errdefs.IsAlreadyExists(err) {
|
|
| 73 |
- return err |
|
| 74 |
- } |
|
| 75 |
- } |
|
| 76 |
- c.Image = index.Annotations["image.name"] |
|
| 77 |
- case images.MediaTypeContainerd1CheckpointConfig: |
|
| 78 |
- data, err := content.ReadBlob(ctx, store, m) |
|
| 79 |
- if err != nil {
|
|
| 80 |
- return errors.Wrap(err, "unable to read checkpoint config") |
|
| 81 |
- } |
|
| 82 |
- var any protobuf.Any |
|
| 83 |
- if err := proto.Unmarshal(data, &any); err != nil {
|
|
| 84 |
- return err |
|
| 85 |
- } |
|
| 86 |
- c.Spec = &any |
|
| 87 |
- } |
|
| 88 |
- } |
|
| 89 |
- if rw != nil {
|
|
| 90 |
- // apply the rw snapshot to the new rw layer |
|
| 91 |
- mounts, err := client.SnapshotService(c.Snapshotter).Mounts(ctx, snapshotKey) |
|
| 92 |
- if err != nil {
|
|
| 93 |
- return errors.Wrapf(err, "unable to get mounts for %s", snapshotKey) |
|
| 94 |
- } |
|
| 95 |
- if _, err := client.DiffService().Apply(ctx, *rw, mounts); err != nil {
|
|
| 96 |
- return errors.Wrap(err, "unable to apply rw diff") |
|
| 97 |
- } |
|
| 98 |
- } |
|
| 99 |
- c.SnapshotKey = snapshotKey |
|
| 100 |
- return nil |
|
| 101 |
- } |
|
| 102 |
-} |
|
| 103 |
- |
|
| 104 | 35 |
// WithRemappedSnapshot creates a new snapshot and remaps the uid/gid for the |
| 105 | 36 |
// filesystem to be used by a container with user namespaces |
| 106 | 37 |
func WithRemappedSnapshot(id string, i Image, uid, gid uint32) NewContainerOpts {
|
| 107 | 38 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,150 @@ |
| 0 |
+/* |
|
| 1 |
+ Copyright The containerd Authors. |
|
| 2 |
+ |
|
| 3 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
+ you may not use this file except in compliance with the License. |
|
| 5 |
+ You may obtain a copy of the License at |
|
| 6 |
+ |
|
| 7 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
+ |
|
| 9 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 10 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
+ See the License for the specific language governing permissions and |
|
| 13 |
+ limitations under the License. |
|
| 14 |
+*/ |
|
| 15 |
+ |
|
| 16 |
+package containerd |
|
| 17 |
+ |
|
| 18 |
+import ( |
|
| 19 |
+ "context" |
|
| 20 |
+ |
|
| 21 |
+ "github.com/containerd/containerd/containers" |
|
| 22 |
+ "github.com/containerd/containerd/content" |
|
| 23 |
+ "github.com/containerd/containerd/images" |
|
| 24 |
+ "github.com/containerd/containerd/platforms" |
|
| 25 |
+ "github.com/gogo/protobuf/proto" |
|
| 26 |
+ ptypes "github.com/gogo/protobuf/types" |
|
| 27 |
+ "github.com/opencontainers/image-spec/identity" |
|
| 28 |
+ imagespec "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 29 |
+ "github.com/pkg/errors" |
|
| 30 |
+) |
|
| 31 |
+ |
|
| 32 |
+var ( |
|
| 33 |
+ // ErrImageNameNotFoundInIndex is returned when the image name is not found in the index |
|
| 34 |
+ ErrImageNameNotFoundInIndex = errors.New("image name not found in index")
|
|
| 35 |
+ // ErrRuntimeNameNotFoundInIndex is returned when the runtime is not found in the index |
|
| 36 |
+ ErrRuntimeNameNotFoundInIndex = errors.New("runtime not found in index")
|
|
| 37 |
+ // ErrSnapshotterNameNotFoundInIndex is returned when the snapshotter is not found in the index |
|
| 38 |
+ ErrSnapshotterNameNotFoundInIndex = errors.New("snapshotter not found in index")
|
|
| 39 |
+) |
|
| 40 |
+ |
|
| 41 |
+// RestoreOpts are options to manage the restore operation |
|
| 42 |
+type RestoreOpts func(context.Context, string, *Client, Image, *imagespec.Index) NewContainerOpts |
|
| 43 |
+ |
|
| 44 |
+// WithRestoreImage restores the image for the container |
|
| 45 |
+func WithRestoreImage(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) NewContainerOpts {
|
|
| 46 |
+ return func(ctx context.Context, client *Client, c *containers.Container) error {
|
|
| 47 |
+ name, ok := index.Annotations[checkpointImageNameLabel] |
|
| 48 |
+ if !ok || name == "" {
|
|
| 49 |
+ return ErrRuntimeNameNotFoundInIndex |
|
| 50 |
+ } |
|
| 51 |
+ snapshotter, ok := index.Annotations[checkpointSnapshotterNameLabel] |
|
| 52 |
+ if !ok || name == "" {
|
|
| 53 |
+ return ErrSnapshotterNameNotFoundInIndex |
|
| 54 |
+ } |
|
| 55 |
+ i, err := client.GetImage(ctx, name) |
|
| 56 |
+ if err != nil {
|
|
| 57 |
+ return err |
|
| 58 |
+ } |
|
| 59 |
+ |
|
| 60 |
+ diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default()) |
|
| 61 |
+ if err != nil {
|
|
| 62 |
+ return err |
|
| 63 |
+ } |
|
| 64 |
+ parent := identity.ChainID(diffIDs).String() |
|
| 65 |
+ if _, err := client.SnapshotService(snapshotter).Prepare(ctx, id, parent); err != nil {
|
|
| 66 |
+ return err |
|
| 67 |
+ } |
|
| 68 |
+ c.Image = i.Name() |
|
| 69 |
+ c.SnapshotKey = id |
|
| 70 |
+ c.Snapshotter = snapshotter |
|
| 71 |
+ return nil |
|
| 72 |
+ } |
|
| 73 |
+} |
|
| 74 |
+ |
|
| 75 |
+// WithRestoreRuntime restores the runtime for the container |
|
| 76 |
+func WithRestoreRuntime(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) NewContainerOpts {
|
|
| 77 |
+ return func(ctx context.Context, client *Client, c *containers.Container) error {
|
|
| 78 |
+ name, ok := index.Annotations[checkpointRuntimeNameLabel] |
|
| 79 |
+ if !ok {
|
|
| 80 |
+ return ErrRuntimeNameNotFoundInIndex |
|
| 81 |
+ } |
|
| 82 |
+ |
|
| 83 |
+ // restore options if present |
|
| 84 |
+ m, err := GetIndexByMediaType(index, images.MediaTypeContainerd1CheckpointRuntimeOptions) |
|
| 85 |
+ if err != nil {
|
|
| 86 |
+ if err != ErrMediaTypeNotFound {
|
|
| 87 |
+ return err |
|
| 88 |
+ } |
|
| 89 |
+ } |
|
| 90 |
+ var options *ptypes.Any |
|
| 91 |
+ if m != nil {
|
|
| 92 |
+ store := client.ContentStore() |
|
| 93 |
+ data, err := content.ReadBlob(ctx, store, *m) |
|
| 94 |
+ if err != nil {
|
|
| 95 |
+ return errors.Wrap(err, "unable to read checkpoint runtime") |
|
| 96 |
+ } |
|
| 97 |
+ if err := proto.Unmarshal(data, options); err != nil {
|
|
| 98 |
+ return err |
|
| 99 |
+ } |
|
| 100 |
+ } |
|
| 101 |
+ |
|
| 102 |
+ c.Runtime = containers.RuntimeInfo{
|
|
| 103 |
+ Name: name, |
|
| 104 |
+ Options: options, |
|
| 105 |
+ } |
|
| 106 |
+ return nil |
|
| 107 |
+ } |
|
| 108 |
+} |
|
| 109 |
+ |
|
| 110 |
+// WithRestoreSpec restores the spec from the checkpoint for the container |
|
| 111 |
+func WithRestoreSpec(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) NewContainerOpts {
|
|
| 112 |
+ return func(ctx context.Context, client *Client, c *containers.Container) error {
|
|
| 113 |
+ m, err := GetIndexByMediaType(index, images.MediaTypeContainerd1CheckpointConfig) |
|
| 114 |
+ if err != nil {
|
|
| 115 |
+ return err |
|
| 116 |
+ } |
|
| 117 |
+ store := client.ContentStore() |
|
| 118 |
+ data, err := content.ReadBlob(ctx, store, *m) |
|
| 119 |
+ if err != nil {
|
|
| 120 |
+ return errors.Wrap(err, "unable to read checkpoint config") |
|
| 121 |
+ } |
|
| 122 |
+ var any ptypes.Any |
|
| 123 |
+ if err := proto.Unmarshal(data, &any); err != nil {
|
|
| 124 |
+ return err |
|
| 125 |
+ } |
|
| 126 |
+ c.Spec = &any |
|
| 127 |
+ return nil |
|
| 128 |
+ } |
|
| 129 |
+} |
|
| 130 |
+ |
|
| 131 |
+// WithRestoreRW restores the rw layer from the checkpoint for the container |
|
| 132 |
+func WithRestoreRW(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) NewContainerOpts {
|
|
| 133 |
+ return func(ctx context.Context, client *Client, c *containers.Container) error {
|
|
| 134 |
+ // apply rw layer |
|
| 135 |
+ rw, err := GetIndexByMediaType(index, imagespec.MediaTypeImageLayerGzip) |
|
| 136 |
+ if err != nil {
|
|
| 137 |
+ return err |
|
| 138 |
+ } |
|
| 139 |
+ mounts, err := client.SnapshotService(c.Snapshotter).Mounts(ctx, c.SnapshotKey) |
|
| 140 |
+ if err != nil {
|
|
| 141 |
+ return err |
|
| 142 |
+ } |
|
| 143 |
+ |
|
| 144 |
+ if _, err := client.DiffService().Apply(ctx, *rw, mounts); err != nil {
|
|
| 145 |
+ return err |
|
| 146 |
+ } |
|
| 147 |
+ return nil |
|
| 148 |
+ } |
|
| 149 |
+} |
| ... | ... |
@@ -86,6 +86,10 @@ type RuntimeInfo struct {
|
| 86 | 86 |
|
| 87 | 87 |
// Store interacts with the underlying container storage |
| 88 | 88 |
type Store interface {
|
| 89 |
+ // Get a container using the id. |
|
| 90 |
+ // |
|
| 91 |
+ // Container object is returned on success. If the id is not known to the |
|
| 92 |
+ // store, an error will be returned. |
|
| 89 | 93 |
Get(ctx context.Context, id string) (Container, error) |
| 90 | 94 |
|
| 91 | 95 |
// List returns containers that match one or more of the provided filters. |
| ... | ... |
@@ -138,10 +138,10 @@ func (e *Exchange) Subscribe(ctx context.Context, fs ...string) (ch <-chan *even |
| 138 | 138 |
) |
| 139 | 139 |
|
| 140 | 140 |
closeAll := func() {
|
| 141 |
- defer close(errq) |
|
| 142 |
- defer e.broadcaster.Remove(dst) |
|
| 143 |
- defer queue.Close() |
|
| 144 |
- defer channel.Close() |
|
| 141 |
+ channel.Close() |
|
| 142 |
+ queue.Close() |
|
| 143 |
+ e.broadcaster.Remove(dst) |
|
| 144 |
+ close(errq) |
|
| 145 | 145 |
} |
| 146 | 146 |
|
| 147 | 147 |
ch = evch |
| ... | ... |
@@ -20,36 +20,23 @@ import ( |
| 20 | 20 |
"context" |
| 21 | 21 |
"io" |
| 22 | 22 |
|
| 23 |
- "github.com/containerd/containerd/images" |
|
| 23 |
+ "github.com/containerd/containerd/images/oci" |
|
| 24 |
+ |
|
| 24 | 25 |
ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
| 25 | 26 |
"github.com/pkg/errors" |
| 26 | 27 |
) |
| 27 | 28 |
|
| 28 |
-type exportOpts struct {
|
|
| 29 |
-} |
|
| 30 |
- |
|
| 31 |
-// ExportOpt allows the caller to specify export-specific options |
|
| 32 |
-type ExportOpt func(c *exportOpts) error |
|
| 33 |
- |
|
| 34 |
-func resolveExportOpt(opts ...ExportOpt) (exportOpts, error) {
|
|
| 35 |
- var eopts exportOpts |
|
| 36 |
- for _, o := range opts {
|
|
| 37 |
- if err := o(&eopts); err != nil {
|
|
| 38 |
- return eopts, err |
|
| 39 |
- } |
|
| 40 |
- } |
|
| 41 |
- return eopts, nil |
|
| 42 |
-} |
|
| 43 |
- |
|
| 44 | 29 |
// Export exports an image to a Tar stream. |
| 45 | 30 |
// OCI format is used by default. |
| 46 | 31 |
// It is up to caller to put "org.opencontainers.image.ref.name" annotation to desc. |
| 47 | 32 |
// TODO(AkihiroSuda): support exporting multiple descriptors at once to a single archive stream. |
| 48 |
-func (c *Client) Export(ctx context.Context, exporter images.Exporter, desc ocispec.Descriptor, opts ...ExportOpt) (io.ReadCloser, error) {
|
|
| 49 |
- _, err := resolveExportOpt(opts...) // unused now |
|
| 33 |
+func (c *Client) Export(ctx context.Context, desc ocispec.Descriptor, opts ...oci.V1ExporterOpt) (io.ReadCloser, error) {
|
|
| 34 |
+ |
|
| 35 |
+ exporter, err := oci.ResolveV1ExportOpt(opts...) |
|
| 50 | 36 |
if err != nil {
|
| 51 | 37 |
return nil, err |
| 52 | 38 |
} |
| 39 |
+ |
|
| 53 | 40 |
pr, pw := io.Pipe() |
| 54 | 41 |
go func() {
|
| 55 | 42 |
pw.CloseWithError(errors.Wrap(exporter.Export(ctx, c.ContentStore(), desc, pw), "export failed")) |
| ... | ... |
@@ -71,7 +71,7 @@ func ParseAll(ss ...string) (Filter, error) {
|
| 71 | 71 |
for _, s := range ss {
|
| 72 | 72 |
f, err := Parse(s) |
| 73 | 73 |
if err != nil {
|
| 74 |
- return nil, errors.Wrapf(errdefs.ErrInvalidArgument, err.Error()) |
|
| 74 |
+ return nil, errors.Wrap(errdefs.ErrInvalidArgument, err.Error()) |
|
| 75 | 75 |
} |
| 76 | 76 |
|
| 77 | 77 |
fs = append(fs, f) |
| ... | ... |
@@ -45,7 +45,7 @@ var ( |
| 45 | 45 |
// Validate return nil if the string s is a valid identifier. |
| 46 | 46 |
// |
| 47 | 47 |
// identifiers must be valid domain names according to RFC 1035, section 2.3.1. To |
| 48 |
-// enforce case insensitvity, all characters must be lower case. |
|
| 48 |
+// enforce case insensitivity, all characters must be lower case. |
|
| 49 | 49 |
// |
| 50 | 50 |
// In general, identifiers that pass this validation, should be safe for use as |
| 51 | 51 |
// a domain names or filesystem path component. |
| ... | ... |
@@ -26,6 +26,7 @@ import ( |
| 26 | 26 |
ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
| 27 | 27 |
"github.com/pkg/errors" |
| 28 | 28 |
"golang.org/x/sync/errgroup" |
| 29 |
+ "golang.org/x/sync/semaphore" |
|
| 29 | 30 |
) |
| 30 | 31 |
|
| 31 | 32 |
var ( |
| ... | ... |
@@ -108,19 +109,30 @@ func Walk(ctx context.Context, handler Handler, descs ...ocispec.Descriptor) err |
| 108 | 108 |
// handler may return `ErrSkipDesc` to signal to the dispatcher to not traverse |
| 109 | 109 |
// any children. |
| 110 | 110 |
// |
| 111 |
+// A concurrency limiter can be passed in to limit the number of concurrent |
|
| 112 |
+// handlers running. When limiter is nil, there is no limit. |
|
| 113 |
+// |
|
| 111 | 114 |
// Typically, this function will be used with `FetchHandler`, often composed |
| 112 | 115 |
// with other handlers. |
| 113 | 116 |
// |
| 114 | 117 |
// If any handler returns an error, the dispatch session will be canceled. |
| 115 |
-func Dispatch(ctx context.Context, handler Handler, descs ...ocispec.Descriptor) error {
|
|
| 118 |
+func Dispatch(ctx context.Context, handler Handler, limiter *semaphore.Weighted, descs ...ocispec.Descriptor) error {
|
|
| 116 | 119 |
eg, ctx := errgroup.WithContext(ctx) |
| 117 | 120 |
for _, desc := range descs {
|
| 118 | 121 |
desc := desc |
| 119 | 122 |
|
| 123 |
+ if limiter != nil {
|
|
| 124 |
+ if err := limiter.Acquire(ctx, 1); err != nil {
|
|
| 125 |
+ return err |
|
| 126 |
+ } |
|
| 127 |
+ } |
|
| 120 | 128 |
eg.Go(func() error {
|
| 121 | 129 |
desc := desc |
| 122 | 130 |
|
| 123 | 131 |
children, err := handler.Handle(ctx, desc) |
| 132 |
+ if limiter != nil {
|
|
| 133 |
+ limiter.Release(1) |
|
| 134 |
+ } |
|
| 124 | 135 |
if err != nil {
|
| 125 | 136 |
if errors.Cause(err) == ErrSkipDesc {
|
| 126 | 137 |
return nil // don't traverse the children. |
| ... | ... |
@@ -129,7 +141,7 @@ func Dispatch(ctx context.Context, handler Handler, descs ...ocispec.Descriptor) |
| 129 | 129 |
} |
| 130 | 130 |
|
| 131 | 131 |
if len(children) > 0 {
|
| 132 |
- return Dispatch(ctx, handler, children...) |
|
| 132 |
+ return Dispatch(ctx, handler, limiter, children...) |
|
| 133 | 133 |
} |
| 134 | 134 |
|
| 135 | 135 |
return nil |
| ... | ... |
@@ -29,11 +29,14 @@ const ( |
| 29 | 29 |
MediaTypeDockerSchema2Manifest = "application/vnd.docker.distribution.manifest.v2+json" |
| 30 | 30 |
MediaTypeDockerSchema2ManifestList = "application/vnd.docker.distribution.manifest.list.v2+json" |
| 31 | 31 |
// Checkpoint/Restore Media Types |
| 32 |
- MediaTypeContainerd1Checkpoint = "application/vnd.containerd.container.criu.checkpoint.criu.tar" |
|
| 33 |
- MediaTypeContainerd1CheckpointPreDump = "application/vnd.containerd.container.criu.checkpoint.predump.tar" |
|
| 34 |
- MediaTypeContainerd1Resource = "application/vnd.containerd.container.resource.tar" |
|
| 35 |
- MediaTypeContainerd1RW = "application/vnd.containerd.container.rw.tar" |
|
| 36 |
- MediaTypeContainerd1CheckpointConfig = "application/vnd.containerd.container.checkpoint.config.v1+proto" |
|
| 32 |
+ MediaTypeContainerd1Checkpoint = "application/vnd.containerd.container.criu.checkpoint.criu.tar" |
|
| 33 |
+ MediaTypeContainerd1CheckpointPreDump = "application/vnd.containerd.container.criu.checkpoint.predump.tar" |
|
| 34 |
+ MediaTypeContainerd1Resource = "application/vnd.containerd.container.resource.tar" |
|
| 35 |
+ MediaTypeContainerd1RW = "application/vnd.containerd.container.rw.tar" |
|
| 36 |
+ MediaTypeContainerd1CheckpointConfig = "application/vnd.containerd.container.checkpoint.config.v1+proto" |
|
| 37 |
+ MediaTypeContainerd1CheckpointOptions = "application/vnd.containerd.container.checkpoint.options.v1+proto" |
|
| 38 |
+ MediaTypeContainerd1CheckpointRuntimeName = "application/vnd.containerd.container.checkpoint.runtime.name" |
|
| 39 |
+ MediaTypeContainerd1CheckpointRuntimeOptions = "application/vnd.containerd.container.checkpoint.runtime.options+proto" |
|
| 37 | 40 |
// Legacy Docker schema1 manifest |
| 38 | 41 |
MediaTypeDockerSchema1Manifest = "application/vnd.docker.distribution.manifest.v1+prettyjws" |
| 39 | 42 |
) |
| 40 | 43 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,241 @@ |
| 0 |
+/* |
|
| 1 |
+ Copyright The containerd Authors. |
|
| 2 |
+ |
|
| 3 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
+ you may not use this file except in compliance with the License. |
|
| 5 |
+ You may obtain a copy of the License at |
|
| 6 |
+ |
|
| 7 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
+ |
|
| 9 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 10 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
+ See the License for the specific language governing permissions and |
|
| 13 |
+ limitations under the License. |
|
| 14 |
+*/ |
|
| 15 |
+ |
|
| 16 |
+package oci |
|
| 17 |
+ |
|
| 18 |
+import ( |
|
| 19 |
+ "archive/tar" |
|
| 20 |
+ "context" |
|
| 21 |
+ "encoding/json" |
|
| 22 |
+ "io" |
|
| 23 |
+ "sort" |
|
| 24 |
+ |
|
| 25 |
+ "github.com/containerd/containerd/content" |
|
| 26 |
+ "github.com/containerd/containerd/images" |
|
| 27 |
+ "github.com/containerd/containerd/platforms" |
|
| 28 |
+ ocispecs "github.com/opencontainers/image-spec/specs-go" |
|
| 29 |
+ ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 30 |
+ "github.com/pkg/errors" |
|
| 31 |
+) |
|
| 32 |
+ |
|
| 33 |
+// V1Exporter implements OCI Image Spec v1. |
|
| 34 |
+// It is up to caller to put "org.opencontainers.image.ref.name" annotation to desc. |
|
| 35 |
+// |
|
| 36 |
+// TODO(AkihiroSuda): add V1Exporter{TranslateMediaTypes: true} that transforms media types,
|
|
| 37 |
+// e.g. application/vnd.docker.image.rootfs.diff.tar.gzip |
|
| 38 |
+// -> application/vnd.oci.image.layer.v1.tar+gzip |
|
| 39 |
+type V1Exporter struct {
|
|
| 40 |
+ AllPlatforms bool |
|
| 41 |
+} |
|
| 42 |
+ |
|
| 43 |
+// V1ExporterOpt allows the caller to set additional options to a new V1Exporter |
|
| 44 |
+type V1ExporterOpt func(c *V1Exporter) error |
|
| 45 |
+ |
|
| 46 |
+// DefaultV1Exporter return a default V1Exporter pointer |
|
| 47 |
+func DefaultV1Exporter() *V1Exporter {
|
|
| 48 |
+ return &V1Exporter{
|
|
| 49 |
+ AllPlatforms: false, |
|
| 50 |
+ } |
|
| 51 |
+} |
|
| 52 |
+ |
|
| 53 |
+// ResolveV1ExportOpt return a new V1Exporter with V1ExporterOpt |
|
| 54 |
+func ResolveV1ExportOpt(opts ...V1ExporterOpt) (*V1Exporter, error) {
|
|
| 55 |
+ exporter := DefaultV1Exporter() |
|
| 56 |
+ for _, o := range opts {
|
|
| 57 |
+ if err := o(exporter); err != nil {
|
|
| 58 |
+ return exporter, err |
|
| 59 |
+ } |
|
| 60 |
+ } |
|
| 61 |
+ return exporter, nil |
|
| 62 |
+} |
|
| 63 |
+ |
|
| 64 |
+// WithAllPlatforms set V1Exporter`s AllPlatforms option |
|
| 65 |
+func WithAllPlatforms(allPlatforms bool) V1ExporterOpt {
|
|
| 66 |
+ return func(c *V1Exporter) error {
|
|
| 67 |
+ c.AllPlatforms = allPlatforms |
|
| 68 |
+ return nil |
|
| 69 |
+ } |
|
| 70 |
+} |
|
| 71 |
+ |
|
| 72 |
+// Export implements Exporter. |
|
| 73 |
+func (oe *V1Exporter) Export(ctx context.Context, store content.Provider, desc ocispec.Descriptor, writer io.Writer) error {
|
|
| 74 |
+ tw := tar.NewWriter(writer) |
|
| 75 |
+ defer tw.Close() |
|
| 76 |
+ |
|
| 77 |
+ records := []tarRecord{
|
|
| 78 |
+ ociLayoutFile(""),
|
|
| 79 |
+ ociIndexRecord(desc), |
|
| 80 |
+ } |
|
| 81 |
+ |
|
| 82 |
+ algorithms := map[string]struct{}{}
|
|
| 83 |
+ exportHandler := func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
|
| 84 |
+ records = append(records, blobRecord(store, desc)) |
|
| 85 |
+ algorithms[desc.Digest.Algorithm().String()] = struct{}{}
|
|
| 86 |
+ return nil, nil |
|
| 87 |
+ } |
|
| 88 |
+ |
|
| 89 |
+ childrenHandler := images.ChildrenHandler(store) |
|
| 90 |
+ |
|
| 91 |
+ if !oe.AllPlatforms {
|
|
| 92 |
+ // get local default platform to fetch image manifest |
|
| 93 |
+ childrenHandler = images.FilterPlatforms(childrenHandler, platforms.Any(platforms.DefaultSpec())) |
|
| 94 |
+ } |
|
| 95 |
+ |
|
| 96 |
+ handlers := images.Handlers( |
|
| 97 |
+ childrenHandler, |
|
| 98 |
+ images.HandlerFunc(exportHandler), |
|
| 99 |
+ ) |
|
| 100 |
+ |
|
| 101 |
+ // Walk sequentially since the number of fetchs is likely one and doing in |
|
| 102 |
+ // parallel requires locking the export handler |
|
| 103 |
+ if err := images.Walk(ctx, handlers, desc); err != nil {
|
|
| 104 |
+ return err |
|
| 105 |
+ } |
|
| 106 |
+ |
|
| 107 |
+ if len(algorithms) > 0 {
|
|
| 108 |
+ records = append(records, directoryRecord("blobs/", 0755))
|
|
| 109 |
+ for alg := range algorithms {
|
|
| 110 |
+ records = append(records, directoryRecord("blobs/"+alg+"/", 0755))
|
|
| 111 |
+ } |
|
| 112 |
+ } |
|
| 113 |
+ |
|
| 114 |
+ return writeTar(ctx, tw, records) |
|
| 115 |
+} |
|
| 116 |
+ |
|
| 117 |
+type tarRecord struct {
|
|
| 118 |
+ Header *tar.Header |
|
| 119 |
+ CopyTo func(context.Context, io.Writer) (int64, error) |
|
| 120 |
+} |
|
| 121 |
+ |
|
| 122 |
+func blobRecord(cs content.Provider, desc ocispec.Descriptor) tarRecord {
|
|
| 123 |
+ path := "blobs/" + desc.Digest.Algorithm().String() + "/" + desc.Digest.Hex() |
|
| 124 |
+ return tarRecord{
|
|
| 125 |
+ Header: &tar.Header{
|
|
| 126 |
+ Name: path, |
|
| 127 |
+ Mode: 0444, |
|
| 128 |
+ Size: desc.Size, |
|
| 129 |
+ Typeflag: tar.TypeReg, |
|
| 130 |
+ }, |
|
| 131 |
+ CopyTo: func(ctx context.Context, w io.Writer) (int64, error) {
|
|
| 132 |
+ r, err := cs.ReaderAt(ctx, desc) |
|
| 133 |
+ if err != nil {
|
|
| 134 |
+ return 0, errors.Wrap(err, "failed to get reader") |
|
| 135 |
+ } |
|
| 136 |
+ defer r.Close() |
|
| 137 |
+ |
|
| 138 |
+ // Verify digest |
|
| 139 |
+ dgstr := desc.Digest.Algorithm().Digester() |
|
| 140 |
+ |
|
| 141 |
+ n, err := io.Copy(io.MultiWriter(w, dgstr.Hash()), content.NewReader(r)) |
|
| 142 |
+ if err != nil {
|
|
| 143 |
+ return 0, errors.Wrap(err, "failed to copy to tar") |
|
| 144 |
+ } |
|
| 145 |
+ if dgstr.Digest() != desc.Digest {
|
|
| 146 |
+ return 0, errors.Errorf("unexpected digest %s copied", dgstr.Digest())
|
|
| 147 |
+ } |
|
| 148 |
+ return n, nil |
|
| 149 |
+ }, |
|
| 150 |
+ } |
|
| 151 |
+} |
|
| 152 |
+ |
|
| 153 |
+func directoryRecord(name string, mode int64) tarRecord {
|
|
| 154 |
+ return tarRecord{
|
|
| 155 |
+ Header: &tar.Header{
|
|
| 156 |
+ Name: name, |
|
| 157 |
+ Mode: mode, |
|
| 158 |
+ Typeflag: tar.TypeDir, |
|
| 159 |
+ }, |
|
| 160 |
+ } |
|
| 161 |
+} |
|
| 162 |
+ |
|
| 163 |
+func ociLayoutFile(version string) tarRecord {
|
|
| 164 |
+ if version == "" {
|
|
| 165 |
+ version = ocispec.ImageLayoutVersion |
|
| 166 |
+ } |
|
| 167 |
+ layout := ocispec.ImageLayout{
|
|
| 168 |
+ Version: version, |
|
| 169 |
+ } |
|
| 170 |
+ |
|
| 171 |
+ b, err := json.Marshal(layout) |
|
| 172 |
+ if err != nil {
|
|
| 173 |
+ panic(err) |
|
| 174 |
+ } |
|
| 175 |
+ |
|
| 176 |
+ return tarRecord{
|
|
| 177 |
+ Header: &tar.Header{
|
|
| 178 |
+ Name: ocispec.ImageLayoutFile, |
|
| 179 |
+ Mode: 0444, |
|
| 180 |
+ Size: int64(len(b)), |
|
| 181 |
+ Typeflag: tar.TypeReg, |
|
| 182 |
+ }, |
|
| 183 |
+ CopyTo: func(ctx context.Context, w io.Writer) (int64, error) {
|
|
| 184 |
+ n, err := w.Write(b) |
|
| 185 |
+ return int64(n), err |
|
| 186 |
+ }, |
|
| 187 |
+ } |
|
| 188 |
+ |
|
| 189 |
+} |
|
| 190 |
+ |
|
| 191 |
+func ociIndexRecord(manifests ...ocispec.Descriptor) tarRecord {
|
|
| 192 |
+ index := ocispec.Index{
|
|
| 193 |
+ Versioned: ocispecs.Versioned{
|
|
| 194 |
+ SchemaVersion: 2, |
|
| 195 |
+ }, |
|
| 196 |
+ Manifests: manifests, |
|
| 197 |
+ } |
|
| 198 |
+ |
|
| 199 |
+ b, err := json.Marshal(index) |
|
| 200 |
+ if err != nil {
|
|
| 201 |
+ panic(err) |
|
| 202 |
+ } |
|
| 203 |
+ |
|
| 204 |
+ return tarRecord{
|
|
| 205 |
+ Header: &tar.Header{
|
|
| 206 |
+ Name: "index.json", |
|
| 207 |
+ Mode: 0644, |
|
| 208 |
+ Size: int64(len(b)), |
|
| 209 |
+ Typeflag: tar.TypeReg, |
|
| 210 |
+ }, |
|
| 211 |
+ CopyTo: func(ctx context.Context, w io.Writer) (int64, error) {
|
|
| 212 |
+ n, err := w.Write(b) |
|
| 213 |
+ return int64(n), err |
|
| 214 |
+ }, |
|
| 215 |
+ } |
|
| 216 |
+} |
|
| 217 |
+ |
|
| 218 |
+func writeTar(ctx context.Context, tw *tar.Writer, records []tarRecord) error {
|
|
| 219 |
+ sort.Slice(records, func(i, j int) bool {
|
|
| 220 |
+ return records[i].Header.Name < records[j].Header.Name |
|
| 221 |
+ }) |
|
| 222 |
+ |
|
| 223 |
+ for _, record := range records {
|
|
| 224 |
+ if err := tw.WriteHeader(record.Header); err != nil {
|
|
| 225 |
+ return err |
|
| 226 |
+ } |
|
| 227 |
+ if record.CopyTo != nil {
|
|
| 228 |
+ n, err := record.CopyTo(ctx, tw) |
|
| 229 |
+ if err != nil {
|
|
| 230 |
+ return err |
|
| 231 |
+ } |
|
| 232 |
+ if n != record.Header.Size {
|
|
| 233 |
+ return errors.Errorf("unexpected copy size for %s", record.Header.Name)
|
|
| 234 |
+ } |
|
| 235 |
+ } else if record.Header.Size > 0 {
|
|
| 236 |
+ return errors.Errorf("no content to write to record with non-zero size for %s", record.Header.Name)
|
|
| 237 |
+ } |
|
| 238 |
+ } |
|
| 239 |
+ return nil |
|
| 240 |
+} |
| ... | ... |
@@ -59,7 +59,6 @@ func (c *Client) Install(ctx context.Context, image Image, opts ...InstallOpts) |
| 59 | 59 |
if err != nil {
|
| 60 | 60 |
return err |
| 61 | 61 |
} |
| 62 |
- defer r.Close() |
|
| 63 | 62 |
if _, err := archive.Apply(ctx, path, r, archive.WithFilter(func(hdr *tar.Header) (bool, error) {
|
| 64 | 63 |
d := filepath.Dir(hdr.Name) |
| 65 | 64 |
result := d == "bin" |
| ... | ... |
@@ -73,8 +72,10 @@ func (c *Client) Install(ctx context.Context, image Image, opts ...InstallOpts) |
| 73 | 73 |
} |
| 74 | 74 |
return result, nil |
| 75 | 75 |
})); err != nil {
|
| 76 |
+ r.Close() |
|
| 76 | 77 |
return err |
| 77 | 78 |
} |
| 79 |
+ r.Close() |
|
| 78 | 80 |
} |
| 79 | 81 |
return nil |
| 80 | 82 |
} |
| ... | ... |
@@ -14,13 +14,11 @@ |
| 14 | 14 |
limitations under the License. |
| 15 | 15 |
*/ |
| 16 | 16 |
|
| 17 |
-package metadata |
|
| 18 |
- |
|
| 19 |
-import ( |
|
| 20 |
- digest "github.com/opencontainers/go-digest" |
|
| 21 |
- bolt "go.etcd.io/bbolt" |
|
| 22 |
-) |
|
| 23 |
- |
|
| 17 |
+// Package metadata stores all labels and object specific metadata by namespace. |
|
| 18 |
+// This package also contains the main garbage collection logic for cleaning up |
|
| 19 |
+// resources consistently and atomically. Resources used by backends will be |
|
| 20 |
+// tracked in the metadata store to be exposed to consumers of this package. |
|
| 21 |
+// |
|
| 24 | 22 |
// The layout where a "/" delineates a bucket is described in the following |
| 25 | 23 |
// section. Please try to follow this as closely as possible when adding |
| 26 | 24 |
// functionality. We can bolster this with helpers and more structure if that |
| ... | ... |
@@ -43,6 +41,84 @@ import ( |
| 43 | 43 |
// |
| 44 | 44 |
// key: object-specific key identifying the storage bucket for the objects |
| 45 | 45 |
// contents. |
| 46 |
+// |
|
| 47 |
+// Below is the current database schema. This should be updated each time |
|
| 48 |
+// the structure is changed in addition to adding a migration and incrementing |
|
| 49 |
+// the database version. Note that `╘══*...*` refers to maps with arbitrary |
|
| 50 |
+// keys. |
|
| 51 |
+// ├──version : <varint> - Latest version, see migrations |
|
| 52 |
+// └──v1 - Schema version bucket |
|
| 53 |
+// ╘══*namespace* |
|
| 54 |
+// ├──labels |
|
| 55 |
+// │ ╘══*key* : <string> - Label value |
|
| 56 |
+// ├──image |
|
| 57 |
+// │ ╘══*image name* |
|
| 58 |
+// │ ├──createdat : <binary time> - Created at |
|
| 59 |
+// │ ├──updatedat : <binary time> - Updated at |
|
| 60 |
+// │ ├──target |
|
| 61 |
+// │ │ ├──digest : <digest> - Descriptor digest |
|
| 62 |
+// │ │ ├──mediatype : <string> - Descriptor media type |
|
| 63 |
+// │ │ └──size : <varint> - Descriptor size |
|
| 64 |
+// │ └──labels |
|
| 65 |
+// │ ╘══*key* : <string> - Label value |
|
| 66 |
+// ├──containers |
|
| 67 |
+// │ ╘══*container id* |
|
| 68 |
+// │ ├──createdat : <binary time> - Created at |
|
| 69 |
+// │ ├──updatedat : <binary time> - Updated at |
|
| 70 |
+// │ ├──spec : <binary> - Proto marshaled spec |
|
| 71 |
+// │ ├──image : <string> - Image name |
|
| 72 |
+// │ ├──snapshotter : <string> - Snapshotter name |
|
| 73 |
+// │ ├──snapshotKey : <string> - Snapshot key |
|
| 74 |
+// │ ├──runtime |
|
| 75 |
+// │ │ ├──name : <string> - Runtime name |
|
| 76 |
+// │ │ ├──extensions |
|
| 77 |
+// │ │ │ ╘══*name* : <binary> - Proto marshaled extension |
|
| 78 |
+// │ │ └──options : <binary> - Proto marshaled options |
|
| 79 |
+// │ └──labels |
|
| 80 |
+// │ ╘══*key* : <string> - Label value |
|
| 81 |
+// ├──snapshots |
|
| 82 |
+// │ ╘══*snapshotter* |
|
| 83 |
+// │ ╘══*snapshot key* |
|
| 84 |
+// │ ├──name : <string> - Snapshot name in backend |
|
| 85 |
+// │ ├──createdat : <binary time> - Created at |
|
| 86 |
+// │ ├──updatedat : <binary time> - Updated at |
|
| 87 |
+// │ ├──parent : <string> - Parent snapshot name |
|
| 88 |
+// │ ├──children |
|
| 89 |
+// │ │ ╘══*snapshot key* : <nil> - Child snapshot reference |
|
| 90 |
+// │ └──labels |
|
| 91 |
+// │ ╘══*key* : <string> - Label value |
|
| 92 |
+// ├──content |
|
| 93 |
+// │ ├──blob |
|
| 94 |
+// │ │ ╘══*blob digest* |
|
| 95 |
+// │ │ ├──createdat : <binary time> - Created at |
|
| 96 |
+// │ │ ├──updatedat : <binary time> - Updated at |
|
| 97 |
+// │ │ ├──size : <varint> - Blob size |
|
| 98 |
+// │ │ └──labels |
|
| 99 |
+// │ │ ╘══*key* : <string> - Label value |
|
| 100 |
+// │ └──ingests |
|
| 101 |
+// │ ╘══*ingest reference* |
|
| 102 |
+// │ ├──ref : <string> - Ingest reference in backend |
|
| 103 |
+// │ ├──expireat : <binary time> - Time to expire ingest |
|
| 104 |
+// │ └──expected : <digest> - Expected commit digest |
|
| 105 |
+// └──leases |
|
| 106 |
+// ╘══*lease id* |
|
| 107 |
+// ├──createdat : <binary time> - Created at |
|
| 108 |
+// ├──labels |
|
| 109 |
+// │ ╘══*key* : <string> - Label value |
|
| 110 |
+// ├──snapshots |
|
| 111 |
+// │ ╘══*snapshotter* |
|
| 112 |
+// │ ╘══*snapshot key* : <nil> - Snapshot reference |
|
| 113 |
+// ├──content |
|
| 114 |
+// │ ╘══*blob digest* : <nil> - Content blob reference |
|
| 115 |
+// └──ingests |
|
| 116 |
+// ╘══*ingest reference* : <nil> - Content ingest reference |
|
| 117 |
+package metadata |
|
| 118 |
+ |
|
| 119 |
+import ( |
|
| 120 |
+ digest "github.com/opencontainers/go-digest" |
|
| 121 |
+ bolt "go.etcd.io/bbolt" |
|
| 122 |
+) |
|
| 123 |
+ |
|
| 46 | 124 |
var ( |
| 47 | 125 |
bucketKeyVersion = []byte(schemaVersion) |
| 48 | 126 |
bucketKeyDBVersion = []byte("version") // stores the version of the schema
|
| ... | ... |
@@ -72,7 +72,7 @@ func (s *containerStore) List(ctx context.Context, fs ...string) ([]containers.C |
| 72 | 72 |
|
| 73 | 73 |
filter, err := filters.ParseAll(fs...) |
| 74 | 74 |
if err != nil {
|
| 75 |
- return nil, errors.Wrapf(errdefs.ErrInvalidArgument, err.Error()) |
|
| 75 |
+ return nil, errors.Wrap(errdefs.ErrInvalidArgument, err.Error()) |
|
| 76 | 76 |
} |
| 77 | 77 |
|
| 78 | 78 |
bkt := getContainersBucket(s.tx, namespace) |
| ... | ... |
@@ -38,16 +38,31 @@ import ( |
| 38 | 38 |
|
| 39 | 39 |
type contentStore struct {
|
| 40 | 40 |
content.Store |
| 41 |
- db *DB |
|
| 42 |
- l sync.RWMutex |
|
| 41 |
+ db *DB |
|
| 42 |
+ shared bool |
|
| 43 |
+ l sync.RWMutex |
|
| 43 | 44 |
} |
| 44 | 45 |
|
| 45 | 46 |
// newContentStore returns a namespaced content store using an existing |
| 46 | 47 |
// content store interface. |
| 47 |
-func newContentStore(db *DB, cs content.Store) *contentStore {
|
|
| 48 |
+// policy defines the sharing behavior for content between namespaces. Both |
|
| 49 |
+// modes will result in shared storage in the backend for committed. Choose |
|
| 50 |
+// "shared" to prevent separate namespaces from having to pull the same content |
|
| 51 |
+// twice. Choose "isolated" if the content must not be shared between |
|
| 52 |
+// namespaces. |
|
| 53 |
+// |
|
| 54 |
+// If the policy is "shared", writes will try to resolve the "expected" digest |
|
| 55 |
+// against the backend, allowing imports of content from other namespaces. In |
|
| 56 |
+// "isolated" mode, the client must prove they have the content by providing |
|
| 57 |
+// the entire blob before the content can be added to another namespace. |
|
| 58 |
+// |
|
| 59 |
+// Since we have only two policies right now, it's simpler using bool to |
|
| 60 |
+// represent it internally. |
|
| 61 |
+func newContentStore(db *DB, shared bool, cs content.Store) *contentStore {
|
|
| 48 | 62 |
return &contentStore{
|
| 49 |
- Store: cs, |
|
| 50 |
- db: db, |
|
| 63 |
+ Store: cs, |
|
| 64 |
+ db: db, |
|
| 65 |
+ shared: shared, |
|
| 51 | 66 |
} |
| 52 | 67 |
} |
| 53 | 68 |
|
| ... | ... |
@@ -383,13 +398,15 @@ func (cs *contentStore) Writer(ctx context.Context, opts ...content.WriterOpt) ( |
| 383 | 383 |
return nil |
| 384 | 384 |
} |
| 385 | 385 |
|
| 386 |
- if st, err := cs.Store.Info(ctx, wOpts.Desc.Digest); err == nil {
|
|
| 387 |
- // Ensure the expected size is the same, it is likely |
|
| 388 |
- // an error if the size is mismatched but the caller |
|
| 389 |
- // must resolve this on commit |
|
| 390 |
- if wOpts.Desc.Size == 0 || wOpts.Desc.Size == st.Size {
|
|
| 391 |
- shared = true |
|
| 392 |
- wOpts.Desc.Size = st.Size |
|
| 386 |
+ if cs.shared {
|
|
| 387 |
+ if st, err := cs.Store.Info(ctx, wOpts.Desc.Digest); err == nil {
|
|
| 388 |
+ // Ensure the expected size is the same, it is likely |
|
| 389 |
+ // an error if the size is mismatched but the caller |
|
| 390 |
+ // must resolve this on commit |
|
| 391 |
+ if wOpts.Desc.Size == 0 || wOpts.Desc.Size == st.Size {
|
|
| 392 |
+ shared = true |
|
| 393 |
+ wOpts.Desc.Size = st.Size |
|
| 394 |
+ } |
|
| 393 | 395 |
} |
| 394 | 396 |
} |
| 395 | 397 |
} |
| ... | ... |
@@ -46,6 +46,19 @@ const ( |
| 46 | 46 |
dbVersion = 3 |
| 47 | 47 |
) |
| 48 | 48 |
|
| 49 |
+// DBOpt configures how we set up the DB |
|
| 50 |
+type DBOpt func(*dbOptions) |
|
| 51 |
+ |
|
| 52 |
+// WithPolicyIsolated isolates contents between namespaces |
|
| 53 |
+func WithPolicyIsolated(o *dbOptions) {
|
|
| 54 |
+ o.shared = false |
|
| 55 |
+} |
|
| 56 |
+ |
|
| 57 |
+// dbOptions configure db options. |
|
| 58 |
+type dbOptions struct {
|
|
| 59 |
+ shared bool |
|
| 60 |
+} |
|
| 61 |
+ |
|
| 49 | 62 |
// DB represents a metadata database backed by a bolt |
| 50 | 63 |
// database. The database is fully namespaced and stores |
| 51 | 64 |
// image, container, namespace, snapshot, and content data |
| ... | ... |
@@ -72,19 +85,28 @@ type DB struct {
|
| 72 | 72 |
// mutationCallbacks are called after each mutation with the flag |
| 73 | 73 |
// set indicating whether any dirty flags are set |
| 74 | 74 |
mutationCallbacks []func(bool) |
| 75 |
+ |
|
| 76 |
+ dbopts dbOptions |
|
| 75 | 77 |
} |
| 76 | 78 |
|
| 77 | 79 |
// NewDB creates a new metadata database using the provided |
| 78 | 80 |
// bolt database, content store, and snapshotters. |
| 79 |
-func NewDB(db *bolt.DB, cs content.Store, ss map[string]snapshots.Snapshotter) *DB {
|
|
| 81 |
+func NewDB(db *bolt.DB, cs content.Store, ss map[string]snapshots.Snapshotter, opts ...DBOpt) *DB {
|
|
| 80 | 82 |
m := &DB{
|
| 81 | 83 |
db: db, |
| 82 | 84 |
ss: make(map[string]*snapshotter, len(ss)), |
| 83 | 85 |
dirtySS: map[string]struct{}{},
|
| 86 |
+ dbopts: dbOptions{
|
|
| 87 |
+ shared: true, |
|
| 88 |
+ }, |
|
| 89 |
+ } |
|
| 90 |
+ |
|
| 91 |
+ for _, opt := range opts {
|
|
| 92 |
+ opt(&m.dbopts) |
|
| 84 | 93 |
} |
| 85 | 94 |
|
| 86 | 95 |
// Initialize data stores |
| 87 |
- m.cs = newContentStore(m, cs) |
|
| 96 |
+ m.cs = newContentStore(m, m.dbopts.shared, cs) |
|
| 88 | 97 |
for name, sn := range ss {
|
| 89 | 98 |
m.ss[name] = newSnapshotter(m, name, sn) |
| 90 | 99 |
} |
| ... | ... |
@@ -84,7 +84,7 @@ func (s *imageStore) List(ctx context.Context, fs ...string) ([]images.Image, er |
| 84 | 84 |
|
| 85 | 85 |
filter, err := filters.ParseAll(fs...) |
| 86 | 86 |
if err != nil {
|
| 87 |
- return nil, errors.Wrapf(errdefs.ErrInvalidArgument, err.Error()) |
|
| 87 |
+ return nil, errors.Wrap(errdefs.ErrInvalidArgument, err.Error()) |
|
| 88 | 88 |
} |
| 89 | 89 |
|
| 90 | 90 |
var m []images.Image |
| ... | ... |
@@ -122,7 +122,7 @@ func (lm *LeaseManager) List(ctx context.Context, fs ...string) ([]leases.Lease, |
| 122 | 122 |
|
| 123 | 123 |
filter, err := filters.ParseAll(fs...) |
| 124 | 124 |
if err != nil {
|
| 125 |
- return nil, errors.Wrapf(errdefs.ErrInvalidArgument, err.Error()) |
|
| 125 |
+ return nil, errors.Wrap(errdefs.ErrInvalidArgument, err.Error()) |
|
| 126 | 126 |
} |
| 127 | 127 |
|
| 128 | 128 |
var ll []leases.Lease |
| ... | ... |
@@ -247,17 +247,8 @@ func populateDefaultWindowsSpec(ctx context.Context, s *Spec, id string) error {
|
| 247 | 247 |
Root: &specs.Root{},
|
| 248 | 248 |
Process: &specs.Process{
|
| 249 | 249 |
Cwd: `C:\`, |
| 250 |
- ConsoleSize: &specs.Box{
|
|
| 251 |
- Width: 80, |
|
| 252 |
- Height: 20, |
|
| 253 |
- }, |
|
| 254 |
- }, |
|
| 255 |
- Windows: &specs.Windows{
|
|
| 256 |
- IgnoreFlushesDuringBoot: true, |
|
| 257 |
- Network: &specs.WindowsNetwork{
|
|
| 258 |
- AllowUnqualifiedDNSQuery: true, |
|
| 259 |
- }, |
|
| 260 | 250 |
}, |
| 251 |
+ Windows: &specs.Windows{},
|
|
| 261 | 252 |
} |
| 262 | 253 |
return nil |
| 263 | 254 |
} |
| ... | ... |
@@ -141,8 +141,10 @@ func WithEnv(environmentVariables []string) SpecOpts {
|
| 141 | 141 |
// replaced by env key or appended to the list |
| 142 | 142 |
func replaceOrAppendEnvValues(defaults, overrides []string) []string {
|
| 143 | 143 |
cache := make(map[string]int, len(defaults)) |
| 144 |
+ results := make([]string, 0, len(defaults)) |
|
| 144 | 145 |
for i, e := range defaults {
|
| 145 | 146 |
parts := strings.SplitN(e, "=", 2) |
| 147 |
+ results = append(results, e) |
|
| 146 | 148 |
cache[parts[0]] = i |
| 147 | 149 |
} |
| 148 | 150 |
|
| ... | ... |
@@ -150,7 +152,7 @@ func replaceOrAppendEnvValues(defaults, overrides []string) []string {
|
| 150 | 150 |
// Values w/o = means they want this env to be removed/unset. |
| 151 | 151 |
if !strings.Contains(value, "=") {
|
| 152 | 152 |
if i, exists := cache[value]; exists {
|
| 153 |
- defaults[i] = "" // Used to indicate it should be removed |
|
| 153 |
+ results[i] = "" // Used to indicate it should be removed |
|
| 154 | 154 |
} |
| 155 | 155 |
continue |
| 156 | 156 |
} |
| ... | ... |
@@ -158,21 +160,21 @@ func replaceOrAppendEnvValues(defaults, overrides []string) []string {
|
| 158 | 158 |
// Just do a normal set/update |
| 159 | 159 |
parts := strings.SplitN(value, "=", 2) |
| 160 | 160 |
if i, exists := cache[parts[0]]; exists {
|
| 161 |
- defaults[i] = value |
|
| 161 |
+ results[i] = value |
|
| 162 | 162 |
} else {
|
| 163 |
- defaults = append(defaults, value) |
|
| 163 |
+ results = append(results, value) |
|
| 164 | 164 |
} |
| 165 | 165 |
} |
| 166 | 166 |
|
| 167 | 167 |
// Now remove all entries that we want to "unset" |
| 168 |
- for i := 0; i < len(defaults); i++ {
|
|
| 169 |
- if defaults[i] == "" {
|
|
| 170 |
- defaults = append(defaults[:i], defaults[i+1:]...) |
|
| 168 |
+ for i := 0; i < len(results); i++ {
|
|
| 169 |
+ if results[i] == "" {
|
|
| 170 |
+ results = append(results[:i], results[i+1:]...) |
|
| 171 | 171 |
i-- |
| 172 | 172 |
} |
| 173 | 173 |
} |
| 174 | 174 |
|
| 175 |
- return defaults |
|
| 175 |
+ return results |
|
| 176 | 176 |
} |
| 177 | 177 |
|
| 178 | 178 |
// WithProcessArgs replaces the args on the generated spec |
| ... | ... |
@@ -310,7 +312,7 @@ func WithImageConfigArgs(image Image, args []string) SpecOpts {
|
| 310 | 310 |
|
| 311 | 311 |
setProcess(s) |
| 312 | 312 |
if s.Linux != nil {
|
| 313 |
- s.Process.Env = append(s.Process.Env, config.Env...) |
|
| 313 |
+ s.Process.Env = replaceOrAppendEnvValues(s.Process.Env, config.Env) |
|
| 314 | 314 |
cmd := config.Cmd |
| 315 | 315 |
if len(args) > 0 {
|
| 316 | 316 |
cmd = args |
| ... | ... |
@@ -332,8 +334,14 @@ func WithImageConfigArgs(image Image, args []string) SpecOpts {
|
| 332 | 332 |
// even if there is no specified user in the image config |
| 333 | 333 |
return WithAdditionalGIDs("root")(ctx, client, c, s)
|
| 334 | 334 |
} else if s.Windows != nil {
|
| 335 |
- s.Process.Env = config.Env |
|
| 336 |
- s.Process.Args = append(config.Entrypoint, config.Cmd...) |
|
| 335 |
+ s.Process.Env = replaceOrAppendEnvValues(s.Process.Env, config.Env) |
|
| 336 |
+ cmd := config.Cmd |
|
| 337 |
+ if len(args) > 0 {
|
|
| 338 |
+ cmd = args |
|
| 339 |
+ } |
|
| 340 |
+ s.Process.Args = append(config.Entrypoint, cmd...) |
|
| 341 |
+ |
|
| 342 |
+ s.Process.Cwd = config.WorkingDir |
|
| 337 | 343 |
s.Process.User = specs.User{
|
| 338 | 344 |
Username: config.User, |
| 339 | 345 |
} |
| ... | ... |
@@ -1026,3 +1034,46 @@ func WithWindowsHyperV(_ context.Context, _ Client, _ *containers.Container, s * |
| 1026 | 1026 |
} |
| 1027 | 1027 |
return nil |
| 1028 | 1028 |
} |
| 1029 |
+ |
|
| 1030 |
+// WithMemoryLimit sets the `Linux.LinuxResources.Memory.Limit` section to the |
|
| 1031 |
+// `limit` specified if the `Linux` section is not `nil`. Additionally sets the |
|
| 1032 |
+// `Windows.WindowsResources.Memory.Limit` section if the `Windows` section is |
|
| 1033 |
+// not `nil`. |
|
| 1034 |
+func WithMemoryLimit(limit uint64) SpecOpts {
|
|
| 1035 |
+ return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
|
| 1036 |
+ if s.Linux != nil {
|
|
| 1037 |
+ if s.Linux.Resources == nil {
|
|
| 1038 |
+ s.Linux.Resources = &specs.LinuxResources{}
|
|
| 1039 |
+ } |
|
| 1040 |
+ if s.Linux.Resources.Memory == nil {
|
|
| 1041 |
+ s.Linux.Resources.Memory = &specs.LinuxMemory{}
|
|
| 1042 |
+ } |
|
| 1043 |
+ l := int64(limit) |
|
| 1044 |
+ s.Linux.Resources.Memory.Limit = &l |
|
| 1045 |
+ } |
|
| 1046 |
+ if s.Windows != nil {
|
|
| 1047 |
+ if s.Windows.Resources == nil {
|
|
| 1048 |
+ s.Windows.Resources = &specs.WindowsResources{}
|
|
| 1049 |
+ } |
|
| 1050 |
+ if s.Windows.Resources.Memory == nil {
|
|
| 1051 |
+ s.Windows.Resources.Memory = &specs.WindowsMemoryResources{}
|
|
| 1052 |
+ } |
|
| 1053 |
+ s.Windows.Resources.Memory.Limit = &limit |
|
| 1054 |
+ } |
|
| 1055 |
+ return nil |
|
| 1056 |
+ } |
|
| 1057 |
+} |
|
| 1058 |
+ |
|
| 1059 |
+// WithAnnotations appends or replaces the annotations on the spec with the |
|
| 1060 |
+// provided annotations |
|
| 1061 |
+func WithAnnotations(annotations map[string]string) SpecOpts {
|
|
| 1062 |
+ return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
|
| 1063 |
+ if s.Annotations == nil {
|
|
| 1064 |
+ s.Annotations = make(map[string]string) |
|
| 1065 |
+ } |
|
| 1066 |
+ for k, v := range annotations {
|
|
| 1067 |
+ s.Annotations[k] = v |
|
| 1068 |
+ } |
|
| 1069 |
+ return nil |
|
| 1070 |
+ } |
|
| 1071 |
+} |
| 1029 | 1072 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,67 @@ |
| 0 |
+// +build windows |
|
| 1 |
+ |
|
| 2 |
+/* |
|
| 3 |
+ Copyright The containerd Authors. |
|
| 4 |
+ |
|
| 5 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 6 |
+ you may not use this file except in compliance with the License. |
|
| 7 |
+ You may obtain a copy of the License at |
|
| 8 |
+ |
|
| 9 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 10 |
+ |
|
| 11 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 12 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 13 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 14 |
+ See the License for the specific language governing permissions and |
|
| 15 |
+ limitations under the License. |
|
| 16 |
+*/ |
|
| 17 |
+ |
|
| 18 |
+package oci |
|
| 19 |
+ |
|
| 20 |
+import ( |
|
| 21 |
+ "context" |
|
| 22 |
+ |
|
| 23 |
+ "github.com/containerd/containerd/containers" |
|
| 24 |
+ specs "github.com/opencontainers/runtime-spec/specs-go" |
|
| 25 |
+) |
|
| 26 |
+ |
|
| 27 |
+// WithWindowsCPUCount sets the `Windows.Resources.CPU.Count` section to the |
|
| 28 |
+// `count` specified. |
|
| 29 |
+func WithWindowsCPUCount(count uint64) SpecOpts {
|
|
| 30 |
+ return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
|
| 31 |
+ if s.Windows.Resources == nil {
|
|
| 32 |
+ s.Windows.Resources = &specs.WindowsResources{}
|
|
| 33 |
+ } |
|
| 34 |
+ if s.Windows.Resources.CPU == nil {
|
|
| 35 |
+ s.Windows.Resources.CPU = &specs.WindowsCPUResources{}
|
|
| 36 |
+ } |
|
| 37 |
+ s.Windows.Resources.CPU.Count = &count |
|
| 38 |
+ return nil |
|
| 39 |
+ } |
|
| 40 |
+} |
|
| 41 |
+ |
|
| 42 |
+// WithWindowsIgnoreFlushesDuringBoot sets `Windows.IgnoreFlushesDuringBoot`. |
|
| 43 |
+func WithWindowsIgnoreFlushesDuringBoot() SpecOpts {
|
|
| 44 |
+ return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
|
| 45 |
+ if s.Windows == nil {
|
|
| 46 |
+ s.Windows = &specs.Windows{}
|
|
| 47 |
+ } |
|
| 48 |
+ s.Windows.IgnoreFlushesDuringBoot = true |
|
| 49 |
+ return nil |
|
| 50 |
+ } |
|
| 51 |
+} |
|
| 52 |
+ |
|
| 53 |
+// WithWindowNetworksAllowUnqualifiedDNSQuery sets `Windows.IgnoreFlushesDuringBoot`. |
|
| 54 |
+func WithWindowNetworksAllowUnqualifiedDNSQuery() SpecOpts {
|
|
| 55 |
+ return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
|
| 56 |
+ if s.Windows == nil {
|
|
| 57 |
+ s.Windows = &specs.Windows{}
|
|
| 58 |
+ } |
|
| 59 |
+ if s.Windows.Network == nil {
|
|
| 60 |
+ s.Windows.Network = &specs.WindowsNetwork{}
|
|
| 61 |
+ } |
|
| 62 |
+ |
|
| 63 |
+ s.Windows.Network.AllowUnqualifiedDNSQuery = true |
|
| 64 |
+ return nil |
|
| 65 |
+ } |
|
| 66 |
+} |
| ... | ... |
@@ -75,6 +75,15 @@ const ( |
| 75 | 75 |
GCPlugin Type = "io.containerd.gc.v1" |
| 76 | 76 |
) |
| 77 | 77 |
|
| 78 |
+const ( |
|
| 79 |
+ // RuntimeLinuxV1 is the legacy linux runtime |
|
| 80 |
+ RuntimeLinuxV1 = "io.containerd.runtime.v1.linux" |
|
| 81 |
+ // RuntimeRuncV1 is the runc runtime that supports a single container |
|
| 82 |
+ RuntimeRuncV1 = "io.containerd.runc.v1" |
|
| 83 |
+ // RuntimeRuncV2 is the runc runtime that supports multiple containers per shim |
|
| 84 |
+ RuntimeRuncV2 = "io.containerd.runc.v2" |
|
| 85 |
+) |
|
| 86 |
+ |
|
| 78 | 87 |
// Registration contains information for registering a plugin |
| 79 | 88 |
type Registration struct {
|
| 80 | 89 |
// Type of the plugin |
| 81 | 90 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,190 @@ |
| 0 |
+/* |
|
| 1 |
+ Copyright The containerd Authors. |
|
| 2 |
+ |
|
| 3 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
+ you may not use this file except in compliance with the License. |
|
| 5 |
+ You may obtain a copy of the License at |
|
| 6 |
+ |
|
| 7 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
+ |
|
| 9 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 10 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
+ See the License for the specific language governing permissions and |
|
| 13 |
+ limitations under the License. |
|
| 14 |
+*/ |
|
| 15 |
+ |
|
| 16 |
+package containerd |
|
| 17 |
+ |
|
| 18 |
+import ( |
|
| 19 |
+ "context" |
|
| 20 |
+ |
|
| 21 |
+ "github.com/containerd/containerd/errdefs" |
|
| 22 |
+ "github.com/containerd/containerd/images" |
|
| 23 |
+ "github.com/containerd/containerd/platforms" |
|
| 24 |
+ "github.com/containerd/containerd/remotes" |
|
| 25 |
+ "github.com/containerd/containerd/remotes/docker" |
|
| 26 |
+ "github.com/containerd/containerd/remotes/docker/schema1" |
|
| 27 |
+ ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 28 |
+ "github.com/pkg/errors" |
|
| 29 |
+ "golang.org/x/sync/semaphore" |
|
| 30 |
+) |
|
| 31 |
+ |
|
| 32 |
+// Pull downloads the provided content into containerd's content store |
|
| 33 |
+// and returns a platform specific image object |
|
| 34 |
+func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image, error) {
|
|
| 35 |
+ pullCtx := defaultRemoteContext() |
|
| 36 |
+ for _, o := range opts {
|
|
| 37 |
+ if err := o(c, pullCtx); err != nil {
|
|
| 38 |
+ return nil, err |
|
| 39 |
+ } |
|
| 40 |
+ } |
|
| 41 |
+ |
|
| 42 |
+ if pullCtx.PlatformMatcher == nil {
|
|
| 43 |
+ if len(pullCtx.Platforms) > 1 {
|
|
| 44 |
+ return nil, errors.New("cannot pull multiplatform image locally, try Fetch")
|
|
| 45 |
+ } else if len(pullCtx.Platforms) == 0 {
|
|
| 46 |
+ pullCtx.PlatformMatcher = platforms.Default() |
|
| 47 |
+ } else {
|
|
| 48 |
+ p, err := platforms.Parse(pullCtx.Platforms[0]) |
|
| 49 |
+ if err != nil {
|
|
| 50 |
+ return nil, errors.Wrapf(err, "invalid platform %s", pullCtx.Platforms[0]) |
|
| 51 |
+ } |
|
| 52 |
+ |
|
| 53 |
+ pullCtx.PlatformMatcher = platforms.Only(p) |
|
| 54 |
+ } |
|
| 55 |
+ } |
|
| 56 |
+ |
|
| 57 |
+ ctx, done, err := c.WithLease(ctx) |
|
| 58 |
+ if err != nil {
|
|
| 59 |
+ return nil, err |
|
| 60 |
+ } |
|
| 61 |
+ defer done(ctx) |
|
| 62 |
+ |
|
| 63 |
+ img, err := c.fetch(ctx, pullCtx, ref, 1) |
|
| 64 |
+ if err != nil {
|
|
| 65 |
+ return nil, err |
|
| 66 |
+ } |
|
| 67 |
+ |
|
| 68 |
+ i := NewImageWithPlatform(c, img, pullCtx.PlatformMatcher) |
|
| 69 |
+ |
|
| 70 |
+ if pullCtx.Unpack {
|
|
| 71 |
+ if err := i.Unpack(ctx, pullCtx.Snapshotter); err != nil {
|
|
| 72 |
+ return nil, errors.Wrapf(err, "failed to unpack image on snapshotter %s", pullCtx.Snapshotter) |
|
| 73 |
+ } |
|
| 74 |
+ } |
|
| 75 |
+ |
|
| 76 |
+ return i, nil |
|
| 77 |
+} |
|
| 78 |
+ |
|
| 79 |
+func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, limit int) (images.Image, error) {
|
|
| 80 |
+ store := c.ContentStore() |
|
| 81 |
+ name, desc, err := rCtx.Resolver.Resolve(ctx, ref) |
|
| 82 |
+ if err != nil {
|
|
| 83 |
+ return images.Image{}, errors.Wrapf(err, "failed to resolve reference %q", ref)
|
|
| 84 |
+ } |
|
| 85 |
+ |
|
| 86 |
+ fetcher, err := rCtx.Resolver.Fetcher(ctx, name) |
|
| 87 |
+ if err != nil {
|
|
| 88 |
+ return images.Image{}, errors.Wrapf(err, "failed to get fetcher for %q", name)
|
|
| 89 |
+ } |
|
| 90 |
+ |
|
| 91 |
+ var ( |
|
| 92 |
+ handler images.Handler |
|
| 93 |
+ |
|
| 94 |
+ isConvertible bool |
|
| 95 |
+ converterFunc func(context.Context, ocispec.Descriptor) (ocispec.Descriptor, error) |
|
| 96 |
+ limiter *semaphore.Weighted |
|
| 97 |
+ ) |
|
| 98 |
+ |
|
| 99 |
+ if desc.MediaType == images.MediaTypeDockerSchema1Manifest && rCtx.ConvertSchema1 {
|
|
| 100 |
+ schema1Converter := schema1.NewConverter(store, fetcher) |
|
| 101 |
+ |
|
| 102 |
+ handler = images.Handlers(append(rCtx.BaseHandlers, schema1Converter)...) |
|
| 103 |
+ |
|
| 104 |
+ isConvertible = true |
|
| 105 |
+ |
|
| 106 |
+ converterFunc = func(ctx context.Context, _ ocispec.Descriptor) (ocispec.Descriptor, error) {
|
|
| 107 |
+ return schema1Converter.Convert(ctx) |
|
| 108 |
+ } |
|
| 109 |
+ } else {
|
|
| 110 |
+ // Get all the children for a descriptor |
|
| 111 |
+ childrenHandler := images.ChildrenHandler(store) |
|
| 112 |
+ // Set any children labels for that content |
|
| 113 |
+ childrenHandler = images.SetChildrenLabels(store, childrenHandler) |
|
| 114 |
+ // Filter children by platforms |
|
| 115 |
+ childrenHandler = images.FilterPlatforms(childrenHandler, rCtx.PlatformMatcher) |
|
| 116 |
+ // Sort and limit manifests if a finite number is needed |
|
| 117 |
+ if limit > 0 {
|
|
| 118 |
+ childrenHandler = images.LimitManifests(childrenHandler, rCtx.PlatformMatcher, limit) |
|
| 119 |
+ } |
|
| 120 |
+ |
|
| 121 |
+ // set isConvertible to true if there is application/octet-stream media type |
|
| 122 |
+ convertibleHandler := images.HandlerFunc( |
|
| 123 |
+ func(_ context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
|
| 124 |
+ if desc.MediaType == docker.LegacyConfigMediaType {
|
|
| 125 |
+ isConvertible = true |
|
| 126 |
+ } |
|
| 127 |
+ |
|
| 128 |
+ return []ocispec.Descriptor{}, nil
|
|
| 129 |
+ }, |
|
| 130 |
+ ) |
|
| 131 |
+ |
|
| 132 |
+ handler = images.Handlers(append(rCtx.BaseHandlers, |
|
| 133 |
+ remotes.FetchHandler(store, fetcher), |
|
| 134 |
+ convertibleHandler, |
|
| 135 |
+ childrenHandler, |
|
| 136 |
+ )...) |
|
| 137 |
+ |
|
| 138 |
+ converterFunc = func(ctx context.Context, desc ocispec.Descriptor) (ocispec.Descriptor, error) {
|
|
| 139 |
+ return docker.ConvertManifest(ctx, store, desc) |
|
| 140 |
+ } |
|
| 141 |
+ } |
|
| 142 |
+ |
|
| 143 |
+ if rCtx.HandlerWrapper != nil {
|
|
| 144 |
+ handler = rCtx.HandlerWrapper(handler) |
|
| 145 |
+ } |
|
| 146 |
+ |
|
| 147 |
+ if rCtx.MaxConcurrentDownloads > 0 {
|
|
| 148 |
+ limiter = semaphore.NewWeighted(int64(rCtx.MaxConcurrentDownloads)) |
|
| 149 |
+ } |
|
| 150 |
+ if err := images.Dispatch(ctx, handler, limiter, desc); err != nil {
|
|
| 151 |
+ return images.Image{}, err
|
|
| 152 |
+ } |
|
| 153 |
+ |
|
| 154 |
+ if isConvertible {
|
|
| 155 |
+ if desc, err = converterFunc(ctx, desc); err != nil {
|
|
| 156 |
+ return images.Image{}, err
|
|
| 157 |
+ } |
|
| 158 |
+ } |
|
| 159 |
+ |
|
| 160 |
+ img := images.Image{
|
|
| 161 |
+ Name: name, |
|
| 162 |
+ Target: desc, |
|
| 163 |
+ Labels: rCtx.Labels, |
|
| 164 |
+ } |
|
| 165 |
+ |
|
| 166 |
+ is := c.ImageService() |
|
| 167 |
+ for {
|
|
| 168 |
+ if created, err := is.Create(ctx, img); err != nil {
|
|
| 169 |
+ if !errdefs.IsAlreadyExists(err) {
|
|
| 170 |
+ return images.Image{}, err
|
|
| 171 |
+ } |
|
| 172 |
+ |
|
| 173 |
+ updated, err := is.Update(ctx, img) |
|
| 174 |
+ if err != nil {
|
|
| 175 |
+ // if image was removed, try create again |
|
| 176 |
+ if errdefs.IsNotFound(err) {
|
|
| 177 |
+ continue |
|
| 178 |
+ } |
|
| 179 |
+ return images.Image{}, err
|
|
| 180 |
+ } |
|
| 181 |
+ |
|
| 182 |
+ img = updated |
|
| 183 |
+ } else {
|
|
| 184 |
+ img = created |
|
| 185 |
+ } |
|
| 186 |
+ |
|
| 187 |
+ return img, nil |
|
| 188 |
+ } |
|
| 189 |
+} |
| ... | ... |
@@ -81,7 +81,7 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R |
| 81 | 81 |
// TODO(dmcg): Store challenge, not token |
| 82 | 82 |
// Move token fetching to authorize |
| 83 | 83 |
return a.setTokenAuth(ctx, host, c.parameters) |
| 84 |
- } else if c.scheme == basicAuth {
|
|
| 84 |
+ } else if c.scheme == basicAuth && a.credentials != nil {
|
|
| 85 | 85 |
// TODO: Resolve credentials on authorize |
| 86 | 86 |
username, secret, err := a.credentials(host) |
| 87 | 87 |
if err != nil {
|
| ... | ... |
@@ -194,7 +194,11 @@ func (a *dockerAuthorizer) fetchTokenWithOAuth(ctx context.Context, to tokenOpti |
| 194 | 194 |
form.Set("password", to.secret)
|
| 195 | 195 |
} |
| 196 | 196 |
|
| 197 |
- resp, err := ctxhttp.PostForm(ctx, a.client, to.realm, form) |
|
| 197 |
+ resp, err := ctxhttp.Post( |
|
| 198 |
+ ctx, a.client, to.realm, |
|
| 199 |
+ "application/x-www-form-urlencoded; charset=utf-8", |
|
| 200 |
+ strings.NewReader(form.Encode()), |
|
| 201 |
+ ) |
|
| 198 | 202 |
if err != nil {
|
| 199 | 203 |
return "", err |
| 200 | 204 |
} |
| ... | ... |
@@ -29,6 +29,7 @@ import ( |
| 29 | 29 |
"github.com/containerd/containerd/log" |
| 30 | 30 |
"github.com/containerd/containerd/reference" |
| 31 | 31 |
"github.com/containerd/containerd/remotes" |
| 32 |
+ "github.com/containerd/containerd/version" |
|
| 32 | 33 |
digest "github.com/opencontainers/go-digest" |
| 33 | 34 |
ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
| 34 | 35 |
"github.com/pkg/errors" |
| ... | ... |
@@ -75,13 +76,16 @@ type ResolverOptions struct {
|
| 75 | 75 |
|
| 76 | 76 |
// Credentials provides username and secret given a host. |
| 77 | 77 |
// If username is empty but a secret is given, that secret |
| 78 |
- // is interpretted as a long lived token. |
|
| 78 |
+ // is interpreted as a long lived token. |
|
| 79 | 79 |
// Deprecated: use Authorizer |
| 80 | 80 |
Credentials func(string) (string, string, error) |
| 81 | 81 |
|
| 82 | 82 |
// Host provides the hostname given a namespace. |
| 83 | 83 |
Host func(string) (string, error) |
| 84 | 84 |
|
| 85 |
+ // Headers are the HTTP request header fields sent by the resolver |
|
| 86 |
+ Headers http.Header |
|
| 87 |
+ |
|
| 85 | 88 |
// PlainHTTP specifies to use plain http and not https |
| 86 | 89 |
PlainHTTP bool |
| 87 | 90 |
|
| ... | ... |
@@ -105,6 +109,7 @@ func DefaultHost(ns string) (string, error) {
|
| 105 | 105 |
type dockerResolver struct {
|
| 106 | 106 |
auth Authorizer |
| 107 | 107 |
host func(string) (string, error) |
| 108 |
+ headers http.Header |
|
| 108 | 109 |
plainHTTP bool |
| 109 | 110 |
client *http.Client |
| 110 | 111 |
tracker StatusTracker |
| ... | ... |
@@ -118,12 +123,27 @@ func NewResolver(options ResolverOptions) remotes.Resolver {
|
| 118 | 118 |
if options.Host == nil {
|
| 119 | 119 |
options.Host = DefaultHost |
| 120 | 120 |
} |
| 121 |
+ if options.Headers == nil {
|
|
| 122 |
+ options.Headers = make(http.Header) |
|
| 123 |
+ } |
|
| 124 |
+ if _, ok := options.Headers["Accept"]; !ok {
|
|
| 125 |
+ // set headers for all the types we support for resolution. |
|
| 126 |
+ options.Headers.Set("Accept", strings.Join([]string{
|
|
| 127 |
+ images.MediaTypeDockerSchema2Manifest, |
|
| 128 |
+ images.MediaTypeDockerSchema2ManifestList, |
|
| 129 |
+ ocispec.MediaTypeImageManifest, |
|
| 130 |
+ ocispec.MediaTypeImageIndex, "*"}, ", ")) |
|
| 131 |
+ } |
|
| 132 |
+ if _, ok := options.Headers["User-Agent"]; !ok {
|
|
| 133 |
+ options.Headers.Set("User-Agent", "containerd/"+version.Version)
|
|
| 134 |
+ } |
|
| 121 | 135 |
if options.Authorizer == nil {
|
| 122 | 136 |
options.Authorizer = NewAuthorizer(options.Client, options.Credentials) |
| 123 | 137 |
} |
| 124 | 138 |
return &dockerResolver{
|
| 125 | 139 |
auth: options.Authorizer, |
| 126 | 140 |
host: options.Host, |
| 141 |
+ headers: options.Headers, |
|
| 127 | 142 |
plainHTTP: options.PlainHTTP, |
| 128 | 143 |
client: options.Client, |
| 129 | 144 |
tracker: options.Tracker, |
| ... | ... |
@@ -182,12 +202,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp |
| 182 | 182 |
return "", ocispec.Descriptor{}, err
|
| 183 | 183 |
} |
| 184 | 184 |
|
| 185 |
- // set headers for all the types we support for resolution. |
|
| 186 |
- req.Header.Set("Accept", strings.Join([]string{
|
|
| 187 |
- images.MediaTypeDockerSchema2Manifest, |
|
| 188 |
- images.MediaTypeDockerSchema2ManifestList, |
|
| 189 |
- ocispec.MediaTypeImageManifest, |
|
| 190 |
- ocispec.MediaTypeImageIndex, "*"}, ", ")) |
|
| 185 |
+ req.Header = r.headers |
|
| 191 | 186 |
|
| 192 | 187 |
log.G(ctx).Debug("resolving")
|
| 193 | 188 |
resp, err := fetcher.doRequestWithRetries(ctx, req, nil) |
| ... | ... |
@@ -156,7 +156,7 @@ func push(ctx context.Context, provider content.Provider, pusher Pusher, desc oc |
| 156 | 156 |
// |
| 157 | 157 |
// Base handlers can be provided which will be called before any push specific |
| 158 | 158 |
// handlers. |
| 159 |
-func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, provider content.Provider, platform platforms.MatchComparer, baseHandlers ...images.Handler) error {
|
|
| 159 |
+func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, provider content.Provider, platform platforms.MatchComparer, wrapper func(h images.Handler) images.Handler) error {
|
|
| 160 | 160 |
var m sync.Mutex |
| 161 | 161 |
manifestStack := []ocispec.Descriptor{}
|
| 162 | 162 |
|
| ... | ... |
@@ -175,13 +175,16 @@ func PushContent(ctx context.Context, pusher Pusher, desc ocispec.Descriptor, pr |
| 175 | 175 |
|
| 176 | 176 |
pushHandler := PushHandler(pusher, provider) |
| 177 | 177 |
|
| 178 |
- handlers := append(baseHandlers, |
|
| 178 |
+ var handler images.Handler = images.Handlers( |
|
| 179 | 179 |
images.FilterPlatforms(images.ChildrenHandler(provider), platform), |
| 180 | 180 |
filterHandler, |
| 181 | 181 |
pushHandler, |
| 182 | 182 |
) |
| 183 |
+ if wrapper != nil {
|
|
| 184 |
+ handler = wrapper(handler) |
|
| 185 |
+ } |
|
| 183 | 186 |
|
| 184 |
- if err := images.Dispatch(ctx, images.Handlers(handlers...), desc); err != nil {
|
|
| 187 |
+ if err := images.Dispatch(ctx, handler, nil, desc); err != nil {
|
|
| 185 | 188 |
return err |
| 186 | 189 |
} |
| 187 | 190 |
|
| ... | ... |
@@ -60,6 +60,8 @@ type CreateOptions struct {
|
| 60 | 60 |
ShimCgroup string `protobuf:"bytes,9,opt,name=shim_cgroup,json=shimCgroup,proto3" json:"shim_cgroup,omitempty"` |
| 61 | 61 |
IoUid uint32 `protobuf:"varint,10,opt,name=io_uid,json=ioUid,proto3" json:"io_uid,omitempty"` |
| 62 | 62 |
IoGid uint32 `protobuf:"varint,11,opt,name=io_gid,json=ioGid,proto3" json:"io_gid,omitempty"` |
| 63 |
+ CriuWorkPath string `protobuf:"bytes,12,opt,name=criu_work_path,json=criuWorkPath,proto3" json:"criu_work_path,omitempty"` |
|
| 64 |
+ CriuImagePath string `protobuf:"bytes,13,opt,name=criu_image_path,json=criuImagePath,proto3" json:"criu_image_path,omitempty"` |
|
| 63 | 65 |
} |
| 64 | 66 |
|
| 65 | 67 |
func (m *CreateOptions) Reset() { *m = CreateOptions{} }
|
| ... | ... |
@@ -74,6 +76,8 @@ type CheckpointOptions struct {
|
| 74 | 74 |
FileLocks bool `protobuf:"varint,5,opt,name=file_locks,json=fileLocks,proto3" json:"file_locks,omitempty"` |
| 75 | 75 |
EmptyNamespaces []string `protobuf:"bytes,6,rep,name=empty_namespaces,json=emptyNamespaces" json:"empty_namespaces,omitempty"` |
| 76 | 76 |
CgroupsMode string `protobuf:"bytes,7,opt,name=cgroups_mode,json=cgroupsMode,proto3" json:"cgroups_mode,omitempty"` |
| 77 |
+ WorkPath string `protobuf:"bytes,8,opt,name=work_path,json=workPath,proto3" json:"work_path,omitempty"` |
|
| 78 |
+ ImagePath string `protobuf:"bytes,9,opt,name=image_path,json=imagePath,proto3" json:"image_path,omitempty"` |
|
| 77 | 79 |
} |
| 78 | 80 |
|
| 79 | 81 |
func (m *CheckpointOptions) Reset() { *m = CheckpointOptions{} }
|
| ... | ... |
@@ -252,6 +256,18 @@ func (m *CreateOptions) MarshalTo(dAtA []byte) (int, error) {
|
| 252 | 252 |
i++ |
| 253 | 253 |
i = encodeVarintRunc(dAtA, i, uint64(m.IoGid)) |
| 254 | 254 |
} |
| 255 |
+ if len(m.CriuWorkPath) > 0 {
|
|
| 256 |
+ dAtA[i] = 0x62 |
|
| 257 |
+ i++ |
|
| 258 |
+ i = encodeVarintRunc(dAtA, i, uint64(len(m.CriuWorkPath))) |
|
| 259 |
+ i += copy(dAtA[i:], m.CriuWorkPath) |
|
| 260 |
+ } |
|
| 261 |
+ if len(m.CriuImagePath) > 0 {
|
|
| 262 |
+ dAtA[i] = 0x6a |
|
| 263 |
+ i++ |
|
| 264 |
+ i = encodeVarintRunc(dAtA, i, uint64(len(m.CriuImagePath))) |
|
| 265 |
+ i += copy(dAtA[i:], m.CriuImagePath) |
|
| 266 |
+ } |
|
| 255 | 267 |
return i, nil |
| 256 | 268 |
} |
| 257 | 269 |
|
| ... | ... |
@@ -341,6 +357,18 @@ func (m *CheckpointOptions) MarshalTo(dAtA []byte) (int, error) {
|
| 341 | 341 |
i = encodeVarintRunc(dAtA, i, uint64(len(m.CgroupsMode))) |
| 342 | 342 |
i += copy(dAtA[i:], m.CgroupsMode) |
| 343 | 343 |
} |
| 344 |
+ if len(m.WorkPath) > 0 {
|
|
| 345 |
+ dAtA[i] = 0x42 |
|
| 346 |
+ i++ |
|
| 347 |
+ i = encodeVarintRunc(dAtA, i, uint64(len(m.WorkPath))) |
|
| 348 |
+ i += copy(dAtA[i:], m.WorkPath) |
|
| 349 |
+ } |
|
| 350 |
+ if len(m.ImagePath) > 0 {
|
|
| 351 |
+ dAtA[i] = 0x4a |
|
| 352 |
+ i++ |
|
| 353 |
+ i = encodeVarintRunc(dAtA, i, uint64(len(m.ImagePath))) |
|
| 354 |
+ i += copy(dAtA[i:], m.ImagePath) |
|
| 355 |
+ } |
|
| 344 | 356 |
return i, nil |
| 345 | 357 |
} |
| 346 | 358 |
|
| ... | ... |
@@ -439,6 +467,14 @@ func (m *CreateOptions) Size() (n int) {
|
| 439 | 439 |
if m.IoGid != 0 {
|
| 440 | 440 |
n += 1 + sovRunc(uint64(m.IoGid)) |
| 441 | 441 |
} |
| 442 |
+ l = len(m.CriuWorkPath) |
|
| 443 |
+ if l > 0 {
|
|
| 444 |
+ n += 1 + l + sovRunc(uint64(l)) |
|
| 445 |
+ } |
|
| 446 |
+ l = len(m.CriuImagePath) |
|
| 447 |
+ if l > 0 {
|
|
| 448 |
+ n += 1 + l + sovRunc(uint64(l)) |
|
| 449 |
+ } |
|
| 442 | 450 |
return n |
| 443 | 451 |
} |
| 444 | 452 |
|
| ... | ... |
@@ -470,6 +506,14 @@ func (m *CheckpointOptions) Size() (n int) {
|
| 470 | 470 |
if l > 0 {
|
| 471 | 471 |
n += 1 + l + sovRunc(uint64(l)) |
| 472 | 472 |
} |
| 473 |
+ l = len(m.WorkPath) |
|
| 474 |
+ if l > 0 {
|
|
| 475 |
+ n += 1 + l + sovRunc(uint64(l)) |
|
| 476 |
+ } |
|
| 477 |
+ l = len(m.ImagePath) |
|
| 478 |
+ if l > 0 {
|
|
| 479 |
+ n += 1 + l + sovRunc(uint64(l)) |
|
| 480 |
+ } |
|
| 473 | 481 |
return n |
| 474 | 482 |
} |
| 475 | 483 |
|
| ... | ... |
@@ -525,6 +569,8 @@ func (this *CreateOptions) String() string {
|
| 525 | 525 |
`ShimCgroup:` + fmt.Sprintf("%v", this.ShimCgroup) + `,`,
|
| 526 | 526 |
`IoUid:` + fmt.Sprintf("%v", this.IoUid) + `,`,
|
| 527 | 527 |
`IoGid:` + fmt.Sprintf("%v", this.IoGid) + `,`,
|
| 528 |
+ `CriuWorkPath:` + fmt.Sprintf("%v", this.CriuWorkPath) + `,`,
|
|
| 529 |
+ `CriuImagePath:` + fmt.Sprintf("%v", this.CriuImagePath) + `,`,
|
|
| 528 | 530 |
`}`, |
| 529 | 531 |
}, "") |
| 530 | 532 |
return s |
| ... | ... |
@@ -541,6 +587,8 @@ func (this *CheckpointOptions) String() string {
|
| 541 | 541 |
`FileLocks:` + fmt.Sprintf("%v", this.FileLocks) + `,`,
|
| 542 | 542 |
`EmptyNamespaces:` + fmt.Sprintf("%v", this.EmptyNamespaces) + `,`,
|
| 543 | 543 |
`CgroupsMode:` + fmt.Sprintf("%v", this.CgroupsMode) + `,`,
|
| 544 |
+ `WorkPath:` + fmt.Sprintf("%v", this.WorkPath) + `,`,
|
|
| 545 |
+ `ImagePath:` + fmt.Sprintf("%v", this.ImagePath) + `,`,
|
|
| 544 | 546 |
`}`, |
| 545 | 547 |
}, "") |
| 546 | 548 |
return s |
| ... | ... |
@@ -994,6 +1042,64 @@ func (m *CreateOptions) Unmarshal(dAtA []byte) error {
|
| 994 | 994 |
break |
| 995 | 995 |
} |
| 996 | 996 |
} |
| 997 |
+ case 12: |
|
| 998 |
+ if wireType != 2 {
|
|
| 999 |
+ return fmt.Errorf("proto: wrong wireType = %d for field CriuWorkPath", wireType)
|
|
| 1000 |
+ } |
|
| 1001 |
+ var stringLen uint64 |
|
| 1002 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1003 |
+ if shift >= 64 {
|
|
| 1004 |
+ return ErrIntOverflowRunc |
|
| 1005 |
+ } |
|
| 1006 |
+ if iNdEx >= l {
|
|
| 1007 |
+ return io.ErrUnexpectedEOF |
|
| 1008 |
+ } |
|
| 1009 |
+ b := dAtA[iNdEx] |
|
| 1010 |
+ iNdEx++ |
|
| 1011 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 1012 |
+ if b < 0x80 {
|
|
| 1013 |
+ break |
|
| 1014 |
+ } |
|
| 1015 |
+ } |
|
| 1016 |
+ intStringLen := int(stringLen) |
|
| 1017 |
+ if intStringLen < 0 {
|
|
| 1018 |
+ return ErrInvalidLengthRunc |
|
| 1019 |
+ } |
|
| 1020 |
+ postIndex := iNdEx + intStringLen |
|
| 1021 |
+ if postIndex > l {
|
|
| 1022 |
+ return io.ErrUnexpectedEOF |
|
| 1023 |
+ } |
|
| 1024 |
+ m.CriuWorkPath = string(dAtA[iNdEx:postIndex]) |
|
| 1025 |
+ iNdEx = postIndex |
|
| 1026 |
+ case 13: |
|
| 1027 |
+ if wireType != 2 {
|
|
| 1028 |
+ return fmt.Errorf("proto: wrong wireType = %d for field CriuImagePath", wireType)
|
|
| 1029 |
+ } |
|
| 1030 |
+ var stringLen uint64 |
|
| 1031 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1032 |
+ if shift >= 64 {
|
|
| 1033 |
+ return ErrIntOverflowRunc |
|
| 1034 |
+ } |
|
| 1035 |
+ if iNdEx >= l {
|
|
| 1036 |
+ return io.ErrUnexpectedEOF |
|
| 1037 |
+ } |
|
| 1038 |
+ b := dAtA[iNdEx] |
|
| 1039 |
+ iNdEx++ |
|
| 1040 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 1041 |
+ if b < 0x80 {
|
|
| 1042 |
+ break |
|
| 1043 |
+ } |
|
| 1044 |
+ } |
|
| 1045 |
+ intStringLen := int(stringLen) |
|
| 1046 |
+ if intStringLen < 0 {
|
|
| 1047 |
+ return ErrInvalidLengthRunc |
|
| 1048 |
+ } |
|
| 1049 |
+ postIndex := iNdEx + intStringLen |
|
| 1050 |
+ if postIndex > l {
|
|
| 1051 |
+ return io.ErrUnexpectedEOF |
|
| 1052 |
+ } |
|
| 1053 |
+ m.CriuImagePath = string(dAtA[iNdEx:postIndex]) |
|
| 1054 |
+ iNdEx = postIndex |
|
| 997 | 1055 |
default: |
| 998 | 1056 |
iNdEx = preIndex |
| 999 | 1057 |
skippy, err := skipRunc(dAtA[iNdEx:]) |
| ... | ... |
@@ -1202,6 +1308,64 @@ func (m *CheckpointOptions) Unmarshal(dAtA []byte) error {
|
| 1202 | 1202 |
} |
| 1203 | 1203 |
m.CgroupsMode = string(dAtA[iNdEx:postIndex]) |
| 1204 | 1204 |
iNdEx = postIndex |
| 1205 |
+ case 8: |
|
| 1206 |
+ if wireType != 2 {
|
|
| 1207 |
+ return fmt.Errorf("proto: wrong wireType = %d for field WorkPath", wireType)
|
|
| 1208 |
+ } |
|
| 1209 |
+ var stringLen uint64 |
|
| 1210 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1211 |
+ if shift >= 64 {
|
|
| 1212 |
+ return ErrIntOverflowRunc |
|
| 1213 |
+ } |
|
| 1214 |
+ if iNdEx >= l {
|
|
| 1215 |
+ return io.ErrUnexpectedEOF |
|
| 1216 |
+ } |
|
| 1217 |
+ b := dAtA[iNdEx] |
|
| 1218 |
+ iNdEx++ |
|
| 1219 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 1220 |
+ if b < 0x80 {
|
|
| 1221 |
+ break |
|
| 1222 |
+ } |
|
| 1223 |
+ } |
|
| 1224 |
+ intStringLen := int(stringLen) |
|
| 1225 |
+ if intStringLen < 0 {
|
|
| 1226 |
+ return ErrInvalidLengthRunc |
|
| 1227 |
+ } |
|
| 1228 |
+ postIndex := iNdEx + intStringLen |
|
| 1229 |
+ if postIndex > l {
|
|
| 1230 |
+ return io.ErrUnexpectedEOF |
|
| 1231 |
+ } |
|
| 1232 |
+ m.WorkPath = string(dAtA[iNdEx:postIndex]) |
|
| 1233 |
+ iNdEx = postIndex |
|
| 1234 |
+ case 9: |
|
| 1235 |
+ if wireType != 2 {
|
|
| 1236 |
+ return fmt.Errorf("proto: wrong wireType = %d for field ImagePath", wireType)
|
|
| 1237 |
+ } |
|
| 1238 |
+ var stringLen uint64 |
|
| 1239 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1240 |
+ if shift >= 64 {
|
|
| 1241 |
+ return ErrIntOverflowRunc |
|
| 1242 |
+ } |
|
| 1243 |
+ if iNdEx >= l {
|
|
| 1244 |
+ return io.ErrUnexpectedEOF |
|
| 1245 |
+ } |
|
| 1246 |
+ b := dAtA[iNdEx] |
|
| 1247 |
+ iNdEx++ |
|
| 1248 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 1249 |
+ if b < 0x80 {
|
|
| 1250 |
+ break |
|
| 1251 |
+ } |
|
| 1252 |
+ } |
|
| 1253 |
+ intStringLen := int(stringLen) |
|
| 1254 |
+ if intStringLen < 0 {
|
|
| 1255 |
+ return ErrInvalidLengthRunc |
|
| 1256 |
+ } |
|
| 1257 |
+ postIndex := iNdEx + intStringLen |
|
| 1258 |
+ if postIndex > l {
|
|
| 1259 |
+ return io.ErrUnexpectedEOF |
|
| 1260 |
+ } |
|
| 1261 |
+ m.ImagePath = string(dAtA[iNdEx:postIndex]) |
|
| 1262 |
+ iNdEx = postIndex |
|
| 1205 | 1263 |
default: |
| 1206 | 1264 |
iNdEx = preIndex |
| 1207 | 1265 |
skippy, err := skipRunc(dAtA[iNdEx:]) |
| ... | ... |
@@ -1412,39 +1576,43 @@ func init() {
|
| 1412 | 1412 |
} |
| 1413 | 1413 |
|
| 1414 | 1414 |
var fileDescriptorRunc = []byte{
|
| 1415 |
- // 541 bytes of a gzipped FileDescriptorProto |
|
| 1416 |
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x93, 0xc1, 0x6e, 0xd3, 0x40, |
|
| 1417 |
- 0x10, 0x86, 0x6b, 0xda, 0x26, 0xce, 0xa4, 0x29, 0xb0, 0x50, 0xc9, 0x14, 0x91, 0x86, 0x00, 0x52, |
|
| 1418 |
- 0xb8, 0xa4, 0x12, 0x88, 0x13, 0xb7, 0xa6, 0x08, 0x55, 0x40, 0xa9, 0x0c, 0x95, 0x10, 0x42, 0x5a, |
|
| 1419 |
- 0xb9, 0xeb, 0x21, 0x59, 0xc5, 0xde, 0x59, 0x79, 0xd7, 0xd4, 0xb9, 0xf5, 0x09, 0x78, 0xae, 0x1e, |
|
| 1420 |
- 0x39, 0x72, 0x42, 0x34, 0x2f, 0x02, 0xf2, 0xda, 0x0e, 0x9c, 0x39, 0x72, 0xfb, 0xe7, 0xfb, 0xc7, |
|
| 1421 |
- 0x9e, 0xd1, 0xbf, 0x1a, 0x98, 0x4c, 0xa5, 0x9d, 0xe5, 0x67, 0x63, 0x41, 0xe9, 0xbe, 0x20, 0x65, |
|
| 1422 |
- 0x23, 0xa9, 0x30, 0x8b, 0xff, 0x96, 0x59, 0xae, 0xac, 0x4c, 0x71, 0x3f, 0x91, 0x2a, 0x2f, 0xca, |
|
| 1423 |
- 0x4a, 0xd8, 0x85, 0x46, 0xe3, 0xd4, 0x58, 0x67, 0x64, 0x89, 0xed, 0xfc, 0x69, 0x1f, 0xbb, 0xb6, |
|
| 1424 |
- 0x71, 0x69, 0xee, 0xde, 0x9e, 0xd2, 0x94, 0x5c, 0xc7, 0x7e, 0xa9, 0xaa, 0xe6, 0xe1, 0x57, 0x0f, |
|
| 1425 |
- 0xba, 0x61, 0xae, 0xc4, 0x5b, 0x6d, 0x25, 0x29, 0xc3, 0x02, 0x68, 0xd7, 0x23, 0x02, 0x6f, 0xe0, |
|
| 1426 |
- 0x8d, 0x3a, 0x61, 0x53, 0xb2, 0xfb, 0xb0, 0x55, 0x4b, 0x9e, 0x11, 0xd9, 0xe0, 0x9a, 0xb3, 0xbb, |
|
| 1427 |
- 0x35, 0x0b, 0x89, 0x2c, 0xbb, 0x0b, 0x1d, 0x91, 0xc9, 0x9c, 0xeb, 0xc8, 0xce, 0x82, 0x75, 0xe7, |
|
| 1428 |
- 0xfb, 0x25, 0x38, 0x89, 0xec, 0x8c, 0x3d, 0x82, 0x6d, 0xb3, 0x30, 0x16, 0xd3, 0x98, 0x8b, 0x69, |
|
| 1429 |
- 0x46, 0xb9, 0x0e, 0x36, 0x06, 0xde, 0xc8, 0x0f, 0x7b, 0x35, 0x9d, 0x38, 0x38, 0xbc, 0x58, 0x87, |
|
| 1430 |
- 0xde, 0x24, 0xc3, 0xc8, 0x62, 0xb3, 0xd2, 0x10, 0x7a, 0x8a, 0xb8, 0x96, 0x5f, 0xc8, 0x56, 0x93, |
|
| 1431 |
- 0x3d, 0xf7, 0x5d, 0x57, 0xd1, 0x49, 0xc9, 0xdc, 0xe4, 0x3b, 0xe0, 0x93, 0x46, 0xc5, 0xad, 0xd0, |
|
| 1432 |
- 0x6e, 0x31, 0x3f, 0x6c, 0x97, 0xf5, 0x7b, 0xa1, 0xd9, 0x13, 0xd8, 0xc1, 0xc2, 0x62, 0xa6, 0xa2, |
|
| 1433 |
- 0x84, 0xe7, 0x4a, 0x16, 0xdc, 0x90, 0x98, 0xa3, 0x35, 0x6e, 0x41, 0x3f, 0xbc, 0xd5, 0x98, 0xa7, |
|
| 1434 |
- 0x4a, 0x16, 0xef, 0x2a, 0x8b, 0xed, 0x82, 0x6f, 0x31, 0x4b, 0xa5, 0x8a, 0x92, 0x7a, 0xcb, 0x55, |
|
| 1435 |
- 0xcd, 0xee, 0x01, 0x7c, 0x96, 0x09, 0xf2, 0x84, 0xc4, 0xdc, 0x04, 0x9b, 0xce, 0xed, 0x94, 0xe4, |
|
| 1436 |
- 0x75, 0x09, 0xd8, 0x63, 0xb8, 0x81, 0xa9, 0xb6, 0x0b, 0xae, 0xa2, 0x14, 0x8d, 0x8e, 0x04, 0x9a, |
|
| 1437 |
- 0xa0, 0x35, 0x58, 0x1f, 0x75, 0xc2, 0xeb, 0x8e, 0x1f, 0xaf, 0x70, 0x99, 0x68, 0x95, 0x84, 0xe1, |
|
| 1438 |
- 0x29, 0xc5, 0x18, 0xb4, 0xab, 0x44, 0x6b, 0xf6, 0x86, 0x62, 0x64, 0x0f, 0x61, 0x5b, 0x11, 0x57, |
|
| 1439 |
- 0x78, 0xce, 0xe7, 0xb8, 0xc8, 0xa4, 0x9a, 0x06, 0xbe, 0x1b, 0xb8, 0xa5, 0xe8, 0x18, 0xcf, 0x5f, |
|
| 1440 |
- 0x55, 0x8c, 0xed, 0x41, 0xd7, 0xcc, 0x64, 0xda, 0xe4, 0xda, 0x71, 0xff, 0x81, 0x12, 0x55, 0xa1, |
|
| 1441 |
- 0xb2, 0x1d, 0x68, 0x49, 0xe2, 0xb9, 0x8c, 0x03, 0x18, 0x78, 0xa3, 0x5e, 0xb8, 0x29, 0xe9, 0x54, |
|
| 1442 |
- 0xc6, 0x35, 0x9e, 0xca, 0x38, 0xe8, 0x36, 0xf8, 0xa5, 0x8c, 0x87, 0xbf, 0x3c, 0xb8, 0x39, 0x99, |
|
| 1443 |
- 0xa1, 0x98, 0x6b, 0x92, 0xca, 0x36, 0xcf, 0xc0, 0x60, 0x03, 0x0b, 0xd9, 0xa4, 0xef, 0xf4, 0xff, |
|
| 1444 |
- 0x1a, 0xfb, 0xf0, 0x19, 0x6c, 0x9f, 0x64, 0x24, 0xd0, 0x98, 0x43, 0xb4, 0x91, 0x4c, 0x0c, 0x7b, |
|
| 1445 |
- 0x00, 0x6d, 0x2c, 0x50, 0x70, 0x19, 0x57, 0x77, 0x71, 0x00, 0xcb, 0x1f, 0x7b, 0xad, 0x17, 0x05, |
|
| 1446 |
- 0x8a, 0xa3, 0xc3, 0xb0, 0x55, 0x5a, 0x47, 0xf1, 0xc1, 0xa7, 0xcb, 0xab, 0xfe, 0xda, 0xf7, 0xab, |
|
| 1447 |
- 0xfe, 0xda, 0xc5, 0xb2, 0xef, 0x5d, 0x2e, 0xfb, 0xde, 0xb7, 0x65, 0xdf, 0xfb, 0xb9, 0xec, 0x7b, |
|
| 1448 |
- 0x1f, 0x0f, 0xfe, 0xf5, 0xb0, 0x9f, 0xaf, 0xd4, 0x87, 0xb5, 0xb3, 0x96, 0xbb, 0xd9, 0xa7, 0xbf, |
|
| 1449 |
- 0x03, 0x00, 0x00, 0xff, 0xff, 0x18, 0xa1, 0x4b, 0x5b, 0x27, 0x04, 0x00, 0x00, |
|
| 1415 |
+ // 604 bytes of a gzipped FileDescriptorProto |
|
| 1416 |
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x94, 0xcf, 0x6e, 0xd3, 0x40, |
|
| 1417 |
+ 0x10, 0xc6, 0xeb, 0xfe, 0x49, 0x9c, 0x49, 0xd2, 0xc2, 0x42, 0x25, 0xd3, 0xaa, 0x69, 0x08, 0x7f, |
|
| 1418 |
+ 0x14, 0x2e, 0xa9, 0x04, 0xe2, 0xc4, 0xad, 0x29, 0x42, 0x15, 0x50, 0x2a, 0x43, 0x05, 0x42, 0x48, |
|
| 1419 |
+ 0x2b, 0x77, 0x3d, 0x24, 0xab, 0xc4, 0x3b, 0x96, 0x77, 0x4d, 0x92, 0x1b, 0x4f, 0xc0, 0x0b, 0xf1, |
|
| 1420 |
+ 0x02, 0x3d, 0x21, 0x8e, 0x9c, 0x10, 0xcd, 0x93, 0xa0, 0x5d, 0xc7, 0x69, 0xcf, 0x1c, 0xb9, 0xcd, |
|
| 1421 |
+ 0xfc, 0xe6, 0xb3, 0x67, 0xf4, 0x7d, 0xb2, 0xa1, 0x3f, 0x90, 0x66, 0x98, 0x9f, 0xf7, 0x04, 0x25, |
|
| 1422 |
+ 0x07, 0x82, 0x94, 0x89, 0xa4, 0xc2, 0x2c, 0xbe, 0x5e, 0x66, 0xb9, 0x32, 0x32, 0xc1, 0x83, 0xb1, |
|
| 1423 |
+ 0x54, 0xf9, 0xd4, 0x76, 0xc2, 0xcc, 0x52, 0xd4, 0xae, 0xea, 0xa5, 0x19, 0x19, 0x62, 0xdb, 0x57, |
|
| 1424 |
+ 0xf2, 0x9e, 0x93, 0xf5, 0xec, 0x70, 0xe7, 0xf6, 0x80, 0x06, 0xe4, 0x14, 0x07, 0xb6, 0x2a, 0xc4, |
|
| 1425 |
+ 0x9d, 0x6f, 0x1e, 0xd4, 0xc3, 0x5c, 0x89, 0x37, 0xa9, 0x91, 0xa4, 0x34, 0x0b, 0xa0, 0xba, 0x58, |
|
| 1426 |
+ 0x11, 0x78, 0x6d, 0xaf, 0x5b, 0x0b, 0xcb, 0x96, 0xdd, 0x85, 0xc6, 0xa2, 0xe4, 0x19, 0x91, 0x09, |
|
| 1427 |
+ 0x56, 0xdd, 0xb8, 0xbe, 0x60, 0x21, 0x91, 0x61, 0xbb, 0x50, 0x13, 0x99, 0xcc, 0x79, 0x1a, 0x99, |
|
| 1428 |
+ 0x61, 0xb0, 0xe6, 0xe6, 0xbe, 0x05, 0xa7, 0x91, 0x19, 0xb2, 0x07, 0xb0, 0xa9, 0x67, 0xda, 0x60, |
|
| 1429 |
+ 0x12, 0x73, 0x31, 0xc8, 0x28, 0x4f, 0x83, 0xf5, 0xb6, 0xd7, 0xf5, 0xc3, 0xe6, 0x82, 0xf6, 0x1d, |
|
| 1430 |
+ 0xec, 0xfc, 0x58, 0x83, 0x66, 0x3f, 0xc3, 0xc8, 0x60, 0x79, 0x52, 0x07, 0x9a, 0x8a, 0x78, 0x2a, |
|
| 1431 |
+ 0xbf, 0x90, 0x29, 0x36, 0x7b, 0xee, 0xb9, 0xba, 0xa2, 0x53, 0xcb, 0xdc, 0xe6, 0x3b, 0xe0, 0x53, |
|
| 1432 |
+ 0x8a, 0x8a, 0x1b, 0x91, 0xba, 0xc3, 0xfc, 0xb0, 0x6a, 0xfb, 0x77, 0x22, 0x65, 0x8f, 0x61, 0x1b, |
|
| 1433 |
+ 0xa7, 0x06, 0x33, 0x15, 0x8d, 0x79, 0xae, 0xe4, 0x94, 0x6b, 0x12, 0x23, 0x34, 0xda, 0x1d, 0xe8, |
|
| 1434 |
+ 0x87, 0xb7, 0xca, 0xe1, 0x99, 0x92, 0xd3, 0xb7, 0xc5, 0x88, 0xed, 0x80, 0x6f, 0x30, 0x4b, 0xa4, |
|
| 1435 |
+ 0x8a, 0xc6, 0x8b, 0x2b, 0x97, 0x3d, 0xdb, 0x03, 0xf8, 0x2c, 0xc7, 0xc8, 0xc7, 0x24, 0x46, 0x3a, |
|
| 1436 |
+ 0xd8, 0x70, 0xd3, 0x9a, 0x25, 0xaf, 0x2c, 0x60, 0x8f, 0xe0, 0x06, 0x26, 0xa9, 0x99, 0x71, 0x15, |
|
| 1437 |
+ 0x25, 0xa8, 0xd3, 0x48, 0xa0, 0x0e, 0x2a, 0xed, 0xb5, 0x6e, 0x2d, 0xdc, 0x72, 0xfc, 0x64, 0x89, |
|
| 1438 |
+ 0xad, 0xa3, 0x85, 0x13, 0x9a, 0x27, 0x14, 0x63, 0x50, 0x2d, 0x1c, 0x5d, 0xb0, 0xd7, 0x14, 0x23, |
|
| 1439 |
+ 0xbb, 0x0f, 0x9b, 0x8a, 0xb8, 0xc2, 0x09, 0x1f, 0xe1, 0x2c, 0x93, 0x6a, 0x10, 0xf8, 0x6e, 0x61, |
|
| 1440 |
+ 0x43, 0xd1, 0x09, 0x4e, 0x5e, 0x16, 0x8c, 0xed, 0x43, 0x5d, 0x0f, 0x65, 0x52, 0xfa, 0x5a, 0x73, |
|
| 1441 |
+ 0xef, 0x01, 0x8b, 0x0a, 0x53, 0xd9, 0x36, 0x54, 0x24, 0xf1, 0x5c, 0xc6, 0x01, 0xb4, 0xbd, 0x6e, |
|
| 1442 |
+ 0x33, 0xdc, 0x90, 0x74, 0x26, 0xe3, 0x05, 0x1e, 0xc8, 0x38, 0xa8, 0x97, 0xf8, 0x85, 0x8c, 0xed, |
|
| 1443 |
+ 0x52, 0x17, 0xe3, 0x84, 0xb2, 0x51, 0x91, 0x65, 0xc3, 0xbd, 0xb1, 0x61, 0xe9, 0x7b, 0xca, 0x46, |
|
| 1444 |
+ 0x2e, 0xcf, 0x87, 0xb0, 0xe5, 0x54, 0x32, 0x89, 0x06, 0x58, 0xc8, 0x9a, 0x4e, 0xd6, 0xb4, 0xf8, |
|
| 1445 |
+ 0xd8, 0x52, 0xab, 0xeb, 0x7c, 0x5f, 0x85, 0x9b, 0xfd, 0x21, 0x8a, 0x51, 0x4a, 0x52, 0x99, 0x32, |
|
| 1446 |
+ 0x54, 0x06, 0xeb, 0x38, 0x95, 0x65, 0x96, 0xae, 0xfe, 0x6f, 0x43, 0xdc, 0x85, 0xda, 0x95, 0x95, |
|
| 1447 |
+ 0x7e, 0xf1, 0x59, 0x4c, 0x4a, 0x1b, 0xf7, 0x00, 0xae, 0x39, 0x58, 0x44, 0x57, 0x93, 0x4b, 0xf7, |
|
| 1448 |
+ 0x9e, 0xc2, 0xe6, 0x69, 0x46, 0x02, 0xb5, 0x3e, 0x42, 0x13, 0xc9, 0xb1, 0x66, 0xf7, 0xa0, 0x8a, |
|
| 1449 |
+ 0x53, 0x14, 0x5c, 0xc6, 0xc5, 0x17, 0x7a, 0x08, 0xf3, 0xdf, 0xfb, 0x95, 0xe7, 0x53, 0x14, 0xc7, |
|
| 1450 |
+ 0x47, 0x61, 0xc5, 0x8e, 0x8e, 0xe3, 0xc3, 0x4f, 0x17, 0x97, 0xad, 0x95, 0x5f, 0x97, 0xad, 0x95, |
|
| 1451 |
+ 0xaf, 0xf3, 0x96, 0x77, 0x31, 0x6f, 0x79, 0x3f, 0xe7, 0x2d, 0xef, 0xcf, 0xbc, 0xe5, 0x7d, 0x3c, |
|
| 1452 |
+ 0xfc, 0xd7, 0x5f, 0xcc, 0xb3, 0x65, 0xf5, 0x61, 0xe5, 0xbc, 0xe2, 0xfe, 0x1e, 0x4f, 0xfe, 0x06, |
|
| 1453 |
+ 0x00, 0x00, 0xff, 0xff, 0x7f, 0x24, 0x6f, 0x2e, 0xb1, 0x04, 0x00, 0x00, |
|
| 1450 | 1454 |
} |
| ... | ... |
@@ -25,6 +25,8 @@ message CreateOptions {
|
| 25 | 25 |
string shim_cgroup = 9; |
| 26 | 26 |
uint32 io_uid = 10; |
| 27 | 27 |
uint32 io_gid = 11; |
| 28 |
+ string criu_work_path = 12; |
|
| 29 |
+ string criu_image_path = 13; |
|
| 28 | 30 |
} |
| 29 | 31 |
|
| 30 | 32 |
message CheckpointOptions {
|
| ... | ... |
@@ -35,6 +37,8 @@ message CheckpointOptions {
|
| 35 | 35 |
bool file_locks = 5; |
| 36 | 36 |
repeated string empty_namespaces = 6; |
| 37 | 37 |
string cgroups_mode = 7; |
| 38 |
+ string work_path = 8; |
|
| 39 |
+ string image_path = 9; |
|
| 38 | 40 |
} |
| 39 | 41 |
|
| 40 | 42 |
message ProcessDetails {
|
| ... | ... |
@@ -20,6 +20,7 @@ package linux |
| 20 | 20 |
|
| 21 | 21 |
import ( |
| 22 | 22 |
"context" |
| 23 |
+ "fmt" |
|
| 23 | 24 |
"io/ioutil" |
| 24 | 25 |
"os" |
| 25 | 26 |
"path/filepath" |
| ... | ... |
@@ -114,12 +115,12 @@ func (b *bundle) NewShimClient(ctx context.Context, namespace string, getClientO |
| 114 | 114 |
|
| 115 | 115 |
// Delete deletes the bundle from disk |
| 116 | 116 |
func (b *bundle) Delete() error {
|
| 117 |
- err := os.RemoveAll(b.path) |
|
| 117 |
+ err := atomicDelete(b.path) |
|
| 118 | 118 |
if err == nil {
|
| 119 |
- return os.RemoveAll(b.workDir) |
|
| 119 |
+ return atomicDelete(b.workDir) |
|
| 120 | 120 |
} |
| 121 | 121 |
// error removing the bundle path; still attempt removing work dir |
| 122 |
- err2 := os.RemoveAll(b.workDir) |
|
| 122 |
+ err2 := atomicDelete(b.workDir) |
|
| 123 | 123 |
if err2 == nil {
|
| 124 | 124 |
return err |
| 125 | 125 |
} |
| ... | ... |
@@ -152,3 +153,13 @@ func (b *bundle) shimConfig(namespace string, c *Config, runcOptions *runctypes. |
| 152 | 152 |
SystemdCgroup: systemdCgroup, |
| 153 | 153 |
} |
| 154 | 154 |
} |
| 155 |
+ |
|
| 156 |
+// atomicDelete renames the path to a hidden file before removal |
|
| 157 |
+func atomicDelete(path string) error {
|
|
| 158 |
+ // create a hidden dir for an atomic removal |
|
| 159 |
+ atomicPath := filepath.Join(filepath.Dir(path), fmt.Sprintf(".%s", filepath.Base(path)))
|
|
| 160 |
+ if err := os.Rename(path, atomicPath); err != nil {
|
|
| 161 |
+ return err |
|
| 162 |
+ } |
|
| 163 |
+ return os.RemoveAll(atomicPath) |
|
| 164 |
+} |
| ... | ... |
@@ -76,6 +76,7 @@ type Init struct {
|
| 76 | 76 |
IoGID int |
| 77 | 77 |
NoPivotRoot bool |
| 78 | 78 |
NoNewKeyring bool |
| 79 |
+ CriuWorkPath string |
|
| 79 | 80 |
} |
| 80 | 81 |
|
| 81 | 82 |
// NewRunc returns a new runc instance for a process |
| ... | ... |
@@ -132,7 +133,7 @@ func (p *Init) Create(ctx context.Context, r *CreateConfig) error {
|
| 132 | 132 |
opts := &runc.RestoreOpts{
|
| 133 | 133 |
CheckpointOpts: runc.CheckpointOpts{
|
| 134 | 134 |
ImagePath: r.Checkpoint, |
| 135 |
- WorkDir: p.WorkDir, |
|
| 135 |
+ WorkDir: p.CriuWorkPath, |
|
| 136 | 136 |
ParentPath: r.ParentCheckpoint, |
| 137 | 137 |
}, |
| 138 | 138 |
PidFile: pidFile, |
| ... | ... |
@@ -425,8 +426,12 @@ func (p *Init) checkpoint(ctx context.Context, r *CheckpointConfig) error {
|
| 425 | 425 |
if !r.Exit {
|
| 426 | 426 |
actions = append(actions, runc.LeaveRunning) |
| 427 | 427 |
} |
| 428 |
- work := filepath.Join(p.WorkDir, "criu-work") |
|
| 429 |
- defer os.RemoveAll(work) |
|
| 428 |
+ // keep criu work directory if criu work dir is set |
|
| 429 |
+ work := r.WorkDir |
|
| 430 |
+ if work == "" {
|
|
| 431 |
+ work = filepath.Join(p.WorkDir, "criu-work") |
|
| 432 |
+ defer os.RemoveAll(work) |
|
| 433 |
+ } |
|
| 430 | 434 |
if err := p.runtime.Checkpoint(ctx, p.id, &runc.CheckpointOpts{
|
| 431 | 435 |
WorkDir: work, |
| 432 | 436 |
ImagePath: r.Path, |
| ... | ... |
@@ -21,6 +21,7 @@ package linux |
| 21 | 21 |
import ( |
| 22 | 22 |
"context" |
| 23 | 23 |
"fmt" |
| 24 |
+ "io" |
|
| 24 | 25 |
"io/ioutil" |
| 25 | 26 |
"os" |
| 26 | 27 |
"path/filepath" |
| ... | ... |
@@ -40,6 +41,7 @@ import ( |
| 40 | 40 |
"github.com/containerd/containerd/plugin" |
| 41 | 41 |
"github.com/containerd/containerd/runtime" |
| 42 | 42 |
"github.com/containerd/containerd/runtime/linux/runctypes" |
| 43 |
+ "github.com/containerd/containerd/runtime/v1" |
|
| 43 | 44 |
"github.com/containerd/containerd/runtime/v1/linux/proc" |
| 44 | 45 |
shim "github.com/containerd/containerd/runtime/v1/shim/v1" |
| 45 | 46 |
runc "github.com/containerd/go-runc" |
| ... | ... |
@@ -288,6 +290,10 @@ func (r *Runtime) restoreTasks(ctx context.Context) ([]*Task, error) {
|
| 288 | 288 |
continue |
| 289 | 289 |
} |
| 290 | 290 |
name := namespace.Name() |
| 291 |
+ // skip hidden directories |
|
| 292 |
+ if len(name) > 0 && name[0] == '.' {
|
|
| 293 |
+ continue |
|
| 294 |
+ } |
|
| 291 | 295 |
log.G(ctx).WithField("namespace", name).Debug("loading tasks in namespace")
|
| 292 | 296 |
tasks, err := r.loadTasks(ctx, name) |
| 293 | 297 |
if err != nil {
|
| ... | ... |
@@ -351,6 +357,30 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) {
|
| 351 | 351 |
continue |
| 352 | 352 |
} |
| 353 | 353 |
|
| 354 |
+ logDirPath := filepath.Join(r.root, ns, id) |
|
| 355 |
+ |
|
| 356 |
+ shimStdoutLog, err := v1.OpenShimStdoutLog(ctx, logDirPath) |
|
| 357 |
+ if err != nil {
|
|
| 358 |
+ log.G(ctx).WithError(err).WithFields(logrus.Fields{
|
|
| 359 |
+ "id": id, |
|
| 360 |
+ "namespace": ns, |
|
| 361 |
+ "logDirPath": logDirPath, |
|
| 362 |
+ }).Error("opening shim stdout log pipe")
|
|
| 363 |
+ continue |
|
| 364 |
+ } |
|
| 365 |
+ go io.Copy(os.Stdout, shimStdoutLog) |
|
| 366 |
+ |
|
| 367 |
+ shimStderrLog, err := v1.OpenShimStderrLog(ctx, logDirPath) |
|
| 368 |
+ if err != nil {
|
|
| 369 |
+ log.G(ctx).WithError(err).WithFields(logrus.Fields{
|
|
| 370 |
+ "id": id, |
|
| 371 |
+ "namespace": ns, |
|
| 372 |
+ "logDirPath": logDirPath, |
|
| 373 |
+ }).Error("opening shim stderr log pipe")
|
|
| 374 |
+ continue |
|
| 375 |
+ } |
|
| 376 |
+ go io.Copy(os.Stderr, shimStderrLog) |
|
| 377 |
+ |
|
| 354 | 378 |
t, err := newTask(id, ns, pid, s, r.events, r.tasks, bundle) |
| 355 | 379 |
if err != nil {
|
| 356 | 380 |
log.G(ctx).WithError(err).Error("loading task type")
|
| 357 | 381 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,38 @@ |
| 0 |
+// +build !windows |
|
| 1 |
+ |
|
| 2 |
+/* |
|
| 3 |
+ Copyright The containerd Authors. |
|
| 4 |
+ |
|
| 5 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 6 |
+ you may not use this file except in compliance with the License. |
|
| 7 |
+ You may obtain a copy of the License at |
|
| 8 |
+ |
|
| 9 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 10 |
+ |
|
| 11 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 12 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 13 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 14 |
+ See the License for the specific language governing permissions and |
|
| 15 |
+ limitations under the License. |
|
| 16 |
+*/ |
|
| 17 |
+ |
|
| 18 |
+package v1 |
|
| 19 |
+ |
|
| 20 |
+import ( |
|
| 21 |
+ "context" |
|
| 22 |
+ "io" |
|
| 23 |
+ "path/filepath" |
|
| 24 |
+ |
|
| 25 |
+ "github.com/containerd/fifo" |
|
| 26 |
+ "golang.org/x/sys/unix" |
|
| 27 |
+) |
|
| 28 |
+ |
|
| 29 |
+// OpenShimStdoutLog opens the shim log for reading |
|
| 30 |
+func OpenShimStdoutLog(ctx context.Context, logDirPath string) (io.ReadWriteCloser, error) {
|
|
| 31 |
+ return fifo.OpenFifo(ctx, filepath.Join(logDirPath, "shim.stdout.log"), unix.O_RDWR|unix.O_CREAT, 0700) |
|
| 32 |
+} |
|
| 33 |
+ |
|
| 34 |
+// OpenShimStderrLog opens the shim log |
|
| 35 |
+func OpenShimStderrLog(ctx context.Context, logDirPath string) (io.ReadWriteCloser, error) {
|
|
| 36 |
+ return fifo.OpenFifo(ctx, filepath.Join(logDirPath, "shim.stderr.log"), unix.O_RDWR|unix.O_CREAT, 0700) |
|
| 37 |
+} |
| ... | ... |
@@ -37,6 +37,7 @@ import ( |
| 37 | 37 |
|
| 38 | 38 |
"github.com/containerd/containerd/events" |
| 39 | 39 |
"github.com/containerd/containerd/log" |
| 40 |
+ v1 "github.com/containerd/containerd/runtime/v1" |
|
| 40 | 41 |
"github.com/containerd/containerd/runtime/v1/shim" |
| 41 | 42 |
shimapi "github.com/containerd/containerd/runtime/v1/shim/v1" |
| 42 | 43 |
"github.com/containerd/containerd/sys" |
| ... | ... |
@@ -62,7 +63,24 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa |
| 62 | 62 |
} |
| 63 | 63 |
defer f.Close() |
| 64 | 64 |
|
| 65 |
- cmd, err := newCommand(binary, daemonAddress, debug, config, f) |
|
| 65 |
+ var stdoutLog io.ReadWriteCloser |
|
| 66 |
+ var stderrLog io.ReadWriteCloser |
|
| 67 |
+ if debug {
|
|
| 68 |
+ stdoutLog, err = v1.OpenShimStdoutLog(ctx, config.WorkDir) |
|
| 69 |
+ if err != nil {
|
|
| 70 |
+ return nil, nil, errors.Wrapf(err, "failed to create stdout log") |
|
| 71 |
+ } |
|
| 72 |
+ |
|
| 73 |
+ stderrLog, err = v1.OpenShimStderrLog(ctx, config.WorkDir) |
|
| 74 |
+ if err != nil {
|
|
| 75 |
+ return nil, nil, errors.Wrapf(err, "failed to create stderr log") |
|
| 76 |
+ } |
|
| 77 |
+ |
|
| 78 |
+ go io.Copy(os.Stdout, stdoutLog) |
|
| 79 |
+ go io.Copy(os.Stderr, stderrLog) |
|
| 80 |
+ } |
|
| 81 |
+ |
|
| 82 |
+ cmd, err := newCommand(binary, daemonAddress, debug, config, f, stdoutLog, stderrLog) |
|
| 66 | 83 |
if err != nil {
|
| 67 | 84 |
return nil, nil, err |
| 68 | 85 |
} |
| ... | ... |
@@ -77,6 +95,12 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa |
| 77 | 77 |
go func() {
|
| 78 | 78 |
cmd.Wait() |
| 79 | 79 |
exitHandler() |
| 80 |
+ if stdoutLog != nil {
|
|
| 81 |
+ stderrLog.Close() |
|
| 82 |
+ } |
|
| 83 |
+ if stdoutLog != nil {
|
|
| 84 |
+ stderrLog.Close() |
|
| 85 |
+ } |
|
| 80 | 86 |
}() |
| 81 | 87 |
log.G(ctx).WithFields(logrus.Fields{
|
| 82 | 88 |
"pid": cmd.Process.Pid, |
| ... | ... |
@@ -104,7 +128,7 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa |
| 104 | 104 |
} |
| 105 | 105 |
} |
| 106 | 106 |
|
| 107 |
-func newCommand(binary, daemonAddress string, debug bool, config shim.Config, socket *os.File) (*exec.Cmd, error) {
|
|
| 107 |
+func newCommand(binary, daemonAddress string, debug bool, config shim.Config, socket *os.File, stdout, stderr io.Writer) (*exec.Cmd, error) {
|
|
| 108 | 108 |
selfExe, err := os.Executable() |
| 109 | 109 |
if err != nil {
|
| 110 | 110 |
return nil, err |
| ... | ... |
@@ -137,10 +161,8 @@ func newCommand(binary, daemonAddress string, debug bool, config shim.Config, so |
| 137 | 137 |
cmd.SysProcAttr = getSysProcAttr() |
| 138 | 138 |
cmd.ExtraFiles = append(cmd.ExtraFiles, socket) |
| 139 | 139 |
cmd.Env = append(os.Environ(), "GOMAXPROCS=2") |
| 140 |
- if debug {
|
|
| 141 |
- cmd.Stdout = os.Stdout |
|
| 142 |
- cmd.Stderr = os.Stderr |
|
| 143 |
- } |
|
| 140 |
+ cmd.Stdout = stdout |
|
| 141 |
+ cmd.Stderr = stderr |
|
| 144 | 142 |
return cmd, nil |
| 145 | 143 |
} |
| 146 | 144 |
|
| ... | ... |
@@ -448,6 +448,7 @@ func (s *Service) Checkpoint(ctx context.Context, r *shimapi.CheckpointTaskReque |
| 448 | 448 |
AllowTerminal: options.Terminal, |
| 449 | 449 |
FileLocks: options.FileLocks, |
| 450 | 450 |
EmptyNamespaces: options.EmptyNamespaces, |
| 451 |
+ WorkDir: options.WorkPath, |
|
| 451 | 452 |
}); err != nil {
|
| 452 | 453 |
return nil, errdefs.ToGRPC(err) |
| 453 | 454 |
} |
| ... | ... |
@@ -657,5 +658,11 @@ func newInit(ctx context.Context, path, workDir, runtimeRoot, namespace, criu st |
| 657 | 657 |
p.IoGID = int(options.IoGid) |
| 658 | 658 |
p.NoPivotRoot = options.NoPivotRoot |
| 659 | 659 |
p.NoNewKeyring = options.NoNewKeyring |
| 660 |
+ p.CriuWorkPath = options.CriuWorkPath |
|
| 661 |
+ if p.CriuWorkPath == "" {
|
|
| 662 |
+ // if criu work path not set, use container WorkDir |
|
| 663 |
+ p.CriuWorkPath = p.WorkDir |
|
| 664 |
+ } |
|
| 665 |
+ |
|
| 660 | 666 |
return p, nil |
| 661 | 667 |
} |
| 662 | 668 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,195 @@ |
| 0 |
+# Runtime v2 |
|
| 1 |
+ |
|
| 2 |
+Runtime v2 introduces a first class shim API for runtime authors to integrate with containerd. |
|
| 3 |
+The shim API is minimal and scoped to the execution lifecycle of a container. |
|
| 4 |
+ |
|
| 5 |
+## Binary Naming |
|
| 6 |
+ |
|
| 7 |
+Users specify the runtime they wish to use when creating a container. |
|
| 8 |
+The runtime can also be changed via a container update. |
|
| 9 |
+ |
|
| 10 |
+```bash |
|
| 11 |
+> ctr run --runtime io.containerd.runc.v1 |
|
| 12 |
+``` |
|
| 13 |
+ |
|
| 14 |
+When a user specifies a runtime name, `io.containerd.runc.v1`, they will specify the name and version of the runtime. |
|
| 15 |
+This will be translated by containerd into a binary name for the shim. |
|
| 16 |
+ |
|
| 17 |
+`io.containerd.runc.v1` -> `containerd-shim-runc-v1` |
|
| 18 |
+ |
|
| 19 |
+containerd keeps the `containerd-shim-*` prefix so that users can `ps aux | grep containerd-shim` to see running shims on their system. |
|
| 20 |
+ |
|
| 21 |
+## Shim Authoring |
|
| 22 |
+ |
|
| 23 |
+This section is dedicated to runtime authors wishing to build a shim. |
|
| 24 |
+It will detail how the API works and different considerations when building shim. |
|
| 25 |
+ |
|
| 26 |
+### Commands |
|
| 27 |
+ |
|
| 28 |
+Container information is provided to a shim in two ways. |
|
| 29 |
+The OCI Runtime Bundle and on the `Create` rpc request. |
|
| 30 |
+ |
|
| 31 |
+#### `start` |
|
| 32 |
+ |
|
| 33 |
+Each shim MUST implement a `start` subcommand. |
|
| 34 |
+This command will launch new shims. |
|
| 35 |
+The start command MUST accept the following flags: |
|
| 36 |
+ |
|
| 37 |
+* `-namespace` the namespace for the container |
|
| 38 |
+* `-address` the address of the containerd's main socket |
|
| 39 |
+* `-publish-binary` the binary path to publish events back to containerd |
|
| 40 |
+* `-id` the id of the container |
|
| 41 |
+ |
|
| 42 |
+The start command, as well as all binary calls to the shim, has the bundle for the container set as the `cwd`. |
|
| 43 |
+ |
|
| 44 |
+The start command MUST return an address to a shim for containerd to issue API requests for container operations. |
|
| 45 |
+ |
|
| 46 |
+The start command can either start a new shim or return an address to an existing shim based on the shim's logic. |
|
| 47 |
+ |
|
| 48 |
+#### `delete` |
|
| 49 |
+ |
|
| 50 |
+Each shim MUST implement a `delete` subcommand. |
|
| 51 |
+This command allows containerd to delete any container resources created, mounted, and/or run by a shim when containerd can no longer communicate over rpc. |
|
| 52 |
+This happens if a shim is SIGKILL'd with a running container. |
|
| 53 |
+These resources will need to be cleaned up when containerd looses the connection to a shim. |
|
| 54 |
+This is also used when containerd boots and reconnects to shims. |
|
| 55 |
+If a bundle is still on disk but containerd cannot connect to a shim, the delete command is invoked. |
|
| 56 |
+ |
|
| 57 |
+The delete command MUST accept the following flags: |
|
| 58 |
+ |
|
| 59 |
+* `-namespace` the namespace for the container |
|
| 60 |
+* `-address` the address of the containerd's main socket |
|
| 61 |
+* `-publish-binary` the binary path to publish events back to containerd |
|
| 62 |
+* `-id` the id of the container |
|
| 63 |
+* `-bundle` the path to the bundle to delete. On non-Windows platforms this will match `cwd` |
|
| 64 |
+ |
|
| 65 |
+The delete command will be executed in the container's bundle as its `cwd` except for on the Windows platform. |
|
| 66 |
+ |
|
| 67 |
+### Host Level Shim Configuration |
|
| 68 |
+ |
|
| 69 |
+containerd does not provide any host level configuration for shims via the API. |
|
| 70 |
+If a shim needs configuration from the user with host level information across all instances, a shim specific configuration file can be setup. |
|
| 71 |
+ |
|
| 72 |
+### Container Level Shim Configuration |
|
| 73 |
+ |
|
| 74 |
+On the create request, there is a generic `*protobuf.Any` that allows a user to specify container level configuration for the shim. |
|
| 75 |
+ |
|
| 76 |
+```proto |
|
| 77 |
+message CreateTaskRequest {
|
|
| 78 |
+ string id = 1; |
|
| 79 |
+ ... |
|
| 80 |
+ google.protobuf.Any options = 10; |
|
| 81 |
+} |
|
| 82 |
+``` |
|
| 83 |
+ |
|
| 84 |
+A shim author can create their own protobuf message for configuration and clients can import and provide this information is needed. |
|
| 85 |
+ |
|
| 86 |
+### I/O |
|
| 87 |
+ |
|
| 88 |
+I/O for a container is provided by the client to the shim via fifo on Linux, named pipes on Windows, or log files on disk. |
|
| 89 |
+The paths to these files are provided on the `Create` rpc for the initial creation and on the `Exec` rpc for additional processes. |
|
| 90 |
+ |
|
| 91 |
+```proto |
|
| 92 |
+message CreateTaskRequest {
|
|
| 93 |
+ string id = 1; |
|
| 94 |
+ bool terminal = 4; |
|
| 95 |
+ string stdin = 5; |
|
| 96 |
+ string stdout = 6; |
|
| 97 |
+ string stderr = 7; |
|
| 98 |
+} |
|
| 99 |
+``` |
|
| 100 |
+ |
|
| 101 |
+```proto |
|
| 102 |
+message ExecProcessRequest {
|
|
| 103 |
+ string id = 1; |
|
| 104 |
+ string exec_id = 2; |
|
| 105 |
+ bool terminal = 3; |
|
| 106 |
+ string stdin = 4; |
|
| 107 |
+ string stdout = 5; |
|
| 108 |
+ string stderr = 6; |
|
| 109 |
+} |
|
| 110 |
+``` |
|
| 111 |
+ |
|
| 112 |
+Containers that are to be launched with an interactive terminal will have the `terminal` field set to `true`, data is still copied over the files(fifos,pipes) in the same way as non interactive containers. |
|
| 113 |
+ |
|
| 114 |
+### Root Filesystems |
|
| 115 |
+ |
|
| 116 |
+The root filesystem for the containers is provided by on the `Create` rpc. |
|
| 117 |
+Shims are responsible for managing the lifecycle of the filesystem mount during the lifecycle of a container. |
|
| 118 |
+ |
|
| 119 |
+```proto |
|
| 120 |
+message CreateTaskRequest {
|
|
| 121 |
+ string id = 1; |
|
| 122 |
+ string bundle = 2; |
|
| 123 |
+ repeated containerd.types.Mount rootfs = 3; |
|
| 124 |
+ ... |
|
| 125 |
+} |
|
| 126 |
+``` |
|
| 127 |
+ |
|
| 128 |
+The mount protobuf message is: |
|
| 129 |
+ |
|
| 130 |
+```proto |
|
| 131 |
+message Mount {
|
|
| 132 |
+ // Type defines the nature of the mount. |
|
| 133 |
+ string type = 1; |
|
| 134 |
+ // Source specifies the name of the mount. Depending on mount type, this |
|
| 135 |
+ // may be a volume name or a host path, or even ignored. |
|
| 136 |
+ string source = 2; |
|
| 137 |
+ // Target path in container |
|
| 138 |
+ string target = 3; |
|
| 139 |
+ // Options specifies zero or more fstab style mount options. |
|
| 140 |
+ repeated string options = 4; |
|
| 141 |
+} |
|
| 142 |
+``` |
|
| 143 |
+ |
|
| 144 |
+Shims are responsible for mounting the filesystem into the `rootfs/` directory of the bundle. |
|
| 145 |
+Shims are also responsible for unmounting of the filesystem. |
|
| 146 |
+During a `delete` binary call, the shim MUST ensure that filesystem is also unmounted. |
|
| 147 |
+Filesystems are provided by the containerd snapshotters. |
|
| 148 |
+ |
|
| 149 |
+### Events |
|
| 150 |
+ |
|
| 151 |
+The Runtime v2 supports an async event model. In order for the an upstream caller (such as Docker) to get these events in the correct order a Runtime v2 shim MUST implement the following events where `Compliance=MUST`. This avoids race conditions between the shim and shim client where for example a call to `Start` can signal a `TaskExitEventTopic` before even returning the results from the `Start` call. With these guarantees of a Runtime v2 shim a call to `Start` is required to have published the async event `TaskStartEventTopic` before the shim can publish the `TaskExitEventTopic`. |
|
| 152 |
+ |
|
| 153 |
+#### Tasks |
|
| 154 |
+ |
|
| 155 |
+| Topic | Compliance | Description | |
|
| 156 |
+| ----- | ---------- | ----------- | |
|
| 157 |
+| `runtime.TaskCreateEventTopic` | MUST | When a task is successfully created | |
|
| 158 |
+| `runtime.TaskStartEventTopic` | MUST (follow `TaskCreateEventTopic`) | When a task is successfully started | |
|
| 159 |
+| `runtime.TaskExitEventTopic` | MUST (follow `TaskStartEventTopic`) | When a task exits expected or unexpected | |
|
| 160 |
+| `runtime.TaskDeleteEventTopic` | MUST (follow `TaskExitEventTopic` or `TaskCreateEventTopic` if never started) | When a task is removed from a shim | |
|
| 161 |
+| `runtime.TaskPausedEventTopic` | SHOULD | When a task is successfully paused | |
|
| 162 |
+| `runtime.TaskResumedEventTopic` | SHOULD (follow `TaskPausedEventTopic`) | When a task is successfully resumed | |
|
| 163 |
+| `runtime.TaskCheckpointedEventTopic` | SHOULD | When a task is checkpointed | |
|
| 164 |
+| `runtime.TaskOOMEventTopic` | SHOULD | If the shim collects Out of Memory events | |
|
| 165 |
+ |
|
| 166 |
+#### Execs |
|
| 167 |
+ |
|
| 168 |
+| Topic | Compliance | Description | |
|
| 169 |
+| ----- | ---------- | ----------- | |
|
| 170 |
+| `runtime.TaskExecAddedEventTopic` | MUST (follow `TaskCreateEventTopic` ) | When an exec is successfully added | |
|
| 171 |
+| `runtime.TaskExecStartedEventTopic` | MUST (follow `TaskExecAddedEventTopic`) | When an exec is successfully started | |
|
| 172 |
+| `runtime.TaskExitEventTopic` | MUST (follow `TaskExecStartedEventTopic`) | When an exec (other than the init exec) exits expected or unexpected | |
|
| 173 |
+| `runtime.TaskDeleteEventTopic` | SHOULD (follow `TaskExitEventTopic` or `TaskExecAddedEventTopic` if never started) | When an exec is removed from a shim | |
|
| 174 |
+ |
|
| 175 |
+### Other |
|
| 176 |
+ |
|
| 177 |
+#### Unsupported rpcs |
|
| 178 |
+ |
|
| 179 |
+If a shim does not or cannot implement an rpc call, it MUST return a `github.com/containerd/containerd/errdefs.ErrNotImplemented` error. |
|
| 180 |
+ |
|
| 181 |
+#### Debugging and Shim Logs |
|
| 182 |
+ |
|
| 183 |
+A fifo on unix or named pipe on Windows will be provided to the shim. |
|
| 184 |
+It can be located inside the `cwd` of the shim named "log". |
|
| 185 |
+The shims can use the existing `github.com/containerd/containerd/log` package to log debug messages. |
|
| 186 |
+Messages will automatically be output in the containerd's daemon logs with the correct fields and runtime set. |
|
| 187 |
+ |
|
| 188 |
+#### ttrpc |
|
| 189 |
+ |
|
| 190 |
+[ttrpc](https://github.com/containerd/ttrpc) is the only currently supported protocol for shims. |
|
| 191 |
+It works with standard protobufs and GRPC services as well as generating clients. |
|
| 192 |
+The only difference between grpc and ttrpc is the wire protocol. |
|
| 193 |
+ttrpc removes the http stack in order to save memory and binary size to keep shims small. |
|
| 194 |
+It is recommended to use ttrpc in your shim but grpc support is also in development. |
| 0 | 195 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,17 @@ |
| 0 |
+/* |
|
| 1 |
+ Copyright The containerd Authors. |
|
| 2 |
+ |
|
| 3 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
+ you may not use this file except in compliance with the License. |
|
| 5 |
+ You may obtain a copy of the License at |
|
| 6 |
+ |
|
| 7 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
+ |
|
| 9 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 10 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
+ See the License for the specific language governing permissions and |
|
| 13 |
+ limitations under the License. |
|
| 14 |
+*/ |
|
| 15 |
+ |
|
| 16 |
+package options |
| 0 | 17 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,1313 @@ |
| 0 |
+// Code generated by protoc-gen-gogo. DO NOT EDIT. |
|
| 1 |
+// source: github.com/containerd/containerd/runtime/v2/runc/options/oci.proto |
|
| 2 |
+ |
|
| 3 |
+/* |
|
| 4 |
+ Package options is a generated protocol buffer package. |
|
| 5 |
+ |
|
| 6 |
+ It is generated from these files: |
|
| 7 |
+ github.com/containerd/containerd/runtime/v2/runc/options/oci.proto |
|
| 8 |
+ |
|
| 9 |
+ It has these top-level messages: |
|
| 10 |
+ Options |
|
| 11 |
+ CheckpointOptions |
|
| 12 |
+ ProcessDetails |
|
| 13 |
+*/ |
|
| 14 |
+package options |
|
| 15 |
+ |
|
| 16 |
+import proto "github.com/gogo/protobuf/proto" |
|
| 17 |
+import fmt "fmt" |
|
| 18 |
+import math "math" |
|
| 19 |
+ |
|
| 20 |
+// skipping weak import gogoproto "github.com/gogo/protobuf/gogoproto" |
|
| 21 |
+ |
|
| 22 |
+import strings "strings" |
|
| 23 |
+import reflect "reflect" |
|
| 24 |
+ |
|
| 25 |
+import io "io" |
|
| 26 |
+ |
|
| 27 |
+// Reference imports to suppress errors if they are not otherwise used. |
|
| 28 |
+var _ = proto.Marshal |
|
| 29 |
+var _ = fmt.Errorf |
|
| 30 |
+var _ = math.Inf |
|
| 31 |
+ |
|
| 32 |
+// This is a compile-time assertion to ensure that this generated file |
|
| 33 |
+// is compatible with the proto package it is being compiled against. |
|
| 34 |
+// A compilation error at this line likely means your copy of the |
|
| 35 |
+// proto package needs to be updated. |
|
| 36 |
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package |
|
| 37 |
+ |
|
| 38 |
+type Options struct {
|
|
| 39 |
+ // disable pivot root when creating a container |
|
| 40 |
+ NoPivotRoot bool `protobuf:"varint,1,opt,name=no_pivot_root,json=noPivotRoot,proto3" json:"no_pivot_root,omitempty"` |
|
| 41 |
+ // create a new keyring for the container |
|
| 42 |
+ NoNewKeyring bool `protobuf:"varint,2,opt,name=no_new_keyring,json=noNewKeyring,proto3" json:"no_new_keyring,omitempty"` |
|
| 43 |
+ // place the shim in a cgroup |
|
| 44 |
+ ShimCgroup string `protobuf:"bytes,3,opt,name=shim_cgroup,json=shimCgroup,proto3" json:"shim_cgroup,omitempty"` |
|
| 45 |
+ // set the I/O's pipes uid |
|
| 46 |
+ IoUid uint32 `protobuf:"varint,4,opt,name=io_uid,json=ioUid,proto3" json:"io_uid,omitempty"` |
|
| 47 |
+ // set the I/O's pipes gid |
|
| 48 |
+ IoGid uint32 `protobuf:"varint,5,opt,name=io_gid,json=ioGid,proto3" json:"io_gid,omitempty"` |
|
| 49 |
+ // binary name of the runc binary |
|
| 50 |
+ BinaryName string `protobuf:"bytes,6,opt,name=binary_name,json=binaryName,proto3" json:"binary_name,omitempty"` |
|
| 51 |
+ // runc root directory |
|
| 52 |
+ Root string `protobuf:"bytes,7,opt,name=root,proto3" json:"root,omitempty"` |
|
| 53 |
+ // criu binary path |
|
| 54 |
+ CriuPath string `protobuf:"bytes,8,opt,name=criu_path,json=criuPath,proto3" json:"criu_path,omitempty"` |
|
| 55 |
+ // enable systemd cgroups |
|
| 56 |
+ SystemdCgroup bool `protobuf:"varint,9,opt,name=systemd_cgroup,json=systemdCgroup,proto3" json:"systemd_cgroup,omitempty"` |
|
| 57 |
+ // criu image path |
|
| 58 |
+ CriuImagePath string `protobuf:"bytes,10,opt,name=criu_image_path,json=criuImagePath,proto3" json:"criu_image_path,omitempty"` |
|
| 59 |
+ // criu work path |
|
| 60 |
+ CriuWorkPath string `protobuf:"bytes,11,opt,name=criu_work_path,json=criuWorkPath,proto3" json:"criu_work_path,omitempty"` |
|
| 61 |
+} |
|
| 62 |
+ |
|
| 63 |
+func (m *Options) Reset() { *m = Options{} }
|
|
| 64 |
+func (*Options) ProtoMessage() {}
|
|
| 65 |
+func (*Options) Descriptor() ([]byte, []int) { return fileDescriptorOci, []int{0} }
|
|
| 66 |
+ |
|
| 67 |
+type CheckpointOptions struct {
|
|
| 68 |
+ // exit the container after a checkpoint |
|
| 69 |
+ Exit bool `protobuf:"varint,1,opt,name=exit,proto3" json:"exit,omitempty"` |
|
| 70 |
+ // checkpoint open tcp connections |
|
| 71 |
+ OpenTcp bool `protobuf:"varint,2,opt,name=open_tcp,json=openTcp,proto3" json:"open_tcp,omitempty"` |
|
| 72 |
+ // checkpoint external unix sockets |
|
| 73 |
+ ExternalUnixSockets bool `protobuf:"varint,3,opt,name=external_unix_sockets,json=externalUnixSockets,proto3" json:"external_unix_sockets,omitempty"` |
|
| 74 |
+ // checkpoint terminals (ptys) |
|
| 75 |
+ Terminal bool `protobuf:"varint,4,opt,name=terminal,proto3" json:"terminal,omitempty"` |
|
| 76 |
+ // allow checkpointing of file locks |
|
| 77 |
+ FileLocks bool `protobuf:"varint,5,opt,name=file_locks,json=fileLocks,proto3" json:"file_locks,omitempty"` |
|
| 78 |
+ // restore provided namespaces as empty namespaces |
|
| 79 |
+ EmptyNamespaces []string `protobuf:"bytes,6,rep,name=empty_namespaces,json=emptyNamespaces" json:"empty_namespaces,omitempty"` |
|
| 80 |
+ // set the cgroups mode, soft, full, strict |
|
| 81 |
+ CgroupsMode string `protobuf:"bytes,7,opt,name=cgroups_mode,json=cgroupsMode,proto3" json:"cgroups_mode,omitempty"` |
|
| 82 |
+ // checkpoint image path |
|
| 83 |
+ ImagePath string `protobuf:"bytes,8,opt,name=image_path,json=imagePath,proto3" json:"image_path,omitempty"` |
|
| 84 |
+ // checkpoint work path |
|
| 85 |
+ WorkPath string `protobuf:"bytes,9,opt,name=work_path,json=workPath,proto3" json:"work_path,omitempty"` |
|
| 86 |
+} |
|
| 87 |
+ |
|
| 88 |
+func (m *CheckpointOptions) Reset() { *m = CheckpointOptions{} }
|
|
| 89 |
+func (*CheckpointOptions) ProtoMessage() {}
|
|
| 90 |
+func (*CheckpointOptions) Descriptor() ([]byte, []int) { return fileDescriptorOci, []int{1} }
|
|
| 91 |
+ |
|
| 92 |
+type ProcessDetails struct {
|
|
| 93 |
+ // exec process id if the process is managed by a shim |
|
| 94 |
+ ExecID string `protobuf:"bytes,1,opt,name=exec_id,json=execId,proto3" json:"exec_id,omitempty"` |
|
| 95 |
+} |
|
| 96 |
+ |
|
| 97 |
+func (m *ProcessDetails) Reset() { *m = ProcessDetails{} }
|
|
| 98 |
+func (*ProcessDetails) ProtoMessage() {}
|
|
| 99 |
+func (*ProcessDetails) Descriptor() ([]byte, []int) { return fileDescriptorOci, []int{2} }
|
|
| 100 |
+ |
|
| 101 |
+func init() {
|
|
| 102 |
+ proto.RegisterType((*Options)(nil), "containerd.runc.v1.Options") |
|
| 103 |
+ proto.RegisterType((*CheckpointOptions)(nil), "containerd.runc.v1.CheckpointOptions") |
|
| 104 |
+ proto.RegisterType((*ProcessDetails)(nil), "containerd.runc.v1.ProcessDetails") |
|
| 105 |
+} |
|
| 106 |
+func (m *Options) Marshal() (dAtA []byte, err error) {
|
|
| 107 |
+ size := m.Size() |
|
| 108 |
+ dAtA = make([]byte, size) |
|
| 109 |
+ n, err := m.MarshalTo(dAtA) |
|
| 110 |
+ if err != nil {
|
|
| 111 |
+ return nil, err |
|
| 112 |
+ } |
|
| 113 |
+ return dAtA[:n], nil |
|
| 114 |
+} |
|
| 115 |
+ |
|
| 116 |
+func (m *Options) MarshalTo(dAtA []byte) (int, error) {
|
|
| 117 |
+ var i int |
|
| 118 |
+ _ = i |
|
| 119 |
+ var l int |
|
| 120 |
+ _ = l |
|
| 121 |
+ if m.NoPivotRoot {
|
|
| 122 |
+ dAtA[i] = 0x8 |
|
| 123 |
+ i++ |
|
| 124 |
+ if m.NoPivotRoot {
|
|
| 125 |
+ dAtA[i] = 1 |
|
| 126 |
+ } else {
|
|
| 127 |
+ dAtA[i] = 0 |
|
| 128 |
+ } |
|
| 129 |
+ i++ |
|
| 130 |
+ } |
|
| 131 |
+ if m.NoNewKeyring {
|
|
| 132 |
+ dAtA[i] = 0x10 |
|
| 133 |
+ i++ |
|
| 134 |
+ if m.NoNewKeyring {
|
|
| 135 |
+ dAtA[i] = 1 |
|
| 136 |
+ } else {
|
|
| 137 |
+ dAtA[i] = 0 |
|
| 138 |
+ } |
|
| 139 |
+ i++ |
|
| 140 |
+ } |
|
| 141 |
+ if len(m.ShimCgroup) > 0 {
|
|
| 142 |
+ dAtA[i] = 0x1a |
|
| 143 |
+ i++ |
|
| 144 |
+ i = encodeVarintOci(dAtA, i, uint64(len(m.ShimCgroup))) |
|
| 145 |
+ i += copy(dAtA[i:], m.ShimCgroup) |
|
| 146 |
+ } |
|
| 147 |
+ if m.IoUid != 0 {
|
|
| 148 |
+ dAtA[i] = 0x20 |
|
| 149 |
+ i++ |
|
| 150 |
+ i = encodeVarintOci(dAtA, i, uint64(m.IoUid)) |
|
| 151 |
+ } |
|
| 152 |
+ if m.IoGid != 0 {
|
|
| 153 |
+ dAtA[i] = 0x28 |
|
| 154 |
+ i++ |
|
| 155 |
+ i = encodeVarintOci(dAtA, i, uint64(m.IoGid)) |
|
| 156 |
+ } |
|
| 157 |
+ if len(m.BinaryName) > 0 {
|
|
| 158 |
+ dAtA[i] = 0x32 |
|
| 159 |
+ i++ |
|
| 160 |
+ i = encodeVarintOci(dAtA, i, uint64(len(m.BinaryName))) |
|
| 161 |
+ i += copy(dAtA[i:], m.BinaryName) |
|
| 162 |
+ } |
|
| 163 |
+ if len(m.Root) > 0 {
|
|
| 164 |
+ dAtA[i] = 0x3a |
|
| 165 |
+ i++ |
|
| 166 |
+ i = encodeVarintOci(dAtA, i, uint64(len(m.Root))) |
|
| 167 |
+ i += copy(dAtA[i:], m.Root) |
|
| 168 |
+ } |
|
| 169 |
+ if len(m.CriuPath) > 0 {
|
|
| 170 |
+ dAtA[i] = 0x42 |
|
| 171 |
+ i++ |
|
| 172 |
+ i = encodeVarintOci(dAtA, i, uint64(len(m.CriuPath))) |
|
| 173 |
+ i += copy(dAtA[i:], m.CriuPath) |
|
| 174 |
+ } |
|
| 175 |
+ if m.SystemdCgroup {
|
|
| 176 |
+ dAtA[i] = 0x48 |
|
| 177 |
+ i++ |
|
| 178 |
+ if m.SystemdCgroup {
|
|
| 179 |
+ dAtA[i] = 1 |
|
| 180 |
+ } else {
|
|
| 181 |
+ dAtA[i] = 0 |
|
| 182 |
+ } |
|
| 183 |
+ i++ |
|
| 184 |
+ } |
|
| 185 |
+ if len(m.CriuImagePath) > 0 {
|
|
| 186 |
+ dAtA[i] = 0x52 |
|
| 187 |
+ i++ |
|
| 188 |
+ i = encodeVarintOci(dAtA, i, uint64(len(m.CriuImagePath))) |
|
| 189 |
+ i += copy(dAtA[i:], m.CriuImagePath) |
|
| 190 |
+ } |
|
| 191 |
+ if len(m.CriuWorkPath) > 0 {
|
|
| 192 |
+ dAtA[i] = 0x5a |
|
| 193 |
+ i++ |
|
| 194 |
+ i = encodeVarintOci(dAtA, i, uint64(len(m.CriuWorkPath))) |
|
| 195 |
+ i += copy(dAtA[i:], m.CriuWorkPath) |
|
| 196 |
+ } |
|
| 197 |
+ return i, nil |
|
| 198 |
+} |
|
| 199 |
+ |
|
| 200 |
+func (m *CheckpointOptions) Marshal() (dAtA []byte, err error) {
|
|
| 201 |
+ size := m.Size() |
|
| 202 |
+ dAtA = make([]byte, size) |
|
| 203 |
+ n, err := m.MarshalTo(dAtA) |
|
| 204 |
+ if err != nil {
|
|
| 205 |
+ return nil, err |
|
| 206 |
+ } |
|
| 207 |
+ return dAtA[:n], nil |
|
| 208 |
+} |
|
| 209 |
+ |
|
| 210 |
+func (m *CheckpointOptions) MarshalTo(dAtA []byte) (int, error) {
|
|
| 211 |
+ var i int |
|
| 212 |
+ _ = i |
|
| 213 |
+ var l int |
|
| 214 |
+ _ = l |
|
| 215 |
+ if m.Exit {
|
|
| 216 |
+ dAtA[i] = 0x8 |
|
| 217 |
+ i++ |
|
| 218 |
+ if m.Exit {
|
|
| 219 |
+ dAtA[i] = 1 |
|
| 220 |
+ } else {
|
|
| 221 |
+ dAtA[i] = 0 |
|
| 222 |
+ } |
|
| 223 |
+ i++ |
|
| 224 |
+ } |
|
| 225 |
+ if m.OpenTcp {
|
|
| 226 |
+ dAtA[i] = 0x10 |
|
| 227 |
+ i++ |
|
| 228 |
+ if m.OpenTcp {
|
|
| 229 |
+ dAtA[i] = 1 |
|
| 230 |
+ } else {
|
|
| 231 |
+ dAtA[i] = 0 |
|
| 232 |
+ } |
|
| 233 |
+ i++ |
|
| 234 |
+ } |
|
| 235 |
+ if m.ExternalUnixSockets {
|
|
| 236 |
+ dAtA[i] = 0x18 |
|
| 237 |
+ i++ |
|
| 238 |
+ if m.ExternalUnixSockets {
|
|
| 239 |
+ dAtA[i] = 1 |
|
| 240 |
+ } else {
|
|
| 241 |
+ dAtA[i] = 0 |
|
| 242 |
+ } |
|
| 243 |
+ i++ |
|
| 244 |
+ } |
|
| 245 |
+ if m.Terminal {
|
|
| 246 |
+ dAtA[i] = 0x20 |
|
| 247 |
+ i++ |
|
| 248 |
+ if m.Terminal {
|
|
| 249 |
+ dAtA[i] = 1 |
|
| 250 |
+ } else {
|
|
| 251 |
+ dAtA[i] = 0 |
|
| 252 |
+ } |
|
| 253 |
+ i++ |
|
| 254 |
+ } |
|
| 255 |
+ if m.FileLocks {
|
|
| 256 |
+ dAtA[i] = 0x28 |
|
| 257 |
+ i++ |
|
| 258 |
+ if m.FileLocks {
|
|
| 259 |
+ dAtA[i] = 1 |
|
| 260 |
+ } else {
|
|
| 261 |
+ dAtA[i] = 0 |
|
| 262 |
+ } |
|
| 263 |
+ i++ |
|
| 264 |
+ } |
|
| 265 |
+ if len(m.EmptyNamespaces) > 0 {
|
|
| 266 |
+ for _, s := range m.EmptyNamespaces {
|
|
| 267 |
+ dAtA[i] = 0x32 |
|
| 268 |
+ i++ |
|
| 269 |
+ l = len(s) |
|
| 270 |
+ for l >= 1<<7 {
|
|
| 271 |
+ dAtA[i] = uint8(uint64(l)&0x7f | 0x80) |
|
| 272 |
+ l >>= 7 |
|
| 273 |
+ i++ |
|
| 274 |
+ } |
|
| 275 |
+ dAtA[i] = uint8(l) |
|
| 276 |
+ i++ |
|
| 277 |
+ i += copy(dAtA[i:], s) |
|
| 278 |
+ } |
|
| 279 |
+ } |
|
| 280 |
+ if len(m.CgroupsMode) > 0 {
|
|
| 281 |
+ dAtA[i] = 0x3a |
|
| 282 |
+ i++ |
|
| 283 |
+ i = encodeVarintOci(dAtA, i, uint64(len(m.CgroupsMode))) |
|
| 284 |
+ i += copy(dAtA[i:], m.CgroupsMode) |
|
| 285 |
+ } |
|
| 286 |
+ if len(m.ImagePath) > 0 {
|
|
| 287 |
+ dAtA[i] = 0x42 |
|
| 288 |
+ i++ |
|
| 289 |
+ i = encodeVarintOci(dAtA, i, uint64(len(m.ImagePath))) |
|
| 290 |
+ i += copy(dAtA[i:], m.ImagePath) |
|
| 291 |
+ } |
|
| 292 |
+ if len(m.WorkPath) > 0 {
|
|
| 293 |
+ dAtA[i] = 0x4a |
|
| 294 |
+ i++ |
|
| 295 |
+ i = encodeVarintOci(dAtA, i, uint64(len(m.WorkPath))) |
|
| 296 |
+ i += copy(dAtA[i:], m.WorkPath) |
|
| 297 |
+ } |
|
| 298 |
+ return i, nil |
|
| 299 |
+} |
|
| 300 |
+ |
|
| 301 |
+func (m *ProcessDetails) Marshal() (dAtA []byte, err error) {
|
|
| 302 |
+ size := m.Size() |
|
| 303 |
+ dAtA = make([]byte, size) |
|
| 304 |
+ n, err := m.MarshalTo(dAtA) |
|
| 305 |
+ if err != nil {
|
|
| 306 |
+ return nil, err |
|
| 307 |
+ } |
|
| 308 |
+ return dAtA[:n], nil |
|
| 309 |
+} |
|
| 310 |
+ |
|
| 311 |
+func (m *ProcessDetails) MarshalTo(dAtA []byte) (int, error) {
|
|
| 312 |
+ var i int |
|
| 313 |
+ _ = i |
|
| 314 |
+ var l int |
|
| 315 |
+ _ = l |
|
| 316 |
+ if len(m.ExecID) > 0 {
|
|
| 317 |
+ dAtA[i] = 0xa |
|
| 318 |
+ i++ |
|
| 319 |
+ i = encodeVarintOci(dAtA, i, uint64(len(m.ExecID))) |
|
| 320 |
+ i += copy(dAtA[i:], m.ExecID) |
|
| 321 |
+ } |
|
| 322 |
+ return i, nil |
|
| 323 |
+} |
|
| 324 |
+ |
|
| 325 |
+func encodeVarintOci(dAtA []byte, offset int, v uint64) int {
|
|
| 326 |
+ for v >= 1<<7 {
|
|
| 327 |
+ dAtA[offset] = uint8(v&0x7f | 0x80) |
|
| 328 |
+ v >>= 7 |
|
| 329 |
+ offset++ |
|
| 330 |
+ } |
|
| 331 |
+ dAtA[offset] = uint8(v) |
|
| 332 |
+ return offset + 1 |
|
| 333 |
+} |
|
| 334 |
+func (m *Options) Size() (n int) {
|
|
| 335 |
+ var l int |
|
| 336 |
+ _ = l |
|
| 337 |
+ if m.NoPivotRoot {
|
|
| 338 |
+ n += 2 |
|
| 339 |
+ } |
|
| 340 |
+ if m.NoNewKeyring {
|
|
| 341 |
+ n += 2 |
|
| 342 |
+ } |
|
| 343 |
+ l = len(m.ShimCgroup) |
|
| 344 |
+ if l > 0 {
|
|
| 345 |
+ n += 1 + l + sovOci(uint64(l)) |
|
| 346 |
+ } |
|
| 347 |
+ if m.IoUid != 0 {
|
|
| 348 |
+ n += 1 + sovOci(uint64(m.IoUid)) |
|
| 349 |
+ } |
|
| 350 |
+ if m.IoGid != 0 {
|
|
| 351 |
+ n += 1 + sovOci(uint64(m.IoGid)) |
|
| 352 |
+ } |
|
| 353 |
+ l = len(m.BinaryName) |
|
| 354 |
+ if l > 0 {
|
|
| 355 |
+ n += 1 + l + sovOci(uint64(l)) |
|
| 356 |
+ } |
|
| 357 |
+ l = len(m.Root) |
|
| 358 |
+ if l > 0 {
|
|
| 359 |
+ n += 1 + l + sovOci(uint64(l)) |
|
| 360 |
+ } |
|
| 361 |
+ l = len(m.CriuPath) |
|
| 362 |
+ if l > 0 {
|
|
| 363 |
+ n += 1 + l + sovOci(uint64(l)) |
|
| 364 |
+ } |
|
| 365 |
+ if m.SystemdCgroup {
|
|
| 366 |
+ n += 2 |
|
| 367 |
+ } |
|
| 368 |
+ l = len(m.CriuImagePath) |
|
| 369 |
+ if l > 0 {
|
|
| 370 |
+ n += 1 + l + sovOci(uint64(l)) |
|
| 371 |
+ } |
|
| 372 |
+ l = len(m.CriuWorkPath) |
|
| 373 |
+ if l > 0 {
|
|
| 374 |
+ n += 1 + l + sovOci(uint64(l)) |
|
| 375 |
+ } |
|
| 376 |
+ return n |
|
| 377 |
+} |
|
| 378 |
+ |
|
| 379 |
+func (m *CheckpointOptions) Size() (n int) {
|
|
| 380 |
+ var l int |
|
| 381 |
+ _ = l |
|
| 382 |
+ if m.Exit {
|
|
| 383 |
+ n += 2 |
|
| 384 |
+ } |
|
| 385 |
+ if m.OpenTcp {
|
|
| 386 |
+ n += 2 |
|
| 387 |
+ } |
|
| 388 |
+ if m.ExternalUnixSockets {
|
|
| 389 |
+ n += 2 |
|
| 390 |
+ } |
|
| 391 |
+ if m.Terminal {
|
|
| 392 |
+ n += 2 |
|
| 393 |
+ } |
|
| 394 |
+ if m.FileLocks {
|
|
| 395 |
+ n += 2 |
|
| 396 |
+ } |
|
| 397 |
+ if len(m.EmptyNamespaces) > 0 {
|
|
| 398 |
+ for _, s := range m.EmptyNamespaces {
|
|
| 399 |
+ l = len(s) |
|
| 400 |
+ n += 1 + l + sovOci(uint64(l)) |
|
| 401 |
+ } |
|
| 402 |
+ } |
|
| 403 |
+ l = len(m.CgroupsMode) |
|
| 404 |
+ if l > 0 {
|
|
| 405 |
+ n += 1 + l + sovOci(uint64(l)) |
|
| 406 |
+ } |
|
| 407 |
+ l = len(m.ImagePath) |
|
| 408 |
+ if l > 0 {
|
|
| 409 |
+ n += 1 + l + sovOci(uint64(l)) |
|
| 410 |
+ } |
|
| 411 |
+ l = len(m.WorkPath) |
|
| 412 |
+ if l > 0 {
|
|
| 413 |
+ n += 1 + l + sovOci(uint64(l)) |
|
| 414 |
+ } |
|
| 415 |
+ return n |
|
| 416 |
+} |
|
| 417 |
+ |
|
| 418 |
+func (m *ProcessDetails) Size() (n int) {
|
|
| 419 |
+ var l int |
|
| 420 |
+ _ = l |
|
| 421 |
+ l = len(m.ExecID) |
|
| 422 |
+ if l > 0 {
|
|
| 423 |
+ n += 1 + l + sovOci(uint64(l)) |
|
| 424 |
+ } |
|
| 425 |
+ return n |
|
| 426 |
+} |
|
| 427 |
+ |
|
| 428 |
+func sovOci(x uint64) (n int) {
|
|
| 429 |
+ for {
|
|
| 430 |
+ n++ |
|
| 431 |
+ x >>= 7 |
|
| 432 |
+ if x == 0 {
|
|
| 433 |
+ break |
|
| 434 |
+ } |
|
| 435 |
+ } |
|
| 436 |
+ return n |
|
| 437 |
+} |
|
| 438 |
+func sozOci(x uint64) (n int) {
|
|
| 439 |
+ return sovOci(uint64((x << 1) ^ uint64((int64(x) >> 63)))) |
|
| 440 |
+} |
|
| 441 |
+func (this *Options) String() string {
|
|
| 442 |
+ if this == nil {
|
|
| 443 |
+ return "nil" |
|
| 444 |
+ } |
|
| 445 |
+ s := strings.Join([]string{`&Options{`,
|
|
| 446 |
+ `NoPivotRoot:` + fmt.Sprintf("%v", this.NoPivotRoot) + `,`,
|
|
| 447 |
+ `NoNewKeyring:` + fmt.Sprintf("%v", this.NoNewKeyring) + `,`,
|
|
| 448 |
+ `ShimCgroup:` + fmt.Sprintf("%v", this.ShimCgroup) + `,`,
|
|
| 449 |
+ `IoUid:` + fmt.Sprintf("%v", this.IoUid) + `,`,
|
|
| 450 |
+ `IoGid:` + fmt.Sprintf("%v", this.IoGid) + `,`,
|
|
| 451 |
+ `BinaryName:` + fmt.Sprintf("%v", this.BinaryName) + `,`,
|
|
| 452 |
+ `Root:` + fmt.Sprintf("%v", this.Root) + `,`,
|
|
| 453 |
+ `CriuPath:` + fmt.Sprintf("%v", this.CriuPath) + `,`,
|
|
| 454 |
+ `SystemdCgroup:` + fmt.Sprintf("%v", this.SystemdCgroup) + `,`,
|
|
| 455 |
+ `CriuImagePath:` + fmt.Sprintf("%v", this.CriuImagePath) + `,`,
|
|
| 456 |
+ `CriuWorkPath:` + fmt.Sprintf("%v", this.CriuWorkPath) + `,`,
|
|
| 457 |
+ `}`, |
|
| 458 |
+ }, "") |
|
| 459 |
+ return s |
|
| 460 |
+} |
|
| 461 |
+func (this *CheckpointOptions) String() string {
|
|
| 462 |
+ if this == nil {
|
|
| 463 |
+ return "nil" |
|
| 464 |
+ } |
|
| 465 |
+ s := strings.Join([]string{`&CheckpointOptions{`,
|
|
| 466 |
+ `Exit:` + fmt.Sprintf("%v", this.Exit) + `,`,
|
|
| 467 |
+ `OpenTcp:` + fmt.Sprintf("%v", this.OpenTcp) + `,`,
|
|
| 468 |
+ `ExternalUnixSockets:` + fmt.Sprintf("%v", this.ExternalUnixSockets) + `,`,
|
|
| 469 |
+ `Terminal:` + fmt.Sprintf("%v", this.Terminal) + `,`,
|
|
| 470 |
+ `FileLocks:` + fmt.Sprintf("%v", this.FileLocks) + `,`,
|
|
| 471 |
+ `EmptyNamespaces:` + fmt.Sprintf("%v", this.EmptyNamespaces) + `,`,
|
|
| 472 |
+ `CgroupsMode:` + fmt.Sprintf("%v", this.CgroupsMode) + `,`,
|
|
| 473 |
+ `ImagePath:` + fmt.Sprintf("%v", this.ImagePath) + `,`,
|
|
| 474 |
+ `WorkPath:` + fmt.Sprintf("%v", this.WorkPath) + `,`,
|
|
| 475 |
+ `}`, |
|
| 476 |
+ }, "") |
|
| 477 |
+ return s |
|
| 478 |
+} |
|
| 479 |
+func (this *ProcessDetails) String() string {
|
|
| 480 |
+ if this == nil {
|
|
| 481 |
+ return "nil" |
|
| 482 |
+ } |
|
| 483 |
+ s := strings.Join([]string{`&ProcessDetails{`,
|
|
| 484 |
+ `ExecID:` + fmt.Sprintf("%v", this.ExecID) + `,`,
|
|
| 485 |
+ `}`, |
|
| 486 |
+ }, "") |
|
| 487 |
+ return s |
|
| 488 |
+} |
|
| 489 |
+func valueToStringOci(v interface{}) string {
|
|
| 490 |
+ rv := reflect.ValueOf(v) |
|
| 491 |
+ if rv.IsNil() {
|
|
| 492 |
+ return "nil" |
|
| 493 |
+ } |
|
| 494 |
+ pv := reflect.Indirect(rv).Interface() |
|
| 495 |
+ return fmt.Sprintf("*%v", pv)
|
|
| 496 |
+} |
|
| 497 |
+func (m *Options) Unmarshal(dAtA []byte) error {
|
|
| 498 |
+ l := len(dAtA) |
|
| 499 |
+ iNdEx := 0 |
|
| 500 |
+ for iNdEx < l {
|
|
| 501 |
+ preIndex := iNdEx |
|
| 502 |
+ var wire uint64 |
|
| 503 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 504 |
+ if shift >= 64 {
|
|
| 505 |
+ return ErrIntOverflowOci |
|
| 506 |
+ } |
|
| 507 |
+ if iNdEx >= l {
|
|
| 508 |
+ return io.ErrUnexpectedEOF |
|
| 509 |
+ } |
|
| 510 |
+ b := dAtA[iNdEx] |
|
| 511 |
+ iNdEx++ |
|
| 512 |
+ wire |= (uint64(b) & 0x7F) << shift |
|
| 513 |
+ if b < 0x80 {
|
|
| 514 |
+ break |
|
| 515 |
+ } |
|
| 516 |
+ } |
|
| 517 |
+ fieldNum := int32(wire >> 3) |
|
| 518 |
+ wireType := int(wire & 0x7) |
|
| 519 |
+ if wireType == 4 {
|
|
| 520 |
+ return fmt.Errorf("proto: Options: wiretype end group for non-group")
|
|
| 521 |
+ } |
|
| 522 |
+ if fieldNum <= 0 {
|
|
| 523 |
+ return fmt.Errorf("proto: Options: illegal tag %d (wire type %d)", fieldNum, wire)
|
|
| 524 |
+ } |
|
| 525 |
+ switch fieldNum {
|
|
| 526 |
+ case 1: |
|
| 527 |
+ if wireType != 0 {
|
|
| 528 |
+ return fmt.Errorf("proto: wrong wireType = %d for field NoPivotRoot", wireType)
|
|
| 529 |
+ } |
|
| 530 |
+ var v int |
|
| 531 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 532 |
+ if shift >= 64 {
|
|
| 533 |
+ return ErrIntOverflowOci |
|
| 534 |
+ } |
|
| 535 |
+ if iNdEx >= l {
|
|
| 536 |
+ return io.ErrUnexpectedEOF |
|
| 537 |
+ } |
|
| 538 |
+ b := dAtA[iNdEx] |
|
| 539 |
+ iNdEx++ |
|
| 540 |
+ v |= (int(b) & 0x7F) << shift |
|
| 541 |
+ if b < 0x80 {
|
|
| 542 |
+ break |
|
| 543 |
+ } |
|
| 544 |
+ } |
|
| 545 |
+ m.NoPivotRoot = bool(v != 0) |
|
| 546 |
+ case 2: |
|
| 547 |
+ if wireType != 0 {
|
|
| 548 |
+ return fmt.Errorf("proto: wrong wireType = %d for field NoNewKeyring", wireType)
|
|
| 549 |
+ } |
|
| 550 |
+ var v int |
|
| 551 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 552 |
+ if shift >= 64 {
|
|
| 553 |
+ return ErrIntOverflowOci |
|
| 554 |
+ } |
|
| 555 |
+ if iNdEx >= l {
|
|
| 556 |
+ return io.ErrUnexpectedEOF |
|
| 557 |
+ } |
|
| 558 |
+ b := dAtA[iNdEx] |
|
| 559 |
+ iNdEx++ |
|
| 560 |
+ v |= (int(b) & 0x7F) << shift |
|
| 561 |
+ if b < 0x80 {
|
|
| 562 |
+ break |
|
| 563 |
+ } |
|
| 564 |
+ } |
|
| 565 |
+ m.NoNewKeyring = bool(v != 0) |
|
| 566 |
+ case 3: |
|
| 567 |
+ if wireType != 2 {
|
|
| 568 |
+ return fmt.Errorf("proto: wrong wireType = %d for field ShimCgroup", wireType)
|
|
| 569 |
+ } |
|
| 570 |
+ var stringLen uint64 |
|
| 571 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 572 |
+ if shift >= 64 {
|
|
| 573 |
+ return ErrIntOverflowOci |
|
| 574 |
+ } |
|
| 575 |
+ if iNdEx >= l {
|
|
| 576 |
+ return io.ErrUnexpectedEOF |
|
| 577 |
+ } |
|
| 578 |
+ b := dAtA[iNdEx] |
|
| 579 |
+ iNdEx++ |
|
| 580 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 581 |
+ if b < 0x80 {
|
|
| 582 |
+ break |
|
| 583 |
+ } |
|
| 584 |
+ } |
|
| 585 |
+ intStringLen := int(stringLen) |
|
| 586 |
+ if intStringLen < 0 {
|
|
| 587 |
+ return ErrInvalidLengthOci |
|
| 588 |
+ } |
|
| 589 |
+ postIndex := iNdEx + intStringLen |
|
| 590 |
+ if postIndex > l {
|
|
| 591 |
+ return io.ErrUnexpectedEOF |
|
| 592 |
+ } |
|
| 593 |
+ m.ShimCgroup = string(dAtA[iNdEx:postIndex]) |
|
| 594 |
+ iNdEx = postIndex |
|
| 595 |
+ case 4: |
|
| 596 |
+ if wireType != 0 {
|
|
| 597 |
+ return fmt.Errorf("proto: wrong wireType = %d for field IoUid", wireType)
|
|
| 598 |
+ } |
|
| 599 |
+ m.IoUid = 0 |
|
| 600 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 601 |
+ if shift >= 64 {
|
|
| 602 |
+ return ErrIntOverflowOci |
|
| 603 |
+ } |
|
| 604 |
+ if iNdEx >= l {
|
|
| 605 |
+ return io.ErrUnexpectedEOF |
|
| 606 |
+ } |
|
| 607 |
+ b := dAtA[iNdEx] |
|
| 608 |
+ iNdEx++ |
|
| 609 |
+ m.IoUid |= (uint32(b) & 0x7F) << shift |
|
| 610 |
+ if b < 0x80 {
|
|
| 611 |
+ break |
|
| 612 |
+ } |
|
| 613 |
+ } |
|
| 614 |
+ case 5: |
|
| 615 |
+ if wireType != 0 {
|
|
| 616 |
+ return fmt.Errorf("proto: wrong wireType = %d for field IoGid", wireType)
|
|
| 617 |
+ } |
|
| 618 |
+ m.IoGid = 0 |
|
| 619 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 620 |
+ if shift >= 64 {
|
|
| 621 |
+ return ErrIntOverflowOci |
|
| 622 |
+ } |
|
| 623 |
+ if iNdEx >= l {
|
|
| 624 |
+ return io.ErrUnexpectedEOF |
|
| 625 |
+ } |
|
| 626 |
+ b := dAtA[iNdEx] |
|
| 627 |
+ iNdEx++ |
|
| 628 |
+ m.IoGid |= (uint32(b) & 0x7F) << shift |
|
| 629 |
+ if b < 0x80 {
|
|
| 630 |
+ break |
|
| 631 |
+ } |
|
| 632 |
+ } |
|
| 633 |
+ case 6: |
|
| 634 |
+ if wireType != 2 {
|
|
| 635 |
+ return fmt.Errorf("proto: wrong wireType = %d for field BinaryName", wireType)
|
|
| 636 |
+ } |
|
| 637 |
+ var stringLen uint64 |
|
| 638 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 639 |
+ if shift >= 64 {
|
|
| 640 |
+ return ErrIntOverflowOci |
|
| 641 |
+ } |
|
| 642 |
+ if iNdEx >= l {
|
|
| 643 |
+ return io.ErrUnexpectedEOF |
|
| 644 |
+ } |
|
| 645 |
+ b := dAtA[iNdEx] |
|
| 646 |
+ iNdEx++ |
|
| 647 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 648 |
+ if b < 0x80 {
|
|
| 649 |
+ break |
|
| 650 |
+ } |
|
| 651 |
+ } |
|
| 652 |
+ intStringLen := int(stringLen) |
|
| 653 |
+ if intStringLen < 0 {
|
|
| 654 |
+ return ErrInvalidLengthOci |
|
| 655 |
+ } |
|
| 656 |
+ postIndex := iNdEx + intStringLen |
|
| 657 |
+ if postIndex > l {
|
|
| 658 |
+ return io.ErrUnexpectedEOF |
|
| 659 |
+ } |
|
| 660 |
+ m.BinaryName = string(dAtA[iNdEx:postIndex]) |
|
| 661 |
+ iNdEx = postIndex |
|
| 662 |
+ case 7: |
|
| 663 |
+ if wireType != 2 {
|
|
| 664 |
+ return fmt.Errorf("proto: wrong wireType = %d for field Root", wireType)
|
|
| 665 |
+ } |
|
| 666 |
+ var stringLen uint64 |
|
| 667 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 668 |
+ if shift >= 64 {
|
|
| 669 |
+ return ErrIntOverflowOci |
|
| 670 |
+ } |
|
| 671 |
+ if iNdEx >= l {
|
|
| 672 |
+ return io.ErrUnexpectedEOF |
|
| 673 |
+ } |
|
| 674 |
+ b := dAtA[iNdEx] |
|
| 675 |
+ iNdEx++ |
|
| 676 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 677 |
+ if b < 0x80 {
|
|
| 678 |
+ break |
|
| 679 |
+ } |
|
| 680 |
+ } |
|
| 681 |
+ intStringLen := int(stringLen) |
|
| 682 |
+ if intStringLen < 0 {
|
|
| 683 |
+ return ErrInvalidLengthOci |
|
| 684 |
+ } |
|
| 685 |
+ postIndex := iNdEx + intStringLen |
|
| 686 |
+ if postIndex > l {
|
|
| 687 |
+ return io.ErrUnexpectedEOF |
|
| 688 |
+ } |
|
| 689 |
+ m.Root = string(dAtA[iNdEx:postIndex]) |
|
| 690 |
+ iNdEx = postIndex |
|
| 691 |
+ case 8: |
|
| 692 |
+ if wireType != 2 {
|
|
| 693 |
+ return fmt.Errorf("proto: wrong wireType = %d for field CriuPath", wireType)
|
|
| 694 |
+ } |
|
| 695 |
+ var stringLen uint64 |
|
| 696 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 697 |
+ if shift >= 64 {
|
|
| 698 |
+ return ErrIntOverflowOci |
|
| 699 |
+ } |
|
| 700 |
+ if iNdEx >= l {
|
|
| 701 |
+ return io.ErrUnexpectedEOF |
|
| 702 |
+ } |
|
| 703 |
+ b := dAtA[iNdEx] |
|
| 704 |
+ iNdEx++ |
|
| 705 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 706 |
+ if b < 0x80 {
|
|
| 707 |
+ break |
|
| 708 |
+ } |
|
| 709 |
+ } |
|
| 710 |
+ intStringLen := int(stringLen) |
|
| 711 |
+ if intStringLen < 0 {
|
|
| 712 |
+ return ErrInvalidLengthOci |
|
| 713 |
+ } |
|
| 714 |
+ postIndex := iNdEx + intStringLen |
|
| 715 |
+ if postIndex > l {
|
|
| 716 |
+ return io.ErrUnexpectedEOF |
|
| 717 |
+ } |
|
| 718 |
+ m.CriuPath = string(dAtA[iNdEx:postIndex]) |
|
| 719 |
+ iNdEx = postIndex |
|
| 720 |
+ case 9: |
|
| 721 |
+ if wireType != 0 {
|
|
| 722 |
+ return fmt.Errorf("proto: wrong wireType = %d for field SystemdCgroup", wireType)
|
|
| 723 |
+ } |
|
| 724 |
+ var v int |
|
| 725 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 726 |
+ if shift >= 64 {
|
|
| 727 |
+ return ErrIntOverflowOci |
|
| 728 |
+ } |
|
| 729 |
+ if iNdEx >= l {
|
|
| 730 |
+ return io.ErrUnexpectedEOF |
|
| 731 |
+ } |
|
| 732 |
+ b := dAtA[iNdEx] |
|
| 733 |
+ iNdEx++ |
|
| 734 |
+ v |= (int(b) & 0x7F) << shift |
|
| 735 |
+ if b < 0x80 {
|
|
| 736 |
+ break |
|
| 737 |
+ } |
|
| 738 |
+ } |
|
| 739 |
+ m.SystemdCgroup = bool(v != 0) |
|
| 740 |
+ case 10: |
|
| 741 |
+ if wireType != 2 {
|
|
| 742 |
+ return fmt.Errorf("proto: wrong wireType = %d for field CriuImagePath", wireType)
|
|
| 743 |
+ } |
|
| 744 |
+ var stringLen uint64 |
|
| 745 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 746 |
+ if shift >= 64 {
|
|
| 747 |
+ return ErrIntOverflowOci |
|
| 748 |
+ } |
|
| 749 |
+ if iNdEx >= l {
|
|
| 750 |
+ return io.ErrUnexpectedEOF |
|
| 751 |
+ } |
|
| 752 |
+ b := dAtA[iNdEx] |
|
| 753 |
+ iNdEx++ |
|
| 754 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 755 |
+ if b < 0x80 {
|
|
| 756 |
+ break |
|
| 757 |
+ } |
|
| 758 |
+ } |
|
| 759 |
+ intStringLen := int(stringLen) |
|
| 760 |
+ if intStringLen < 0 {
|
|
| 761 |
+ return ErrInvalidLengthOci |
|
| 762 |
+ } |
|
| 763 |
+ postIndex := iNdEx + intStringLen |
|
| 764 |
+ if postIndex > l {
|
|
| 765 |
+ return io.ErrUnexpectedEOF |
|
| 766 |
+ } |
|
| 767 |
+ m.CriuImagePath = string(dAtA[iNdEx:postIndex]) |
|
| 768 |
+ iNdEx = postIndex |
|
| 769 |
+ case 11: |
|
| 770 |
+ if wireType != 2 {
|
|
| 771 |
+ return fmt.Errorf("proto: wrong wireType = %d for field CriuWorkPath", wireType)
|
|
| 772 |
+ } |
|
| 773 |
+ var stringLen uint64 |
|
| 774 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 775 |
+ if shift >= 64 {
|
|
| 776 |
+ return ErrIntOverflowOci |
|
| 777 |
+ } |
|
| 778 |
+ if iNdEx >= l {
|
|
| 779 |
+ return io.ErrUnexpectedEOF |
|
| 780 |
+ } |
|
| 781 |
+ b := dAtA[iNdEx] |
|
| 782 |
+ iNdEx++ |
|
| 783 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 784 |
+ if b < 0x80 {
|
|
| 785 |
+ break |
|
| 786 |
+ } |
|
| 787 |
+ } |
|
| 788 |
+ intStringLen := int(stringLen) |
|
| 789 |
+ if intStringLen < 0 {
|
|
| 790 |
+ return ErrInvalidLengthOci |
|
| 791 |
+ } |
|
| 792 |
+ postIndex := iNdEx + intStringLen |
|
| 793 |
+ if postIndex > l {
|
|
| 794 |
+ return io.ErrUnexpectedEOF |
|
| 795 |
+ } |
|
| 796 |
+ m.CriuWorkPath = string(dAtA[iNdEx:postIndex]) |
|
| 797 |
+ iNdEx = postIndex |
|
| 798 |
+ default: |
|
| 799 |
+ iNdEx = preIndex |
|
| 800 |
+ skippy, err := skipOci(dAtA[iNdEx:]) |
|
| 801 |
+ if err != nil {
|
|
| 802 |
+ return err |
|
| 803 |
+ } |
|
| 804 |
+ if skippy < 0 {
|
|
| 805 |
+ return ErrInvalidLengthOci |
|
| 806 |
+ } |
|
| 807 |
+ if (iNdEx + skippy) > l {
|
|
| 808 |
+ return io.ErrUnexpectedEOF |
|
| 809 |
+ } |
|
| 810 |
+ iNdEx += skippy |
|
| 811 |
+ } |
|
| 812 |
+ } |
|
| 813 |
+ |
|
| 814 |
+ if iNdEx > l {
|
|
| 815 |
+ return io.ErrUnexpectedEOF |
|
| 816 |
+ } |
|
| 817 |
+ return nil |
|
| 818 |
+} |
|
| 819 |
+func (m *CheckpointOptions) Unmarshal(dAtA []byte) error {
|
|
| 820 |
+ l := len(dAtA) |
|
| 821 |
+ iNdEx := 0 |
|
| 822 |
+ for iNdEx < l {
|
|
| 823 |
+ preIndex := iNdEx |
|
| 824 |
+ var wire uint64 |
|
| 825 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 826 |
+ if shift >= 64 {
|
|
| 827 |
+ return ErrIntOverflowOci |
|
| 828 |
+ } |
|
| 829 |
+ if iNdEx >= l {
|
|
| 830 |
+ return io.ErrUnexpectedEOF |
|
| 831 |
+ } |
|
| 832 |
+ b := dAtA[iNdEx] |
|
| 833 |
+ iNdEx++ |
|
| 834 |
+ wire |= (uint64(b) & 0x7F) << shift |
|
| 835 |
+ if b < 0x80 {
|
|
| 836 |
+ break |
|
| 837 |
+ } |
|
| 838 |
+ } |
|
| 839 |
+ fieldNum := int32(wire >> 3) |
|
| 840 |
+ wireType := int(wire & 0x7) |
|
| 841 |
+ if wireType == 4 {
|
|
| 842 |
+ return fmt.Errorf("proto: CheckpointOptions: wiretype end group for non-group")
|
|
| 843 |
+ } |
|
| 844 |
+ if fieldNum <= 0 {
|
|
| 845 |
+ return fmt.Errorf("proto: CheckpointOptions: illegal tag %d (wire type %d)", fieldNum, wire)
|
|
| 846 |
+ } |
|
| 847 |
+ switch fieldNum {
|
|
| 848 |
+ case 1: |
|
| 849 |
+ if wireType != 0 {
|
|
| 850 |
+ return fmt.Errorf("proto: wrong wireType = %d for field Exit", wireType)
|
|
| 851 |
+ } |
|
| 852 |
+ var v int |
|
| 853 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 854 |
+ if shift >= 64 {
|
|
| 855 |
+ return ErrIntOverflowOci |
|
| 856 |
+ } |
|
| 857 |
+ if iNdEx >= l {
|
|
| 858 |
+ return io.ErrUnexpectedEOF |
|
| 859 |
+ } |
|
| 860 |
+ b := dAtA[iNdEx] |
|
| 861 |
+ iNdEx++ |
|
| 862 |
+ v |= (int(b) & 0x7F) << shift |
|
| 863 |
+ if b < 0x80 {
|
|
| 864 |
+ break |
|
| 865 |
+ } |
|
| 866 |
+ } |
|
| 867 |
+ m.Exit = bool(v != 0) |
|
| 868 |
+ case 2: |
|
| 869 |
+ if wireType != 0 {
|
|
| 870 |
+ return fmt.Errorf("proto: wrong wireType = %d for field OpenTcp", wireType)
|
|
| 871 |
+ } |
|
| 872 |
+ var v int |
|
| 873 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 874 |
+ if shift >= 64 {
|
|
| 875 |
+ return ErrIntOverflowOci |
|
| 876 |
+ } |
|
| 877 |
+ if iNdEx >= l {
|
|
| 878 |
+ return io.ErrUnexpectedEOF |
|
| 879 |
+ } |
|
| 880 |
+ b := dAtA[iNdEx] |
|
| 881 |
+ iNdEx++ |
|
| 882 |
+ v |= (int(b) & 0x7F) << shift |
|
| 883 |
+ if b < 0x80 {
|
|
| 884 |
+ break |
|
| 885 |
+ } |
|
| 886 |
+ } |
|
| 887 |
+ m.OpenTcp = bool(v != 0) |
|
| 888 |
+ case 3: |
|
| 889 |
+ if wireType != 0 {
|
|
| 890 |
+ return fmt.Errorf("proto: wrong wireType = %d for field ExternalUnixSockets", wireType)
|
|
| 891 |
+ } |
|
| 892 |
+ var v int |
|
| 893 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 894 |
+ if shift >= 64 {
|
|
| 895 |
+ return ErrIntOverflowOci |
|
| 896 |
+ } |
|
| 897 |
+ if iNdEx >= l {
|
|
| 898 |
+ return io.ErrUnexpectedEOF |
|
| 899 |
+ } |
|
| 900 |
+ b := dAtA[iNdEx] |
|
| 901 |
+ iNdEx++ |
|
| 902 |
+ v |= (int(b) & 0x7F) << shift |
|
| 903 |
+ if b < 0x80 {
|
|
| 904 |
+ break |
|
| 905 |
+ } |
|
| 906 |
+ } |
|
| 907 |
+ m.ExternalUnixSockets = bool(v != 0) |
|
| 908 |
+ case 4: |
|
| 909 |
+ if wireType != 0 {
|
|
| 910 |
+ return fmt.Errorf("proto: wrong wireType = %d for field Terminal", wireType)
|
|
| 911 |
+ } |
|
| 912 |
+ var v int |
|
| 913 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 914 |
+ if shift >= 64 {
|
|
| 915 |
+ return ErrIntOverflowOci |
|
| 916 |
+ } |
|
| 917 |
+ if iNdEx >= l {
|
|
| 918 |
+ return io.ErrUnexpectedEOF |
|
| 919 |
+ } |
|
| 920 |
+ b := dAtA[iNdEx] |
|
| 921 |
+ iNdEx++ |
|
| 922 |
+ v |= (int(b) & 0x7F) << shift |
|
| 923 |
+ if b < 0x80 {
|
|
| 924 |
+ break |
|
| 925 |
+ } |
|
| 926 |
+ } |
|
| 927 |
+ m.Terminal = bool(v != 0) |
|
| 928 |
+ case 5: |
|
| 929 |
+ if wireType != 0 {
|
|
| 930 |
+ return fmt.Errorf("proto: wrong wireType = %d for field FileLocks", wireType)
|
|
| 931 |
+ } |
|
| 932 |
+ var v int |
|
| 933 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 934 |
+ if shift >= 64 {
|
|
| 935 |
+ return ErrIntOverflowOci |
|
| 936 |
+ } |
|
| 937 |
+ if iNdEx >= l {
|
|
| 938 |
+ return io.ErrUnexpectedEOF |
|
| 939 |
+ } |
|
| 940 |
+ b := dAtA[iNdEx] |
|
| 941 |
+ iNdEx++ |
|
| 942 |
+ v |= (int(b) & 0x7F) << shift |
|
| 943 |
+ if b < 0x80 {
|
|
| 944 |
+ break |
|
| 945 |
+ } |
|
| 946 |
+ } |
|
| 947 |
+ m.FileLocks = bool(v != 0) |
|
| 948 |
+ case 6: |
|
| 949 |
+ if wireType != 2 {
|
|
| 950 |
+ return fmt.Errorf("proto: wrong wireType = %d for field EmptyNamespaces", wireType)
|
|
| 951 |
+ } |
|
| 952 |
+ var stringLen uint64 |
|
| 953 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 954 |
+ if shift >= 64 {
|
|
| 955 |
+ return ErrIntOverflowOci |
|
| 956 |
+ } |
|
| 957 |
+ if iNdEx >= l {
|
|
| 958 |
+ return io.ErrUnexpectedEOF |
|
| 959 |
+ } |
|
| 960 |
+ b := dAtA[iNdEx] |
|
| 961 |
+ iNdEx++ |
|
| 962 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 963 |
+ if b < 0x80 {
|
|
| 964 |
+ break |
|
| 965 |
+ } |
|
| 966 |
+ } |
|
| 967 |
+ intStringLen := int(stringLen) |
|
| 968 |
+ if intStringLen < 0 {
|
|
| 969 |
+ return ErrInvalidLengthOci |
|
| 970 |
+ } |
|
| 971 |
+ postIndex := iNdEx + intStringLen |
|
| 972 |
+ if postIndex > l {
|
|
| 973 |
+ return io.ErrUnexpectedEOF |
|
| 974 |
+ } |
|
| 975 |
+ m.EmptyNamespaces = append(m.EmptyNamespaces, string(dAtA[iNdEx:postIndex])) |
|
| 976 |
+ iNdEx = postIndex |
|
| 977 |
+ case 7: |
|
| 978 |
+ if wireType != 2 {
|
|
| 979 |
+ return fmt.Errorf("proto: wrong wireType = %d for field CgroupsMode", wireType)
|
|
| 980 |
+ } |
|
| 981 |
+ var stringLen uint64 |
|
| 982 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 983 |
+ if shift >= 64 {
|
|
| 984 |
+ return ErrIntOverflowOci |
|
| 985 |
+ } |
|
| 986 |
+ if iNdEx >= l {
|
|
| 987 |
+ return io.ErrUnexpectedEOF |
|
| 988 |
+ } |
|
| 989 |
+ b := dAtA[iNdEx] |
|
| 990 |
+ iNdEx++ |
|
| 991 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 992 |
+ if b < 0x80 {
|
|
| 993 |
+ break |
|
| 994 |
+ } |
|
| 995 |
+ } |
|
| 996 |
+ intStringLen := int(stringLen) |
|
| 997 |
+ if intStringLen < 0 {
|
|
| 998 |
+ return ErrInvalidLengthOci |
|
| 999 |
+ } |
|
| 1000 |
+ postIndex := iNdEx + intStringLen |
|
| 1001 |
+ if postIndex > l {
|
|
| 1002 |
+ return io.ErrUnexpectedEOF |
|
| 1003 |
+ } |
|
| 1004 |
+ m.CgroupsMode = string(dAtA[iNdEx:postIndex]) |
|
| 1005 |
+ iNdEx = postIndex |
|
| 1006 |
+ case 8: |
|
| 1007 |
+ if wireType != 2 {
|
|
| 1008 |
+ return fmt.Errorf("proto: wrong wireType = %d for field ImagePath", wireType)
|
|
| 1009 |
+ } |
|
| 1010 |
+ var stringLen uint64 |
|
| 1011 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1012 |
+ if shift >= 64 {
|
|
| 1013 |
+ return ErrIntOverflowOci |
|
| 1014 |
+ } |
|
| 1015 |
+ if iNdEx >= l {
|
|
| 1016 |
+ return io.ErrUnexpectedEOF |
|
| 1017 |
+ } |
|
| 1018 |
+ b := dAtA[iNdEx] |
|
| 1019 |
+ iNdEx++ |
|
| 1020 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 1021 |
+ if b < 0x80 {
|
|
| 1022 |
+ break |
|
| 1023 |
+ } |
|
| 1024 |
+ } |
|
| 1025 |
+ intStringLen := int(stringLen) |
|
| 1026 |
+ if intStringLen < 0 {
|
|
| 1027 |
+ return ErrInvalidLengthOci |
|
| 1028 |
+ } |
|
| 1029 |
+ postIndex := iNdEx + intStringLen |
|
| 1030 |
+ if postIndex > l {
|
|
| 1031 |
+ return io.ErrUnexpectedEOF |
|
| 1032 |
+ } |
|
| 1033 |
+ m.ImagePath = string(dAtA[iNdEx:postIndex]) |
|
| 1034 |
+ iNdEx = postIndex |
|
| 1035 |
+ case 9: |
|
| 1036 |
+ if wireType != 2 {
|
|
| 1037 |
+ return fmt.Errorf("proto: wrong wireType = %d for field WorkPath", wireType)
|
|
| 1038 |
+ } |
|
| 1039 |
+ var stringLen uint64 |
|
| 1040 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1041 |
+ if shift >= 64 {
|
|
| 1042 |
+ return ErrIntOverflowOci |
|
| 1043 |
+ } |
|
| 1044 |
+ if iNdEx >= l {
|
|
| 1045 |
+ return io.ErrUnexpectedEOF |
|
| 1046 |
+ } |
|
| 1047 |
+ b := dAtA[iNdEx] |
|
| 1048 |
+ iNdEx++ |
|
| 1049 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 1050 |
+ if b < 0x80 {
|
|
| 1051 |
+ break |
|
| 1052 |
+ } |
|
| 1053 |
+ } |
|
| 1054 |
+ intStringLen := int(stringLen) |
|
| 1055 |
+ if intStringLen < 0 {
|
|
| 1056 |
+ return ErrInvalidLengthOci |
|
| 1057 |
+ } |
|
| 1058 |
+ postIndex := iNdEx + intStringLen |
|
| 1059 |
+ if postIndex > l {
|
|
| 1060 |
+ return io.ErrUnexpectedEOF |
|
| 1061 |
+ } |
|
| 1062 |
+ m.WorkPath = string(dAtA[iNdEx:postIndex]) |
|
| 1063 |
+ iNdEx = postIndex |
|
| 1064 |
+ default: |
|
| 1065 |
+ iNdEx = preIndex |
|
| 1066 |
+ skippy, err := skipOci(dAtA[iNdEx:]) |
|
| 1067 |
+ if err != nil {
|
|
| 1068 |
+ return err |
|
| 1069 |
+ } |
|
| 1070 |
+ if skippy < 0 {
|
|
| 1071 |
+ return ErrInvalidLengthOci |
|
| 1072 |
+ } |
|
| 1073 |
+ if (iNdEx + skippy) > l {
|
|
| 1074 |
+ return io.ErrUnexpectedEOF |
|
| 1075 |
+ } |
|
| 1076 |
+ iNdEx += skippy |
|
| 1077 |
+ } |
|
| 1078 |
+ } |
|
| 1079 |
+ |
|
| 1080 |
+ if iNdEx > l {
|
|
| 1081 |
+ return io.ErrUnexpectedEOF |
|
| 1082 |
+ } |
|
| 1083 |
+ return nil |
|
| 1084 |
+} |
|
| 1085 |
+func (m *ProcessDetails) Unmarshal(dAtA []byte) error {
|
|
| 1086 |
+ l := len(dAtA) |
|
| 1087 |
+ iNdEx := 0 |
|
| 1088 |
+ for iNdEx < l {
|
|
| 1089 |
+ preIndex := iNdEx |
|
| 1090 |
+ var wire uint64 |
|
| 1091 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1092 |
+ if shift >= 64 {
|
|
| 1093 |
+ return ErrIntOverflowOci |
|
| 1094 |
+ } |
|
| 1095 |
+ if iNdEx >= l {
|
|
| 1096 |
+ return io.ErrUnexpectedEOF |
|
| 1097 |
+ } |
|
| 1098 |
+ b := dAtA[iNdEx] |
|
| 1099 |
+ iNdEx++ |
|
| 1100 |
+ wire |= (uint64(b) & 0x7F) << shift |
|
| 1101 |
+ if b < 0x80 {
|
|
| 1102 |
+ break |
|
| 1103 |
+ } |
|
| 1104 |
+ } |
|
| 1105 |
+ fieldNum := int32(wire >> 3) |
|
| 1106 |
+ wireType := int(wire & 0x7) |
|
| 1107 |
+ if wireType == 4 {
|
|
| 1108 |
+ return fmt.Errorf("proto: ProcessDetails: wiretype end group for non-group")
|
|
| 1109 |
+ } |
|
| 1110 |
+ if fieldNum <= 0 {
|
|
| 1111 |
+ return fmt.Errorf("proto: ProcessDetails: illegal tag %d (wire type %d)", fieldNum, wire)
|
|
| 1112 |
+ } |
|
| 1113 |
+ switch fieldNum {
|
|
| 1114 |
+ case 1: |
|
| 1115 |
+ if wireType != 2 {
|
|
| 1116 |
+ return fmt.Errorf("proto: wrong wireType = %d for field ExecID", wireType)
|
|
| 1117 |
+ } |
|
| 1118 |
+ var stringLen uint64 |
|
| 1119 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1120 |
+ if shift >= 64 {
|
|
| 1121 |
+ return ErrIntOverflowOci |
|
| 1122 |
+ } |
|
| 1123 |
+ if iNdEx >= l {
|
|
| 1124 |
+ return io.ErrUnexpectedEOF |
|
| 1125 |
+ } |
|
| 1126 |
+ b := dAtA[iNdEx] |
|
| 1127 |
+ iNdEx++ |
|
| 1128 |
+ stringLen |= (uint64(b) & 0x7F) << shift |
|
| 1129 |
+ if b < 0x80 {
|
|
| 1130 |
+ break |
|
| 1131 |
+ } |
|
| 1132 |
+ } |
|
| 1133 |
+ intStringLen := int(stringLen) |
|
| 1134 |
+ if intStringLen < 0 {
|
|
| 1135 |
+ return ErrInvalidLengthOci |
|
| 1136 |
+ } |
|
| 1137 |
+ postIndex := iNdEx + intStringLen |
|
| 1138 |
+ if postIndex > l {
|
|
| 1139 |
+ return io.ErrUnexpectedEOF |
|
| 1140 |
+ } |
|
| 1141 |
+ m.ExecID = string(dAtA[iNdEx:postIndex]) |
|
| 1142 |
+ iNdEx = postIndex |
|
| 1143 |
+ default: |
|
| 1144 |
+ iNdEx = preIndex |
|
| 1145 |
+ skippy, err := skipOci(dAtA[iNdEx:]) |
|
| 1146 |
+ if err != nil {
|
|
| 1147 |
+ return err |
|
| 1148 |
+ } |
|
| 1149 |
+ if skippy < 0 {
|
|
| 1150 |
+ return ErrInvalidLengthOci |
|
| 1151 |
+ } |
|
| 1152 |
+ if (iNdEx + skippy) > l {
|
|
| 1153 |
+ return io.ErrUnexpectedEOF |
|
| 1154 |
+ } |
|
| 1155 |
+ iNdEx += skippy |
|
| 1156 |
+ } |
|
| 1157 |
+ } |
|
| 1158 |
+ |
|
| 1159 |
+ if iNdEx > l {
|
|
| 1160 |
+ return io.ErrUnexpectedEOF |
|
| 1161 |
+ } |
|
| 1162 |
+ return nil |
|
| 1163 |
+} |
|
| 1164 |
+func skipOci(dAtA []byte) (n int, err error) {
|
|
| 1165 |
+ l := len(dAtA) |
|
| 1166 |
+ iNdEx := 0 |
|
| 1167 |
+ for iNdEx < l {
|
|
| 1168 |
+ var wire uint64 |
|
| 1169 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1170 |
+ if shift >= 64 {
|
|
| 1171 |
+ return 0, ErrIntOverflowOci |
|
| 1172 |
+ } |
|
| 1173 |
+ if iNdEx >= l {
|
|
| 1174 |
+ return 0, io.ErrUnexpectedEOF |
|
| 1175 |
+ } |
|
| 1176 |
+ b := dAtA[iNdEx] |
|
| 1177 |
+ iNdEx++ |
|
| 1178 |
+ wire |= (uint64(b) & 0x7F) << shift |
|
| 1179 |
+ if b < 0x80 {
|
|
| 1180 |
+ break |
|
| 1181 |
+ } |
|
| 1182 |
+ } |
|
| 1183 |
+ wireType := int(wire & 0x7) |
|
| 1184 |
+ switch wireType {
|
|
| 1185 |
+ case 0: |
|
| 1186 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1187 |
+ if shift >= 64 {
|
|
| 1188 |
+ return 0, ErrIntOverflowOci |
|
| 1189 |
+ } |
|
| 1190 |
+ if iNdEx >= l {
|
|
| 1191 |
+ return 0, io.ErrUnexpectedEOF |
|
| 1192 |
+ } |
|
| 1193 |
+ iNdEx++ |
|
| 1194 |
+ if dAtA[iNdEx-1] < 0x80 {
|
|
| 1195 |
+ break |
|
| 1196 |
+ } |
|
| 1197 |
+ } |
|
| 1198 |
+ return iNdEx, nil |
|
| 1199 |
+ case 1: |
|
| 1200 |
+ iNdEx += 8 |
|
| 1201 |
+ return iNdEx, nil |
|
| 1202 |
+ case 2: |
|
| 1203 |
+ var length int |
|
| 1204 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1205 |
+ if shift >= 64 {
|
|
| 1206 |
+ return 0, ErrIntOverflowOci |
|
| 1207 |
+ } |
|
| 1208 |
+ if iNdEx >= l {
|
|
| 1209 |
+ return 0, io.ErrUnexpectedEOF |
|
| 1210 |
+ } |
|
| 1211 |
+ b := dAtA[iNdEx] |
|
| 1212 |
+ iNdEx++ |
|
| 1213 |
+ length |= (int(b) & 0x7F) << shift |
|
| 1214 |
+ if b < 0x80 {
|
|
| 1215 |
+ break |
|
| 1216 |
+ } |
|
| 1217 |
+ } |
|
| 1218 |
+ iNdEx += length |
|
| 1219 |
+ if length < 0 {
|
|
| 1220 |
+ return 0, ErrInvalidLengthOci |
|
| 1221 |
+ } |
|
| 1222 |
+ return iNdEx, nil |
|
| 1223 |
+ case 3: |
|
| 1224 |
+ for {
|
|
| 1225 |
+ var innerWire uint64 |
|
| 1226 |
+ var start int = iNdEx |
|
| 1227 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 1228 |
+ if shift >= 64 {
|
|
| 1229 |
+ return 0, ErrIntOverflowOci |
|
| 1230 |
+ } |
|
| 1231 |
+ if iNdEx >= l {
|
|
| 1232 |
+ return 0, io.ErrUnexpectedEOF |
|
| 1233 |
+ } |
|
| 1234 |
+ b := dAtA[iNdEx] |
|
| 1235 |
+ iNdEx++ |
|
| 1236 |
+ innerWire |= (uint64(b) & 0x7F) << shift |
|
| 1237 |
+ if b < 0x80 {
|
|
| 1238 |
+ break |
|
| 1239 |
+ } |
|
| 1240 |
+ } |
|
| 1241 |
+ innerWireType := int(innerWire & 0x7) |
|
| 1242 |
+ if innerWireType == 4 {
|
|
| 1243 |
+ break |
|
| 1244 |
+ } |
|
| 1245 |
+ next, err := skipOci(dAtA[start:]) |
|
| 1246 |
+ if err != nil {
|
|
| 1247 |
+ return 0, err |
|
| 1248 |
+ } |
|
| 1249 |
+ iNdEx = start + next |
|
| 1250 |
+ } |
|
| 1251 |
+ return iNdEx, nil |
|
| 1252 |
+ case 4: |
|
| 1253 |
+ return iNdEx, nil |
|
| 1254 |
+ case 5: |
|
| 1255 |
+ iNdEx += 4 |
|
| 1256 |
+ return iNdEx, nil |
|
| 1257 |
+ default: |
|
| 1258 |
+ return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
|
| 1259 |
+ } |
|
| 1260 |
+ } |
|
| 1261 |
+ panic("unreachable")
|
|
| 1262 |
+} |
|
| 1263 |
+ |
|
| 1264 |
+var ( |
|
| 1265 |
+ ErrInvalidLengthOci = fmt.Errorf("proto: negative length found during unmarshaling")
|
|
| 1266 |
+ ErrIntOverflowOci = fmt.Errorf("proto: integer overflow")
|
|
| 1267 |
+) |
|
| 1268 |
+ |
|
| 1269 |
+func init() {
|
|
| 1270 |
+ proto.RegisterFile("github.com/containerd/containerd/runtime/v2/runc/options/oci.proto", fileDescriptorOci)
|
|
| 1271 |
+} |
|
| 1272 |
+ |
|
| 1273 |
+var fileDescriptorOci = []byte{
|
|
| 1274 |
+ // 587 bytes of a gzipped FileDescriptorProto |
|
| 1275 |
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0xcf, 0x6e, 0xd3, 0x40, |
|
| 1276 |
+ 0x10, 0x87, 0xeb, 0xfe, 0x49, 0xec, 0x4d, 0x93, 0xc2, 0x42, 0x25, 0xd3, 0x8a, 0x34, 0x94, 0x82, |
|
| 1277 |
+ 0xc2, 0x25, 0x11, 0x45, 0x9c, 0xb8, 0xa0, 0xb6, 0x08, 0x55, 0x40, 0xa9, 0x0c, 0x15, 0xa8, 0x97, |
|
| 1278 |
+ 0x95, 0xbb, 0x1e, 0x9c, 0x51, 0xe2, 0x1d, 0xcb, 0xbb, 0x69, 0xd2, 0x1b, 0xef, 0xc5, 0x0b, 0xf4, |
|
| 1279 |
+ 0xc8, 0x91, 0x13, 0xa2, 0xb9, 0xf1, 0x16, 0x68, 0xd7, 0x4e, 0xdb, 0x33, 0x27, 0xcf, 0x7e, 0xf3, |
|
| 1280 |
+ 0xf3, 0x78, 0xfd, 0xad, 0x96, 0xed, 0xa5, 0x68, 0x06, 0xe3, 0xb3, 0x9e, 0xa4, 0xac, 0x2f, 0x49, |
|
| 1281 |
+ 0x99, 0x18, 0x15, 0x14, 0xc9, 0xed, 0xb2, 0x18, 0x2b, 0x83, 0x19, 0xf4, 0xcf, 0x77, 0x6d, 0x29, |
|
| 1282 |
+ 0xfb, 0x94, 0x1b, 0x24, 0xa5, 0xfb, 0x24, 0xb1, 0x97, 0x17, 0x64, 0x88, 0xf3, 0x9b, 0x74, 0xcf, |
|
| 1283 |
+ 0x46, 0x7a, 0xe7, 0xcf, 0x37, 0xee, 0xa7, 0x94, 0x92, 0x6b, 0xf7, 0x6d, 0x55, 0x26, 0xb7, 0xff, |
|
| 1284 |
+ 0x2e, 0xb2, 0xfa, 0xc7, 0xf2, 0x7d, 0xbe, 0xcd, 0x9a, 0x8a, 0x44, 0x8e, 0xe7, 0x64, 0x44, 0x41, |
|
| 1285 |
+ 0x64, 0x42, 0xaf, 0xe3, 0x75, 0xfd, 0xa8, 0xa1, 0xe8, 0xd8, 0xb2, 0x88, 0xc8, 0xf0, 0x1d, 0xd6, |
|
| 1286 |
+ 0x52, 0x24, 0x14, 0x4c, 0xc4, 0x10, 0x2e, 0x0a, 0x54, 0x69, 0xb8, 0xe8, 0x42, 0xab, 0x8a, 0x8e, |
|
| 1287 |
+ 0x60, 0xf2, 0xae, 0x64, 0x7c, 0x8b, 0x35, 0xf4, 0x00, 0x33, 0x21, 0xd3, 0x82, 0xc6, 0x79, 0xb8, |
|
| 1288 |
+ 0xd4, 0xf1, 0xba, 0x41, 0xc4, 0x2c, 0xda, 0x77, 0x84, 0xaf, 0xb3, 0x1a, 0x92, 0x18, 0x63, 0x12, |
|
| 1289 |
+ 0x2e, 0x77, 0xbc, 0x6e, 0x33, 0x5a, 0x41, 0x3a, 0xc1, 0xa4, 0xc2, 0x29, 0x26, 0xe1, 0xca, 0x1c, |
|
| 1290 |
+ 0xbf, 0xc5, 0xc4, 0x8e, 0x3b, 0x43, 0x15, 0x17, 0x17, 0x42, 0xc5, 0x19, 0x84, 0xb5, 0x72, 0x5c, |
|
| 1291 |
+ 0x89, 0x8e, 0xe2, 0x0c, 0x38, 0x67, 0xcb, 0x6e, 0xc3, 0x75, 0xd7, 0x71, 0x35, 0xdf, 0x64, 0x81, |
|
| 1292 |
+ 0x2c, 0x70, 0x2c, 0xf2, 0xd8, 0x0c, 0x42, 0xdf, 0x35, 0x7c, 0x0b, 0x8e, 0x63, 0x33, 0xe0, 0x4f, |
|
| 1293 |
+ 0x58, 0x4b, 0x5f, 0x68, 0x03, 0x59, 0x32, 0xdf, 0x63, 0xe0, 0x7e, 0xa3, 0x59, 0xd1, 0x6a, 0x9b, |
|
| 1294 |
+ 0x4f, 0xd9, 0x9a, 0x9b, 0x81, 0x59, 0x9c, 0x42, 0x39, 0x89, 0xb9, 0x49, 0x4d, 0x8b, 0x0f, 0x2d, |
|
| 1295 |
+ 0x75, 0xe3, 0x76, 0x58, 0xcb, 0xe5, 0x26, 0x54, 0x0c, 0xcb, 0x58, 0xc3, 0xc5, 0x56, 0x2d, 0xfd, |
|
| 1296 |
+ 0x42, 0xc5, 0xd0, 0xa6, 0xb6, 0x7f, 0x2c, 0xb2, 0xbb, 0xfb, 0x03, 0x90, 0xc3, 0x9c, 0x50, 0x99, |
|
| 1297 |
+ 0xb9, 0x75, 0xce, 0x96, 0x61, 0x8a, 0x73, 0xd9, 0xae, 0xe6, 0x0f, 0x98, 0x4f, 0x39, 0x28, 0x61, |
|
| 1298 |
+ 0x64, 0x5e, 0xf9, 0xad, 0xdb, 0xf5, 0x67, 0x99, 0xf3, 0x5d, 0xb6, 0x0e, 0x53, 0x03, 0x85, 0x8a, |
|
| 1299 |
+ 0x47, 0x62, 0xac, 0x70, 0x2a, 0x34, 0xc9, 0x21, 0x18, 0xed, 0x24, 0xfb, 0xd1, 0xbd, 0x79, 0xf3, |
|
| 1300 |
+ 0x44, 0xe1, 0xf4, 0x53, 0xd9, 0xe2, 0x1b, 0xcc, 0x37, 0x50, 0x64, 0xa8, 0xe2, 0x91, 0xf3, 0xed, |
|
| 1301 |
+ 0x47, 0xd7, 0x6b, 0xfe, 0x90, 0xb1, 0x6f, 0x38, 0x02, 0x31, 0x22, 0x39, 0xd4, 0x4e, 0xbb, 0x1f, |
|
| 1302 |
+ 0x05, 0x96, 0xbc, 0xb7, 0x80, 0x3f, 0x63, 0x77, 0x20, 0xcb, 0x4d, 0x69, 0x5e, 0xe7, 0xb1, 0x04, |
|
| 1303 |
+ 0x1d, 0xd6, 0x3a, 0x4b, 0xdd, 0x20, 0x5a, 0x73, 0xfc, 0xe8, 0x1a, 0xf3, 0x47, 0x6c, 0xb5, 0x74, |
|
| 1304 |
+ 0xa9, 0x45, 0x46, 0x09, 0x54, 0x87, 0xd1, 0xa8, 0xd8, 0x07, 0x4a, 0xc0, 0x7e, 0xec, 0x96, 0xca, |
|
| 1305 |
+ 0xf2, 0x50, 0x02, 0xbc, 0xd6, 0xb8, 0xc9, 0x82, 0x1b, 0x83, 0x41, 0x79, 0x64, 0x93, 0xb9, 0xbd, |
|
| 1306 |
+ 0x97, 0xac, 0x75, 0x5c, 0x90, 0x04, 0xad, 0x0f, 0xc0, 0xc4, 0x38, 0xd2, 0xfc, 0x31, 0xab, 0xc3, |
|
| 1307 |
+ 0x14, 0xa4, 0xc0, 0xc4, 0xc9, 0x0b, 0xf6, 0xd8, 0xec, 0xf7, 0x56, 0xed, 0xcd, 0x14, 0xe4, 0xe1, |
|
| 1308 |
+ 0x41, 0x54, 0xb3, 0xad, 0xc3, 0x64, 0xef, 0xf4, 0xf2, 0xaa, 0xbd, 0xf0, 0xeb, 0xaa, 0xbd, 0xf0, |
|
| 1309 |
+ 0x7d, 0xd6, 0xf6, 0x2e, 0x67, 0x6d, 0xef, 0xe7, 0xac, 0xed, 0xfd, 0x99, 0xb5, 0xbd, 0xd3, 0xd7, |
|
| 1310 |
+ 0xff, 0x7b, 0xd1, 0x5e, 0x55, 0xcf, 0xaf, 0x0b, 0x67, 0x35, 0x77, 0x8b, 0x5e, 0xfc, 0x0b, 0x00, |
|
| 1311 |
+ 0x00, 0xff, 0xff, 0x90, 0x50, 0x79, 0xf2, 0xb5, 0x03, 0x00, 0x00, |
|
| 1312 |
+} |
| 0 | 1313 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,58 @@ |
| 0 |
+syntax = "proto3"; |
|
| 1 |
+ |
|
| 2 |
+package containerd.runc.v1; |
|
| 3 |
+ |
|
| 4 |
+import weak "gogoproto/gogo.proto"; |
|
| 5 |
+ |
|
| 6 |
+option go_package = "github.com/containerd/containerd/runtime/v2/runc/options;options"; |
|
| 7 |
+ |
|
| 8 |
+message Options {
|
|
| 9 |
+ // disable pivot root when creating a container |
|
| 10 |
+ bool no_pivot_root = 1; |
|
| 11 |
+ // create a new keyring for the container |
|
| 12 |
+ bool no_new_keyring = 2; |
|
| 13 |
+ // place the shim in a cgroup |
|
| 14 |
+ string shim_cgroup = 3; |
|
| 15 |
+ // set the I/O's pipes uid |
|
| 16 |
+ uint32 io_uid = 4; |
|
| 17 |
+ // set the I/O's pipes gid |
|
| 18 |
+ uint32 io_gid = 5; |
|
| 19 |
+ // binary name of the runc binary |
|
| 20 |
+ string binary_name = 6; |
|
| 21 |
+ // runc root directory |
|
| 22 |
+ string root = 7; |
|
| 23 |
+ // criu binary path |
|
| 24 |
+ string criu_path = 8; |
|
| 25 |
+ // enable systemd cgroups |
|
| 26 |
+ bool systemd_cgroup = 9; |
|
| 27 |
+ // criu image path |
|
| 28 |
+ string criu_image_path = 10; |
|
| 29 |
+ // criu work path |
|
| 30 |
+ string criu_work_path = 11; |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+message CheckpointOptions {
|
|
| 34 |
+ // exit the container after a checkpoint |
|
| 35 |
+ bool exit = 1; |
|
| 36 |
+ // checkpoint open tcp connections |
|
| 37 |
+ bool open_tcp = 2; |
|
| 38 |
+ // checkpoint external unix sockets |
|
| 39 |
+ bool external_unix_sockets = 3; |
|
| 40 |
+ // checkpoint terminals (ptys) |
|
| 41 |
+ bool terminal = 4; |
|
| 42 |
+ // allow checkpointing of file locks |
|
| 43 |
+ bool file_locks = 5; |
|
| 44 |
+ // restore provided namespaces as empty namespaces |
|
| 45 |
+ repeated string empty_namespaces = 6; |
|
| 46 |
+ // set the cgroups mode, soft, full, strict |
|
| 47 |
+ string cgroups_mode = 7; |
|
| 48 |
+ // checkpoint image path |
|
| 49 |
+ string image_path = 8; |
|
| 50 |
+ // checkpoint work path |
|
| 51 |
+ string work_path = 9; |
|
| 52 |
+} |
|
| 53 |
+ |
|
| 54 |
+message ProcessDetails {
|
|
| 55 |
+ // exec process id if the process is managed by a shim |
|
| 56 |
+ string exec_id = 1; |
|
| 57 |
+} |
| ... | ... |
@@ -83,6 +83,44 @@ type ProxyPlugin struct {
|
| 83 | 83 |
Address string `toml:"address"` |
| 84 | 84 |
} |
| 85 | 85 |
|
| 86 |
+// BoltConfig defines the configuration values for the bolt plugin, which is |
|
| 87 |
+// loaded here, rather than back registered in the metadata package. |
|
| 88 |
+type BoltConfig struct {
|
|
| 89 |
+ // ContentSharingPolicy sets the sharing policy for content between |
|
| 90 |
+ // namespaces. |
|
| 91 |
+ // |
|
| 92 |
+ // The default mode "shared" will make blobs available in all |
|
| 93 |
+ // namespaces once it is pulled into any namespace. The blob will be pulled |
|
| 94 |
+ // into the namespace if a writer is opened with the "Expected" digest that |
|
| 95 |
+ // is already present in the backend. |
|
| 96 |
+ // |
|
| 97 |
+ // The alternative mode, "isolated" requires that clients prove they have |
|
| 98 |
+ // access to the content by providing all of the content to the ingest |
|
| 99 |
+ // before the blob is added to the namespace. |
|
| 100 |
+ // |
|
| 101 |
+ // Both modes share backing data, while "shared" will reduce total |
|
| 102 |
+ // bandwidth across namespaces, at the cost of allowing access to any blob |
|
| 103 |
+ // just by knowing its digest. |
|
| 104 |
+ ContentSharingPolicy string `toml:"content_sharing_policy"` |
|
| 105 |
+} |
|
| 106 |
+ |
|
| 107 |
+const ( |
|
| 108 |
+ // SharingPolicyShared represents the "shared" sharing policy |
|
| 109 |
+ SharingPolicyShared = "shared" |
|
| 110 |
+ // SharingPolicyIsolated represents the "isolated" sharing policy |
|
| 111 |
+ SharingPolicyIsolated = "isolated" |
|
| 112 |
+) |
|
| 113 |
+ |
|
| 114 |
+// Validate validates if BoltConfig is valid |
|
| 115 |
+func (bc *BoltConfig) Validate() error {
|
|
| 116 |
+ switch bc.ContentSharingPolicy {
|
|
| 117 |
+ case SharingPolicyShared, SharingPolicyIsolated: |
|
| 118 |
+ return nil |
|
| 119 |
+ default: |
|
| 120 |
+ return errors.Wrapf(errdefs.ErrInvalidArgument, "unknown policy: %s", bc.ContentSharingPolicy) |
|
| 121 |
+ } |
|
| 122 |
+} |
|
| 123 |
+ |
|
| 86 | 124 |
// Decode unmarshals a plugin specific configuration by plugin id |
| 87 | 125 |
func (c *Config) Decode(id string, v interface{}) (interface{}, error) {
|
| 88 | 126 |
data, ok := c.Plugins[id] |
| 89 | 127 |
deleted file mode 100644 |
| ... | ... |
@@ -1,60 +0,0 @@ |
| 1 |
-/* |
|
| 2 |
- Copyright The containerd Authors. |
|
| 3 |
- |
|
| 4 |
- Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
- you may not use this file except in compliance with the License. |
|
| 6 |
- You may obtain a copy of the License at |
|
| 7 |
- |
|
| 8 |
- http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
- |
|
| 10 |
- Unless required by applicable law or agreed to in writing, software |
|
| 11 |
- distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
- See the License for the specific language governing permissions and |
|
| 14 |
- limitations under the License. |
|
| 15 |
-*/ |
|
| 16 |
- |
|
| 17 |
-package containerd |
|
| 18 |
- |
|
| 19 |
-import ( |
|
| 20 |
- "syscall" |
|
| 21 |
- |
|
| 22 |
- "golang.org/x/sys/unix" |
|
| 23 |
-) |
|
| 24 |
- |
|
| 25 |
-var signalMap = map[string]syscall.Signal{
|
|
| 26 |
- "ABRT": unix.SIGABRT, |
|
| 27 |
- "ALRM": unix.SIGALRM, |
|
| 28 |
- "BUS": unix.SIGBUS, |
|
| 29 |
- "CHLD": unix.SIGCHLD, |
|
| 30 |
- "CLD": unix.SIGCLD, |
|
| 31 |
- "CONT": unix.SIGCONT, |
|
| 32 |
- "FPE": unix.SIGFPE, |
|
| 33 |
- "HUP": unix.SIGHUP, |
|
| 34 |
- "ILL": unix.SIGILL, |
|
| 35 |
- "INT": unix.SIGINT, |
|
| 36 |
- "IO": unix.SIGIO, |
|
| 37 |
- "IOT": unix.SIGIOT, |
|
| 38 |
- "KILL": unix.SIGKILL, |
|
| 39 |
- "PIPE": unix.SIGPIPE, |
|
| 40 |
- "POLL": unix.SIGPOLL, |
|
| 41 |
- "PROF": unix.SIGPROF, |
|
| 42 |
- "PWR": unix.SIGPWR, |
|
| 43 |
- "QUIT": unix.SIGQUIT, |
|
| 44 |
- "SEGV": unix.SIGSEGV, |
|
| 45 |
- "STKFLT": unix.SIGSTKFLT, |
|
| 46 |
- "STOP": unix.SIGSTOP, |
|
| 47 |
- "SYS": unix.SIGSYS, |
|
| 48 |
- "TERM": unix.SIGTERM, |
|
| 49 |
- "TRAP": unix.SIGTRAP, |
|
| 50 |
- "TSTP": unix.SIGTSTP, |
|
| 51 |
- "TTIN": unix.SIGTTIN, |
|
| 52 |
- "TTOU": unix.SIGTTOU, |
|
| 53 |
- "URG": unix.SIGURG, |
|
| 54 |
- "USR1": unix.SIGUSR1, |
|
| 55 |
- "USR2": unix.SIGUSR2, |
|
| 56 |
- "VTALRM": unix.SIGVTALRM, |
|
| 57 |
- "WINCH": unix.SIGWINCH, |
|
| 58 |
- "XCPU": unix.SIGXCPU, |
|
| 59 |
- "XFSZ": unix.SIGXFSZ, |
|
| 60 |
-} |
| 61 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,58 +0,0 @@ |
| 1 |
-// +build darwin freebsd solaris |
|
| 2 |
- |
|
| 3 |
-/* |
|
| 4 |
- Copyright The containerd Authors. |
|
| 5 |
- |
|
| 6 |
- Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 7 |
- you may not use this file except in compliance with the License. |
|
| 8 |
- You may obtain a copy of the License at |
|
| 9 |
- |
|
| 10 |
- http://www.apache.org/licenses/LICENSE-2.0 |
|
| 11 |
- |
|
| 12 |
- Unless required by applicable law or agreed to in writing, software |
|
| 13 |
- distributed under the License is distributed on an "AS IS" BASIS, |
|
| 14 |
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 15 |
- See the License for the specific language governing permissions and |
|
| 16 |
- limitations under the License. |
|
| 17 |
-*/ |
|
| 18 |
- |
|
| 19 |
-package containerd |
|
| 20 |
- |
|
| 21 |
-import ( |
|
| 22 |
- "syscall" |
|
| 23 |
- |
|
| 24 |
- "golang.org/x/sys/unix" |
|
| 25 |
-) |
|
| 26 |
- |
|
| 27 |
-var signalMap = map[string]syscall.Signal{
|
|
| 28 |
- "ABRT": unix.SIGABRT, |
|
| 29 |
- "ALRM": unix.SIGALRM, |
|
| 30 |
- "BUS": unix.SIGBUS, |
|
| 31 |
- "CHLD": unix.SIGCHLD, |
|
| 32 |
- "CONT": unix.SIGCONT, |
|
| 33 |
- "FPE": unix.SIGFPE, |
|
| 34 |
- "HUP": unix.SIGHUP, |
|
| 35 |
- "ILL": unix.SIGILL, |
|
| 36 |
- "INT": unix.SIGINT, |
|
| 37 |
- "IO": unix.SIGIO, |
|
| 38 |
- "IOT": unix.SIGIOT, |
|
| 39 |
- "KILL": unix.SIGKILL, |
|
| 40 |
- "PIPE": unix.SIGPIPE, |
|
| 41 |
- "PROF": unix.SIGPROF, |
|
| 42 |
- "QUIT": unix.SIGQUIT, |
|
| 43 |
- "SEGV": unix.SIGSEGV, |
|
| 44 |
- "STOP": unix.SIGSTOP, |
|
| 45 |
- "SYS": unix.SIGSYS, |
|
| 46 |
- "TERM": unix.SIGTERM, |
|
| 47 |
- "TRAP": unix.SIGTRAP, |
|
| 48 |
- "TSTP": unix.SIGTSTP, |
|
| 49 |
- "TTIN": unix.SIGTTIN, |
|
| 50 |
- "TTOU": unix.SIGTTOU, |
|
| 51 |
- "URG": unix.SIGURG, |
|
| 52 |
- "USR1": unix.SIGUSR1, |
|
| 53 |
- "USR2": unix.SIGUSR2, |
|
| 54 |
- "VTALRM": unix.SIGVTALRM, |
|
| 55 |
- "WINCH": unix.SIGWINCH, |
|
| 56 |
- "XCPU": unix.SIGXCPU, |
|
| 57 |
- "XFSZ": unix.SIGXFSZ, |
|
| 58 |
-} |
| 59 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,39 +0,0 @@ |
| 1 |
-/* |
|
| 2 |
- Copyright The containerd Authors. |
|
| 3 |
- |
|
| 4 |
- Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 |
- you may not use this file except in compliance with the License. |
|
| 6 |
- You may obtain a copy of the License at |
|
| 7 |
- |
|
| 8 |
- http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 |
- |
|
| 10 |
- Unless required by applicable law or agreed to in writing, software |
|
| 11 |
- distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 |
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 |
- See the License for the specific language governing permissions and |
|
| 14 |
- limitations under the License. |
|
| 15 |
-*/ |
|
| 16 |
- |
|
| 17 |
-package containerd |
|
| 18 |
- |
|
| 19 |
-import ( |
|
| 20 |
- "syscall" |
|
| 21 |
- |
|
| 22 |
- "golang.org/x/sys/windows" |
|
| 23 |
-) |
|
| 24 |
- |
|
| 25 |
-var signalMap = map[string]syscall.Signal{
|
|
| 26 |
- "HUP": syscall.Signal(windows.SIGHUP), |
|
| 27 |
- "INT": syscall.Signal(windows.SIGINT), |
|
| 28 |
- "QUIT": syscall.Signal(windows.SIGQUIT), |
|
| 29 |
- "SIGILL": syscall.Signal(windows.SIGILL), |
|
| 30 |
- "TRAP": syscall.Signal(windows.SIGTRAP), |
|
| 31 |
- "ABRT": syscall.Signal(windows.SIGABRT), |
|
| 32 |
- "BUS": syscall.Signal(windows.SIGBUS), |
|
| 33 |
- "FPE": syscall.Signal(windows.SIGFPE), |
|
| 34 |
- "KILL": syscall.Signal(windows.SIGKILL), |
|
| 35 |
- "SEGV": syscall.Signal(windows.SIGSEGV), |
|
| 36 |
- "PIPE": syscall.Signal(windows.SIGPIPE), |
|
| 37 |
- "ALRM": syscall.Signal(windows.SIGALRM), |
|
| 38 |
- "TERM": syscall.Signal(windows.SIGTERM), |
|
| 39 |
-} |
| ... | ... |
@@ -20,13 +20,11 @@ import ( |
| 20 | 20 |
"context" |
| 21 | 21 |
"encoding/json" |
| 22 | 22 |
"fmt" |
| 23 |
- "strconv" |
|
| 24 |
- "strings" |
|
| 25 | 23 |
"syscall" |
| 26 | 24 |
|
| 27 | 25 |
"github.com/containerd/containerd/content" |
| 28 | 26 |
"github.com/containerd/containerd/images" |
| 29 |
- "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 27 |
+ v1 "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 30 | 28 |
) |
| 31 | 29 |
|
| 32 | 30 |
// StopSignalLabel is a well-known containerd label for storing the stop |
| ... | ... |
@@ -83,23 +81,3 @@ func GetOCIStopSignal(ctx context.Context, image Image, defaultSignal string) (s |
| 83 | 83 |
|
| 84 | 84 |
return config.StopSignal, nil |
| 85 | 85 |
} |
| 86 |
- |
|
| 87 |
-// ParseSignal parses a given string into a syscall.Signal |
|
| 88 |
-// it checks that the signal exists in the platform-appropriate signalMap |
|
| 89 |
-func ParseSignal(rawSignal string) (syscall.Signal, error) {
|
|
| 90 |
- s, err := strconv.Atoi(rawSignal) |
|
| 91 |
- if err == nil {
|
|
| 92 |
- sig := syscall.Signal(s) |
|
| 93 |
- for _, msig := range signalMap {
|
|
| 94 |
- if sig == msig {
|
|
| 95 |
- return sig, nil |
|
| 96 |
- } |
|
| 97 |
- } |
|
| 98 |
- return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
|
| 99 |
- } |
|
| 100 |
- signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")] |
|
| 101 |
- if !ok {
|
|
| 102 |
- return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
|
| 103 |
- } |
|
| 104 |
- return signal, nil |
|
| 105 |
-} |
| 106 | 86 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,47 @@ |
| 0 |
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris |
|
| 1 |
+ |
|
| 2 |
+/* |
|
| 3 |
+ Copyright The containerd Authors. |
|
| 4 |
+ |
|
| 5 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 6 |
+ you may not use this file except in compliance with the License. |
|
| 7 |
+ You may obtain a copy of the License at |
|
| 8 |
+ |
|
| 9 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 10 |
+ |
|
| 11 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 12 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 13 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 14 |
+ See the License for the specific language governing permissions and |
|
| 15 |
+ limitations under the License. |
|
| 16 |
+*/ |
|
| 17 |
+ |
|
| 18 |
+package containerd |
|
| 19 |
+ |
|
| 20 |
+import ( |
|
| 21 |
+ "fmt" |
|
| 22 |
+ "strconv" |
|
| 23 |
+ "strings" |
|
| 24 |
+ "syscall" |
|
| 25 |
+ |
|
| 26 |
+ "golang.org/x/sys/unix" |
|
| 27 |
+) |
|
| 28 |
+ |
|
| 29 |
+// ParseSignal parses a given string into a syscall.Signal |
|
| 30 |
+// the rawSignal can be a string with "SIG" prefix, |
|
| 31 |
+// or a signal number in string format. |
|
| 32 |
+func ParseSignal(rawSignal string) (syscall.Signal, error) {
|
|
| 33 |
+ s, err := strconv.Atoi(rawSignal) |
|
| 34 |
+ if err == nil {
|
|
| 35 |
+ signal := syscall.Signal(s) |
|
| 36 |
+ if unix.SignalName(signal) != "" {
|
|
| 37 |
+ return signal, nil |
|
| 38 |
+ } |
|
| 39 |
+ return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
|
| 40 |
+ } |
|
| 41 |
+ signal := unix.SignalNum(strings.ToUpper(rawSignal)) |
|
| 42 |
+ if signal == 0 {
|
|
| 43 |
+ return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
|
| 44 |
+ } |
|
| 45 |
+ return signal, nil |
|
| 46 |
+} |
| 0 | 47 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,63 @@ |
| 0 |
+/* |
|
| 1 |
+ Copyright The containerd Authors. |
|
| 2 |
+ |
|
| 3 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
+ you may not use this file except in compliance with the License. |
|
| 5 |
+ You may obtain a copy of the License at |
|
| 6 |
+ |
|
| 7 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
+ |
|
| 9 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 10 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
+ See the License for the specific language governing permissions and |
|
| 13 |
+ limitations under the License. |
|
| 14 |
+*/ |
|
| 15 |
+ |
|
| 16 |
+package containerd |
|
| 17 |
+ |
|
| 18 |
+import ( |
|
| 19 |
+ "fmt" |
|
| 20 |
+ "strconv" |
|
| 21 |
+ "strings" |
|
| 22 |
+ "syscall" |
|
| 23 |
+ |
|
| 24 |
+ "golang.org/x/sys/windows" |
|
| 25 |
+) |
|
| 26 |
+ |
|
| 27 |
+var signalMap = map[string]syscall.Signal{
|
|
| 28 |
+ "HUP": syscall.Signal(windows.SIGHUP), |
|
| 29 |
+ "INT": syscall.Signal(windows.SIGINT), |
|
| 30 |
+ "QUIT": syscall.Signal(windows.SIGQUIT), |
|
| 31 |
+ "SIGILL": syscall.Signal(windows.SIGILL), |
|
| 32 |
+ "TRAP": syscall.Signal(windows.SIGTRAP), |
|
| 33 |
+ "ABRT": syscall.Signal(windows.SIGABRT), |
|
| 34 |
+ "BUS": syscall.Signal(windows.SIGBUS), |
|
| 35 |
+ "FPE": syscall.Signal(windows.SIGFPE), |
|
| 36 |
+ "KILL": syscall.Signal(windows.SIGKILL), |
|
| 37 |
+ "SEGV": syscall.Signal(windows.SIGSEGV), |
|
| 38 |
+ "PIPE": syscall.Signal(windows.SIGPIPE), |
|
| 39 |
+ "ALRM": syscall.Signal(windows.SIGALRM), |
|
| 40 |
+ "TERM": syscall.Signal(windows.SIGTERM), |
|
| 41 |
+} |
|
| 42 |
+ |
|
| 43 |
+// ParseSignal parses a given string into a syscall.Signal |
|
| 44 |
+// the rawSignal can be a string with "SIG" prefix, |
|
| 45 |
+// or a signal number in string format. |
|
| 46 |
+func ParseSignal(rawSignal string) (syscall.Signal, error) {
|
|
| 47 |
+ s, err := strconv.Atoi(rawSignal) |
|
| 48 |
+ if err == nil {
|
|
| 49 |
+ sig := syscall.Signal(s) |
|
| 50 |
+ for _, msig := range signalMap {
|
|
| 51 |
+ if sig == msig {
|
|
| 52 |
+ return sig, nil |
|
| 53 |
+ } |
|
| 54 |
+ } |
|
| 55 |
+ return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
|
| 56 |
+ } |
|
| 57 |
+ signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")] |
|
| 58 |
+ if !ok {
|
|
| 59 |
+ return -1, fmt.Errorf("unknown signal %q", rawSignal)
|
|
| 60 |
+ } |
|
| 61 |
+ return signal, nil |
|
| 62 |
+} |
| ... | ... |
@@ -160,9 +160,13 @@ func (u *Usage) Add(other Usage) {
|
| 160 | 160 |
// layerPath, tmpDir := getLayerPath(), mkTmpDir() // just a path to layer tar file. |
| 161 | 161 |
// |
| 162 | 162 |
// We start by using a Snapshotter to Prepare a new snapshot transaction, using a |
| 163 |
-// key and descending from the empty parent "": |
|
| 163 |
+// key and descending from the empty parent "". To prevent our layer from being |
|
| 164 |
+// garbage collected during unpacking, we add the `containerd.io/gc.root` label: |
|
| 164 | 165 |
// |
| 165 |
-// mounts, err := snapshotter.Prepare(ctx, key, "") |
|
| 166 |
+// noGcOpt := snapshots.WithLabels(map[string]string{
|
|
| 167 |
+// "containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339), |
|
| 168 |
+// }) |
|
| 169 |
+// mounts, err := snapshotter.Prepare(ctx, key, "", noGcOpt) |
|
| 166 | 170 |
// if err != nil { ... }
|
| 167 | 171 |
// |
| 168 | 172 |
// We get back a list of mounts from Snapshotter.Prepare, with the key identifying |
| ... | ... |
@@ -191,15 +195,13 @@ func (u *Usage) Add(other Usage) {
|
| 191 | 191 |
// |
| 192 | 192 |
// Now that we've verified and unpacked our layer, we commit the active |
| 193 | 193 |
// snapshot to a name. For this example, we are just going to use the layer |
| 194 |
-// digest, but in practice, this will probably be the ChainID: |
|
| 194 |
+// digest, but in practice, this will probably be the ChainID. This also removes |
|
| 195 |
+// the active snapshot: |
|
| 195 | 196 |
// |
| 196 |
-// if err := snapshotter.Commit(ctx, digest.String(), key); err != nil { ... }
|
|
| 197 |
+// if err := snapshotter.Commit(ctx, digest.String(), key, noGcOpt); err != nil { ... }
|
|
| 197 | 198 |
// |
| 198 | 199 |
// Now, we have a layer in the Snapshotter that can be accessed with the digest |
| 199 |
-// provided during commit. Once you have committed the snapshot, the active |
|
| 200 |
-// snapshot can be removed with the following: |
|
| 201 |
-// |
|
| 202 |
-// snapshotter.Remove(ctx, key) |
|
| 200 |
+// provided during commit. |
|
| 203 | 201 |
// |
| 204 | 202 |
// Importing the Next Layer |
| 205 | 203 |
// |
| ... | ... |
@@ -207,7 +209,7 @@ func (u *Usage) Add(other Usage) {
|
| 207 | 207 |
// above except that the parent is provided as parent when calling |
| 208 | 208 |
// Manager.Prepare, assuming a clean, unique key identifier: |
| 209 | 209 |
// |
| 210 |
-// mounts, err := snapshotter.Prepare(ctx, key, parentDigest) |
|
| 210 |
+// mounts, err := snapshotter.Prepare(ctx, key, parentDigest, noGcOpt) |
|
| 211 | 211 |
// |
| 212 | 212 |
// We then mount, apply and commit, as we did above. The new snapshot will be |
| 213 | 213 |
// based on the content of the previous one. |
| ... | ... |
@@ -37,11 +37,13 @@ import ( |
| 37 | 37 |
"github.com/containerd/containerd/mount" |
| 38 | 38 |
"github.com/containerd/containerd/plugin" |
| 39 | 39 |
"github.com/containerd/containerd/rootfs" |
| 40 |
+ "github.com/containerd/containerd/runtime/linux/runctypes" |
|
| 41 |
+ "github.com/containerd/containerd/runtime/v2/runc/options" |
|
| 40 | 42 |
"github.com/containerd/typeurl" |
| 41 | 43 |
google_protobuf "github.com/gogo/protobuf/types" |
| 42 | 44 |
digest "github.com/opencontainers/go-digest" |
| 43 | 45 |
is "github.com/opencontainers/image-spec/specs-go" |
| 44 |
- "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 46 |
+ v1 "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 45 | 47 |
specs "github.com/opencontainers/runtime-spec/specs-go" |
| 46 | 48 |
"github.com/pkg/errors" |
| 47 | 49 |
) |
| ... | ... |
@@ -115,6 +117,13 @@ type CheckpointTaskInfo struct {
|
| 115 | 115 |
ParentCheckpoint digest.Digest |
| 116 | 116 |
// Options hold runtime specific settings for checkpointing a task |
| 117 | 117 |
Options interface{}
|
| 118 |
+ |
|
| 119 |
+ runtime string |
|
| 120 |
+} |
|
| 121 |
+ |
|
| 122 |
+// Runtime name for the container |
|
| 123 |
+func (i *CheckpointTaskInfo) Runtime() string {
|
|
| 124 |
+ return i.runtime |
|
| 118 | 125 |
} |
| 119 | 126 |
|
| 120 | 127 |
// CheckpointTaskOpts allows the caller to set checkpoint options |
| ... | ... |
@@ -129,6 +138,12 @@ type TaskInfo struct {
|
| 129 | 129 |
RootFS []mount.Mount |
| 130 | 130 |
// Options hold runtime specific settings for task creation |
| 131 | 131 |
Options interface{}
|
| 132 |
+ runtime string |
|
| 133 |
+} |
|
| 134 |
+ |
|
| 135 |
+// Runtime name for the container |
|
| 136 |
+func (i *TaskInfo) Runtime() string {
|
|
| 137 |
+ return i.runtime |
|
| 132 | 138 |
} |
| 133 | 139 |
|
| 134 | 140 |
// Task is the executable object within containerd |
| ... | ... |
@@ -147,6 +162,8 @@ type Task interface {
|
| 147 | 147 |
// OCI Index that can be push and pulled from a remote resource. |
| 148 | 148 |
// |
| 149 | 149 |
// Additional software like CRIU maybe required to checkpoint and restore tasks |
| 150 |
+ // NOTE: Checkpoint supports to dump task information to a directory, in this way, |
|
| 151 |
+ // an empty OCI Index will be returned. |
|
| 150 | 152 |
Checkpoint(context.Context, ...CheckpointTaskOpts) (Image, error) |
| 151 | 153 |
// Update modifies executing tasks with updated settings |
| 152 | 154 |
Update(context.Context, ...UpdateTaskOpts) error |
| ... | ... |
@@ -389,17 +406,25 @@ func (t *task) Resize(ctx context.Context, w, h uint32) error {
|
| 389 | 389 |
return errdefs.FromGRPC(err) |
| 390 | 390 |
} |
| 391 | 391 |
|
| 392 |
+// NOTE: Checkpoint supports to dump task information to a directory, in this way, an empty |
|
| 393 |
+// OCI Index will be returned. |
|
| 392 | 394 |
func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Image, error) {
|
| 393 | 395 |
ctx, done, err := t.client.WithLease(ctx) |
| 394 | 396 |
if err != nil {
|
| 395 | 397 |
return nil, err |
| 396 | 398 |
} |
| 397 | 399 |
defer done(ctx) |
| 400 |
+ cr, err := t.client.ContainerService().Get(ctx, t.id) |
|
| 401 |
+ if err != nil {
|
|
| 402 |
+ return nil, err |
|
| 403 |
+ } |
|
| 398 | 404 |
|
| 399 | 405 |
request := &tasks.CheckpointTaskRequest{
|
| 400 | 406 |
ContainerID: t.id, |
| 401 | 407 |
} |
| 402 |
- var i CheckpointTaskInfo |
|
| 408 |
+ i := CheckpointTaskInfo{
|
|
| 409 |
+ runtime: cr.Runtime.Name, |
|
| 410 |
+ } |
|
| 403 | 411 |
for _, o := range opts {
|
| 404 | 412 |
if err := o(&i); err != nil {
|
| 405 | 413 |
return nil, err |
| ... | ... |
@@ -422,10 +447,6 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Imag |
| 422 | 422 |
return nil, err |
| 423 | 423 |
} |
| 424 | 424 |
defer t.Resume(ctx) |
| 425 |
- cr, err := t.client.ContainerService().Get(ctx, t.id) |
|
| 426 |
- if err != nil {
|
|
| 427 |
- return nil, err |
|
| 428 |
- } |
|
| 429 | 425 |
index := v1.Index{
|
| 430 | 426 |
Versioned: is.Versioned{
|
| 431 | 427 |
SchemaVersion: 2, |
| ... | ... |
@@ -435,6 +456,12 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Imag |
| 435 | 435 |
if err := t.checkpointTask(ctx, &index, request); err != nil {
|
| 436 | 436 |
return nil, err |
| 437 | 437 |
} |
| 438 |
+ // if checkpoint image path passed, jump checkpoint image, |
|
| 439 |
+ // return an empty image |
|
| 440 |
+ if isCheckpointPathExist(cr.Runtime.Name, i.Options) {
|
|
| 441 |
+ return NewImage(t.client, images.Image{}), nil
|
|
| 442 |
+ } |
|
| 443 |
+ |
|
| 438 | 444 |
if cr.Image != "" {
|
| 439 | 445 |
if err := t.checkpointImage(ctx, &index, cr.Image); err != nil {
|
| 440 | 446 |
return nil, err |
| ... | ... |
@@ -544,6 +571,7 @@ func (t *task) checkpointTask(ctx context.Context, index *v1.Index, request *tas |
| 544 | 544 |
if err != nil {
|
| 545 | 545 |
return errdefs.FromGRPC(err) |
| 546 | 546 |
} |
| 547 |
+ // NOTE: response.Descriptors can be an empty slice if checkpoint image is jumped |
|
| 547 | 548 |
// add the checkpoint descriptors to the index |
| 548 | 549 |
for _, d := range response.Descriptors {
|
| 549 | 550 |
index.Manifests = append(index.Manifests, v1.Descriptor{
|
| ... | ... |
@@ -621,3 +649,24 @@ func writeContent(ctx context.Context, store content.Ingester, mediaType, ref st |
| 621 | 621 |
Size: size, |
| 622 | 622 |
}, nil |
| 623 | 623 |
} |
| 624 |
+ |
|
| 625 |
+// isCheckpointPathExist only suitable for runc runtime now |
|
| 626 |
+func isCheckpointPathExist(runtime string, v interface{}) bool {
|
|
| 627 |
+ if v == nil {
|
|
| 628 |
+ return false |
|
| 629 |
+ } |
|
| 630 |
+ |
|
| 631 |
+ switch runtime {
|
|
| 632 |
+ case plugin.RuntimeRuncV1, plugin.RuntimeRuncV2: |
|
| 633 |
+ if opts, ok := v.(*options.CheckpointOptions); ok && opts.ImagePath != "" {
|
|
| 634 |
+ return true |
|
| 635 |
+ } |
|
| 636 |
+ |
|
| 637 |
+ case plugin.RuntimeLinuxV1: |
|
| 638 |
+ if opts, ok := v.(*runctypes.CheckpointOptions); ok && opts.ImagePath != "" {
|
|
| 639 |
+ return true |
|
| 640 |
+ } |
|
| 641 |
+ } |
|
| 642 |
+ |
|
| 643 |
+ return false |
|
| 644 |
+} |
| ... | ... |
@@ -27,6 +27,8 @@ import ( |
| 27 | 27 |
"github.com/containerd/containerd/errdefs" |
| 28 | 28 |
"github.com/containerd/containerd/images" |
| 29 | 29 |
"github.com/containerd/containerd/mount" |
| 30 |
+ "github.com/containerd/containerd/runtime/linux/runctypes" |
|
| 31 |
+ "github.com/containerd/containerd/runtime/v2/runc/options" |
|
| 30 | 32 |
imagespec "github.com/opencontainers/image-spec/specs-go/v1" |
| 31 | 33 |
"github.com/opencontainers/runtime-spec/specs-go" |
| 32 | 34 |
"github.com/pkg/errors" |
| ... | ... |
@@ -89,6 +91,58 @@ func WithCheckpointName(name string) CheckpointTaskOpts {
|
| 89 | 89 |
} |
| 90 | 90 |
} |
| 91 | 91 |
|
| 92 |
+// WithCheckpointImagePath sets image path for checkpoint option |
|
| 93 |
+func WithCheckpointImagePath(path string) CheckpointTaskOpts {
|
|
| 94 |
+ return func(r *CheckpointTaskInfo) error {
|
|
| 95 |
+ if CheckRuntime(r.Runtime(), "io.containerd.runc") {
|
|
| 96 |
+ if r.Options == nil {
|
|
| 97 |
+ r.Options = &options.CheckpointOptions{}
|
|
| 98 |
+ } |
|
| 99 |
+ opts, ok := r.Options.(*options.CheckpointOptions) |
|
| 100 |
+ if !ok {
|
|
| 101 |
+ return errors.New("invalid v2 shim checkpoint options format")
|
|
| 102 |
+ } |
|
| 103 |
+ opts.ImagePath = path |
|
| 104 |
+ } else {
|
|
| 105 |
+ if r.Options == nil {
|
|
| 106 |
+ r.Options = &runctypes.CheckpointOptions{}
|
|
| 107 |
+ } |
|
| 108 |
+ opts, ok := r.Options.(*runctypes.CheckpointOptions) |
|
| 109 |
+ if !ok {
|
|
| 110 |
+ return errors.New("invalid v1 shim checkpoint options format")
|
|
| 111 |
+ } |
|
| 112 |
+ opts.ImagePath = path |
|
| 113 |
+ } |
|
| 114 |
+ return nil |
|
| 115 |
+ } |
|
| 116 |
+} |
|
| 117 |
+ |
|
| 118 |
+// WithRestoreImagePath sets image path for create option |
|
| 119 |
+func WithRestoreImagePath(path string) NewTaskOpts {
|
|
| 120 |
+ return func(ctx context.Context, c *Client, ti *TaskInfo) error {
|
|
| 121 |
+ if CheckRuntime(ti.Runtime(), "io.containerd.runc") {
|
|
| 122 |
+ if ti.Options == nil {
|
|
| 123 |
+ ti.Options = &options.Options{}
|
|
| 124 |
+ } |
|
| 125 |
+ opts, ok := ti.Options.(*options.Options) |
|
| 126 |
+ if !ok {
|
|
| 127 |
+ return errors.New("invalid v2 shim create options format")
|
|
| 128 |
+ } |
|
| 129 |
+ opts.CriuImagePath = path |
|
| 130 |
+ } else {
|
|
| 131 |
+ if ti.Options == nil {
|
|
| 132 |
+ ti.Options = &runctypes.CreateOptions{}
|
|
| 133 |
+ } |
|
| 134 |
+ opts, ok := ti.Options.(*runctypes.CreateOptions) |
|
| 135 |
+ if !ok {
|
|
| 136 |
+ return errors.New("invalid v1 shim create options format")
|
|
| 137 |
+ } |
|
| 138 |
+ opts.CriuImagePath = path |
|
| 139 |
+ } |
|
| 140 |
+ return nil |
|
| 141 |
+ } |
|
| 142 |
+} |
|
| 143 |
+ |
|
| 92 | 144 |
// ProcessDeleteOpts allows the caller to set options for the deletion of a task |
| 93 | 145 |
type ProcessDeleteOpts func(context.Context, Process) error |
| 94 | 146 |
|
| ... | ... |
@@ -22,36 +22,58 @@ import ( |
| 22 | 22 |
"context" |
| 23 | 23 |
|
| 24 | 24 |
"github.com/containerd/containerd/runtime/linux/runctypes" |
| 25 |
+ "github.com/containerd/containerd/runtime/v2/runc/options" |
|
| 25 | 26 |
"github.com/pkg/errors" |
| 26 | 27 |
) |
| 27 | 28 |
|
| 28 | 29 |
// WithNoNewKeyring causes tasks not to be created with a new keyring for secret storage. |
| 29 | 30 |
// There is an upper limit on the number of keyrings in a linux system |
| 30 | 31 |
func WithNoNewKeyring(ctx context.Context, c *Client, ti *TaskInfo) error {
|
| 31 |
- if ti.Options == nil {
|
|
| 32 |
- ti.Options = &runctypes.CreateOptions{}
|
|
| 33 |
- } |
|
| 34 |
- opts, ok := ti.Options.(*runctypes.CreateOptions) |
|
| 35 |
- if !ok {
|
|
| 36 |
- return errors.New("could not cast TaskInfo Options to CreateOptions")
|
|
| 32 |
+ if CheckRuntime(ti.Runtime(), "io.containerd.runc") {
|
|
| 33 |
+ if ti.Options == nil {
|
|
| 34 |
+ ti.Options = &options.Options{}
|
|
| 35 |
+ } |
|
| 36 |
+ opts, ok := ti.Options.(*options.Options) |
|
| 37 |
+ if !ok {
|
|
| 38 |
+ return errors.New("invalid v2 shim create options format")
|
|
| 39 |
+ } |
|
| 40 |
+ opts.NoNewKeyring = true |
|
| 41 |
+ } else {
|
|
| 42 |
+ if ti.Options == nil {
|
|
| 43 |
+ ti.Options = &runctypes.CreateOptions{}
|
|
| 44 |
+ } |
|
| 45 |
+ opts, ok := ti.Options.(*runctypes.CreateOptions) |
|
| 46 |
+ if !ok {
|
|
| 47 |
+ return errors.New("could not cast TaskInfo Options to CreateOptions")
|
|
| 48 |
+ } |
|
| 49 |
+ opts.NoNewKeyring = true |
|
| 37 | 50 |
} |
| 38 |
- |
|
| 39 |
- opts.NoNewKeyring = true |
|
| 40 | 51 |
return nil |
| 41 | 52 |
} |
| 42 | 53 |
|
| 43 | 54 |
// WithNoPivotRoot instructs the runtime not to you pivot_root |
| 44 |
-func WithNoPivotRoot(_ context.Context, _ *Client, info *TaskInfo) error {
|
|
| 45 |
- if info.Options == nil {
|
|
| 46 |
- info.Options = &runctypes.CreateOptions{
|
|
| 47 |
- NoPivotRoot: true, |
|
| 55 |
+func WithNoPivotRoot(_ context.Context, _ *Client, ti *TaskInfo) error {
|
|
| 56 |
+ if CheckRuntime(ti.Runtime(), "io.containerd.runc") {
|
|
| 57 |
+ if ti.Options == nil {
|
|
| 58 |
+ ti.Options = &options.Options{}
|
|
| 48 | 59 |
} |
| 49 |
- return nil |
|
| 50 |
- } |
|
| 51 |
- opts, ok := info.Options.(*runctypes.CreateOptions) |
|
| 52 |
- if !ok {
|
|
| 53 |
- return errors.New("invalid options type, expected runctypes.CreateOptions")
|
|
| 60 |
+ opts, ok := ti.Options.(*options.Options) |
|
| 61 |
+ if !ok {
|
|
| 62 |
+ return errors.New("invalid v2 shim create options format")
|
|
| 63 |
+ } |
|
| 64 |
+ opts.NoPivotRoot = true |
|
| 65 |
+ } else {
|
|
| 66 |
+ if ti.Options == nil {
|
|
| 67 |
+ ti.Options = &runctypes.CreateOptions{
|
|
| 68 |
+ NoPivotRoot: true, |
|
| 69 |
+ } |
|
| 70 |
+ return nil |
|
| 71 |
+ } |
|
| 72 |
+ opts, ok := ti.Options.(*runctypes.CreateOptions) |
|
| 73 |
+ if !ok {
|
|
| 74 |
+ return errors.New("invalid options type, expected runctypes.CreateOptions")
|
|
| 75 |
+ } |
|
| 76 |
+ opts.NoPivotRoot = true |
|
| 54 | 77 |
} |
| 55 |
- opts.NoPivotRoot = true |
|
| 56 | 78 |
return nil |
| 57 | 79 |
} |
| ... | ... |
@@ -19,31 +19,32 @@ github.com/matttproud/golang_protobuf_extensions v1.0.0 |
| 19 | 19 |
github.com/gogo/protobuf v1.0.0 |
| 20 | 20 |
github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef |
| 21 | 21 |
github.com/golang/protobuf v1.1.0 |
| 22 |
-github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353 # v1.0.1-45-geba862d |
|
| 22 |
+github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db |
|
| 23 | 23 |
github.com/opencontainers/runc 2b18fe1d885ee5083ef9f0838fee39b62d653e30 |
| 24 |
-github.com/sirupsen/logrus v1.0.0 |
|
| 24 |
+github.com/konsorten/go-windows-terminal-sequences v1.0.1 |
|
| 25 |
+github.com/sirupsen/logrus v1.3.0 |
|
| 25 | 26 |
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c |
| 26 | 27 |
golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac |
| 27 | 28 |
google.golang.org/grpc v1.12.0 |
| 28 | 29 |
github.com/pkg/errors v0.8.0 |
| 29 | 30 |
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7 |
| 30 |
-golang.org/x/sys 41f3e6584952bb034a481797859f6ab34b6803bd https://github.com/golang/sys |
|
| 31 |
+golang.org/x/sys d455e41777fca6e8a5a79e34a14b8368bc11d9ba https://github.com/golang/sys |
|
| 31 | 32 |
github.com/opencontainers/image-spec v1.0.1 |
| 32 |
-golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c |
|
| 33 |
+golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e |
|
| 33 | 34 |
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895 |
| 34 | 35 |
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0 |
| 35 |
-github.com/Microsoft/go-winio v0.4.11 |
|
| 36 |
-github.com/Microsoft/hcsshim v0.8.1 |
|
| 36 |
+github.com/Microsoft/go-winio v0.4.12 |
|
| 37 |
+github.com/Microsoft/hcsshim v0.8.5 |
|
| 37 | 38 |
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944 |
| 38 | 39 |
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4 |
| 39 |
-github.com/containerd/ttrpc 2a805f71863501300ae1976d29f0454ae003e85a |
|
| 40 |
+github.com/containerd/ttrpc f02858b1457c5ca3aaec3a0803eb0d59f96e41d6 |
|
| 40 | 41 |
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16 |
| 41 | 42 |
gotest.tools v2.1.0 |
| 42 | 43 |
github.com/google/go-cmp v0.1.0 |
| 43 |
-go.etcd.io/bbolt v1.3.1-etcd.8 |
|
| 44 |
+go.etcd.io/bbolt v1.3.2 |
|
| 44 | 45 |
|
| 45 | 46 |
# cri dependencies |
| 46 |
-github.com/containerd/cri a92c40017473cbe0239ce180125f12669757e44f # release/1.2 branch |
|
| 47 |
+github.com/containerd/cri 4dd6735020f5596dd41738f8c4f5cb07fa804c5e # master |
|
| 47 | 48 |
github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90 |
| 48 | 49 |
github.com/blang/semver v3.1.0 |
| 49 | 50 |
github.com/containernetworking/cni v0.6.0 |
| ... | ... |
@@ -53,8 +54,6 @@ github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580 |
| 53 | 53 |
github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00 |
| 54 | 54 |
github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528 |
| 55 | 55 |
github.com/emicklei/go-restful v2.2.1 |
| 56 |
-github.com/ghodss/yaml v1.0.0 |
|
| 57 |
-github.com/golang/glog 44145f04b68cf362d9c4df2182967c2275eaefed |
|
| 58 | 56 |
github.com/google/gofuzz 44d81051d367757e1c7c6a5a86423ece9afcf63c |
| 59 | 57 |
github.com/hashicorp/errwrap 7554cd9344cec97297fa6649b055a8c98c2a1e55 |
| 60 | 58 |
github.com/hashicorp/go-multierror ed905158d87462226a13fe39ddf685ea65f1c11f |
| ... | ... |
@@ -73,17 +72,19 @@ golang.org/x/oauth2 a6bd8cefa1811bd24b86f8902872e4e8225f74c4 |
| 73 | 73 |
golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631 |
| 74 | 74 |
gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 |
| 75 | 75 |
gopkg.in/yaml.v2 v2.2.1 |
| 76 |
-k8s.io/api kubernetes-1.12.0 |
|
| 77 |
-k8s.io/apimachinery kubernetes-1.12.0 |
|
| 78 |
-k8s.io/apiserver kubernetes-1.12.0 |
|
| 79 |
-k8s.io/client-go kubernetes-1.12.0 |
|
| 80 |
-k8s.io/kubernetes v1.12.0 |
|
| 81 |
-k8s.io/utils cd34563cd63c2bd7c6fe88a73c4dcf34ed8a67cb |
|
| 76 |
+k8s.io/api kubernetes-1.13.0 |
|
| 77 |
+k8s.io/apimachinery kubernetes-1.13.0 |
|
| 78 |
+k8s.io/apiserver kubernetes-1.13.0 |
|
| 79 |
+k8s.io/client-go kubernetes-1.13.0 |
|
| 80 |
+k8s.io/klog 8139d8cb77af419532b33dfa7dd09fbc5f1d344f |
|
| 81 |
+k8s.io/kubernetes v1.13.0 |
|
| 82 |
+k8s.io/utils 0d26856f57b32ec3398579285e5c8a2bfe8c5243 |
|
| 83 |
+sigs.k8s.io/yaml v1.1.0 |
|
| 82 | 84 |
|
| 83 | 85 |
# zfs dependencies |
| 84 |
-github.com/containerd/zfs 9a0b8b8b5982014b729cd34eb7cd7a11062aa6ec |
|
| 86 |
+github.com/containerd/zfs 9f6ef3b1fe5144bd91fe5855b4eba81bc0d17d03 |
|
| 85 | 87 |
github.com/mistifyio/go-zfs 166add352731e515512690329794ee593f1aaff2 |
| 86 | 88 |
github.com/pborman/uuid c65b2f87fee37d1c7854c9164a450713c28d50cd |
| 87 | 89 |
|
| 88 | 90 |
# aufs dependencies |
| 89 |
-github.com/containerd/aufs ffa39970e26ad01d81f540b21e65f9c1841a5f92 |
|
| 91 |
+github.com/containerd/aufs da3cf16bfbe68ba8f114f1536a05c01528a25434 |
| 90 | 92 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,29 @@ |
| 0 |
+/* |
|
| 1 |
+ Copyright The containerd Authors. |
|
| 2 |
+ |
|
| 3 |
+ Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
+ you may not use this file except in compliance with the License. |
|
| 5 |
+ You may obtain a copy of the License at |
|
| 6 |
+ |
|
| 7 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
+ |
|
| 9 |
+ Unless required by applicable law or agreed to in writing, software |
|
| 10 |
+ distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
+ See the License for the specific language governing permissions and |
|
| 13 |
+ limitations under the License. |
|
| 14 |
+*/ |
|
| 15 |
+ |
|
| 16 |
+package version |
|
| 17 |
+ |
|
| 18 |
+var ( |
|
| 19 |
+ // Package is filled at linking time |
|
| 20 |
+ Package = "github.com/containerd/containerd" |
|
| 21 |
+ |
|
| 22 |
+ // Version holds the complete version number. Filled in at linking time. |
|
| 23 |
+ Version = "1.2.0+unknown" |
|
| 24 |
+ |
|
| 25 |
+ // Revision is filled with the VCS (e.g. git) revision being used to build |
|
| 26 |
+ // the program at linking time. |
|
| 27 |
+ Revision = "" |
|
| 28 |
+) |
| ... | ... |
@@ -50,3 +50,13 @@ TODO: |
| 50 | 50 |
- [ ] Document protocol layout |
| 51 | 51 |
- [ ] Add testing under concurrent load to ensure |
| 52 | 52 |
- [ ] Verify connection error handling |
| 53 |
+ |
|
| 54 |
+# Project details |
|
| 55 |
+ |
|
| 56 |
+ttrpc is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE). |
|
| 57 |
+As a containerd sub-project, you will find the: |
|
| 58 |
+ * [Project governance](https://github.com/containerd/project/blob/master/GOVERNANCE.md), |
|
| 59 |
+ * [Maintainers](https://github.com/containerd/project/blob/master/MAINTAINERS), |
|
| 60 |
+ * and [Contributing guidelines](https://github.com/containerd/project/blob/master/CONTRIBUTING.md) |
|
| 61 |
+ |
|
| 62 |
+information in our [`containerd/project`](https://github.com/containerd/project) repository. |
| ... | ... |
@@ -24,6 +24,7 @@ import ( |
| 24 | 24 |
"strings" |
| 25 | 25 |
"sync" |
| 26 | 26 |
"syscall" |
| 27 |
+ "time" |
|
| 27 | 28 |
|
| 28 | 29 |
"github.com/gogo/protobuf/proto" |
| 29 | 30 |
"github.com/pkg/errors" |
| ... | ... |
@@ -86,6 +87,10 @@ func (c *Client) Call(ctx context.Context, service, method string, req, resp int |
| 86 | 86 |
cresp = &Response{}
|
| 87 | 87 |
) |
| 88 | 88 |
|
| 89 |
+ if dl, ok := ctx.Deadline(); ok {
|
|
| 90 |
+ creq.TimeoutNano = dl.Sub(time.Now()).Nanoseconds() |
|
| 91 |
+ } |
|
| 92 |
+ |
|
| 89 | 93 |
if err := c.dispatch(ctx, creq, cresp); err != nil {
|
| 90 | 94 |
return err |
| 91 | 95 |
} |
| ... | ... |
@@ -104,6 +109,7 @@ func (c *Client) Call(ctx context.Context, service, method string, req, resp int |
| 104 | 104 |
func (c *Client) dispatch(ctx context.Context, req *Request, resp *Response) error {
|
| 105 | 105 |
errs := make(chan error, 1) |
| 106 | 106 |
call := &callRequest{
|
| 107 |
+ ctx: ctx, |
|
| 107 | 108 |
req: req, |
| 108 | 109 |
resp: resp, |
| 109 | 110 |
errs: errs, |
| ... | ... |
@@ -414,6 +414,9 @@ func (c *serverConn) run(sctx context.Context) {
|
| 414 | 414 |
case request := <-requests: |
| 415 | 415 |
active++ |
| 416 | 416 |
go func(id uint32) {
|
| 417 |
+ ctx, cancel := getRequestContext(ctx, request.req) |
|
| 418 |
+ defer cancel() |
|
| 419 |
+ |
|
| 417 | 420 |
p, status := c.server.services.call(ctx, request.req.Service, request.req.Method, request.req.Payload) |
| 418 | 421 |
resp := &Response{
|
| 419 | 422 |
Status: status.Proto(), |
| ... | ... |
@@ -454,3 +457,15 @@ func (c *serverConn) run(sctx context.Context) {
|
| 454 | 454 |
} |
| 455 | 455 |
} |
| 456 | 456 |
} |
| 457 |
+ |
|
| 458 |
+var noopFunc = func() {}
|
|
| 459 |
+ |
|
| 460 |
+func getRequestContext(ctx context.Context, req *Request) (retCtx context.Context, cancel func()) {
|
|
| 461 |
+ cancel = noopFunc |
|
| 462 |
+ if req.TimeoutNano == 0 {
|
|
| 463 |
+ return ctx, cancel |
|
| 464 |
+ } |
|
| 465 |
+ |
|
| 466 |
+ ctx, cancel = context.WithTimeout(ctx, time.Duration(req.TimeoutNano)) |
|
| 467 |
+ return ctx, cancel |
|
| 468 |
+} |
| ... | ... |
@@ -23,9 +23,10 @@ import ( |
| 23 | 23 |
) |
| 24 | 24 |
|
| 25 | 25 |
type Request struct {
|
| 26 |
- Service string `protobuf:"bytes,1,opt,name=service,proto3"` |
|
| 27 |
- Method string `protobuf:"bytes,2,opt,name=method,proto3"` |
|
| 28 |
- Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3"` |
|
| 26 |
+ Service string `protobuf:"bytes,1,opt,name=service,proto3"` |
|
| 27 |
+ Method string `protobuf:"bytes,2,opt,name=method,proto3"` |
|
| 28 |
+ Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3"` |
|
| 29 |
+ TimeoutNano int64 `protobuf:"varint,4,opt,name=timeout_nano,proto3"` |
|
| 29 | 30 |
} |
| 30 | 31 |
|
| 31 | 32 |
func (r *Request) Reset() { *r = Request{} }
|
| 32 | 33 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,30 @@ |
| 0 |
+// Copyright 2019 The Go Authors. All rights reserved. |
|
| 1 |
+// Use of this source code is governed by a BSD-style |
|
| 2 |
+// license that can be found in the LICENSE file. |
|
| 3 |
+ |
|
| 4 |
+package cpu |
|
| 5 |
+ |
|
| 6 |
+import ( |
|
| 7 |
+ "encoding/binary" |
|
| 8 |
+ "runtime" |
|
| 9 |
+) |
|
| 10 |
+ |
|
| 11 |
+// hostByteOrder returns binary.LittleEndian on little-endian machines and |
|
| 12 |
+// binary.BigEndian on big-endian machines. |
|
| 13 |
+func hostByteOrder() binary.ByteOrder {
|
|
| 14 |
+ switch runtime.GOARCH {
|
|
| 15 |
+ case "386", "amd64", "amd64p32", |
|
| 16 |
+ "arm", "arm64", |
|
| 17 |
+ "mipsle", "mips64le", "mips64p32le", |
|
| 18 |
+ "ppc64le", |
|
| 19 |
+ "riscv", "riscv64": |
|
| 20 |
+ return binary.LittleEndian |
|
| 21 |
+ case "armbe", "arm64be", |
|
| 22 |
+ "mips", "mips64", "mips64p32", |
|
| 23 |
+ "ppc", "ppc64", |
|
| 24 |
+ "s390", "s390x", |
|
| 25 |
+ "sparc", "sparc64": |
|
| 26 |
+ return binary.BigEndian |
|
| 27 |
+ } |
|
| 28 |
+ panic("unknown architecture")
|
|
| 29 |
+} |
| ... | ... |
@@ -6,6 +6,13 @@ |
| 6 | 6 |
// various CPU architectures. |
| 7 | 7 |
package cpu |
| 8 | 8 |
|
| 9 |
+// Initialized reports whether the CPU features were initialized. |
|
| 10 |
+// |
|
| 11 |
+// For some GOOS/GOARCH combinations initialization of the CPU features depends |
|
| 12 |
+// on reading an operating specific file, e.g. /proc/self/auxv on linux/arm |
|
| 13 |
+// Initialized will report false if reading the file fails. |
|
| 14 |
+var Initialized bool |
|
| 15 |
+ |
|
| 9 | 16 |
// CacheLinePad is used to pad structs to avoid false sharing. |
| 10 | 17 |
type CacheLinePad struct{ _ [cacheLineSize]byte }
|
| 11 | 18 |
|
| ... | ... |
@@ -87,3 +94,33 @@ var PPC64 struct {
|
| 87 | 87 |
IsPOWER9 bool // ISA v3.00 (POWER9) |
| 88 | 88 |
_ CacheLinePad |
| 89 | 89 |
} |
| 90 |
+ |
|
| 91 |
+// S390X contains the supported CPU features of the current IBM Z |
|
| 92 |
+// (s390x) platform. If the current platform is not IBM Z then all |
|
| 93 |
+// feature flags are false. |
|
| 94 |
+// |
|
| 95 |
+// S390X is padded to avoid false sharing. Further HasVX is only set |
|
| 96 |
+// if the OS supports vector registers in addition to the STFLE |
|
| 97 |
+// feature bit being set. |
|
| 98 |
+var S390X struct {
|
|
| 99 |
+ _ CacheLinePad |
|
| 100 |
+ HasZARCH bool // z/Architecture mode is active [mandatory] |
|
| 101 |
+ HasSTFLE bool // store facility list extended |
|
| 102 |
+ HasLDISP bool // long (20-bit) displacements |
|
| 103 |
+ HasEIMM bool // 32-bit immediates |
|
| 104 |
+ HasDFP bool // decimal floating point |
|
| 105 |
+ HasETF3EH bool // ETF-3 enhanced |
|
| 106 |
+ HasMSA bool // message security assist (CPACF) |
|
| 107 |
+ HasAES bool // KM-AES{128,192,256} functions
|
|
| 108 |
+ HasAESCBC bool // KMC-AES{128,192,256} functions
|
|
| 109 |
+ HasAESCTR bool // KMCTR-AES{128,192,256} functions
|
|
| 110 |
+ HasAESGCM bool // KMA-GCM-AES{128,192,256} functions
|
|
| 111 |
+ HasGHASH bool // KIMD-GHASH function |
|
| 112 |
+ HasSHA1 bool // K{I,L}MD-SHA-1 functions
|
|
| 113 |
+ HasSHA256 bool // K{I,L}MD-SHA-256 functions
|
|
| 114 |
+ HasSHA512 bool // K{I,L}MD-SHA-512 functions
|
|
| 115 |
+ HasSHA3 bool // K{I,L}MD-SHA3-{224,256,384,512} and K{I,L}MD-SHAKE-{128,256} functions
|
|
| 116 |
+ HasVX bool // vector facility |
|
| 117 |
+ HasVXE bool // vector-enhancements facility 1 |
|
| 118 |
+ _ CacheLinePad |
|
| 119 |
+} |
| 90 | 120 |
deleted file mode 100644 |
| ... | ... |
@@ -1,67 +0,0 @@ |
| 1 |
-// Copyright 2018 The Go Authors. All rights reserved. |
|
| 2 |
-// Use of this source code is governed by a BSD-style |
|
| 3 |
-// license that can be found in the LICENSE file. |
|
| 4 |
- |
|
| 5 |
-package cpu |
|
| 6 |
- |
|
| 7 |
-const cacheLineSize = 64 |
|
| 8 |
- |
|
| 9 |
-// HWCAP/HWCAP2 bits. These are exposed by Linux. |
|
| 10 |
-const ( |
|
| 11 |
- hwcap_FP = 1 << 0 |
|
| 12 |
- hwcap_ASIMD = 1 << 1 |
|
| 13 |
- hwcap_EVTSTRM = 1 << 2 |
|
| 14 |
- hwcap_AES = 1 << 3 |
|
| 15 |
- hwcap_PMULL = 1 << 4 |
|
| 16 |
- hwcap_SHA1 = 1 << 5 |
|
| 17 |
- hwcap_SHA2 = 1 << 6 |
|
| 18 |
- hwcap_CRC32 = 1 << 7 |
|
| 19 |
- hwcap_ATOMICS = 1 << 8 |
|
| 20 |
- hwcap_FPHP = 1 << 9 |
|
| 21 |
- hwcap_ASIMDHP = 1 << 10 |
|
| 22 |
- hwcap_CPUID = 1 << 11 |
|
| 23 |
- hwcap_ASIMDRDM = 1 << 12 |
|
| 24 |
- hwcap_JSCVT = 1 << 13 |
|
| 25 |
- hwcap_FCMA = 1 << 14 |
|
| 26 |
- hwcap_LRCPC = 1 << 15 |
|
| 27 |
- hwcap_DCPOP = 1 << 16 |
|
| 28 |
- hwcap_SHA3 = 1 << 17 |
|
| 29 |
- hwcap_SM3 = 1 << 18 |
|
| 30 |
- hwcap_SM4 = 1 << 19 |
|
| 31 |
- hwcap_ASIMDDP = 1 << 20 |
|
| 32 |
- hwcap_SHA512 = 1 << 21 |
|
| 33 |
- hwcap_SVE = 1 << 22 |
|
| 34 |
- hwcap_ASIMDFHM = 1 << 23 |
|
| 35 |
-) |
|
| 36 |
- |
|
| 37 |
-func doinit() {
|
|
| 38 |
- // HWCAP feature bits |
|
| 39 |
- ARM64.HasFP = isSet(HWCap, hwcap_FP) |
|
| 40 |
- ARM64.HasASIMD = isSet(HWCap, hwcap_ASIMD) |
|
| 41 |
- ARM64.HasEVTSTRM = isSet(HWCap, hwcap_EVTSTRM) |
|
| 42 |
- ARM64.HasAES = isSet(HWCap, hwcap_AES) |
|
| 43 |
- ARM64.HasPMULL = isSet(HWCap, hwcap_PMULL) |
|
| 44 |
- ARM64.HasSHA1 = isSet(HWCap, hwcap_SHA1) |
|
| 45 |
- ARM64.HasSHA2 = isSet(HWCap, hwcap_SHA2) |
|
| 46 |
- ARM64.HasCRC32 = isSet(HWCap, hwcap_CRC32) |
|
| 47 |
- ARM64.HasATOMICS = isSet(HWCap, hwcap_ATOMICS) |
|
| 48 |
- ARM64.HasFPHP = isSet(HWCap, hwcap_FPHP) |
|
| 49 |
- ARM64.HasASIMDHP = isSet(HWCap, hwcap_ASIMDHP) |
|
| 50 |
- ARM64.HasCPUID = isSet(HWCap, hwcap_CPUID) |
|
| 51 |
- ARM64.HasASIMDRDM = isSet(HWCap, hwcap_ASIMDRDM) |
|
| 52 |
- ARM64.HasJSCVT = isSet(HWCap, hwcap_JSCVT) |
|
| 53 |
- ARM64.HasFCMA = isSet(HWCap, hwcap_FCMA) |
|
| 54 |
- ARM64.HasLRCPC = isSet(HWCap, hwcap_LRCPC) |
|
| 55 |
- ARM64.HasDCPOP = isSet(HWCap, hwcap_DCPOP) |
|
| 56 |
- ARM64.HasSHA3 = isSet(HWCap, hwcap_SHA3) |
|
| 57 |
- ARM64.HasSM3 = isSet(HWCap, hwcap_SM3) |
|
| 58 |
- ARM64.HasSM4 = isSet(HWCap, hwcap_SM4) |
|
| 59 |
- ARM64.HasASIMDDP = isSet(HWCap, hwcap_ASIMDDP) |
|
| 60 |
- ARM64.HasSHA512 = isSet(HWCap, hwcap_SHA512) |
|
| 61 |
- ARM64.HasSVE = isSet(HWCap, hwcap_SVE) |
|
| 62 |
- ARM64.HasASIMDFHM = isSet(HWCap, hwcap_ASIMDFHM) |
|
| 63 |
-} |
|
| 64 |
- |
|
| 65 |
-func isSet(hwc uint, value uint) bool {
|
|
| 66 |
- return hwc&value != 0 |
|
| 67 |
-} |
| 68 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,21 @@ |
| 0 |
+// Copyright 2019 The Go Authors. All rights reserved. |
|
| 1 |
+// Use of this source code is governed by a BSD-style |
|
| 2 |
+// license that can be found in the LICENSE file. |
|
| 3 |
+ |
|
| 4 |
+// +build !gccgo |
|
| 5 |
+ |
|
| 6 |
+package cpu |
|
| 7 |
+ |
|
| 8 |
+// haveAsmFunctions reports whether the other functions in this file can |
|
| 9 |
+// be safely called. |
|
| 10 |
+func haveAsmFunctions() bool { return true }
|
|
| 11 |
+ |
|
| 12 |
+// The following feature detection functions are defined in cpu_s390x.s. |
|
| 13 |
+// They are likely to be expensive to call so the results should be cached. |
|
| 14 |
+func stfle() facilityList |
|
| 15 |
+func kmQuery() queryResult |
|
| 16 |
+func kmcQuery() queryResult |
|
| 17 |
+func kmctrQuery() queryResult |
|
| 18 |
+func kmaQuery() queryResult |
|
| 19 |
+func kimdQuery() queryResult |
|
| 20 |
+func klmdQuery() queryResult |
| 0 | 21 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,22 @@ |
| 0 |
+// Copyright 2019 The Go Authors. All rights reserved. |
|
| 1 |
+// Use of this source code is governed by a BSD-style |
|
| 2 |
+// license that can be found in the LICENSE file. |
|
| 3 |
+ |
|
| 4 |
+// +build gccgo |
|
| 5 |
+ |
|
| 6 |
+package cpu |
|
| 7 |
+ |
|
| 8 |
+// haveAsmFunctions reports whether the other functions in this file can |
|
| 9 |
+// be safely called. |
|
| 10 |
+func haveAsmFunctions() bool { return false }
|
|
| 11 |
+ |
|
| 12 |
+// TODO(mundaym): the following feature detection functions are currently |
|
| 13 |
+// stubs. See https://golang.org/cl/162887 for how to fix this. |
|
| 14 |
+// They are likely to be expensive to call so the results should be cached. |
|
| 15 |
+func stfle() facilityList { panic("not implemented for gccgo") }
|
|
| 16 |
+func kmQuery() queryResult { panic("not implemented for gccgo") }
|
|
| 17 |
+func kmcQuery() queryResult { panic("not implemented for gccgo") }
|
|
| 18 |
+func kmctrQuery() queryResult { panic("not implemented for gccgo") }
|
|
| 19 |
+func kmaQuery() queryResult { panic("not implemented for gccgo") }
|
|
| 20 |
+func kimdQuery() queryResult { panic("not implemented for gccgo") }
|
|
| 21 |
+func klmdQuery() queryResult { panic("not implemented for gccgo") }
|
| ... | ... |
@@ -7,9 +7,7 @@ |
| 7 | 7 |
package cpu |
| 8 | 8 |
|
| 9 | 9 |
import ( |
| 10 |
- "encoding/binary" |
|
| 11 | 10 |
"io/ioutil" |
| 12 |
- "runtime" |
|
| 13 | 11 |
) |
| 14 | 12 |
|
| 15 | 13 |
const ( |
| ... | ... |
@@ -18,44 +16,44 @@ const ( |
| 18 | 18 |
|
| 19 | 19 |
procAuxv = "/proc/self/auxv" |
| 20 | 20 |
|
| 21 |
- uintSize uint = 32 << (^uint(0) >> 63) |
|
| 21 |
+ uintSize = int(32 << (^uint(0) >> 63)) |
|
| 22 | 22 |
) |
| 23 | 23 |
|
| 24 | 24 |
// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2 |
| 25 | 25 |
// These are initialized in cpu_$GOARCH.go |
| 26 | 26 |
// and should not be changed after they are initialized. |
| 27 |
-var HWCap uint |
|
| 28 |
-var HWCap2 uint |
|
| 27 |
+var hwCap uint |
|
| 28 |
+var hwCap2 uint |
|
| 29 | 29 |
|
| 30 | 30 |
func init() {
|
| 31 | 31 |
buf, err := ioutil.ReadFile(procAuxv) |
| 32 | 32 |
if err != nil {
|
| 33 |
- panic("read proc auxv failed: " + err.Error())
|
|
| 33 |
+ // e.g. on android /proc/self/auxv is not accessible, so silently |
|
| 34 |
+ // ignore the error and leave Initialized = false |
|
| 35 |
+ return |
|
| 34 | 36 |
} |
| 35 | 37 |
|
| 36 |
- pb := int(uintSize / 8) |
|
| 37 |
- |
|
| 38 |
- for i := 0; i < len(buf)-pb*2; i += pb * 2 {
|
|
| 38 |
+ bo := hostByteOrder() |
|
| 39 |
+ for len(buf) >= 2*(uintSize/8) {
|
|
| 39 | 40 |
var tag, val uint |
| 40 | 41 |
switch uintSize {
|
| 41 | 42 |
case 32: |
| 42 |
- tag = uint(binary.LittleEndian.Uint32(buf[i:])) |
|
| 43 |
- val = uint(binary.LittleEndian.Uint32(buf[i+pb:])) |
|
| 43 |
+ tag = uint(bo.Uint32(buf[0:])) |
|
| 44 |
+ val = uint(bo.Uint32(buf[4:])) |
|
| 45 |
+ buf = buf[8:] |
|
| 44 | 46 |
case 64: |
| 45 |
- if runtime.GOARCH == "ppc64" {
|
|
| 46 |
- tag = uint(binary.BigEndian.Uint64(buf[i:])) |
|
| 47 |
- val = uint(binary.BigEndian.Uint64(buf[i+pb:])) |
|
| 48 |
- } else {
|
|
| 49 |
- tag = uint(binary.LittleEndian.Uint64(buf[i:])) |
|
| 50 |
- val = uint(binary.LittleEndian.Uint64(buf[i+pb:])) |
|
| 51 |
- } |
|
| 47 |
+ tag = uint(bo.Uint64(buf[0:])) |
|
| 48 |
+ val = uint(bo.Uint64(buf[8:])) |
|
| 49 |
+ buf = buf[16:] |
|
| 52 | 50 |
} |
| 53 | 51 |
switch tag {
|
| 54 | 52 |
case _AT_HWCAP: |
| 55 |
- HWCap = val |
|
| 53 |
+ hwCap = val |
|
| 56 | 54 |
case _AT_HWCAP2: |
| 57 |
- HWCap2 = val |
|
| 55 |
+ hwCap2 = val |
|
| 58 | 56 |
} |
| 59 | 57 |
} |
| 60 | 58 |
doinit() |
| 59 |
+ |
|
| 60 |
+ Initialized = true |
|
| 61 | 61 |
} |
| 62 | 62 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,67 @@ |
| 0 |
+// Copyright 2018 The Go Authors. All rights reserved. |
|
| 1 |
+// Use of this source code is governed by a BSD-style |
|
| 2 |
+// license that can be found in the LICENSE file. |
|
| 3 |
+ |
|
| 4 |
+package cpu |
|
| 5 |
+ |
|
| 6 |
+const cacheLineSize = 64 |
|
| 7 |
+ |
|
| 8 |
+// HWCAP/HWCAP2 bits. These are exposed by Linux. |
|
| 9 |
+const ( |
|
| 10 |
+ hwcap_FP = 1 << 0 |
|
| 11 |
+ hwcap_ASIMD = 1 << 1 |
|
| 12 |
+ hwcap_EVTSTRM = 1 << 2 |
|
| 13 |
+ hwcap_AES = 1 << 3 |
|
| 14 |
+ hwcap_PMULL = 1 << 4 |
|
| 15 |
+ hwcap_SHA1 = 1 << 5 |
|
| 16 |
+ hwcap_SHA2 = 1 << 6 |
|
| 17 |
+ hwcap_CRC32 = 1 << 7 |
|
| 18 |
+ hwcap_ATOMICS = 1 << 8 |
|
| 19 |
+ hwcap_FPHP = 1 << 9 |
|
| 20 |
+ hwcap_ASIMDHP = 1 << 10 |
|
| 21 |
+ hwcap_CPUID = 1 << 11 |
|
| 22 |
+ hwcap_ASIMDRDM = 1 << 12 |
|
| 23 |
+ hwcap_JSCVT = 1 << 13 |
|
| 24 |
+ hwcap_FCMA = 1 << 14 |
|
| 25 |
+ hwcap_LRCPC = 1 << 15 |
|
| 26 |
+ hwcap_DCPOP = 1 << 16 |
|
| 27 |
+ hwcap_SHA3 = 1 << 17 |
|
| 28 |
+ hwcap_SM3 = 1 << 18 |
|
| 29 |
+ hwcap_SM4 = 1 << 19 |
|
| 30 |
+ hwcap_ASIMDDP = 1 << 20 |
|
| 31 |
+ hwcap_SHA512 = 1 << 21 |
|
| 32 |
+ hwcap_SVE = 1 << 22 |
|
| 33 |
+ hwcap_ASIMDFHM = 1 << 23 |
|
| 34 |
+) |
|
| 35 |
+ |
|
| 36 |
+func doinit() {
|
|
| 37 |
+ // HWCAP feature bits |
|
| 38 |
+ ARM64.HasFP = isSet(hwCap, hwcap_FP) |
|
| 39 |
+ ARM64.HasASIMD = isSet(hwCap, hwcap_ASIMD) |
|
| 40 |
+ ARM64.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM) |
|
| 41 |
+ ARM64.HasAES = isSet(hwCap, hwcap_AES) |
|
| 42 |
+ ARM64.HasPMULL = isSet(hwCap, hwcap_PMULL) |
|
| 43 |
+ ARM64.HasSHA1 = isSet(hwCap, hwcap_SHA1) |
|
| 44 |
+ ARM64.HasSHA2 = isSet(hwCap, hwcap_SHA2) |
|
| 45 |
+ ARM64.HasCRC32 = isSet(hwCap, hwcap_CRC32) |
|
| 46 |
+ ARM64.HasATOMICS = isSet(hwCap, hwcap_ATOMICS) |
|
| 47 |
+ ARM64.HasFPHP = isSet(hwCap, hwcap_FPHP) |
|
| 48 |
+ ARM64.HasASIMDHP = isSet(hwCap, hwcap_ASIMDHP) |
|
| 49 |
+ ARM64.HasCPUID = isSet(hwCap, hwcap_CPUID) |
|
| 50 |
+ ARM64.HasASIMDRDM = isSet(hwCap, hwcap_ASIMDRDM) |
|
| 51 |
+ ARM64.HasJSCVT = isSet(hwCap, hwcap_JSCVT) |
|
| 52 |
+ ARM64.HasFCMA = isSet(hwCap, hwcap_FCMA) |
|
| 53 |
+ ARM64.HasLRCPC = isSet(hwCap, hwcap_LRCPC) |
|
| 54 |
+ ARM64.HasDCPOP = isSet(hwCap, hwcap_DCPOP) |
|
| 55 |
+ ARM64.HasSHA3 = isSet(hwCap, hwcap_SHA3) |
|
| 56 |
+ ARM64.HasSM3 = isSet(hwCap, hwcap_SM3) |
|
| 57 |
+ ARM64.HasSM4 = isSet(hwCap, hwcap_SM4) |
|
| 58 |
+ ARM64.HasASIMDDP = isSet(hwCap, hwcap_ASIMDDP) |
|
| 59 |
+ ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512) |
|
| 60 |
+ ARM64.HasSVE = isSet(hwCap, hwcap_SVE) |
|
| 61 |
+ ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM) |
|
| 62 |
+} |
|
| 63 |
+ |
|
| 64 |
+func isSet(hwc uint, value uint) bool {
|
|
| 65 |
+ return hwc&value != 0 |
|
| 66 |
+} |
| 0 | 67 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,33 @@ |
| 0 |
+// Copyright 2018 The Go Authors. All rights reserved. |
|
| 1 |
+// Use of this source code is governed by a BSD-style |
|
| 2 |
+// license that can be found in the LICENSE file. |
|
| 3 |
+ |
|
| 4 |
+// +build linux |
|
| 5 |
+// +build ppc64 ppc64le |
|
| 6 |
+ |
|
| 7 |
+package cpu |
|
| 8 |
+ |
|
| 9 |
+const cacheLineSize = 128 |
|
| 10 |
+ |
|
| 11 |
+// HWCAP/HWCAP2 bits. These are exposed by the kernel. |
|
| 12 |
+const ( |
|
| 13 |
+ // ISA Level |
|
| 14 |
+ _PPC_FEATURE2_ARCH_2_07 = 0x80000000 |
|
| 15 |
+ _PPC_FEATURE2_ARCH_3_00 = 0x00800000 |
|
| 16 |
+ |
|
| 17 |
+ // CPU features |
|
| 18 |
+ _PPC_FEATURE2_DARN = 0x00200000 |
|
| 19 |
+ _PPC_FEATURE2_SCV = 0x00100000 |
|
| 20 |
+) |
|
| 21 |
+ |
|
| 22 |
+func doinit() {
|
|
| 23 |
+ // HWCAP2 feature bits |
|
| 24 |
+ PPC64.IsPOWER8 = isSet(hwCap2, _PPC_FEATURE2_ARCH_2_07) |
|
| 25 |
+ PPC64.IsPOWER9 = isSet(hwCap2, _PPC_FEATURE2_ARCH_3_00) |
|
| 26 |
+ PPC64.HasDARN = isSet(hwCap2, _PPC_FEATURE2_DARN) |
|
| 27 |
+ PPC64.HasSCV = isSet(hwCap2, _PPC_FEATURE2_SCV) |
|
| 28 |
+} |
|
| 29 |
+ |
|
| 30 |
+func isSet(hwc uint, value uint) bool {
|
|
| 31 |
+ return hwc&value != 0 |
|
| 32 |
+} |
| 0 | 33 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,161 @@ |
| 0 |
+// Copyright 2019 The Go Authors. All rights reserved. |
|
| 1 |
+// Use of this source code is governed by a BSD-style |
|
| 2 |
+// license that can be found in the LICENSE file. |
|
| 3 |
+ |
|
| 4 |
+package cpu |
|
| 5 |
+ |
|
| 6 |
+const cacheLineSize = 256 |
|
| 7 |
+ |
|
| 8 |
+const ( |
|
| 9 |
+ // bit mask values from /usr/include/bits/hwcap.h |
|
| 10 |
+ hwcap_ZARCH = 2 |
|
| 11 |
+ hwcap_STFLE = 4 |
|
| 12 |
+ hwcap_MSA = 8 |
|
| 13 |
+ hwcap_LDISP = 16 |
|
| 14 |
+ hwcap_EIMM = 32 |
|
| 15 |
+ hwcap_DFP = 64 |
|
| 16 |
+ hwcap_ETF3EH = 256 |
|
| 17 |
+ hwcap_VX = 2048 |
|
| 18 |
+ hwcap_VXE = 8192 |
|
| 19 |
+) |
|
| 20 |
+ |
|
| 21 |
+// bitIsSet reports whether the bit at index is set. The bit index |
|
| 22 |
+// is in big endian order, so bit index 0 is the leftmost bit. |
|
| 23 |
+func bitIsSet(bits []uint64, index uint) bool {
|
|
| 24 |
+ return bits[index/64]&((1<<63)>>(index%64)) != 0 |
|
| 25 |
+} |
|
| 26 |
+ |
|
| 27 |
+// function is the code for the named cryptographic function. |
|
| 28 |
+type function uint8 |
|
| 29 |
+ |
|
| 30 |
+const ( |
|
| 31 |
+ // KM{,A,C,CTR} function codes
|
|
| 32 |
+ aes128 function = 18 // AES-128 |
|
| 33 |
+ aes192 function = 19 // AES-192 |
|
| 34 |
+ aes256 function = 20 // AES-256 |
|
| 35 |
+ |
|
| 36 |
+ // K{I,L}MD function codes
|
|
| 37 |
+ sha1 function = 1 // SHA-1 |
|
| 38 |
+ sha256 function = 2 // SHA-256 |
|
| 39 |
+ sha512 function = 3 // SHA-512 |
|
| 40 |
+ sha3_224 function = 32 // SHA3-224 |
|
| 41 |
+ sha3_256 function = 33 // SHA3-256 |
|
| 42 |
+ sha3_384 function = 34 // SHA3-384 |
|
| 43 |
+ sha3_512 function = 35 // SHA3-512 |
|
| 44 |
+ shake128 function = 36 // SHAKE-128 |
|
| 45 |
+ shake256 function = 37 // SHAKE-256 |
|
| 46 |
+ |
|
| 47 |
+ // KLMD function codes |
|
| 48 |
+ ghash function = 65 // GHASH |
|
| 49 |
+) |
|
| 50 |
+ |
|
| 51 |
+// queryResult contains the result of a Query function |
|
| 52 |
+// call. Bits are numbered in big endian order so the |
|
| 53 |
+// leftmost bit (the MSB) is at index 0. |
|
| 54 |
+type queryResult struct {
|
|
| 55 |
+ bits [2]uint64 |
|
| 56 |
+} |
|
| 57 |
+ |
|
| 58 |
+// Has reports whether the given functions are present. |
|
| 59 |
+func (q *queryResult) Has(fns ...function) bool {
|
|
| 60 |
+ if len(fns) == 0 {
|
|
| 61 |
+ panic("no function codes provided")
|
|
| 62 |
+ } |
|
| 63 |
+ for _, f := range fns {
|
|
| 64 |
+ if !bitIsSet(q.bits[:], uint(f)) {
|
|
| 65 |
+ return false |
|
| 66 |
+ } |
|
| 67 |
+ } |
|
| 68 |
+ return true |
|
| 69 |
+} |
|
| 70 |
+ |
|
| 71 |
+// facility is a bit index for the named facility. |
|
| 72 |
+type facility uint8 |
|
| 73 |
+ |
|
| 74 |
+const ( |
|
| 75 |
+ // cryptography facilities |
|
| 76 |
+ msa4 facility = 77 // message-security-assist extension 4 |
|
| 77 |
+ msa8 facility = 146 // message-security-assist extension 8 |
|
| 78 |
+) |
|
| 79 |
+ |
|
| 80 |
+// facilityList contains the result of an STFLE call. |
|
| 81 |
+// Bits are numbered in big endian order so the |
|
| 82 |
+// leftmost bit (the MSB) is at index 0. |
|
| 83 |
+type facilityList struct {
|
|
| 84 |
+ bits [4]uint64 |
|
| 85 |
+} |
|
| 86 |
+ |
|
| 87 |
+// Has reports whether the given facilities are present. |
|
| 88 |
+func (s *facilityList) Has(fs ...facility) bool {
|
|
| 89 |
+ if len(fs) == 0 {
|
|
| 90 |
+ panic("no facility bits provided")
|
|
| 91 |
+ } |
|
| 92 |
+ for _, f := range fs {
|
|
| 93 |
+ if !bitIsSet(s.bits[:], uint(f)) {
|
|
| 94 |
+ return false |
|
| 95 |
+ } |
|
| 96 |
+ } |
|
| 97 |
+ return true |
|
| 98 |
+} |
|
| 99 |
+ |
|
| 100 |
+func doinit() {
|
|
| 101 |
+ // test HWCAP bit vector |
|
| 102 |
+ has := func(featureMask uint) bool {
|
|
| 103 |
+ return hwCap&featureMask == featureMask |
|
| 104 |
+ } |
|
| 105 |
+ |
|
| 106 |
+ // mandatory |
|
| 107 |
+ S390X.HasZARCH = has(hwcap_ZARCH) |
|
| 108 |
+ |
|
| 109 |
+ // optional |
|
| 110 |
+ S390X.HasSTFLE = has(hwcap_STFLE) |
|
| 111 |
+ S390X.HasLDISP = has(hwcap_LDISP) |
|
| 112 |
+ S390X.HasEIMM = has(hwcap_EIMM) |
|
| 113 |
+ S390X.HasETF3EH = has(hwcap_ETF3EH) |
|
| 114 |
+ S390X.HasDFP = has(hwcap_DFP) |
|
| 115 |
+ S390X.HasMSA = has(hwcap_MSA) |
|
| 116 |
+ S390X.HasVX = has(hwcap_VX) |
|
| 117 |
+ if S390X.HasVX {
|
|
| 118 |
+ S390X.HasVXE = has(hwcap_VXE) |
|
| 119 |
+ } |
|
| 120 |
+ |
|
| 121 |
+ // We need implementations of stfle, km and so on |
|
| 122 |
+ // to detect cryptographic features. |
|
| 123 |
+ if !haveAsmFunctions() {
|
|
| 124 |
+ return |
|
| 125 |
+ } |
|
| 126 |
+ |
|
| 127 |
+ // optional cryptographic functions |
|
| 128 |
+ if S390X.HasMSA {
|
|
| 129 |
+ aes := []function{aes128, aes192, aes256}
|
|
| 130 |
+ |
|
| 131 |
+ // cipher message |
|
| 132 |
+ km, kmc := kmQuery(), kmcQuery() |
|
| 133 |
+ S390X.HasAES = km.Has(aes...) |
|
| 134 |
+ S390X.HasAESCBC = kmc.Has(aes...) |
|
| 135 |
+ if S390X.HasSTFLE {
|
|
| 136 |
+ facilities := stfle() |
|
| 137 |
+ if facilities.Has(msa4) {
|
|
| 138 |
+ kmctr := kmctrQuery() |
|
| 139 |
+ S390X.HasAESCTR = kmctr.Has(aes...) |
|
| 140 |
+ } |
|
| 141 |
+ if facilities.Has(msa8) {
|
|
| 142 |
+ kma := kmaQuery() |
|
| 143 |
+ S390X.HasAESGCM = kma.Has(aes...) |
|
| 144 |
+ } |
|
| 145 |
+ } |
|
| 146 |
+ |
|
| 147 |
+ // compute message digest |
|
| 148 |
+ kimd := kimdQuery() // intermediate (no padding) |
|
| 149 |
+ klmd := klmdQuery() // last (padding) |
|
| 150 |
+ S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1) |
|
| 151 |
+ S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256) |
|
| 152 |
+ S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512) |
|
| 153 |
+ S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist |
|
| 154 |
+ sha3 := []function{
|
|
| 155 |
+ sha3_224, sha3_256, sha3_384, sha3_512, |
|
| 156 |
+ shake128, shake256, |
|
| 157 |
+ } |
|
| 158 |
+ S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...) |
|
| 159 |
+ } |
|
| 160 |
+} |
| 0 | 161 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,11 @@ |
| 0 |
+// Copyright 2019 The Go Authors. All rights reserved. |
|
| 1 |
+// Use of this source code is governed by a BSD-style |
|
| 2 |
+// license that can be found in the LICENSE file. |
|
| 3 |
+ |
|
| 4 |
+// +build !linux,arm64 |
|
| 5 |
+ |
|
| 6 |
+package cpu |
|
| 7 |
+ |
|
| 8 |
+const cacheLineSize = 64 |
|
| 9 |
+ |
|
| 10 |
+func doinit() {}
|
| 0 | 11 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,12 @@ |
| 0 |
+// Copyright 2019 The Go Authors. All rights reserved. |
|
| 1 |
+// Use of this source code is governed by a BSD-style |
|
| 2 |
+// license that can be found in the LICENSE file. |
|
| 3 |
+ |
|
| 4 |
+// +build !linux |
|
| 5 |
+// +build ppc64 ppc64le |
|
| 6 |
+ |
|
| 7 |
+package cpu |
|
| 8 |
+ |
|
| 9 |
+const cacheLineSize = 128 |
|
| 10 |
+ |
|
| 11 |
+func doinit() {}
|
| 0 | 12 |
deleted file mode 100644 |
| ... | ... |
@@ -1,32 +0,0 @@ |
| 1 |
-// Copyright 2018 The Go Authors. All rights reserved. |
|
| 2 |
-// Use of this source code is governed by a BSD-style |
|
| 3 |
-// license that can be found in the LICENSE file. |
|
| 4 |
- |
|
| 5 |
-// +build ppc64 ppc64le |
|
| 6 |
- |
|
| 7 |
-package cpu |
|
| 8 |
- |
|
| 9 |
-const cacheLineSize = 128 |
|
| 10 |
- |
|
| 11 |
-// HWCAP/HWCAP2 bits. These are exposed by the kernel. |
|
| 12 |
-const ( |
|
| 13 |
- // ISA Level |
|
| 14 |
- _PPC_FEATURE2_ARCH_2_07 = 0x80000000 |
|
| 15 |
- _PPC_FEATURE2_ARCH_3_00 = 0x00800000 |
|
| 16 |
- |
|
| 17 |
- // CPU features |
|
| 18 |
- _PPC_FEATURE2_DARN = 0x00200000 |
|
| 19 |
- _PPC_FEATURE2_SCV = 0x00100000 |
|
| 20 |
-) |
|
| 21 |
- |
|
| 22 |
-func doinit() {
|
|
| 23 |
- // HWCAP2 feature bits |
|
| 24 |
- PPC64.IsPOWER8 = isSet(HWCap2, _PPC_FEATURE2_ARCH_2_07) |
|
| 25 |
- PPC64.IsPOWER9 = isSet(HWCap2, _PPC_FEATURE2_ARCH_3_00) |
|
| 26 |
- PPC64.HasDARN = isSet(HWCap2, _PPC_FEATURE2_DARN) |
|
| 27 |
- PPC64.HasSCV = isSet(HWCap2, _PPC_FEATURE2_SCV) |
|
| 28 |
-} |
|
| 29 |
- |
|
| 30 |
-func isSet(hwc uint, value uint) bool {
|
|
| 31 |
- return hwc&value != 0 |
|
| 32 |
-} |
| 10 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,57 @@ |
| 0 |
+// Copyright 2019 The Go Authors. All rights reserved. |
|
| 1 |
+// Use of this source code is governed by a BSD-style |
|
| 2 |
+// license that can be found in the LICENSE file. |
|
| 3 |
+ |
|
| 4 |
+// +build !gccgo |
|
| 5 |
+ |
|
| 6 |
+#include "textflag.h" |
|
| 7 |
+ |
|
| 8 |
+// func stfle() facilityList |
|
| 9 |
+TEXT ·stfle(SB), NOSPLIT|NOFRAME, $0-32 |
|
| 10 |
+ MOVD $ret+0(FP), R1 |
|
| 11 |
+ MOVD $3, R0 // last doubleword index to store |
|
| 12 |
+ XC $32, (R1), (R1) // clear 4 doublewords (32 bytes) |
|
| 13 |
+ WORD $0xb2b01000 // store facility list extended (STFLE) |
|
| 14 |
+ RET |
|
| 15 |
+ |
|
| 16 |
+// func kmQuery() queryResult |
|
| 17 |
+TEXT ·kmQuery(SB), NOSPLIT|NOFRAME, $0-16 |
|
| 18 |
+ MOVD $0, R0 // set function code to 0 (KM-Query) |
|
| 19 |
+ MOVD $ret+0(FP), R1 // address of 16-byte return value |
|
| 20 |
+ WORD $0xB92E0024 // cipher message (KM) |
|
| 21 |
+ RET |
|
| 22 |
+ |
|
| 23 |
+// func kmcQuery() queryResult |
|
| 24 |
+TEXT ·kmcQuery(SB), NOSPLIT|NOFRAME, $0-16 |
|
| 25 |
+ MOVD $0, R0 // set function code to 0 (KMC-Query) |
|
| 26 |
+ MOVD $ret+0(FP), R1 // address of 16-byte return value |
|
| 27 |
+ WORD $0xB92F0024 // cipher message with chaining (KMC) |
|
| 28 |
+ RET |
|
| 29 |
+ |
|
| 30 |
+// func kmctrQuery() queryResult |
|
| 31 |
+TEXT ·kmctrQuery(SB), NOSPLIT|NOFRAME, $0-16 |
|
| 32 |
+ MOVD $0, R0 // set function code to 0 (KMCTR-Query) |
|
| 33 |
+ MOVD $ret+0(FP), R1 // address of 16-byte return value |
|
| 34 |
+ WORD $0xB92D4024 // cipher message with counter (KMCTR) |
|
| 35 |
+ RET |
|
| 36 |
+ |
|
| 37 |
+// func kmaQuery() queryResult |
|
| 38 |
+TEXT ·kmaQuery(SB), NOSPLIT|NOFRAME, $0-16 |
|
| 39 |
+ MOVD $0, R0 // set function code to 0 (KMA-Query) |
|
| 40 |
+ MOVD $ret+0(FP), R1 // address of 16-byte return value |
|
| 41 |
+ WORD $0xb9296024 // cipher message with authentication (KMA) |
|
| 42 |
+ RET |
|
| 43 |
+ |
|
| 44 |
+// func kimdQuery() queryResult |
|
| 45 |
+TEXT ·kimdQuery(SB), NOSPLIT|NOFRAME, $0-16 |
|
| 46 |
+ MOVD $0, R0 // set function code to 0 (KIMD-Query) |
|
| 47 |
+ MOVD $ret+0(FP), R1 // address of 16-byte return value |
|
| 48 |
+ WORD $0xB93E0024 // compute intermediate message digest (KIMD) |
|
| 49 |
+ RET |
|
| 50 |
+ |
|
| 51 |
+// func klmdQuery() queryResult |
|
| 52 |
+TEXT ·klmdQuery(SB), NOSPLIT|NOFRAME, $0-16 |
|
| 53 |
+ MOVD $0, R0 // set function code to 0 (KLMD-Query) |
|
| 54 |
+ MOVD $ret+0(FP), R1 // address of 16-byte return value |
|
| 55 |
+ WORD $0xB93F0024 // compute last message digest (KLMD) |
|
| 56 |
+ RET |
| ... | ... |
@@ -32,7 +32,7 @@ To build the files for your current OS and architecture, make sure GOOS and |
| 32 | 32 |
GOARCH are set correctly and run `mkall.sh`. This will generate the files for |
| 33 | 33 |
your specific system. Running `mkall.sh -n` shows the commands that will be run. |
| 34 | 34 |
|
| 35 |
-Requirements: bash, perl, go |
|
| 35 |
+Requirements: bash, go |
|
| 36 | 36 |
|
| 37 | 37 |
### New Build System (currently for `GOOS == "linux"`) |
| 38 | 38 |
|
| ... | ... |
@@ -52,14 +52,14 @@ system and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will |
| 52 | 52 |
then generate all of the files for all of the GOOS/GOARCH pairs in the new build |
| 53 | 53 |
system. Running `mkall.sh -n` shows the commands that will be run. |
| 54 | 54 |
|
| 55 |
-Requirements: bash, perl, go, docker |
|
| 55 |
+Requirements: bash, go, docker |
|
| 56 | 56 |
|
| 57 | 57 |
## Component files |
| 58 | 58 |
|
| 59 | 59 |
This section describes the various files used in the code generation process. |
| 60 | 60 |
It also contains instructions on how to modify these files to add a new |
| 61 | 61 |
architecture/OS or to add additional syscalls, types, or constants. Note that |
| 62 |
-if you are using the new build system, the scripts cannot be called normally. |
|
| 62 |
+if you are using the new build system, the scripts/programs cannot be called normally. |
|
| 63 | 63 |
They must be called from within the docker container. |
| 64 | 64 |
|
| 65 | 65 |
### asm files |
| ... | ... |
@@ -81,8 +81,8 @@ each GOOS/GOARCH pair. |
| 81 | 81 |
|
| 82 | 82 |
### mksysnum |
| 83 | 83 |
|
| 84 |
-Mksysnum is a script located at `${GOOS}/mksysnum.pl` (or `mksysnum_${GOOS}.pl`
|
|
| 85 |
-for the old system). This script takes in a list of header files containing the |
|
| 84 |
+Mksysnum is a Go program located at `${GOOS}/mksysnum.go` (or `mksysnum_${GOOS}.go`
|
|
| 85 |
+for the old system). This program takes in a list of header files containing the |
|
| 86 | 86 |
syscall number declarations and parses them to produce the corresponding list of |
| 87 | 87 |
Go numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated
|
| 88 | 88 |
constants. |
| ... | ... |
@@ -92,14 +92,14 @@ new installation of the target OS (or updating the source checkouts for the |
| 92 | 92 |
new build system). However, depending on the OS, you make need to update the |
| 93 | 93 |
parsing in mksysnum. |
| 94 | 94 |
|
| 95 |
-### mksyscall.pl |
|
| 95 |
+### mksyscall.go |
|
| 96 | 96 |
|
| 97 | 97 |
The `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are
|
| 98 | 98 |
hand-written Go files which implement system calls (for unix, the specific OS, |
| 99 | 99 |
or the specific OS/Architecture pair respectively) that need special handling |
| 100 | 100 |
and list `//sys` comments giving prototypes for ones that can be generated. |
| 101 | 101 |
|
| 102 |
-The mksyscall.pl script takes the `//sys` and `//sysnb` comments and converts |
|
| 102 |
+The mksyscall.go program takes the `//sys` and `//sysnb` comments and converts |
|
| 103 | 103 |
them into syscalls. This requires the name of the prototype in the comment to |
| 104 | 104 |
match a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function
|
| 105 | 105 |
prototype can be exported (capitalized) or not. |
| ... | ... |
@@ -160,7 +160,7 @@ signal numbers, and constants. Generated by `mkerrors.sh` (see above). |
| 160 | 160 |
### `zsyscall_${GOOS}_${GOARCH}.go`
|
| 161 | 161 |
|
| 162 | 162 |
A file containing all the generated syscalls for a specific GOOS and GOARCH. |
| 163 |
-Generated by `mksyscall.pl` (see above). |
|
| 163 |
+Generated by `mksyscall.go` (see above). |
|
| 164 | 164 |
|
| 165 | 165 |
### `zsysnum_${GOOS}_${GOARCH}.go`
|
| 166 | 166 |
|
| ... | ... |
@@ -25,8 +25,8 @@ func cmsgAlignOf(salen int) int {
|
| 25 | 25 |
if SizeofPtr == 8 {
|
| 26 | 26 |
salign = 4 |
| 27 | 27 |
} |
| 28 |
- case "openbsd": |
|
| 29 |
- // OpenBSD armv7 requires 64-bit alignment. |
|
| 28 |
+ case "netbsd", "openbsd": |
|
| 29 |
+ // NetBSD and OpenBSD armv7 require 64-bit alignment. |
|
| 30 | 30 |
if runtime.GOARCH == "arm" {
|
| 31 | 31 |
salign = 8 |
| 32 | 32 |
} |
| ... | ... |
@@ -416,6 +416,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e |
| 416 | 416 |
//sys Chmod(path string, mode uint32) (err error) |
| 417 | 417 |
//sys Chown(path string, uid int, gid int) (err error) |
| 418 | 418 |
//sys Chroot(path string) (err error) |
| 419 |
+//sys ClockGettime(clockid int32, time *Timespec) (err error) |
|
| 419 | 420 |
//sys Close(fd int) (err error) |
| 420 | 421 |
//sys Dup(fd int) (nfd int, err error) |
| 421 | 422 |
//sys Dup2(from int, to int) (err error) |
| ... | ... |
@@ -994,6 +994,20 @@ func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
|
| 994 | 994 |
return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) |
| 995 | 995 |
} |
| 996 | 996 |
|
| 997 |
+// SetsockoptSockFprog attaches a classic BPF or an extended BPF program to a |
|
| 998 |
+// socket to filter incoming packets. See 'man 7 socket' for usage information. |
|
| 999 |
+func SetsockoptSockFprog(fd, level, opt int, fprog *SockFprog) error {
|
|
| 1000 |
+ return setsockopt(fd, level, opt, unsafe.Pointer(fprog), unsafe.Sizeof(*fprog)) |
|
| 1001 |
+} |
|
| 1002 |
+ |
|
| 1003 |
+func SetsockoptCanRawFilter(fd, level, opt int, filter []CanFilter) error {
|
|
| 1004 |
+ var p unsafe.Pointer |
|
| 1005 |
+ if len(filter) > 0 {
|
|
| 1006 |
+ p = unsafe.Pointer(&filter[0]) |
|
| 1007 |
+ } |
|
| 1008 |
+ return setsockopt(fd, level, opt, p, uintptr(len(filter)*SizeofCanFilter)) |
|
| 1009 |
+} |
|
| 1010 |
+ |
|
| 997 | 1011 |
// Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html) |
| 998 | 1012 |
|
| 999 | 1013 |
// KeyctlInt calls keyctl commands in which each argument is an int. |
| ... | ... |
@@ -28,6 +28,11 @@ var ( |
| 28 | 28 |
errENOENT error = syscall.ENOENT |
| 29 | 29 |
) |
| 30 | 30 |
|
| 31 |
+var ( |
|
| 32 |
+ signalNameMapOnce sync.Once |
|
| 33 |
+ signalNameMap map[string]syscall.Signal |
|
| 34 |
+) |
|
| 35 |
+ |
|
| 31 | 36 |
// errnoErr returns common boxed Errno values, to prevent |
| 32 | 37 |
// allocations at runtime. |
| 33 | 38 |
func errnoErr(e syscall.Errno) error {
|
| ... | ... |
@@ -66,6 +71,19 @@ func SignalName(s syscall.Signal) string {
|
| 66 | 66 |
return "" |
| 67 | 67 |
} |
| 68 | 68 |
|
| 69 |
+// SignalNum returns the syscall.Signal for signal named s, |
|
| 70 |
+// or 0 if a signal with such name is not found. |
|
| 71 |
+// The signal name should start with "SIG". |
|
| 72 |
+func SignalNum(s string) syscall.Signal {
|
|
| 73 |
+ signalNameMapOnce.Do(func() {
|
|
| 74 |
+ signalNameMap = make(map[string]syscall.Signal) |
|
| 75 |
+ for _, signal := range signalList {
|
|
| 76 |
+ signalNameMap[signal.name] = signal.num |
|
| 77 |
+ } |
|
| 78 |
+ }) |
|
| 79 |
+ return signalNameMap[s] |
|
| 80 |
+} |
|
| 81 |
+ |
|
| 69 | 82 |
// clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte. |
| 70 | 83 |
func clen(n []byte) int {
|
| 71 | 84 |
i := bytes.IndexByte(n, 0) |
| ... | ... |
@@ -943,6 +943,21 @@ func libc_chroot_trampoline() |
| 943 | 943 |
|
| 944 | 944 |
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT |
| 945 | 945 |
|
| 946 |
+func ClockGettime(clockid int32, time *Timespec) (err error) {
|
|
| 947 |
+ _, _, e1 := syscall_syscall(funcPC(libc_clock_gettime_trampoline), uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) |
|
| 948 |
+ if e1 != 0 {
|
|
| 949 |
+ err = errnoErr(e1) |
|
| 950 |
+ } |
|
| 951 |
+ return |
|
| 952 |
+} |
|
| 953 |
+ |
|
| 954 |
+func libc_clock_gettime_trampoline() |
|
| 955 |
+ |
|
| 956 |
+//go:linkname libc_clock_gettime libc_clock_gettime |
|
| 957 |
+//go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib" |
|
| 958 |
+ |
|
| 959 |
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT |
|
| 960 |
+ |
|
| 946 | 961 |
func Close(fd int) (err error) {
|
| 947 | 962 |
_, _, e1 := syscall_syscall(funcPC(libc_close_trampoline), uintptr(fd), 0, 0) |
| 948 | 963 |
if e1 != 0 {
|
| ... | ... |
@@ -108,6 +108,8 @@ TEXT ·libc_chown_trampoline(SB),NOSPLIT,$0-0 |
| 108 | 108 |
JMP libc_chown(SB) |
| 109 | 109 |
TEXT ·libc_chroot_trampoline(SB),NOSPLIT,$0-0 |
| 110 | 110 |
JMP libc_chroot(SB) |
| 111 |
+TEXT ·libc_clock_gettime_trampoline(SB),NOSPLIT,$0-0 |
|
| 112 |
+ JMP libc_clock_gettime(SB) |
|
| 111 | 113 |
TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0 |
| 112 | 114 |
JMP libc_close(SB) |
| 113 | 115 |
TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0 |
| ... | ... |
@@ -1,4 +1,4 @@ |
| 1 |
-// mksyscall_solaris.pl -tags solaris,amd64 syscall_solaris.go syscall_solaris_amd64.go |
|
| 1 |
+// go run mksyscall_solaris.go -tags solaris,amd64 syscall_solaris.go syscall_solaris_amd64.go |
|
| 2 | 2 |
// Code generated by the command above; see README.md. DO NOT EDIT. |
| 3 | 3 |
|
| 4 | 4 |
// +build solaris,amd64 |
| ... | ... |
@@ -1,4 +1,4 @@ |
| 1 |
-// go run mksysnum.go /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/sys/syscall.h |
|
| 1 |
+// go run mksysnum.go /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/sys/syscall.h |
|
| 2 | 2 |
// Code generated by the command above; see README.md. DO NOT EDIT. |
| 3 | 3 |
|
| 4 | 4 |
// +build amd64,darwin |
| ... | ... |
@@ -431,6 +431,8 @@ const ( |
| 431 | 431 |
SYS_NTP_ADJTIME = 527 |
| 432 | 432 |
SYS_NTP_GETTIME = 528 |
| 433 | 433 |
SYS_OS_FAULT_WITH_PAYLOAD = 529 |
| 434 |
- SYS_MAXSYSCALL = 530 |
|
| 434 |
+ SYS_KQUEUE_WORKLOOP_CTL = 530 |
|
| 435 |
+ SYS___MACH_BRIDGE_REMOTE_TIME = 531 |
|
| 436 |
+ SYS_MAXSYSCALL = 532 |
|
| 435 | 437 |
SYS_INVALID = 63 |
| 436 | 438 |
) |
| ... | ... |
@@ -405,6 +405,11 @@ type TCPInfo struct {
|
| 405 | 405 |
Total_retrans uint32 |
| 406 | 406 |
} |
| 407 | 407 |
|
| 408 |
+type CanFilter struct {
|
|
| 409 |
+ Id uint32 |
|
| 410 |
+ Mask uint32 |
|
| 411 |
+} |
|
| 412 |
+ |
|
| 408 | 413 |
const ( |
| 409 | 414 |
SizeofSockaddrInet4 = 0x10 |
| 410 | 415 |
SizeofSockaddrInet6 = 0x1c |
| ... | ... |
@@ -434,6 +439,7 @@ const ( |
| 434 | 434 |
SizeofICMPv6Filter = 0x20 |
| 435 | 435 |
SizeofUcred = 0xc |
| 436 | 436 |
SizeofTCPInfo = 0x68 |
| 437 |
+ SizeofCanFilter = 0x8 |
|
| 437 | 438 |
) |
| 438 | 439 |
|
| 439 | 440 |
const ( |
| ... | ... |
@@ -569,6 +575,7 @@ const ( |
| 569 | 569 |
SizeofIfAddrmsg = 0x8 |
| 570 | 570 |
SizeofRtMsg = 0xc |
| 571 | 571 |
SizeofRtNexthop = 0x8 |
| 572 |
+ SizeofNdUseroptmsg = 0x10 |
|
| 572 | 573 |
) |
| 573 | 574 |
|
| 574 | 575 |
type NlMsghdr struct {
|
| ... | ... |
@@ -634,6 +641,17 @@ type RtNexthop struct {
|
| 634 | 634 |
Ifindex int32 |
| 635 | 635 |
} |
| 636 | 636 |
|
| 637 |
+type NdUseroptmsg struct {
|
|
| 638 |
+ Family uint8 |
|
| 639 |
+ Pad1 uint8 |
|
| 640 |
+ Opts_len uint16 |
|
| 641 |
+ Ifindex int32 |
|
| 642 |
+ Icmp_type uint8 |
|
| 643 |
+ Icmp_code uint8 |
|
| 644 |
+ Pad2 uint16 |
|
| 645 |
+ Pad3 uint32 |
|
| 646 |
+} |
|
| 647 |
+ |
|
| 637 | 648 |
const ( |
| 638 | 649 |
SizeofSockFilter = 0x8 |
| 639 | 650 |
SizeofSockFprog = 0x8 |
| ... | ... |
@@ -406,6 +406,11 @@ type TCPInfo struct {
|
| 406 | 406 |
Total_retrans uint32 |
| 407 | 407 |
} |
| 408 | 408 |
|
| 409 |
+type CanFilter struct {
|
|
| 410 |
+ Id uint32 |
|
| 411 |
+ Mask uint32 |
|
| 412 |
+} |
|
| 413 |
+ |
|
| 409 | 414 |
const ( |
| 410 | 415 |
SizeofSockaddrInet4 = 0x10 |
| 411 | 416 |
SizeofSockaddrInet6 = 0x1c |
| ... | ... |
@@ -435,6 +440,7 @@ const ( |
| 435 | 435 |
SizeofICMPv6Filter = 0x20 |
| 436 | 436 |
SizeofUcred = 0xc |
| 437 | 437 |
SizeofTCPInfo = 0x68 |
| 438 |
+ SizeofCanFilter = 0x8 |
|
| 438 | 439 |
) |
| 439 | 440 |
|
| 440 | 441 |
const ( |
| ... | ... |
@@ -570,6 +576,7 @@ const ( |
| 570 | 570 |
SizeofIfAddrmsg = 0x8 |
| 571 | 571 |
SizeofRtMsg = 0xc |
| 572 | 572 |
SizeofRtNexthop = 0x8 |
| 573 |
+ SizeofNdUseroptmsg = 0x10 |
|
| 573 | 574 |
) |
| 574 | 575 |
|
| 575 | 576 |
type NlMsghdr struct {
|
| ... | ... |
@@ -635,6 +642,17 @@ type RtNexthop struct {
|
| 635 | 635 |
Ifindex int32 |
| 636 | 636 |
} |
| 637 | 637 |
|
| 638 |
+type NdUseroptmsg struct {
|
|
| 639 |
+ Family uint8 |
|
| 640 |
+ Pad1 uint8 |
|
| 641 |
+ Opts_len uint16 |
|
| 642 |
+ Ifindex int32 |
|
| 643 |
+ Icmp_type uint8 |
|
| 644 |
+ Icmp_code uint8 |
|
| 645 |
+ Pad2 uint16 |
|
| 646 |
+ Pad3 uint32 |
|
| 647 |
+} |
|
| 648 |
+ |
|
| 638 | 649 |
const ( |
| 639 | 650 |
SizeofSockFilter = 0x8 |
| 640 | 651 |
SizeofSockFprog = 0x10 |
| ... | ... |
@@ -409,6 +409,11 @@ type TCPInfo struct {
|
| 409 | 409 |
Total_retrans uint32 |
| 410 | 410 |
} |
| 411 | 411 |
|
| 412 |
+type CanFilter struct {
|
|
| 413 |
+ Id uint32 |
|
| 414 |
+ Mask uint32 |
|
| 415 |
+} |
|
| 416 |
+ |
|
| 412 | 417 |
const ( |
| 413 | 418 |
SizeofSockaddrInet4 = 0x10 |
| 414 | 419 |
SizeofSockaddrInet6 = 0x1c |
| ... | ... |
@@ -438,6 +443,7 @@ const ( |
| 438 | 438 |
SizeofICMPv6Filter = 0x20 |
| 439 | 439 |
SizeofUcred = 0xc |
| 440 | 440 |
SizeofTCPInfo = 0x68 |
| 441 |
+ SizeofCanFilter = 0x8 |
|
| 441 | 442 |
) |
| 442 | 443 |
|
| 443 | 444 |
const ( |
| ... | ... |
@@ -573,6 +579,7 @@ const ( |
| 573 | 573 |
SizeofIfAddrmsg = 0x8 |
| 574 | 574 |
SizeofRtMsg = 0xc |
| 575 | 575 |
SizeofRtNexthop = 0x8 |
| 576 |
+ SizeofNdUseroptmsg = 0x10 |
|
| 576 | 577 |
) |
| 577 | 578 |
|
| 578 | 579 |
type NlMsghdr struct {
|
| ... | ... |
@@ -638,6 +645,17 @@ type RtNexthop struct {
|
| 638 | 638 |
Ifindex int32 |
| 639 | 639 |
} |
| 640 | 640 |
|
| 641 |
+type NdUseroptmsg struct {
|
|
| 642 |
+ Family uint8 |
|
| 643 |
+ Pad1 uint8 |
|
| 644 |
+ Opts_len uint16 |
|
| 645 |
+ Ifindex int32 |
|
| 646 |
+ Icmp_type uint8 |
|
| 647 |
+ Icmp_code uint8 |
|
| 648 |
+ Pad2 uint16 |
|
| 649 |
+ Pad3 uint32 |
|
| 650 |
+} |
|
| 651 |
+ |
|
| 641 | 652 |
const ( |
| 642 | 653 |
SizeofSockFilter = 0x8 |
| 643 | 654 |
SizeofSockFprog = 0x8 |
| ... | ... |
@@ -407,6 +407,11 @@ type TCPInfo struct {
|
| 407 | 407 |
Total_retrans uint32 |
| 408 | 408 |
} |
| 409 | 409 |
|
| 410 |
+type CanFilter struct {
|
|
| 411 |
+ Id uint32 |
|
| 412 |
+ Mask uint32 |
|
| 413 |
+} |
|
| 414 |
+ |
|
| 410 | 415 |
const ( |
| 411 | 416 |
SizeofSockaddrInet4 = 0x10 |
| 412 | 417 |
SizeofSockaddrInet6 = 0x1c |
| ... | ... |
@@ -436,6 +441,7 @@ const ( |
| 436 | 436 |
SizeofICMPv6Filter = 0x20 |
| 437 | 437 |
SizeofUcred = 0xc |
| 438 | 438 |
SizeofTCPInfo = 0x68 |
| 439 |
+ SizeofCanFilter = 0x8 |
|
| 439 | 440 |
) |
| 440 | 441 |
|
| 441 | 442 |
const ( |
| ... | ... |
@@ -571,6 +577,7 @@ const ( |
| 571 | 571 |
SizeofIfAddrmsg = 0x8 |
| 572 | 572 |
SizeofRtMsg = 0xc |
| 573 | 573 |
SizeofRtNexthop = 0x8 |
| 574 |
+ SizeofNdUseroptmsg = 0x10 |
|
| 574 | 575 |
) |
| 575 | 576 |
|
| 576 | 577 |
type NlMsghdr struct {
|
| ... | ... |
@@ -636,6 +643,17 @@ type RtNexthop struct {
|
| 636 | 636 |
Ifindex int32 |
| 637 | 637 |
} |
| 638 | 638 |
|
| 639 |
+type NdUseroptmsg struct {
|
|
| 640 |
+ Family uint8 |
|
| 641 |
+ Pad1 uint8 |
|
| 642 |
+ Opts_len uint16 |
|
| 643 |
+ Ifindex int32 |
|
| 644 |
+ Icmp_type uint8 |
|
| 645 |
+ Icmp_code uint8 |
|
| 646 |
+ Pad2 uint16 |
|
| 647 |
+ Pad3 uint32 |
|
| 648 |
+} |
|
| 649 |
+ |
|
| 639 | 650 |
const ( |
| 640 | 651 |
SizeofSockFilter = 0x8 |
| 641 | 652 |
SizeofSockFprog = 0x10 |
| ... | ... |
@@ -408,6 +408,11 @@ type TCPInfo struct {
|
| 408 | 408 |
Total_retrans uint32 |
| 409 | 409 |
} |
| 410 | 410 |
|
| 411 |
+type CanFilter struct {
|
|
| 412 |
+ Id uint32 |
|
| 413 |
+ Mask uint32 |
|
| 414 |
+} |
|
| 415 |
+ |
|
| 411 | 416 |
const ( |
| 412 | 417 |
SizeofSockaddrInet4 = 0x10 |
| 413 | 418 |
SizeofSockaddrInet6 = 0x1c |
| ... | ... |
@@ -437,6 +442,7 @@ const ( |
| 437 | 437 |
SizeofICMPv6Filter = 0x20 |
| 438 | 438 |
SizeofUcred = 0xc |
| 439 | 439 |
SizeofTCPInfo = 0x68 |
| 440 |
+ SizeofCanFilter = 0x8 |
|
| 440 | 441 |
) |
| 441 | 442 |
|
| 442 | 443 |
const ( |
| ... | ... |
@@ -572,6 +578,7 @@ const ( |
| 572 | 572 |
SizeofIfAddrmsg = 0x8 |
| 573 | 573 |
SizeofRtMsg = 0xc |
| 574 | 574 |
SizeofRtNexthop = 0x8 |
| 575 |
+ SizeofNdUseroptmsg = 0x10 |
|
| 575 | 576 |
) |
| 576 | 577 |
|
| 577 | 578 |
type NlMsghdr struct {
|
| ... | ... |
@@ -637,6 +644,17 @@ type RtNexthop struct {
|
| 637 | 637 |
Ifindex int32 |
| 638 | 638 |
} |
| 639 | 639 |
|
| 640 |
+type NdUseroptmsg struct {
|
|
| 641 |
+ Family uint8 |
|
| 642 |
+ Pad1 uint8 |
|
| 643 |
+ Opts_len uint16 |
|
| 644 |
+ Ifindex int32 |
|
| 645 |
+ Icmp_type uint8 |
|
| 646 |
+ Icmp_code uint8 |
|
| 647 |
+ Pad2 uint16 |
|
| 648 |
+ Pad3 uint32 |
|
| 649 |
+} |
|
| 650 |
+ |
|
| 640 | 651 |
const ( |
| 641 | 652 |
SizeofSockFilter = 0x8 |
| 642 | 653 |
SizeofSockFprog = 0x8 |
| ... | ... |
@@ -407,6 +407,11 @@ type TCPInfo struct {
|
| 407 | 407 |
Total_retrans uint32 |
| 408 | 408 |
} |
| 409 | 409 |
|
| 410 |
+type CanFilter struct {
|
|
| 411 |
+ Id uint32 |
|
| 412 |
+ Mask uint32 |
|
| 413 |
+} |
|
| 414 |
+ |
|
| 410 | 415 |
const ( |
| 411 | 416 |
SizeofSockaddrInet4 = 0x10 |
| 412 | 417 |
SizeofSockaddrInet6 = 0x1c |
| ... | ... |
@@ -436,6 +441,7 @@ const ( |
| 436 | 436 |
SizeofICMPv6Filter = 0x20 |
| 437 | 437 |
SizeofUcred = 0xc |
| 438 | 438 |
SizeofTCPInfo = 0x68 |
| 439 |
+ SizeofCanFilter = 0x8 |
|
| 439 | 440 |
) |
| 440 | 441 |
|
| 441 | 442 |
const ( |
| ... | ... |
@@ -571,6 +577,7 @@ const ( |
| 571 | 571 |
SizeofIfAddrmsg = 0x8 |
| 572 | 572 |
SizeofRtMsg = 0xc |
| 573 | 573 |
SizeofRtNexthop = 0x8 |
| 574 |
+ SizeofNdUseroptmsg = 0x10 |
|
| 574 | 575 |
) |
| 575 | 576 |
|
| 576 | 577 |
type NlMsghdr struct {
|
| ... | ... |
@@ -636,6 +643,17 @@ type RtNexthop struct {
|
| 636 | 636 |
Ifindex int32 |
| 637 | 637 |
} |
| 638 | 638 |
|
| 639 |
+type NdUseroptmsg struct {
|
|
| 640 |
+ Family uint8 |
|
| 641 |
+ Pad1 uint8 |
|
| 642 |
+ Opts_len uint16 |
|
| 643 |
+ Ifindex int32 |
|
| 644 |
+ Icmp_type uint8 |
|
| 645 |
+ Icmp_code uint8 |
|
| 646 |
+ Pad2 uint16 |
|
| 647 |
+ Pad3 uint32 |
|
| 648 |
+} |
|
| 649 |
+ |
|
| 639 | 650 |
const ( |
| 640 | 651 |
SizeofSockFilter = 0x8 |
| 641 | 652 |
SizeofSockFprog = 0x10 |
| ... | ... |
@@ -407,6 +407,11 @@ type TCPInfo struct {
|
| 407 | 407 |
Total_retrans uint32 |
| 408 | 408 |
} |
| 409 | 409 |
|
| 410 |
+type CanFilter struct {
|
|
| 411 |
+ Id uint32 |
|
| 412 |
+ Mask uint32 |
|
| 413 |
+} |
|
| 414 |
+ |
|
| 410 | 415 |
const ( |
| 411 | 416 |
SizeofSockaddrInet4 = 0x10 |
| 412 | 417 |
SizeofSockaddrInet6 = 0x1c |
| ... | ... |
@@ -436,6 +441,7 @@ const ( |
| 436 | 436 |
SizeofICMPv6Filter = 0x20 |
| 437 | 437 |
SizeofUcred = 0xc |
| 438 | 438 |
SizeofTCPInfo = 0x68 |
| 439 |
+ SizeofCanFilter = 0x8 |
|
| 439 | 440 |
) |
| 440 | 441 |
|
| 441 | 442 |
const ( |
| ... | ... |
@@ -571,6 +577,7 @@ const ( |
| 571 | 571 |
SizeofIfAddrmsg = 0x8 |
| 572 | 572 |
SizeofRtMsg = 0xc |
| 573 | 573 |
SizeofRtNexthop = 0x8 |
| 574 |
+ SizeofNdUseroptmsg = 0x10 |
|
| 574 | 575 |
) |
| 575 | 576 |
|
| 576 | 577 |
type NlMsghdr struct {
|
| ... | ... |
@@ -636,6 +643,17 @@ type RtNexthop struct {
|
| 636 | 636 |
Ifindex int32 |
| 637 | 637 |
} |
| 638 | 638 |
|
| 639 |
+type NdUseroptmsg struct {
|
|
| 640 |
+ Family uint8 |
|
| 641 |
+ Pad1 uint8 |
|
| 642 |
+ Opts_len uint16 |
|
| 643 |
+ Ifindex int32 |
|
| 644 |
+ Icmp_type uint8 |
|
| 645 |
+ Icmp_code uint8 |
|
| 646 |
+ Pad2 uint16 |
|
| 647 |
+ Pad3 uint32 |
|
| 648 |
+} |
|
| 649 |
+ |
|
| 639 | 650 |
const ( |
| 640 | 651 |
SizeofSockFilter = 0x8 |
| 641 | 652 |
SizeofSockFprog = 0x10 |
| ... | ... |
@@ -408,6 +408,11 @@ type TCPInfo struct {
|
| 408 | 408 |
Total_retrans uint32 |
| 409 | 409 |
} |
| 410 | 410 |
|
| 411 |
+type CanFilter struct {
|
|
| 412 |
+ Id uint32 |
|
| 413 |
+ Mask uint32 |
|
| 414 |
+} |
|
| 415 |
+ |
|
| 411 | 416 |
const ( |
| 412 | 417 |
SizeofSockaddrInet4 = 0x10 |
| 413 | 418 |
SizeofSockaddrInet6 = 0x1c |
| ... | ... |
@@ -437,6 +442,7 @@ const ( |
| 437 | 437 |
SizeofICMPv6Filter = 0x20 |
| 438 | 438 |
SizeofUcred = 0xc |
| 439 | 439 |
SizeofTCPInfo = 0x68 |
| 440 |
+ SizeofCanFilter = 0x8 |
|
| 440 | 441 |
) |
| 441 | 442 |
|
| 442 | 443 |
const ( |
| ... | ... |
@@ -572,6 +578,7 @@ const ( |
| 572 | 572 |
SizeofIfAddrmsg = 0x8 |
| 573 | 573 |
SizeofRtMsg = 0xc |
| 574 | 574 |
SizeofRtNexthop = 0x8 |
| 575 |
+ SizeofNdUseroptmsg = 0x10 |
|
| 575 | 576 |
) |
| 576 | 577 |
|
| 577 | 578 |
type NlMsghdr struct {
|
| ... | ... |
@@ -637,6 +644,17 @@ type RtNexthop struct {
|
| 637 | 637 |
Ifindex int32 |
| 638 | 638 |
} |
| 639 | 639 |
|
| 640 |
+type NdUseroptmsg struct {
|
|
| 641 |
+ Family uint8 |
|
| 642 |
+ Pad1 uint8 |
|
| 643 |
+ Opts_len uint16 |
|
| 644 |
+ Ifindex int32 |
|
| 645 |
+ Icmp_type uint8 |
|
| 646 |
+ Icmp_code uint8 |
|
| 647 |
+ Pad2 uint16 |
|
| 648 |
+ Pad3 uint32 |
|
| 649 |
+} |
|
| 650 |
+ |
|
| 640 | 651 |
const ( |
| 641 | 652 |
SizeofSockFilter = 0x8 |
| 642 | 653 |
SizeofSockFprog = 0x8 |
| ... | ... |
@@ -408,6 +408,11 @@ type TCPInfo struct {
|
| 408 | 408 |
Total_retrans uint32 |
| 409 | 409 |
} |
| 410 | 410 |
|
| 411 |
+type CanFilter struct {
|
|
| 412 |
+ Id uint32 |
|
| 413 |
+ Mask uint32 |
|
| 414 |
+} |
|
| 415 |
+ |
|
| 411 | 416 |
const ( |
| 412 | 417 |
SizeofSockaddrInet4 = 0x10 |
| 413 | 418 |
SizeofSockaddrInet6 = 0x1c |
| ... | ... |
@@ -437,6 +442,7 @@ const ( |
| 437 | 437 |
SizeofICMPv6Filter = 0x20 |
| 438 | 438 |
SizeofUcred = 0xc |
| 439 | 439 |
SizeofTCPInfo = 0x68 |
| 440 |
+ SizeofCanFilter = 0x8 |
|
| 440 | 441 |
) |
| 441 | 442 |
|
| 442 | 443 |
const ( |
| ... | ... |
@@ -572,6 +578,7 @@ const ( |
| 572 | 572 |
SizeofIfAddrmsg = 0x8 |
| 573 | 573 |
SizeofRtMsg = 0xc |
| 574 | 574 |
SizeofRtNexthop = 0x8 |
| 575 |
+ SizeofNdUseroptmsg = 0x10 |
|
| 575 | 576 |
) |
| 576 | 577 |
|
| 577 | 578 |
type NlMsghdr struct {
|
| ... | ... |
@@ -637,6 +644,17 @@ type RtNexthop struct {
|
| 637 | 637 |
Ifindex int32 |
| 638 | 638 |
} |
| 639 | 639 |
|
| 640 |
+type NdUseroptmsg struct {
|
|
| 641 |
+ Family uint8 |
|
| 642 |
+ Pad1 uint8 |
|
| 643 |
+ Opts_len uint16 |
|
| 644 |
+ Ifindex int32 |
|
| 645 |
+ Icmp_type uint8 |
|
| 646 |
+ Icmp_code uint8 |
|
| 647 |
+ Pad2 uint16 |
|
| 648 |
+ Pad3 uint32 |
|
| 649 |
+} |
|
| 650 |
+ |
|
| 640 | 651 |
const ( |
| 641 | 652 |
SizeofSockFilter = 0x8 |
| 642 | 653 |
SizeofSockFprog = 0x10 |
| ... | ... |
@@ -408,6 +408,11 @@ type TCPInfo struct {
|
| 408 | 408 |
Total_retrans uint32 |
| 409 | 409 |
} |
| 410 | 410 |
|
| 411 |
+type CanFilter struct {
|
|
| 412 |
+ Id uint32 |
|
| 413 |
+ Mask uint32 |
|
| 414 |
+} |
|
| 415 |
+ |
|
| 411 | 416 |
const ( |
| 412 | 417 |
SizeofSockaddrInet4 = 0x10 |
| 413 | 418 |
SizeofSockaddrInet6 = 0x1c |
| ... | ... |
@@ -437,6 +442,7 @@ const ( |
| 437 | 437 |
SizeofICMPv6Filter = 0x20 |
| 438 | 438 |
SizeofUcred = 0xc |
| 439 | 439 |
SizeofTCPInfo = 0x68 |
| 440 |
+ SizeofCanFilter = 0x8 |
|
| 440 | 441 |
) |
| 441 | 442 |
|
| 442 | 443 |
const ( |
| ... | ... |
@@ -572,6 +578,7 @@ const ( |
| 572 | 572 |
SizeofIfAddrmsg = 0x8 |
| 573 | 573 |
SizeofRtMsg = 0xc |
| 574 | 574 |
SizeofRtNexthop = 0x8 |
| 575 |
+ SizeofNdUseroptmsg = 0x10 |
|
| 575 | 576 |
) |
| 576 | 577 |
|
| 577 | 578 |
type NlMsghdr struct {
|
| ... | ... |
@@ -637,6 +644,17 @@ type RtNexthop struct {
|
| 637 | 637 |
Ifindex int32 |
| 638 | 638 |
} |
| 639 | 639 |
|
| 640 |
+type NdUseroptmsg struct {
|
|
| 641 |
+ Family uint8 |
|
| 642 |
+ Pad1 uint8 |
|
| 643 |
+ Opts_len uint16 |
|
| 644 |
+ Ifindex int32 |
|
| 645 |
+ Icmp_type uint8 |
|
| 646 |
+ Icmp_code uint8 |
|
| 647 |
+ Pad2 uint16 |
|
| 648 |
+ Pad3 uint32 |
|
| 649 |
+} |
|
| 650 |
+ |
|
| 640 | 651 |
const ( |
| 641 | 652 |
SizeofSockFilter = 0x8 |
| 642 | 653 |
SizeofSockFprog = 0x10 |
| ... | ... |
@@ -407,6 +407,11 @@ type TCPInfo struct {
|
| 407 | 407 |
Total_retrans uint32 |
| 408 | 408 |
} |
| 409 | 409 |
|
| 410 |
+type CanFilter struct {
|
|
| 411 |
+ Id uint32 |
|
| 412 |
+ Mask uint32 |
|
| 413 |
+} |
|
| 414 |
+ |
|
| 410 | 415 |
const ( |
| 411 | 416 |
SizeofSockaddrInet4 = 0x10 |
| 412 | 417 |
SizeofSockaddrInet6 = 0x1c |
| ... | ... |
@@ -436,6 +441,7 @@ const ( |
| 436 | 436 |
SizeofICMPv6Filter = 0x20 |
| 437 | 437 |
SizeofUcred = 0xc |
| 438 | 438 |
SizeofTCPInfo = 0x68 |
| 439 |
+ SizeofCanFilter = 0x8 |
|
| 439 | 440 |
) |
| 440 | 441 |
|
| 441 | 442 |
const ( |
| ... | ... |
@@ -571,6 +577,7 @@ const ( |
| 571 | 571 |
SizeofIfAddrmsg = 0x8 |
| 572 | 572 |
SizeofRtMsg = 0xc |
| 573 | 573 |
SizeofRtNexthop = 0x8 |
| 574 |
+ SizeofNdUseroptmsg = 0x10 |
|
| 574 | 575 |
) |
| 575 | 576 |
|
| 576 | 577 |
type NlMsghdr struct {
|
| ... | ... |
@@ -636,6 +643,17 @@ type RtNexthop struct {
|
| 636 | 636 |
Ifindex int32 |
| 637 | 637 |
} |
| 638 | 638 |
|
| 639 |
+type NdUseroptmsg struct {
|
|
| 640 |
+ Family uint8 |
|
| 641 |
+ Pad1 uint8 |
|
| 642 |
+ Opts_len uint16 |
|
| 643 |
+ Ifindex int32 |
|
| 644 |
+ Icmp_type uint8 |
|
| 645 |
+ Icmp_code uint8 |
|
| 646 |
+ Pad2 uint16 |
|
| 647 |
+ Pad3 uint32 |
|
| 648 |
+} |
|
| 649 |
+ |
|
| 639 | 650 |
const ( |
| 640 | 651 |
SizeofSockFilter = 0x8 |
| 641 | 652 |
SizeofSockFprog = 0x10 |
| ... | ... |
@@ -406,6 +406,11 @@ type TCPInfo struct {
|
| 406 | 406 |
Total_retrans uint32 |
| 407 | 407 |
} |
| 408 | 408 |
|
| 409 |
+type CanFilter struct {
|
|
| 410 |
+ Id uint32 |
|
| 411 |
+ Mask uint32 |
|
| 412 |
+} |
|
| 413 |
+ |
|
| 409 | 414 |
const ( |
| 410 | 415 |
SizeofSockaddrInet4 = 0x10 |
| 411 | 416 |
SizeofSockaddrInet6 = 0x1c |
| ... | ... |
@@ -435,6 +440,7 @@ const ( |
| 435 | 435 |
SizeofICMPv6Filter = 0x20 |
| 436 | 436 |
SizeofUcred = 0xc |
| 437 | 437 |
SizeofTCPInfo = 0x68 |
| 438 |
+ SizeofCanFilter = 0x8 |
|
| 438 | 439 |
) |
| 439 | 440 |
|
| 440 | 441 |
const ( |
| ... | ... |
@@ -570,6 +576,7 @@ const ( |
| 570 | 570 |
SizeofIfAddrmsg = 0x8 |
| 571 | 571 |
SizeofRtMsg = 0xc |
| 572 | 572 |
SizeofRtNexthop = 0x8 |
| 573 |
+ SizeofNdUseroptmsg = 0x10 |
|
| 573 | 574 |
) |
| 574 | 575 |
|
| 575 | 576 |
type NlMsghdr struct {
|
| ... | ... |
@@ -635,6 +642,17 @@ type RtNexthop struct {
|
| 635 | 635 |
Ifindex int32 |
| 636 | 636 |
} |
| 637 | 637 |
|
| 638 |
+type NdUseroptmsg struct {
|
|
| 639 |
+ Family uint8 |
|
| 640 |
+ Pad1 uint8 |
|
| 641 |
+ Opts_len uint16 |
|
| 642 |
+ Ifindex int32 |
|
| 643 |
+ Icmp_type uint8 |
|
| 644 |
+ Icmp_code uint8 |
|
| 645 |
+ Pad2 uint16 |
|
| 646 |
+ Pad3 uint32 |
|
| 647 |
+} |
|
| 648 |
+ |
|
| 638 | 649 |
const ( |
| 639 | 650 |
SizeofSockFilter = 0x8 |
| 640 | 651 |
SizeofSockFprog = 0x10 |
| ... | ... |
@@ -410,6 +410,11 @@ type TCPInfo struct {
|
| 410 | 410 |
Total_retrans uint32 |
| 411 | 411 |
} |
| 412 | 412 |
|
| 413 |
+type CanFilter struct {
|
|
| 414 |
+ Id uint32 |
|
| 415 |
+ Mask uint32 |
|
| 416 |
+} |
|
| 417 |
+ |
|
| 413 | 418 |
const ( |
| 414 | 419 |
SizeofSockaddrInet4 = 0x10 |
| 415 | 420 |
SizeofSockaddrInet6 = 0x1c |
| ... | ... |
@@ -439,6 +444,7 @@ const ( |
| 439 | 439 |
SizeofICMPv6Filter = 0x20 |
| 440 | 440 |
SizeofUcred = 0xc |
| 441 | 441 |
SizeofTCPInfo = 0x68 |
| 442 |
+ SizeofCanFilter = 0x8 |
|
| 442 | 443 |
) |
| 443 | 444 |
|
| 444 | 445 |
const ( |
| ... | ... |
@@ -574,6 +580,7 @@ const ( |
| 574 | 574 |
SizeofIfAddrmsg = 0x8 |
| 575 | 575 |
SizeofRtMsg = 0xc |
| 576 | 576 |
SizeofRtNexthop = 0x8 |
| 577 |
+ SizeofNdUseroptmsg = 0x10 |
|
| 577 | 578 |
) |
| 578 | 579 |
|
| 579 | 580 |
type NlMsghdr struct {
|
| ... | ... |
@@ -639,6 +646,17 @@ type RtNexthop struct {
|
| 639 | 639 |
Ifindex int32 |
| 640 | 640 |
} |
| 641 | 641 |
|
| 642 |
+type NdUseroptmsg struct {
|
|
| 643 |
+ Family uint8 |
|
| 644 |
+ Pad1 uint8 |
|
| 645 |
+ Opts_len uint16 |
|
| 646 |
+ Ifindex int32 |
|
| 647 |
+ Icmp_type uint8 |
|
| 648 |
+ Icmp_code uint8 |
|
| 649 |
+ Pad2 uint16 |
|
| 650 |
+ Pad3 uint32 |
|
| 651 |
+} |
|
| 652 |
+ |
|
| 642 | 653 |
const ( |
| 643 | 654 |
SizeofSockFilter = 0x8 |
| 644 | 655 |
SizeofSockFprog = 0x10 |
| ... | ... |
@@ -149,7 +149,7 @@ const ( |
| 149 | 149 |
DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS = 0x22b |
| 150 | 150 |
DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS = 0x22c |
| 151 | 151 |
DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d |
| 152 |
- DOMAIN_ALIAS_RID_MONITORING_USERS = 0X22e |
|
| 152 |
+ DOMAIN_ALIAS_RID_MONITORING_USERS = 0x22e |
|
| 153 | 153 |
DOMAIN_ALIAS_RID_LOGGING_USERS = 0x22f |
| 154 | 154 |
DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS = 0x230 |
| 155 | 155 |
DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS = 0x231 |
| ... | ... |
@@ -80,6 +80,7 @@ type ChangeRequest struct {
|
| 80 | 80 |
EventType uint32 |
| 81 | 81 |
EventData uintptr |
| 82 | 82 |
CurrentStatus Status |
| 83 |
+ Context uintptr |
|
| 83 | 84 |
} |
| 84 | 85 |
|
| 85 | 86 |
// Handler is the interface that must be implemented to build Windows service. |
| ... | ... |
@@ -121,12 +122,11 @@ func init() {
|
| 121 | 121 |
cRegisterServiceCtrlHandlerExW = a.MustFindProc("RegisterServiceCtrlHandlerExW").Addr()
|
| 122 | 122 |
} |
| 123 | 123 |
|
| 124 |
-// The HandlerEx prototype also has a context pointer but since we don't use |
|
| 125 |
-// it at start-up time we don't have to pass it over either. |
|
| 126 | 124 |
type ctlEvent struct {
|
| 127 | 125 |
cmd Cmd |
| 128 | 126 |
eventType uint32 |
| 129 | 127 |
eventData uintptr |
| 128 |
+ context uintptr |
|
| 130 | 129 |
errno uint32 |
| 131 | 130 |
} |
| 132 | 131 |
|
| ... | ... |
@@ -238,13 +238,12 @@ func (s *service) run() {
|
| 238 | 238 |
exitFromHandler <- exitCode{ss, errno}
|
| 239 | 239 |
}() |
| 240 | 240 |
|
| 241 |
- status := Status{State: Stopped}
|
|
| 242 | 241 |
ec := exitCode{isSvcSpecific: true, errno: 0}
|
| 242 |
+ outcr := ChangeRequest{
|
|
| 243 |
+ CurrentStatus: Status{State: Stopped},
|
|
| 244 |
+ } |
|
| 243 | 245 |
var outch chan ChangeRequest |
| 244 | 246 |
inch := s.c |
| 245 |
- var cmd Cmd |
|
| 246 |
- var evtype uint32 |
|
| 247 |
- var evdata uintptr |
|
| 248 | 247 |
loop: |
| 249 | 248 |
for {
|
| 250 | 249 |
select {
|
| ... | ... |
@@ -255,10 +254,11 @@ loop: |
| 255 | 255 |
} |
| 256 | 256 |
inch = nil |
| 257 | 257 |
outch = cmdsToHandler |
| 258 |
- cmd = r.cmd |
|
| 259 |
- evtype = r.eventType |
|
| 260 |
- evdata = r.eventData |
|
| 261 |
- case outch <- ChangeRequest{cmd, evtype, evdata, status}:
|
|
| 258 |
+ outcr.Cmd = r.cmd |
|
| 259 |
+ outcr.EventType = r.eventType |
|
| 260 |
+ outcr.EventData = r.eventData |
|
| 261 |
+ outcr.Context = r.context |
|
| 262 |
+ case outch <- outcr: |
|
| 262 | 263 |
inch = s.c |
| 263 | 264 |
outch = nil |
| 264 | 265 |
case c := <-changesFromHandler: |
| ... | ... |
@@ -271,7 +271,7 @@ loop: |
| 271 | 271 |
} |
| 272 | 272 |
break loop |
| 273 | 273 |
} |
| 274 |
- status = c |
|
| 274 |
+ outcr.CurrentStatus = c |
|
| 275 | 275 |
case ec = <-exitFromHandler: |
| 276 | 276 |
break loop |
| 277 | 277 |
} |
| ... | ... |
@@ -315,8 +315,8 @@ func Run(name string, handler Handler) error {
|
| 315 | 315 |
return err |
| 316 | 316 |
} |
| 317 | 317 |
|
| 318 |
- ctlHandler := func(ctl uint32, evtype uint32, evdata uintptr, context uintptr) uintptr {
|
|
| 319 |
- e := ctlEvent{cmd: Cmd(ctl), eventType: evtype, eventData: evdata}
|
|
| 318 |
+ ctlHandler := func(ctl, evtype, evdata, context uintptr) uintptr {
|
|
| 319 |
+ e := ctlEvent{cmd: Cmd(ctl), eventType: uint32(evtype), eventData: evdata, context: context}
|
|
| 320 | 320 |
// We assume that this callback function is running on |
| 321 | 321 |
// the same thread as Run. Nowhere in MS documentation |
| 322 | 322 |
// I could find statement to guarantee that. So putting |
| ... | ... |
@@ -22,7 +22,8 @@ TEXT ·servicemain(SB),7,$0 |
| 22 | 22 |
MOVL AX, (SP) |
| 23 | 23 |
MOVL $·servicectlhandler(SB), AX |
| 24 | 24 |
MOVL AX, 4(SP) |
| 25 |
- MOVL $0, 8(SP) |
|
| 25 |
+ // Set context to 123456 to test issue #25660. |
|
| 26 |
+ MOVL $123456, 8(SP) |
|
| 26 | 27 |
MOVL ·cRegisterServiceCtrlHandlerExW(SB), AX |
| 27 | 28 |
MOVL SP, BP |
| 28 | 29 |
CALL AX |
| ... | ... |
@@ -14,6 +14,8 @@ TEXT ·servicemain(SB),7,$0 |
| 14 | 14 |
MOVQ ·sName(SB), CX |
| 15 | 15 |
MOVQ $·servicectlhandler(SB), DX |
| 16 | 16 |
// BUG(pastarmovj): Figure out a way to pass in context in R8. |
| 17 |
+ // Set context to 123456 to test issue #25660. |
|
| 18 |
+ MOVQ $123456, R8 |
|
| 17 | 19 |
MOVQ ·cRegisterServiceCtrlHandlerExW(SB), AX |
| 18 | 20 |
CALL AX |
| 19 | 21 |
CMPQ AX, $0 |