mirror of https://github.com/k3s-io/k3s
Merge pull request #2065 from dweomer/containerd/v1.3.6-selinux
updated containerd/cri selinux supportpull/2103/head
commit
97ff5affab
13
go.mod
13
go.mod
|
@ -8,11 +8,10 @@ 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/rancher/containerd v1.3.6-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.6
|
github.com/containerd/cri => github.com/rancher/cri v1.3.0-k3s.7
|
||||||
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/typeurl => github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd
|
github.com/containerd/typeurl => github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd
|
||||||
github.com/coreos/flannel => github.com/rancher/flannel v0.12.0-k3s1
|
github.com/coreos/flannel => github.com/rancher/flannel v0.12.0-k3s1
|
||||||
github.com/coreos/go-systemd => github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e
|
github.com/coreos/go-systemd => github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e
|
||||||
|
@ -67,12 +66,12 @@ require (
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||||
github.com/bronze1man/goStrongswanVici v0.0.0-20190828090544-27d02f80ba40 // indirect
|
github.com/bronze1man/goStrongswanVici v0.0.0-20190828090544-27d02f80ba40 // indirect
|
||||||
github.com/containerd/cgroups v0.0.0-00010101000000-000000000000 // indirect
|
github.com/containerd/cgroups v0.0.0-00010101000000-000000000000 // indirect
|
||||||
github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69
|
github.com/containerd/containerd v1.3.6
|
||||||
github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6 // indirect
|
github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6 // indirect
|
||||||
github.com/containerd/cri v0.0.0-00010101000000-000000000000
|
github.com/containerd/cri v0.0.0-00010101000000-000000000000
|
||||||
github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c // indirect
|
github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c // indirect
|
||||||
github.com/containerd/go-cni v0.0.0-20190904155053-d20b7eebc7ee // indirect
|
github.com/containerd/go-cni v0.0.0-20190813230227-49fbd9b210f3 // indirect
|
||||||
github.com/containerd/go-runc v0.0.0-20190923131748-a2952bc25f51 // indirect
|
github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda // indirect
|
||||||
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8 // indirect
|
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8 // indirect
|
||||||
github.com/containernetworking/plugins v0.8.2 // indirect
|
github.com/containernetworking/plugins v0.8.2 // indirect
|
||||||
github.com/coreos/flannel v0.11.0
|
github.com/coreos/flannel v0.11.0
|
||||||
|
@ -93,7 +92,7 @@ require (
|
||||||
github.com/mattn/go-sqlite3 v1.13.0
|
github.com/mattn/go-sqlite3 v1.13.0
|
||||||
github.com/natefinch/lumberjack v2.0.0+incompatible
|
github.com/natefinch/lumberjack v2.0.0+incompatible
|
||||||
github.com/opencontainers/runc v1.0.0-rc10
|
github.com/opencontainers/runc v1.0.0-rc10
|
||||||
github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52
|
github.com/opencontainers/selinux v1.5.3-0.20200613095409-bb88c45a3863
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/rancher/dynamiclistener v0.2.1-0.20200418023342-52ede5ec9234
|
github.com/rancher/dynamiclistener v0.2.1-0.20200418023342-52ede5ec9234
|
||||||
github.com/rancher/helm-controller v0.6.3
|
github.com/rancher/helm-controller v0.6.3
|
||||||
|
|
21
go.sum
21
go.sum
|
@ -117,8 +117,9 @@ github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02 h1:tN9D97v5A
|
||||||
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||||
github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c h1:KFbqHhDeaHM7IfFtXHfUHMDaUStpM2YwBR+iJCIOsKk=
|
github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c h1:KFbqHhDeaHM7IfFtXHfUHMDaUStpM2YwBR+iJCIOsKk=
|
||||||
github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||||
github.com/containerd/go-cni v0.0.0-20190904155053-d20b7eebc7ee h1:fV37ZKnYs79fSyI3mu/XZFJVezrVsXBLbfojcTPpdXM=
|
github.com/containerd/go-cni v0.0.0-20190813230227-49fbd9b210f3 h1:owkX+hC6Inv1XUep/pAjF7qJpnZWjbtETw5r1DVYFPo=
|
||||||
github.com/containerd/go-cni v0.0.0-20190904155053-d20b7eebc7ee/go.mod h1:2wlRxCQdiBY+OcjNg5x8kI+5mEL1fGt25L4IzQHYJsM=
|
github.com/containerd/go-cni v0.0.0-20190813230227-49fbd9b210f3/go.mod h1:2wlRxCQdiBY+OcjNg5x8kI+5mEL1fGt25L4IzQHYJsM=
|
||||||
|
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
||||||
github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda h1:3LYDkJtHAZGbWD75PoTBJuxldc+njsz9uSfjwIoOR6c=
|
github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda h1:3LYDkJtHAZGbWD75PoTBJuxldc+njsz9uSfjwIoOR6c=
|
||||||
github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
||||||
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||||
|
@ -409,7 +410,9 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
|
github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
|
||||||
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/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 v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874 h1:cAv7ZbSmyb1wjn6T4TIiyFCkpcfgpbcNNC3bM2srLaI=
|
||||||
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-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||||
github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
@ -447,7 +450,6 @@ github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46O
|
||||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 h1:UUHMLvzt/31azWTN/ifGWef4WUqvXk0iRqdhdy/2uzI=
|
|
||||||
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-20190613124551-e81189438503/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
|
github.com/juju/testing v0.0.0-20190613124551-e81189438503/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
|
||||||
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||||
|
@ -592,6 +594,8 @@ github.com/opencontainers/runtime-spec v0.0.0-20180911193056-5684b8af48c1/go.mod
|
||||||
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
||||||
github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52 h1:B8hYj3NxHmjsC3T+tnlZ1UhInqUgnyF1zlGPmzNg2Qk=
|
github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52 h1:B8hYj3NxHmjsC3T+tnlZ1UhInqUgnyF1zlGPmzNg2Qk=
|
||||||
github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
|
github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
|
||||||
|
github.com/opencontainers/selinux v1.5.3-0.20200613095409-bb88c45a3863 h1:pAUx/lkmegJdgEH27YJImvNLOs/ydx/NbKJ2vIJ2PHY=
|
||||||
|
github.com/opencontainers/selinux v1.5.3-0.20200613095409-bb88c45a3863/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
|
||||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
|
@ -620,10 +624,10 @@ 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-20190930180311-e5c5ffe4bdf0 h1:iXE9kmlAqhusXxzkXictdNgWS7p4ZBnmv9SdyMgTf6E=
|
github.com/rakelkar/gonetsh v0.0.0-20190930180311-e5c5ffe4bdf0 h1:iXE9kmlAqhusXxzkXictdNgWS7p4ZBnmv9SdyMgTf6E=
|
||||||
github.com/rakelkar/gonetsh v0.0.0-20190930180311-e5c5ffe4bdf0/go.mod h1:4XHkfaUj+URzGO9sohoAgt2V9Y8nIW7fugpu0E6gShk=
|
github.com/rakelkar/gonetsh v0.0.0-20190930180311-e5c5ffe4bdf0/go.mod h1:4XHkfaUj+URzGO9sohoAgt2V9Y8nIW7fugpu0E6gShk=
|
||||||
github.com/rancher/containerd v1.3.3-k3s2 h1:RZr+TqFt7+YsrSYkyytlhW4HmneWeFNM7IymNOoGW6A=
|
github.com/rancher/containerd v1.3.6-k3s1 h1:wSGjKMQM3TRCsgWAd+lA9zy/JM4/A9MuUxZFGIxt0+0=
|
||||||
github.com/rancher/containerd v1.3.3-k3s2/go.mod h1:ZMfzmqce2Z+QSEqdHMfeJs1TZ/UeJ1aDrazjpQT4ehM=
|
github.com/rancher/containerd v1.3.6-k3s1/go.mod h1:ZMfzmqce2Z+QSEqdHMfeJs1TZ/UeJ1aDrazjpQT4ehM=
|
||||||
github.com/rancher/cri v1.3.0-k3s.6 h1:jeom53pNYUJHlZBHpax8vpQeBoW19vSVGAQn9jPyIcc=
|
github.com/rancher/cri v1.3.0-k3s.7 h1:5V/AVFLCpYIsJMavJKjKpwrQU92e87dhWSX43N4q8Gg=
|
||||||
github.com/rancher/cri v1.3.0-k3s.6/go.mod h1:Ht5T1dIKzm+4NExmb7wDVG6qR+j0xeXIjjhCv1d9geY=
|
github.com/rancher/cri v1.3.0-k3s.7/go.mod h1:Ht5T1dIKzm+4NExmb7wDVG6qR+j0xeXIjjhCv1d9geY=
|
||||||
github.com/rancher/cri-tools v1.18.0-k3s1 h1:pLYthxpSu6k3Up9tNAMA0MK2ERqB6FC1sZQPRSW1qSg=
|
github.com/rancher/cri-tools v1.18.0-k3s1 h1:pLYthxpSu6k3Up9tNAMA0MK2ERqB6FC1sZQPRSW1qSg=
|
||||||
github.com/rancher/cri-tools v1.18.0-k3s1/go.mod h1:Ij/GWNRcEDP6zVN6eQpvN/s0nhuJVtPQFy7RAdl+Wu8=
|
github.com/rancher/cri-tools v1.18.0-k3s1/go.mod h1:Ij/GWNRcEDP6zVN6eQpvN/s0nhuJVtPQFy7RAdl+Wu8=
|
||||||
github.com/rancher/dynamiclistener v0.2.1-0.20200418023342-52ede5ec9234 h1:wZ1Zh7fI7B9hfZw9Ouhz7171CZKu6XffM3ysUhhO6i0=
|
github.com/rancher/dynamiclistener v0.2.1-0.20200418023342-52ede5ec9234 h1:wZ1Zh7fI7B9hfZw9Ouhz7171CZKu6XffM3ysUhhO6i0=
|
||||||
|
@ -682,7 +686,6 @@ github.com/rancher/kubernetes/staging/src/k8s.io/metrics v1.18.6-k3s1 h1:eUs9gsR
|
||||||
github.com/rancher/kubernetes/staging/src/k8s.io/metrics v1.18.6-k3s1/go.mod h1:xZM9EdJpWjqIWPvLiCP7vYKUEMwIgc0S8nc/MlLVK3Y=
|
github.com/rancher/kubernetes/staging/src/k8s.io/metrics v1.18.6-k3s1/go.mod h1:xZM9EdJpWjqIWPvLiCP7vYKUEMwIgc0S8nc/MlLVK3Y=
|
||||||
github.com/rancher/kubernetes/staging/src/k8s.io/sample-apiserver v1.18.6-k3s1/go.mod h1:p8OmVbdzpawdZ/r9E1qcdJpzRirEg4OcSg8aZVWqvJo=
|
github.com/rancher/kubernetes/staging/src/k8s.io/sample-apiserver v1.18.6-k3s1/go.mod h1:p8OmVbdzpawdZ/r9E1qcdJpzRirEg4OcSg8aZVWqvJo=
|
||||||
github.com/rancher/moq v0.0.0-20190404221404-ee5226d43009/go.mod h1:wpITyDPTi/Na5h73XkbuEf2AP9fbgrIGqqxVzFhYD6U=
|
github.com/rancher/moq v0.0.0-20190404221404-ee5226d43009/go.mod h1:wpITyDPTi/Na5h73XkbuEf2AP9fbgrIGqqxVzFhYD6U=
|
||||||
github.com/rancher/nocode v0.0.0-20200630202308-cb097102c09f h1:mX6kuT3Ah9v1iEO3rgCQ7ZH9heVh67r3a9l94ua8P7U=
|
|
||||||
github.com/rancher/nocode v0.0.0-20200630202308-cb097102c09f/go.mod h1:iAAt6Amgbysi6srDJs9SxGSbG2j/JSRb/xCrnEtA69g=
|
github.com/rancher/nocode v0.0.0-20200630202308-cb097102c09f/go.mod h1:iAAt6Amgbysi6srDJs9SxGSbG2j/JSRb/xCrnEtA69g=
|
||||||
github.com/rancher/remotedialer v0.2.0 h1:xD7t3K6JYwTdAsxmGtTHQMkEkFgKouQ1foLxVW424Dc=
|
github.com/rancher/remotedialer v0.2.0 h1:xD7t3K6JYwTdAsxmGtTHQMkEkFgKouQ1foLxVW424Dc=
|
||||||
github.com/rancher/remotedialer v0.2.0/go.mod h1:tkU8ZvrR5lRgaKWaX71nAy6daeqvPFx/lJEnbW7tXSI=
|
github.com/rancher/remotedialer v0.2.0/go.mod h1:tkU8ZvrR5lRgaKWaX71nAy6daeqvPFx/lJEnbW7tXSI=
|
||||||
|
@ -807,6 +810,7 @@ github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5
|
||||||
github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM=
|
github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM=
|
||||||
github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||||
github.com/vishvananda/netns v0.0.0-20170219233438-54f0e4339ce7/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
github.com/vishvananda/netns v0.0.0-20170219233438-54f0e4339ce7/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||||
|
github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936 h1:J9gO8RJCAFlln1jsvRba/CWVUnMHwObklfxxjErl1uk=
|
||||||
github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc h1:R83G5ikgLMxrBvLh22JhdfI8K6YXEPHx5P03Uu3DRs4=
|
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc h1:R83G5ikgLMxrBvLh22JhdfI8K6YXEPHx5P03Uu3DRs4=
|
||||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||||
|
@ -940,6 +944,7 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e h1:9vRrk9YW2BTzLP0VCB9ZDjU4cPqkg+IDWL7XgxA1yxQ=
|
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e h1:9vRrk9YW2BTzLP0VCB9ZDjU4cPqkg+IDWL7XgxA1yxQ=
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
|
|
@ -69,6 +69,14 @@ func Run(ctx context.Context, cfg *config.Node) error {
|
||||||
cmd := exec.Command(args[0], args[1:]...)
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
cmd.Stdout = stdOut
|
cmd.Stdout = stdOut
|
||||||
cmd.Stderr = stdErr
|
cmd.Stderr = stdErr
|
||||||
|
cmd.Env = os.Environ()
|
||||||
|
// elide NOTIFY_SOCKET to prevent spurious notifications to systemd
|
||||||
|
for i := range cmd.Env {
|
||||||
|
if strings.HasPrefix(cmd.Env[i], "NOTIFY_SOCKET=") {
|
||||||
|
cmd.Env = append(cmd.Env[:i], cmd.Env[i+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
addDeathSig(cmd)
|
addDeathSig(cmd)
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "containerd: %s\n", err)
|
fmt.Fprintf(os.Stderr, "containerd: %s\n", err)
|
||||||
|
|
|
@ -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:
|
||||||
- errcheck
|
- errcheck
|
||||||
|
|
||||||
run:
|
run:
|
||||||
deadline: 2m
|
deadline: 3m
|
||||||
skip-dirs:
|
skip-dirs:
|
||||||
- api
|
- api
|
||||||
- design
|
- design
|
||||||
|
|
|
@ -1,38 +1,76 @@
|
||||||
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>
|
||||||
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 +80,11 @@ 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>
|
Zhongming Chang<zhongming.chang@daocloud.io>
|
||||||
zhoulin xie <zhoulin.xie@daocloud.io> <42261994+JoeWrightss@users.noreply.github.com>
|
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
|
||||||
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.12"
|
||||||
|
|
||||||
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:
|
||||||
- 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:
|
||||||
- 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`:
|
||||||
|
|
||||||
```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
|
||||||
|
|
||||||
# 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:
|
||||||
@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) $@"
|
||||||
|
|
|
@ -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
|
||||||
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
|
||||||
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
|
||||||
|
|
62
vendor/github.com/containerd/containerd/cmd/containerd/command/notify_linux.go
generated
vendored
Normal file
62
vendor/github.com/containerd/containerd/cmd/containerd/command/notify_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
// +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
|
||||||
|
}
|
31
vendor/github.com/containerd/containerd/cmd/containerd/command/notify_unsupported.go
generated
vendored
Normal file
31
vendor/github.com/containerd/containerd/cmd/containerd/command/notify_unsupported.go
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// +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
|
||||||
|
}
|
3
vendor/github.com/containerd/containerd/cmd/containerd/command/service_windows.go
generated
vendored
3
vendor/github.com/containerd/containerd/cmd/containerd/command/service_windows.go
generated
vendored
|
@ -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 {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
service = h
|
|
||||||
go func() {
|
go func() {
|
||||||
if interactive {
|
if interactive {
|
||||||
err = debug.Run(serviceNameFlag, h)
|
err = debug.Run(serviceNameFlag, h)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
comment: false
|
|
@ -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,
|
||||||
|
|
||||||
// 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 {
|
|
||||||
return os.RemoveAll(path)
|
|
||||||
}
|
}
|
||||||
|
closer := func() error {
|
||||||
|
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 {
|
||||||
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 ""
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ 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
|
||||||
|
|
|
@ -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) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
|
|
@ -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
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
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 {
|
||||||
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)
|
||||||
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
|
||||||
|
defer func() {
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result := multierror.Append(err)
|
||||||
|
for _, fn := range closers {
|
||||||
|
result = multierror.Append(result, fn())
|
||||||
|
}
|
||||||
|
err = multierror.Flatten(result)
|
||||||
|
}()
|
||||||
|
|
||||||
|
out, err := newPipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to create stdout pipes")
|
||||||
|
}
|
||||||
|
closers = append(closers, out.Close)
|
||||||
|
|
||||||
|
serr, err := newPipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to create stderr pipes")
|
||||||
|
}
|
||||||
|
closers = append(closers, serr.Close)
|
||||||
|
|
||||||
|
r, w, err := os.Pipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
closers = append(closers, r.Close, w.Close)
|
||||||
|
|
||||||
|
cmd := exec.Command(uri.Path, args...)
|
||||||
cmd.Env = append(cmd.Env,
|
cmd.Env = append(cmd.Env,
|
||||||
"CONTAINER_ID="+id,
|
"CONTAINER_ID="+id,
|
||||||
"CONTAINER_NAMESPACE="+ns,
|
"CONTAINER_NAMESPACE="+ns,
|
||||||
)
|
)
|
||||||
out, err := newPipe()
|
|
||||||
if err != nil {
|
|
||||||
cancel()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
serr, err := newPipe()
|
|
||||||
if err != nil {
|
|
||||||
cancel()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
r, w, err := os.Pipe()
|
|
||||||
if err != nil {
|
|
||||||
cancel()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
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)
|
||||||
|
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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:")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
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
|
||||||
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.
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,21 +323,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
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
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"))
|
||||||
|
|
|
@ -256,7 +256,16 @@ func (s *service) Cleanup(ctx context.Context) (*taskAPI.DeleteResponse, error)
|
||||||
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 {
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
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 (
|
||||||
"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
|
||||||
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
|
||||||
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.RawSyscall(syscall.SYS_READ,
|
||||||
|
uintptr(pipefds[0]),
|
||||||
|
uintptr(unsafe.Pointer(&status)),
|
||||||
|
unsafe.Sizeof(status))
|
||||||
|
if errno != 0 {
|
||||||
|
return errors.Wrap(errno, "failed to read pipe")
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = syscall.Errno(ws.ExitStatus())
|
if status != 0 {
|
||||||
if errno != 0 {
|
return errors.Wrap(status, "failed to mount")
|
||||||
return errors.Wrap(errno, "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)
|
||||||
_, _, 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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,91 +1,93 @@
|
||||||
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/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/urfave/cli v1.22.0
|
|
||||||
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
|
|
||||||
github.com/BurntSushi/toml v0.3.1
|
|
||||||
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
|
|
||||||
github.com/containerd/ttrpc 92c8520ef9f86600c650dd540266a007bf03670f
|
|
||||||
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
|
|
||||||
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
|
github.com/russross/blackfriday 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
|
||||||
|
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
||||||
|
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||||
|
google.golang.org/grpc v1.23.0
|
||||||
|
gotest.tools v2.3.0
|
||||||
|
|
||||||
# cri dependencies
|
# cri dependencies
|
||||||
github.com/containerd/cri b1bef15fbeb6c6f0569b67322acfa74ca3597755 # release/1.3
|
github.com/containerd/cri f864905c93b97db15503c217dc9a43eb65670b53 # release/1.3 branch
|
||||||
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 5215b1806f52b1fcc2070a8826c542c9d33cd3cf
|
||||||
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 (
|
||||||
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.6+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.
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# 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 @@
|
||||||
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
|
||||||
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:
|
||||||
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
|
||||||
@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
|
||||||
@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
|
||||||
|
|
||||||
install.deps: ## install dependencies of cri (default 'seccomp apparmor' BUILDTAGS for runc build)
|
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.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
|
||||||
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) {
|
||||||
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) {
|
||||||
}
|
}
|
||||||
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 {
|
||||||
|
|
||||||
// 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"`
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
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
|
||||||
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
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if retErr != nil {
|
if retErr != nil {
|
||||||
_ = label.ReleaseLabel(processLabel)
|
selinux.ReleaseLabel(processLabel)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
@ -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 (
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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
|
||||||
}
|
}
|
||||||
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
|
||||||
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 *
|
||||||
return &newImage, nil
|
return &newImage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toLabel(selinuxOptions *runtime.SELinuxOption) (labels []string) {
|
func toLabel(selinuxOptions *runtime.SELinuxOption) ([]string, error) {
|
||||||
if selinuxOptions == nil {
|
var labels []string
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if selinuxOptions == 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) {
|
||||||
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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
// 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 != "" {
|
|
||||||
cert, err = tls.LoadX509KeyPair(registryTLSConfig.CertFile, registryTLSConfig.KeyFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to load cert file")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if registryTLSConfig.CertFile != "" && registryTLSConfig.KeyFile == "" {
|
if registryTLSConfig.CertFile != "" && registryTLSConfig.KeyFile == "" {
|
||||||
return nil, errors.Errorf("cert file %q was specified, but no corresponding key file was specified", registryTLSConfig.CertFile)
|
return nil, errors.Errorf("cert file %q was specified, but no corresponding key file was specified", registryTLSConfig.CertFile)
|
||||||
}
|
}
|
||||||
if registryTLSConfig.CertFile == "" && registryTLSConfig.KeyFile != "" {
|
if registryTLSConfig.CertFile == "" && registryTLSConfig.KeyFile != "" {
|
||||||
return nil, errors.Errorf("key file %q was specified, but no corresponding cert file was specified", 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 != "" {
|
||||||
|
cert, err = tls.LoadX509KeyPair(registryTLSConfig.CertFile, registryTLSConfig.KeyFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to load cert file")
|
||||||
|
}
|
||||||
|
if len(cert.Certificate) != 0 {
|
||||||
|
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||||
|
}
|
||||||
|
tlsConfig.BuildNameToCertificate()
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
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{
|
tlsConfig.InsecureSkipVerify = registryTLSConfig.InsecureSkipVerify
|
||||||
RootCAs: caCertPool,
|
|
||||||
}
|
|
||||||
if len(cert.Certificate) != 0 {
|
|
||||||
tlsConfig.Certificates = []tls.Certificate{cert}
|
|
||||||
}
|
|
||||||
tlsConfig.BuildNameToCertificate()
|
|
||||||
return tlsConfig, nil
|
return tlsConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 (
|
||||||
"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
|
||||||
// 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 (
|
||||||
"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
|
||||||
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
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if retErr != nil && processLabel != "" {
|
if retErr != nil && processLabel != "" {
|
||||||
_ = label.ReleaseLabel(processLabel)
|
selinux.ReleaseLabel(processLabel)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
/*
|
/*
|
||||||
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
|
||||||
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
|
||||||
}
|
}
|
||||||
// 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
|
||||||
// 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.
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,75 +1,80 @@
|
||||||
# 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/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
|
||||||
|
|
|
@ -42,14 +42,6 @@ func WithCapabilityBandWidth(bandWidth BandWidth) NamespaceOpts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithCapabilityDNS adds support for dns
|
|
||||||
func WithCapabilityDNS(dns DNS) NamespaceOpts {
|
|
||||||
return func(c *Namespace) error {
|
|
||||||
c.capabilityArgs["dns"] = dns
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithCapability(name string, capability interface{}) NamespaceOpts {
|
func WithCapability(name string, capability interface{}) NamespaceOpts {
|
||||||
return func(c *Namespace) error {
|
return func(c *Namespace) error {
|
||||||
c.capabilityArgs[name] = capability
|
c.capabilityArgs[name] = capability
|
||||||
|
|
|
@ -142,24 +142,6 @@ func WithConfFile(fileName string) CNIOpt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithConfListBytes can be used to load network config list directly
|
|
||||||
// from byte
|
|
||||||
func WithConfListBytes(bytes []byte) CNIOpt {
|
|
||||||
return func(c *libcni) error {
|
|
||||||
confList, err := cnilibrary.ConfListFromBytes(bytes)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
i := len(c.networks)
|
|
||||||
c.networks = append(c.networks, &Network{
|
|
||||||
cni: c.cniConfig,
|
|
||||||
config: confList,
|
|
||||||
ifName: getIfName(c.prefix, i),
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithConfListFile can be used to load network config
|
// WithConfListFile can be used to load network config
|
||||||
// from an .conflist file. Supported with absolute fileName
|
// from an .conflist file. Supported with absolute fileName
|
||||||
// with path only.
|
// with path only.
|
||||||
|
|
|
@ -53,13 +53,3 @@ type BandWidth struct {
|
||||||
EgressRate uint64
|
EgressRate uint64
|
||||||
EgressBurst uint64
|
EgressBurst uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// DNS defines the dns config
|
|
||||||
type DNS struct {
|
|
||||||
// List of DNS servers of the cluster.
|
|
||||||
Servers []string
|
|
||||||
// List of DNS search domains of the cluster.
|
|
||||||
Searches []string
|
|
||||||
// List of DNS options.
|
|
||||||
Options []string
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,354 @@
|
||||||
|
Mozilla Public License, version 2.0
|
||||||
|
|
||||||
|
1. Definitions
|
||||||
|
|
||||||
|
1.1. “Contributor”
|
||||||
|
|
||||||
|
means each individual or legal entity that creates, contributes to the
|
||||||
|
creation of, or owns Covered Software.
|
||||||
|
|
||||||
|
1.2. “Contributor Version”
|
||||||
|
|
||||||
|
means the combination of the Contributions of others (if any) used by a
|
||||||
|
Contributor and that particular Contributor’s Contribution.
|
||||||
|
|
||||||
|
1.3. “Contribution”
|
||||||
|
|
||||||
|
means Covered Software of a particular Contributor.
|
||||||
|
|
||||||
|
1.4. “Covered Software”
|
||||||
|
|
||||||
|
means Source Code Form to which the initial Contributor has attached the
|
||||||
|
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||||
|
Modifications of such Source Code Form, in each case including portions
|
||||||
|
thereof.
|
||||||
|
|
||||||
|
1.5. “Incompatible With Secondary Licenses”
|
||||||
|
means
|
||||||
|
|
||||||
|
a. that the initial Contributor has attached the notice described in
|
||||||
|
Exhibit B to the Covered Software; or
|
||||||
|
|
||||||
|
b. that the Covered Software was made available under the terms of version
|
||||||
|
1.1 or earlier of the License, but not also under the terms of a
|
||||||
|
Secondary License.
|
||||||
|
|
||||||
|
1.6. “Executable Form”
|
||||||
|
|
||||||
|
means any form of the work other than Source Code Form.
|
||||||
|
|
||||||
|
1.7. “Larger Work”
|
||||||
|
|
||||||
|
means a work that combines Covered Software with other material, in a separate
|
||||||
|
file or files, that is not Covered Software.
|
||||||
|
|
||||||
|
1.8. “License”
|
||||||
|
|
||||||
|
means this document.
|
||||||
|
|
||||||
|
1.9. “Licensable”
|
||||||
|
|
||||||
|
means having the right to grant, to the maximum extent possible, whether at the
|
||||||
|
time of the initial grant or subsequently, any and all of the rights conveyed by
|
||||||
|
this License.
|
||||||
|
|
||||||
|
1.10. “Modifications”
|
||||||
|
|
||||||
|
means any of the following:
|
||||||
|
|
||||||
|
a. any file in Source Code Form that results from an addition to, deletion
|
||||||
|
from, or modification of the contents of Covered Software; or
|
||||||
|
|
||||||
|
b. any new file in Source Code Form that contains any Covered Software.
|
||||||
|
|
||||||
|
1.11. “Patent Claims” of a Contributor
|
||||||
|
|
||||||
|
means any patent claim(s), including without limitation, method, process,
|
||||||
|
and apparatus claims, in any patent Licensable by such Contributor that
|
||||||
|
would be infringed, but for the grant of the License, by the making,
|
||||||
|
using, selling, offering for sale, having made, import, or transfer of
|
||||||
|
either its Contributions or its Contributor Version.
|
||||||
|
|
||||||
|
1.12. “Secondary License”
|
||||||
|
|
||||||
|
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||||
|
General Public License, Version 2.1, the GNU Affero General Public
|
||||||
|
License, Version 3.0, or any later versions of those licenses.
|
||||||
|
|
||||||
|
1.13. “Source Code Form”
|
||||||
|
|
||||||
|
means the form of the work preferred for making modifications.
|
||||||
|
|
||||||
|
1.14. “You” (or “Your”)
|
||||||
|
|
||||||
|
means an individual or a legal entity exercising rights under this
|
||||||
|
License. For legal entities, “You” includes any entity that controls, is
|
||||||
|
controlled by, or is under common control with You. For purposes of this
|
||||||
|
definition, “control” means (a) the power, direct or indirect, to cause
|
||||||
|
the direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||||
|
outstanding shares or beneficial ownership of such entity.
|
||||||
|
|
||||||
|
|
||||||
|
2. License Grants and Conditions
|
||||||
|
|
||||||
|
2.1. Grants
|
||||||
|
|
||||||
|
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||||
|
non-exclusive license:
|
||||||
|
|
||||||
|
a. under intellectual property rights (other than patent or trademark)
|
||||||
|
Licensable by such Contributor to use, reproduce, make available,
|
||||||
|
modify, display, perform, distribute, and otherwise exploit its
|
||||||
|
Contributions, either on an unmodified basis, with Modifications, or as
|
||||||
|
part of a Larger Work; and
|
||||||
|
|
||||||
|
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||||
|
sale, have made, import, and otherwise transfer either its Contributions
|
||||||
|
or its Contributor Version.
|
||||||
|
|
||||||
|
2.2. Effective Date
|
||||||
|
|
||||||
|
The licenses granted in Section 2.1 with respect to any Contribution become
|
||||||
|
effective for each Contribution on the date the Contributor first distributes
|
||||||
|
such Contribution.
|
||||||
|
|
||||||
|
2.3. Limitations on Grant Scope
|
||||||
|
|
||||||
|
The licenses granted in this Section 2 are the only rights granted under this
|
||||||
|
License. No additional rights or licenses will be implied from the distribution
|
||||||
|
or licensing of Covered Software under this License. Notwithstanding Section
|
||||||
|
2.1(b) above, no patent license is granted by a Contributor:
|
||||||
|
|
||||||
|
a. for any code that a Contributor has removed from Covered Software; or
|
||||||
|
|
||||||
|
b. for infringements caused by: (i) Your and any other third party’s
|
||||||
|
modifications of Covered Software, or (ii) the combination of its
|
||||||
|
Contributions with other software (except as part of its Contributor
|
||||||
|
Version); or
|
||||||
|
|
||||||
|
c. under Patent Claims infringed by Covered Software in the absence of its
|
||||||
|
Contributions.
|
||||||
|
|
||||||
|
This License does not grant any rights in the trademarks, service marks, or
|
||||||
|
logos of any Contributor (except as may be necessary to comply with the
|
||||||
|
notice requirements in Section 3.4).
|
||||||
|
|
||||||
|
2.4. Subsequent Licenses
|
||||||
|
|
||||||
|
No Contributor makes additional grants as a result of Your choice to
|
||||||
|
distribute the Covered Software under a subsequent version of this License
|
||||||
|
(see Section 10.2) or under the terms of a Secondary License (if permitted
|
||||||
|
under the terms of Section 3.3).
|
||||||
|
|
||||||
|
2.5. Representation
|
||||||
|
|
||||||
|
Each Contributor represents that the Contributor believes its Contributions
|
||||||
|
are its original creation(s) or it has sufficient rights to grant the
|
||||||
|
rights to its Contributions conveyed by this License.
|
||||||
|
|
||||||
|
2.6. Fair Use
|
||||||
|
|
||||||
|
This License is not intended to limit any rights You have under applicable
|
||||||
|
copyright doctrines of fair use, fair dealing, or other equivalents.
|
||||||
|
|
||||||
|
2.7. Conditions
|
||||||
|
|
||||||
|
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||||
|
Section 2.1.
|
||||||
|
|
||||||
|
|
||||||
|
3. Responsibilities
|
||||||
|
|
||||||
|
3.1. Distribution of Source Form
|
||||||
|
|
||||||
|
All distribution of Covered Software in Source Code Form, including any
|
||||||
|
Modifications that You create or to which You contribute, must be under the
|
||||||
|
terms of this License. You must inform recipients that the Source Code Form
|
||||||
|
of the Covered Software is governed by the terms of this License, and how
|
||||||
|
they can obtain a copy of this License. You may not attempt to alter or
|
||||||
|
restrict the recipients’ rights in the Source Code Form.
|
||||||
|
|
||||||
|
3.2. Distribution of Executable Form
|
||||||
|
|
||||||
|
If You distribute Covered Software in Executable Form then:
|
||||||
|
|
||||||
|
a. such Covered Software must also be made available in Source Code Form,
|
||||||
|
as described in Section 3.1, and You must inform recipients of the
|
||||||
|
Executable Form how they can obtain a copy of such Source Code Form by
|
||||||
|
reasonable means in a timely manner, at a charge no more than the cost
|
||||||
|
of distribution to the recipient; and
|
||||||
|
|
||||||
|
b. You may distribute such Executable Form under the terms of this License,
|
||||||
|
or sublicense it under different terms, provided that the license for
|
||||||
|
the Executable Form does not attempt to limit or alter the recipients’
|
||||||
|
rights in the Source Code Form under this License.
|
||||||
|
|
||||||
|
3.3. Distribution of a Larger Work
|
||||||
|
|
||||||
|
You may create and distribute a Larger Work under terms of Your choice,
|
||||||
|
provided that You also comply with the requirements of this License for the
|
||||||
|
Covered Software. If the Larger Work is a combination of Covered Software
|
||||||
|
with a work governed by one or more Secondary Licenses, and the Covered
|
||||||
|
Software is not Incompatible With Secondary Licenses, this License permits
|
||||||
|
You to additionally distribute such Covered Software under the terms of
|
||||||
|
such Secondary License(s), so that the recipient of the Larger Work may, at
|
||||||
|
their option, further distribute the Covered Software under the terms of
|
||||||
|
either this License or such Secondary License(s).
|
||||||
|
|
||||||
|
3.4. Notices
|
||||||
|
|
||||||
|
You may not remove or alter the substance of any license notices (including
|
||||||
|
copyright notices, patent notices, disclaimers of warranty, or limitations
|
||||||
|
of liability) contained within the Source Code Form of the Covered
|
||||||
|
Software, except that You may alter any license notices to the extent
|
||||||
|
required to remedy known factual inaccuracies.
|
||||||
|
|
||||||
|
3.5. Application of Additional Terms
|
||||||
|
|
||||||
|
You may choose to offer, and to charge a fee for, warranty, support,
|
||||||
|
indemnity or liability obligations to one or more recipients of Covered
|
||||||
|
Software. However, You may do so only on Your own behalf, and not on behalf
|
||||||
|
of any Contributor. You must make it absolutely clear that any such
|
||||||
|
warranty, support, indemnity, or liability obligation is offered by You
|
||||||
|
alone, and You hereby agree to indemnify every Contributor for any
|
||||||
|
liability incurred by such Contributor as a result of warranty, support,
|
||||||
|
indemnity or liability terms You offer. You may include additional
|
||||||
|
disclaimers of warranty and limitations of liability specific to any
|
||||||
|
jurisdiction.
|
||||||
|
|
||||||
|
4. Inability to Comply Due to Statute or Regulation
|
||||||
|
|
||||||
|
If it is impossible for You to comply with any of the terms of this License
|
||||||
|
with respect to some or all of the Covered Software due to statute, judicial
|
||||||
|
order, or regulation then You must: (a) comply with the terms of this License
|
||||||
|
to the maximum extent possible; and (b) describe the limitations and the code
|
||||||
|
they affect. Such description must be placed in a text file included with all
|
||||||
|
distributions of the Covered Software under this License. Except to the
|
||||||
|
extent prohibited by statute or regulation, such description must be
|
||||||
|
sufficiently detailed for a recipient of ordinary skill to be able to
|
||||||
|
understand it.
|
||||||
|
|
||||||
|
5. Termination
|
||||||
|
|
||||||
|
5.1. The rights granted under this License will terminate automatically if You
|
||||||
|
fail to comply with any of its terms. However, if You become compliant,
|
||||||
|
then the rights granted under this License from a particular Contributor
|
||||||
|
are reinstated (a) provisionally, unless and until such Contributor
|
||||||
|
explicitly and finally terminates Your grants, and (b) on an ongoing basis,
|
||||||
|
if such Contributor fails to notify You of the non-compliance by some
|
||||||
|
reasonable means prior to 60 days after You have come back into compliance.
|
||||||
|
Moreover, Your grants from a particular Contributor are reinstated on an
|
||||||
|
ongoing basis if such Contributor notifies You of the non-compliance by
|
||||||
|
some reasonable means, this is the first time You have received notice of
|
||||||
|
non-compliance with this License from such Contributor, and You become
|
||||||
|
compliant prior to 30 days after Your receipt of the notice.
|
||||||
|
|
||||||
|
5.2. If You initiate litigation against any entity by asserting a patent
|
||||||
|
infringement claim (excluding declaratory judgment actions, counter-claims,
|
||||||
|
and cross-claims) alleging that a Contributor Version directly or
|
||||||
|
indirectly infringes any patent, then the rights granted to You by any and
|
||||||
|
all Contributors for the Covered Software under Section 2.1 of this License
|
||||||
|
shall terminate.
|
||||||
|
|
||||||
|
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||||
|
license agreements (excluding distributors and resellers) which have been
|
||||||
|
validly granted by You or Your distributors under this License prior to
|
||||||
|
termination shall survive termination.
|
||||||
|
|
||||||
|
6. Disclaimer of Warranty
|
||||||
|
|
||||||
|
Covered Software is provided under this License on an “as is” basis, without
|
||||||
|
warranty of any kind, either expressed, implied, or statutory, including,
|
||||||
|
without limitation, warranties that the Covered Software is free of defects,
|
||||||
|
merchantable, fit for a particular purpose or non-infringing. The entire
|
||||||
|
risk as to the quality and performance of the Covered Software is with You.
|
||||||
|
Should any Covered Software prove defective in any respect, You (not any
|
||||||
|
Contributor) assume the cost of any necessary servicing, repair, or
|
||||||
|
correction. This disclaimer of warranty constitutes an essential part of this
|
||||||
|
License. No use of any Covered Software is authorized under this License
|
||||||
|
except under this disclaimer.
|
||||||
|
|
||||||
|
7. Limitation of Liability
|
||||||
|
|
||||||
|
Under no circumstances and under no legal theory, whether tort (including
|
||||||
|
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||||
|
distributes Covered Software as permitted above, be liable to You for any
|
||||||
|
direct, indirect, special, incidental, or consequential damages of any
|
||||||
|
character including, without limitation, damages for lost profits, loss of
|
||||||
|
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses, even if such party shall have been
|
||||||
|
informed of the possibility of such damages. This limitation of liability
|
||||||
|
shall not apply to liability for death or personal injury resulting from such
|
||||||
|
party’s negligence to the extent applicable law prohibits such limitation.
|
||||||
|
Some jurisdictions do not allow the exclusion or limitation of incidental or
|
||||||
|
consequential damages, so this exclusion and limitation may not apply to You.
|
||||||
|
|
||||||
|
8. Litigation
|
||||||
|
|
||||||
|
Any litigation relating to this License may be brought only in the courts of
|
||||||
|
a jurisdiction where the defendant maintains its principal place of business
|
||||||
|
and such litigation shall be governed by laws of that jurisdiction, without
|
||||||
|
reference to its conflict-of-law provisions. Nothing in this Section shall
|
||||||
|
prevent a party’s ability to bring cross-claims or counter-claims.
|
||||||
|
|
||||||
|
9. Miscellaneous
|
||||||
|
|
||||||
|
This License represents the complete agreement concerning the subject matter
|
||||||
|
hereof. If any provision of this License is held to be unenforceable, such
|
||||||
|
provision shall be reformed only to the extent necessary to make it
|
||||||
|
enforceable. Any law or regulation which provides that the language of a
|
||||||
|
contract shall be construed against the drafter shall not be used to construe
|
||||||
|
this License against a Contributor.
|
||||||
|
|
||||||
|
|
||||||
|
10. Versions of the License
|
||||||
|
|
||||||
|
10.1. New Versions
|
||||||
|
|
||||||
|
Mozilla Foundation is the license steward. Except as provided in Section
|
||||||
|
10.3, no one other than the license steward has the right to modify or
|
||||||
|
publish new versions of this License. Each version will be given a
|
||||||
|
distinguishing version number.
|
||||||
|
|
||||||
|
10.2. Effect of New Versions
|
||||||
|
|
||||||
|
You may distribute the Covered Software under the terms of the version of
|
||||||
|
the License under which You originally received the Covered Software, or
|
||||||
|
under the terms of any subsequent version published by the license
|
||||||
|
steward.
|
||||||
|
|
||||||
|
10.3. Modified Versions
|
||||||
|
|
||||||
|
If you create software not governed by this License, and you want to
|
||||||
|
create a new license for such software, you may create and use a modified
|
||||||
|
version of this License if you rename the license and remove any
|
||||||
|
references to the name of the license steward (except to note that such
|
||||||
|
modified license differs from this License).
|
||||||
|
|
||||||
|
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
|
||||||
|
If You choose to distribute Source Code Form that is Incompatible With
|
||||||
|
Secondary Licenses under the terms of this version of the License, the
|
||||||
|
notice described in Exhibit B of this License must be attached.
|
||||||
|
|
||||||
|
Exhibit A - Source Code Form License Notice
|
||||||
|
|
||||||
|
This Source Code Form is subject to the
|
||||||
|
terms of the Mozilla Public License, v.
|
||||||
|
2.0. If a copy of the MPL was not
|
||||||
|
distributed with this file, You can
|
||||||
|
obtain one at
|
||||||
|
http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
If it is not possible or desirable to put the notice in a particular file, then
|
||||||
|
You may include the notice in a location (such as a LICENSE file in a relevant
|
||||||
|
directory) where a recipient would be likely to look for such a notice.
|
||||||
|
|
||||||
|
You may add additional accurate notices of copyright ownership.
|
||||||
|
|
||||||
|
Exhibit B - “Incompatible With Secondary Licenses” Notice
|
||||||
|
|
||||||
|
This Source Code Form is “Incompatible
|
||||||
|
With Secondary Licenses”, as defined by
|
||||||
|
the Mozilla Public License, v. 2.0.
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
# 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, ErrNotExist) {
|
||||||
|
// 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!
|
||||||
|
}
|
||||||
|
```
|
|
@ -0,0 +1,169 @@
|
||||||
|
// 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}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
sudo: false
|
||||||
|
|
||||||
|
language: go
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.6
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
script: make test testrace
|
|
@ -0,0 +1,353 @@
|
||||||
|
Mozilla Public License, version 2.0
|
||||||
|
|
||||||
|
1. Definitions
|
||||||
|
|
||||||
|
1.1. “Contributor”
|
||||||
|
|
||||||
|
means each individual or legal entity that creates, contributes to the
|
||||||
|
creation of, or owns Covered Software.
|
||||||
|
|
||||||
|
1.2. “Contributor Version”
|
||||||
|
|
||||||
|
means the combination of the Contributions of others (if any) used by a
|
||||||
|
Contributor and that particular Contributor’s Contribution.
|
||||||
|
|
||||||
|
1.3. “Contribution”
|
||||||
|
|
||||||
|
means Covered Software of a particular Contributor.
|
||||||
|
|
||||||
|
1.4. “Covered Software”
|
||||||
|
|
||||||
|
means Source Code Form to which the initial Contributor has attached the
|
||||||
|
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||||
|
Modifications of such Source Code Form, in each case including portions
|
||||||
|
thereof.
|
||||||
|
|
||||||
|
1.5. “Incompatible With Secondary Licenses”
|
||||||
|
means
|
||||||
|
|
||||||
|
a. that the initial Contributor has attached the notice described in
|
||||||
|
Exhibit B to the Covered Software; or
|
||||||
|
|
||||||
|
b. that the Covered Software was made available under the terms of version
|
||||||
|
1.1 or earlier of the License, but not also under the terms of a
|
||||||
|
Secondary License.
|
||||||
|
|
||||||
|
1.6. “Executable Form”
|
||||||
|
|
||||||
|
means any form of the work other than Source Code Form.
|
||||||
|
|
||||||
|
1.7. “Larger Work”
|
||||||
|
|
||||||
|
means a work that combines Covered Software with other material, in a separate
|
||||||
|
file or files, that is not Covered Software.
|
||||||
|
|
||||||
|
1.8. “License”
|
||||||
|
|
||||||
|
means this document.
|
||||||
|
|
||||||
|
1.9. “Licensable”
|
||||||
|
|
||||||
|
means having the right to grant, to the maximum extent possible, whether at the
|
||||||
|
time of the initial grant or subsequently, any and all of the rights conveyed by
|
||||||
|
this License.
|
||||||
|
|
||||||
|
1.10. “Modifications”
|
||||||
|
|
||||||
|
means any of the following:
|
||||||
|
|
||||||
|
a. any file in Source Code Form that results from an addition to, deletion
|
||||||
|
from, or modification of the contents of Covered Software; or
|
||||||
|
|
||||||
|
b. any new file in Source Code Form that contains any Covered Software.
|
||||||
|
|
||||||
|
1.11. “Patent Claims” of a Contributor
|
||||||
|
|
||||||
|
means any patent claim(s), including without limitation, method, process,
|
||||||
|
and apparatus claims, in any patent Licensable by such Contributor that
|
||||||
|
would be infringed, but for the grant of the License, by the making,
|
||||||
|
using, selling, offering for sale, having made, import, or transfer of
|
||||||
|
either its Contributions or its Contributor Version.
|
||||||
|
|
||||||
|
1.12. “Secondary License”
|
||||||
|
|
||||||
|
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||||
|
General Public License, Version 2.1, the GNU Affero General Public
|
||||||
|
License, Version 3.0, or any later versions of those licenses.
|
||||||
|
|
||||||
|
1.13. “Source Code Form”
|
||||||
|
|
||||||
|
means the form of the work preferred for making modifications.
|
||||||
|
|
||||||
|
1.14. “You” (or “Your”)
|
||||||
|
|
||||||
|
means an individual or a legal entity exercising rights under this
|
||||||
|
License. For legal entities, “You” includes any entity that controls, is
|
||||||
|
controlled by, or is under common control with You. For purposes of this
|
||||||
|
definition, “control” means (a) the power, direct or indirect, to cause
|
||||||
|
the direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||||
|
outstanding shares or beneficial ownership of such entity.
|
||||||
|
|
||||||
|
|
||||||
|
2. License Grants and Conditions
|
||||||
|
|
||||||
|
2.1. Grants
|
||||||
|
|
||||||
|
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||||
|
non-exclusive license:
|
||||||
|
|
||||||
|
a. under intellectual property rights (other than patent or trademark)
|
||||||
|
Licensable by such Contributor to use, reproduce, make available,
|
||||||
|
modify, display, perform, distribute, and otherwise exploit its
|
||||||
|
Contributions, either on an unmodified basis, with Modifications, or as
|
||||||
|
part of a Larger Work; and
|
||||||
|
|
||||||
|
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||||
|
sale, have made, import, and otherwise transfer either its Contributions
|
||||||
|
or its Contributor Version.
|
||||||
|
|
||||||
|
2.2. Effective Date
|
||||||
|
|
||||||
|
The licenses granted in Section 2.1 with respect to any Contribution become
|
||||||
|
effective for each Contribution on the date the Contributor first distributes
|
||||||
|
such Contribution.
|
||||||
|
|
||||||
|
2.3. Limitations on Grant Scope
|
||||||
|
|
||||||
|
The licenses granted in this Section 2 are the only rights granted under this
|
||||||
|
License. No additional rights or licenses will be implied from the distribution
|
||||||
|
or licensing of Covered Software under this License. Notwithstanding Section
|
||||||
|
2.1(b) above, no patent license is granted by a Contributor:
|
||||||
|
|
||||||
|
a. for any code that a Contributor has removed from Covered Software; or
|
||||||
|
|
||||||
|
b. for infringements caused by: (i) Your and any other third party’s
|
||||||
|
modifications of Covered Software, or (ii) the combination of its
|
||||||
|
Contributions with other software (except as part of its Contributor
|
||||||
|
Version); or
|
||||||
|
|
||||||
|
c. under Patent Claims infringed by Covered Software in the absence of its
|
||||||
|
Contributions.
|
||||||
|
|
||||||
|
This License does not grant any rights in the trademarks, service marks, or
|
||||||
|
logos of any Contributor (except as may be necessary to comply with the
|
||||||
|
notice requirements in Section 3.4).
|
||||||
|
|
||||||
|
2.4. Subsequent Licenses
|
||||||
|
|
||||||
|
No Contributor makes additional grants as a result of Your choice to
|
||||||
|
distribute the Covered Software under a subsequent version of this License
|
||||||
|
(see Section 10.2) or under the terms of a Secondary License (if permitted
|
||||||
|
under the terms of Section 3.3).
|
||||||
|
|
||||||
|
2.5. Representation
|
||||||
|
|
||||||
|
Each Contributor represents that the Contributor believes its Contributions
|
||||||
|
are its original creation(s) or it has sufficient rights to grant the
|
||||||
|
rights to its Contributions conveyed by this License.
|
||||||
|
|
||||||
|
2.6. Fair Use
|
||||||
|
|
||||||
|
This License is not intended to limit any rights You have under applicable
|
||||||
|
copyright doctrines of fair use, fair dealing, or other equivalents.
|
||||||
|
|
||||||
|
2.7. Conditions
|
||||||
|
|
||||||
|
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||||
|
Section 2.1.
|
||||||
|
|
||||||
|
|
||||||
|
3. Responsibilities
|
||||||
|
|
||||||
|
3.1. Distribution of Source Form
|
||||||
|
|
||||||
|
All distribution of Covered Software in Source Code Form, including any
|
||||||
|
Modifications that You create or to which You contribute, must be under the
|
||||||
|
terms of this License. You must inform recipients that the Source Code Form
|
||||||
|
of the Covered Software is governed by the terms of this License, and how
|
||||||
|
they can obtain a copy of this License. You may not attempt to alter or
|
||||||
|
restrict the recipients’ rights in the Source Code Form.
|
||||||
|
|
||||||
|
3.2. Distribution of Executable Form
|
||||||
|
|
||||||
|
If You distribute Covered Software in Executable Form then:
|
||||||
|
|
||||||
|
a. such Covered Software must also be made available in Source Code Form,
|
||||||
|
as described in Section 3.1, and You must inform recipients of the
|
||||||
|
Executable Form how they can obtain a copy of such Source Code Form by
|
||||||
|
reasonable means in a timely manner, at a charge no more than the cost
|
||||||
|
of distribution to the recipient; and
|
||||||
|
|
||||||
|
b. You may distribute such Executable Form under the terms of this License,
|
||||||
|
or sublicense it under different terms, provided that the license for
|
||||||
|
the Executable Form does not attempt to limit or alter the recipients’
|
||||||
|
rights in the Source Code Form under this License.
|
||||||
|
|
||||||
|
3.3. Distribution of a Larger Work
|
||||||
|
|
||||||
|
You may create and distribute a Larger Work under terms of Your choice,
|
||||||
|
provided that You also comply with the requirements of this License for the
|
||||||
|
Covered Software. If the Larger Work is a combination of Covered Software
|
||||||
|
with a work governed by one or more Secondary Licenses, and the Covered
|
||||||
|
Software is not Incompatible With Secondary Licenses, this License permits
|
||||||
|
You to additionally distribute such Covered Software under the terms of
|
||||||
|
such Secondary License(s), so that the recipient of the Larger Work may, at
|
||||||
|
their option, further distribute the Covered Software under the terms of
|
||||||
|
either this License or such Secondary License(s).
|
||||||
|
|
||||||
|
3.4. Notices
|
||||||
|
|
||||||
|
You may not remove or alter the substance of any license notices (including
|
||||||
|
copyright notices, patent notices, disclaimers of warranty, or limitations
|
||||||
|
of liability) contained within the Source Code Form of the Covered
|
||||||
|
Software, except that You may alter any license notices to the extent
|
||||||
|
required to remedy known factual inaccuracies.
|
||||||
|
|
||||||
|
3.5. Application of Additional Terms
|
||||||
|
|
||||||
|
You may choose to offer, and to charge a fee for, warranty, support,
|
||||||
|
indemnity or liability obligations to one or more recipients of Covered
|
||||||
|
Software. However, You may do so only on Your own behalf, and not on behalf
|
||||||
|
of any Contributor. You must make it absolutely clear that any such
|
||||||
|
warranty, support, indemnity, or liability obligation is offered by You
|
||||||
|
alone, and You hereby agree to indemnify every Contributor for any
|
||||||
|
liability incurred by such Contributor as a result of warranty, support,
|
||||||
|
indemnity or liability terms You offer. You may include additional
|
||||||
|
disclaimers of warranty and limitations of liability specific to any
|
||||||
|
jurisdiction.
|
||||||
|
|
||||||
|
4. Inability to Comply Due to Statute or Regulation
|
||||||
|
|
||||||
|
If it is impossible for You to comply with any of the terms of this License
|
||||||
|
with respect to some or all of the Covered Software due to statute, judicial
|
||||||
|
order, or regulation then You must: (a) comply with the terms of this License
|
||||||
|
to the maximum extent possible; and (b) describe the limitations and the code
|
||||||
|
they affect. Such description must be placed in a text file included with all
|
||||||
|
distributions of the Covered Software under this License. Except to the
|
||||||
|
extent prohibited by statute or regulation, such description must be
|
||||||
|
sufficiently detailed for a recipient of ordinary skill to be able to
|
||||||
|
understand it.
|
||||||
|
|
||||||
|
5. Termination
|
||||||
|
|
||||||
|
5.1. The rights granted under this License will terminate automatically if You
|
||||||
|
fail to comply with any of its terms. However, if You become compliant,
|
||||||
|
then the rights granted under this License from a particular Contributor
|
||||||
|
are reinstated (a) provisionally, unless and until such Contributor
|
||||||
|
explicitly and finally terminates Your grants, and (b) on an ongoing basis,
|
||||||
|
if such Contributor fails to notify You of the non-compliance by some
|
||||||
|
reasonable means prior to 60 days after You have come back into compliance.
|
||||||
|
Moreover, Your grants from a particular Contributor are reinstated on an
|
||||||
|
ongoing basis if such Contributor notifies You of the non-compliance by
|
||||||
|
some reasonable means, this is the first time You have received notice of
|
||||||
|
non-compliance with this License from such Contributor, and You become
|
||||||
|
compliant prior to 30 days after Your receipt of the notice.
|
||||||
|
|
||||||
|
5.2. If You initiate litigation against any entity by asserting a patent
|
||||||
|
infringement claim (excluding declaratory judgment actions, counter-claims,
|
||||||
|
and cross-claims) alleging that a Contributor Version directly or
|
||||||
|
indirectly infringes any patent, then the rights granted to You by any and
|
||||||
|
all Contributors for the Covered Software under Section 2.1 of this License
|
||||||
|
shall terminate.
|
||||||
|
|
||||||
|
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||||
|
license agreements (excluding distributors and resellers) which have been
|
||||||
|
validly granted by You or Your distributors under this License prior to
|
||||||
|
termination shall survive termination.
|
||||||
|
|
||||||
|
6. Disclaimer of Warranty
|
||||||
|
|
||||||
|
Covered Software is provided under this License on an “as is” basis, without
|
||||||
|
warranty of any kind, either expressed, implied, or statutory, including,
|
||||||
|
without limitation, warranties that the Covered Software is free of defects,
|
||||||
|
merchantable, fit for a particular purpose or non-infringing. The entire
|
||||||
|
risk as to the quality and performance of the Covered Software is with You.
|
||||||
|
Should any Covered Software prove defective in any respect, You (not any
|
||||||
|
Contributor) assume the cost of any necessary servicing, repair, or
|
||||||
|
correction. This disclaimer of warranty constitutes an essential part of this
|
||||||
|
License. No use of any Covered Software is authorized under this License
|
||||||
|
except under this disclaimer.
|
||||||
|
|
||||||
|
7. Limitation of Liability
|
||||||
|
|
||||||
|
Under no circumstances and under no legal theory, whether tort (including
|
||||||
|
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||||
|
distributes Covered Software as permitted above, be liable to You for any
|
||||||
|
direct, indirect, special, incidental, or consequential damages of any
|
||||||
|
character including, without limitation, damages for lost profits, loss of
|
||||||
|
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses, even if such party shall have been
|
||||||
|
informed of the possibility of such damages. This limitation of liability
|
||||||
|
shall not apply to liability for death or personal injury resulting from such
|
||||||
|
party’s negligence to the extent applicable law prohibits such limitation.
|
||||||
|
Some jurisdictions do not allow the exclusion or limitation of incidental or
|
||||||
|
consequential damages, so this exclusion and limitation may not apply to You.
|
||||||
|
|
||||||
|
8. Litigation
|
||||||
|
|
||||||
|
Any litigation relating to this License may be brought only in the courts of
|
||||||
|
a jurisdiction where the defendant maintains its principal place of business
|
||||||
|
and such litigation shall be governed by laws of that jurisdiction, without
|
||||||
|
reference to its conflict-of-law provisions. Nothing in this Section shall
|
||||||
|
prevent a party’s ability to bring cross-claims or counter-claims.
|
||||||
|
|
||||||
|
9. Miscellaneous
|
||||||
|
|
||||||
|
This License represents the complete agreement concerning the subject matter
|
||||||
|
hereof. If any provision of this License is held to be unenforceable, such
|
||||||
|
provision shall be reformed only to the extent necessary to make it
|
||||||
|
enforceable. Any law or regulation which provides that the language of a
|
||||||
|
contract shall be construed against the drafter shall not be used to construe
|
||||||
|
this License against a Contributor.
|
||||||
|
|
||||||
|
|
||||||
|
10. Versions of the License
|
||||||
|
|
||||||
|
10.1. New Versions
|
||||||
|
|
||||||
|
Mozilla Foundation is the license steward. Except as provided in Section
|
||||||
|
10.3, no one other than the license steward has the right to modify or
|
||||||
|
publish new versions of this License. Each version will be given a
|
||||||
|
distinguishing version number.
|
||||||
|
|
||||||
|
10.2. Effect of New Versions
|
||||||
|
|
||||||
|
You may distribute the Covered Software under the terms of the version of
|
||||||
|
the License under which You originally received the Covered Software, or
|
||||||
|
under the terms of any subsequent version published by the license
|
||||||
|
steward.
|
||||||
|
|
||||||
|
10.3. Modified Versions
|
||||||
|
|
||||||
|
If you create software not governed by this License, and you want to
|
||||||
|
create a new license for such software, you may create and use a modified
|
||||||
|
version of this License if you rename the license and remove any
|
||||||
|
references to the name of the license steward (except to note that such
|
||||||
|
modified license differs from this License).
|
||||||
|
|
||||||
|
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
|
||||||
|
If You choose to distribute Source Code Form that is Incompatible With
|
||||||
|
Secondary Licenses under the terms of this version of the License, the
|
||||||
|
notice described in Exhibit B of this License must be attached.
|
||||||
|
|
||||||
|
Exhibit A - Source Code Form License Notice
|
||||||
|
|
||||||
|
This Source Code Form is subject to the
|
||||||
|
terms of the Mozilla Public License, v.
|
||||||
|
2.0. If a copy of the MPL was not
|
||||||
|
distributed with this file, You can
|
||||||
|
obtain one at
|
||||||
|
http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
If it is not possible or desirable to put the notice in a particular file, then
|
||||||
|
You may include the notice in a location (such as a LICENSE file in a relevant
|
||||||
|
directory) where a recipient would be likely to look for such a notice.
|
||||||
|
|
||||||
|
You may add additional accurate notices of copyright ownership.
|
||||||
|
|
||||||
|
Exhibit B - “Incompatible With Secondary Licenses” Notice
|
||||||
|
|
||||||
|
This Source Code Form is “Incompatible
|
||||||
|
With Secondary Licenses”, as defined by
|
||||||
|
the Mozilla Public License, v. 2.0.
|
|
@ -0,0 +1,31 @@
|
||||||
|
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
|
|
@ -0,0 +1,97 @@
|
||||||
|
# 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()
|
||||||
|
```
|
|
@ -0,0 +1,41 @@
|
||||||
|
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...)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
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\n* %s", 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\n%s",
|
||||||
|
len(es), strings.Join(points, "\n"))
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
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 implementatin 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 implementd only to
|
||||||
|
// satisfy the errwrap.Wrapper interface.
|
||||||
|
func (e *Error) WrappedErrors() []error {
|
||||||
|
return e.Errors
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,109 +1,97 @@
|
||||||
// +build !selinux !linux
|
|
||||||
|
|
||||||
package label
|
package label
|
||||||
|
|
||||||
// InitLabels returns the process label and file labels to be used within
|
import (
|
||||||
// the container. A list of options can be passed into this function to alter
|
"fmt"
|
||||||
// the labels.
|
|
||||||
func InitLabels(options []string) (string, string, error) {
|
|
||||||
return "", "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ROMountLabel() string {
|
"github.com/opencontainers/selinux/go-selinux"
|
||||||
return ""
|
)
|
||||||
}
|
|
||||||
|
|
||||||
func GenLabels(options string) (string, string, error) {
|
// Deprecated: use selinux.ROFileLabel
|
||||||
return "", "", nil
|
var ROMountLabel = selinux.ROFileLabel
|
||||||
}
|
|
||||||
|
|
||||||
func FormatMountLabel(src string, mountLabel string) string {
|
// SetProcessLabel takes a process label and tells the kernel to assign the
|
||||||
return src
|
// label to the next program executed by the current process.
|
||||||
}
|
// Deprecated: use selinux.SetExecLabel
|
||||||
|
var SetProcessLabel = selinux.SetExecLabel
|
||||||
|
|
||||||
func SetProcessLabel(processLabel string) error {
|
// ProcessLabel returns the process label that the kernel will assign
|
||||||
return nil
|
// to the next program executed by the current process. If "" is returned
|
||||||
}
|
// this indicates that the default labeling will happen for the process.
|
||||||
|
// Deprecated: use selinux.ExecLabel
|
||||||
|
var ProcessLabel = selinux.ExecLabel
|
||||||
|
|
||||||
func ProcessLabel() (string, error) {
|
// SetSocketLabel takes a process label and tells the kernel to assign the
|
||||||
return "", nil
|
// label to the next socket that gets created
|
||||||
}
|
// Deprecated: use selinux.SetSocketLabel
|
||||||
|
var SetSocketLabel = selinux.SetSocketLabel
|
||||||
|
|
||||||
func SetSocketLabel(processLabel string) error {
|
// SocketLabel retrieves the current default socket label setting
|
||||||
return nil
|
// Deprecated: use selinux.SocketLabel
|
||||||
}
|
var SocketLabel = selinux.SocketLabel
|
||||||
|
|
||||||
func SocketLabel() (string, error) {
|
// SetKeyLabel takes a process label and tells the kernel to assign the
|
||||||
return "", nil
|
// label to the next kernel keyring that gets created
|
||||||
}
|
// Deprecated: use selinux.SetKeyLabel
|
||||||
|
var SetKeyLabel = selinux.SetKeyLabel
|
||||||
|
|
||||||
func SetKeyLabel(processLabel string) error {
|
// KeyLabel retrieves the current default kernel keyring label setting
|
||||||
return nil
|
// Deprecated: use selinux.KeyLabel
|
||||||
}
|
var KeyLabel = selinux.KeyLabel
|
||||||
|
|
||||||
func KeyLabel() (string, error) {
|
// FileLabel returns the label for specified path
|
||||||
return "", nil
|
// Deprecated: use selinux.FileLabel
|
||||||
}
|
var FileLabel = selinux.FileLabel
|
||||||
|
|
||||||
func FileLabel(path string) (string, error) {
|
// PidLabel will return the label of the process running with the specified pid
|
||||||
return "", nil
|
// Deprecated: use selinux.PidLabel
|
||||||
}
|
var PidLabel = selinux.PidLabel
|
||||||
|
|
||||||
func SetFileLabel(path string, fileLabel string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetFileCreateLabel(fileLabel string) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Relabel(path string, fileLabel string, shared bool) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func PidLabel(pid int) (string, error) {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Init initialises the labeling system
|
||||||
func Init() {
|
func Init() {
|
||||||
|
_ = selinux.GetEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearLabels clears all reserved labels
|
// ClearLabels will clear all reserved labels
|
||||||
func ClearLabels() {
|
// Deprecated: use selinux.ClearLabels
|
||||||
return
|
var ClearLabels = selinux.ClearLabels
|
||||||
}
|
|
||||||
|
|
||||||
|
// ReserveLabel will record the fact that the MCS label has already been used.
|
||||||
|
// This will prevent InitLabels from using the MCS label in a newly created
|
||||||
|
// container
|
||||||
|
// Deprecated: use selinux.ReserveLabel
|
||||||
func ReserveLabel(label string) error {
|
func ReserveLabel(label string) error {
|
||||||
|
selinux.ReserveLabel(label)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReleaseLabel will remove the reservation of the MCS label.
|
||||||
|
// This will allow InitLabels to use the MCS label in a newly created
|
||||||
|
// containers
|
||||||
|
// Deprecated: use selinux.ReleaseLabel
|
||||||
func ReleaseLabel(label string) error {
|
func ReleaseLabel(label string) error {
|
||||||
|
selinux.ReleaseLabel(label)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DupSecOpt takes a process label and returns security options that
|
// DupSecOpt takes a process label and returns security options that
|
||||||
// can be used to set duplicate labels on future container processes
|
// can be used to set duplicate labels on future container processes
|
||||||
func DupSecOpt(src string) ([]string, error) {
|
// Deprecated: use selinux.DupSecOpt
|
||||||
return nil, nil
|
var DupSecOpt = selinux.DupSecOpt
|
||||||
}
|
|
||||||
|
|
||||||
// DisableSecOpt returns a security opt that can disable labeling
|
// FormatMountLabel returns a string to be used by the mount command.
|
||||||
// support for future container processes
|
// The format of this string will be used to alter the labeling of the mountpoint.
|
||||||
func DisableSecOpt() []string {
|
// The string returned is suitable to be used as the options field of the mount command.
|
||||||
return nil
|
// If you need to have additional mount point options, you can pass them in as
|
||||||
}
|
// the first parameter. Second parameter is the label that you wish to apply
|
||||||
|
// to all content in the mount point.
|
||||||
// Validate checks that the label does not include unexpected options
|
func FormatMountLabel(src, mountLabel string) string {
|
||||||
func Validate(label string) error {
|
if mountLabel != "" {
|
||||||
return nil
|
switch src {
|
||||||
}
|
case "":
|
||||||
|
src = fmt.Sprintf("context=%q", mountLabel)
|
||||||
// RelabelNeeded checks whether the user requested a relabel
|
default:
|
||||||
func RelabelNeeded(label string) bool {
|
src = fmt.Sprintf("%s,context=%q", src, mountLabel)
|
||||||
return false
|
}
|
||||||
}
|
}
|
||||||
|
return src
|
||||||
// IsShared checks that the label includes a "shared" mark
|
|
||||||
func IsShared(label string) bool {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
package label
|
package label
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/opencontainers/selinux/go-selinux"
|
"github.com/opencontainers/selinux/go-selinux"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Valid Label Options
|
// Valid Label Options
|
||||||
|
@ -21,7 +21,7 @@ var validOptions = map[string]bool{
|
||||||
"level": true,
|
"level": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
var ErrIncompatibleLabel = fmt.Errorf("Bad SELinux option z and Z can not be used together")
|
var ErrIncompatibleLabel = errors.New("Bad SELinux option z and Z can not be used together")
|
||||||
|
|
||||||
// InitLabels returns the process label and file labels to be used within
|
// InitLabels returns the process label and file labels to be used within
|
||||||
// the container. A list of options can be passed into this function to alter
|
// the container. A list of options can be passed into this function to alter
|
||||||
|
@ -35,14 +35,14 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
|
||||||
if processLabel != "" {
|
if processLabel != "" {
|
||||||
defer func() {
|
defer func() {
|
||||||
if Err != nil {
|
if Err != nil {
|
||||||
ReleaseLabel(mountLabel)
|
selinux.ReleaseLabel(mountLabel)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
pcon, err := selinux.NewContext(processLabel)
|
pcon, err := selinux.NewContext(processLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
mcsLevel := pcon["level"]
|
||||||
mcon, err := selinux.NewContext(mountLabel)
|
mcon, err := selinux.NewContext(mountLabel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
|
@ -52,121 +52,61 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
|
||||||
return "", mountLabel, nil
|
return "", mountLabel, nil
|
||||||
}
|
}
|
||||||
if i := strings.Index(opt, ":"); i == -1 {
|
if i := strings.Index(opt, ":"); i == -1 {
|
||||||
return "", "", fmt.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt)
|
return "", "", errors.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt)
|
||||||
}
|
}
|
||||||
con := strings.SplitN(opt, ":", 2)
|
con := strings.SplitN(opt, ":", 2)
|
||||||
if !validOptions[con[0]] {
|
if !validOptions[con[0]] {
|
||||||
return "", "", fmt.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0])
|
return "", "", errors.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0])
|
||||||
|
|
||||||
}
|
}
|
||||||
if con[0] == "filetype" {
|
if con[0] == "filetype" {
|
||||||
mcon["type"] = con[1]
|
mcon["type"] = con[1]
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
pcon[con[0]] = con[1]
|
pcon[con[0]] = con[1]
|
||||||
if con[0] == "level" || con[0] == "user" {
|
if con[0] == "level" || con[0] == "user" {
|
||||||
mcon[con[0]] = con[1]
|
mcon[con[0]] = con[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ = ReleaseLabel(processLabel)
|
if pcon.Get() != processLabel {
|
||||||
|
if pcon["level"] != mcsLevel {
|
||||||
|
selinux.ReleaseLabel(processLabel)
|
||||||
|
}
|
||||||
processLabel = pcon.Get()
|
processLabel = pcon.Get()
|
||||||
|
selinux.ReserveLabel(processLabel)
|
||||||
|
}
|
||||||
mountLabel = mcon.Get()
|
mountLabel = mcon.Get()
|
||||||
_ = ReserveLabel(processLabel)
|
|
||||||
}
|
}
|
||||||
return processLabel, mountLabel, nil
|
return processLabel, mountLabel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ROMountLabel() string {
|
// Deprecated: The GenLabels function is only to be used during the transition
|
||||||
return selinux.ROFileLabel()
|
// to the official API. Use InitLabels(strings.Fields(options)) instead.
|
||||||
}
|
|
||||||
|
|
||||||
// DEPRECATED: The GenLabels function is only to be used during the transition to the official API.
|
|
||||||
func GenLabels(options string) (string, string, error) {
|
func GenLabels(options string) (string, string, error) {
|
||||||
return InitLabels(strings.Fields(options))
|
return InitLabels(strings.Fields(options))
|
||||||
}
|
}
|
||||||
|
|
||||||
// FormatMountLabel returns a string to be used by the mount command.
|
|
||||||
// The format of this string will be used to alter the labeling of the mountpoint.
|
|
||||||
// The string returned is suitable to be used as the options field of the mount command.
|
|
||||||
// If you need to have additional mount point options, you can pass them in as
|
|
||||||
// the first parameter. Second parameter is the label that you wish to apply
|
|
||||||
// to all content in the mount point.
|
|
||||||
func FormatMountLabel(src, mountLabel string) string {
|
|
||||||
if mountLabel != "" {
|
|
||||||
switch src {
|
|
||||||
case "":
|
|
||||||
src = fmt.Sprintf("context=%q", mountLabel)
|
|
||||||
default:
|
|
||||||
src = fmt.Sprintf("%s,context=%q", src, mountLabel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return src
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetProcessLabel takes a process label and tells the kernel to assign the
|
|
||||||
// label to the next program executed by the current process.
|
|
||||||
func SetProcessLabel(processLabel string) error {
|
|
||||||
return selinux.SetExecLabel(processLabel)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSocketLabel takes a process label and tells the kernel to assign the
|
|
||||||
// label to the next socket that gets created
|
|
||||||
func SetSocketLabel(processLabel string) error {
|
|
||||||
return selinux.SetSocketLabel(processLabel)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SocketLabel retrieves the current default socket label setting
|
|
||||||
func SocketLabel() (string, error) {
|
|
||||||
return selinux.SocketLabel()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetKeyLabel takes a process label and tells the kernel to assign the
|
|
||||||
// label to the next kernel keyring that gets created
|
|
||||||
func SetKeyLabel(processLabel string) error {
|
|
||||||
return selinux.SetKeyLabel(processLabel)
|
|
||||||
}
|
|
||||||
|
|
||||||
// KeyLabel retrieves the current default kernel keyring label setting
|
|
||||||
func KeyLabel() (string, error) {
|
|
||||||
return selinux.KeyLabel()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProcessLabel returns the process label that the kernel will assign
|
|
||||||
// to the next program executed by the current process. If "" is returned
|
|
||||||
// this indicates that the default labeling will happen for the process.
|
|
||||||
func ProcessLabel() (string, error) {
|
|
||||||
return selinux.ExecLabel()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileLabel returns the label for specified path
|
|
||||||
func FileLabel(path string) (string, error) {
|
|
||||||
return selinux.FileLabel(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFileLabel modifies the "path" label to the specified file label
|
// SetFileLabel modifies the "path" label to the specified file label
|
||||||
func SetFileLabel(path string, fileLabel string) error {
|
func SetFileLabel(path string, fileLabel string) error {
|
||||||
if selinux.GetEnabled() && fileLabel != "" {
|
if !selinux.GetEnabled() || fileLabel == "" {
|
||||||
return selinux.SetFileLabel(path, fileLabel)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
return selinux.SetFileLabel(path, fileLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFileCreateLabel tells the kernel the label for all files to be created
|
// SetFileCreateLabel tells the kernel the label for all files to be created
|
||||||
func SetFileCreateLabel(fileLabel string) error {
|
func SetFileCreateLabel(fileLabel string) error {
|
||||||
if selinux.GetEnabled() {
|
if !selinux.GetEnabled() {
|
||||||
return selinux.SetFSCreateLabel(fileLabel)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
return selinux.SetFSCreateLabel(fileLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relabel changes the label of path to the filelabel string.
|
// Relabel changes the label of path to the filelabel string.
|
||||||
// It changes the MCS label to s0 if shared is true.
|
// It changes the MCS label to s0 if shared is true.
|
||||||
// This will allow all containers to share the content.
|
// This will allow all containers to share the content.
|
||||||
func Relabel(path string, fileLabel string, shared bool) error {
|
func Relabel(path string, fileLabel string, shared bool) error {
|
||||||
if !selinux.GetEnabled() {
|
if !selinux.GetEnabled() || fileLabel == "" {
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if fileLabel == "" {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +151,7 @@ func Relabel(path string, fileLabel string, shared bool) error {
|
||||||
path = strings.TrimSuffix(path, "/")
|
path = strings.TrimSuffix(path, "/")
|
||||||
}
|
}
|
||||||
if exclude_paths[path] {
|
if exclude_paths[path] {
|
||||||
return fmt.Errorf("SELinux relabeling of %s is not allowed", path)
|
return errors.Errorf("SELinux relabeling of %s is not allowed", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
if shared {
|
if shared {
|
||||||
|
@ -229,48 +169,10 @@ func Relabel(path string, fileLabel string, shared bool) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PidLabel will return the label of the process running with the specified pid
|
|
||||||
func PidLabel(pid int) (string, error) {
|
|
||||||
return selinux.PidLabel(pid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init initialises the labeling system
|
|
||||||
func Init() {
|
|
||||||
selinux.GetEnabled()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClearLabels will clear all reserved labels
|
|
||||||
func ClearLabels() {
|
|
||||||
selinux.ClearLabels()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReserveLabel will record the fact that the MCS label has already been used.
|
|
||||||
// This will prevent InitLabels from using the MCS label in a newly created
|
|
||||||
// container
|
|
||||||
func ReserveLabel(label string) error {
|
|
||||||
selinux.ReserveLabel(label)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReleaseLabel will remove the reservation of the MCS label.
|
|
||||||
// This will allow InitLabels to use the MCS label in a newly created
|
|
||||||
// containers
|
|
||||||
func ReleaseLabel(label string) error {
|
|
||||||
selinux.ReleaseLabel(label)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DupSecOpt takes a process label and returns security options that
|
|
||||||
// can be used to set duplicate labels on future container processes
|
|
||||||
func DupSecOpt(src string) ([]string, error) {
|
|
||||||
return selinux.DupSecOpt(src)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DisableSecOpt returns a security opt that can disable labeling
|
// DisableSecOpt returns a security opt that can disable labeling
|
||||||
// support for future container processes
|
// support for future container processes
|
||||||
func DisableSecOpt() []string {
|
// Deprecated: use selinux.DisableSecOpt
|
||||||
return selinux.DisableSecOpt()
|
var DisableSecOpt = selinux.DisableSecOpt
|
||||||
}
|
|
||||||
|
|
||||||
// Validate checks that the label does not include unexpected options
|
// Validate checks that the label does not include unexpected options
|
||||||
func Validate(label string) error {
|
func Validate(label string) error {
|
||||||
|
|
50
vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go
generated
vendored
Normal file
50
vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// +build !selinux !linux
|
||||||
|
|
||||||
|
package label
|
||||||
|
|
||||||
|
// InitLabels returns the process label and file labels to be used within
|
||||||
|
// the container. A list of options can be passed into this function to alter
|
||||||
|
// the labels.
|
||||||
|
func InitLabels(options []string) (string, string, error) {
|
||||||
|
return "", "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: The GenLabels function is only to be used during the transition
|
||||||
|
// to the official API. Use InitLabels(strings.Fields(options)) instead.
|
||||||
|
func GenLabels(options string) (string, string, error) {
|
||||||
|
return "", "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetFileLabel(path string, fileLabel string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetFileCreateLabel(fileLabel string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Relabel(path string, fileLabel string, shared bool) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableSecOpt returns a security opt that can disable labeling
|
||||||
|
// support for future container processes
|
||||||
|
func DisableSecOpt() []string {
|
||||||
|
// TODO the selinux.DisableSecOpt stub returns []string{"disable"} instead of "nil"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate checks that the label does not include unexpected options
|
||||||
|
func Validate(label string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RelabelNeeded checks whether the user requested a relabel
|
||||||
|
func RelabelNeeded(label string) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsShared checks that the label includes a "shared" mark
|
||||||
|
func IsShared(label string) bool {
|
||||||
|
return false
|
||||||
|
}
|
|
@ -7,18 +7,19 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
|
"github.com/opencontainers/selinux/pkg/pwalk"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,20 +31,22 @@ const (
|
||||||
// Disabled constant to indicate SELinux is disabled
|
// Disabled constant to indicate SELinux is disabled
|
||||||
Disabled = -1
|
Disabled = -1
|
||||||
|
|
||||||
|
// DefaultCategoryRange is the upper bound on the category range
|
||||||
|
DefaultCategoryRange = uint32(1024)
|
||||||
|
|
||||||
|
contextFile = "/usr/share/containers/selinux/contexts"
|
||||||
selinuxDir = "/etc/selinux/"
|
selinuxDir = "/etc/selinux/"
|
||||||
selinuxConfig = selinuxDir + "config"
|
selinuxConfig = selinuxDir + "config"
|
||||||
selinuxfsMount = "/sys/fs/selinux"
|
selinuxfsMount = "/sys/fs/selinux"
|
||||||
selinuxTypeTag = "SELINUXTYPE"
|
selinuxTypeTag = "SELINUXTYPE"
|
||||||
selinuxTag = "SELINUX"
|
selinuxTag = "SELINUX"
|
||||||
xattrNameSelinux = "security.selinux"
|
xattrNameSelinux = "security.selinux"
|
||||||
stRdOnly = 0x01
|
|
||||||
selinuxfsMagic = 0xf97cff8c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type selinuxState struct {
|
type selinuxState struct {
|
||||||
enabledSet bool
|
enabledSet bool
|
||||||
enabled bool
|
enabled bool
|
||||||
selinuxfsSet bool
|
selinuxfsOnce sync.Once
|
||||||
selinuxfs string
|
selinuxfs string
|
||||||
mcsList map[string]bool
|
mcsList map[string]bool
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
|
@ -57,11 +60,18 @@ var (
|
||||||
// InvalidLabel is returned when an invalid label is specified.
|
// InvalidLabel is returned when an invalid label is specified.
|
||||||
InvalidLabel = errors.New("Invalid Label")
|
InvalidLabel = errors.New("Invalid Label")
|
||||||
|
|
||||||
|
// CategoryRange allows the upper bound on the category range to be adjusted
|
||||||
|
CategoryRange = DefaultCategoryRange
|
||||||
|
|
||||||
assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
|
assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
|
||||||
roFileLabel string
|
roFileLabel string
|
||||||
state = selinuxState{
|
state = selinuxState{
|
||||||
mcsList: make(map[string]bool),
|
mcsList: make(map[string]bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for attrPath()
|
||||||
|
attrPathOnce sync.Once
|
||||||
|
haveThreadSelf bool
|
||||||
)
|
)
|
||||||
|
|
||||||
// Context is a representation of the SELinux label broken into 4 parts
|
// Context is a representation of the SELinux label broken into 4 parts
|
||||||
|
@ -98,30 +108,23 @@ func SetDisabled() {
|
||||||
state.setEnable(false)
|
state.setEnable(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *selinuxState) setSELinuxfs(selinuxfs string) string {
|
|
||||||
s.Lock()
|
|
||||||
defer s.Unlock()
|
|
||||||
s.selinuxfsSet = true
|
|
||||||
s.selinuxfs = selinuxfs
|
|
||||||
return s.selinuxfs
|
|
||||||
}
|
|
||||||
|
|
||||||
func verifySELinuxfsMount(mnt string) bool {
|
func verifySELinuxfsMount(mnt string) bool {
|
||||||
var buf syscall.Statfs_t
|
var buf unix.Statfs_t
|
||||||
for {
|
for {
|
||||||
err := syscall.Statfs(mnt, &buf)
|
err := unix.Statfs(mnt, &buf)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if err == syscall.EAGAIN {
|
if err == unix.EAGAIN {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if uint32(buf.Type) != uint32(selinuxfsMagic) {
|
|
||||||
|
if uint32(buf.Type) != uint32(unix.SELINUX_MAGIC) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (buf.Flags & stRdOnly) != 0 {
|
if (buf.Flags & unix.ST_RDONLY) != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,33 +169,29 @@ func findSELinuxfs() string {
|
||||||
// if there is one, or an empty string in case of EOF or error.
|
// if there is one, or an empty string in case of EOF or error.
|
||||||
func findSELinuxfsMount(s *bufio.Scanner) string {
|
func findSELinuxfsMount(s *bufio.Scanner) string {
|
||||||
for s.Scan() {
|
for s.Scan() {
|
||||||
txt := s.Text()
|
txt := s.Bytes()
|
||||||
// The first field after - is fs type.
|
// The first field after - is fs type.
|
||||||
// Safe as spaces in mountpoints are encoded as \040
|
// Safe as spaces in mountpoints are encoded as \040
|
||||||
if !strings.Contains(txt, " - selinuxfs ") {
|
if !bytes.Contains(txt, []byte(" - selinuxfs ")) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const mPos = 5 // mount point is 5th field
|
const mPos = 5 // mount point is 5th field
|
||||||
fields := strings.SplitN(txt, " ", mPos+1)
|
fields := bytes.SplitN(txt, []byte(" "), mPos+1)
|
||||||
if len(fields) < mPos+1 {
|
if len(fields) < mPos+1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return fields[mPos-1]
|
return string(fields[mPos-1])
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *selinuxState) getSELinuxfs() string {
|
func (s *selinuxState) getSELinuxfs() string {
|
||||||
s.Lock()
|
s.selinuxfsOnce.Do(func() {
|
||||||
selinuxfs := s.selinuxfs
|
s.selinuxfs = findSELinuxfs()
|
||||||
selinuxfsSet := s.selinuxfsSet
|
})
|
||||||
s.Unlock()
|
|
||||||
if selinuxfsSet {
|
|
||||||
return selinuxfs
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.setSELinuxfs(findSELinuxfs())
|
return s.selinuxfs
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs
|
// getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs
|
||||||
|
@ -254,10 +253,17 @@ func getSELinuxPolicyRoot() string {
|
||||||
return filepath.Join(selinuxDir, readConfig(selinuxTypeTag))
|
return filepath.Join(selinuxDir, readConfig(selinuxTypeTag))
|
||||||
}
|
}
|
||||||
|
|
||||||
func isProcHandle(fh *os.File) (bool, error) {
|
func isProcHandle(fh *os.File) error {
|
||||||
var buf unix.Statfs_t
|
var buf unix.Statfs_t
|
||||||
err := unix.Fstatfs(int(fh.Fd()), &buf)
|
err := unix.Fstatfs(int(fh.Fd()), &buf)
|
||||||
return buf.Type == unix.PROC_SUPER_MAGIC, err
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "statfs(%q) failed", fh.Name())
|
||||||
|
}
|
||||||
|
if buf.Type != unix.PROC_SUPER_MAGIC {
|
||||||
|
return errors.Errorf("file %q is not on procfs", fh.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readCon(fpath string) (string, error) {
|
func readCon(fpath string) (string, error) {
|
||||||
|
@ -271,10 +277,8 @@ func readCon(fpath string) (string, error) {
|
||||||
}
|
}
|
||||||
defer in.Close()
|
defer in.Close()
|
||||||
|
|
||||||
if ok, err := isProcHandle(in); err != nil {
|
if err := isProcHandle(in); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
} else if !ok {
|
|
||||||
return "", fmt.Errorf("%s not on procfs", fpath)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var retval string
|
var retval string
|
||||||
|
@ -284,12 +288,32 @@ func readCon(fpath string) (string, error) {
|
||||||
return strings.Trim(retval, "\x00"), nil
|
return strings.Trim(retval, "\x00"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClassIndex returns the int index for an object class in the loaded policy, or -1 and an error
|
||||||
|
func ClassIndex(class string) (int, error) {
|
||||||
|
permpath := fmt.Sprintf("class/%s/index", class)
|
||||||
|
indexpath := filepath.Join(getSelinuxMountPoint(), permpath)
|
||||||
|
|
||||||
|
indexB, err := ioutil.ReadFile(indexpath)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
index, err := strconv.Atoi(string(indexB))
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return index, nil
|
||||||
|
}
|
||||||
|
|
||||||
// SetFileLabel sets the SELinux label for this path or returns an error.
|
// SetFileLabel sets the SELinux label for this path or returns an error.
|
||||||
func SetFileLabel(fpath string, label string) error {
|
func SetFileLabel(fpath string, label string) error {
|
||||||
if fpath == "" {
|
if fpath == "" {
|
||||||
return ErrEmptyPath
|
return ErrEmptyPath
|
||||||
}
|
}
|
||||||
return lsetxattr(fpath, xattrNameSelinux, []byte(label), 0)
|
if err := unix.Lsetxattr(fpath, xattrNameSelinux, []byte(label), 0); err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to set file label on %s", fpath)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileLabel returns the SELinux label for this path or returns an error.
|
// FileLabel returns the SELinux label for this path or returns an error.
|
||||||
|
@ -314,7 +338,7 @@ SetFSCreateLabel tells kernel the label to create all file system objects
|
||||||
created by this task. Setting label="" to return to default.
|
created by this task. Setting label="" to return to default.
|
||||||
*/
|
*/
|
||||||
func SetFSCreateLabel(label string) error {
|
func SetFSCreateLabel(label string) error {
|
||||||
return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid()), label)
|
return writeAttr("fscreate", label)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -322,12 +346,12 @@ FSCreateLabel returns the default label the kernel which the kernel is using
|
||||||
for file system objects created by this task. "" indicates default.
|
for file system objects created by this task. "" indicates default.
|
||||||
*/
|
*/
|
||||||
func FSCreateLabel() (string, error) {
|
func FSCreateLabel() (string, error) {
|
||||||
return readCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid()))
|
return readAttr("fscreate")
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentLabel returns the SELinux label of the current process thread, or an error.
|
// CurrentLabel returns the SELinux label of the current process thread, or an error.
|
||||||
func CurrentLabel() (string, error) {
|
func CurrentLabel() (string, error) {
|
||||||
return readCon(fmt.Sprintf("/proc/self/task/%d/attr/current", syscall.Gettid()))
|
return readAttr("current")
|
||||||
}
|
}
|
||||||
|
|
||||||
// PidLabel returns the SELinux label of the given pid, or an error.
|
// PidLabel returns the SELinux label of the given pid, or an error.
|
||||||
|
@ -340,10 +364,10 @@ ExecLabel returns the SELinux label that the kernel will use for any programs
|
||||||
that are executed by the current process thread, or an error.
|
that are executed by the current process thread, or an error.
|
||||||
*/
|
*/
|
||||||
func ExecLabel() (string, error) {
|
func ExecLabel() (string, error) {
|
||||||
return readCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid()))
|
return readAttr("exec")
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeCon(fpath string, val string) error {
|
func writeCon(fpath, val string) error {
|
||||||
if fpath == "" {
|
if fpath == "" {
|
||||||
return ErrEmptyPath
|
return ErrEmptyPath
|
||||||
}
|
}
|
||||||
|
@ -359,10 +383,8 @@ func writeCon(fpath string, val string) error {
|
||||||
}
|
}
|
||||||
defer out.Close()
|
defer out.Close()
|
||||||
|
|
||||||
if ok, err := isProcHandle(out); err != nil {
|
if err := isProcHandle(out); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if !ok {
|
|
||||||
return fmt.Errorf("%s not on procfs", fpath)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if val != "" {
|
if val != "" {
|
||||||
|
@ -370,7 +392,36 @@ func writeCon(fpath string, val string) error {
|
||||||
} else {
|
} else {
|
||||||
_, err = out.Write(nil)
|
_, err = out.Write(nil)
|
||||||
}
|
}
|
||||||
return err
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to set %s on procfs", fpath)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func attrPath(attr string) string {
|
||||||
|
// Linux >= 3.17 provides this
|
||||||
|
const threadSelfPrefix = "/proc/thread-self/attr"
|
||||||
|
|
||||||
|
attrPathOnce.Do(func() {
|
||||||
|
st, err := os.Stat(threadSelfPrefix)
|
||||||
|
if err == nil && st.Mode().IsDir() {
|
||||||
|
haveThreadSelf = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if haveThreadSelf {
|
||||||
|
return path.Join(threadSelfPrefix, attr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.Join("/proc/self/task/", strconv.Itoa(unix.Gettid()), "/attr/", attr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func readAttr(attr string) (string, error) {
|
||||||
|
return readCon(attrPath(attr))
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeAttr(attr, val string) error {
|
||||||
|
return writeCon(attrPath(attr), val)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -382,6 +433,18 @@ func CanonicalizeContext(val string) (string, error) {
|
||||||
return readWriteCon(filepath.Join(getSelinuxMountPoint(), "context"), val)
|
return readWriteCon(filepath.Join(getSelinuxMountPoint(), "context"), val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ComputeCreateContext requests the type transition from source to target for class from the kernel.
|
||||||
|
*/
|
||||||
|
func ComputeCreateContext(source string, target string, class string) (string, error) {
|
||||||
|
classidx, err := ClassIndex(class)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return readWriteCon(filepath.Join(getSelinuxMountPoint(), "create"), fmt.Sprintf("%s %s %d", source, target, classidx))
|
||||||
|
}
|
||||||
|
|
||||||
func readWriteCon(fpath string, val string) (string, error) {
|
func readWriteCon(fpath string, val string) (string, error) {
|
||||||
if fpath == "" {
|
if fpath == "" {
|
||||||
return "", ErrEmptyPath
|
return "", ErrEmptyPath
|
||||||
|
@ -409,7 +472,7 @@ SetExecLabel sets the SELinux label that the kernel will use for any programs
|
||||||
that are executed by the current process thread, or an error.
|
that are executed by the current process thread, or an error.
|
||||||
*/
|
*/
|
||||||
func SetExecLabel(label string) error {
|
func SetExecLabel(label string) error {
|
||||||
return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid()), label)
|
return writeAttr("exec", label)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -417,33 +480,33 @@ SetTaskLabel sets the SELinux label for the current thread, or an error.
|
||||||
This requires the dyntransition permission.
|
This requires the dyntransition permission.
|
||||||
*/
|
*/
|
||||||
func SetTaskLabel(label string) error {
|
func SetTaskLabel(label string) error {
|
||||||
return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/current", syscall.Gettid()), label)
|
return writeAttr("current", label)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSocketLabel takes a process label and tells the kernel to assign the
|
// SetSocketLabel takes a process label and tells the kernel to assign the
|
||||||
// label to the next socket that gets created
|
// label to the next socket that gets created
|
||||||
func SetSocketLabel(label string) error {
|
func SetSocketLabel(label string) error {
|
||||||
return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/sockcreate", syscall.Gettid()), label)
|
return writeAttr("sockcreate", label)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SocketLabel retrieves the current socket label setting
|
// SocketLabel retrieves the current socket label setting
|
||||||
func SocketLabel() (string, error) {
|
func SocketLabel() (string, error) {
|
||||||
return readCon(fmt.Sprintf("/proc/self/task/%d/attr/sockcreate", syscall.Gettid()))
|
return readAttr("sockcreate")
|
||||||
}
|
}
|
||||||
|
|
||||||
// PeerLabel retrieves the label of the client on the other side of a socket
|
// PeerLabel retrieves the label of the client on the other side of a socket
|
||||||
func PeerLabel(fd uintptr) (string, error) {
|
func PeerLabel(fd uintptr) (string, error) {
|
||||||
return unix.GetsockoptString(int(fd), syscall.SOL_SOCKET, syscall.SO_PEERSEC)
|
return unix.GetsockoptString(int(fd), unix.SOL_SOCKET, unix.SO_PEERSEC)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetKeyLabel takes a process label and tells the kernel to assign the
|
// SetKeyLabel takes a process label and tells the kernel to assign the
|
||||||
// label to the next kernel keyring that gets created
|
// label to the next kernel keyring that gets created
|
||||||
func SetKeyLabel(label string) error {
|
func SetKeyLabel(label string) error {
|
||||||
err := writeCon("/proc/self/attr/keycreate", label)
|
err := writeCon("/proc/self/attr/keycreate", label)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(errors.Cause(err)) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if label == "" && os.IsPermission(err) && !GetEnabled() {
|
if label == "" && os.IsPermission(errors.Cause(err)) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
@ -499,19 +562,18 @@ func ReserveLabel(label string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func selinuxEnforcePath() string {
|
func selinuxEnforcePath() string {
|
||||||
return fmt.Sprintf("%s/enforce", getSelinuxMountPoint())
|
return path.Join(getSelinuxMountPoint(), "enforce")
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
|
// EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
|
||||||
func EnforceMode() int {
|
func EnforceMode() int {
|
||||||
var enforce int
|
var enforce int
|
||||||
|
|
||||||
enforceS, err := readCon(selinuxEnforcePath())
|
enforceB, err := ioutil.ReadFile(selinuxEnforcePath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
enforce, err = strconv.Atoi(string(enforceB))
|
||||||
enforce, err = strconv.Atoi(string(enforceS))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
@ -523,7 +585,7 @@ SetEnforceMode sets the current SELinux mode Enforcing, Permissive.
|
||||||
Disabled is not valid, since this needs to be set at boot time.
|
Disabled is not valid, since this needs to be set at boot time.
|
||||||
*/
|
*/
|
||||||
func SetEnforceMode(mode int) error {
|
func SetEnforceMode(mode int) error {
|
||||||
return writeCon(selinuxEnforcePath(), fmt.Sprintf("%d", mode))
|
return ioutil.WriteFile(selinuxEnforcePath(), []byte(strconv.Itoa(mode)), 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -629,23 +691,26 @@ func ROFileLabel() string {
|
||||||
return roFileLabel
|
return roFileLabel
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func openContextFile() (*os.File, error) {
|
||||||
ContainerLabels returns an allocated processLabel and fileLabel to be used for
|
if f, err := os.Open(contextFile); err == nil {
|
||||||
container labeling by the calling process.
|
return f, nil
|
||||||
*/
|
}
|
||||||
func ContainerLabels() (processLabel string, fileLabel string) {
|
lxcPath := filepath.Join(getSELinuxPolicyRoot(), "/contexts/lxc_contexts")
|
||||||
|
return os.Open(lxcPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
var labels = loadLabels()
|
||||||
|
|
||||||
|
func loadLabels() map[string]string {
|
||||||
var (
|
var (
|
||||||
val, key string
|
val, key string
|
||||||
bufin *bufio.Reader
|
bufin *bufio.Reader
|
||||||
)
|
)
|
||||||
|
|
||||||
if !GetEnabled() {
|
labels := make(map[string]string)
|
||||||
return "", ""
|
in, err := openContextFile()
|
||||||
}
|
|
||||||
lxcPath := fmt.Sprintf("%s/contexts/lxc_contexts", getSELinuxPolicyRoot())
|
|
||||||
in, err := os.Open(lxcPath)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", ""
|
return labels
|
||||||
}
|
}
|
||||||
defer in.Close()
|
defer in.Close()
|
||||||
|
|
||||||
|
@ -657,7 +722,7 @@ func ContainerLabels() (processLabel string, fileLabel string) {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
done = true
|
done = true
|
||||||
} else {
|
} else {
|
||||||
goto exit
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
line = strings.TrimSpace(line)
|
line = strings.TrimSpace(line)
|
||||||
|
@ -671,29 +736,67 @@ func ContainerLabels() (processLabel string, fileLabel string) {
|
||||||
}
|
}
|
||||||
if groups := assignRegex.FindStringSubmatch(line); groups != nil {
|
if groups := assignRegex.FindStringSubmatch(line); groups != nil {
|
||||||
key, val = strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2])
|
key, val = strings.TrimSpace(groups[1]), strings.TrimSpace(groups[2])
|
||||||
if key == "process" {
|
labels[key] = strings.Trim(val, "\"")
|
||||||
processLabel = strings.Trim(val, "\"")
|
|
||||||
}
|
|
||||||
if key == "file" {
|
|
||||||
fileLabel = strings.Trim(val, "\"")
|
|
||||||
}
|
|
||||||
if key == "ro_file" {
|
|
||||||
roFileLabel = strings.Trim(val, "\"")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if processLabel == "" || fileLabel == "" {
|
return labels
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
KVMContainerLabels returns the default processLabel and mountLabel to be used
|
||||||
|
for kvm containers by the calling process.
|
||||||
|
*/
|
||||||
|
func KVMContainerLabels() (string, string) {
|
||||||
|
processLabel := labels["kvm_process"]
|
||||||
|
if processLabel == "" {
|
||||||
|
processLabel = labels["process"]
|
||||||
|
}
|
||||||
|
|
||||||
|
return addMcs(processLabel, labels["file"])
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
InitContainerLabels returns the default processLabel and file labels to be
|
||||||
|
used for containers running an init system like systemd by the calling process.
|
||||||
|
*/
|
||||||
|
func InitContainerLabels() (string, string) {
|
||||||
|
processLabel := labels["init_process"]
|
||||||
|
if processLabel == "" {
|
||||||
|
processLabel = labels["process"]
|
||||||
|
}
|
||||||
|
|
||||||
|
return addMcs(processLabel, labels["file"])
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ContainerLabels returns an allocated processLabel and fileLabel to be used for
|
||||||
|
container labeling by the calling process.
|
||||||
|
*/
|
||||||
|
func ContainerLabels() (processLabel string, fileLabel string) {
|
||||||
|
if !GetEnabled() {
|
||||||
return "", ""
|
return "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
processLabel = labels["process"]
|
||||||
|
fileLabel = labels["file"]
|
||||||
|
roFileLabel = labels["ro_file"]
|
||||||
|
|
||||||
|
if processLabel == "" || fileLabel == "" {
|
||||||
|
return "", fileLabel
|
||||||
|
}
|
||||||
|
|
||||||
if roFileLabel == "" {
|
if roFileLabel == "" {
|
||||||
roFileLabel = fileLabel
|
roFileLabel = fileLabel
|
||||||
}
|
}
|
||||||
exit:
|
|
||||||
|
return addMcs(processLabel, fileLabel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func addMcs(processLabel, fileLabel string) (string, string) {
|
||||||
scon, _ := NewContext(processLabel)
|
scon, _ := NewContext(processLabel)
|
||||||
if scon["level"] != "" {
|
if scon["level"] != "" {
|
||||||
mcs := uniqMcs(1024)
|
mcs := uniqMcs(CategoryRange)
|
||||||
scon["level"] = mcs
|
scon["level"] = mcs
|
||||||
processLabel = scon.Get()
|
processLabel = scon.Get()
|
||||||
scon, _ = NewContext(fileLabel)
|
scon, _ = NewContext(fileLabel)
|
||||||
|
@ -705,7 +808,7 @@ exit:
|
||||||
|
|
||||||
// SecurityCheckContext validates that the SELinux label is understood by the kernel
|
// SecurityCheckContext validates that the SELinux label is understood by the kernel
|
||||||
func SecurityCheckContext(val string) error {
|
func SecurityCheckContext(val string) error {
|
||||||
return writeCon(fmt.Sprintf("%s/context", getSelinuxMountPoint()), val)
|
return ioutil.WriteFile(path.Join(getSelinuxMountPoint(), "context"), []byte(val), 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -745,14 +848,14 @@ func badPrefix(fpath string) error {
|
||||||
badPrefixes := []string{"/usr"}
|
badPrefixes := []string{"/usr"}
|
||||||
for _, prefix := range badPrefixes {
|
for _, prefix := range badPrefixes {
|
||||||
if strings.HasPrefix(fpath, prefix) {
|
if strings.HasPrefix(fpath, prefix) {
|
||||||
return fmt.Errorf("relabeling content in %s is not allowed", prefix)
|
return errors.Errorf("relabeling content in %s is not allowed", prefix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chcon changes the `fpath` file object to the SELinux label `label`.
|
// Chcon changes the fpath file object to the SELinux label label.
|
||||||
// If `fpath` is a directory and `recurse`` is true, Chcon will walk the
|
// If fpath is a directory and recurse is true, Chcon will walk the
|
||||||
// directory tree setting the label.
|
// directory tree setting the label.
|
||||||
func Chcon(fpath string, label string, recurse bool) error {
|
func Chcon(fpath string, label string, recurse bool) error {
|
||||||
if fpath == "" {
|
if fpath == "" {
|
||||||
|
@ -764,19 +867,19 @@ func Chcon(fpath string, label string, recurse bool) error {
|
||||||
if err := badPrefix(fpath); err != nil {
|
if err := badPrefix(fpath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
callback := func(p string, info os.FileInfo, err error) error {
|
|
||||||
|
if !recurse {
|
||||||
|
return SetFileLabel(fpath, label)
|
||||||
|
}
|
||||||
|
|
||||||
|
return pwalk.Walk(fpath, func(p string, info os.FileInfo, err error) error {
|
||||||
e := SetFileLabel(p, label)
|
e := SetFileLabel(p, label)
|
||||||
if os.IsNotExist(e) {
|
// Walk a file tree can race with removal, so ignore ENOENT
|
||||||
|
if os.IsNotExist(errors.Cause(e)) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return e
|
return e
|
||||||
}
|
})
|
||||||
|
|
||||||
if recurse {
|
|
||||||
return filepath.Walk(fpath, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
return SetFileLabel(fpath, label)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DupSecOpt takes an SELinux process label and returns security options that
|
// DupSecOpt takes an SELinux process label and returns security options that
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// +build !selinux
|
// +build !selinux !linux
|
||||||
|
|
||||||
package selinux
|
package selinux
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ const (
|
||||||
Permissive = 0
|
Permissive = 0
|
||||||
// Disabled constant to indicate SELinux is disabled
|
// Disabled constant to indicate SELinux is disabled
|
||||||
Disabled = -1
|
Disabled = -1
|
||||||
|
// DefaultCategoryRange is the upper bound on the category range
|
||||||
|
DefaultCategoryRange = uint32(1024)
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -20,6 +22,8 @@ var (
|
||||||
ErrMCSAlreadyExists = errors.New("MCS label already exists")
|
ErrMCSAlreadyExists = errors.New("MCS label already exists")
|
||||||
// ErrEmptyPath is returned when an empty path has been specified.
|
// ErrEmptyPath is returned when an empty path has been specified.
|
||||||
ErrEmptyPath = errors.New("empty path")
|
ErrEmptyPath = errors.New("empty path")
|
||||||
|
// CategoryRange allows the upper bound on the category range to be adjusted
|
||||||
|
CategoryRange = DefaultCategoryRange
|
||||||
)
|
)
|
||||||
|
|
||||||
// Context is a representation of the SELinux label broken into 4 parts
|
// Context is a representation of the SELinux label broken into 4 parts
|
||||||
|
@ -35,6 +39,11 @@ func GetEnabled() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClassIndex returns the int index for an object class in the loaded policy, or -1 and an error
|
||||||
|
func ClassIndex(class string) (int, error) {
|
||||||
|
return -1, nil
|
||||||
|
}
|
||||||
|
|
||||||
// SetFileLabel sets the SELinux label for this path or returns an error.
|
// SetFileLabel sets the SELinux label for this path or returns an error.
|
||||||
func SetFileLabel(fpath string, label string) error {
|
func SetFileLabel(fpath string, label string) error {
|
||||||
return nil
|
return nil
|
||||||
|
@ -88,6 +97,13 @@ func CanonicalizeContext(val string) (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ComputeCreateContext requests the type transition from source to target for class from the kernel.
|
||||||
|
*/
|
||||||
|
func ComputeCreateContext(source string, target string, class string) (string, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SetExecLabel sets the SELinux label that the kernel will use for any programs
|
SetExecLabel sets the SELinux label that the kernel will use for any programs
|
||||||
that are executed by the current process thread, or an error.
|
that are executed by the current process thread, or an error.
|
||||||
|
@ -189,6 +205,18 @@ func ROFileLabel() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KVMContainerLabels returns the default processLabel and mountLabel to be used
|
||||||
|
// for kvm containers by the calling process.
|
||||||
|
func KVMContainerLabels() (string, string) {
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitContainerLabels returns the default processLabel and file labels to be
|
||||||
|
// used for containers running an init system like systemd by the calling
|
||||||
|
func InitContainerLabels() (string, string) {
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ContainerLabels returns an allocated processLabel and fileLabel to be used for
|
ContainerLabels returns an allocated processLabel and fileLabel to be used for
|
||||||
container labeling by the calling process.
|
container labeling by the calling process.
|
||||||
|
|
|
@ -3,76 +3,28 @@
|
||||||
package selinux
|
package selinux
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"syscall"
|
"golang.org/x/sys/unix"
|
||||||
"unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _zero uintptr
|
|
||||||
|
|
||||||
// Returns a []byte slice if the xattr is set and nil otherwise
|
// Returns a []byte slice if the xattr is set and nil otherwise
|
||||||
// Requires path and its attribute as arguments
|
// Requires path and its attribute as arguments
|
||||||
func lgetxattr(path string, attr string) ([]byte, error) {
|
func lgetxattr(path string, attr string) ([]byte, error) {
|
||||||
var sz int
|
|
||||||
pathBytes, err := syscall.BytePtrFromString(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
attrBytes, err := syscall.BytePtrFromString(attr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start with a 128 length byte array
|
// Start with a 128 length byte array
|
||||||
sz = 128
|
dest := make([]byte, 128)
|
||||||
dest := make([]byte, sz)
|
sz, errno := unix.Lgetxattr(path, attr, dest)
|
||||||
destBytes := unsafe.Pointer(&dest[0])
|
for errno == unix.ERANGE {
|
||||||
_sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
|
// Buffer too small, use zero-sized buffer to get the actual size
|
||||||
|
sz, errno = unix.Lgetxattr(path, attr, []byte{})
|
||||||
|
if errno != nil {
|
||||||
|
return nil, errno
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
|
||||||
case errno == syscall.ENODATA:
|
|
||||||
return nil, errno
|
|
||||||
case errno == syscall.ENOTSUP:
|
|
||||||
return nil, errno
|
|
||||||
case errno == syscall.ERANGE:
|
|
||||||
// 128 byte array might just not be good enough,
|
|
||||||
// A dummy buffer is used ``uintptr(0)`` to get real size
|
|
||||||
// of the xattrs on disk
|
|
||||||
_sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(unsafe.Pointer(nil)), uintptr(0), 0, 0)
|
|
||||||
sz = int(_sz)
|
|
||||||
if sz < 0 {
|
|
||||||
return nil, errno
|
|
||||||
}
|
|
||||||
dest = make([]byte, sz)
|
dest = make([]byte, sz)
|
||||||
destBytes := unsafe.Pointer(&dest[0])
|
sz, errno = unix.Lgetxattr(path, attr, dest)
|
||||||
_sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
|
}
|
||||||
if errno != 0 {
|
if errno != nil {
|
||||||
return nil, errno
|
return nil, errno
|
||||||
}
|
}
|
||||||
case errno != 0:
|
|
||||||
return nil, errno
|
|
||||||
}
|
|
||||||
sz = int(_sz)
|
|
||||||
return dest[:sz], nil
|
return dest[:sz], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func lsetxattr(path string, attr string, data []byte, flags int) error {
|
|
||||||
pathBytes, err := syscall.BytePtrFromString(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
attrBytes, err := syscall.BytePtrFromString(attr)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var dataBytes unsafe.Pointer
|
|
||||||
if len(data) > 0 {
|
|
||||||
dataBytes = unsafe.Pointer(&data[0])
|
|
||||||
} else {
|
|
||||||
dataBytes = unsafe.Pointer(&_zero)
|
|
||||||
}
|
|
||||||
_, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0)
|
|
||||||
if errno != 0 {
|
|
||||||
return errno
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
## pwalk: parallel implementation of filepath.Walk
|
||||||
|
|
||||||
|
This is a wrapper for [filepath.Walk](https://pkg.go.dev/path/filepath?tab=doc#Walk)
|
||||||
|
which may speed it up by calling multiple callback functions (WalkFunc) in parallel,
|
||||||
|
utilizing goroutines.
|
||||||
|
|
||||||
|
By default, it utilizes 2\*runtime.NumCPU() goroutines for callbacks.
|
||||||
|
This can be changed by using WalkN function which has the additional
|
||||||
|
parameter, specifying the number of goroutines (concurrency).
|
||||||
|
|
||||||
|
### Caveats
|
||||||
|
|
||||||
|
Please note the following limitations of this code:
|
||||||
|
|
||||||
|
* Unlike filepath.Walk, the order of calls is non-deterministic;
|
||||||
|
|
||||||
|
* Only primitive error handling is supported:
|
||||||
|
|
||||||
|
* filepath.SkipDir is not supported;
|
||||||
|
|
||||||
|
* no errors are ever passed to WalkFunc;
|
||||||
|
|
||||||
|
* once any error is returned from any WalkFunc instance, no more new calls
|
||||||
|
to WalkFunc are made, and the error is returned to the caller of Walk;
|
||||||
|
|
||||||
|
* if more than one walkFunc instance will return an error, only one
|
||||||
|
of such errors will be propagated and returned by Walk, others
|
||||||
|
will be silently discarded.
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
For the official documentation, see
|
||||||
|
https://pkg.go.dev/github.com/opencontainers/selinux/pkg/pwalk?tab=doc
|
||||||
|
|
||||||
|
### Benchmarks
|
||||||
|
|
||||||
|
For a WalkFunc that consists solely of the return statement, this
|
||||||
|
implementation is about 10% slower than the standard library's
|
||||||
|
filepath.Walk.
|
||||||
|
|
||||||
|
Otherwise (if a WalkFunc is doing something) this is usually faster,
|
||||||
|
except when the WalkN(..., 1) is used.
|
|
@ -0,0 +1,99 @@
|
||||||
|
package pwalk
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WalkFunc = filepath.WalkFunc
|
||||||
|
|
||||||
|
// Walk is a wrapper for filepath.Walk which can call multiple walkFn
|
||||||
|
// in parallel, allowing to handle each item concurrently. A maximum of
|
||||||
|
// twice the runtime.NumCPU() walkFn will be called at any one time.
|
||||||
|
// If you want to change the maximum, use WalkN instead.
|
||||||
|
//
|
||||||
|
// The order of calls is non-deterministic.
|
||||||
|
//
|
||||||
|
// Note that this implementation only supports primitive error handling:
|
||||||
|
//
|
||||||
|
// * no errors are ever passed to WalkFn
|
||||||
|
//
|
||||||
|
// * once a walkFn returns any error, all further processing stops
|
||||||
|
// and the error is returned to the caller of Walk;
|
||||||
|
//
|
||||||
|
// * filepath.SkipDir is not supported;
|
||||||
|
//
|
||||||
|
// * if more than one walkFn instance will return an error, only one
|
||||||
|
// of such errors will be propagated and returned by Walk, others
|
||||||
|
// will be silently discarded.
|
||||||
|
//
|
||||||
|
func Walk(root string, walkFn WalkFunc) error {
|
||||||
|
return WalkN(root, walkFn, runtime.NumCPU()*2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WalkN is a wrapper for filepath.Walk which can call multiple walkFn
|
||||||
|
// in parallel, allowing to handle each item concurrently. A maximum of
|
||||||
|
// num walkFn will be called at any one time.
|
||||||
|
func WalkN(root string, walkFn WalkFunc, num int) error {
|
||||||
|
// make sure limit is sensible
|
||||||
|
if num < 1 {
|
||||||
|
return errors.Errorf("walk(%q): num must be > 0", root)
|
||||||
|
}
|
||||||
|
|
||||||
|
files := make(chan *walkArgs, 2*num)
|
||||||
|
errCh := make(chan error, 1) // get the first error, ignore others
|
||||||
|
|
||||||
|
// Start walking a tree asap
|
||||||
|
var err error
|
||||||
|
go func() {
|
||||||
|
err = filepath.Walk(root, func(p string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
close(files)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// add a file to the queue unless a callback sent an error
|
||||||
|
select {
|
||||||
|
case e := <-errCh:
|
||||||
|
close(files)
|
||||||
|
return e
|
||||||
|
default:
|
||||||
|
files <- &walkArgs{path: p, info: &info}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if err == nil {
|
||||||
|
close(files)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(num)
|
||||||
|
for i := 0; i < num; i++ {
|
||||||
|
go func() {
|
||||||
|
for file := range files {
|
||||||
|
if e := walkFn(file.path, *file.info, nil); e != nil {
|
||||||
|
select {
|
||||||
|
case errCh <- e: // sent ok
|
||||||
|
default: // buffer full
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// walkArgs holds the arguments that were passed to the Walk or WalkLimit
|
||||||
|
// functions.
|
||||||
|
type walkArgs struct {
|
||||||
|
path string
|
||||||
|
info *os.FileInfo
|
||||||
|
}
|
|
@ -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.6 => github.com/rancher/containerd v1.3.6-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
|
||||||
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.6
|
# github.com/containerd/cri v0.0.0-00010101000000-000000000000 => github.com/rancher/cri v1.3.0-k3s.7
|
||||||
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
|
||||||
|
@ -318,9 +318,9 @@ github.com/containerd/cri/pkg/store/snapshot
|
||||||
github.com/containerd/cri/pkg/util
|
github.com/containerd/cri/pkg/util
|
||||||
# github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c
|
# github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c
|
||||||
github.com/containerd/fifo
|
github.com/containerd/fifo
|
||||||
# github.com/containerd/go-cni v0.0.0-20190904155053-d20b7eebc7ee
|
# github.com/containerd/go-cni v0.0.0-20190813230227-49fbd9b210f3
|
||||||
github.com/containerd/go-cni
|
github.com/containerd/go-cni
|
||||||
# github.com/containerd/go-runc v0.0.0-20190923131748-a2952bc25f51 => github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda
|
# github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda
|
||||||
github.com/containerd/go-runc
|
github.com/containerd/go-runc
|
||||||
# github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8
|
# github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8
|
||||||
github.com/containerd/ttrpc
|
github.com/containerd/ttrpc
|
||||||
|
@ -595,6 +595,10 @@ github.com/grpc-ecosystem/go-grpc-prometheus
|
||||||
github.com/grpc-ecosystem/grpc-gateway/internal
|
github.com/grpc-ecosystem/grpc-gateway/internal
|
||||||
github.com/grpc-ecosystem/grpc-gateway/runtime
|
github.com/grpc-ecosystem/grpc-gateway/runtime
|
||||||
github.com/grpc-ecosystem/grpc-gateway/utilities
|
github.com/grpc-ecosystem/grpc-gateway/utilities
|
||||||
|
# github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce
|
||||||
|
github.com/hashicorp/errwrap
|
||||||
|
# github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874
|
||||||
|
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
|
||||||
|
@ -692,9 +696,10 @@ github.com/opencontainers/runc/libcontainer/utils
|
||||||
github.com/opencontainers/runc/types
|
github.com/opencontainers/runc/types
|
||||||
# github.com/opencontainers/runtime-spec v1.0.0 => github.com/opencontainers/runtime-spec v0.0.0-20180911193056-5684b8af48c1
|
# github.com/opencontainers/runtime-spec v1.0.0 => github.com/opencontainers/runtime-spec v0.0.0-20180911193056-5684b8af48c1
|
||||||
github.com/opencontainers/runtime-spec/specs-go
|
github.com/opencontainers/runtime-spec/specs-go
|
||||||
# github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52
|
# github.com/opencontainers/selinux v1.5.3-0.20200613095409-bb88c45a3863
|
||||||
github.com/opencontainers/selinux/go-selinux
|
github.com/opencontainers/selinux/go-selinux
|
||||||
github.com/opencontainers/selinux/go-selinux/label
|
github.com/opencontainers/selinux/go-selinux/label
|
||||||
|
github.com/opencontainers/selinux/pkg/pwalk
|
||||||
# github.com/peterbourgon/diskv v2.0.1+incompatible
|
# github.com/peterbourgon/diskv v2.0.1+incompatible
|
||||||
github.com/peterbourgon/diskv
|
github.com/peterbourgon/diskv
|
||||||
# github.com/pkg/errors v0.9.1
|
# github.com/pkg/errors v0.9.1
|
||||||
|
|
Loading…
Reference in New Issue