Unverified Commit b3079b79 authored by Jacob Blain Christen's avatar Jacob Blain Christen Committed by GitHub

[release-1.17] containerd: v1.3.9-k3s1 (#2630)

Also bumped runc to v1.0.0-rc10 (same as for 1.18 release). Signed-off-by: 's avatarJacob Blain Christen <jacob@rancher.com>
parent 66ca5582
...@@ -7,9 +7,9 @@ replace ( ...@@ -7,9 +7,9 @@ replace (
github.com/containerd/btrfs => github.com/containerd/btrfs v0.0.0-20181101203652-af5082808c83 github.com/containerd/btrfs => github.com/containerd/btrfs v0.0.0-20181101203652-af5082808c83
github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601 github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601
github.com/containerd/console => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50 github.com/containerd/console => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50
github.com/containerd/containerd => github.com/rancher/containerd v1.3.3-k3s2 github.com/containerd/containerd => github.com/k3s-io/containerd v1.3.9-k3s1
github.com/containerd/continuity => github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02 github.com/containerd/continuity => github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02
github.com/containerd/cri => github.com/rancher/cri v1.3.0-k3s.5 github.com/containerd/cri => github.com/k3s-io/cri v1.3.0-k3s.9 // k3s-release/1.3
github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c
github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda
github.com/containerd/typeurl => github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd github.com/containerd/typeurl => github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd
......
...@@ -456,6 +456,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1 ...@@ -456,6 +456,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
...@@ -463,6 +464,7 @@ github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj ...@@ -463,6 +464,7 @@ github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-memdb v1.0.0/go.mod h1:I6dKdmYhZqU0RJSheVEWgTNWdVQH5QvTgIUQ0t/t32M= github.com/hashicorp/go-memdb v1.0.0/go.mod h1:I6dKdmYhZqU0RJSheVEWgTNWdVQH5QvTgIUQ0t/t32M=
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-plugin v1.0.0/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= github.com/hashicorp/go-plugin v1.0.0/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
...@@ -515,6 +517,10 @@ github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVE ...@@ -515,6 +517,10 @@ github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVE
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
github.com/juju/testing v0.0.0-20190613124551-e81189438503/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= github.com/juju/testing v0.0.0-20190613124551-e81189438503/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
github.com/k3s-io/containerd v1.3.9-k3s1 h1:VeMMmcojFZDJlLkgtIr7GAmDUgtGS7ME3KvLo9g/6+s=
github.com/k3s-io/containerd v1.3.9-k3s1/go.mod h1:eMCLnqhZCzg+cZuvfMLStYPsrx5cWGpdZL6krPhK8RI=
github.com/k3s-io/cri v1.3.0-k3s.9 h1:1PUJysV7YQElM5JEjnHdOQ2kgwtTiSJ5fpx1j4/WjzU=
github.com/k3s-io/cri v1.3.0-k3s.9/go.mod h1:fGPUUHMKQik/vIegSe05DtX/m4miovdtvVLqRUFAkK0=
github.com/k3s-io/kubernetes v1.17.14-k3s1 h1:qI3+vAOjxo1rANfoSqpUf+e/o36tSAgXc/p7JofSYMU= github.com/k3s-io/kubernetes v1.17.14-k3s1 h1:qI3+vAOjxo1rANfoSqpUf+e/o36tSAgXc/p7JofSYMU=
github.com/k3s-io/kubernetes v1.17.14-k3s1/go.mod h1:J8bqjhrOYZ/dDhaQU8sEfM+aH81x3Urfw1uODZc7ZfU= github.com/k3s-io/kubernetes v1.17.14-k3s1/go.mod h1:J8bqjhrOYZ/dDhaQU8sEfM+aH81x3Urfw1uODZc7ZfU=
github.com/k3s-io/kubernetes/staging/src/k8s.io/api v1.17.14-k3s1 h1:Z83y7Wd7Hg6/i+rZJZ0HUf+q2k8u8jE7PJg/aLbcoIA= github.com/k3s-io/kubernetes/staging/src/k8s.io/api v1.17.14-k3s1 h1:Z83y7Wd7Hg6/i+rZJZ0HUf+q2k8u8jE7PJg/aLbcoIA=
...@@ -743,10 +749,6 @@ github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1: ...@@ -743,10 +749,6 @@ github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:
github.com/quobyte/api v0.1.2/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI= github.com/quobyte/api v0.1.2/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI=
github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8 h1:83l9gPhYtgxODlZKU0Odq4pQuDcMZEVgAh364+PV3OU= github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8 h1:83l9gPhYtgxODlZKU0Odq4pQuDcMZEVgAh364+PV3OU=
github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8/go.mod h1:4XHkfaUj+URzGO9sohoAgt2V9Y8nIW7fugpu0E6gShk= github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8/go.mod h1:4XHkfaUj+URzGO9sohoAgt2V9Y8nIW7fugpu0E6gShk=
github.com/rancher/containerd v1.3.3-k3s2 h1:RZr+TqFt7+YsrSYkyytlhW4HmneWeFNM7IymNOoGW6A=
github.com/rancher/containerd v1.3.3-k3s2/go.mod h1:ZMfzmqce2Z+QSEqdHMfeJs1TZ/UeJ1aDrazjpQT4ehM=
github.com/rancher/cri v1.3.0-k3s.5 h1:qYhzSaOkWbvAvYcXSn2s5/qfcnUDweYy0m1CPUunehQ=
github.com/rancher/cri v1.3.0-k3s.5/go.mod h1:Ht5T1dIKzm+4NExmb7wDVG6qR+j0xeXIjjhCv1d9geY=
github.com/rancher/cri-tools v1.17.0-k3s1 h1:jfu97FowbraTDc7b6fxWtO+dq+DU2oW+ABBQSEFiRb0= github.com/rancher/cri-tools v1.17.0-k3s1 h1:jfu97FowbraTDc7b6fxWtO+dq+DU2oW+ABBQSEFiRb0=
github.com/rancher/cri-tools v1.17.0-k3s1/go.mod h1:bRTZttsvk+nCG8tSFs8D6UUx8CkMXR5TAsRLS0fXAqI= github.com/rancher/cri-tools v1.17.0-k3s1/go.mod h1:bRTZttsvk+nCG8tSFs8D6UUx8CkMXR5TAsRLS0fXAqI=
github.com/rancher/dynamiclistener v0.2.0 h1:KucYwJXVVGhZ/NndfMCeQoCafT/VN7kvqSGgmlX8Lxk= github.com/rancher/dynamiclistener v0.2.0 h1:KucYwJXVVGhZ/NndfMCeQoCafT/VN7kvqSGgmlX8Lxk=
......
...@@ -13,7 +13,7 @@ environment: ...@@ -13,7 +13,7 @@ environment:
GOPATH: C:\gopath GOPATH: C:\gopath
CGO_ENABLED: 1 CGO_ENABLED: 1
matrix: matrix:
- GO_VERSION: 1.12.15 - GO_VERSION: 1.13.12
before_build: before_build:
- choco install -y mingw --version 5.3.0 - choco install -y mingw --version 5.3.0
......
...@@ -15,7 +15,7 @@ linters: ...@@ -15,7 +15,7 @@ linters:
- errcheck - errcheck
run: run:
deadline: 2m deadline: 3m
skip-dirs: skip-dirs:
- api - api
- design - design
......
Abhinandan Prativadi <abhi@docker.com> Abhinandan Prativadi <abhi@docker.com>
Abhinandan Prativadi <abhi@docker.com> <aprativadi@gmail.com> Abhinandan Prativadi <abhi@docker.com> <aprativadi@gmail.com>
Ace-Tang <aceapril@126.com>
Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp> <suda.akihiro@lab.ntt.co.jp> Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp> <suda.akihiro@lab.ntt.co.jp>
Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp> <suda.kyoto@gmail.com> Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp> <suda.kyoto@gmail.com>
Allen Sun <shlallen1990@gmail.com> <allensun@AllenSundeMacBook-Pro.local>
Alexander Morozov <lk4d4math@gmail.com> <lk4d4@docker.com>
Amit Krishnan <krish.amit@gmail.com> <amit.krishnan@oracle.com>
Andrei Vagin <avagin@virtuozzo.com> <avagin@openvz.org> Andrei Vagin <avagin@virtuozzo.com> <avagin@openvz.org>
Andrey Kolomentsev <andrey.kolomentsev@gmail.com> Andrey Kolomentsev <andrey.kolomentsev@gmail.com>
Arnaud Porterie <icecrime@gmail.com>
Arnaud Porterie <icecrime@gmail.com> <arnaud.porterie@docker.com>
Bob Mader <swapdisk@users.noreply.github.com>
Boris Popovschi <zyqsempai@mail.ru>
Bowen Yan <loneybw@gmail.com>
Brent Baude <bbaude@redhat.com> Brent Baude <bbaude@redhat.com>
Cao Zhihao <caozhihao@163.com>
Cao Zhihao <caozhihao@163.com> <caozhihao.xd@bytedance.com>
Carlos Eduardo <me@carlosedp.com> <me@carlosedp.com> Carlos Eduardo <me@carlosedp.com> <me@carlosedp.com>
Cristian Staretu <cristian.staretu@gmail.com>
Cristian Staretu <cristian.staretu@gmail.com> <unclejack@users.noreply.github.com>
Daniel Dao <dqminh89@gmail.com>
Edgar Lee <edgarl@netflix.com> <edgar.lee@docker.com>
Eric Ren <renzhen.rz@alibaba-linux.com> <renzhen.rz@alibaba-inc.com> Eric Ren <renzhen.rz@alibaba-linux.com> <renzhen.rz@alibaba-inc.com>
Fahed Dorgaa <fahed.dorgaa@gmail.com>
Frank Yang <yyb196@gmail.com> Frank Yang <yyb196@gmail.com>
Fupan Li <lifupan@gmail.com>
Georgia Panoutsakopoulou <gpanoutsak@gmail.com> Georgia Panoutsakopoulou <gpanoutsak@gmail.com>
Guangming Wang <guangming.wang@daocloud.io> Guangming Wang <guangming.wang@daocloud.io>
Haiyan Meng <haiyanmeng@google.com> Haiyan Meng <haiyanmeng@google.com>
Harry Zhang <harryz@hyper.sh> <harryzhang@zju.edu.cn>
Hu Shuai <hus.fnst@cn.fujitsu.com>
Hu Shuai <hus.fnst@cn.fujitsu.com> <hushuaiia@qq.com>
Jaana Burcu Dogan <burcujdogan@gmail.com> <jbd@golang.org>
Jess Valarezo <valarezo.jessica@gmail.com>
Jess Valarezo <valarezo.jessica@gmail.com> <jessica.valarezo@docker.com>
Jian Liao <jliao@alauda.io> Jian Liao <jliao@alauda.io>
Jian Liao <jliao@alauda.io> <liaojian@Dabllo.local> Jian Liao <jliao@alauda.io> <liaojian@Dabllo.local>
Ji'an Liu <anthonyliu@zju.edu.cn> Ji'an Liu <anthonyliu@zju.edu.cn>
Jie Zhang <iamkadisi@163.com> Jie Zhang <iamkadisi@163.com>
John Howard <john.howard@microsoft.com> <jhoward@microsoft.com> John Howard <github@lowenna.com>
John Howard <john.howard@microsoft.com> <jhowardmsft@users.noreply.github.com> John Howard <github@lowenna.com> <john.howard@microsoft.com>
John Howard <github@lowenna.com> <jhoward@microsoft.com>
John Howard <github@lowenna.com> <jhowardmsft@users.noreply.github.com>
Luc Perkins <lucperkins@gmail.com>
Julien Balestra <julien.balestra@datadoghq.com> Julien Balestra <julien.balestra@datadoghq.com>
Justin Cormack <justin.cormack@docker.com> <justin@specialbusservice.com> Justin Cormack <justin.cormack@docker.com> <justin@specialbusservice.com>
Justin Terry <juterry@microsoft.com> Justin Terry <juterry@microsoft.com>
Justin Terry <juterry@microsoft.com> <jterry75@users.noreply.github.com> Justin Terry <juterry@microsoft.com> <jterry75@users.noreply.github.com>
Kenfe-Mickaël Laventure <mickael.laventure@gmail.com> Kenfe-Mickaël Laventure <mickael.laventure@gmail.com>
Kevin Kern <kaiwentan@harmonycloud.cn>
Kevin Xu <cming.xu@gmail.com> Kevin Xu <cming.xu@gmail.com>
Kohei Tokunaga <ktokunaga.mail@gmail.com>
Krasi Georgiev <krasi.root@gmail.com> <krasi@vip-consult.solutions>
Lantao Liu <lantaol@google.com>
Lantao Liu <lantaol@google.com> <taotaotheripper@gmail.com> Lantao Liu <lantaol@google.com> <taotaotheripper@gmail.com>
Lifubang <lifubang@aliyun.com> <lifubang@acmcoder.com> Lifubang <lifubang@aliyun.com> <lifubang@acmcoder.com>
Lu Jingxiao <lujingxiao@huawei.com> Lu Jingxiao <lujingxiao@huawei.com>
Maksym Pavlenko <makpav@amazon.com> <pavlenko.maksym@gmail.com> Maksym Pavlenko <makpav@amazon.com> <pavlenko.maksym@gmail.com>
Mario Hros <spam@k3a.me>
Mario Hros <spam@k3a.me> <root@k3a.me>
Mark Gordon <msg555@gmail.com> Mark Gordon <msg555@gmail.com>
Michael Katsoulis <michaelkatsoulis88@gmail.com> Michael Katsoulis <michaelkatsoulis88@gmail.com>
Mike Brown <brownwm@us.ibm.com> <mikebrow@users.noreply.github.com> Mike Brown <brownwm@us.ibm.com> <mikebrow@users.noreply.github.com>
Nishchay Kumar <mrawesomenix@gmail.com> Nishchay Kumar <mrawesomenix@gmail.com>
Oliver Stenbom <oliver@stenbom.eu> <ostenbom@pivotal.io>
Phil Estes <estesp@gmail.com> <estesp@linux.vnet.ibm.com> Phil Estes <estesp@gmail.com> <estesp@linux.vnet.ibm.com>
Reid Li <reid.li@utexas.edu>
Ross Boucher <rboucher@gmail.com>
Ruediger Maass <ruediger.maass@de.ibm.com>
Rui Cao <ruicao@alauda.io> <ruicao@alauda.io> Rui Cao <ruicao@alauda.io> <ruicao@alauda.io>
Sakeven Jiang <jc5930@sina.cn>
Seth Pellegrino <spellegrino@newrelic.com> <30441101+sethp-nr@users.noreply.github.com>
Shengbo Song <thomassong@tencent.com>
Stephen J Day <stevvooe@gmail.com> <stephen.day@getcruise.com> Stephen J Day <stevvooe@gmail.com> <stephen.day@getcruise.com>
Stephen J Day <stevvooe@gmail.com> <stevvooe@users.noreply.github.com> Stephen J Day <stevvooe@gmail.com> <stevvooe@users.noreply.github.com>
Stephen J Day <stevvooe@gmail.com> <stephen.day@docker.com> Stephen J Day <stevvooe@gmail.com> <stephen.day@docker.com>
...@@ -42,8 +81,12 @@ Tõnis Tiigi <tonistiigi@gmail.com> ...@@ -42,8 +81,12 @@ Tõnis Tiigi <tonistiigi@gmail.com>
Wei Fu <fuweid89@gmail.com> <fhfuwei@163.com> Wei Fu <fuweid89@gmail.com> <fhfuwei@163.com>
Xiaodong Zhang <a4012017@sina.com> Xiaodong Zhang <a4012017@sina.com>
Xuean Yan <yan.xuean@zte.com.cn> Xuean Yan <yan.xuean@zte.com.cn>
Yue Zhang <zy675793960@yeah.net>
Yuxing Liu <starnop@163.com> Yuxing Liu <starnop@163.com>
zhenguang zhu <zhengguang.zhu@daocloud.io> Zhang Wei <zhangwei555@huawei.com>
zhongming chang<zhongming.chang@daocloud.io> Zhenguang Zhu <zhengguang.zhu@daocloud.io>
zhoulin xie <zhoulin.xie@daocloud.io> Zhiyu Li <payall4u@qq.com> <404977848@qq.com>
zhoulin xie <zhoulin.xie@daocloud.io> <42261994+JoeWrightss@users.noreply.github.com> Zhongming Chang<zhongming.chang@daocloud.io>
Zhoulin Xie <zhoulin.xie@daocloud.io>
Zhoulin Xie <zhoulin.xie@daocloud.io> <42261994+JoeWrightss@users.noreply.github.com>
张潇 <xiaozhang0210@hotmail.com>
...@@ -4,19 +4,24 @@ sudo: required ...@@ -4,19 +4,24 @@ sudo: required
services: services:
- docker - docker
branches:
except:
- master
- release/1.3
language: go language: go
os: os:
- linux - linux
go: go:
- "1.12.15" - "1.13.15"
env: env:
- TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runc.v1 TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=bionic - TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runc.v1 TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=bionic GOPROXY=direct
- TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runc.v2 TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=bionic TRAVIS_RELEASE=yes - TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runc.v2 TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=bionic TRAVIS_RELEASE=yes GOPROXY=direct
- TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runtime.v1.linux TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=bionic - TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runtime.v1.linux TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=bionic GOPROXY=direct
- TRAVIS_GOOS=darwin TRAVIS_CGO_ENABLED=0 - TRAVIS_GOOS=darwin TRAVIS_CGO_ENABLED=0 GOPROXY=direct
matrix: matrix:
include: include:
...@@ -24,7 +29,7 @@ matrix: ...@@ -24,7 +29,7 @@ matrix:
- if: type != pull_request - if: type != pull_request
os: linux os: linux
dist: xenial dist: xenial
env: TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runc.v2 TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=xenial env: TRAVIS_GOOS=linux TEST_RUNTIME=io.containerd.runc.v2 TRAVIS_CGO_ENABLED=1 TRAVIS_DISTRO=xenial GOPROXY=direct
go_import_path: github.com/containerd/containerd go_import_path: github.com/containerd/containerd
...@@ -73,7 +78,7 @@ script: ...@@ -73,7 +78,7 @@ script:
- DCO_VERBOSITY=-q ../project/script/validate/dco - DCO_VERBOSITY=-q ../project/script/validate/dco
- ../project/script/validate/fileheader ../project/ - ../project/script/validate/fileheader ../project/
- travis_wait ../project/script/validate/vendor - travis_wait ../project/script/validate/vendor
- GOOS=linux script/setup/install-dev-tools - GOOS=linux GO111MODULE=off script/setup/install-dev-tools
- go build -i . - go build -i .
- make check - make check
- if [ "$GOOS" = "linux" ]; then make check-protos check-api-descriptors; fi - if [ "$GOOS" = "linux" ]; then make check-protos check-api-descriptors; fi
......
...@@ -207,7 +207,7 @@ Next, let's build `runc`: ...@@ -207,7 +207,7 @@ Next, let's build `runc`:
```sh ```sh
cd /go/src/github.com/opencontainers/runc cd /go/src/github.com/opencontainers/runc
make BUILDTAGS='seccomp apparmor' && make install make BUILDTAGS='seccomp apparmor selinux' && make install
``` ```
When working with `ctr`, the simple test client we just built, don't forget to start the daemon! When working with `ctr`, the simple test client we just built, don't forget to start the daemon!
......
...@@ -87,7 +87,7 @@ endif ...@@ -87,7 +87,7 @@ endif
# Project binaries. # Project binaries.
COMMANDS=ctr containerd containerd-stress COMMANDS=ctr containerd containerd-stress
MANPAGES=ctr.1 containerd.1 containerd-config.1 containerd-config.toml.5 MANPAGES=ctr.8 containerd.8 containerd-config.8 containerd-config.toml.5
ifdef BUILDTAGS ifdef BUILDTAGS
GO_BUILDTAGS = ${BUILDTAGS} GO_BUILDTAGS = ${BUILDTAGS}
...@@ -209,15 +209,15 @@ mandir: ...@@ -209,15 +209,15 @@ mandir:
@mkdir -p man @mkdir -p man
# Kept for backwards compatability # Kept for backwards compatability
genman: man/containerd.1 man/ctr.1 genman: man/containerd.8 man/ctr.8
man/containerd.1: FORCE man/containerd.8: FORCE
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
go run cmd/gen-manpages/main.go containerd man/ go run cmd/gen-manpages/main.go $(@F) $(@D)
man/ctr.1: FORCE man/ctr.8: FORCE
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
go run cmd/gen-manpages/main.go ctr man/ go run cmd/gen-manpages/main.go $(@F) $(@D)
man/%: docs/man/%.md FORCE man/%: docs/man/%.md FORCE
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
......
...@@ -52,6 +52,6 @@ containerd is designed to be embedded into a larger system, hence it only includ ...@@ -52,6 +52,6 @@ containerd is designed to be embedded into a larger system, hence it only includ
### How is the scope changed? ### How is the scope changed?
The scope of this project is a whitelist. The scope of this project is an allowed list.
If it's not mentioned as being in scope, it is out of scope. If it's not mentioned as being in scope, it is out of scope.
For the scope of this project to change it requires a 100% vote from all maintainers of the project. For the scope of this project to change it requires a 100% vote from all maintainers of the project.
...@@ -71,7 +71,7 @@ var ( ...@@ -71,7 +71,7 @@ var (
func init() { func init() {
flag.BoolVar(&debugFlag, "debug", false, "enable debug output in logs") flag.BoolVar(&debugFlag, "debug", false, "enable debug output in logs")
flag.StringVar(&namespaceFlag, "namespace", "", "namespace that owns the shim") flag.StringVar(&namespaceFlag, "namespace", "", "namespace that owns the shim")
flag.StringVar(&socketFlag, "socket", "", "abstract socket path to serve") flag.StringVar(&socketFlag, "socket", "", "socket path to serve")
flag.StringVar(&addressFlag, "address", "", "grpc address back to main containerd") flag.StringVar(&addressFlag, "address", "", "grpc address back to main containerd")
flag.StringVar(&workdirFlag, "workdir", "", "path used to storge large temporary data") flag.StringVar(&workdirFlag, "workdir", "", "path used to storge large temporary data")
flag.StringVar(&runtimeRootFlag, "runtime-root", process.RuncRoot, "root directory for the runtime") flag.StringVar(&runtimeRootFlag, "runtime-root", process.RuncRoot, "root directory for the runtime")
...@@ -202,10 +202,18 @@ func serve(ctx context.Context, server *ttrpc.Server, path string) error { ...@@ -202,10 +202,18 @@ func serve(ctx context.Context, server *ttrpc.Server, path string) error {
f.Close() f.Close()
path = "[inherited from parent]" path = "[inherited from parent]"
} else { } else {
if len(path) > 106 { const (
return errors.Errorf("%q: unix socket path too long (> 106)", path) abstractSocketPrefix = "\x00"
socketPathLimit = 106
)
p := strings.TrimPrefix(path, "unix://")
if len(p) == len(path) {
p = abstractSocketPrefix + p
}
if len(p) > socketPathLimit {
return errors.Errorf("%q: unix socket path too long (> %d)", p, socketPathLimit)
} }
l, err = net.Listen("unix", "\x00"+path) l, err = net.Listen("unix", p)
} }
if err != nil { if err != nil {
return err return err
......
...@@ -227,6 +227,10 @@ can be used and modified as necessary as a custom configuration.` ...@@ -227,6 +227,10 @@ can be used and modified as necessary as a custom configuration.`
} }
serve(ctx, l, server.ServeGRPC) serve(ctx, l, server.ServeGRPC)
if err := notifyReady(ctx); err != nil {
log.G(ctx).WithError(err).Warn("notify ready failed")
}
log.G(ctx).Infof("containerd successfully booted in %fs", time.Since(start).Seconds()) log.G(ctx).Infof("containerd successfully booted in %fs", time.Since(start).Seconds())
<-done <-done
return nil return nil
......
...@@ -52,6 +52,10 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se ...@@ -52,6 +52,10 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se
case unix.SIGPIPE: case unix.SIGPIPE:
continue continue
default: default:
if err := notifyStopping(ctx); err != nil {
log.G(ctx).WithError(err).Error("notify stopping failed")
}
if server == nil { if server == nil {
close(done) close(done)
return return
......
...@@ -51,6 +51,11 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se ...@@ -51,6 +51,11 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se
server = s server = s
case s := <-signals: case s := <-signals:
log.G(ctx).WithField("signal", s).Debug("received signal") log.G(ctx).WithField("signal", s).Debug("received signal")
if err := notifyStopping(ctx); err != nil {
log.G(ctx).WithError(err).Error("notify stopping failed")
}
if server == nil { if server == nil {
close(done) close(done)
return return
......
// +build linux
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package command
import (
"context"
"os"
sd "github.com/coreos/go-systemd/daemon"
"github.com/containerd/containerd/log"
)
const (
// SdNotifyReady tells the service manager that service startup is finished
// or the service finished loading its configuration.
SdNotifyReady = "READY=1"
// SdNotifyStopping tells the service manager that the service is beginning
// its shutdown.
SdNotifyStopping = "STOPPING=1"
)
// notifyReady notifies systemd that the daemon is ready to serve requests
func notifyReady(ctx context.Context) error {
return sdNotify(ctx, SdNotifyReady)
}
// notifyStopping notifies systemd that the daemon is about to be stopped
func notifyStopping(ctx context.Context) error {
return sdNotify(ctx, SdNotifyStopping)
}
func sdNotify(ctx context.Context, state string) error {
if os.Getenv("NOTIFY_SOCKET") != "" {
notified, err := sd.SdNotify(false, state)
log.G(ctx).
WithError(err).
WithField("notified", notified).
WithField("state", state).
Debug("sd notification")
return err
}
return nil
}
// +build !linux
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package command
import (
"context"
)
func notifyReady(ctx context.Context) error {
return nil
}
func notifyStopping(ctx context.Context) error {
return nil
}
...@@ -49,8 +49,6 @@ var ( ...@@ -49,8 +49,6 @@ var (
allocConsole = kernel32.NewProc("AllocConsole") allocConsole = kernel32.NewProc("AllocConsole")
oldStderr windows.Handle oldStderr windows.Handle
panicFile *os.File panicFile *os.File
service *handler
) )
const defaultServiceName = "containerd" const defaultServiceName = "containerd"
...@@ -282,7 +280,6 @@ func launchService(s *server.Server, done chan struct{}) error { ...@@ -282,7 +280,6 @@ func launchService(s *server.Server, done chan struct{}) error {
return err return err
} }
service = h
go func() { go func() {
if interactive { if interactive {
err = debug.Run(serviceNameFlag, h) err = debug.Run(serviceNameFlag, h)
...@@ -350,8 +347,8 @@ func initPanicFile(path string) error { ...@@ -350,8 +347,8 @@ func initPanicFile(path string) error {
// Update STD_ERROR_HANDLE to point to the panic file so that Go writes to // Update STD_ERROR_HANDLE to point to the panic file so that Go writes to
// it when it panics. Remember the old stderr to restore it before removing // it when it panics. Remember the old stderr to restore it before removing
// the panic file. // the panic file.
sh := windows.STD_ERROR_HANDLE sh := uint32(windows.STD_ERROR_HANDLE)
h, err := windows.GetStdHandle(uint32(sh)) h, err := windows.GetStdHandle(sh)
if err != nil { if err != nil {
return err return err
} }
...@@ -375,7 +372,7 @@ func initPanicFile(path string) error { ...@@ -375,7 +372,7 @@ func initPanicFile(path string) error {
func removePanicFile() { func removePanicFile() {
if st, err := panicFile.Stat(); err == nil { if st, err := panicFile.Stat(); err == nil {
if st.Size() == 0 { if st.Size() == 0 {
sh := windows.STD_ERROR_HANDLE sh := uint32(windows.STD_ERROR_HANDLE)
setStdHandle.Call(uintptr(sh), uintptr(oldStderr)) setStdHandle.Call(uintptr(sh), uintptr(oldStderr))
panicFile.Close() panicFile.Close()
os.Remove(panicFile.Name()) os.Remove(panicFile.Name())
......
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"io/ioutil" "io/ioutil"
"net" "net"
"path/filepath" "path/filepath"
"strings"
"github.com/containerd/console" "github.com/containerd/console"
"github.com/containerd/containerd/cmd/ctr/commands" "github.com/containerd/containerd/cmd/ctr/commands"
...@@ -240,10 +241,11 @@ func getTaskService(context *cli.Context) (task.TaskService, error) { ...@@ -240,10 +241,11 @@ func getTaskService(context *cli.Context) (task.TaskService, error) {
s1 := filepath.Join(string(filepath.Separator), "containerd-shim", ns, id, "shim.sock") s1 := filepath.Join(string(filepath.Separator), "containerd-shim", ns, id, "shim.sock")
// this should not error, ctr always get a default ns // this should not error, ctr always get a default ns
ctx := namespaces.WithNamespace(gocontext.Background(), ns) ctx := namespaces.WithNamespace(gocontext.Background(), ns)
s2, _ := shim.SocketAddress(ctx, id) s2, _ := shim.SocketAddress(ctx, context.GlobalString("address"), id)
s2 = strings.TrimPrefix(s2, "unix://")
for _, socket := range []string{s1, s2} { for _, socket := range []string{s2, "\x00" + s1} {
conn, err := net.Dial("unix", "\x00"+socket) conn, err := net.Dial("unix", socket)
if err == nil { if err == nil {
client := ttrpc.NewClient(conn) client := ttrpc.NewClient(conn)
......
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
"syscall" "syscall"
"github.com/containerd/containerd" "github.com/containerd/containerd"
"github.com/containerd/containerd/errdefs"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
...@@ -36,8 +37,16 @@ func ForwardAllSignals(ctx gocontext.Context, task killer) chan os.Signal { ...@@ -36,8 +37,16 @@ func ForwardAllSignals(ctx gocontext.Context, task killer) chan os.Signal {
signal.Notify(sigc) signal.Notify(sigc)
go func() { go func() {
for s := range sigc { for s := range sigc {
if canIgnoreSignal(s) {
logrus.Debugf("Ignoring signal %s", s)
continue
}
logrus.Debug("forwarding signal ", s) logrus.Debug("forwarding signal ", s)
if err := task.Kill(ctx, s.(syscall.Signal)); err != nil { if err := task.Kill(ctx, s.(syscall.Signal)); err != nil {
if errdefs.IsNotFound(err) {
logrus.WithError(err).Debugf("Not forwarding signal %s", s)
return
}
logrus.WithError(err).Errorf("forward signal %s", s) logrus.WithError(err).Errorf("forward signal %s", s)
} }
} }
......
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package commands
import (
"os"
"golang.org/x/sys/unix"
)
func canIgnoreSignal(s os.Signal) bool {
return s == unix.SIGURG
}
//+build !linux
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package commands
import "os"
func canIgnoreSignal(_ os.Signal) bool {
return false
}
...@@ -32,6 +32,7 @@ import ( ...@@ -32,6 +32,7 @@ import (
"github.com/containerd/containerd/images" "github.com/containerd/containerd/images"
"github.com/containerd/containerd/oci" "github.com/containerd/containerd/oci"
"github.com/containerd/containerd/runtime/v2/runc/options" "github.com/containerd/containerd/runtime/v2/runc/options"
"github.com/containerd/containerd/sys"
"github.com/containerd/typeurl" "github.com/containerd/typeurl"
prototypes "github.com/gogo/protobuf/types" prototypes "github.com/gogo/protobuf/types"
ver "github.com/opencontainers/image-spec/specs-go" ver "github.com/opencontainers/image-spec/specs-go"
...@@ -422,14 +423,33 @@ func attachExistingIO(response *tasks.GetResponse, ioAttach cio.Attach) (cio.IO, ...@@ -422,14 +423,33 @@ func attachExistingIO(response *tasks.GetResponse, ioAttach cio.Attach) (cio.IO,
// loadFifos loads the containers fifos // loadFifos loads the containers fifos
func loadFifos(response *tasks.GetResponse) *cio.FIFOSet { func loadFifos(response *tasks.GetResponse) *cio.FIFOSet {
path := getFifoDir([]string{ fifos := []string{
response.Process.Stdin, response.Process.Stdin,
response.Process.Stdout, response.Process.Stdout,
response.Process.Stderr, response.Process.Stderr,
}) }
closer := func() error { closer := func() error {
return os.RemoveAll(path) var (
err error
dirs = map[string]struct{}{}
)
for _, fifo := range fifos {
if isFifo, _ := sys.IsFifo(fifo); isFifo {
if rerr := os.Remove(fifo); err == nil {
err = rerr
}
dirs[filepath.Dir(fifo)] = struct{}{}
}
}
for dir := range dirs {
// we ignore errors here because we don't
// want to remove the directory if it isn't
// empty
os.Remove(dir)
}
return err
} }
return cio.NewFIFOSet(cio.Config{ return cio.NewFIFOSet(cio.Config{
Stdin: response.Process.Stdin, Stdin: response.Process.Stdin,
Stdout: response.Process.Stdout, Stdout: response.Process.Stdout,
...@@ -437,14 +457,3 @@ func loadFifos(response *tasks.GetResponse) *cio.FIFOSet { ...@@ -437,14 +457,3 @@ func loadFifos(response *tasks.GetResponse) *cio.FIFOSet {
Terminal: response.Process.Terminal, Terminal: response.Process.Terminal,
}, closer) }, closer)
} }
// getFifoDir looks for any non-empty path for a stdio fifo
// and returns the dir for where it is located
func getFifoDir(paths []string) string {
for _, p := range paths {
if p != "" {
return filepath.Dir(p)
}
}
return ""
}
...@@ -87,21 +87,21 @@ func WithRestoreRuntime(ctx context.Context, id string, client *Client, checkpoi ...@@ -87,21 +87,21 @@ func WithRestoreRuntime(ctx context.Context, id string, client *Client, checkpoi
return err return err
} }
} }
var options *ptypes.Any var options ptypes.Any
if m != nil { if m != nil {
store := client.ContentStore() store := client.ContentStore()
data, err := content.ReadBlob(ctx, store, *m) data, err := content.ReadBlob(ctx, store, *m)
if err != nil { if err != nil {
return errors.Wrap(err, "unable to read checkpoint runtime") return errors.Wrap(err, "unable to read checkpoint runtime")
} }
if err := proto.Unmarshal(data, options); err != nil { if err := proto.Unmarshal(data, &options); err != nil {
return err return err
} }
} }
c.Runtime = containers.RuntimeInfo{ c.Runtime = containers.RuntimeInfo{
Name: name, Name: name,
Options: options, Options: &options,
} }
return nil return nil
} }
......
...@@ -7,9 +7,11 @@ After=network.target local-fs.target ...@@ -7,9 +7,11 @@ After=network.target local-fs.target
ExecStartPre=-/sbin/modprobe overlay ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerd ExecStart=/usr/local/bin/containerd
Type=notify
Delegate=yes Delegate=yes
KillMode=process KillMode=process
Restart=always Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead # Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting. # in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity LimitNPROC=infinity
...@@ -18,6 +20,7 @@ LimitNOFILE=1048576 ...@@ -18,6 +20,7 @@ LimitNOFILE=1048576
# Comment TasksMax if your systemd version does not supports it. # Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version. # Only systemd 226 and above support this version.
TasksMax=infinity TasksMax=infinity
OOMScoreAdjust=-999
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
...@@ -47,7 +47,7 @@ func arches() []specs.Arch { ...@@ -47,7 +47,7 @@ func arches() []specs.Arch {
} }
} }
// DefaultProfile defines the whitelist for the default seccomp profile. // DefaultProfile defines the allowed syscalls for the default seccomp profile.
func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
syscalls := []specs.LinuxSyscall{ syscalls := []specs.LinuxSyscall{
{ {
...@@ -55,7 +55,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -55,7 +55,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"accept", "accept",
"accept4", "accept4",
"access", "access",
"alarm", "adjtimex",
"alarm", "alarm",
"bind", "bind",
"brk", "brk",
...@@ -65,9 +65,14 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -65,9 +65,14 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"chmod", "chmod",
"chown", "chown",
"chown32", "chown32",
"clock_adjtime",
"clock_adjtime64",
"clock_getres", "clock_getres",
"clock_getres_time64",
"clock_gettime", "clock_gettime",
"clock_gettime64",
"clock_nanosleep", "clock_nanosleep",
"clock_nanosleep_time64",
"close", "close",
"connect", "connect",
"copy_file_range", "copy_file_range",
...@@ -89,6 +94,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -89,6 +94,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"exit", "exit",
"exit_group", "exit_group",
"faccessat", "faccessat",
"faccessat2",
"fadvise64", "fadvise64",
"fadvise64_64", "fadvise64_64",
"fallocate", "fallocate",
...@@ -117,6 +123,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -117,6 +123,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"ftruncate", "ftruncate",
"ftruncate64", "ftruncate64",
"futex", "futex",
"futex_time64",
"futimesat", "futimesat",
"getcpu", "getcpu",
"getcwd", "getcwd",
...@@ -163,10 +170,14 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -163,10 +170,14 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"io_destroy", "io_destroy",
"io_getevents", "io_getevents",
"io_pgetevents", "io_pgetevents",
"io_pgetevents_time64",
"ioprio_get", "ioprio_get",
"ioprio_set", "ioprio_set",
"io_setup", "io_setup",
"io_submit", "io_submit",
"io_uring_enter",
"io_uring_register",
"io_uring_setup",
"ipc", "ipc",
"kill", "kill",
"lchown", "lchown",
...@@ -184,6 +195,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -184,6 +195,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"lstat", "lstat",
"lstat64", "lstat64",
"madvise", "madvise",
"membarrier",
"memfd_create", "memfd_create",
"mincore", "mincore",
"mkdir", "mkdir",
...@@ -200,7 +212,9 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -200,7 +212,9 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"mq_notify", "mq_notify",
"mq_open", "mq_open",
"mq_timedreceive", "mq_timedreceive",
"mq_timedreceive_time64",
"mq_timedsend", "mq_timedsend",
"mq_timedsend_time64",
"mq_unlink", "mq_unlink",
"mremap", "mremap",
"msgctl", "msgctl",
...@@ -216,18 +230,23 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -216,18 +230,23 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"_newselect", "_newselect",
"open", "open",
"openat", "openat",
"openat2",
"pause", "pause",
"pipe", "pipe",
"pipe2", "pipe2",
"poll", "poll",
"ppoll", "ppoll",
"ppoll_time64",
"prctl", "prctl",
"pread64", "pread64",
"preadv", "preadv",
"preadv2",
"prlimit64", "prlimit64",
"pselect6", "pselect6",
"pselect6_time64",
"pwrite64", "pwrite64",
"pwritev", "pwritev",
"pwritev2",
"read", "read",
"readahead", "readahead",
"readlink", "readlink",
...@@ -236,6 +255,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -236,6 +255,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"recv", "recv",
"recvfrom", "recvfrom",
"recvmmsg", "recvmmsg",
"recvmmsg_time64",
"recvmsg", "recvmsg",
"remap_file_pages", "remap_file_pages",
"removexattr", "removexattr",
...@@ -244,6 +264,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -244,6 +264,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"renameat2", "renameat2",
"restart_syscall", "restart_syscall",
"rmdir", "rmdir",
"rseq",
"rt_sigaction", "rt_sigaction",
"rt_sigpending", "rt_sigpending",
"rt_sigprocmask", "rt_sigprocmask",
...@@ -251,6 +272,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -251,6 +272,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"rt_sigreturn", "rt_sigreturn",
"rt_sigsuspend", "rt_sigsuspend",
"rt_sigtimedwait", "rt_sigtimedwait",
"rt_sigtimedwait_time64",
"rt_tgsigqueueinfo", "rt_tgsigqueueinfo",
"sched_getaffinity", "sched_getaffinity",
"sched_getattr", "sched_getattr",
...@@ -259,6 +281,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -259,6 +281,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"sched_get_priority_min", "sched_get_priority_min",
"sched_getscheduler", "sched_getscheduler",
"sched_rr_get_interval", "sched_rr_get_interval",
"sched_rr_get_interval_time64",
"sched_setaffinity", "sched_setaffinity",
"sched_setattr", "sched_setattr",
"sched_setparam", "sched_setparam",
...@@ -270,6 +293,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -270,6 +293,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"semget", "semget",
"semop", "semop",
"semtimedop", "semtimedop",
"semtimedop_time64",
"send", "send",
"sendfile", "sendfile",
"sendfile64", "sendfile64",
...@@ -329,18 +353,21 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -329,18 +353,21 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"sync_file_range", "sync_file_range",
"syncfs", "syncfs",
"sysinfo", "sysinfo",
"syslog",
"tee", "tee",
"tgkill", "tgkill",
"time", "time",
"timer_create", "timer_create",
"timer_delete", "timer_delete",
"timerfd_create",
"timerfd_gettime",
"timerfd_settime",
"timer_getoverrun", "timer_getoverrun",
"timer_gettime", "timer_gettime",
"timer_gettime64",
"timer_settime", "timer_settime",
"timer_settime64",
"timerfd_create",
"timerfd_gettime",
"timerfd_gettime64",
"timerfd_settime",
"timerfd_settime64",
"times", "times",
"tkill", "tkill",
"truncate", "truncate",
...@@ -352,6 +379,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -352,6 +379,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"unlinkat", "unlinkat",
"utime", "utime",
"utimensat", "utimensat",
"utimensat_time64",
"utimes", "utimes",
"vfork", "vfork",
"vmsplice", "vmsplice",
...@@ -392,6 +420,28 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -392,6 +420,28 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
Args: []specs.LinuxSeccompArg{ Args: []specs.LinuxSeccompArg{
{ {
Index: 0, Index: 0,
Value: 0x20000,
Op: specs.OpEqualTo,
},
},
},
{
Names: []string{"personality"},
Action: specs.ActAllow,
Args: []specs.LinuxSeccompArg{
{
Index: 0,
Value: 0x20008,
Op: specs.OpEqualTo,
},
},
},
{
Names: []string{"personality"},
Action: specs.ActAllow,
Args: []specs.LinuxSeccompArg{
{
Index: 0,
Value: 0xffffffff, Value: 0xffffffff,
Op: specs.OpEqualTo, Op: specs.OpEqualTo,
}, },
...@@ -407,11 +457,20 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -407,11 +457,20 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
// include by arch // include by arch
switch runtime.GOARCH { switch runtime.GOARCH {
case "ppc64le":
s.Syscalls = append(s.Syscalls, specs.LinuxSyscall{
Names: []string{
"sync_file_range2",
},
Action: specs.ActAllow,
Args: []specs.LinuxSeccompArg{},
})
case "arm", "arm64": case "arm", "arm64":
s.Syscalls = append(s.Syscalls, specs.LinuxSyscall{ s.Syscalls = append(s.Syscalls, specs.LinuxSyscall{
Names: []string{ Names: []string{
"arm_fadvise64_64", "arm_fadvise64_64",
"arm_sync_file_range", "arm_sync_file_range",
"sync_file_range2",
"breakpoint", "breakpoint",
"cacheflush", "cacheflush",
"set_tls", "set_tls",
...@@ -468,9 +527,11 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -468,9 +527,11 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"mount", "mount",
"name_to_handle_at", "name_to_handle_at",
"perf_event_open", "perf_event_open",
"quotactl",
"setdomainname", "setdomainname",
"sethostname", "sethostname",
"setns", "setns",
"syslog",
"umount", "umount",
"umount2", "umount2",
"unshare", "unshare",
...@@ -496,7 +557,6 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -496,7 +557,6 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
"delete_module", "delete_module",
"init_module", "init_module",
"finit_module", "finit_module",
"query_module",
}, },
Action: specs.ActAllow, Action: specs.ActAllow,
Args: []specs.LinuxSeccompArg{}, Args: []specs.LinuxSeccompArg{},
...@@ -532,7 +592,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -532,7 +592,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
Names: []string{ Names: []string{
"settimeofday", "settimeofday",
"stime", "stime",
"adjtimex", "clock_settime",
}, },
Action: specs.ActAllow, Action: specs.ActAllow,
Args: []specs.LinuxSeccompArg{}, Args: []specs.LinuxSeccompArg{},
...@@ -543,6 +603,12 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { ...@@ -543,6 +603,12 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
Action: specs.ActAllow, Action: specs.ActAllow,
Args: []specs.LinuxSeccompArg{}, Args: []specs.LinuxSeccompArg{},
}) })
case "CAP_SYSLOG":
s.Syscalls = append(s.Syscalls, specs.LinuxSyscall{
Names: []string{"syslog"},
Action: specs.ActAllow,
Args: []specs.LinuxSeccompArg{},
})
} }
} }
......
...@@ -20,7 +20,7 @@ package seccomp ...@@ -20,7 +20,7 @@ package seccomp
import specs "github.com/opencontainers/runtime-spec/specs-go" import specs "github.com/opencontainers/runtime-spec/specs-go"
// DefaultProfile defines the whitelist for the default seccomp profile. // DefaultProfile defines the allowed syscalls for the default seccomp profile.
func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp { func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
return &specs.LinuxSeccomp{} return &specs.LinuxSeccomp{}
} }
...@@ -197,6 +197,7 @@ func (i *image) Usage(ctx context.Context, opts ...UsageOpt) (int64, error) { ...@@ -197,6 +197,7 @@ func (i *image) Usage(ctx context.Context, opts ...UsageOpt) (int64, error) {
desc.Size = info.Size desc.Size = info.Size
} }
if config.snapshots {
for k, v := range info.Labels { for k, v := range info.Labels {
const prefix = "containerd.io/gc.ref.snapshot." const prefix = "containerd.io/gc.ref.snapshot."
if !strings.HasPrefix(k, prefix) { if !strings.HasPrefix(k, prefix) {
...@@ -218,6 +219,7 @@ func (i *image) Usage(ctx context.Context, opts ...UsageOpt) (int64, error) { ...@@ -218,6 +219,7 @@ func (i *image) Usage(ctx context.Context, opts ...UsageOpt) (int64, error) {
} }
} }
} }
}
// Ignore unknown sizes. Generally unknown sizes should // Ignore unknown sizes. Generally unknown sizes should
// never be set in manifests, however, the usage // never be set in manifests, however, the usage
......
...@@ -181,7 +181,7 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader, opt ...@@ -181,7 +181,7 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader, opt
Layers: layers, Layers: layers,
} }
desc, err := writeManifest(ctx, store, manifest, ocispec.MediaTypeImageManifest) desc, err := writeManifest(ctx, store, manifest, manifest.MediaType)
if err != nil { if err != nil {
return ocispec.Descriptor{}, errors.Wrap(err, "write docker manifest") return ocispec.Descriptor{}, errors.Wrap(err, "write docker manifest")
} }
......
...@@ -29,15 +29,20 @@ import ( ...@@ -29,15 +29,20 @@ import (
"sync" "sync"
"sync/atomic" "sync/atomic"
"syscall" "syscall"
"time"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/pkg/stdio" "github.com/containerd/containerd/pkg/stdio"
"github.com/containerd/containerd/sys"
"github.com/containerd/fifo" "github.com/containerd/fifo"
runc "github.com/containerd/go-runc" runc "github.com/containerd/go-runc"
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
const binaryIOProcTermTimeout = 12 * time.Second // Give logger process solid 10 seconds for cleanup
var bufPool = sync.Pool{ var bufPool = sync.Pool{
New: func() interface{} { New: func() interface{} {
// setting to 4096 to align with PIPE_BUF // setting to 4096 to align with PIPE_BUF
...@@ -174,7 +179,7 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w ...@@ -174,7 +179,7 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w
}, },
}, },
} { } {
ok, err := isFifo(i.name) ok, err := sys.IsFifo(i.name)
if err != nil { if err != nil {
return err return err
} }
...@@ -240,28 +245,13 @@ func (c *countingWriteCloser) Close() error { ...@@ -240,28 +245,13 @@ func (c *countingWriteCloser) Close() error {
return c.WriteCloser.Close() return c.WriteCloser.Close()
} }
// isFifo checks if a file is a fifo
// if the file does not exist then it returns false
func isFifo(path string) (bool, error) {
stat, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
if stat.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
return true, nil
}
return false, nil
}
// NewBinaryIO runs a custom binary process for pluggable shim logging // NewBinaryIO runs a custom binary process for pluggable shim logging
func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error) { func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (_ runc.IO, err error) {
ns, err := namespaces.NamespaceRequired(ctx) ns, err := namespaces.NamespaceRequired(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var args []string var args []string
for k, vs := range uri.Query() { for k, vs := range uri.Query() {
args = append(args, k) args = append(args, k)
...@@ -269,48 +259,64 @@ func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error) ...@@ -269,48 +259,64 @@ func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error)
args = append(args, vs[0]) args = append(args, vs[0])
} }
} }
ctx, cancel := context.WithCancel(ctx)
cmd := exec.CommandContext(ctx, uri.Path, args...) var closers []func() error
cmd.Env = append(cmd.Env, defer func() {
"CONTAINER_ID="+id, if err == nil {
"CONTAINER_NAMESPACE="+ns, return
) }
result := multierror.Append(err)
for _, fn := range closers {
result = multierror.Append(result, fn())
}
err = multierror.Flatten(result)
}()
out, err := newPipe() out, err := newPipe()
if err != nil { if err != nil {
cancel() return nil, errors.Wrap(err, "failed to create stdout pipes")
return nil, err
} }
closers = append(closers, out.Close)
serr, err := newPipe() serr, err := newPipe()
if err != nil { if err != nil {
cancel() return nil, errors.Wrap(err, "failed to create stderr pipes")
return nil, err
} }
closers = append(closers, serr.Close)
r, w, err := os.Pipe() r, w, err := os.Pipe()
if err != nil { if err != nil {
cancel()
return nil, err return nil, err
} }
closers = append(closers, r.Close, w.Close)
cmd := exec.Command(uri.Path, args...)
cmd.Env = append(cmd.Env,
"CONTAINER_ID="+id,
"CONTAINER_NAMESPACE="+ns,
)
cmd.ExtraFiles = append(cmd.ExtraFiles, out.r, serr.r, w) cmd.ExtraFiles = append(cmd.ExtraFiles, out.r, serr.r, w)
// don't need to register this with the reaper or wait when // don't need to register this with the reaper or wait when
// running inside a shim // running inside a shim
if err := cmd.Start(); err != nil { if err := cmd.Start(); err != nil {
cancel() return nil, errors.Wrap(err, "failed to start binary process")
return nil, err
} }
closers = append(closers, func() error { return cmd.Process.Kill() })
// close our side of the pipe after start // close our side of the pipe after start
if err := w.Close(); err != nil { if err := w.Close(); err != nil {
cancel() return nil, errors.Wrap(err, "failed to close write pipe after start")
return nil, err
} }
// wait for the logging binary to be ready // wait for the logging binary to be ready
b := make([]byte, 1) b := make([]byte, 1)
if _, err := r.Read(b); err != nil && err != io.EOF { if _, err := r.Read(b); err != nil && err != io.EOF {
cancel() return nil, errors.Wrap(err, "failed to read from logging binary")
return nil, err
} }
return &binaryIO{ return &binaryIO{
cmd: cmd, cmd: cmd,
cancel: cancel,
out: out, out: out,
err: serr, err: serr,
}, nil }, nil
...@@ -318,37 +324,81 @@ func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error) ...@@ -318,37 +324,81 @@ func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error)
type binaryIO struct { type binaryIO struct {
cmd *exec.Cmd cmd *exec.Cmd
cancel func()
out, err *pipe out, err *pipe
} }
func (b *binaryIO) CloseAfterStart() (err error) { func (b *binaryIO) CloseAfterStart() error {
for _, v := range []*pipe{ var (
b.out, result *multierror.Error
b.err, )
} {
for _, v := range []*pipe{b.out, b.err} {
if v != nil { if v != nil {
if cerr := v.r.Close(); err == nil { if err := v.r.Close(); err != nil {
err = cerr result = multierror.Append(result, err)
} }
} }
} }
return err
return result.ErrorOrNil()
} }
func (b *binaryIO) Close() (err error) { func (b *binaryIO) Close() error {
b.cancel() var (
for _, v := range []*pipe{ result *multierror.Error
b.out, )
b.err,
} { for _, v := range []*pipe{b.out, b.err} {
if v != nil { if v != nil {
if cerr := v.Close(); err == nil { if err := v.Close(); err != nil {
err = cerr result = multierror.Append(result, err)
}
}
} }
if err := b.cancel(); err != nil {
result = multierror.Append(result, err)
} }
return result.ErrorOrNil()
}
func (b *binaryIO) cancel() error {
if b.cmd == nil || b.cmd.Process == nil {
return nil
}
// Send SIGTERM first, so logger process has a chance to flush and exit properly
if err := b.cmd.Process.Signal(syscall.SIGTERM); err != nil {
result := multierror.Append(errors.Wrap(err, "failed to send SIGTERM"))
log.L.WithError(err).Warn("failed to send SIGTERM signal, killing logging shim")
if err := b.cmd.Process.Kill(); err != nil {
result = multierror.Append(result, errors.Wrap(err, "failed to kill process after faulty SIGTERM"))
} }
return result.ErrorOrNil()
}
done := make(chan error)
go func() {
done <- b.cmd.Wait()
}()
select {
case err := <-done:
return err return err
case <-time.After(binaryIOProcTermTimeout):
log.L.Warn("failed to wait for shim logger process to exit, killing")
err := b.cmd.Process.Kill()
if err != nil {
return errors.Wrap(err, "failed to kill shim logger process")
}
return nil
}
} }
func (b *binaryIO) Stdin() io.WriteCloser { func (b *binaryIO) Stdin() io.WriteCloser {
...@@ -389,9 +439,15 @@ type pipe struct { ...@@ -389,9 +439,15 @@ type pipe struct {
} }
func (p *pipe) Close() error { func (p *pipe) Close() error {
err := p.w.Close() var result *multierror.Error
if rerr := p.r.Close(); err == nil {
err = rerr if err := p.w.Close(); err != nil {
result = multierror.Append(result, errors.Wrap(err, "failed to close write pipe"))
} }
return err
if err := p.r.Close(); err != nil {
result = multierror.Append(result, errors.Wrap(err, "failed to close read pipe"))
}
return multierror.Prefix(result.ErrorOrNil(), "pipe:")
} }
...@@ -137,6 +137,8 @@ func checkKillError(err error) error { ...@@ -137,6 +137,8 @@ func checkKillError(err error) error {
strings.Contains(strings.ToLower(err.Error()), "no such process") || strings.Contains(strings.ToLower(err.Error()), "no such process") ||
err == unix.ESRCH { err == unix.ESRCH {
return errors.Wrapf(errdefs.ErrNotFound, "process already finished") return errors.Wrapf(errdefs.ErrNotFound, "process already finished")
} else if strings.Contains(err.Error(), "does not exist") {
return errors.Wrapf(errdefs.ErrNotFound, "no such container")
} }
return errors.Wrapf(err, "unknown error after kill") return errors.Wrapf(err, "unknown error after kill")
} }
......
...@@ -96,41 +96,49 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R ...@@ -96,41 +96,49 @@ func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.R
images.MediaTypeDockerSchema1Manifest, images.MediaTypeDockerSchema1Manifest,
ocispec.MediaTypeImageManifest, ocispec.MediaTypeImageIndex: ocispec.MediaTypeImageManifest, ocispec.MediaTypeImageIndex:
var firstErr error
for _, host := range r.hosts { for _, host := range r.hosts {
req := r.request(host, http.MethodGet, "manifests", desc.Digest.String()) req := r.request(host, http.MethodGet, "manifests", desc.Digest.String())
rc, err := r.open(ctx, req, desc.MediaType, offset) rc, err := r.open(ctx, req, desc.MediaType, offset)
if err != nil { if err != nil {
if errdefs.IsNotFound(err) { // Store the error for referencing later
continue // try another host if firstErr == nil {
firstErr = err
} }
continue // try another host
return nil, err
} }
return rc, nil return rc, nil
} }
return nil, firstErr
} }
// Finally use blobs endpoints // Finally use blobs endpoints
var firstErr error
for _, host := range r.hosts { for _, host := range r.hosts {
req := r.request(host, http.MethodGet, "blobs", desc.Digest.String()) req := r.request(host, http.MethodGet, "blobs", desc.Digest.String())
rc, err := r.open(ctx, req, desc.MediaType, offset) rc, err := r.open(ctx, req, desc.MediaType, offset)
if err != nil { if err != nil {
if errdefs.IsNotFound(err) { // Store the error for referencing later
continue // try another host if firstErr == nil {
firstErr = err
} }
continue // try another host
return nil, err
} }
return rc, nil return rc, nil
} }
return nil, errors.Wrapf(errdefs.ErrNotFound, if errdefs.IsNotFound(firstErr) {
firstErr = errors.Wrapf(errdefs.ErrNotFound,
"could not fetch content descriptor %v (%v) from remote", "could not fetch content descriptor %v (%v) from remote",
desc.Digest, desc.MediaType) desc.Digest, desc.MediaType)
}
return nil, firstErr
}) })
} }
......
...@@ -204,6 +204,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten ...@@ -204,6 +204,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
q.Add("digest", desc.Digest.String()) q.Add("digest", desc.Digest.String())
req = p.request(lhost, http.MethodPut) req = p.request(lhost, http.MethodPut)
req.header.Set("Content-Type", "application/octet-stream")
req.path = lurl.Path + "?" + q.Encode() req.path = lurl.Path + "?" + q.Encode()
} }
p.tracker.SetStatus(ref, Status{ p.tracker.SetStatus(ref, Status{
......
...@@ -286,7 +286,11 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp ...@@ -286,7 +286,11 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
if errors.Cause(err) == ErrInvalidAuthorization { if errors.Cause(err) == ErrInvalidAuthorization {
err = errors.Wrapf(err, "pull access denied, repository does not exist or may require authorization") err = errors.Wrapf(err, "pull access denied, repository does not exist or may require authorization")
} }
return "", ocispec.Descriptor{}, err // Store the error for referencing later
if lastErr == nil {
lastErr = err
}
continue // try another host
} }
resp.Body.Close() // don't care about body contents. resp.Body.Close() // don't care about body contents.
......
...@@ -91,7 +91,7 @@ func ShimRemote(c *Config, daemonAddress, cgroup string, exitHandler func()) Shi ...@@ -91,7 +91,7 @@ func ShimRemote(c *Config, daemonAddress, cgroup string, exitHandler func()) Shi
return func(b *bundle, ns string, ropts *runctypes.RuncOptions) (shim.Config, client.Opt) { return func(b *bundle, ns string, ropts *runctypes.RuncOptions) (shim.Config, client.Opt) {
config := b.shimConfig(ns, c, ropts) config := b.shimConfig(ns, c, ropts)
return config, return config,
client.WithStart(c.Shim, b.shimAddress(ns), daemonAddress, cgroup, c.ShimDebug, exitHandler) client.WithStart(c.Shim, b.shimAddress(ns, daemonAddress), daemonAddress, cgroup, c.ShimDebug, exitHandler)
} }
} }
...@@ -117,6 +117,11 @@ func (b *bundle) NewShimClient(ctx context.Context, namespace string, getClientO ...@@ -117,6 +117,11 @@ func (b *bundle) NewShimClient(ctx context.Context, namespace string, getClientO
// Delete deletes the bundle from disk // Delete deletes the bundle from disk
func (b *bundle) Delete() error { func (b *bundle) Delete() error {
address, _ := b.loadAddress()
if address != "" {
// we don't care about errors here
client.RemoveSocket(address)
}
err := atomicDelete(b.path) err := atomicDelete(b.path)
if err == nil { if err == nil {
return atomicDelete(b.workDir) return atomicDelete(b.workDir)
...@@ -133,9 +138,11 @@ func (b *bundle) legacyShimAddress(namespace string) string { ...@@ -133,9 +138,11 @@ func (b *bundle) legacyShimAddress(namespace string) string {
return filepath.Join(string(filepath.Separator), "containerd-shim", namespace, b.id, "shim.sock") return filepath.Join(string(filepath.Separator), "containerd-shim", namespace, b.id, "shim.sock")
} }
func (b *bundle) shimAddress(namespace string) string { const socketRoot = "/run/containerd"
d := sha256.Sum256([]byte(filepath.Join(namespace, b.id)))
return filepath.Join(string(filepath.Separator), "containerd-shim", fmt.Sprintf("%x.sock", d)) func (b *bundle) shimAddress(namespace, socketPath string) string {
d := sha256.Sum256([]byte(filepath.Join(socketPath, namespace, b.id)))
return fmt.Sprintf("unix://%s/%x", filepath.Join(socketRoot, "s"), d)
} }
func (b *bundle) loadAddress() (string, error) { func (b *bundle) loadAddress() (string, error) {
......
...@@ -62,6 +62,9 @@ const ( ...@@ -62,6 +62,9 @@ const (
configFilename = "config.json" configFilename = "config.json"
defaultRuntime = "runc" defaultRuntime = "runc"
defaultShim = "containerd-shim" defaultShim = "containerd-shim"
// cleanupTimeout is default timeout for cleanup operations
cleanupTimeout = 1 * time.Minute
) )
func init() { func init() {
...@@ -212,7 +215,10 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts ...@@ -212,7 +215,10 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts
} }
defer func() { defer func() {
if err != nil { if err != nil {
if kerr := s.KillShim(ctx); kerr != nil { deferCtx, deferCancel := context.WithTimeout(
namespaces.WithNamespace(context.TODO(), namespace), cleanupTimeout)
defer deferCancel()
if kerr := s.KillShim(deferCtx); kerr != nil {
log.G(ctx).WithError(err).Error("failed to kill shim") log.G(ctx).WithError(err).Error("failed to kill shim")
} }
} }
......
...@@ -57,9 +57,17 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa ...@@ -57,9 +57,17 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa
return func(ctx context.Context, config shim.Config) (_ shimapi.ShimService, _ io.Closer, err error) { return func(ctx context.Context, config shim.Config) (_ shimapi.ShimService, _ io.Closer, err error) {
socket, err := newSocket(address) socket, err := newSocket(address)
if err != nil { if err != nil {
if !eaddrinuse(err) {
return nil, nil, err return nil, nil, err
} }
defer socket.Close() if err := RemoveSocket(address); err != nil {
return nil, nil, errors.Wrap(err, "remove already used socket")
}
if socket, err = newSocket(address); err != nil {
return nil, nil, err
}
}
f, err := socket.File() f, err := socket.File()
if err != nil { if err != nil {
return nil, nil, errors.Wrapf(err, "failed to get fd for socket %s", address) return nil, nil, errors.Wrapf(err, "failed to get fd for socket %s", address)
...@@ -104,6 +112,8 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa ...@@ -104,6 +112,8 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa
if stderrLog != nil { if stderrLog != nil {
stderrLog.Close() stderrLog.Close()
} }
socket.Close()
RemoveSocket(address)
}() }()
log.G(ctx).WithFields(logrus.Fields{ log.G(ctx).WithFields(logrus.Fields{
"pid": cmd.Process.Pid, "pid": cmd.Process.Pid,
...@@ -138,6 +148,26 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa ...@@ -138,6 +148,26 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa
} }
} }
func eaddrinuse(err error) bool {
cause := errors.Cause(err)
netErr, ok := cause.(*net.OpError)
if !ok {
return false
}
if netErr.Op != "listen" {
return false
}
syscallErr, ok := netErr.Err.(*os.SyscallError)
if !ok {
return false
}
errno, ok := syscallErr.Err.(syscall.Errno)
if !ok {
return false
}
return errno == syscall.EADDRINUSE
}
// setupOOMScore gets containerd's oom score and adds +1 to it // setupOOMScore gets containerd's oom score and adds +1 to it
// to ensure a shim has a lower* score than the daemons // to ensure a shim has a lower* score than the daemons
func setupOOMScore(shimPid int) error { func setupOOMScore(shimPid int) error {
...@@ -210,31 +240,73 @@ func writeFile(path, address string) error { ...@@ -210,31 +240,73 @@ func writeFile(path, address string) error {
return os.Rename(tempPath, path) return os.Rename(tempPath, path)
} }
const (
abstractSocketPrefix = "\x00"
socketPathLimit = 106
)
type socket string
func (s socket) isAbstract() bool {
return !strings.HasPrefix(string(s), "unix://")
}
func (s socket) path() string {
path := strings.TrimPrefix(string(s), "unix://")
// if there was no trim performed, we assume an abstract socket
if len(path) == len(s) {
path = abstractSocketPrefix + path
}
return path
}
func newSocket(address string) (*net.UnixListener, error) { func newSocket(address string) (*net.UnixListener, error) {
if len(address) > 106 { if len(address) > socketPathLimit {
return nil, errors.Errorf("%q: unix socket path too long (> 106)", address) return nil, errors.Errorf("%q: unix socket path too long (> %d)", address, socketPathLimit)
}
var (
sock = socket(address)
path = sock.path()
)
if !sock.isAbstract() {
if err := os.MkdirAll(filepath.Dir(path), 0600); err != nil {
return nil, errors.Wrapf(err, "%s", path)
} }
l, err := net.Listen("unix", "\x00"+address) }
l, err := net.Listen("unix", path)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to listen to abstract unix socket %q", address) return nil, errors.Wrapf(err, "failed to listen to unix socket %q (abstract: %t)", address, sock.isAbstract())
}
if err := os.Chmod(path, 0600); err != nil {
l.Close()
return nil, err
} }
return l.(*net.UnixListener), nil return l.(*net.UnixListener), nil
} }
// RemoveSocket removes the socket at the specified address if
// it exists on the filesystem
func RemoveSocket(address string) error {
sock := socket(address)
if !sock.isAbstract() {
return os.Remove(sock.path())
}
return nil
}
func connect(address string, d func(string, time.Duration) (net.Conn, error)) (net.Conn, error) { func connect(address string, d func(string, time.Duration) (net.Conn, error)) (net.Conn, error) {
return d(address, 100*time.Second) return d(address, 100*time.Second)
} }
func annonDialer(address string, timeout time.Duration) (net.Conn, error) { func anonDialer(address string, timeout time.Duration) (net.Conn, error) {
address = strings.TrimPrefix(address, "unix://") return net.DialTimeout("unix", socket(address).path(), timeout)
return net.DialTimeout("unix", "\x00"+address, timeout)
} }
// WithConnect connects to an existing shim // WithConnect connects to an existing shim
func WithConnect(address string, onClose func()) Opt { func WithConnect(address string, onClose func()) Opt {
return func(ctx context.Context, config shim.Config) (shimapi.ShimService, io.Closer, error) { return func(ctx context.Context, config shim.Config) (shimapi.ShimService, io.Closer, error) {
conn, err := connect(address, annonDialer) conn, err := connect(address, anonDialer)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
...@@ -323,21 +395,31 @@ func (c *Client) signalShim(ctx context.Context, sig syscall.Signal) error { ...@@ -323,21 +395,31 @@ func (c *Client) signalShim(ctx context.Context, sig syscall.Signal) error {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return ctx.Err() return ctx.Err()
case <-c.waitForExit(pid): case <-c.waitForExit(ctx, pid):
return nil return nil
} }
} }
func (c *Client) waitForExit(pid int) <-chan struct{} { func (c *Client) waitForExit(ctx context.Context, pid int) <-chan struct{} {
c.exitOnce.Do(func() { go c.exitOnce.Do(func() {
defer close(c.exitCh)
ticker := time.NewTicker(10 * time.Millisecond)
defer ticker.Stop()
for { for {
// use kill(pid, 0) here because the shim could have been reparented // use kill(pid, 0) here because the shim could have been reparented
// and we are no longer able to waitpid(pid, ...) on the shim // and we are no longer able to waitpid(pid, ...) on the shim
if err := unix.Kill(pid, 0); err == unix.ESRCH { if err := unix.Kill(pid, 0); err == unix.ESRCH {
close(c.exitCh)
return return
} }
time.Sleep(10 * time.Millisecond)
select {
case <-ticker.C:
case <-ctx.Done():
log.G(ctx).WithField("pid", pid).Warn("timed out while waiting for shim to exit")
return
}
} }
}) })
return c.exitCh return c.exitCh
......
...@@ -20,6 +20,7 @@ package runc ...@@ -20,6 +20,7 @@ package runc
import ( import (
"context" "context"
"encoding/json"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
...@@ -87,6 +88,10 @@ func NewContainer(ctx context.Context, platform stdio.Platform, r *task.CreateTa ...@@ -87,6 +88,10 @@ func NewContainer(ctx context.Context, platform stdio.Platform, r *task.CreateTa
Options: r.Options, Options: r.Options,
} }
if err := WriteOptions(r.Bundle, opts); err != nil {
return nil, err
}
// For historical reason, we write opts.BinaryName as well as the entire opts
if err := WriteRuntime(r.Bundle, opts.BinaryName); err != nil { if err := WriteRuntime(r.Bundle, opts.BinaryName); err != nil {
return nil, err return nil, err
} }
...@@ -142,6 +147,39 @@ func NewContainer(ctx context.Context, platform stdio.Platform, r *task.CreateTa ...@@ -142,6 +147,39 @@ func NewContainer(ctx context.Context, platform stdio.Platform, r *task.CreateTa
return container, nil return container, nil
} }
const optionsFilename = "options.json"
// ReadOptions reads the option information from the path.
// When the file does not exist, ReadOptions returns nil without an error.
func ReadOptions(path string) (*options.Options, error) {
filePath := filepath.Join(path, optionsFilename)
if _, err := os.Stat(filePath); err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, err
}
data, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, err
}
var opts options.Options
if err := json.Unmarshal(data, &opts); err != nil {
return nil, err
}
return &opts, nil
}
// WriteOptions writes the options information into the path
func WriteOptions(path string, opts options.Options) error {
data, err := json.Marshal(opts)
if err != nil {
return err
}
return ioutil.WriteFile(filepath.Join(path, optionsFilename), data, 0600)
}
// ReadRuntime reads the runtime information from the path // ReadRuntime reads the runtime information from the path
func ReadRuntime(path string) (string, error) { func ReadRuntime(path string) (string, error) {
data, err := ioutil.ReadFile(filepath.Join(path, "runtime")) data, err := ioutil.ReadFile(filepath.Join(path, "runtime"))
......
...@@ -25,7 +25,6 @@ import ( ...@@ -25,7 +25,6 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strings"
"sync" "sync"
"syscall" "syscall"
"time" "time"
...@@ -96,6 +95,10 @@ func New(ctx context.Context, id string, publisher shim.Publisher, shutdown func ...@@ -96,6 +95,10 @@ func New(ctx context.Context, id string, publisher shim.Publisher, shutdown func
return nil, errors.Wrap(err, "failed to initialized platform behavior") return nil, errors.Wrap(err, "failed to initialized platform behavior")
} }
go s.forward(ctx, publisher) go s.forward(ctx, publisher)
if address, err := shim.ReadAddress("address"); err == nil {
s.shimAddress = address
}
return s, nil return s, nil
} }
...@@ -115,6 +118,7 @@ type service struct { ...@@ -115,6 +118,7 @@ type service struct {
containers map[string]*runc.Container containers map[string]*runc.Container
shimAddress string
cancel func() cancel func()
} }
...@@ -158,7 +162,7 @@ func readSpec() (*spec, error) { ...@@ -158,7 +162,7 @@ func readSpec() (*spec, error) {
return &s, nil return &s, nil
} }
func (s *service) StartShim(ctx context.Context, id, containerdBinary, containerdAddress, containerdTTRPCAddress string) (string, error) { func (s *service) StartShim(ctx context.Context, id, containerdBinary, containerdAddress, containerdTTRPCAddress string) (_ string, retErr error) {
cmd, err := newCommand(ctx, id, containerdBinary, containerdAddress, containerdTTRPCAddress) cmd, err := newCommand(ctx, id, containerdBinary, containerdAddress, containerdTTRPCAddress)
if err != nil { if err != nil {
return "", err return "", err
...@@ -174,34 +178,52 @@ func (s *service) StartShim(ctx context.Context, id, containerdBinary, container ...@@ -174,34 +178,52 @@ func (s *service) StartShim(ctx context.Context, id, containerdBinary, container
break break
} }
} }
address, err := shim.SocketAddress(ctx, grouping) address, err := shim.SocketAddress(ctx, containerdAddress, grouping)
if err != nil { if err != nil {
return "", err return "", err
} }
socket, err := shim.NewSocket(address) socket, err := shim.NewSocket(address)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "address already in use") { // the only time where this would happen is if there is a bug and the socket
// was not cleaned up in the cleanup method of the shim or we are using the
// grouping functionality where the new process should be run with the same
// shim as an existing container
if !shim.SocketEaddrinuse(err) {
return "", errors.Wrap(err, "create new shim socket")
}
if shim.CanConnect(address) {
if err := shim.WriteAddress("address", address); err != nil { if err := shim.WriteAddress("address", address); err != nil {
return "", err return "", errors.Wrap(err, "write existing socket for shim")
} }
return address, nil return address, nil
} }
return "", err if err := shim.RemoveSocket(address); err != nil {
return "", errors.Wrap(err, "remove pre-existing socket")
} }
defer socket.Close() if socket, err = shim.NewSocket(address); err != nil {
return "", errors.Wrap(err, "try create new shim socket 2x")
}
}
defer func() {
if retErr != nil {
socket.Close()
_ = shim.RemoveSocket(address)
}
}()
f, err := socket.File() f, err := socket.File()
if err != nil { if err != nil {
return "", err return "", err
} }
defer f.Close()
cmd.ExtraFiles = append(cmd.ExtraFiles, f) cmd.ExtraFiles = append(cmd.ExtraFiles, f)
if err := cmd.Start(); err != nil { if err := cmd.Start(); err != nil {
f.Close()
return "", err return "", err
} }
defer func() { defer func() {
if err != nil { if retErr != nil {
cmd.Process.Kill() cmd.Process.Kill()
} }
}() }()
...@@ -251,12 +273,20 @@ func (s *service) Cleanup(ctx context.Context) (*taskAPI.DeleteResponse, error) ...@@ -251,12 +273,20 @@ func (s *service) Cleanup(ctx context.Context) (*taskAPI.DeleteResponse, error)
if err != nil { if err != nil {
return nil, err return nil, err
} }
runtime, err := runc.ReadRuntime(path) runtime, err := runc.ReadRuntime(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
r := process.NewRunc(process.RuncRoot, path, ns, runtime, "", false) opts, err := runc.ReadOptions(path)
if err != nil {
return nil, err
}
root := process.RuncRoot
if opts != nil && opts.Root != "" {
root = opts.Root
}
r := process.NewRunc(root, path, ns, runtime, "", false)
if err := r.Delete(ctx, s.id, &runcC.DeleteOpts{ if err := r.Delete(ctx, s.id, &runcC.DeleteOpts{
Force: true, Force: true,
}); err != nil { }); err != nil {
...@@ -601,7 +631,9 @@ func (s *service) Shutdown(ctx context.Context, r *taskAPI.ShutdownRequest) (*pt ...@@ -601,7 +631,9 @@ func (s *service) Shutdown(ctx context.Context, r *taskAPI.ShutdownRequest) (*pt
if s.platform != nil { if s.platform != nil {
s.platform.Close() s.platform.Close()
} }
if s.shimAddress != "" {
_ = shim.RemoveSocket(s.shimAddress)
}
return empty, nil return empty, nil
} }
...@@ -729,9 +761,7 @@ func (s *service) forward(ctx context.Context, publisher shim.Publisher) { ...@@ -729,9 +761,7 @@ func (s *service) forward(ctx context.Context, publisher shim.Publisher) {
ns, _ := namespaces.Namespace(ctx) ns, _ := namespaces.Namespace(ctx)
ctx = namespaces.WithNamespace(context.Background(), ns) ctx = namespaces.WithNamespace(context.Background(), ns)
for e := range s.events { for e := range s.events {
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
err := publisher.Publish(ctx, runc.GetTopic(e), e) err := publisher.Publish(ctx, runc.GetTopic(e), e)
cancel()
if err != nil { if err != nil {
logrus.WithError(err).Error("post event") logrus.WithError(err).Error("post event")
} }
......
...@@ -430,10 +430,14 @@ func (s *shim) Stats(ctx context.Context) (*ptypes.Any, error) { ...@@ -430,10 +430,14 @@ func (s *shim) Stats(ctx context.Context) (*ptypes.Any, error) {
} }
func (s *shim) Process(ctx context.Context, id string) (runtime.Process, error) { func (s *shim) Process(ctx context.Context, id string) (runtime.Process, error) {
return &process{ p := &process{
id: id, id: id,
shim: s, shim: s,
}, nil }
if _, err := p.State(ctx); err != nil {
return nil, err
}
return p, nil
} }
func (s *shim) State(ctx context.Context) (runtime.State, error) { func (s *shim) State(ctx context.Context) (runtime.State, error) {
......
...@@ -128,7 +128,9 @@ func (l *RemoteEventsPublisher) Publish(ctx context.Context, topic string, event ...@@ -128,7 +128,9 @@ func (l *RemoteEventsPublisher) Publish(ctx context.Context, topic string, event
} }
func (l *RemoteEventsPublisher) forwardRequest(ctx context.Context, req *v1.ForwardRequest) error { func (l *RemoteEventsPublisher) forwardRequest(ctx context.Context, req *v1.ForwardRequest) error {
_, err := l.client.EventsService().Forward(ctx, req) fCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
_, err := l.client.EventsService().Forward(fCtx, req)
cancel()
if err == nil { if err == nil {
return nil return nil
} }
...@@ -142,9 +144,9 @@ func (l *RemoteEventsPublisher) forwardRequest(ctx context.Context, req *v1.Forw ...@@ -142,9 +144,9 @@ func (l *RemoteEventsPublisher) forwardRequest(ctx context.Context, req *v1.Forw
return err return err
} }
if _, err := l.client.EventsService().Forward(ctx, req); err != nil { fCtx, cancel = context.WithTimeout(ctx, 5*time.Second)
return err _, err = l.client.EventsService().Forward(fCtx, req)
} cancel()
return nil return err
} }
...@@ -101,7 +101,7 @@ func parseFlags() { ...@@ -101,7 +101,7 @@ func parseFlags() {
flag.BoolVar(&debugFlag, "debug", false, "enable debug output in logs") flag.BoolVar(&debugFlag, "debug", false, "enable debug output in logs")
flag.StringVar(&namespaceFlag, "namespace", "", "namespace that owns the shim") flag.StringVar(&namespaceFlag, "namespace", "", "namespace that owns the shim")
flag.StringVar(&idFlag, "id", "", "id of the task") flag.StringVar(&idFlag, "id", "", "id of the task")
flag.StringVar(&socketFlag, "socket", "", "abstract socket path to serve") flag.StringVar(&socketFlag, "socket", "", "socket path to serve")
flag.StringVar(&bundlePath, "bundle", "", "path to the bundle if not workdir") flag.StringVar(&bundlePath, "bundle", "", "path to the bundle if not workdir")
flag.StringVar(&addressFlag, "address", "", "grpc address back to main containerd") flag.StringVar(&addressFlag, "address", "", "grpc address back to main containerd")
...@@ -183,7 +183,6 @@ func run(id string, initFunc Init, config Config) error { ...@@ -183,7 +183,6 @@ func run(id string, initFunc Init, config Config) error {
ctx = context.WithValue(ctx, OptsKey{}, Opts{BundlePath: bundlePath, Debug: debugFlag}) ctx = context.WithValue(ctx, OptsKey{}, Opts{BundlePath: bundlePath, Debug: debugFlag})
ctx = log.WithLogger(ctx, log.G(ctx).WithField("runtime", id)) ctx = log.WithLogger(ctx, log.G(ctx).WithField("runtime", id))
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
service, err := initFunc(ctx, idFlag, publisher, cancel) service, err := initFunc(ctx, idFlag, publisher, cancel)
if err != nil { if err != nil {
return err return err
...@@ -288,11 +287,15 @@ func serve(ctx context.Context, server *ttrpc.Server, path string) error { ...@@ -288,11 +287,15 @@ func serve(ctx context.Context, server *ttrpc.Server, path string) error {
return err return err
} }
go func() { go func() {
defer l.Close()
if err := server.Serve(ctx, l); err != nil && if err := server.Serve(ctx, l); err != nil &&
!strings.Contains(err.Error(), "use of closed network connection") { !strings.Contains(err.Error(), "use of closed network connection") {
logrus.WithError(err).Fatal("containerd-shim: ttrpc server failure") logrus.WithError(err).Fatal("containerd-shim: ttrpc server failure")
} }
l.Close()
if address, err := ReadAddress("address"); err == nil {
_ = RemoveSocket(address)
}
}() }()
return nil return nil
} }
......
...@@ -58,15 +58,15 @@ func serveListener(path string) (net.Listener, error) { ...@@ -58,15 +58,15 @@ func serveListener(path string) (net.Listener, error) {
l, err = net.FileListener(os.NewFile(3, "socket")) l, err = net.FileListener(os.NewFile(3, "socket"))
path = "[inherited from parent]" path = "[inherited from parent]"
} else { } else {
if len(path) > 106 { if len(path) > socketPathLimit {
return nil, errors.Errorf("%q: unix socket path too long (> 106)", path) return nil, errors.Errorf("%q: unix socket path too long (> %d)", path, socketPathLimit)
} }
l, err = net.Listen("unix", "\x00"+path) l, err = net.Listen("unix", path)
} }
if err != nil { if err != nil {
return nil, err return nil, err
} }
logrus.WithField("socket", path).Debug("serving api on abstract socket") logrus.WithField("socket", path).Debug("serving api on socket")
return l, nil return l, nil
} }
......
...@@ -169,7 +169,7 @@ func WriteAddress(path, address string) error { ...@@ -169,7 +169,7 @@ func WriteAddress(path, address string) error {
// ErrNoAddress is returned when the address file has no content // ErrNoAddress is returned when the address file has no content
var ErrNoAddress = errors.New("no shim address") var ErrNoAddress = errors.New("no shim address")
// ReadAddress returns the shim's abstract socket address from the path // ReadAddress returns the shim's socket address from the path
func ReadAddress(path string) (string, error) { func ReadAddress(path string) (string, error) {
path, err := filepath.Abs(path) path, err := filepath.Abs(path)
if err != nil { if err != nil {
......
...@@ -34,7 +34,10 @@ import ( ...@@ -34,7 +34,10 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
const shimBinaryFormat = "containerd-shim-%s-%s" const (
shimBinaryFormat = "containerd-shim-%s-%s"
socketPathLimit = 106
)
func getSysProcAttr() *syscall.SysProcAttr { func getSysProcAttr() *syscall.SysProcAttr {
return &syscall.SysProcAttr{ return &syscall.SysProcAttr{
...@@ -62,20 +65,21 @@ func AdjustOOMScore(pid int) error { ...@@ -62,20 +65,21 @@ func AdjustOOMScore(pid int) error {
return nil return nil
} }
// SocketAddress returns an abstract socket address const socketRoot = "/run/containerd"
func SocketAddress(ctx context.Context, id string) (string, error) {
// SocketAddress returns a socket address
func SocketAddress(ctx context.Context, socketPath, id string) (string, error) {
ns, err := namespaces.NamespaceRequired(ctx) ns, err := namespaces.NamespaceRequired(ctx)
if err != nil { if err != nil {
return "", err return "", err
} }
d := sha256.Sum256([]byte(filepath.Join(ns, id))) d := sha256.Sum256([]byte(filepath.Join(socketPath, ns, id)))
return filepath.Join(string(filepath.Separator), "containerd-shim", fmt.Sprintf("%x.sock", d)), nil return fmt.Sprintf("unix://%s/%x", filepath.Join(socketRoot, "s"), d), nil
} }
// AnonDialer returns a dialer for an abstract socket // AnonDialer returns a dialer for a socket
func AnonDialer(address string, timeout time.Duration) (net.Conn, error) { func AnonDialer(address string, timeout time.Duration) (net.Conn, error) {
address = strings.TrimPrefix(address, "unix://") return net.DialTimeout("unix", socket(address).path(), timeout)
return net.DialTimeout("unix", "\x00"+address, timeout)
} }
func AnonReconnectDialer(address string, timeout time.Duration) (net.Conn, error) { func AnonReconnectDialer(address string, timeout time.Duration) (net.Conn, error) {
...@@ -84,12 +88,82 @@ func AnonReconnectDialer(address string, timeout time.Duration) (net.Conn, error ...@@ -84,12 +88,82 @@ func AnonReconnectDialer(address string, timeout time.Duration) (net.Conn, error
// NewSocket returns a new socket // NewSocket returns a new socket
func NewSocket(address string) (*net.UnixListener, error) { func NewSocket(address string) (*net.UnixListener, error) {
if len(address) > 106 { var (
return nil, errors.Errorf("%q: unix socket path too long (> 106)", address) sock = socket(address)
path = sock.path()
)
if !sock.isAbstract() {
if err := os.MkdirAll(filepath.Dir(path), 0600); err != nil {
return nil, errors.Wrapf(err, "%s", path)
} }
l, err := net.Listen("unix", "\x00"+address) }
l, err := net.Listen("unix", path)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to listen to abstract unix socket %q", address) return nil, err
}
if err := os.Chmod(path, 0600); err != nil {
os.Remove(sock.path())
l.Close()
return nil, err
} }
return l.(*net.UnixListener), nil return l.(*net.UnixListener), nil
} }
const abstractSocketPrefix = "\x00"
type socket string
func (s socket) isAbstract() bool {
return !strings.HasPrefix(string(s), "unix://")
}
func (s socket) path() string {
path := strings.TrimPrefix(string(s), "unix://")
// if there was no trim performed, we assume an abstract socket
if len(path) == len(s) {
path = abstractSocketPrefix + path
}
return path
}
// RemoveSocket removes the socket at the specified address if
// it exists on the filesystem
func RemoveSocket(address string) error {
sock := socket(address)
if !sock.isAbstract() {
return os.Remove(sock.path())
}
return nil
}
// SocketEaddrinuse returns true if the provided error is caused by the
// EADDRINUSE error number
func SocketEaddrinuse(err error) bool {
netErr, ok := err.(*net.OpError)
if !ok {
return false
}
if netErr.Op != "listen" {
return false
}
syscallErr, ok := netErr.Err.(*os.SyscallError)
if !ok {
return false
}
errno, ok := syscallErr.Err.(syscall.Errno)
if !ok {
return false
}
return errno == syscall.EADDRINUSE
}
// CanConnect returns true if the socket provided at the address
// is accepting new connections
func CanConnect(address string) bool {
conn, err := AnonDialer(address, 100*time.Millisecond)
if err != nil {
return false
}
conn.Close()
return true
}
...@@ -79,3 +79,9 @@ func AnonDialer(address string, timeout time.Duration) (net.Conn, error) { ...@@ -79,3 +79,9 @@ func AnonDialer(address string, timeout time.Duration) (net.Conn, error) {
return c, nil return c, nil
} }
} }
// RemoveSocket removes the socket at the specified address if
// it exists on the filesystem
func RemoveSocket(address string) error {
return nil
}
...@@ -118,6 +118,13 @@ func initFunc(ic *plugin.InitContext) (interface{}, error) { ...@@ -118,6 +118,13 @@ func initFunc(ic *plugin.InitContext) (interface{}, error) {
l.monitor.Monitor(t) l.monitor.Monitor(t)
} }
} }
v2Tasks, err := l.v2Runtime.Tasks(ic.Context, true)
if err != nil {
return nil, err
}
for _, t := range v2Tasks {
l.monitor.Monitor(t)
}
return l, nil return l, nil
} }
......
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sys
import "os"
// IsFifo checks if a file is a (named pipe) fifo
// if the file does not exist then it returns false
func IsFifo(path string) (bool, error) {
stat, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
if stat.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
return true, nil
}
return false, nil
}
...@@ -21,6 +21,7 @@ import ( ...@@ -21,6 +21,7 @@ import (
"syscall" "syscall"
"unsafe" "unsafe"
"github.com/containerd/containerd/log"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
...@@ -30,9 +31,8 @@ func FMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data ...@@ -30,9 +31,8 @@ func FMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data
var ( var (
sourceP, targetP, fstypeP, dataP *byte sourceP, targetP, fstypeP, dataP *byte
pid uintptr pid uintptr
ws unix.WaitStatus
err error err error
errno syscall.Errno errno, status syscall.Errno
) )
sourceP, err = syscall.BytePtrFromString(source) sourceP, err = syscall.BytePtrFromString(source)
...@@ -60,37 +60,62 @@ func FMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data ...@@ -60,37 +60,62 @@ func FMountat(dirfd uintptr, source, target, fstype string, flags uintptr, data
runtime.LockOSThread() runtime.LockOSThread()
defer runtime.UnlockOSThread() defer runtime.UnlockOSThread()
var pipefds [2]int
if err := syscall.Pipe2(pipefds[:], syscall.O_CLOEXEC); err != nil {
return errors.Wrap(err, "failed to open pipe")
}
defer func() {
// close both ends of the pipe in a deferred function, since open file
// descriptor table is shared with child
syscall.Close(pipefds[0])
syscall.Close(pipefds[1])
}()
pid, errno = forkAndMountat(dirfd, pid, errno = forkAndMountat(dirfd,
uintptr(unsafe.Pointer(sourceP)), uintptr(unsafe.Pointer(sourceP)),
uintptr(unsafe.Pointer(targetP)), uintptr(unsafe.Pointer(targetP)),
uintptr(unsafe.Pointer(fstypeP)), uintptr(unsafe.Pointer(fstypeP)),
flags, flags,
uintptr(unsafe.Pointer(dataP))) uintptr(unsafe.Pointer(dataP)),
pipefds[1],
)
if errno != 0 { if errno != 0 {
return errors.Wrap(errno, "failed to fork thread") return errors.Wrap(errno, "failed to fork thread")
} }
_, err = unix.Wait4(int(pid), &ws, 0, nil) defer func() {
_, err := unix.Wait4(int(pid), nil, 0, nil)
for err == syscall.EINTR { for err == syscall.EINTR {
_, err = unix.Wait4(int(pid), &ws, 0, nil) _, err = unix.Wait4(int(pid), nil, 0, nil)
} }
if err != nil { if err != nil {
return errors.Wrapf(err, "failed to find pid=%d process", pid) log.L.WithError(err).Debugf("failed to find pid=%d process", pid)
} }
}()
errno = syscall.Errno(ws.ExitStatus()) _, _, errno = syscall.RawSyscall(syscall.SYS_READ,
uintptr(pipefds[0]),
uintptr(unsafe.Pointer(&status)),
unsafe.Sizeof(status))
if errno != 0 { if errno != 0 {
return errors.Wrap(errno, "failed to mount") return errors.Wrap(errno, "failed to read pipe")
} }
if status != 0 {
return errors.Wrap(status, "failed to mount")
}
return nil return nil
} }
// forkAndMountat will fork thread, change working dir and mount. // forkAndMountat will fork thread, change working dir and mount.
// //
// precondition: the runtime OS thread must be locked. // precondition: the runtime OS thread must be locked.
func forkAndMountat(dirfd uintptr, source, target, fstype, flags, data uintptr) (pid uintptr, errno syscall.Errno) { func forkAndMountat(dirfd uintptr, source, target, fstype, flags, data uintptr, pipefd int) (pid uintptr, errno syscall.Errno) {
// block signal during clone // block signal during clone
beforeFork() beforeFork()
...@@ -114,6 +139,7 @@ func forkAndMountat(dirfd uintptr, source, target, fstype, flags, data uintptr) ...@@ -114,6 +139,7 @@ func forkAndMountat(dirfd uintptr, source, target, fstype, flags, data uintptr)
_, _, errno = syscall.RawSyscall6(syscall.SYS_MOUNT, source, target, fstype, flags, data, 0) _, _, errno = syscall.RawSyscall6(syscall.SYS_MOUNT, source, target, fstype, flags, data, 0)
childerr: childerr:
_, _, errno = syscall.RawSyscall(syscall.SYS_WRITE, uintptr(pipefd), uintptr(unsafe.Pointer(&errno)), unsafe.Sizeof(errno))
syscall.RawSyscall(syscall.SYS_EXIT, uintptr(errno), 0, 0) syscall.RawSyscall(syscall.SYS_EXIT, uintptr(errno), 0, 0)
panic("unreachable") panic("unreachable")
} }
github.com/containerd/go-runc e029b79d8cda8374981c64eba71f28ec38e5526f github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f github.com/BurntSushi/toml v0.3.1
github.com/containerd/cgroups c4b9ac5c7601384c965b9646fc515884e091ebb9
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
github.com/containerd/btrfs af5082808c833de0e79c1e72eea9fea239364877 github.com/containerd/btrfs af5082808c833de0e79c1e72eea9fea239364877
github.com/containerd/cgroups 9f1c62dddf4bc7cc72822ebe353bae7006141b1b
github.com/containerd/console v1.0.0
github.com/containerd/continuity f2a389ac0a02ce21c09edd7344677a601970f41c github.com/containerd/continuity f2a389ac0a02ce21c09edd7344677a601970f41c
github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
github.com/containerd/go-runc e029b79d8cda8374981c64eba71f28ec38e5526f
github.com/containerd/ttrpc v1.0.0
github.com/containerd/typeurl v1.0.0
github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6 github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
github.com/cpuguy83/go-md2man v1.0.10
github.com/docker/go-events e31b211e4f1cd09aa76fe4ac244571fab96ae47f
github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098 github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
github.com/docker/go-units v0.4.0 github.com/docker/go-units v0.4.0
github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f github.com/godbus/dbus v3
github.com/gogo/googleapis v1.2.0
github.com/gogo/protobuf v1.2.1
github.com/golang/protobuf v1.2.0
github.com/google/go-cmp v0.2.0
github.com/google/uuid v1.1.1
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
github.com/hashicorp/errwrap v1.0.0
github.com/hashicorp/go-multierror v1.0.0
github.com/hashicorp/golang-lru v0.5.3
github.com/imdario/mergo v0.3.7
github.com/konsorten/go-windows-terminal-sequences v1.0.1
github.com/matttproud/golang_protobuf_extensions v1.0.1
github.com/Microsoft/go-winio v0.4.14
github.com/Microsoft/hcsshim 9e921883ac929bbe515b39793ece99ce3a9d7706
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
github.com/opencontainers/image-spec v1.0.1
github.com/opencontainers/runc v1.0.0-rc10
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823 github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823
github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c
github.com/prometheus/common 89604d197083d4781071d3c65855d24ecfb0a563 github.com/prometheus/common 89604d197083d4781071d3c65855d24ecfb0a563
github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd
github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9 github.com/russross/blackfriday v1.5.2
github.com/matttproud/golang_protobuf_extensions v1.0.1
github.com/gogo/protobuf v1.2.1
github.com/gogo/googleapis v1.2.0
github.com/golang/protobuf v1.2.0
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
github.com/opencontainers/runc d736ef14f0288d6993a1845745d6756cfc9ddd5a # v1.0.0-rc9
github.com/konsorten/go-windows-terminal-sequences v1.0.1
github.com/sirupsen/logrus v1.4.1 github.com/sirupsen/logrus v1.4.1
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
github.com/urfave/cli v1.22.0 github.com/urfave/cli v1.22.0
go.etcd.io/bbolt v1.3.3
go.opencensus.io v0.22.0
golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3 golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3
google.golang.org/grpc 6eaf6f47437a6b4e2153a190160ef39a92c7eceb # v1.23.0
github.com/pkg/errors v0.8.1
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
golang.org/x/sys 9eafafc0a87e0fd0aeeba439a4573537970c44c7 https://github.com/golang/sys
github.com/opencontainers/image-spec v1.0.1
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
github.com/BurntSushi/toml v0.3.1 golang.org/x/sys 9eafafc0a87e0fd0aeeba439a4573537970c44c7
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
github.com/Microsoft/go-winio v0.4.14
github.com/Microsoft/hcsshim 9e921883ac929bbe515b39793ece99ce3a9d7706
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4 golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
github.com/containerd/ttrpc 92c8520ef9f86600c650dd540266a007bf03670f google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2 google.golang.org/grpc v1.23.0
gotest.tools v2.3.0 gotest.tools v2.3.0
github.com/google/go-cmp v0.2.0
go.etcd.io/bbolt v1.3.3
github.com/hashicorp/errwrap v1.0.0
github.com/hashicorp/go-multierror v1.0.0
github.com/hashicorp/golang-lru v0.5.3
go.opencensus.io v0.22.0
github.com/imdario/mergo v0.3.7
github.com/cpuguy83/go-md2man v1.0.10
github.com/russross/blackfriday v1.5.2
# cri dependencies # cri dependencies
github.com/containerd/cri b1bef15fbeb6c6f0569b67322acfa74ca3597755 # release/1.3 github.com/containerd/cri v1.3.0-k3s.9 https://github.com/rancher/cri.git
github.com/containerd/go-cni 49fbd9b210f3c8ee3b7fd3cd797aabaf364627c1
github.com/containernetworking/cni v0.7.1
github.com/containernetworking/plugins v0.7.6
github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew v1.1.1
github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580 github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00 github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00
github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528 github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528
github.com/emicklei/go-restful v2.9.5 github.com/emicklei/go-restful v2.9.5
github.com/google/gofuzz v1.0.0 github.com/google/gofuzz v1.0.0
github.com/json-iterator/go v1.1.7 github.com/json-iterator/go v1.1.8
github.com/modern-go/reflect2 1.0.1
github.com/modern-go/concurrent 1.0.3 github.com/modern-go/concurrent 1.0.3
github.com/opencontainers/selinux v1.2.2 github.com/modern-go/reflect2 1.0.1
github.com/opencontainers/selinux bb88c45a3863dc4c38320d71b890bb30ef9feba4
github.com/seccomp/libseccomp-golang v0.9.1 github.com/seccomp/libseccomp-golang v0.9.1
github.com/tchap/go-patricia v2.2.6 github.com/tchap/go-patricia v2.2.6
golang.org/x/crypto 5c40567a22f818bd14a1ea7245dad9f8ef0691aa golang.org/x/crypto 69ecbb4d6d5dab05e49161c6e77ea40a030884e1
golang.org/x/oauth2 0f29369cfe4552d0e4bcddc57cc75f4d7e672a33 golang.org/x/oauth2 0f29369cfe4552d0e4bcddc57cc75f4d7e672a33
golang.org/x/time 85acf8d2951cb2a3bde7632f9ff273ef0379bcbd golang.org/x/time 9d24e82272b4f38b78bc8cff74fa936d31ccd8ef
gopkg.in/inf.v0 v0.9.0 gopkg.in/inf.v0 v0.9.1
gopkg.in/yaml.v2 v2.2.2 gopkg.in/yaml.v2 v2.2.8
k8s.io/api kubernetes-1.16.0-rc.2 k8s.io/api v0.16.6
k8s.io/apimachinery kubernetes-1.16.0-rc.2 k8s.io/apimachinery v0.16.6
k8s.io/apiserver kubernetes-1.16.0-rc.2 k8s.io/apiserver v0.16.6
k8s.io/cri-api kubernetes-1.16.0-rc.2 k8s.io/client-go v0.16.6
k8s.io/client-go kubernetes-1.16.0-rc.2 k8s.io/cri-api v0.16.6
k8s.io/klog v0.4.0 k8s.io/klog v1.0.0
k8s.io/kubernetes v1.16.0-rc.2 k8s.io/kubernetes v1.16.6
k8s.io/utils c2654d5206da6b7b6ace12841e8f359bb89b443c k8s.io/utils e782cd3c129fc98ee807f3c889c0f26eb7c9daf5
sigs.k8s.io/yaml v1.1.0 sigs.k8s.io/yaml v1.1.0
# cni dependencies
github.com/containerd/go-cni 49fbd9b210f3c8ee3b7fd3cd797aabaf364627c1
github.com/containernetworking/cni v0.7.1
github.com/containernetworking/plugins v0.7.6
# zfs dependencies # zfs dependencies
github.com/containerd/zfs 2ceb2dbb8154202ed1b8fd32e4ea25b491d7b251 github.com/containerd/zfs 2ceb2dbb8154202ed1b8fd32e4ea25b491d7b251
github.com/mistifyio/go-zfs f784269be439d704d3dfa1906f45dd848fed2beb github.com/mistifyio/go-zfs f784269be439d704d3dfa1906f45dd848fed2beb
github.com/google/uuid v1.1.1
# aufs dependencies # aufs dependencies
github.com/containerd/aufs f894a800659b6e11c1a13084abd1712f346e349c github.com/containerd/aufs f894a800659b6e11c1a13084abd1712f346e349c
...@@ -21,7 +21,7 @@ var ( ...@@ -21,7 +21,7 @@ var (
Package = "github.com/containerd/containerd" Package = "github.com/containerd/containerd"
// Version holds the complete version number. Filled in at linking time. // Version holds the complete version number. Filled in at linking time.
Version = "1.3.2+unknown" Version = "1.3.9+unknown"
// Revision is filled with the VCS (e.g. git) revision being used to build // Revision is filled with the VCS (e.g. git) revision being used to build
// the program at linking time. // the program at linking time.
......
# Copyright 2018 The containerd Authors. # Copyright The containerd Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
...@@ -15,9 +15,13 @@ ...@@ -15,9 +15,13 @@
GO := go GO := go
GOOS := $(shell $(GO) env GOOS) GOOS := $(shell $(GO) env GOOS)
GOARCH := $(shell $(GO) env GOARCH) GOARCH := $(shell $(GO) env GOARCH)
WHALE = "🇩" WHALE := "🇩"
ONI = "👹" ONI := "👹"
EPOCH_TEST_COMMIT := f9e02affccd51702191e5312665a16045ffef8ab ifeq ($(GOOS),windows)
WHALE = "+"
ONI = "-"
endif
EPOCH_TEST_COMMIT := 67de3e4ccf2b2a69b8398798af7cfca01abf7a7e
PROJECT := github.com/containerd/cri PROJECT := github.com/containerd/cri
BINDIR := ${DESTDIR}/usr/local/bin BINDIR := ${DESTDIR}/usr/local/bin
BUILD_DIR := _output BUILD_DIR := _output
...@@ -26,35 +30,39 @@ BUILD_DIR := _output ...@@ -26,35 +30,39 @@ BUILD_DIR := _output
VERSION := $(shell git rev-parse --short HEAD) VERSION := $(shell git rev-parse --short HEAD)
TARBALL_PREFIX := cri-containerd TARBALL_PREFIX := cri-containerd
TARBALL := $(TARBALL_PREFIX)-$(VERSION).$(GOOS)-$(GOARCH).tar.gz TARBALL := $(TARBALL_PREFIX)-$(VERSION).$(GOOS)-$(GOARCH).tar.gz
BUILD_TAGS := seccomp apparmor ifneq ($(GOOS),windows)
BUILD_TAGS := seccomp apparmor selinux no_btrfs
endif
export BUILDTAGS := $(BUILD_TAGS)
# Add `-TEST` suffix to indicate that all binaries built from this repo are for test. # Add `-TEST` suffix to indicate that all binaries built from this repo are for test.
GO_LDFLAGS := -X $(PROJECT)/vendor/github.com/containerd/containerd/version.Version=$(VERSION)-TEST GO_LDFLAGS := -X $(PROJECT)/vendor/github.com/containerd/containerd/version.Version=$(VERSION)-TEST
SOURCES := $(shell find cmd/ pkg/ vendor/ -name '*.go') SOURCES := $(shell find cmd/ pkg/ vendor/ -name '*.go')
PLUGIN_SOURCES := $(shell ls *.go) PLUGIN_SOURCES := $(shell ls *.go)
INTEGRATION_SOURCES := $(shell find integration/ -name '*.go') INTEGRATION_SOURCES := $(shell find integration/ -name '*.go')
CONTAINERD_BIN := containerd
ifeq ($(GOOS),windows)
CONTAINERD_BIN := $(CONTAINERD_BIN).exe
endif
all: binaries all: binaries
help: ## this help help: ## this help
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z0-9._-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | sort @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z0-9._-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | sort
verify: lint gofmt boiler check-vendor ## execute the source code verification tools verify: lint gofmt check-vendor ## execute the source code verification tools
version: ## print current cri plugin release version version: ## print current cri plugin release version
@echo $(VERSION) @echo $(VERSION)
lint: lint:
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
golangci-lint run --skip-files .*_test.go golangci-lint run
gofmt: gofmt:
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
@./hack/verify-gofmt.sh @./hack/verify-gofmt.sh
boiler:
@echo "$(WHALE) $@"
@./hack/verify-boilerplate.sh
check-vendor: check-vendor:
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
@./hack/verify-vendor.sh @./hack/verify-vendor.sh
...@@ -72,7 +80,7 @@ sync-vendor: ...@@ -72,7 +80,7 @@ sync-vendor:
update-vendor: sync-vendor sort-vendor ## Syncs containerd/vendor.conf -> vendor.conf and sorts vendor.conf update-vendor: sync-vendor sort-vendor ## Syncs containerd/vendor.conf -> vendor.conf and sorts vendor.conf
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
$(BUILD_DIR)/containerd: $(SOURCES) $(PLUGIN_SOURCES) $(BUILD_DIR)/$(CONTAINERD_BIN): $(SOURCES) $(PLUGIN_SOURCES)
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
$(GO) build -o $@ \ $(GO) build -o $@ \
-tags '$(BUILD_TAGS)' \ -tags '$(BUILD_TAGS)' \
...@@ -107,29 +115,34 @@ clean: ## cleanup binaries ...@@ -107,29 +115,34 @@ clean: ## cleanup binaries
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
@rm -rf $(BUILD_DIR)/* @rm -rf $(BUILD_DIR)/*
binaries: $(BUILD_DIR)/containerd ## build a customized containerd (same result as make containerd) binaries: $(BUILD_DIR)/$(CONTAINERD_BIN) ## build a customized containerd (same result as make containerd)
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
static-binaries: GO_LDFLAGS += -extldflags "-fno-PIC -static" static-binaries: GO_LDFLAGS += -extldflags "-fno-PIC -static"
static-binaries: $(BUILD_DIR)/containerd ## build static containerd static-binaries: $(BUILD_DIR)/$(CONTAINERD_BIN) ## build static containerd
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
containerd: $(BUILD_DIR)/containerd ## build a customized containerd with CRI plugin for testing containerd: $(BUILD_DIR)/$(CONTAINERD_BIN) ## build a customized containerd with CRI plugin for testing
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
install-containerd: containerd ## installs customized containerd to system location install-containerd: containerd ## installs customized containerd to system location
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
@install -D -m 755 $(BUILD_DIR)/containerd $(BINDIR)/containerd @install -D -m 755 $(BUILD_DIR)/$(CONTAINERD_BIN) "$(BINDIR)/$(CONTAINERD_BIN)"
install: install-containerd ## installs customized containerd to system location install: install-containerd ## installs customized containerd to system location
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
uninstall: ## remove containerd from system location uninstall: ## remove containerd from system location
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
@rm -f $(BINDIR)/containerd @rm -f "$(BINDIR)/$(CONTAINERD_BIN)"
ifeq ($(GOOS),windows)
$(BUILD_DIR)/$(TARBALL): static-binaries vendor.conf
@BUILD_DIR=$(BUILD_DIR) TARBALL=$(TARBALL) VERSION=$(VERSION) ./hack/release-windows.sh
else
$(BUILD_DIR)/$(TARBALL): static-binaries vendor.conf $(BUILD_DIR)/$(TARBALL): static-binaries vendor.conf
@BUILD_DIR=$(BUILD_DIR) TARBALL=$(TARBALL) VERSION=$(VERSION) ./hack/release.sh @BUILD_DIR=$(BUILD_DIR) TARBALL=$(TARBALL) VERSION=$(VERSION) ./hack/release.sh
endif
release: $(BUILD_DIR)/$(TARBALL) ## build release tarball release: $(BUILD_DIR)/$(TARBALL) ## build release tarball
...@@ -142,22 +155,29 @@ proto: ## update protobuf of the cri plugin api ...@@ -142,22 +155,29 @@ proto: ## update protobuf of the cri plugin api
@API_PATH=pkg/api/v1 hack/update-proto.sh @API_PATH=pkg/api/v1 hack/update-proto.sh
@API_PATH=pkg/api/runtimeoptions/v1 hack/update-proto.sh @API_PATH=pkg/api/runtimeoptions/v1 hack/update-proto.sh
.PHONY: install.deps .PHONY: install.deps .install.deps.linux .install.deps.windows
ifeq ($(GOOS),windows)
install.deps: .install.deps.windows ## install windows deps on windows
else
install.deps: .install.deps.linux ## install windows deps on linux
endif
install.deps: ## install dependencies of cri (default 'seccomp apparmor' BUILDTAGS for runc build) .install.deps.linux: ## install dependencies of cri
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
@./hack/install/install-deps.sh @./hack/install/install-deps.sh
.install.deps.windows: ## install dependencies of cri on windows
@echo "$(WHALE) $@"
@./hack/install/windows/install-deps.sh
.PHONY: .gitvalidation .PHONY: .gitvalidation
# When this is running in travis, it will only check the travis commit range. # make .gitvalidation is only used localy for manual testing
# When running outside travis, it will check from $(EPOCH_TEST_COMMIT)..HEAD. # requires a clone of github.com/containerd/project
# containerd/project DCO validation runs automatically with github actions in ci.yml for each pull
.gitvalidation: .gitvalidation:
@echo "$(WHALE) $@" @echo "$(WHALE) $@"
ifeq ($(TRAVIS),true) DCO_VERBOSITY=-v DCO_RANGE=$(EPOCH_TEST_COMMIT)..HEAD ../project/script/validate/dco
git-validation -q -run DCO,short-subject
else
git-validation -v -run DCO,short-subject -range $(EPOCH_TEST_COMMIT)..HEAD
endif
.PHONY: install.tools .install.gitvalidation .install.golangci-lint .install.vndr .PHONY: install.tools .install.gitvalidation .install.golangci-lint .install.vndr
...@@ -186,7 +206,6 @@ install.tools: .install.gitvalidation .install.golangci-lint .install.vndr ## in ...@@ -186,7 +206,6 @@ install.tools: .install.gitvalidation .install.golangci-lint .install.vndr ## in
install-containerd \ install-containerd \
release \ release \
push \ push \
boiler \
clean \ clean \
default \ default \
gofmt \ gofmt \
......
...@@ -63,6 +63,10 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) { ...@@ -63,6 +63,10 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) {
ic.Meta.Exports = map[string]string{"CRIVersion": constants.CRIVersion} ic.Meta.Exports = map[string]string{"CRIVersion": constants.CRIVersion}
ctx := ic.Context ctx := ic.Context
pluginConfig := ic.Config.(*criconfig.PluginConfig) pluginConfig := ic.Config.(*criconfig.PluginConfig)
if err := criconfig.ValidatePluginConfig(ctx, pluginConfig); err != nil {
return nil, errors.Wrap(err, "invalid plugin config")
}
c := criconfig.Config{ c := criconfig.Config{
PluginConfig: *pluginConfig, PluginConfig: *pluginConfig,
ContainerdRootDir: filepath.Dir(ic.Root), ContainerdRootDir: filepath.Dir(ic.Root),
...@@ -72,10 +76,6 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) { ...@@ -72,10 +76,6 @@ func initCRIService(ic *plugin.InitContext) (interface{}, error) {
} }
log.G(ctx).Infof("Start cri plugin with config %+v", c) log.G(ctx).Infof("Start cri plugin with config %+v", c)
if err := criconfig.ValidatePluginConfig(ctx, pluginConfig); err != nil {
return nil, errors.Wrap(err, "invalid plugin config")
}
if err := setGLogLevel(); err != nil { if err := setGLogLevel(); err != nil {
return nil, errors.Wrap(err, "failed to set glog level") return nil, errors.Wrap(err, "failed to set glog level")
} }
......
...@@ -122,6 +122,7 @@ type AuthConfig struct { ...@@ -122,6 +122,7 @@ type AuthConfig struct {
// TLSConfig contains the CA/Cert/Key used for a registry // TLSConfig contains the CA/Cert/Key used for a registry
type TLSConfig struct { type TLSConfig struct {
InsecureSkipVerify bool `toml:"insecure_skip_verify" json:"insecure_skip_verify"`
CAFile string `toml:"ca_file" json:"caFile"` CAFile string `toml:"ca_file" json:"caFile"`
CertFile string `toml:"cert_file" json:"certFile"` CertFile string `toml:"cert_file" json:"certFile"`
KeyFile string `toml:"key_file" json:"keyFile"` KeyFile string `toml:"key_file" json:"keyFile"`
......
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Copyright The runc Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package seccomp
import (
"bufio"
"os"
"strings"
"golang.org/x/sys/unix"
)
// IsEnabled returns if the kernel has been configured to support seccomp.
// From https://github.com/opencontainers/runc/blob/v1.0.0-rc91/libcontainer/seccomp/seccomp_linux.go#L86-L102
func IsEnabled() bool {
// Try to read from /proc/self/status for kernels > 3.8
s, err := parseStatusFile("/proc/self/status")
if err != nil {
// Check if Seccomp is supported, via CONFIG_SECCOMP.
if err := unix.Prctl(unix.PR_GET_SECCOMP, 0, 0, 0, 0); err != unix.EINVAL {
// Make sure the kernel has CONFIG_SECCOMP_FILTER.
if err := unix.Prctl(unix.PR_SET_SECCOMP, unix.SECCOMP_MODE_FILTER, 0, 0, 0); err != unix.EINVAL {
return true
}
}
return false
}
_, ok := s["Seccomp"]
return ok
}
// parseStatusFile is from https://github.com/opencontainers/runc/blob/v1.0.0-rc91/libcontainer/seccomp/seccomp_linux.go#L243-L268
func parseStatusFile(path string) (map[string]string, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
s := bufio.NewScanner(f)
status := make(map[string]string)
for s.Scan() {
text := s.Text()
parts := strings.Split(text, ":")
if len(parts) <= 1 {
continue
}
status[parts[0]] = parts[1]
}
if err := s.Err(); err != nil {
return nil, err
}
return status, nil
}
// +build !linux
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package seccomp
func IsEnabled() bool {
return false
}
...@@ -39,6 +39,7 @@ import ( ...@@ -39,6 +39,7 @@ import (
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
imagespec "github.com/opencontainers/image-spec/specs-go/v1" imagespec "github.com/opencontainers/image-spec/specs-go/v1"
runtimespec "github.com/opencontainers/runtime-spec/specs-go" runtimespec "github.com/opencontainers/runtime-spec/specs-go"
selinux "github.com/opencontainers/selinux/go-selinux"
"github.com/opencontainers/selinux/go-selinux/label" "github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/net/context" "golang.org/x/net/context"
...@@ -182,7 +183,7 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta ...@@ -182,7 +183,7 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
} }
defer func() { defer func() {
if retErr != nil { if retErr != nil {
_ = label.ReleaseLabel(spec.Process.SelinuxLabel) selinux.ReleaseLabel(spec.Process.SelinuxLabel)
} }
}() }()
...@@ -379,11 +380,13 @@ func (c *criService) generateContainerSpec(id string, sandboxID string, sandboxP ...@@ -379,11 +380,13 @@ func (c *criService) generateContainerSpec(id string, sandboxID string, sandboxP
specOpts = append(specOpts, oci.WithEnv(env)) specOpts = append(specOpts, oci.WithEnv(env))
securityContext := config.GetLinux().GetSecurityContext() securityContext := config.GetLinux().GetSecurityContext()
labelOptions := toLabel(securityContext.GetSelinuxOptions()) labelOptions, err := toLabel(securityContext.GetSelinuxOptions())
if len(labelOptions) == 0 { if err != nil {
// Use pod level SELinux config return nil, err
}
if len(labelOptions) == 0 { // Use pod level SELinux config
if sandbox, err := c.sandboxStore.Get(sandboxID); err == nil { if sandbox, err := c.sandboxStore.Get(sandboxID); err == nil {
labelOptions, err = label.DupSecOpt(sandbox.ProcessLabel) labelOptions, err = selinux.DupSecOpt(sandbox.ProcessLabel)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -396,7 +399,7 @@ func (c *criService) generateContainerSpec(id string, sandboxID string, sandboxP ...@@ -396,7 +399,7 @@ func (c *criService) generateContainerSpec(id string, sandboxID string, sandboxP
} }
defer func() { defer func() {
if retErr != nil { if retErr != nil {
_ = label.ReleaseLabel(processLabel) selinux.ReleaseLabel(processLabel)
} }
}() }()
...@@ -492,8 +495,8 @@ func (c *criService) generateVolumeMounts(containerRootDir string, criMounts []* ...@@ -492,8 +495,8 @@ func (c *criService) generateVolumeMounts(containerRootDir string, criMounts []*
mounts = append(mounts, &runtime.Mount{ mounts = append(mounts, &runtime.Mount{
ContainerPath: dst, ContainerPath: dst,
HostPath: src, HostPath: src,
SelinuxRelabel: true,
// Use default mount propagation. // Use default mount propagation.
// TODO(random-liu): What about selinux relabel?
}) })
} }
return mounts return mounts
...@@ -547,6 +550,7 @@ func (c *criService) generateContainerMounts(sandboxID string, config *runtime.C ...@@ -547,6 +550,7 @@ func (c *criService) generateContainerMounts(sandboxID string, config *runtime.C
ContainerPath: devShm, ContainerPath: devShm,
HostPath: sandboxDevShm, HostPath: sandboxDevShm,
Readonly: false, Readonly: false,
SelinuxRelabel: sandboxDevShm != devShm,
}) })
} }
return mounts return mounts
......
...@@ -22,6 +22,7 @@ import ( ...@@ -22,6 +22,7 @@ import (
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/docker/docker/pkg/system" "github.com/docker/docker/pkg/system"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context" "golang.org/x/net/context"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
...@@ -30,7 +31,6 @@ import ( ...@@ -30,7 +31,6 @@ import (
) )
// RemoveContainer removes the container. // RemoveContainer removes the container.
// TODO(random-liu): Forcibly stop container if it's running.
func (c *criService) RemoveContainer(ctx context.Context, r *runtime.RemoveContainerRequest) (_ *runtime.RemoveContainerResponse, retErr error) { func (c *criService) RemoveContainer(ctx context.Context, r *runtime.RemoveContainerRequest) (_ *runtime.RemoveContainerResponse, retErr error) {
container, err := c.containerStore.Get(r.GetContainerId()) container, err := c.containerStore.Get(r.GetContainerId())
if err != nil { if err != nil {
...@@ -43,6 +43,17 @@ func (c *criService) RemoveContainer(ctx context.Context, r *runtime.RemoveConta ...@@ -43,6 +43,17 @@ func (c *criService) RemoveContainer(ctx context.Context, r *runtime.RemoveConta
} }
id := container.ID id := container.ID
// Forcibly stop the containers if they are in running or unknown state
state := container.Status.Get().State()
if state == runtime.ContainerState_CONTAINER_RUNNING ||
state == runtime.ContainerState_CONTAINER_UNKNOWN {
logrus.Infof("Forcibly stopping container %q", id)
if err := c.stopContainer(ctx, container, 0); err != nil {
return nil, errors.Wrapf(err, "failed to forcibly stop container %q", id)
}
}
// Set removing state to prevent other start/remove operations against this container // Set removing state to prevent other start/remove operations against this container
// while it's being removed. // while it's being removed.
if err := setContainerRemoving(container); err != nil { if err := setContainerRemoving(container); err != nil {
......
...@@ -333,6 +333,12 @@ func handleContainerExit(ctx context.Context, e *eventtypes.TaskExit, cntr conta ...@@ -333,6 +333,12 @@ func handleContainerExit(ctx context.Context, e *eventtypes.TaskExit, cntr conta
status.Pid = 0 status.Pid = 0
status.FinishedAt = e.ExitedAt.UnixNano() status.FinishedAt = e.ExitedAt.UnixNano()
status.ExitCode = int32(e.ExitStatus) status.ExitCode = int32(e.ExitStatus)
// Unknown state can only transit to EXITED state, so we need
// to handle unknown state here.
if status.Unknown {
logrus.Debugf("Container %q transited from UNKNOWN to EXITED", cntr.ID)
status.Unknown = false
}
return status, nil return status, nil
}) })
if err != nil { if err != nil {
......
...@@ -298,11 +298,15 @@ func (c *criService) ensureImageExists(ctx context.Context, ref string, config * ...@@ -298,11 +298,15 @@ func (c *criService) ensureImageExists(ctx context.Context, ref string, config *
return &newImage, nil return &newImage, nil
} }
func toLabel(selinuxOptions *runtime.SELinuxOption) (labels []string) { func toLabel(selinuxOptions *runtime.SELinuxOption) ([]string, error) {
var labels []string
if selinuxOptions == nil { if selinuxOptions == nil {
return nil return nil, nil
}
if err := checkSelinuxLevel(selinuxOptions.Level); err != nil {
return nil, err
} }
if selinuxOptions.User != "" { if selinuxOptions.User != "" {
labels = append(labels, "user:"+selinuxOptions.User) labels = append(labels, "user:"+selinuxOptions.User)
} }
...@@ -316,11 +320,15 @@ func toLabel(selinuxOptions *runtime.SELinuxOption) (labels []string) { ...@@ -316,11 +320,15 @@ func toLabel(selinuxOptions *runtime.SELinuxOption) (labels []string) {
labels = append(labels, "level:"+selinuxOptions.Level) labels = append(labels, "level:"+selinuxOptions.Level)
} }
return return labels, nil
} }
func initLabelsFromOpt(selinuxOpts *runtime.SELinuxOption) (string, string, error) { func initLabelsFromOpt(selinuxOpts *runtime.SELinuxOption) (string, string, error) {
return initLabels(toLabel(selinuxOpts)) labels, err := toLabel(selinuxOpts)
if err != nil {
return "", "", err
}
return label.InitLabels(labels)
} }
func initLabels(options []string) (string, string, error) { func initLabels(options []string) (string, string, error) {
...@@ -339,7 +347,7 @@ func checkSelinuxLevel(level string) error { ...@@ -339,7 +347,7 @@ func checkSelinuxLevel(level string) error {
return nil return nil
} }
matched, err := regexp.MatchString(`^s\d(-s\d)??(:c\d{1,4}((.c\d{1,4})?,c\d{1,4})*(.c\d{1,4})?(,c\d{1,4}(.c\d{1,4})?)*)?$`, level) matched, err := regexp.MatchString(`^s\d(-s\d)??(:c\d{1,4}(\.c\d{1,4})?(,c\d{1,4}(\.c\d{1,4})?)*)?$`, level)
if err != nil { if err != nil {
return errors.Wrapf(err, "the format of 'level' %q is not correct", level) return errors.Wrapf(err, "the format of 'level' %q is not correct", level)
} }
...@@ -473,6 +481,7 @@ func unknownContainerStatus() containerstore.Status { ...@@ -473,6 +481,7 @@ func unknownContainerStatus() containerstore.Status {
FinishedAt: 0, FinishedAt: 0,
ExitCode: unknownExitCode, ExitCode: unknownExitCode,
Reason: unknownExitReason, Reason: unknownExitReason,
Unknown: true,
} }
} }
......
...@@ -253,22 +253,28 @@ func (c *criService) updateImage(ctx context.Context, r string) error { ...@@ -253,22 +253,28 @@ func (c *criService) updateImage(ctx context.Context, r string) error {
// getTLSConfig returns a TLSConfig configured with a CA/Cert/Key specified by registryTLSConfig // getTLSConfig returns a TLSConfig configured with a CA/Cert/Key specified by registryTLSConfig
func (c *criService) getTLSConfig(registryTLSConfig criconfig.TLSConfig) (*tls.Config, error) { func (c *criService) getTLSConfig(registryTLSConfig criconfig.TLSConfig) (*tls.Config, error) {
var ( var (
tlsConfig = &tls.Config{}
cert tls.Certificate cert tls.Certificate
err error err error
) )
if registryTLSConfig.CertFile != "" && registryTLSConfig.KeyFile == "" {
return nil, errors.Errorf("cert file %q was specified, but no corresponding key file was specified", registryTLSConfig.CertFile)
}
if registryTLSConfig.CertFile == "" && registryTLSConfig.KeyFile != "" {
return nil, errors.Errorf("key file %q was specified, but no corresponding cert file was specified", registryTLSConfig.KeyFile)
}
if registryTLSConfig.CertFile != "" && registryTLSConfig.KeyFile != "" { if registryTLSConfig.CertFile != "" && registryTLSConfig.KeyFile != "" {
cert, err = tls.LoadX509KeyPair(registryTLSConfig.CertFile, registryTLSConfig.KeyFile) cert, err = tls.LoadX509KeyPair(registryTLSConfig.CertFile, registryTLSConfig.KeyFile)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to load cert file") return nil, errors.Wrap(err, "failed to load cert file")
} }
if len(cert.Certificate) != 0 {
tlsConfig.Certificates = []tls.Certificate{cert}
} }
if registryTLSConfig.CertFile != "" && registryTLSConfig.KeyFile == "" { tlsConfig.BuildNameToCertificate() // nolint:staticcheck
return nil, errors.Errorf("cert file %q was specified, but no corresponding key file was specified", registryTLSConfig.CertFile)
}
if registryTLSConfig.CertFile == "" && registryTLSConfig.KeyFile != "" {
return nil, errors.Errorf("key file %q was specified, but no corresponding cert file was specified", registryTLSConfig.KeyFile)
} }
if registryTLSConfig.CAFile != "" {
caCertPool, err := x509.SystemCertPool() caCertPool, err := x509.SystemCertPool()
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to get system cert pool") return nil, errors.Wrap(err, "failed to get system cert pool")
...@@ -278,14 +284,10 @@ func (c *criService) getTLSConfig(registryTLSConfig criconfig.TLSConfig) (*tls.C ...@@ -278,14 +284,10 @@ func (c *criService) getTLSConfig(registryTLSConfig criconfig.TLSConfig) (*tls.C
return nil, errors.Wrap(err, "failed to load CA file") return nil, errors.Wrap(err, "failed to load CA file")
} }
caCertPool.AppendCertsFromPEM(caCert) caCertPool.AppendCertsFromPEM(caCert)
tlsConfig.RootCAs = caCertPool
tlsConfig := &tls.Config{
RootCAs: caCertPool,
} }
if len(cert.Certificate) != 0 {
tlsConfig.Certificates = []tls.Certificate{cert} tlsConfig.InsecureSkipVerify = registryTLSConfig.InsecureSkipVerify
}
tlsConfig.BuildNameToCertificate()
return tlsConfig, nil return tlsConfig, nil
} }
......
...@@ -307,7 +307,9 @@ func (c *criService) loadContainer(ctx context.Context, cntr containerd.Containe ...@@ -307,7 +307,9 @@ func (c *criService) loadContainer(ctx context.Context, cntr containerd.Containe
}() }()
if err != nil { if err != nil {
log.G(ctx).WithError(err).Errorf("Failed to load container status for %q", id) log.G(ctx).WithError(err).Errorf("Failed to load container status for %q", id)
status = unknownContainerStatus() // Only set the unknown field in this case, because other fields may
// contain useful information loaded from the checkpoint.
status.Unknown = true
} }
opts := []containerstore.Opts{ opts := []containerstore.Opts{
containerstore.WithStatus(status, containerDir), containerstore.WithStatus(status, containerDir),
......
...@@ -22,6 +22,7 @@ import ( ...@@ -22,6 +22,7 @@ import (
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/docker/docker/pkg/system" "github.com/docker/docker/pkg/system"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/net/context" "golang.org/x/net/context"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
...@@ -49,7 +50,10 @@ func (c *criService) RemovePodSandbox(ctx context.Context, r *runtime.RemovePodS ...@@ -49,7 +50,10 @@ func (c *criService) RemovePodSandbox(ctx context.Context, r *runtime.RemovePodS
// Return error if sandbox container is still running or unknown. // Return error if sandbox container is still running or unknown.
state := sandbox.Status.Get().State state := sandbox.Status.Get().State
if state == sandboxstore.StateReady || state == sandboxstore.StateUnknown { if state == sandboxstore.StateReady || state == sandboxstore.StateUnknown {
return nil, errors.Errorf("sandbox container %q is not fully stopped", id) logrus.Infof("Forcibly stopping sandbox %q", id)
if err := c.stopPodSandbox(ctx, sandbox); err != nil {
return nil, errors.Wrapf(err, "failed to forcibly stop sandbox %q", id)
}
} }
// Return error if sandbox network namespace is not closed yet. // Return error if sandbox network namespace is not closed yet.
......
...@@ -34,7 +34,7 @@ import ( ...@@ -34,7 +34,7 @@ import (
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
imagespec "github.com/opencontainers/image-spec/specs-go/v1" imagespec "github.com/opencontainers/image-spec/specs-go/v1"
runtimespec "github.com/opencontainers/runtime-spec/specs-go" runtimespec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux/label" selinux "github.com/opencontainers/selinux/go-selinux"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/net/context" "golang.org/x/net/context"
...@@ -162,7 +162,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox ...@@ -162,7 +162,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
sandbox.ProcessLabel = spec.Process.SelinuxLabel sandbox.ProcessLabel = spec.Process.SelinuxLabel
defer func() { defer func() {
if retErr != nil { if retErr != nil {
_ = label.ReleaseLabel(sandbox.ProcessLabel) selinux.ReleaseLabel(sandbox.ProcessLabel)
} }
}() }()
...@@ -284,7 +284,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox ...@@ -284,7 +284,7 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
var taskOpts []containerd.NewTaskOpts var taskOpts []containerd.NewTaskOpts
// TODO(random-liu): Remove this after shim v1 is deprecated. // TODO(random-liu): Remove this after shim v1 is deprecated.
if c.config.NoPivot && ociRuntime.Type == plugin.RuntimeRuncV1 { if c.config.NoPivot && (ociRuntime.Type == plugin.RuntimeRuncV1 || ociRuntime.Type == plugin.RuntimeRuncV2) {
taskOpts = append(taskOpts, containerd.WithNoPivotRoot) taskOpts = append(taskOpts, containerd.WithNoPivotRoot)
} }
// We don't need stdio for sandbox container. // We don't need stdio for sandbox container.
...@@ -422,7 +422,7 @@ func (c *criService) generateSandboxContainerSpec(id string, config *runtime.Pod ...@@ -422,7 +422,7 @@ func (c *criService) generateSandboxContainerSpec(id string, config *runtime.Pod
} }
defer func() { defer func() {
if retErr != nil && processLabel != "" { if retErr != nil && processLabel != "" {
_ = label.ReleaseLabel(processLabel) selinux.ReleaseLabel(processLabel)
} }
}() }()
......
/* /*
Copyright 2017 The Kubernetes Authors. Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package server package server
...@@ -40,6 +40,15 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb ...@@ -40,6 +40,15 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb
return nil, errors.Wrapf(err, "an error occurred when try to find sandbox %q", return nil, errors.Wrapf(err, "an error occurred when try to find sandbox %q",
r.GetPodSandboxId()) r.GetPodSandboxId())
} }
if err := c.stopPodSandbox(ctx, sandbox); err != nil {
return nil, err
}
return &runtime.StopPodSandboxResponse{}, nil
}
func (c *criService) stopPodSandbox(ctx context.Context, sandbox sandboxstore.Sandbox) error {
// Use the full sandbox id. // Use the full sandbox id.
id := sandbox.ID id := sandbox.ID
...@@ -53,20 +62,20 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb ...@@ -53,20 +62,20 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb
} }
// Forcibly stop the container. Do not use `StopContainer`, because it introduces a race // Forcibly stop the container. Do not use `StopContainer`, because it introduces a race
// if a container is removed after list. // if a container is removed after list.
if err = c.stopContainer(ctx, container, 0); err != nil { if err := c.stopContainer(ctx, container, 0); err != nil {
return nil, errors.Wrapf(err, "failed to stop container %q", container.ID) return errors.Wrapf(err, "failed to stop container %q", container.ID)
} }
} }
if err := c.unmountSandboxFiles(id, sandbox.Config); err != nil { if err := c.unmountSandboxFiles(id, sandbox.Config); err != nil {
return nil, errors.Wrap(err, "failed to unmount sandbox files") return errors.Wrap(err, "failed to unmount sandbox files")
} }
// Only stop sandbox container when it's running or unknown. // Only stop sandbox container when it's running or unknown.
state := sandbox.Status.Get().State state := sandbox.Status.Get().State
if state == sandboxstore.StateReady || state == sandboxstore.StateUnknown { if state == sandboxstore.StateReady || state == sandboxstore.StateUnknown {
if err := c.stopSandboxContainer(ctx, sandbox); err != nil { if err := c.stopSandboxContainer(ctx, sandbox); err != nil {
return nil, errors.Wrapf(err, "failed to stop sandbox container %q in %q state", id, state) return errors.Wrapf(err, "failed to stop sandbox container %q in %q state", id, state)
} }
} }
...@@ -75,21 +84,21 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb ...@@ -75,21 +84,21 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb
// Use empty netns path if netns is not available. This is defined in: // Use empty netns path if netns is not available. This is defined in:
// https://github.com/containernetworking/cni/blob/v0.7.0-alpha1/SPEC.md // https://github.com/containernetworking/cni/blob/v0.7.0-alpha1/SPEC.md
if closed, err := sandbox.NetNS.Closed(); err != nil { if closed, err := sandbox.NetNS.Closed(); err != nil {
return nil, errors.Wrap(err, "failed to check network namespace closed") return errors.Wrap(err, "failed to check network namespace closed")
} else if closed { } else if closed {
sandbox.NetNSPath = "" sandbox.NetNSPath = ""
} }
if err := c.teardownPodNetwork(ctx, sandbox); err != nil { if err := c.teardownPodNetwork(ctx, sandbox); err != nil {
return nil, errors.Wrapf(err, "failed to destroy network for sandbox %q", id) return errors.Wrapf(err, "failed to destroy network for sandbox %q", id)
} }
if err = sandbox.NetNS.Remove(); err != nil { if err := sandbox.NetNS.Remove(); err != nil {
return nil, errors.Wrapf(err, "failed to remove network namespace for sandbox %q", id) return errors.Wrapf(err, "failed to remove network namespace for sandbox %q", id)
} }
} }
log.G(ctx).Infof("TearDown network for sandbox %q successfully", id) log.G(ctx).Infof("TearDown network for sandbox %q successfully", id)
return &runtime.StopPodSandboxResponse{}, nil return nil
} }
// stopSandboxContainer kills the sandbox container. // stopSandboxContainer kills the sandbox container.
......
...@@ -28,7 +28,6 @@ import ( ...@@ -28,7 +28,6 @@ import (
"github.com/containerd/cri/pkg/store/label" "github.com/containerd/cri/pkg/store/label"
cni "github.com/containerd/go-cni" cni "github.com/containerd/go-cni"
runcapparmor "github.com/opencontainers/runc/libcontainer/apparmor" runcapparmor "github.com/opencontainers/runc/libcontainer/apparmor"
runcseccomp "github.com/opencontainers/runc/libcontainer/seccomp"
runcsystem "github.com/opencontainers/runc/libcontainer/system" runcsystem "github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/selinux/go-selinux" "github.com/opencontainers/selinux/go-selinux"
"github.com/pkg/errors" "github.com/pkg/errors"
...@@ -42,6 +41,7 @@ import ( ...@@ -42,6 +41,7 @@ import (
ctrdutil "github.com/containerd/cri/pkg/containerd/util" ctrdutil "github.com/containerd/cri/pkg/containerd/util"
osinterface "github.com/containerd/cri/pkg/os" osinterface "github.com/containerd/cri/pkg/os"
"github.com/containerd/cri/pkg/registrar" "github.com/containerd/cri/pkg/registrar"
"github.com/containerd/cri/pkg/seccomp"
containerstore "github.com/containerd/cri/pkg/store/container" containerstore "github.com/containerd/cri/pkg/store/container"
imagestore "github.com/containerd/cri/pkg/store/image" imagestore "github.com/containerd/cri/pkg/store/image"
sandboxstore "github.com/containerd/cri/pkg/store/sandbox" sandboxstore "github.com/containerd/cri/pkg/store/sandbox"
...@@ -110,7 +110,7 @@ func NewCRIService(config criconfig.Config, client *containerd.Client) (CRIServi ...@@ -110,7 +110,7 @@ func NewCRIService(config criconfig.Config, client *containerd.Client) (CRIServi
config: config, config: config,
client: client, client: client,
apparmorEnabled: runcapparmor.IsEnabled() && !config.DisableApparmor, apparmorEnabled: runcapparmor.IsEnabled() && !config.DisableApparmor,
seccompEnabled: runcseccomp.IsEnabled(), seccompEnabled: seccomp.IsEnabled(),
os: osinterface.RealOS{}, os: osinterface.RealOS{},
sandboxStore: sandboxstore.NewStore(labels), sandboxStore: sandboxstore.NewStore(labels),
containerStore: containerstore.NewStore(labels), containerStore: containerstore.NewStore(labels),
......
...@@ -94,10 +94,16 @@ type Status struct { ...@@ -94,10 +94,16 @@ type Status struct {
// Removing indicates that the container is in removing state. // Removing indicates that the container is in removing state.
// This field doesn't need to be checkpointed. // This field doesn't need to be checkpointed.
Removing bool `json:"-"` Removing bool `json:"-"`
// Unknown indicates that the container status is not fully loaded.
// This field doesn't need to be checkpointed.
Unknown bool `json:"-"`
} }
// State returns current state of the container based on the container status. // State returns current state of the container based on the container status.
func (s Status) State() runtime.ContainerState { func (s Status) State() runtime.ContainerState {
if s.Unknown {
return runtime.ContainerState_CONTAINER_UNKNOWN
}
if s.FinishedAt != 0 { if s.FinishedAt != 0 {
return runtime.ContainerState_CONTAINER_EXITED return runtime.ContainerState_CONTAINER_EXITED
} }
......
# cri dependencies # cri dependencies
github.com/tchap/go-patricia v2.2.6 github.com/tchap/go-patricia v2.2.6
github.com/opencontainers/selinux v1.2.2 github.com/opencontainers/selinux bb88c45a3863dc4c38320d71b890bb30ef9feba4
github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00 github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00
github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580 github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
# containerd dependencies # containerd dependencies
go.etcd.io/bbolt 2eb7227adea1d5cf85f0bc2a82b7059b13c2fa68
google.golang.org/grpc 25c4f928eaa6d96443009bd842389fb4fa48664e # v1.20.1
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
golang.org/x/sys 4c4f7f33c9ed00de01c4c741d2177abfcfe19307 https://github.com/golang/sys
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
github.com/sirupsen/logrus v1.4.1
github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd
github.com/prometheus/common 89604d197083d4781071d3c65855d24ecfb0a563
github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c
github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823
github.com/pkg/errors v0.8.1
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
github.com/opencontainers/runc f4982d86f7fde0b6f953cc62ccc4022c519a10a9 # v1.0.0-rc8-32-gf4982d86
github.com/opencontainers/image-spec v1.0.1
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
github.com/matttproud/golang_protobuf_extensions v1.0.1
github.com/grpc-ecosystem/go-grpc-prometheus v1.1
github.com/google/uuid v1.1.1
github.com/golang/protobuf v1.2.0
github.com/gogo/protobuf v1.2.1
github.com/gogo/googleapis v1.2.0
github.com/godbus/dbus v3
github.com/docker/go-units v0.4.0
github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
github.com/coreos/go-systemd v14
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
github.com/containerd/ttrpc 92c8520ef9f86600c650dd540266a007bf03670f
github.com/containerd/go-runc e029b79d8cda8374981c64eba71f28ec38e5526f
github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
github.com/containerd/continuity f2a389ac0a02ce21c09edd7344677a601970f41c
github.com/containerd/containerd d4802a64f9737f02db3426751f380d97fc878dec
github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
github.com/containerd/cgroups c4b9ac5c7601384c965b9646fc515884e091ebb9
github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
github.com/Microsoft/hcsshim 9e921883ac929bbe515b39793ece99ce3a9d7706
github.com/Microsoft/go-winio v0.4.14
github.com/BurntSushi/toml v0.3.1 github.com/BurntSushi/toml v0.3.1
github.com/imdario/mergo v0.3.7 github.com/Microsoft/go-winio v0.4.14
github.com/Microsoft/hcsshim 9e921883ac929bbe515b39793ece99ce3a9d7706
github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
github.com/containerd/cgroups c4b9ac5c7601384c965b9646fc515884e091ebb9
github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
github.com/containerd/containerd v1.3.6
github.com/containerd/continuity f2a389ac0a02ce21c09edd7344677a601970f41c
github.com/containerd/fifo bda0ff6ed73c67bfb5e62bc9c697f146b7fd7f13
github.com/containerd/go-runc e029b79d8cda8374981c64eba71f28ec38e5526f
github.com/containerd/ttrpc 92c8520ef9f86600c650dd540266a007bf03670f
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6 # v14
github.com/cpuguy83/go-md2man 7762f7e404f8416dfa1d9bb6a8c192aa9acb4d19 # v1.0.10
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
github.com/docker/go-units v0.4.0
github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f # v3
github.com/gogo/googleapis v1.2.0
github.com/gogo/protobuf v1.2.1
github.com/golang/protobuf v1.2.0
github.com/google/uuid 0cd6bf5da1e1c83f8b45653022c74f71af0538a4 # v1.1.1
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0 # v1.1
github.com/hashicorp/golang-lru v0.5.3
github.com/imdario/mergo 7c29201646fa3de8506f701213473dd407f19646 # v0.3.7
github.com/matttproud/golang_protobuf_extensions v1.0.1
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
github.com/opencontainers/image-spec v1.0.1
github.com/opencontainers/runc d736ef14f0288d6993a1845745d6756cfc9ddd5a # v1.0.0-rc9
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823
github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c
github.com/prometheus/common 89604d197083d4781071d3c65855d24ecfb0a563
github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd
github.com/russross/blackfriday 05f3235734ad95d0016f6a23902f06461fcf567a # v1.5.2
github.com/sirupsen/logrus v1.4.1
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
github.com/urfave/cli v1.22.0
go.etcd.io/bbolt v1.3.3
go.opencensus.io v0.22.0
golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
golang.org/x/sys 9eafafc0a87e0fd0aeeba439a4573537970c44c7 https://github.com/golang/sys
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
google.golang.org/appengine v1.5.0
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
google.golang.org/grpc 6eaf6f47437a6b4e2153a190160ef39a92c7eceb # v1.23.0
# kubernetes dependencies # kubernetes dependencies
sigs.k8s.io/yaml v1.1.0 sigs.k8s.io/yaml v1.1.0
k8s.io/utils c2654d5206da6b7b6ace12841e8f359bb89b443c k8s.io/utils e782cd3c129fc98ee807f3c889c0f26eb7c9daf5
k8s.io/kubernetes v1.16.0-rc.2 k8s.io/kubernetes v1.16.6
k8s.io/klog v0.4.0 k8s.io/klog v1.0.0
k8s.io/cri-api kubernetes-1.16.0-rc.2 k8s.io/cri-api kubernetes-1.16.6
k8s.io/client-go kubernetes-1.16.0-rc.2 k8s.io/client-go kubernetes-1.16.6
k8s.io/api kubernetes-1.16.0-rc.2 k8s.io/api kubernetes-1.16.6
k8s.io/apiserver kubernetes-1.16.0-rc.2 k8s.io/apiserver kubernetes-1.16.6
k8s.io/apimachinery kubernetes-1.16.0-rc.2 k8s.io/apimachinery kubernetes-1.16.6
gopkg.in/yaml.v2 v2.2.2 gopkg.in/yaml.v2 53403b58ad1b561927d19068c655246f2db79d48 # v2.2.8
gopkg.in/inf.v0 v0.9.0 gopkg.in/inf.v0 v0.9.1
golang.org/x/time 85acf8d2951cb2a3bde7632f9ff273ef0379bcbd golang.org/x/time 9d24e82272b4f38b78bc8cff74fa936d31ccd8ef
golang.org/x/oauth2 0f29369cfe4552d0e4bcddc57cc75f4d7e672a33 golang.org/x/oauth2 0f29369cfe4552d0e4bcddc57cc75f4d7e672a33
golang.org/x/crypto 5c40567a22f818bd14a1ea7245dad9f8ef0691aa golang.org/x/crypto 60c769a6c58655dab1b9adac0d58967dd517cfba
github.com/stretchr/testify v1.3.0 github.com/stretchr/testify v1.4.0
github.com/seccomp/libseccomp-golang v0.9.1
github.com/pmezard/go-difflib v1.0.0 github.com/pmezard/go-difflib v1.0.0
github.com/modern-go/reflect2 1.0.1 github.com/modern-go/reflect2 v1.0.1
github.com/modern-go/concurrent 1.0.3 github.com/modern-go/concurrent 1.0.3
github.com/json-iterator/go v1.1.7 github.com/json-iterator/go v1.1.8
github.com/google/gofuzz v1.0.0 github.com/google/gofuzz v1.0.0
github.com/emicklei/go-restful v2.9.5 github.com/emicklei/go-restful v2.9.5
github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528 github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528
......
# errwrap
`errwrap` is a package for Go that formalizes the pattern of wrapping errors
and checking if an error contains another error.
There is a common pattern in Go of taking a returned `error` value and
then wrapping it (such as with `fmt.Errorf`) before returning it. The problem
with this pattern is that you completely lose the original `error` structure.
Arguably the _correct_ approach is that you should make a custom structure
implementing the `error` interface, and have the original error as a field
on that structure, such [as this example](http://golang.org/pkg/os/#PathError).
This is a good approach, but you have to know the entire chain of possible
rewrapping that happens, when you might just care about one.
`errwrap` formalizes this pattern (it doesn't matter what approach you use
above) by giving a single interface for wrapping errors, checking if a specific
error is wrapped, and extracting that error.
## Installation and Docs
Install using `go get github.com/hashicorp/errwrap`.
Full documentation is available at
http://godoc.org/github.com/hashicorp/errwrap
## Usage
#### Basic Usage
Below is a very basic example of its usage:
```go
// A function that always returns an error, but wraps it, like a real
// function might.
func tryOpen() error {
_, err := os.Open("/i/dont/exist")
if err != nil {
return errwrap.Wrapf("Doesn't exist: {{err}}", err)
}
return nil
}
func main() {
err := tryOpen()
// We can use the Contains helpers to check if an error contains
// another error. It is safe to do this with a nil error, or with
// an error that doesn't even use the errwrap package.
if errwrap.Contains(err, "does not exist") {
// Do something
}
if errwrap.ContainsType(err, new(os.PathError)) {
// Do something
}
// Or we can use the associated `Get` functions to just extract
// a specific error. This would return nil if that specific error doesn't
// exist.
perr := errwrap.GetType(err, new(os.PathError))
}
```
#### Custom Types
If you're already making custom types that properly wrap errors, then
you can get all the functionality of `errwraps.Contains` and such by
implementing the `Wrapper` interface with just one function. Example:
```go
type AppError {
Code ErrorCode
Err error
}
func (e *AppError) WrappedErrors() []error {
return []error{e.Err}
}
```
Now this works:
```go
err := &AppError{Err: fmt.Errorf("an error")}
if errwrap.ContainsType(err, fmt.Errorf("")) {
// This will work!
}
```
// Package errwrap implements methods to formalize error wrapping in Go.
//
// All of the top-level functions that take an `error` are built to be able
// to take any error, not just wrapped errors. This allows you to use errwrap
// without having to type-check and type-cast everywhere.
package errwrap
import (
"errors"
"reflect"
"strings"
)
// WalkFunc is the callback called for Walk.
type WalkFunc func(error)
// Wrapper is an interface that can be implemented by custom types to
// have all the Contains, Get, etc. functions in errwrap work.
//
// When Walk reaches a Wrapper, it will call the callback for every
// wrapped error in addition to the wrapper itself. Since all the top-level
// functions in errwrap use Walk, this means that all those functions work
// with your custom type.
type Wrapper interface {
WrappedErrors() []error
}
// Wrap defines that outer wraps inner, returning an error type that
// can be cleanly used with the other methods in this package, such as
// Contains, GetAll, etc.
//
// This function won't modify the error message at all (the outer message
// will be used).
func Wrap(outer, inner error) error {
return &wrappedError{
Outer: outer,
Inner: inner,
}
}
// Wrapf wraps an error with a formatting message. This is similar to using
// `fmt.Errorf` to wrap an error. If you're using `fmt.Errorf` to wrap
// errors, you should replace it with this.
//
// format is the format of the error message. The string '{{err}}' will
// be replaced with the original error message.
func Wrapf(format string, err error) error {
outerMsg := "<nil>"
if err != nil {
outerMsg = err.Error()
}
outer := errors.New(strings.Replace(
format, "{{err}}", outerMsg, -1))
return Wrap(outer, err)
}
// Contains checks if the given error contains an error with the
// message msg. If err is not a wrapped error, this will always return
// false unless the error itself happens to match this msg.
func Contains(err error, msg string) bool {
return len(GetAll(err, msg)) > 0
}
// ContainsType checks if the given error contains an error with
// the same concrete type as v. If err is not a wrapped error, this will
// check the err itself.
func ContainsType(err error, v interface{}) bool {
return len(GetAllType(err, v)) > 0
}
// Get is the same as GetAll but returns the deepest matching error.
func Get(err error, msg string) error {
es := GetAll(err, msg)
if len(es) > 0 {
return es[len(es)-1]
}
return nil
}
// GetType is the same as GetAllType but returns the deepest matching error.
func GetType(err error, v interface{}) error {
es := GetAllType(err, v)
if len(es) > 0 {
return es[len(es)-1]
}
return nil
}
// GetAll gets all the errors that might be wrapped in err with the
// given message. The order of the errors is such that the outermost
// matching error (the most recent wrap) is index zero, and so on.
func GetAll(err error, msg string) []error {
var result []error
Walk(err, func(err error) {
if err.Error() == msg {
result = append(result, err)
}
})
return result
}
// GetAllType gets all the errors that are the same type as v.
//
// The order of the return value is the same as described in GetAll.
func GetAllType(err error, v interface{}) []error {
var result []error
var search string
if v != nil {
search = reflect.TypeOf(v).String()
}
Walk(err, func(err error) {
var needle string
if err != nil {
needle = reflect.TypeOf(err).String()
}
if needle == search {
result = append(result, err)
}
})
return result
}
// Walk walks all the wrapped errors in err and calls the callback. If
// err isn't a wrapped error, this will be called once for err. If err
// is a wrapped error, the callback will be called for both the wrapper
// that implements error as well as the wrapped error itself.
func Walk(err error, cb WalkFunc) {
if err == nil {
return
}
switch e := err.(type) {
case *wrappedError:
cb(e.Outer)
Walk(e.Inner, cb)
case Wrapper:
cb(err)
for _, err := range e.WrappedErrors() {
Walk(err, cb)
}
default:
cb(err)
}
}
// wrappedError is an implementation of error that has both the
// outer and inner errors.
type wrappedError struct {
Outer error
Inner error
}
func (w *wrappedError) Error() string {
return w.Outer.Error()
}
func (w *wrappedError) WrappedErrors() []error {
return []error{w.Outer, w.Inner}
}
module github.com/hashicorp/errwrap
sudo: false
language: go
go:
- 1.x
branches:
only:
- master
script: make test testrace
TEST?=./...
default: test
# test runs the test suite and vets the code.
test: generate
@echo "==> Running tests..."
@go list $(TEST) \
| grep -v "/vendor/" \
| xargs -n1 go test -timeout=60s -parallel=10 ${TESTARGS}
# testrace runs the race checker
testrace: generate
@echo "==> Running tests (race)..."
@go list $(TEST) \
| grep -v "/vendor/" \
| xargs -n1 go test -timeout=60s -race ${TESTARGS}
# updatedeps installs all the dependencies needed to run and build.
updatedeps:
@sh -c "'${CURDIR}/scripts/deps.sh' '${NAME}'"
# generate runs `go generate` to build the dynamically generated source files.
generate:
@echo "==> Generating..."
@find . -type f -name '.DS_Store' -delete
@go list ./... \
| grep -v "/vendor/" \
| xargs -n1 go generate
.PHONY: default test testrace updatedeps generate
# go-multierror
[![Build Status](http://img.shields.io/travis/hashicorp/go-multierror.svg?style=flat-square)][travis]
[![Go Documentation](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)][godocs]
[travis]: https://travis-ci.org/hashicorp/go-multierror
[godocs]: https://godoc.org/github.com/hashicorp/go-multierror
`go-multierror` is a package for Go that provides a mechanism for
representing a list of `error` values as a single `error`.
This allows a function in Go to return an `error` that might actually
be a list of errors. If the caller knows this, they can unwrap the
list and access the errors. If the caller doesn't know, the error
formats to a nice human-readable format.
`go-multierror` implements the
[errwrap](https://github.com/hashicorp/errwrap) interface so that it can
be used with that library, as well.
## Installation and Docs
Install using `go get github.com/hashicorp/go-multierror`.
Full documentation is available at
http://godoc.org/github.com/hashicorp/go-multierror
## Usage
go-multierror is easy to use and purposely built to be unobtrusive in
existing Go applications/libraries that may not be aware of it.
**Building a list of errors**
The `Append` function is used to create a list of errors. This function
behaves a lot like the Go built-in `append` function: it doesn't matter
if the first argument is nil, a `multierror.Error`, or any other `error`,
the function behaves as you would expect.
```go
var result error
if err := step1(); err != nil {
result = multierror.Append(result, err)
}
if err := step2(); err != nil {
result = multierror.Append(result, err)
}
return result
```
**Customizing the formatting of the errors**
By specifying a custom `ErrorFormat`, you can customize the format
of the `Error() string` function:
```go
var result *multierror.Error
// ... accumulate errors here, maybe using Append
if result != nil {
result.ErrorFormat = func([]error) string {
return "errors!"
}
}
```
**Accessing the list of errors**
`multierror.Error` implements `error` so if the caller doesn't know about
multierror, it will work just fine. But if you're aware a multierror might
be returned, you can use type switches to access the list of errors:
```go
if err := something(); err != nil {
if merr, ok := err.(*multierror.Error); ok {
// Use merr.Errors
}
}
```
**Returning a multierror only if there are errors**
If you build a `multierror.Error`, you can use the `ErrorOrNil` function
to return an `error` implementation only if there are errors to return:
```go
var result *multierror.Error
// ... accumulate errors here
// Return the `error` only if errors were added to the multierror, otherwise
// return nil since there are no errors.
return result.ErrorOrNil()
```
package multierror
// Append is a helper function that will append more errors
// onto an Error in order to create a larger multi-error.
//
// If err is not a multierror.Error, then it will be turned into
// one. If any of the errs are multierr.Error, they will be flattened
// one level into err.
func Append(err error, errs ...error) *Error {
switch err := err.(type) {
case *Error:
// Typed nils can reach here, so initialize if we are nil
if err == nil {
err = new(Error)
}
// Go through each error and flatten
for _, e := range errs {
switch e := e.(type) {
case *Error:
if e != nil {
err.Errors = append(err.Errors, e.Errors...)
}
default:
if e != nil {
err.Errors = append(err.Errors, e)
}
}
}
return err
default:
newErrs := make([]error, 0, len(errs)+1)
if err != nil {
newErrs = append(newErrs, err)
}
newErrs = append(newErrs, errs...)
return Append(&Error{}, newErrs...)
}
}
package multierror
// Flatten flattens the given error, merging any *Errors together into
// a single *Error.
func Flatten(err error) error {
// If it isn't an *Error, just return the error as-is
if _, ok := err.(*Error); !ok {
return err
}
// Otherwise, make the result and flatten away!
flatErr := new(Error)
flatten(err, flatErr)
return flatErr
}
func flatten(err error, flatErr *Error) {
switch err := err.(type) {
case *Error:
for _, e := range err.Errors {
flatten(e, flatErr)
}
default:
flatErr.Errors = append(flatErr.Errors, err)
}
}
package multierror
import (
"fmt"
"strings"
)
// ErrorFormatFunc is a function callback that is called by Error to
// turn the list of errors into a string.
type ErrorFormatFunc func([]error) string
// ListFormatFunc is a basic formatter that outputs the number of errors
// that occurred along with a bullet point list of the errors.
func ListFormatFunc(es []error) string {
if len(es) == 1 {
return fmt.Sprintf("1 error occurred:\n\t* %s\n\n", es[0])
}
points := make([]string, len(es))
for i, err := range es {
points[i] = fmt.Sprintf("* %s", err)
}
return fmt.Sprintf(
"%d errors occurred:\n\t%s\n\n",
len(es), strings.Join(points, "\n\t"))
}
module github.com/hashicorp/go-multierror
require github.com/hashicorp/errwrap v1.0.0
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce h1:prjrVgOk2Yg6w+PflHoszQNLTUh4kaByUcEWM/9uin4=
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
package multierror
import (
"fmt"
)
// Error is an error type to track multiple errors. This is used to
// accumulate errors in cases and return them as a single "error".
type Error struct {
Errors []error
ErrorFormat ErrorFormatFunc
}
func (e *Error) Error() string {
fn := e.ErrorFormat
if fn == nil {
fn = ListFormatFunc
}
return fn(e.Errors)
}
// ErrorOrNil returns an error interface if this Error represents
// a list of errors, or returns nil if the list of errors is empty. This
// function is useful at the end of accumulation to make sure that the value
// returned represents the existence of errors.
func (e *Error) ErrorOrNil() error {
if e == nil {
return nil
}
if len(e.Errors) == 0 {
return nil
}
return e
}
func (e *Error) GoString() string {
return fmt.Sprintf("*%#v", *e)
}
// WrappedErrors returns the list of errors that this Error is wrapping.
// It is an implementation of the errwrap.Wrapper interface so that
// multierror.Error can be used with that library.
//
// This method is not safe to be called concurrently and is no different
// than accessing the Errors field directly. It is implemented only to
// satisfy the errwrap.Wrapper interface.
func (e *Error) WrappedErrors() []error {
return e.Errors
}
package multierror
import (
"fmt"
"github.com/hashicorp/errwrap"
)
// Prefix is a helper function that will prefix some text
// to the given error. If the error is a multierror.Error, then
// it will be prefixed to each wrapped error.
//
// This is useful to use when appending multiple multierrors
// together in order to give better scoping.
func Prefix(err error, prefix string) error {
if err == nil {
return nil
}
format := fmt.Sprintf("%s {{err}}", prefix)
switch err := err.(type) {
case *Error:
// Typed nils can reach here, so initialize if we are nil
if err == nil {
err = new(Error)
}
// Wrap each of the errors
for i, e := range err.Errors {
err.Errors[i] = errwrap.Wrapf(format, e)
}
return err
default:
return errwrap.Wrapf(format, err)
}
}
package multierror
// Len implements sort.Interface function for length
func (err Error) Len() int {
return len(err.Errors)
}
// Swap implements sort.Interface function for swapping elements
func (err Error) Swap(i, j int) {
err.Errors[i], err.Errors[j] = err.Errors[j], err.Errors[i]
}
// Less implements sort.Interface function for determining order
func (err Error) Less(i, j int) bool {
return err.Errors[i].Error() < err.Errors[j].Error()
}
...@@ -157,7 +157,7 @@ github.com/container-storage-interface/spec/lib/go/csi ...@@ -157,7 +157,7 @@ github.com/container-storage-interface/spec/lib/go/csi
github.com/containerd/cgroups github.com/containerd/cgroups
# github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50 # github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 => github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50
github.com/containerd/console github.com/containerd/console
# github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69 => github.com/rancher/containerd v1.3.3-k3s2 # github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69 => github.com/k3s-io/containerd v1.3.9-k3s1
github.com/containerd/containerd github.com/containerd/containerd
github.com/containerd/containerd/api/events github.com/containerd/containerd/api/events
github.com/containerd/containerd/api/services/containers/v1 github.com/containerd/containerd/api/services/containers/v1
...@@ -294,7 +294,7 @@ github.com/containerd/continuity/pathdriver ...@@ -294,7 +294,7 @@ github.com/containerd/continuity/pathdriver
github.com/containerd/continuity/proto github.com/containerd/continuity/proto
github.com/containerd/continuity/syscallx github.com/containerd/continuity/syscallx
github.com/containerd/continuity/sysx github.com/containerd/continuity/sysx
# github.com/containerd/cri v0.0.0-00010101000000-000000000000 => github.com/rancher/cri v1.3.0-k3s.5 # github.com/containerd/cri v0.0.0-00010101000000-000000000000 => github.com/k3s-io/cri v1.3.0-k3s.9
github.com/containerd/cri github.com/containerd/cri
github.com/containerd/cri/pkg/annotations github.com/containerd/cri/pkg/annotations
github.com/containerd/cri/pkg/api/runtimeoptions/v1 github.com/containerd/cri/pkg/api/runtimeoptions/v1
...@@ -307,6 +307,7 @@ github.com/containerd/cri/pkg/ioutil ...@@ -307,6 +307,7 @@ github.com/containerd/cri/pkg/ioutil
github.com/containerd/cri/pkg/netns github.com/containerd/cri/pkg/netns
github.com/containerd/cri/pkg/os github.com/containerd/cri/pkg/os
github.com/containerd/cri/pkg/registrar github.com/containerd/cri/pkg/registrar
github.com/containerd/cri/pkg/seccomp
github.com/containerd/cri/pkg/server github.com/containerd/cri/pkg/server
github.com/containerd/cri/pkg/server/io github.com/containerd/cri/pkg/server/io
github.com/containerd/cri/pkg/store github.com/containerd/cri/pkg/store
...@@ -581,6 +582,10 @@ github.com/gregjones/httpcache ...@@ -581,6 +582,10 @@ github.com/gregjones/httpcache
github.com/gregjones/httpcache/diskcache github.com/gregjones/httpcache/diskcache
# github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 # github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/grpc-ecosystem/go-grpc-prometheus github.com/grpc-ecosystem/go-grpc-prometheus
# github.com/hashicorp/errwrap v1.0.0
github.com/hashicorp/errwrap
# github.com/hashicorp/go-multierror v1.0.0
github.com/hashicorp/go-multierror
# github.com/hashicorp/golang-lru v0.5.3 # github.com/hashicorp/golang-lru v0.5.3
github.com/hashicorp/golang-lru github.com/hashicorp/golang-lru
github.com/hashicorp/golang-lru/simplelru github.com/hashicorp/golang-lru/simplelru
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment