diff --git a/cmd/containerd/builtins/builtins.go b/cmd/containerd/builtins/builtins.go index 3e64dcea5..5fdbfcab7 100644 --- a/cmd/containerd/builtins/builtins.go +++ b/cmd/containerd/builtins/builtins.go @@ -23,6 +23,7 @@ import ( _ "github.com/containerd/containerd/gc/scheduler" _ "github.com/containerd/containerd/leases/plugin" _ "github.com/containerd/containerd/metadata/plugin" + _ "github.com/containerd/containerd/pkg/nri/plugin" _ "github.com/containerd/containerd/runtime/restart/monitor" _ "github.com/containerd/containerd/runtime/v2" _ "github.com/containerd/containerd/services/containers" diff --git a/go.mod b/go.mod index b92d242c6..1d4879e1e 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,9 @@ require ( github.com/containerd/go-cni v1.1.6 github.com/containerd/go-runc v1.0.0 github.com/containerd/imgcrypt v1.1.5-0.20220421044638-8ba028dca028 - github.com/containerd/nri v0.1.0 + // We need an NRI with the updated interface. We use a replace to + // divert it until the corresponding PR lands in the NRI repo. + github.com/containerd/nri v0.2.0 github.com/containerd/ttrpc v1.1.1-0.20220420014843-944ef4a40df3 github.com/containerd/typeurl v1.0.3-0.20220422153119-7f6e6d160d67 github.com/containerd/zfs v1.0.0 @@ -47,7 +49,7 @@ require ( github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b github.com/opencontainers/runc v1.1.4 - github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 + github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb github.com/opencontainers/selinux v1.10.2 github.com/pelletier/go-toml v1.9.3 github.com/prometheus/client_golang v1.12.1 @@ -82,7 +84,6 @@ require ( require ( cloud.google.com/go/compute/metadata v0.2.1 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/blang/semver v3.5.1+incompatible // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect @@ -106,7 +107,9 @@ require ( github.com/moby/spdystream v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/opencontainers/runtime-tools v0.0.0-20190417131837-cd1349b7c47e // indirect + // ATM the runtime-tools commit we need are beyond the latest tag. + // We use a replace to handle that until a new version is tagged. + github.com/opencontainers/runtime-tools v0.9.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect @@ -117,9 +120,6 @@ require ( github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 // indirect github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 // indirect go.opencensus.io v0.23.0 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1 // indirect @@ -131,7 +131,7 @@ require ( golang.org/x/term v0.1.0 // indirect golang.org/x/text v0.4.0 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect - golang.org/x/tools v0.1.13-0.20221007141809-02bef08ac854 // indirect + golang.org/x/tools v0.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect @@ -141,3 +141,9 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) + +replace ( + // Temporarily divert repo for updated/extended NRI. + github.com/containerd/nri => github.com/klihub/nri v0.0.0-20221122201439-2b09b4ad5cf3 + github.com/opencontainers/runtime-tools => github.com/opencontainers/runtime-tools v0.0.0-20221026201742-946c877fa809 +) diff --git a/go.sum b/go.sum index 87a85d9e1..a9db4ec51 100644 --- a/go.sum +++ b/go.sum @@ -76,6 +76,7 @@ github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JP github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= @@ -89,6 +90,7 @@ github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwT github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= +github.com/Microsoft/hcsshim v0.9.4/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= github.com/Microsoft/hcsshim v0.10.0-rc.1 h1:Lms8jwpaIdIUvoBNee8ZuvIi1XnNy9uvnxSC9L1q1x4= github.com/Microsoft/hcsshim v0.10.0-rc.1/go.mod h1:7XX96hdvnwWGdXnksDNdhfFcUH1BtQY6bL2L3f9Abyk= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= @@ -129,7 +131,6 @@ github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngE github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= @@ -173,6 +174,7 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= @@ -192,7 +194,6 @@ github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2v github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI= github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= -github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= @@ -213,7 +214,6 @@ github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go. github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= @@ -225,6 +225,7 @@ github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTV github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s= github.com/containerd/containerd v1.6.1/go.mod h1:1nJz5xCZPusx6jJU8Frfct988y0NpumIq9ODB0kLtoE= +github.com/containerd/containerd v1.6.9/go.mod h1:XVicUvkxOrftE2Q1YWUXgZwkkAxwQYNOFzYWvfVfEfQ= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -237,7 +238,6 @@ github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvA github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= -github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= github.com/containerd/fifo v1.0.0 h1:6PirWBr9/L7GDamKr+XM0IeUFXu5mf3M/BPpH9gaLBU= @@ -259,12 +259,9 @@ github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6T github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow= github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms= github.com/containerd/imgcrypt v1.1.3/go.mod h1:/TPA1GIDXMzbj01yd8pIbQiLdQxed5ue1wb8bP7PQu4= +github.com/containerd/imgcrypt v1.1.4/go.mod h1:LorQnPtzL/T0IyCeftcsMEO7AqxUDbdO8j/tSUpgxvo= github.com/containerd/imgcrypt v1.1.5-0.20220421044638-8ba028dca028 h1:CqFTne8EGv2eAWAS0O6weGE5RtP0Q8XiFUdkDT840Yc= github.com/containerd/imgcrypt v1.1.5-0.20220421044638-8ba028dca028/go.mod h1:LorQnPtzL/T0IyCeftcsMEO7AqxUDbdO8j/tSUpgxvo= -github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= -github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= -github.com/containerd/nri v0.1.0 h1:6QioHRlThlKh2RkRTR4kIT3PKAcrLo3gIWnjkM4dQmQ= -github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= @@ -377,6 +374,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -504,6 +502,7 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= @@ -624,6 +623,8 @@ github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klihub/nri v0.0.0-20221122201439-2b09b4ad5cf3 h1:8V9PThT2f1pBaGz0lSJ6EtLnIuxKEz5utRh1/8tHD0U= +github.com/klihub/nri v0.0.0-20221122201439-2b09b4ad5cf3/go.mod h1:Q2u9Sudol4IkJ6YK0gShznKMxM6Un0Y3O4Wslf5Nerg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -674,6 +675,7 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= +github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= @@ -709,6 +711,7 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= +github.com/networkplumbing/go-nft v0.2.0/go.mod h1:HnnM+tYvlGAsMU7yoYwXEVLLiDW9gdMmb5HoGcwpuQs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= @@ -729,7 +732,12 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0 h1:TRtrvv2vdQqzkwrQ1ke6vtXf7IK34RBUJafIy1wMwls= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -740,7 +748,12 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -751,15 +764,16 @@ github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= +github.com/opencontainers/runc v1.1.2/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= github.com/opencontainers/runc v1.1.4 h1:nRCz/8sKg6K6jgYAFLDlXzPeITBZJyX28DBVhWD+5dg= github.com/opencontainers/runc v1.1.4/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -767,15 +781,16 @@ github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/ github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -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-20190417131837-cd1349b7c47e h1:2Tg49TNXSTIsX8AAtmo1aQ1IbfnoUFzkOp7p2iWygtc= -github.com/opencontainers/runtime-tools v0.0.0-20190417131837-cd1349b7c47e/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= -github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= +github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb h1:1xSVPOd7/UA+39/hXEGnBJ13p6JFB0E1EvQFlrRDOXI= +github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-tools v0.0.0-20221026201742-946c877fa809 h1:WSwkWIIS4s+E/dPF6HuVZ/hnq1WfXN371eESjREnU8k= +github.com/opencontainers/runtime-tools v0.0.0-20221026201742-946c877fa809/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI= github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/opencontainers/selinux v1.10.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opencontainers/selinux v1.10.2 h1:NFy2xCsjn7+WspbfZkUd5zyVeisV7VFbPSP96+8/ha4= github.com/opencontainers/selinux v1.10.2/go.mod h1:cARutUbaUrlRClyvxOICCgKixCs6L05aUsohzA3EkHQ= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -801,6 +816,7 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -916,6 +932,7 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1 github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.19.1/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -931,7 +948,6 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -947,6 +963,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= @@ -1038,6 +1056,8 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1075,6 +1095,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1131,8 +1153,14 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.1.1-0.20221027164007-c63010009c80 h1:CtRWmqbiPSOXwJV1JoY7pWiTx2xzVKQ813bvU+Y/9jI= golang.org/x/net v0.1.1-0.20221027164007-c63010009c80/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1161,6 +1189,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1256,19 +1285,26 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220405210540-1e041c57c461/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1355,9 +1391,12 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.13-0.20221007141809-02bef08ac854 h1:fzDvmJnoyma87dC7IBnNQWmMZNalsNrtiY1X6PwmME0= -golang.org/x/tools v0.1.13-0.20221007141809-02bef08ac854/go.mod h1:VsjNM1dMo+Ofkp5d7y7fOdQZD8MTXSQ4w3EPk65AvKU= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1443,6 +1482,7 @@ google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxH google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20221107162902-2d387536bcdd h1:1eV6KuDTxraYYsYGWksp1thEGP+8dtX/TINL9h+ppiI= google.golang.org/genproto v0.0.0-20221107162902-2d387536bcdd/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= @@ -1473,6 +1513,8 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1488,6 +1530,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= @@ -1576,6 +1619,8 @@ k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= k8s.io/cri-api v0.23.1/go.mod h1:REJE3PSU0h/LOV1APBrupxrEJqnoxZC8KWzkBUHwrK4= +k8s.io/cri-api v0.25.0/go.mod h1:J1rAyQkSJ2Q6I+aBMOVgg2/cbbebso6FNa0UagiR0kc= +k8s.io/cri-api v0.25.3/go.mod h1:riC/P0yOGUf2K1735wW+CXs1aY2ctBgePtnnoFLd0dU= k8s.io/cri-api v0.26.0-beta.0 h1:mVt2/80VZy2dRN4mpVYJbPB9L/Zt/EvVev++zPTV9Tw= k8s.io/cri-api v0.26.0-beta.0/go.mod h1:E49tenyB7esgfIguEd7+g9qYhHOr9peyyBcSaeH6Gxw= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= diff --git a/integration/client/go.mod b/integration/client/go.mod index 9a669026a..f6a66bb66 100644 --- a/integration/client/go.mod +++ b/integration/client/go.mod @@ -13,7 +13,7 @@ require ( github.com/containerd/typeurl v1.0.3-0.20220422153119-7f6e6d160d67 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b - github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 + github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb github.com/sirupsen/logrus v1.9.0 github.com/stretchr/testify v1.8.0 golang.org/x/sys v0.2.0 @@ -58,7 +58,7 @@ require ( golang.org/x/net v0.1.1-0.20221027164007-c63010009c80 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/text v0.4.0 // indirect - golang.org/x/tools v0.1.13-0.20221007141809-02bef08ac854 // indirect + golang.org/x/tools v0.2.0 // indirect google.golang.org/genproto v0.0.0-20221107162902-2d387536bcdd // indirect google.golang.org/grpc v1.50.1 // indirect google.golang.org/protobuf v1.28.1 // indirect @@ -70,4 +70,10 @@ require ( // IMPORTANT: this replace rule ONLY replaces containerd itself; dependencies // in the "require" section above are still taken into account for version // resolution if newer. -replace github.com/containerd/containerd => ../../ +replace ( + github.com/containerd/containerd => ../../ + + // Temporarily divert repo for updated/extended NRI. + github.com/containerd/nri => github.com/klihub/nri v0.0.0-20221122201439-2b09b4ad5cf3 + github.com/opencontainers/runtime-tools => github.com/opencontainers/runtime-tools v0.0.0-20221026201742-946c877fa809 +) diff --git a/integration/client/go.sum b/integration/client/go.sum index 7fc59b613..d67dc334c 100644 --- a/integration/client/go.sum +++ b/integration/client/go.sum @@ -390,6 +390,7 @@ github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2B github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= +github.com/Microsoft/hcsshim v0.9.4/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= github.com/Microsoft/hcsshim v0.10.0-rc.1 h1:Lms8jwpaIdIUvoBNee8ZuvIi1XnNy9uvnxSC9L1q1x4= github.com/Microsoft/hcsshim v0.10.0-rc.1/go.mod h1:7XX96hdvnwWGdXnksDNdhfFcUH1BtQY6bL2L3f9Abyk= github.com/Microsoft/hcsshim/test v0.0.0-20210408205431-da33ecd607e1 h1:pVKfKyPkXna29XlGjxSr9J0A7vNucOUHZ/2ClcTWalw= @@ -485,7 +486,6 @@ github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0Z github.com/containerd/go-runc v1.0.0 h1:oU+lLv1ULm5taqgV/CJivypVODI4SUz1znWjv3nNYS0= github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= github.com/containerd/imgcrypt v1.1.5-0.20220421044638-8ba028dca028/go.mod h1:LorQnPtzL/T0IyCeftcsMEO7AqxUDbdO8j/tSUpgxvo= -github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM= github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ= @@ -611,6 +611,7 @@ github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -779,8 +780,10 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klihub/nri v0.0.0-20221122201439-2b09b4ad5cf3/go.mod h1:Q2u9Sudol4IkJ6YK0gShznKMxM6Un0Y3O4Wslf5Nerg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -824,6 +827,7 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= @@ -833,6 +837,7 @@ github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vyg github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI= github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= @@ -865,6 +870,9 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -874,10 +882,14 @@ github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+t github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= @@ -888,12 +900,14 @@ github.com/opencontainers/runc v1.1.4/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJ github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -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-20190417131837-cd1349b7c47e/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= +github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb h1:1xSVPOd7/UA+39/hXEGnBJ13p6JFB0E1EvQFlrRDOXI= +github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-tools v0.0.0-20221026201742-946c877fa809/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI= github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/opencontainers/selinux v1.10.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opencontainers/selinux v1.10.2 h1:NFy2xCsjn7+WspbfZkUd5zyVeisV7VFbPSP96+8/ha4= github.com/opencontainers/selinux v1.10.2/go.mod h1:cARutUbaUrlRClyvxOICCgKixCs6L05aUsohzA3EkHQ= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -1011,6 +1025,7 @@ github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwD github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/urfave/cli v1.19.1/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -1452,8 +1467,9 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.1.13-0.20221007141809-02bef08ac854 h1:fzDvmJnoyma87dC7IBnNQWmMZNalsNrtiY1X6PwmME0= golang.org/x/tools v0.1.13-0.20221007141809-02bef08ac854/go.mod h1:VsjNM1dMo+Ofkp5d7y7fOdQZD8MTXSQ4w3EPk65AvKU= +golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1736,6 +1752,7 @@ k8s.io/client-go v0.25.4/go.mod h1:8trHCAC83XKY0wsBIpbirZU4NTUpbuhc2JnI7OruGZw= k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= k8s.io/component-base v0.25.4/go.mod h1:nnZJU8OP13PJEm6/p5V2ztgX2oyteIaAGKGMYb2L2cY= k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.25.3/go.mod h1:riC/P0yOGUf2K1735wW+CXs1aY2ctBgePtnnoFLd0dU= k8s.io/cri-api v0.26.0-beta.0/go.mod h1:E49tenyB7esgfIguEd7+g9qYhHOr9peyyBcSaeH6Gxw= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= diff --git a/pkg/nri/config.go b/pkg/nri/config.go new file mode 100644 index 000000000..06d31436a --- /dev/null +++ b/pkg/nri/config.go @@ -0,0 +1,58 @@ +/* + 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 nri + +import ( + nri "github.com/containerd/nri/pkg/adaptation" +) + +// Config data for NRI. +type Config struct { + // Disable this NRI plugin and containerd NRI functionality altogether. + Disable bool `toml:"disable" json:"disable"` + // ConfigPath is the path to the NRI configuration file to use. + ConfigPath string `toml:"config_file" json:"configFile"` + // SocketPath is the path to the NRI socket to create for NRI plugins to connect to. + SocketPath string `toml:"socket_path" json:"socketPath"` + // PluginPath is the path to search for NRI plugins to launch on startup. + PluginPath string `toml:"plugin_path" json:"pluginPath"` +} + +// DefaultConfig returns the default configuration. +func DefaultConfig() *Config { + return &Config{ + Disable: true, + ConfigPath: nri.DefaultConfigPath, + SocketPath: nri.DefaultSocketPath, + PluginPath: nri.DefaultPluginPath, + } +} + +// toOptions returns NRI options for this configuration. +func (c *Config) toOptions() []nri.Option { + opts := []nri.Option{} + if c.ConfigPath != "" { + opts = append(opts, nri.WithConfigPath(c.ConfigPath)) + } + if c.SocketPath != "" { + opts = append(opts, nri.WithSocketPath(c.SocketPath)) + } + if c.PluginPath != "" { + opts = append(opts, nri.WithPluginPath(c.PluginPath)) + } + return opts +} diff --git a/pkg/nri/container.go b/pkg/nri/container.go new file mode 100644 index 000000000..076fa8522 --- /dev/null +++ b/pkg/nri/container.go @@ -0,0 +1,72 @@ +/* + 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 nri + +import ( + nri "github.com/containerd/nri/pkg/adaptation" +) + +// Container interface for interacting with NRI. +type Container interface { + GetDomain() string + + GetPodSandboxID() string + GetID() string + GetName() string + GetState() nri.ContainerState + GetLabels() map[string]string + GetAnnotations() map[string]string + GetArgs() []string + GetEnv() []string + GetMounts() []*nri.Mount + GetHooks() *nri.Hooks + GetLinuxContainer() LinuxContainer + + GetPid() uint32 +} + +type LinuxContainer interface { + GetLinuxNamespaces() []*nri.LinuxNamespace + GetLinuxDevices() []*nri.LinuxDevice + GetLinuxResources() *nri.LinuxResources + GetOOMScoreAdj() *int + GetCgroupsPath() string +} + +func commonContainerToNRI(ctr Container) *nri.Container { + return &nri.Container{ + Id: ctr.GetID(), + PodSandboxId: ctr.GetPodSandboxID(), + Name: ctr.GetName(), + State: ctr.GetState(), + Labels: ctr.GetLabels(), + Annotations: ctr.GetAnnotations(), + Args: ctr.GetArgs(), + Env: ctr.GetEnv(), + Mounts: ctr.GetMounts(), + Hooks: ctr.GetHooks(), + Pid: ctr.GetPid(), + } +} + +func containersToNRI(ctrList []Container) []*nri.Container { + ctrs := []*nri.Container{} + for _, ctr := range ctrList { + ctrs = append(ctrs, containerToNRI(ctr)) + } + return ctrs +} diff --git a/pkg/nri/container_linux.go b/pkg/nri/container_linux.go new file mode 100644 index 000000000..0632b6dc0 --- /dev/null +++ b/pkg/nri/container_linux.go @@ -0,0 +1,37 @@ +//go:build linux +// +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 nri + +import ( + nri "github.com/containerd/nri/pkg/adaptation" +) + +func containerToNRI(ctr Container) *nri.Container { + nriCtr := commonContainerToNRI(ctr) + lnxCtr := ctr.GetLinuxContainer() + nriCtr.Linux = &nri.LinuxContainer{ + Namespaces: lnxCtr.GetLinuxNamespaces(), + Devices: lnxCtr.GetLinuxDevices(), + Resources: lnxCtr.GetLinuxResources(), + OomScoreAdj: nri.Int(lnxCtr.GetOOMScoreAdj()), + CgroupsPath: lnxCtr.GetCgroupsPath(), + } + return nriCtr +} diff --git a/pkg/nri/container_other.go b/pkg/nri/container_other.go new file mode 100644 index 000000000..9f1793a64 --- /dev/null +++ b/pkg/nri/container_other.go @@ -0,0 +1,28 @@ +//go:build !linux +// +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 nri + +import ( + nri "github.com/containerd/nri/pkg/adaptation" +) + +func containerToNRI(ctr Container) *nri.Container { + return commonContainerToNRI(ctr) +} diff --git a/pkg/nri/domain.go b/pkg/nri/domain.go new file mode 100644 index 000000000..186ce13d0 --- /dev/null +++ b/pkg/nri/domain.go @@ -0,0 +1,183 @@ +/* + 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 nri + +import ( + "context" + "fmt" + "sync" + + "github.com/containerd/containerd/errdefs" + "github.com/containerd/containerd/log" + "github.com/containerd/containerd/namespaces" + nri "github.com/containerd/nri/pkg/adaptation" + "github.com/sirupsen/logrus" +) + +// Domain implements the functions the generic NRI interface needs to +// deal with pods and containers from a particular containerd namespace. +type Domain interface { + // GetName() returns the containerd namespace for this domain. + GetName() string + + // ListPodSandboxes list all pods in this namespace. + ListPodSandboxes() []PodSandbox + + // ListContainer list all containers in this namespace. + ListContainers() []Container + + // GetPodSandbox returns the pod for the given ID. + GetPodSandbox(string) (PodSandbox, bool) + + // GetContainer returns the container for the given ID. + GetContainer(string) (Container, bool) + + // UpdateContainer applies an NRI container update request in the namespace. + UpdateContainer(context.Context, *nri.ContainerUpdate) error + + // EvictContainer evicts the requested container in the namespace. + EvictContainer(context.Context, *nri.ContainerEviction) error +} + +// RegisterDomain registers an NRI domain for a containerd namespace. +func RegisterDomain(d Domain) { + err := domains.add(d) + if err != nil { + logrus.WithError(err).Fatalf("Failed to register namespace %q with NRI", d.GetName()) + } + + logrus.Infof("Registered namespace %q with NRI", d.GetName()) +} + +type domainTable struct { + sync.Mutex + domains map[string]Domain +} + +func (t *domainTable) add(d Domain) error { + t.Lock() + defer t.Unlock() + + namespace := d.GetName() + + if _, ok := t.domains[namespace]; ok { + return errdefs.ErrAlreadyExists + } + + t.domains[namespace] = d + return nil +} + +func (t *domainTable) listPodSandboxes() []PodSandbox { + var pods []PodSandbox + + t.Lock() + defer t.Unlock() + + for _, d := range t.domains { + pods = append(pods, d.ListPodSandboxes()...) + } + return pods +} + +func (t *domainTable) listContainers() []Container { + var ctrs []Container + + t.Lock() + defer t.Unlock() + + for _, d := range t.domains { + ctrs = append(ctrs, d.ListContainers()...) + } + return ctrs +} + +func (t *domainTable) getContainer(id string) (Container, Domain) { + t.Lock() + defer t.Unlock() + + // TODO(klihub): Are ID conflicts across namespaces possible ? Probably... + + for _, d := range t.domains { + if ctr, ok := d.GetContainer(id); ok { + return ctr, d + } + } + return nil, nil +} + +func (t *domainTable) updateContainers(ctx context.Context, updates []*nri.ContainerUpdate) ([]*nri.ContainerUpdate, error) { + var failed []*nri.ContainerUpdate + + for _, u := range updates { + _, d := t.getContainer(u.ContainerId) + if d == nil { + continue + } + + domain := d.GetName() + err := d.UpdateContainer(namespaces.WithNamespace(ctx, domain), u) + if err != nil { + log.G(ctx).WithError(err).Errorf("NRI update of %s container %s failed", + domain, u.ContainerId) + if !u.IgnoreFailure { + failed = append(failed, u) + } + continue + } + + log.G(ctx).Tracef("NRI update of %s container %s successful", domain, u.ContainerId) + } + + if len(failed) != 0 { + return failed, fmt.Errorf("NRI update of some containers failed") + } + + return nil, nil +} + +func (t *domainTable) evictContainers(ctx context.Context, evict []*nri.ContainerEviction) ([]*nri.ContainerEviction, error) { + var failed []*nri.ContainerEviction + + for _, e := range evict { + _, d := t.getContainer(e.ContainerId) + if d == nil { + continue + } + + domain := d.GetName() + err := d.EvictContainer(namespaces.WithNamespace(ctx, domain), e) + if err != nil { + log.G(ctx).WithError(err).Errorf("NRI eviction of %s container %s failed", + domain, e.ContainerId) + failed = append(failed, e) + continue + } + + log.G(ctx).Tracef("NRI eviction of %s container %s successful", domain, e.ContainerId) + } + + if len(failed) != 0 { + return failed, fmt.Errorf("NRI eviction of some containers failed") + } + + return nil, nil +} + +var domains = &domainTable{ + domains: make(map[string]Domain), +} diff --git a/pkg/nri/nri.go b/pkg/nri/nri.go new file mode 100644 index 000000000..4323872a4 --- /dev/null +++ b/pkg/nri/nri.go @@ -0,0 +1,525 @@ +/* + 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 nri + +import ( + "context" + "fmt" + "path" + "sync" + + "github.com/containerd/containerd/log" + "github.com/sirupsen/logrus" + + "github.com/containerd/containerd/version" + nri "github.com/containerd/nri/pkg/adaptation" +) + +// API implements a common API for interfacing NRI from containerd. It is +// agnostic to any internal containerd implementation details of pods and +// containers. It needs corresponding Domain interfaces for each containerd +// namespace it needs to handle. These domains take care of the namespace- +// specific details of providing pod and container metadata to NRI and of +// applying NRI-requested adjustments to the state of containers. +type API interface { + // IsEnabled returns true if the NRI interface is enabled and initialized. + IsEnabled() bool + + // Start start the NRI interface, allowing external NRI plugins to + // connect, register, and hook themselves into the lifecycle events + // of pods and containers. + Start() error + + // Stop stops the NRI interface. + Stop() + + // RunPodSandbox relays pod creation events to NRI. + RunPodSandbox(context.Context, PodSandbox) error + + // StopPodSandbox relays pod shutdown events to NRI. + StopPodSandbox(context.Context, PodSandbox) error + + // RemovePodSandbox relays pod removal events to NRI. + RemovePodSandbox(context.Context, PodSandbox) error + + // CreateContainer relays container creation requests to NRI. + CreateContainer(context.Context, PodSandbox, Container) (*nri.ContainerAdjustment, error) + + // PostCreateContainer relays successful container creation events to NRI. + PostCreateContainer(context.Context, PodSandbox, Container) error + + // StartContainer relays container start request notifications to NRI. + StartContainer(context.Context, PodSandbox, Container) error + + // PostStartContainer relays successful container startup events to NRI. + PostStartContainer(context.Context, PodSandbox, Container) error + + // UpdateContainer relays container update requests to NRI. + UpdateContainer(context.Context, PodSandbox, Container, *nri.LinuxResources) (*nri.LinuxResources, error) + + // PostUpdateContainer relays successful container update events to NRI. + PostUpdateContainer(context.Context, PodSandbox, Container) error + + // StopContainer relays container stop requests to NRI. + StopContainer(context.Context, PodSandbox, Container) error + + // NotifyContainerExit handles the exit event of a container. + NotifyContainerExit(context.Context, PodSandbox, Container) + + // StopContainer relays container removal events to NRI. + RemoveContainer(context.Context, PodSandbox, Container) error +} + +type State int + +const ( + Created State = iota + 1 + Running + Stopped + Removed +) + +type local struct { + sync.Mutex + cfg *Config + nri *nri.Adaptation + + state map[string]State +} + +var _ API = &local{} + +// New creates an instance of the NRI interface with the given configuration. +func New(cfg *Config) (API, error) { + l := &local{ + cfg: cfg, + } + + if cfg.Disable { + logrus.Info("NRI interface is disabled by configuration.") + return l, nil + } + + var ( + name = path.Base(version.Package) + version = version.Version + opts = cfg.toOptions() + syncFn = l.syncPlugin + updateFn = l.updateFromPlugin + err error + ) + + l.nri, err = nri.New(name, version, syncFn, updateFn, opts...) + if err != nil { + return nil, fmt.Errorf("failed to initialize NRI interface: %w", err) + } + + l.state = make(map[string]State) + + logrus.Info("created NRI interface") + + return l, nil +} + +func (l *local) IsEnabled() bool { + return l != nil && !l.cfg.Disable +} + +func (l *local) Start() error { + if !l.IsEnabled() { + return nil + } + + err := l.nri.Start() + if err != nil { + return fmt.Errorf("failed to start NRI interface: %w", err) + } + + return nil +} + +func (l *local) Stop() { + if !l.IsEnabled() { + return + } + + l.Lock() + defer l.Unlock() + + l.nri.Stop() + l.nri = nil +} + +func (l *local) RunPodSandbox(ctx context.Context, pod PodSandbox) error { + if !l.IsEnabled() { + return nil + } + + l.Lock() + defer l.Unlock() + + request := &nri.RunPodSandboxRequest{ + Pod: podSandboxToNRI(pod), + } + + err := l.nri.RunPodSandbox(ctx, request) + l.setState(pod.GetID(), Running) + return err +} + +func (l *local) StopPodSandbox(ctx context.Context, pod PodSandbox) error { + if !l.IsEnabled() { + return nil + } + + l.Lock() + defer l.Unlock() + + if !l.needsStopping(pod.GetID()) { + return nil + } + + request := &nri.StopPodSandboxRequest{ + Pod: podSandboxToNRI(pod), + } + + err := l.nri.StopPodSandbox(ctx, request) + l.setState(pod.GetID(), Stopped) + return err +} + +func (l *local) RemovePodSandbox(ctx context.Context, pod PodSandbox) error { + if !l.IsEnabled() { + return nil + } + + l.Lock() + defer l.Unlock() + + if !l.needsRemoval(pod.GetID()) { + return nil + } + + request := &nri.RemovePodSandboxRequest{ + Pod: podSandboxToNRI(pod), + } + + err := l.nri.RemovePodSandbox(ctx, request) + l.setState(pod.GetID(), Removed) + return err +} + +func (l *local) CreateContainer(ctx context.Context, pod PodSandbox, ctr Container) (*nri.ContainerAdjustment, error) { + if !l.IsEnabled() { + return nil, nil + } + + l.Lock() + defer l.Unlock() + + request := &nri.CreateContainerRequest{ + Pod: podSandboxToNRI(pod), + Container: containerToNRI(ctr), + } + + response, err := l.nri.CreateContainer(ctx, request) + l.setState(request.Container.Id, Created) + if err != nil { + return nil, err + } + + _, err = l.evictContainers(ctx, response.Evict) + if err != nil { + // TODO(klihub): we ignore pre-create eviction failures for now + log.G(ctx).WithError(err).Warnf("pre-create eviction failed") + } + + if _, err := l.applyUpdates(ctx, response.Update); err != nil { + // TODO(klihub): we ignore pre-create update failures for now + log.G(ctx).WithError(err).Warnf("pre-create update failed") + } + + return response.Adjust, nil +} + +func (l *local) PostCreateContainer(ctx context.Context, pod PodSandbox, ctr Container) error { + if !l.IsEnabled() { + return nil + } + + l.Lock() + defer l.Unlock() + + request := &nri.PostCreateContainerRequest{ + Pod: podSandboxToNRI(pod), + Container: containerToNRI(ctr), + } + + return l.nri.PostCreateContainer(ctx, request) +} + +func (l *local) StartContainer(ctx context.Context, pod PodSandbox, ctr Container) error { + if !l.IsEnabled() { + return nil + } + + l.Lock() + defer l.Unlock() + + request := &nri.StartContainerRequest{ + Pod: podSandboxToNRI(pod), + Container: containerToNRI(ctr), + } + + err := l.nri.StartContainer(ctx, request) + l.setState(request.Container.Id, Running) + + return err +} + +func (l *local) PostStartContainer(ctx context.Context, pod PodSandbox, ctr Container) error { + if !l.IsEnabled() { + return nil + } + + l.Lock() + defer l.Unlock() + + request := &nri.PostStartContainerRequest{ + Pod: podSandboxToNRI(pod), + Container: containerToNRI(ctr), + } + + return l.nri.PostStartContainer(ctx, request) +} + +func (l *local) UpdateContainer(ctx context.Context, pod PodSandbox, ctr Container, req *nri.LinuxResources) (*nri.LinuxResources, error) { + if !l.IsEnabled() { + return nil, nil + } + + l.Lock() + defer l.Unlock() + + request := &nri.UpdateContainerRequest{ + Pod: podSandboxToNRI(pod), + Container: containerToNRI(ctr), + LinuxResources: req, + } + + response, err := l.nri.UpdateContainer(ctx, request) + if err != nil { + return nil, err + } + + _, err = l.evictContainers(ctx, response.Evict) + if err != nil { + // TODO(klihub): we ignore pre-update eviction failures for now + log.G(ctx).WithError(err).Warnf("pre-update eviction failed") + } + + cnt := len(response.Update) + if cnt == 0 { + return nil, nil + } + + if cnt > 1 { + _, err = l.applyUpdates(ctx, response.Update[0:cnt-1]) + if err != nil { + // TODO(klihub): we ignore pre-update update failures for now + log.G(ctx).WithError(err).Warnf("pre-update update failed") + } + } + + return response.Update[cnt-1].GetLinux().GetResources(), nil +} + +func (l *local) PostUpdateContainer(ctx context.Context, pod PodSandbox, ctr Container) error { + if !l.IsEnabled() { + return nil + } + + l.Lock() + defer l.Unlock() + + request := &nri.PostUpdateContainerRequest{ + Pod: podSandboxToNRI(pod), + Container: containerToNRI(ctr), + } + + return l.nri.PostUpdateContainer(ctx, request) +} + +func (l *local) StopContainer(ctx context.Context, pod PodSandbox, ctr Container) error { + if !l.IsEnabled() { + return nil + } + + l.Lock() + defer l.Unlock() + + return l.stopContainer(ctx, pod, ctr) +} + +func (l *local) NotifyContainerExit(ctx context.Context, pod PodSandbox, ctr Container) { + go func() { + l.Lock() + defer l.Unlock() + l.stopContainer(ctx, pod, ctr) + }() +} + +func (l *local) stopContainer(ctx context.Context, pod PodSandbox, ctr Container) error { + if !l.needsStopping(ctr.GetID()) { + log.G(ctx).Tracef("NRI stopContainer: container %s does not need stopping", + ctr.GetID()) + return nil + } + + request := &nri.StopContainerRequest{ + Pod: podSandboxToNRI(pod), + Container: containerToNRI(ctr), + } + + response, err := l.nri.StopContainer(ctx, request) + l.setState(request.Container.Id, Stopped) + if err != nil { + return err + } + + _, err = l.applyUpdates(ctx, response.Update) + if err != nil { + // TODO(klihub): we ignore post-stop update failures for now + log.G(ctx).WithError(err).Warnf("post-stop update failed") + } + + return nil +} + +func (l *local) RemoveContainer(ctx context.Context, pod PodSandbox, ctr Container) error { + if !l.IsEnabled() { + return nil + } + + l.Lock() + defer l.Unlock() + + if !l.needsRemoval(ctr.GetID()) { + return nil + } + + l.stopContainer(ctx, pod, ctr) + + request := &nri.RemoveContainerRequest{ + Pod: podSandboxToNRI(pod), + Container: containerToNRI(ctr), + } + err := l.nri.RemoveContainer(ctx, request) + l.setState(request.Container.Id, Removed) + + return err +} + +func (l *local) syncPlugin(ctx context.Context, syncFn nri.SyncCB) error { + l.Lock() + defer l.Unlock() + + log.G(ctx).Info("Synchronizing NRI (plugin) with current runtime state") + + pods := podSandboxesToNRI(domains.listPodSandboxes()) + containers := containersToNRI(domains.listContainers()) + + for _, ctr := range containers { + switch ctr.GetState() { + case nri.ContainerState_CONTAINER_CREATED: + l.setState(ctr.GetId(), Created) + case nri.ContainerState_CONTAINER_RUNNING, nri.ContainerState_CONTAINER_PAUSED: + l.setState(ctr.GetId(), Running) + case nri.ContainerState_CONTAINER_STOPPED: + l.setState(ctr.GetId(), Stopped) + default: + l.setState(ctr.GetId(), Removed) + } + } + + updates, err := syncFn(ctx, pods, containers) + if err != nil { + return err + } + + _, err = l.applyUpdates(ctx, updates) + if err != nil { + // TODO(klihub): we ignore post-sync update failures for now + log.G(ctx).WithError(err).Warnf("post-sync update failed") + } + + return nil +} + +func (l *local) updateFromPlugin(ctx context.Context, req []*nri.ContainerUpdate) ([]*nri.ContainerUpdate, error) { + l.Lock() + defer l.Unlock() + + log.G(ctx).Trace("Unsolicited NRI container updates") + + failed, err := l.applyUpdates(ctx, req) + return failed, err +} + +func (l *local) applyUpdates(ctx context.Context, updates []*nri.ContainerUpdate) ([]*nri.ContainerUpdate, error) { + // TODO(klihub): should we pre-save state and attempt a rollback on failure ? + failed, err := domains.updateContainers(ctx, updates) + return failed, err +} + +func (l *local) evictContainers(ctx context.Context, evict []*nri.ContainerEviction) ([]*nri.ContainerEviction, error) { + failed, err := domains.evictContainers(ctx, evict) + return failed, err +} + +func (l *local) setState(id string, state State) { + if state != Removed { + l.state[id] = state + return + } + + delete(l.state, id) +} + +func (l *local) getState(id string) State { + if state, ok := l.state[id]; ok { + return state + } + + return Removed +} + +func (l *local) needsStopping(id string) bool { + s := l.getState(id) + if s == Created || s == Running { + return true + } + return false +} + +func (l *local) needsRemoval(id string) bool { + s := l.getState(id) + if s == Created || s == Running || s == Stopped { + return true + } + return false +} diff --git a/pkg/nri/plugin/plugin.go b/pkg/nri/plugin/plugin.go new file mode 100644 index 000000000..a2fc30e59 --- /dev/null +++ b/pkg/nri/plugin/plugin.go @@ -0,0 +1,36 @@ +/* + 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 plugin + +import ( + "github.com/containerd/containerd/pkg/nri" + "github.com/containerd/containerd/plugin" +) + +func init() { + plugin.Register(&plugin.Registration{ + Type: plugin.NRIApiPlugin, + ID: "nri", + Config: nri.DefaultConfig(), + InitFn: initFunc, + }) +} + +func initFunc(ic *plugin.InitContext) (interface{}, error) { + l, err := nri.New(ic.Config.(*nri.Config)) + return l, err +} diff --git a/pkg/nri/sandbox.go b/pkg/nri/sandbox.go new file mode 100644 index 000000000..85d6178aa --- /dev/null +++ b/pkg/nri/sandbox.go @@ -0,0 +1,67 @@ +/* + 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 nri + +import ( + nri "github.com/containerd/nri/pkg/adaptation" +) + +// PodSandbox interface for interacting with NRI. +type PodSandbox interface { + GetDomain() string + + GetID() string + GetName() string + GetUID() string + GetNamespace() string + GetLabels() map[string]string + GetAnnotations() map[string]string + GetRuntimeHandler() string + GetLinuxPodSandbox() LinuxPodSandbox + + GetPid() uint32 +} + +type LinuxPodSandbox interface { + GetLinuxNamespaces() []*nri.LinuxNamespace + GetPodLinuxOverhead() *nri.LinuxResources + GetPodLinuxResources() *nri.LinuxResources + GetCgroupParent() string + GetCgroupsPath() string + GetLinuxResources() *nri.LinuxResources +} + +func commonPodSandboxToNRI(pod PodSandbox) *nri.PodSandbox { + return &nri.PodSandbox{ + Id: pod.GetID(), + Name: pod.GetName(), + Uid: pod.GetUID(), + Namespace: pod.GetNamespace(), + Labels: pod.GetLabels(), + Annotations: pod.GetAnnotations(), + RuntimeHandler: pod.GetRuntimeHandler(), + Pid: pod.GetPid(), + } +} + +func podSandboxesToNRI(podList []PodSandbox) []*nri.PodSandbox { + pods := []*nri.PodSandbox{} + for _, pod := range podList { + pods = append(pods, podSandboxToNRI(pod)) + } + return pods +} diff --git a/pkg/nri/sandbox_linux.go b/pkg/nri/sandbox_linux.go new file mode 100644 index 000000000..6e457945f --- /dev/null +++ b/pkg/nri/sandbox_linux.go @@ -0,0 +1,38 @@ +//go:build linux +// +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 nri + +import ( + nri "github.com/containerd/nri/pkg/adaptation" +) + +func podSandboxToNRI(pod PodSandbox) *nri.PodSandbox { + nriPod := commonPodSandboxToNRI(pod) + lnxPod := pod.GetLinuxPodSandbox() + nriPod.Linux = &nri.LinuxPodSandbox{ + Namespaces: lnxPod.GetLinuxNamespaces(), + PodOverhead: lnxPod.GetPodLinuxOverhead(), + PodResources: lnxPod.GetPodLinuxResources(), + CgroupParent: lnxPod.GetCgroupParent(), + CgroupsPath: lnxPod.GetCgroupsPath(), + Resources: lnxPod.GetLinuxResources(), + } + return nriPod +} diff --git a/pkg/nri/sandbox_other.go b/pkg/nri/sandbox_other.go new file mode 100644 index 000000000..d7683cfa8 --- /dev/null +++ b/pkg/nri/sandbox_other.go @@ -0,0 +1,28 @@ +//go:build !linux +// +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 nri + +import ( + nri "github.com/containerd/nri/pkg/adaptation" +) + +func podSandboxToNRI(pod PodSandbox) *nri.PodSandbox { + return commonPodSandboxToNRI(pod) +} diff --git a/plugin/plugin.go b/plugin/plugin.go index f427b14a4..d4d3eaea4 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -80,6 +80,8 @@ const ( LeasePlugin Type = "io.containerd.lease.v1" // TracingProcessorPlugin implements a open telemetry span processor TracingProcessorPlugin Type = "io.containerd.tracing.processor.v1" + // NRIApiPlugin implements the NRI adaptation interface for containerd. + NRIApiPlugin Type = "io.containerd.nri.v1" ) const ( diff --git a/vendor/github.com/blang/semver/.travis.yml b/vendor/github.com/blang/semver/.travis.yml deleted file mode 100644 index 102fb9a69..000000000 --- a/vendor/github.com/blang/semver/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -language: go -matrix: - include: - - go: 1.4.3 - - go: 1.5.4 - - go: 1.6.3 - - go: 1.7 - - go: tip - allow_failures: - - go: tip -install: -- go get golang.org/x/tools/cmd/cover -- go get github.com/mattn/goveralls -script: -- echo "Test and track coverage" ; $HOME/gopath/bin/goveralls -package "." -service=travis-ci - -repotoken $COVERALLS_TOKEN -- echo "Build examples" ; cd examples && go build -- echo "Check if gofmt'd" ; diff -u <(echo -n) <(gofmt -d -s .) -env: - global: - secure: HroGEAUQpVq9zX1b1VIkraLiywhGbzvNnTZq2TMxgK7JHP8xqNplAeF1izrR2i4QLL9nsY+9WtYss4QuPvEtZcVHUobw6XnL6radF7jS1LgfYZ9Y7oF+zogZ2I5QUMRLGA7rcxQ05s7mKq3XZQfeqaNts4bms/eZRefWuaFZbkw= diff --git a/vendor/github.com/blang/semver/LICENSE b/vendor/github.com/blang/semver/LICENSE deleted file mode 100644 index 5ba5c86fc..000000000 --- a/vendor/github.com/blang/semver/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License - -Copyright (c) 2014 Benedikt Lang - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/vendor/github.com/blang/semver/README.md b/vendor/github.com/blang/semver/README.md deleted file mode 100644 index 08b2e4a3d..000000000 --- a/vendor/github.com/blang/semver/README.md +++ /dev/null @@ -1,194 +0,0 @@ -semver for golang [![Build Status](https://travis-ci.org/blang/semver.svg?branch=master)](https://travis-ci.org/blang/semver) [![GoDoc](https://godoc.org/github.com/blang/semver?status.png)](https://godoc.org/github.com/blang/semver) [![Coverage Status](https://img.shields.io/coveralls/blang/semver.svg)](https://coveralls.io/r/blang/semver?branch=master) -====== - -semver is a [Semantic Versioning](http://semver.org/) library written in golang. It fully covers spec version `2.0.0`. - -Usage ------ -```bash -$ go get github.com/blang/semver -``` -Note: Always vendor your dependencies or fix on a specific version tag. - -```go -import github.com/blang/semver -v1, err := semver.Make("1.0.0-beta") -v2, err := semver.Make("2.0.0-beta") -v1.Compare(v2) -``` - -Also check the [GoDocs](http://godoc.org/github.com/blang/semver). - -Why should I use this lib? ------ - -- Fully spec compatible -- No reflection -- No regex -- Fully tested (Coverage >99%) -- Readable parsing/validation errors -- Fast (See [Benchmarks](#benchmarks)) -- Only Stdlib -- Uses values instead of pointers -- Many features, see below - - -Features ------ - -- Parsing and validation at all levels -- Comparator-like comparisons -- Compare Helper Methods -- InPlace manipulation -- Ranges `>=1.0.0 <2.0.0 || >=3.0.0 !3.0.1-beta.1` -- Wildcards `>=1.x`, `<=2.5.x` -- Sortable (implements sort.Interface) -- database/sql compatible (sql.Scanner/Valuer) -- encoding/json compatible (json.Marshaler/Unmarshaler) - -Ranges ------- - -A `Range` is a set of conditions which specify which versions satisfy the range. - -A condition is composed of an operator and a version. The supported operators are: - -- `<1.0.0` Less than `1.0.0` -- `<=1.0.0` Less than or equal to `1.0.0` -- `>1.0.0` Greater than `1.0.0` -- `>=1.0.0` Greater than or equal to `1.0.0` -- `1.0.0`, `=1.0.0`, `==1.0.0` Equal to `1.0.0` -- `!1.0.0`, `!=1.0.0` Not equal to `1.0.0`. Excludes version `1.0.0`. - -Note that spaces between the operator and the version will be gracefully tolerated. - -A `Range` can link multiple `Ranges` separated by space: - -Ranges can be linked by logical AND: - - - `>1.0.0 <2.0.0` would match between both ranges, so `1.1.1` and `1.8.7` but not `1.0.0` or `2.0.0` - - `>1.0.0 <3.0.0 !2.0.3-beta.2` would match every version between `1.0.0` and `3.0.0` except `2.0.3-beta.2` - -Ranges can also be linked by logical OR: - - - `<2.0.0 || >=3.0.0` would match `1.x.x` and `3.x.x` but not `2.x.x` - -AND has a higher precedence than OR. It's not possible to use brackets. - -Ranges can be combined by both AND and OR - - - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1` - -Range usage: - -``` -v, err := semver.Parse("1.2.3") -range, err := semver.ParseRange(">1.0.0 <2.0.0 || >=3.0.0") -if range(v) { - //valid -} - -``` - -Example ------ - -Have a look at full examples in [examples/main.go](examples/main.go) - -```go -import github.com/blang/semver - -v, err := semver.Make("0.0.1-alpha.preview+123.github") -fmt.Printf("Major: %d\n", v.Major) -fmt.Printf("Minor: %d\n", v.Minor) -fmt.Printf("Patch: %d\n", v.Patch) -fmt.Printf("Pre: %s\n", v.Pre) -fmt.Printf("Build: %s\n", v.Build) - -// Prerelease versions array -if len(v.Pre) > 0 { - fmt.Println("Prerelease versions:") - for i, pre := range v.Pre { - fmt.Printf("%d: %q\n", i, pre) - } -} - -// Build meta data array -if len(v.Build) > 0 { - fmt.Println("Build meta data:") - for i, build := range v.Build { - fmt.Printf("%d: %q\n", i, build) - } -} - -v001, err := semver.Make("0.0.1") -// Compare using helpers: v.GT(v2), v.LT, v.GTE, v.LTE -v001.GT(v) == true -v.LT(v001) == true -v.GTE(v) == true -v.LTE(v) == true - -// Or use v.Compare(v2) for comparisons (-1, 0, 1): -v001.Compare(v) == 1 -v.Compare(v001) == -1 -v.Compare(v) == 0 - -// Manipulate Version in place: -v.Pre[0], err = semver.NewPRVersion("beta") -if err != nil { - fmt.Printf("Error parsing pre release version: %q", err) -} - -fmt.Println("\nValidate versions:") -v.Build[0] = "?" - -err = v.Validate() -if err != nil { - fmt.Printf("Validation failed: %s\n", err) -} -``` - - -Benchmarks ------ - - BenchmarkParseSimple-4 5000000 390 ns/op 48 B/op 1 allocs/op - BenchmarkParseComplex-4 1000000 1813 ns/op 256 B/op 7 allocs/op - BenchmarkParseAverage-4 1000000 1171 ns/op 163 B/op 4 allocs/op - BenchmarkStringSimple-4 20000000 119 ns/op 16 B/op 1 allocs/op - BenchmarkStringLarger-4 10000000 206 ns/op 32 B/op 2 allocs/op - BenchmarkStringComplex-4 5000000 324 ns/op 80 B/op 3 allocs/op - BenchmarkStringAverage-4 5000000 273 ns/op 53 B/op 2 allocs/op - BenchmarkValidateSimple-4 200000000 9.33 ns/op 0 B/op 0 allocs/op - BenchmarkValidateComplex-4 3000000 469 ns/op 0 B/op 0 allocs/op - BenchmarkValidateAverage-4 5000000 256 ns/op 0 B/op 0 allocs/op - BenchmarkCompareSimple-4 100000000 11.8 ns/op 0 B/op 0 allocs/op - BenchmarkCompareComplex-4 50000000 30.8 ns/op 0 B/op 0 allocs/op - BenchmarkCompareAverage-4 30000000 41.5 ns/op 0 B/op 0 allocs/op - BenchmarkSort-4 3000000 419 ns/op 256 B/op 2 allocs/op - BenchmarkRangeParseSimple-4 2000000 850 ns/op 192 B/op 5 allocs/op - BenchmarkRangeParseAverage-4 1000000 1677 ns/op 400 B/op 10 allocs/op - BenchmarkRangeParseComplex-4 300000 5214 ns/op 1440 B/op 30 allocs/op - BenchmarkRangeMatchSimple-4 50000000 25.6 ns/op 0 B/op 0 allocs/op - BenchmarkRangeMatchAverage-4 30000000 56.4 ns/op 0 B/op 0 allocs/op - BenchmarkRangeMatchComplex-4 10000000 153 ns/op 0 B/op 0 allocs/op - -See benchmark cases at [semver_test.go](semver_test.go) - - -Motivation ------ - -I simply couldn't find any lib supporting the full spec. Others were just wrong or used reflection and regex which i don't like. - - -Contribution ------ - -Feel free to make a pull request. For bigger changes create a issue first to discuss about it. - - -License ------ - -See [LICENSE](LICENSE) file. diff --git a/vendor/github.com/blang/semver/json.go b/vendor/github.com/blang/semver/json.go deleted file mode 100644 index a74bf7c44..000000000 --- a/vendor/github.com/blang/semver/json.go +++ /dev/null @@ -1,23 +0,0 @@ -package semver - -import ( - "encoding/json" -) - -// MarshalJSON implements the encoding/json.Marshaler interface. -func (v Version) MarshalJSON() ([]byte, error) { - return json.Marshal(v.String()) -} - -// UnmarshalJSON implements the encoding/json.Unmarshaler interface. -func (v *Version) UnmarshalJSON(data []byte) (err error) { - var versionString string - - if err = json.Unmarshal(data, &versionString); err != nil { - return - } - - *v, err = Parse(versionString) - - return -} diff --git a/vendor/github.com/blang/semver/package.json b/vendor/github.com/blang/semver/package.json deleted file mode 100644 index 1cf8ebdd9..000000000 --- a/vendor/github.com/blang/semver/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "author": "blang", - "bugs": { - "URL": "https://github.com/blang/semver/issues", - "url": "https://github.com/blang/semver/issues" - }, - "gx": { - "dvcsimport": "github.com/blang/semver" - }, - "gxVersion": "0.10.0", - "language": "go", - "license": "MIT", - "name": "semver", - "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", - "version": "3.5.1" -} - diff --git a/vendor/github.com/blang/semver/range.go b/vendor/github.com/blang/semver/range.go deleted file mode 100644 index fca406d47..000000000 --- a/vendor/github.com/blang/semver/range.go +++ /dev/null @@ -1,416 +0,0 @@ -package semver - -import ( - "fmt" - "strconv" - "strings" - "unicode" -) - -type wildcardType int - -const ( - noneWildcard wildcardType = iota - majorWildcard wildcardType = 1 - minorWildcard wildcardType = 2 - patchWildcard wildcardType = 3 -) - -func wildcardTypefromInt(i int) wildcardType { - switch i { - case 1: - return majorWildcard - case 2: - return minorWildcard - case 3: - return patchWildcard - default: - return noneWildcard - } -} - -type comparator func(Version, Version) bool - -var ( - compEQ comparator = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) == 0 - } - compNE = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) != 0 - } - compGT = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) == 1 - } - compGE = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) >= 0 - } - compLT = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) == -1 - } - compLE = func(v1 Version, v2 Version) bool { - return v1.Compare(v2) <= 0 - } -) - -type versionRange struct { - v Version - c comparator -} - -// rangeFunc creates a Range from the given versionRange. -func (vr *versionRange) rangeFunc() Range { - return Range(func(v Version) bool { - return vr.c(v, vr.v) - }) -} - -// Range represents a range of versions. -// A Range can be used to check if a Version satisfies it: -// -// range, err := semver.ParseRange(">1.0.0 <2.0.0") -// range(semver.MustParse("1.1.1") // returns true -type Range func(Version) bool - -// OR combines the existing Range with another Range using logical OR. -func (rf Range) OR(f Range) Range { - return Range(func(v Version) bool { - return rf(v) || f(v) - }) -} - -// AND combines the existing Range with another Range using logical AND. -func (rf Range) AND(f Range) Range { - return Range(func(v Version) bool { - return rf(v) && f(v) - }) -} - -// ParseRange parses a range and returns a Range. -// If the range could not be parsed an error is returned. -// -// Valid ranges are: -// - "<1.0.0" -// - "<=1.0.0" -// - ">1.0.0" -// - ">=1.0.0" -// - "1.0.0", "=1.0.0", "==1.0.0" -// - "!1.0.0", "!=1.0.0" -// -// A Range can consist of multiple ranges separated by space: -// Ranges can be linked by logical AND: -// - ">1.0.0 <2.0.0" would match between both ranges, so "1.1.1" and "1.8.7" but not "1.0.0" or "2.0.0" -// - ">1.0.0 <3.0.0 !2.0.3-beta.2" would match every version between 1.0.0 and 3.0.0 except 2.0.3-beta.2 -// -// Ranges can also be linked by logical OR: -// - "<2.0.0 || >=3.0.0" would match "1.x.x" and "3.x.x" but not "2.x.x" -// -// AND has a higher precedence than OR. It's not possible to use brackets. -// -// Ranges can be combined by both AND and OR -// -// - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1` -func ParseRange(s string) (Range, error) { - parts := splitAndTrim(s) - orParts, err := splitORParts(parts) - if err != nil { - return nil, err - } - expandedParts, err := expandWildcardVersion(orParts) - if err != nil { - return nil, err - } - var orFn Range - for _, p := range expandedParts { - var andFn Range - for _, ap := range p { - opStr, vStr, err := splitComparatorVersion(ap) - if err != nil { - return nil, err - } - vr, err := buildVersionRange(opStr, vStr) - if err != nil { - return nil, fmt.Errorf("Could not parse Range %q: %s", ap, err) - } - rf := vr.rangeFunc() - - // Set function - if andFn == nil { - andFn = rf - } else { // Combine with existing function - andFn = andFn.AND(rf) - } - } - if orFn == nil { - orFn = andFn - } else { - orFn = orFn.OR(andFn) - } - - } - return orFn, nil -} - -// splitORParts splits the already cleaned parts by '||'. -// Checks for invalid positions of the operator and returns an -// error if found. -func splitORParts(parts []string) ([][]string, error) { - var ORparts [][]string - last := 0 - for i, p := range parts { - if p == "||" { - if i == 0 { - return nil, fmt.Errorf("First element in range is '||'") - } - ORparts = append(ORparts, parts[last:i]) - last = i + 1 - } - } - if last == len(parts) { - return nil, fmt.Errorf("Last element in range is '||'") - } - ORparts = append(ORparts, parts[last:]) - return ORparts, nil -} - -// buildVersionRange takes a slice of 2: operator and version -// and builds a versionRange, otherwise an error. -func buildVersionRange(opStr, vStr string) (*versionRange, error) { - c := parseComparator(opStr) - if c == nil { - return nil, fmt.Errorf("Could not parse comparator %q in %q", opStr, strings.Join([]string{opStr, vStr}, "")) - } - v, err := Parse(vStr) - if err != nil { - return nil, fmt.Errorf("Could not parse version %q in %q: %s", vStr, strings.Join([]string{opStr, vStr}, ""), err) - } - - return &versionRange{ - v: v, - c: c, - }, nil - -} - -// inArray checks if a byte is contained in an array of bytes -func inArray(s byte, list []byte) bool { - for _, el := range list { - if el == s { - return true - } - } - return false -} - -// splitAndTrim splits a range string by spaces and cleans whitespaces -func splitAndTrim(s string) (result []string) { - last := 0 - var lastChar byte - excludeFromSplit := []byte{'>', '<', '='} - for i := 0; i < len(s); i++ { - if s[i] == ' ' && !inArray(lastChar, excludeFromSplit) { - if last < i-1 { - result = append(result, s[last:i]) - } - last = i + 1 - } else if s[i] != ' ' { - lastChar = s[i] - } - } - if last < len(s)-1 { - result = append(result, s[last:]) - } - - for i, v := range result { - result[i] = strings.Replace(v, " ", "", -1) - } - - // parts := strings.Split(s, " ") - // for _, x := range parts { - // if s := strings.TrimSpace(x); len(s) != 0 { - // result = append(result, s) - // } - // } - return -} - -// splitComparatorVersion splits the comparator from the version. -// Input must be free of leading or trailing spaces. -func splitComparatorVersion(s string) (string, string, error) { - i := strings.IndexFunc(s, unicode.IsDigit) - if i == -1 { - return "", "", fmt.Errorf("Could not get version from string: %q", s) - } - return strings.TrimSpace(s[0:i]), s[i:], nil -} - -// getWildcardType will return the type of wildcard that the -// passed version contains -func getWildcardType(vStr string) wildcardType { - parts := strings.Split(vStr, ".") - nparts := len(parts) - wildcard := parts[nparts-1] - - possibleWildcardType := wildcardTypefromInt(nparts) - if wildcard == "x" { - return possibleWildcardType - } - - return noneWildcard -} - -// createVersionFromWildcard will convert a wildcard version -// into a regular version, replacing 'x's with '0's, handling -// special cases like '1.x.x' and '1.x' -func createVersionFromWildcard(vStr string) string { - // handle 1.x.x - vStr2 := strings.Replace(vStr, ".x.x", ".x", 1) - vStr2 = strings.Replace(vStr2, ".x", ".0", 1) - parts := strings.Split(vStr2, ".") - - // handle 1.x - if len(parts) == 2 { - return vStr2 + ".0" - } - - return vStr2 -} - -// incrementMajorVersion will increment the major version -// of the passed version -func incrementMajorVersion(vStr string) (string, error) { - parts := strings.Split(vStr, ".") - i, err := strconv.Atoi(parts[0]) - if err != nil { - return "", err - } - parts[0] = strconv.Itoa(i + 1) - - return strings.Join(parts, "."), nil -} - -// incrementMajorVersion will increment the minor version -// of the passed version -func incrementMinorVersion(vStr string) (string, error) { - parts := strings.Split(vStr, ".") - i, err := strconv.Atoi(parts[1]) - if err != nil { - return "", err - } - parts[1] = strconv.Itoa(i + 1) - - return strings.Join(parts, "."), nil -} - -// expandWildcardVersion will expand wildcards inside versions -// following these rules: -// -// * when dealing with patch wildcards: -// >= 1.2.x will become >= 1.2.0 -// <= 1.2.x will become < 1.3.0 -// > 1.2.x will become >= 1.3.0 -// < 1.2.x will become < 1.2.0 -// != 1.2.x will become < 1.2.0 >= 1.3.0 -// -// * when dealing with minor wildcards: -// >= 1.x will become >= 1.0.0 -// <= 1.x will become < 2.0.0 -// > 1.x will become >= 2.0.0 -// < 1.0 will become < 1.0.0 -// != 1.x will become < 1.0.0 >= 2.0.0 -// -// * when dealing with wildcards without -// version operator: -// 1.2.x will become >= 1.2.0 < 1.3.0 -// 1.x will become >= 1.0.0 < 2.0.0 -func expandWildcardVersion(parts [][]string) ([][]string, error) { - var expandedParts [][]string - for _, p := range parts { - var newParts []string - for _, ap := range p { - if strings.Index(ap, "x") != -1 { - opStr, vStr, err := splitComparatorVersion(ap) - if err != nil { - return nil, err - } - - versionWildcardType := getWildcardType(vStr) - flatVersion := createVersionFromWildcard(vStr) - - var resultOperator string - var shouldIncrementVersion bool - switch opStr { - case ">": - resultOperator = ">=" - shouldIncrementVersion = true - case ">=": - resultOperator = ">=" - case "<": - resultOperator = "<" - case "<=": - resultOperator = "<" - shouldIncrementVersion = true - case "", "=", "==": - newParts = append(newParts, ">="+flatVersion) - resultOperator = "<" - shouldIncrementVersion = true - case "!=", "!": - newParts = append(newParts, "<"+flatVersion) - resultOperator = ">=" - shouldIncrementVersion = true - } - - var resultVersion string - if shouldIncrementVersion { - switch versionWildcardType { - case patchWildcard: - resultVersion, _ = incrementMinorVersion(flatVersion) - case minorWildcard: - resultVersion, _ = incrementMajorVersion(flatVersion) - } - } else { - resultVersion = flatVersion - } - - ap = resultOperator + resultVersion - } - newParts = append(newParts, ap) - } - expandedParts = append(expandedParts, newParts) - } - - return expandedParts, nil -} - -func parseComparator(s string) comparator { - switch s { - case "==": - fallthrough - case "": - fallthrough - case "=": - return compEQ - case ">": - return compGT - case ">=": - return compGE - case "<": - return compLT - case "<=": - return compLE - case "!": - fallthrough - case "!=": - return compNE - } - - return nil -} - -// MustParseRange is like ParseRange but panics if the range cannot be parsed. -func MustParseRange(s string) Range { - r, err := ParseRange(s) - if err != nil { - panic(`semver: ParseRange(` + s + `): ` + err.Error()) - } - return r -} diff --git a/vendor/github.com/blang/semver/semver.go b/vendor/github.com/blang/semver/semver.go deleted file mode 100644 index 8ee0842e6..000000000 --- a/vendor/github.com/blang/semver/semver.go +++ /dev/null @@ -1,418 +0,0 @@ -package semver - -import ( - "errors" - "fmt" - "strconv" - "strings" -) - -const ( - numbers string = "0123456789" - alphas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" - alphanum = alphas + numbers -) - -// SpecVersion is the latest fully supported spec version of semver -var SpecVersion = Version{ - Major: 2, - Minor: 0, - Patch: 0, -} - -// Version represents a semver compatible version -type Version struct { - Major uint64 - Minor uint64 - Patch uint64 - Pre []PRVersion - Build []string //No Precendence -} - -// Version to string -func (v Version) String() string { - b := make([]byte, 0, 5) - b = strconv.AppendUint(b, v.Major, 10) - b = append(b, '.') - b = strconv.AppendUint(b, v.Minor, 10) - b = append(b, '.') - b = strconv.AppendUint(b, v.Patch, 10) - - if len(v.Pre) > 0 { - b = append(b, '-') - b = append(b, v.Pre[0].String()...) - - for _, pre := range v.Pre[1:] { - b = append(b, '.') - b = append(b, pre.String()...) - } - } - - if len(v.Build) > 0 { - b = append(b, '+') - b = append(b, v.Build[0]...) - - for _, build := range v.Build[1:] { - b = append(b, '.') - b = append(b, build...) - } - } - - return string(b) -} - -// Equals checks if v is equal to o. -func (v Version) Equals(o Version) bool { - return (v.Compare(o) == 0) -} - -// EQ checks if v is equal to o. -func (v Version) EQ(o Version) bool { - return (v.Compare(o) == 0) -} - -// NE checks if v is not equal to o. -func (v Version) NE(o Version) bool { - return (v.Compare(o) != 0) -} - -// GT checks if v is greater than o. -func (v Version) GT(o Version) bool { - return (v.Compare(o) == 1) -} - -// GTE checks if v is greater than or equal to o. -func (v Version) GTE(o Version) bool { - return (v.Compare(o) >= 0) -} - -// GE checks if v is greater than or equal to o. -func (v Version) GE(o Version) bool { - return (v.Compare(o) >= 0) -} - -// LT checks if v is less than o. -func (v Version) LT(o Version) bool { - return (v.Compare(o) == -1) -} - -// LTE checks if v is less than or equal to o. -func (v Version) LTE(o Version) bool { - return (v.Compare(o) <= 0) -} - -// LE checks if v is less than or equal to o. -func (v Version) LE(o Version) bool { - return (v.Compare(o) <= 0) -} - -// Compare compares Versions v to o: -// -1 == v is less than o -// 0 == v is equal to o -// 1 == v is greater than o -func (v Version) Compare(o Version) int { - if v.Major != o.Major { - if v.Major > o.Major { - return 1 - } - return -1 - } - if v.Minor != o.Minor { - if v.Minor > o.Minor { - return 1 - } - return -1 - } - if v.Patch != o.Patch { - if v.Patch > o.Patch { - return 1 - } - return -1 - } - - // Quick comparison if a version has no prerelease versions - if len(v.Pre) == 0 && len(o.Pre) == 0 { - return 0 - } else if len(v.Pre) == 0 && len(o.Pre) > 0 { - return 1 - } else if len(v.Pre) > 0 && len(o.Pre) == 0 { - return -1 - } - - i := 0 - for ; i < len(v.Pre) && i < len(o.Pre); i++ { - if comp := v.Pre[i].Compare(o.Pre[i]); comp == 0 { - continue - } else if comp == 1 { - return 1 - } else { - return -1 - } - } - - // If all pr versions are the equal but one has further prversion, this one greater - if i == len(v.Pre) && i == len(o.Pre) { - return 0 - } else if i == len(v.Pre) && i < len(o.Pre) { - return -1 - } else { - return 1 - } - -} - -// Validate validates v and returns error in case -func (v Version) Validate() error { - // Major, Minor, Patch already validated using uint64 - - for _, pre := range v.Pre { - if !pre.IsNum { //Numeric prerelease versions already uint64 - if len(pre.VersionStr) == 0 { - return fmt.Errorf("Prerelease can not be empty %q", pre.VersionStr) - } - if !containsOnly(pre.VersionStr, alphanum) { - return fmt.Errorf("Invalid character(s) found in prerelease %q", pre.VersionStr) - } - } - } - - for _, build := range v.Build { - if len(build) == 0 { - return fmt.Errorf("Build meta data can not be empty %q", build) - } - if !containsOnly(build, alphanum) { - return fmt.Errorf("Invalid character(s) found in build meta data %q", build) - } - } - - return nil -} - -// New is an alias for Parse and returns a pointer, parses version string and returns a validated Version or error -func New(s string) (vp *Version, err error) { - v, err := Parse(s) - vp = &v - return -} - -// Make is an alias for Parse, parses version string and returns a validated Version or error -func Make(s string) (Version, error) { - return Parse(s) -} - -// ParseTolerant allows for certain version specifications that do not strictly adhere to semver -// specs to be parsed by this library. It does so by normalizing versions before passing them to -// Parse(). It currently trims spaces, removes a "v" prefix, and adds a 0 patch number to versions -// with only major and minor components specified -func ParseTolerant(s string) (Version, error) { - s = strings.TrimSpace(s) - s = strings.TrimPrefix(s, "v") - - // Split into major.minor.(patch+pr+meta) - parts := strings.SplitN(s, ".", 3) - if len(parts) < 3 { - if strings.ContainsAny(parts[len(parts)-1], "+-") { - return Version{}, errors.New("Short version cannot contain PreRelease/Build meta data") - } - for len(parts) < 3 { - parts = append(parts, "0") - } - s = strings.Join(parts, ".") - } - - return Parse(s) -} - -// Parse parses version string and returns a validated Version or error -func Parse(s string) (Version, error) { - if len(s) == 0 { - return Version{}, errors.New("Version string empty") - } - - // Split into major.minor.(patch+pr+meta) - parts := strings.SplitN(s, ".", 3) - if len(parts) != 3 { - return Version{}, errors.New("No Major.Minor.Patch elements found") - } - - // Major - if !containsOnly(parts[0], numbers) { - return Version{}, fmt.Errorf("Invalid character(s) found in major number %q", parts[0]) - } - if hasLeadingZeroes(parts[0]) { - return Version{}, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0]) - } - major, err := strconv.ParseUint(parts[0], 10, 64) - if err != nil { - return Version{}, err - } - - // Minor - if !containsOnly(parts[1], numbers) { - return Version{}, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1]) - } - if hasLeadingZeroes(parts[1]) { - return Version{}, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1]) - } - minor, err := strconv.ParseUint(parts[1], 10, 64) - if err != nil { - return Version{}, err - } - - v := Version{} - v.Major = major - v.Minor = minor - - var build, prerelease []string - patchStr := parts[2] - - if buildIndex := strings.IndexRune(patchStr, '+'); buildIndex != -1 { - build = strings.Split(patchStr[buildIndex+1:], ".") - patchStr = patchStr[:buildIndex] - } - - if preIndex := strings.IndexRune(patchStr, '-'); preIndex != -1 { - prerelease = strings.Split(patchStr[preIndex+1:], ".") - patchStr = patchStr[:preIndex] - } - - if !containsOnly(patchStr, numbers) { - return Version{}, fmt.Errorf("Invalid character(s) found in patch number %q", patchStr) - } - if hasLeadingZeroes(patchStr) { - return Version{}, fmt.Errorf("Patch number must not contain leading zeroes %q", patchStr) - } - patch, err := strconv.ParseUint(patchStr, 10, 64) - if err != nil { - return Version{}, err - } - - v.Patch = patch - - // Prerelease - for _, prstr := range prerelease { - parsedPR, err := NewPRVersion(prstr) - if err != nil { - return Version{}, err - } - v.Pre = append(v.Pre, parsedPR) - } - - // Build meta data - for _, str := range build { - if len(str) == 0 { - return Version{}, errors.New("Build meta data is empty") - } - if !containsOnly(str, alphanum) { - return Version{}, fmt.Errorf("Invalid character(s) found in build meta data %q", str) - } - v.Build = append(v.Build, str) - } - - return v, nil -} - -// MustParse is like Parse but panics if the version cannot be parsed. -func MustParse(s string) Version { - v, err := Parse(s) - if err != nil { - panic(`semver: Parse(` + s + `): ` + err.Error()) - } - return v -} - -// PRVersion represents a PreRelease Version -type PRVersion struct { - VersionStr string - VersionNum uint64 - IsNum bool -} - -// NewPRVersion creates a new valid prerelease version -func NewPRVersion(s string) (PRVersion, error) { - if len(s) == 0 { - return PRVersion{}, errors.New("Prerelease is empty") - } - v := PRVersion{} - if containsOnly(s, numbers) { - if hasLeadingZeroes(s) { - return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s) - } - num, err := strconv.ParseUint(s, 10, 64) - - // Might never be hit, but just in case - if err != nil { - return PRVersion{}, err - } - v.VersionNum = num - v.IsNum = true - } else if containsOnly(s, alphanum) { - v.VersionStr = s - v.IsNum = false - } else { - return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s) - } - return v, nil -} - -// IsNumeric checks if prerelease-version is numeric -func (v PRVersion) IsNumeric() bool { - return v.IsNum -} - -// Compare compares two PreRelease Versions v and o: -// -1 == v is less than o -// 0 == v is equal to o -// 1 == v is greater than o -func (v PRVersion) Compare(o PRVersion) int { - if v.IsNum && !o.IsNum { - return -1 - } else if !v.IsNum && o.IsNum { - return 1 - } else if v.IsNum && o.IsNum { - if v.VersionNum == o.VersionNum { - return 0 - } else if v.VersionNum > o.VersionNum { - return 1 - } else { - return -1 - } - } else { // both are Alphas - if v.VersionStr == o.VersionStr { - return 0 - } else if v.VersionStr > o.VersionStr { - return 1 - } else { - return -1 - } - } -} - -// PreRelease version to string -func (v PRVersion) String() string { - if v.IsNum { - return strconv.FormatUint(v.VersionNum, 10) - } - return v.VersionStr -} - -func containsOnly(s string, set string) bool { - return strings.IndexFunc(s, func(r rune) bool { - return !strings.ContainsRune(set, r) - }) == -1 -} - -func hasLeadingZeroes(s string) bool { - return len(s) > 1 && s[0] == '0' -} - -// NewBuildVersion creates a new valid build version -func NewBuildVersion(s string) (string, error) { - if len(s) == 0 { - return "", errors.New("Buildversion is empty") - } - if !containsOnly(s, alphanum) { - return "", fmt.Errorf("Invalid character(s) found in build meta data %q", s) - } - return s, nil -} diff --git a/vendor/github.com/blang/semver/sort.go b/vendor/github.com/blang/semver/sort.go deleted file mode 100644 index e18f88082..000000000 --- a/vendor/github.com/blang/semver/sort.go +++ /dev/null @@ -1,28 +0,0 @@ -package semver - -import ( - "sort" -) - -// Versions represents multiple versions. -type Versions []Version - -// Len returns length of version collection -func (s Versions) Len() int { - return len(s) -} - -// Swap swaps two versions inside the collection by its indices -func (s Versions) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -// Less checks if version at index i is less than version at index j -func (s Versions) Less(i, j int) bool { - return s[i].LT(s[j]) -} - -// Sort sorts a slice of versions -func Sort(versions []Version) { - sort.Sort(Versions(versions)) -} diff --git a/vendor/github.com/blang/semver/sql.go b/vendor/github.com/blang/semver/sql.go deleted file mode 100644 index eb4d80266..000000000 --- a/vendor/github.com/blang/semver/sql.go +++ /dev/null @@ -1,30 +0,0 @@ -package semver - -import ( - "database/sql/driver" - "fmt" -) - -// Scan implements the database/sql.Scanner interface. -func (v *Version) Scan(src interface{}) (err error) { - var str string - switch src := src.(type) { - case string: - str = src - case []byte: - str = string(src) - default: - return fmt.Errorf("Version.Scan: cannot convert %T to string.", src) - } - - if t, err := Parse(str); err == nil { - *v = t - } - - return -} - -// Value implements the database/sql/driver.Valuer interface. -func (v Version) Value() (driver.Value, error) { - return v.String(), nil -} diff --git a/vendor/github.com/containerd/nri/.golangci.yml b/vendor/github.com/containerd/nri/.golangci.yml index 4cef1ca7a..294c14a91 100644 --- a/vendor/github.com/containerd/nri/.golangci.yml +++ b/vendor/github.com/containerd/nri/.golangci.yml @@ -1,22 +1,41 @@ linters: enable: - - structcheck - - varcheck - staticcheck - unconvert - gofmt - goimports - - golint - ineffassign - vet - unused - misspell + - revive disable: - errcheck issues: include: - EXC0002 + exclude-rules: + # We have protoc-generated ttRPC/gRPC code. When adding extra functions + # for generated types we want to consistently violate golint's semantic + # function name spelling rules, instead of inconsistently doing so only + # from automatically generated files. These rules are for that. + - path: pkg/adaptation/result.go + linters: + - golint + - revive + text: "should be claim" + # Ignore naming violation in the test suite as well. + - path: pkg/adaptation/adaptation_suite_test.go + linters: + - golint + - revive + text: "should be strip" + # Differ copies pods and containers with Mutexes for diffing. Should be harmless. + - path: plugins/differ/nri-differ.go + linters: + - govet + text: "copylocks: .*protobuf/internal/impl.MessageState.*" run: timeout: 2m diff --git a/vendor/github.com/containerd/nri/Makefile b/vendor/github.com/containerd/nri/Makefile index 1b070210e..d3c590af9 100644 --- a/vendor/github.com/containerd/nri/Makefile +++ b/vendor/github.com/containerd/nri/Makefile @@ -12,5 +12,166 @@ # See the License for the specific language governing permissions and # limitations under the License. -all: - go build -v +PROTO_SOURCES = $(shell find . -name '*.proto' | grep -v /vendor/) +PROTO_GOFILES = $(patsubst %.proto,%.pb.go,$(PROTO_SOURCES)) +PROTO_INCLUDE = -I$(PWD):/usr/local/include:/usr/include +PROTO_OPTIONS = --proto_path=. $(PROTO_INCLUDE) \ + --go_opt=paths=source_relative --go_out=. \ + --go-ttrpc_opt=paths=source_relative --go-ttrpc_out=. +PROTO_COMPILE = PATH=$(PATH):$(shell go env GOPATH)/bin; protoc $(PROTO_OPTIONS) + +GO_CMD := go +GO_BUILD := $(GO_CMD) build +GO_INSTALL := $(GO_CMD) install +GO_TEST := $(GO_CMD) test +GO_LINT := golint -set_exit_status +GO_FMT := gofmt +GO_VET := $(GO_CMD) vet + +GO_MODULES := $(shell $(GO_CMD) list ./...) + +GOLANG_CILINT := golangci-lint +GINKGO := ginkgo + +BUILD_PATH := $(shell pwd)/build +BIN_PATH := $(BUILD_PATH)/bin +COVERAGE_PATH := $(BUILD_PATH)/coverage + +PLUGINS := \ + $(BIN_PATH)/logger \ + $(BIN_PATH)/device-injector \ + $(BIN_PATH)/hook-injector \ + $(BIN_PATH)/differ \ + $(BIN_PATH)/v010-adapter \ + $(BIN_PATH)/template + + +ifneq ($(V),1) + Q := @ +endif + +# +# top-level targets +# + +all: build build-plugins + +build: build-proto build-check + +clean: clean-plugins + +allclean: clean clean-cache + +test: test-gopkgs + +# +# build targets +# + +build-proto: $(PROTO_GOFILES) + +build-plugins: $(PLUGINS) + +build-check: + $(Q)$(GO_BUILD) -v $(GO_MODULES) + +# +# clean targets +# + +clean-plugins: + $(Q)rm -f $(PLUGINS) + +clean-cache: + $(Q)$(GO_CMD) clean -cache -testcache + +# +# plugins build targets +# + +$(BIN_PATH)/logger: $(wildcard plugins/logger/*.go) + $(Q)echo "Building $@..."; \ + cd $(dir $<) && $(GO_BUILD) -o $@ . + +$(BIN_PATH)/device-injector: $(wildcard plugins/device-injector/*.go) + $(Q)echo "Building $@..."; \ + cd $(dir $<) && $(GO_BUILD) -o $@ . + +$(BIN_PATH)/hook-injector: $(wildcard plugins/hook-injector/*.go) + $(Q)echo "Building $@..."; \ + cd $(dir $<) && $(GO_BUILD) -o $@ . + +$(BIN_PATH)/differ: $(wildcard plugins/differ/*.go) + $(Q)echo "Building $@..."; \ + cd $(dir $<) && $(GO_BUILD) -o $@ . + +$(BIN_PATH)/v010-adapter: $(wildcard plugins/v010-adapter/*.go) + $(Q)echo "Building $@..."; \ + cd $(dir $<) && $(GO_BUILD) -o $@ . + +$(BIN_PATH)/template: $(wildcard plugins/template/*.go) + $(Q)echo "Building $@..."; \ + cd $(dir $<) && $(GO_BUILD) -o $@ . + +# +# test targets +# + +test-gopkgs: ginkgo-tests + +ginkgo-tests: + $(Q)$(GINKGO) run \ + --race \ + --trace \ + --cover \ + --covermode atomic \ + --output-dir $(COVERAGE_PATH) \ + --junit-report junit.xml \ + --coverprofile coverprofile \ + --succinct \ + -r .; \ + $(GO_CMD) tool cover -html=$(COVERAGE_PATH)/coverprofile -o $(COVERAGE_PATH)/coverage.html + +codecov: SHELL := $(shell which bash) +codecov: + bash <(curl -s https://codecov.io/bash) -f $(COVERAGE_PATH)/coverprofile + +# +# other validation targets +# + +fmt format: + $(Q)$(GO_FMT) -s -d -e . + +lint: + $(Q)$(GO_LINT) -set_exit_status ./... + +vet: + $(Q)$(GO_VET) ./... + +golangci-lint: + $(Q)$(GOLANG_CILINT) run + +# +# proto generation targets +# + +%.pb.go: %.proto + $(Q)echo "Generating $@..."; \ + $(PROTO_COMPILE) $< + +# +# targets for installing dependencies +# + +install-protoc install-protobuf: + $(Q)./scripts/install-protobuf && \ + +install-ttrpc-plugin: + $(Q)$(GO_INSTALL) github.com/containerd/ttrpc/cmd/protoc-gen-go-ttrpc@74421d10189e8c118870d294c9f7f62db2d33ec1 + +install-protoc-dependencies: + $(Q)$(GO_INSTALL) google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.0 + +install-ginkgo: + $(Q)$(GO_INSTALL) -mod=mod github.com/onsi/ginkgo/v2/ginkgo diff --git a/vendor/github.com/containerd/nri/README-v0.1.0.md b/vendor/github.com/containerd/nri/README-v0.1.0.md new file mode 100644 index 000000000..0f81fd039 --- /dev/null +++ b/vendor/github.com/containerd/nri/README-v0.1.0.md @@ -0,0 +1,115 @@ +# nri - Node Resource Interface + +[![PkgGoDev](https://pkg.go.dev/badge/github.com/containerd/nri)](https://pkg.go.dev/github.com/containerd/nri) +[![Build Status](https://github.com/containerd/nri/workflows/CI/badge.svg)](https://github.com/containerd/nri/actions?query=workflow%3ACI) +[![codecov](https://codecov.io/gh/containerd/nri/branch/main/graph/badge.svg)](https://codecov.io/gh/containerd/nri) +[![Go Report Card](https://goreportcard.com/badge/github.com/containerd/nri)](https://goreportcard.com/report/github.com/containerd/nri) + +*This project is currently in DRAFT status* + +This project is a WIP for a new, CNI like, interface for managing resources on a node for Pods and Containers. + +## Documentation + +The basic interface, concepts and plugin design of the Container Network Interface (CNI) is an elegant way to handle multiple implementations of the network stack for containers. +This concept can be used for additional interfaces to customize a container's runtime environment. +This proposal covers a new interface for resource management on a node with a structured API and plugin design for containers. + +## Lifecycle + +The big selling point for CNI is that it has a structured interface for modifying the network namespace for a container. +This is different from generic hooks as they lack a type safe API injected into the lifecycle of a container. +The lifecycle point that CNI and NRI plugins will be injected into is the point between `Create` and `Start` of the container's init process. + +`Create->NRI->Start` + +## Configuration + +Configuration is split into two parts. One is the payload that is specific to a plugin invocation while the second is the host level configuration and options that specify what plugins to run and provide additional configuration to a plugin. + +### Filepath and Binaries + +Plugin binary paths can be configured via the consumer but will default to `/opt/nri/bin`. +Binaries are named with their type as the binary name, same as the CNI plugin naming scheme. + +### Host Level Config + +The config's default location will be `/etc/nri/resource.d/*.conf`. + +```json +{ + "version": "0.1", + "plugins": [ + { + "type": "konfine", + "conf": { + "systemReserved": [0, 1] + } + }, + { + "type": "clearcfs" + } + ] +} +``` + +### Input + +Input to a plugin is provided via `STDIN` as a `json` payload. + +```json +{ + "version": "0.1", + "state": "create", + "id": "redis", + "pid": 1234, + "spec": { + "resources": {}, + "cgroupsPath": "default/redis", + "namespaces": { + "pid": "/proc/44/ns/pid", + "mount": "/proc/44/ns/mnt", + "net": "/proc/44/ns/net" + }, + "annotations": { + "qos.class": "ls" + } + } +} +``` + +### Output + +```json +{ + "version": "0.1", + "state": "create", + "id": "redis", + "pid": 1234, + "cgroupsPath": "qos-ls/default/redis" +} +``` + +## Commands + +* Invoke - provides invocations into different lifecycle changes of a container + - states: `setup|pause|resume|update|delete` + +## Packages + +A Go based API and client package will be created for both producers of plugins and consumers, commonly being the container runtime (containerd). + +### Sample Plugin + +* [clearcfs](examples/clearcfs/main.go) + +## Project details + +nri is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE). +As a containerd sub-project, you will find the: + + * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md), + * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS), + * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md) + +information in our [`containerd/project`](https://github.com/containerd/project) repository. diff --git a/vendor/github.com/containerd/nri/README.md b/vendor/github.com/containerd/nri/README.md index 8329973f9..fb31edc2d 100644 --- a/vendor/github.com/containerd/nri/README.md +++ b/vendor/github.com/containerd/nri/README.md @@ -1,167 +1,306 @@ -# nri - Node Resource Interface +## Node Resource Interface, Revisited -[![PkgGoDev](https://pkg.go.dev/badge/github.com/containerd/nri)](https://pkg.go.dev/github.com/containerd/nri) -[![Build Status](https://github.com/containerd/nri/workflows/CI/badge.svg)](https://github.com/containerd/nri/actions?query=workflow%3ACI) -[![codecov](https://codecov.io/gh/containerd/nri/branch/master/graph/badge.svg)](https://codecov.io/gh/containerd/nri) -[![Go Report Card](https://goreportcard.com/badge/github.com/containerd/nri)](https://goreportcard.com/report/github.com/containerd/nri) +### Goal -*This project is currently in DRAFT status* +NRI allows plugging domain- or vendor-specific custom logic into OCI- +compatible runtimes. This logic can make controlled changes to containers +or perform extra actions outside the scope of OCI at certain points in a +containers lifecycle. This can be used, for instance, for improved allocation +and management of devices and other container resources. -This project is a WIP for a new, CNI like, interface for managing resources on a node for Pods and Containers. +NRI defines the interfaces and implements the common infrastructure for +enabling such pluggable runtime extensions, NRI plugins. This also keeps +the plugins themselves runtime-agnostic. -## Documentation +The goal is to enable NRI support in the most commonly used OCI runtimes, +[containerd](https://github.com/containerd/containerd) and +[CRI-O](https://github.com/cri-o/cri-o). -The basic interface, concepts and plugin design of the Container Network Interface (CNI) is an elegant way to handle multiple implementations of the network stack for containers. -This concept can be used for additional interfaces to customize a container's runtime environment. -This proposal covers a new interface for resource management on a node with a structured API and plugin design for containers. +### Background -## Lifecycle +The revisited API is a major rewrite of NRI. It changes the scope of NRI +and how it gets integrated into runtimes. It reworks how plugins are +implemented, how they communicate with the runtime, and what kind of +changes they can make to containers. -The big selling point for CNI is that it has a structured interface for modifying the network namespace for a container. -This is different from generic hooks as they lack a type safe API injected into the lifecycle of a container. -The lifecycle point that CNI and NRI plugins will be injected into is the point between `Create` and `Start` of the container's init process. +[NRI v0.1.0](README-v0.1.0.md) used an OCI hook-like one-shot plugin invocation +mechanism where a separate instance of a plugin was spawned for every NRI +event. This instance then used its standard input and output to receive a +request and provide a response, both as JSON data. -`Create->NRI->Start` +Plugins in NRI are daemon-like entities. A single instance of a plugin is +now responsible for handling the full stream of NRI events and requests. A +unix-domain socket is used as the transport for communication. Instead of +JSON requests and responses NRI is defined as a formal, protobuf-based +'NRI plugin protocol' which is compiled into ttRPC bindings. This should +result in improved communication efficiency with lower per-message overhead, +and enable straightforward implementation of stateful NRI plugins. -## Configuration +### Components -Configuration is split into two parts. One is the payload that is specific to a plugin invocation while the second is the host level configuration and options that specify what plugins to run and provide additional configuration to a plugin. +The NRI implementation consists of a number of components. The core of +these are essential for implementing working end-to-end NRI support in +runtimes. These core components are the actual [NRI protocol](pkg/api), +and the [NRI runtime adaptation](pkg/adaptation). -### Filepath and Binaries +Together these establish the model of how a runtime interacts with NRI and +how plugins interact with containers in the runtime through NRI. They also +define under which conditions plugins can make changes to containers and +the extent of these changes. -Plugin binary paths can be configured via the consumer but will default to `/opt/nri/bin`. -Binaries are named with their type as the binary name, same as the CNI plugin naming scheme. +The rest of the components are the [NRI plugin stub library](pkg/stub) +and [some sample NRI plugins](plugins). [Some plugins](plugins/hook-injector) +implement useful functionality in real world scenarios. [A few](plugins/differ) +[others](plugins/logger) are useful for debugging. All of the sample plugins +serve as practical examples of how the stub library can be used to implement +NRI plugins. -### Host Level Config +### Protocol, Plugin API -The config's default location will be `/etc/nri/resource.d/*.conf`. +The core of NRI is defined by a protobuf [protocol definition](pkg/api/api.proto) +of the low-level plugin API. The API defines two services, Runtime and Plugin. -```json -{ - "version": "0.1", - "plugins": [ - { - "type": "konfine", - "conf": { - "systemReserved": [0, 1] - } - }, - { - "type": "clearcfs" - } - ] -} -``` +The Runtime service is the public interface runtimes expose for NRI plugins. All +requests on this interface are initiated by the plugin. The interface provides +functions for -### Input + - initiating plugin registration + - requesting unsolicited updates to containers -Input to a plugin is provided via `STDIN` as a `json` payload. +The Plugin service is the public interface NRI uses to interact with plugins. +All requests on this interface are initiated by NRI/the runtime. The interface +provides functions for -```json -{ - "version": "0.1", - "state": "create", - "id": "redis", - "pid": 1234, - "spec": { - "resources": {}, - "cgroupsPath": "default/redis", - "namespaces": { - "pid": "/proc/44/ns/pid", - "mount": "/proc/44/ns/mnt", - "net": "/proc/44/ns/net" - }, - "annotations": { - "qos.class": "ls" - } - } -} -``` + - configuring the plugin + - getting initial list of already existing pods and containers + - hooking the plugin into pod/container lifecycle events + - shutting down the plugin -### Output +#### Plugin Registration -```json -{ - "version": "0.1", - "state": "create", - "id": "redis", - "pid": 1234, - "cgroupsPath": "qos-ls/default/redis" -} -``` +Before a plugin can start receiving and processing container events, it needs +to register itself with NRI. During registration the plugin and NRI perform a +handshake sequence which consists of the following steps: -## Commands + 1. the plugin identifies itself to the runtime + 2. NRI provides plugin-specific configuration data to the plugin + 3. the plugin subscribes to pod and container lifecycle events of interest + 4. NRI sends list of existing pods and containers to plugin + 5. the plugin requests any updates deemed necessary to existing containers -* Invoke - provides invocations into different lifecycle changes of a container - - states: `setup|pause|resume|update|delete` +The plugin identifies itself to NRI by a plugin name and a plugin index. The +plugin index is used by NRI to determine in which order the plugin is hooked +into pod and container lifecycle event processing with respect to any other +plugins. -## Packages +The plugin name is used to pick plugin-specific data to send to the plugin +as configuration. This data is only present if the plugin has been launched +by NRI. If the plugin has been externally started it is expected to acquire +its configuration also by external means. The plugin subscribes to pod and +container lifecycle events of interest in its response to configuration. -A Go based API and client package will be created for both producers of plugins and consumers, commonly being the container runtime (containerd). +As the last step in the registration and handshaking process, NRI sends the +full set of pods and containers known to the runtime. The plugin can request +updates it considers necessary to any of the known containers in response. -### Sample Plugin +Once the handshake sequence is over and the plugin has registered with NRI, +it will start receiving pod and container lifecycle events according to its +subscription. -**clearcfs** +#### Pod Data and Available Lifecycle Events -Clear the cfs quotas for `ls` services. +
+NRI Pod Lifecycle Events +

+ +

+
+ +NRI plugins can subscribe to the following pod lifecycle events: + + - creation + - stopping + - removal + +The following pieces of pod metadata are available to plugins in NRI: + + - ID + - name + - UID + - namespace + - labels + - annotations + - cgroup parent directory + - runtime handler name + +#### Container Data and Available Lifecycle Events + +
+NRI Container Lifecycle Events +

+ +

+
+ +NRI plugins can subscribe to the following container lifecycle events: + + - creation (*) + - post-creation + - starting + - post-start + - updating (*) + - post-update + - stopping (*) + - removal + +*) Plugins can request adjustment or updates to containers in response to +these events. + +The following pieces of container metadata are available to plugins in NRI: + + - ID + - pod ID + - name + - state + - labels + - annotations + - command line arguments + - environment variables + - mounts + - OCI hooks + - linux + - namespace IDs + - devices + - resources + - memory + - limit + - reservation + - swap limit + - kernel limit + - kernel TCP limit + - swappiness + - OOM disabled flag + - hierarchical accounting flag + - hugepage limits + - CPU + - shares + - quota + - period + - realtime runtime + - realtime period + - cpuset CPUs + - cpuset memory + - Block I/O class + - RDT class + +Apart from data identifying the container, these pieces of information +represent the corresponding data in the container's OCI Spec. + +#### Container Adjustment + +During container creation plugins can request changes to the following +container parameters: + + - annotations + - mounts + - environment variables + - OCI hooks + - linux + - devices + - resources + - memory + - limit + - reservation + - swap limit + - kernel limit + - kernel TCP limit + - swappiness + - OOM disabled flag + - hierarchical accounting flag + - hugepage limits + - CPU + - shares + - quota + - period + - realtime runtime + - realtime period + - cpuset CPUs + - cpuset memory + - Block I/O class + - RDT class + +#### Container Updates + +Once a container has been created plugins can request updates to them. +These updates can be requested in response to another containers creation +request, in response to any containers update request, in response to any +containers stop request, or they can be requested as part of a separate +unsolicited container update request. The following container parameters +can be updated this way: + + - resources + - memory + - limit + - reservation + - swap limit + - kernel limit + - kernel TCP limit + - swappiness + - OOM disabled flag + - hierarchical accounting flag + - hugepage limits + - CPU + - shares + - quota + - period + - realtime runtime + - realtime period + - cpuset CPUs + - cpuset memory + - Block I/O class + - RDT class -```go -package main +### Runtime Adaptation -import ( - "context" - "fmt" - "os" +The NRI [runtime adaptation](pkg/adaptation) package is the interface +runtimes use to integrate to NRI and interact with NRI plugins. It +implements basic plugin discovery, startup and configuration. It also +provides the functions necessary to hook NRI plugins into lifecycle +events of pods and containers from the runtime. - "github.com/containerd/containerd/pkg/nri/skel" - "github.com/containerd/containerd/pkg/nri/types" - "github.com/sirupsen/logrus" -) +The package hides the fact that multiple NRI plugins might be processing +any single pod or container lifecycle event. It takes care of invoking +plugins in the correct order and combining responses by multiple plugins +into a single one. While combining responses, the package detects any +unintentional conflicting changes made by multiple plugins to a single +container and flags such an event as an error to the runtime. -var max = []byte("max") +### Wrapped OCI Spec Generator -// clearCFS clears any cfs quotas for the containers -type clearCFS struct { -} +The [OCI Spec generator](pkg/runtime-tools/generate) package wraps the +[corresponding package](https://github.com/opencontainers/runtime-tools/tree/master/generate) +and adds functions for applying NRI container adjustments and updates to +OCI Specs. This package can be used by runtime NRI integration code to +apply NRI responses to containers. -func (c *clearCFS) Type() string { - return "clearcfs" -} +### Plugin Stub Library -func (c *clearCFS) Invoke(ctx context.Context, r *types.Request) (*types.Result, error) { - result := r.NewResult() - if r.State != types.Create { - return result, nil - } - switch r.Spec.Annotations["qos.class"] { - case "ls": - logrus.Debugf("clearing cfs for %s", r.ID) - group, err := cg.Load(r.Spec.CgroupsPath) - if err != nil { - return nil, err - } - return result, group.Write(cg.CFSMax) - } - return result, nil -} +The plugin stub hides many of the low-level details of implementing an NRI +plugin. It takes care of connection establishment, plugin registration, +configuration, and event subscription. All [sample plugins](pkg/plugins) +are implemented using the stub. Any of these can be used as a tutorial on +how the stub library should be used. -func main() { - ctx := context.Background() - if err := skel.Run(ctx, &clearCFS{}); err != nil { - fmt.Fprintf(os.Stderr, "%s", err) - os.Exit(1) - } -} -``` +### Sample Plugins -## Project details +The following sample plugins exist for NRI: -nri is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE). -As a containerd sub-project, you will find the: + - [logger](plugins/logger) + - [differ](plugins/differ) + - [device injector](plugins/device-injector) + - [OCI hook injector](plugins/hook-injector) + - [NRI v0.1.0 plugin adapter](plugins/v010-adapter) - * [Project governance](https://github.com/containerd/project/blob/master/GOVERNANCE.md), - * [Maintainers](https://github.com/containerd/project/blob/master/MAINTAINERS), - * and [Contributing guidelines](https://github.com/containerd/project/blob/master/CONTRIBUTING.md) - -information in our [`containerd/project`](https://github.com/containerd/project) repository. +Please see the documentation of these plugins for further details +about what and how each of these plugins can be used for. diff --git a/vendor/github.com/containerd/nri/client.go b/vendor/github.com/containerd/nri/client.go index 78c8fd094..63227c881 100644 --- a/vendor/github.com/containerd/nri/client.go +++ b/vendor/github.com/containerd/nri/client.go @@ -28,7 +28,6 @@ import ( "github.com/containerd/containerd" "github.com/containerd/containerd/oci" types "github.com/containerd/nri/types/v1" - "github.com/pkg/errors" ) const ( @@ -107,7 +106,7 @@ func (c *Client) InvokeWithSandbox(ctx context.Context, task containerd.Task, st r.Conf = p.Conf result, err := c.invokePlugin(ctx, p.Type, r) if err != nil { - return nil, errors.Wrapf(err, "plugin: %s", p.Type) + return nil, fmt.Errorf("plugin: %s: %w", p.Type, err) } r.Results = append(r.Results, result) } @@ -141,7 +140,7 @@ func (c *Client) invokePlugin(ctx context.Context, name string, r *types.Request } var result types.Result if err := json.Unmarshal(out, &result); err != nil { - return nil, errors.Errorf("failed to unmarshal plugin output: %s: %s", err.Error(), msg) + return nil, fmt.Errorf("failed to unmarshal plugin output %s: %w", msg, err) } if result.Err() != nil { return nil, result.Err() diff --git a/vendor/github.com/containerd/nri/pkg/adaptation/adaptation.go b/vendor/github.com/containerd/nri/pkg/adaptation/adaptation.go new file mode 100644 index 000000000..f472cdc8a --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/adaptation/adaptation.go @@ -0,0 +1,504 @@ +/* + 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 adaptation + +import ( + "context" + "errors" + "fmt" + "io/fs" + "net" + "os" + "path/filepath" + "sort" + "sync" + + "github.com/containerd/nri/pkg/api" + "github.com/containerd/nri/pkg/log" +) + +const ( + // DefaultConfigPath is the default path to the NRI configuration. + DefaultConfigPath = "/etc/nri/nri.conf" + // DefaultPluginPath is the default path to search for NRI plugins. + DefaultPluginPath = "/opt/nri/plugins" + // DefaultSocketPath is the default socket path for external plugins. + DefaultSocketPath = api.DefaultSocketPath +) + +// SyncFn is a container runtime function for state synchronization. +type SyncFn func(context.Context, SyncCB) error + +// SyncCB is an NRI function used to synchronize plugins with the runtime. +type SyncCB func(context.Context, []*PodSandbox, []*Container) ([]*ContainerUpdate, error) + +// UpdateFn is a container runtime function for unsolicited container updates. +type UpdateFn func(context.Context, []*ContainerUpdate) ([]*ContainerUpdate, error) + +// Adaptation is the NRI abstraction for container runtime NRI adaptation/integration. +type Adaptation struct { + sync.Mutex + name string + version string + configPath string + pluginPath string + socketPath string + syncFn SyncFn + updateFn UpdateFn + cfg *Config + listener net.Listener + plugins []*plugin +} + +var ( + // Used instead of nil Context in logging. + noCtx = context.TODO() +) + +// Option to apply to the NRI runtime. +type Option func(*Adaptation) error + +// WithConfigPath returns an option to override the default NRI config path. +func WithConfigPath(path string) Option { + return func(r *Adaptation) error { + r.configPath = path + return nil + } +} + +// WithConfig returns an option to provide a pre-parsed NRI configuration. +func WithConfig(cfg *Config) Option { + return func(r *Adaptation) error { + r.cfg = cfg + r.configPath = cfg.path + return nil + } +} + +// WithPluginPath returns an option to override the default NRI plugin path. +func WithPluginPath(path string) Option { + return func(r *Adaptation) error { + r.pluginPath = path + return nil + } +} + +// WithSocketPath returns an option to override the default NRI socket path. +func WithSocketPath(path string) Option { + return func(r *Adaptation) error { + r.socketPath = path + return nil + } +} + +// New creates a new NRI Runtime. +func New(name, version string, syncFn SyncFn, updateFn UpdateFn, opts ...Option) (*Adaptation, error) { + var err error + + r := &Adaptation{ + name: name, + version: version, + syncFn: syncFn, + updateFn: updateFn, + configPath: DefaultConfigPath, + pluginPath: DefaultPluginPath, + socketPath: DefaultSocketPath, + } + + for _, o := range opts { + if err = o(r); err != nil { + return nil, fmt.Errorf("failed to apply option: %w", err) + } + } + + if r.cfg == nil { + if r.cfg, err = ReadConfig(r.configPath); err != nil { + return nil, err + } + } + + log.Infof(noCtx, "runtime interface created") + + return r, nil +} + +// Start up the NRI runtime. +func (r *Adaptation) Start() error { + log.Infof(noCtx, "runtime interface starting up...") + + r.Lock() + defer r.Unlock() + + if err := r.startPlugins(); err != nil { + return err + } + + if err := r.startListener(); err != nil { + return err + } + + return nil +} + +// Stop the NRI runtime. +func (r *Adaptation) Stop() { + log.Infof(noCtx, "runtime interface shutting down...") + + r.Lock() + defer r.Unlock() + + r.stopListener() + r.stopPlugins() +} + +// RunPodSandbox relays the corresponding CRI event to plugins. +func (r *Adaptation) RunPodSandbox(ctx context.Context, evt *StateChangeEvent) error { + evt.Event = Event_RUN_POD_SANDBOX + return r.StateChange(ctx, evt) +} + +// StopPodSandbox relays the corresponding CRI event to plugins. +func (r *Adaptation) StopPodSandbox(ctx context.Context, evt *StateChangeEvent) error { + evt.Event = Event_STOP_POD_SANDBOX + return r.StateChange(ctx, evt) +} + +// RemovePodSandbox relays the corresponding CRI event to plugins. +func (r *Adaptation) RemovePodSandbox(ctx context.Context, evt *StateChangeEvent) error { + evt.Event = Event_REMOVE_POD_SANDBOX + return r.StateChange(ctx, evt) +} + +// CreateContainer relays the corresponding CRI request to plugins. +func (r *Adaptation) CreateContainer(ctx context.Context, req *CreateContainerRequest) (*CreateContainerResponse, error) { + r.Lock() + defer r.Unlock() + defer r.removeClosedPlugins() + + result := collectCreateContainerResult(req) + for _, plugin := range r.plugins { + rpl, err := plugin.createContainer(ctx, req) + if err != nil { + return nil, err + } + err = result.apply(rpl, plugin.name()) + if err != nil { + return nil, err + } + } + + return result.createContainerResponse(), nil +} + +// PostCreateContainer relays the corresponding CRI event to plugins. +func (r *Adaptation) PostCreateContainer(ctx context.Context, evt *StateChangeEvent) error { + evt.Event = Event_POST_CREATE_CONTAINER + return r.StateChange(ctx, evt) +} + +// StartContainer relays the corresponding CRI event to plugins. +func (r *Adaptation) StartContainer(ctx context.Context, evt *StateChangeEvent) error { + evt.Event = Event_START_CONTAINER + return r.StateChange(ctx, evt) +} + +// PostStartContainer relays the corresponding CRI event to plugins. +func (r *Adaptation) PostStartContainer(ctx context.Context, evt *StateChangeEvent) error { + evt.Event = Event_POST_START_CONTAINER + return r.StateChange(ctx, evt) +} + +// UpdateContainer relays the corresponding CRI request to plugins. +func (r *Adaptation) UpdateContainer(ctx context.Context, req *UpdateContainerRequest) (*UpdateContainerResponse, error) { + r.Lock() + defer r.Unlock() + defer r.removeClosedPlugins() + + result := collectUpdateContainerResult(req) + for _, plugin := range r.plugins { + rpl, err := plugin.updateContainer(ctx, req) + if err != nil { + return nil, err + } + err = result.apply(rpl, plugin.name()) + if err != nil { + return nil, err + } + } + + return result.updateContainerResponse(), nil +} + +// PostUpdateContainer relays the corresponding CRI event to plugins. +func (r *Adaptation) PostUpdateContainer(ctx context.Context, evt *StateChangeEvent) error { + evt.Event = Event_POST_UPDATE_CONTAINER + return r.StateChange(ctx, evt) +} + +// StopContainer relays the corresponding CRI request to plugins. +func (r *Adaptation) StopContainer(ctx context.Context, req *StopContainerRequest) (*StopContainerResponse, error) { + r.Lock() + defer r.Unlock() + defer r.removeClosedPlugins() + + result := collectStopContainerResult() + for _, plugin := range r.plugins { + rpl, err := plugin.stopContainer(ctx, req) + if err != nil { + return nil, err + } + err = result.apply(rpl, plugin.name()) + if err != nil { + return nil, err + } + } + + return result.stopContainerResponse(), nil +} + +// RemoveContainer relays the corresponding CRI event to plugins. +func (r *Adaptation) RemoveContainer(ctx context.Context, evt *StateChangeEvent) error { + evt.Event = Event_REMOVE_CONTAINER + return r.StateChange(ctx, evt) +} + +// StateChange relays pod- or container events to plugins. +func (r *Adaptation) StateChange(ctx context.Context, evt *StateChangeEvent) error { + if evt.Event == Event_UNKNOWN { + return errors.New("invalid (unset) event in state change notification") + } + + r.Lock() + defer r.Unlock() + defer r.removeClosedPlugins() + + for _, plugin := range r.plugins { + err := plugin.StateChange(ctx, evt) + if err != nil { + return err + } + } + + return nil +} + +// Perform a set of unsolicited container updates requested by a plugin. +func (r *Adaptation) updateContainers(ctx context.Context, req []*ContainerUpdate) ([]*ContainerUpdate, error) { + r.Lock() + defer r.Unlock() + + return r.updateFn(ctx, req) +} + +// Start up pre-installed plugins. +func (r *Adaptation) startPlugins() (retErr error) { + var plugins []*plugin + + log.Infof(noCtx, "starting plugins...") + + ids, names, configs, err := r.discoverPlugins() + if err != nil { + return err + } + + defer func() { + if retErr != nil { + for _, p := range plugins { + p.stop() + } + } + }() + + for i, name := range names { + log.Infof(noCtx, "starting plugin %q...", name) + + id := ids[i] + + p, err := newLaunchedPlugin(r.pluginPath, id, name, configs[i]) + if err != nil { + return fmt.Errorf("failed to start NRI plugin %q: %w", name, err) + } + + if err := p.start(r.name, r.version); err != nil { + return err + } + + plugins = append(plugins, p) + } + + r.plugins = plugins + r.sortPlugins() + + return nil +} + +// Stop plugins. +func (r *Adaptation) stopPlugins() { + log.Infof(noCtx, "stopping plugins...") + + for _, p := range r.plugins { + p.stop() + } + r.plugins = nil +} + +func (r *Adaptation) removeClosedPlugins() { + active := []*plugin{} + for _, p := range r.plugins { + if !p.isClosed() { + active = append(active, p) + } + } + r.plugins = active +} + +func (r *Adaptation) startListener() error { + if r.cfg.DisableConnections { + log.Infof(noCtx, "connection from external plugins disabled") + return nil + } + + os.Remove(r.socketPath) + if err := os.MkdirAll(filepath.Dir(r.socketPath), 0755); err != nil { + return fmt.Errorf("failed to create socket %q: %w", r.socketPath, err) + } + + l, err := net.ListenUnix("unix", &net.UnixAddr{ + Name: r.socketPath, + Net: "unix", + }) + if err != nil { + return fmt.Errorf("failed to create socket %q: %w", r.socketPath, err) + } + + r.acceptPluginConnections(l) + + return nil +} + +func (r *Adaptation) stopListener() { + if r.listener != nil { + r.listener.Close() + } +} + +func (r *Adaptation) acceptPluginConnections(l net.Listener) error { + r.listener = l + + ctx := context.Background() + go func() { + for { + conn, err := l.Accept() + if err != nil { + log.Infof(ctx, "stopped accepting plugin connections (%v)", err) + return + } + + p, err := newExternalPlugin(conn) + if err != nil { + log.Errorf(ctx, "failed to create external plugin: %v", err) + continue + } + + if err := p.start(r.name, r.version); err != nil { + log.Errorf(ctx, "failed to start external plugin: %v", err) + continue + } + + r.Lock() + + err = r.syncFn(ctx, p.synchronize) + if err != nil { + log.Infof(ctx, "failed to synchronize plugin: %v", err) + } else { + r.plugins = append(r.plugins, p) + r.sortPlugins() + } + + r.Unlock() + + log.Infof(ctx, "plugin %q connected", p.name()) + } + }() + + return nil +} + +func (r *Adaptation) discoverPlugins() ([]string, []string, []string, error) { + var ( + plugins []string + indices []string + configs []string + entries []os.DirEntry + info fs.FileInfo + err error + ) + + if entries, err = os.ReadDir(r.pluginPath); err != nil { + if os.IsNotExist(err) { + return nil, nil, nil, nil + } + return nil, nil, nil, fmt.Errorf("failed to discover plugins in %s: %w", + r.pluginPath, err) + } + + for _, e := range entries { + if e.IsDir() { + continue + } + if info, err = e.Info(); err != nil { + continue + } + if info.Mode()&fs.FileMode(0o111) == 0 { + continue + } + + name := e.Name() + idx, base, err := api.ParsePluginName(name) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to discover plugins in %s: %w", + r.pluginPath, err) + } + + cfg, err := r.cfg.getPluginConfig(idx, base) + if err != nil { + return nil, nil, nil, fmt.Errorf("failed to discover plugins in %s: %w", + r.pluginPath, err) + } + + log.Infof(noCtx, "discovered plugin %s", name) + + indices = append(indices, idx) + plugins = append(plugins, base) + configs = append(configs, cfg) + } + + return indices, plugins, configs, nil +} + +func (r *Adaptation) sortPlugins() { + r.removeClosedPlugins() + sort.Slice(r.plugins, func(i, j int) bool { + return r.plugins[i].idx < r.plugins[j].idx + }) + if len(r.plugins) > 0 { + log.Infof(noCtx, "plugin invocation order") + for i, p := range r.plugins { + log.Infof(noCtx, " #%d: %q (%s)", i+1, p.name(), p.qualifiedName()) + } + } +} diff --git a/vendor/github.com/containerd/nri/pkg/adaptation/api.go b/vendor/github.com/containerd/nri/pkg/adaptation/api.go new file mode 100644 index 000000000..bc8ada065 --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/adaptation/api.go @@ -0,0 +1,151 @@ +/* + 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 adaptation + +import ( + "github.com/containerd/nri/pkg/api" +) + +// +// Alias types, consts and functions from api for the runtime. +// + +// Aliased request/response/event types for api/api.proto. +// nolint +type ( + RegisterPluginRequest = api.RegisterPluginRequest + RegisterPluginResponse = api.Empty + UpdateContainersRequest = api.UpdateContainersRequest + UpdateContainersResponse = api.UpdateContainersResponse + + ConfigureRequest = api.ConfigureRequest + ConfigureResponse = api.ConfigureResponse + SynchronizeRequest = api.SynchronizeRequest + SynchronizeResponse = api.SynchronizeResponse + + CreateContainerRequest = api.CreateContainerRequest + CreateContainerResponse = api.CreateContainerResponse + UpdateContainerRequest = api.UpdateContainerRequest + UpdateContainerResponse = api.UpdateContainerResponse + StopContainerRequest = api.StopContainerRequest + StopContainerResponse = api.StopContainerResponse + + StateChangeEvent = api.StateChangeEvent + StateChangeResponse = api.StateChangeResponse + RunPodSandboxRequest = api.RunPodSandboxRequest + StopPodSandboxRequest = api.StopPodSandboxRequest + RemovePodSandboxRequest = api.RemovePodSandboxRequest + StartContainerRequest = api.StartContainerRequest + StartContainerResponse = api.StartContainerResponse + RemoveContainerRequest = api.RemoveContainerRequest + RemoveContainerResponse = api.RemoveContainerResponse + PostCreateContainerRequest = api.PostCreateContainerRequest + PostCreateContainerResponse = api.PostCreateContainerResponse + PostStartContainerRequest = api.PostStartContainerRequest + PostStartContainerResponse = api.PostStartContainerResponse + PostUpdateContainerRequest = api.PostUpdateContainerRequest + PostUpdateContainerResponse = api.PostUpdateContainerResponse + + PodSandbox = api.PodSandbox + LinuxPodSandbox = api.LinuxPodSandbox + Container = api.Container + ContainerAdjustment = api.ContainerAdjustment + LinuxContainerAdjustment = api.LinuxContainerAdjustment + ContainerUpdate = api.ContainerUpdate + LinuxContainerUpdate = api.LinuxContainerUpdate + ContainerEviction = api.ContainerEviction + ContainerState = api.ContainerState + KeyValue = api.KeyValue + Mount = api.Mount + LinuxContainer = api.LinuxContainer + LinuxNamespace = api.LinuxNamespace + LinuxResources = api.LinuxResources + LinuxCPU = api.LinuxCPU + LinuxMemory = api.LinuxMemory + LinuxDevice = api.LinuxDevice + LinuxDeviceCgroup = api.LinuxDeviceCgroup + HugepageLimit = api.HugepageLimit + Hooks = api.Hooks + Hook = api.Hook + + EventMask = api.EventMask +) + +// Aliased consts for api/api.proto. +// nolint +const ( + Event_UNKNOWN = api.Event_UNKNOWN + Event_RUN_POD_SANDBOX = api.Event_RUN_POD_SANDBOX + Event_STOP_POD_SANDBOX = api.Event_STOP_POD_SANDBOX + Event_REMOVE_POD_SANDBOX = api.Event_REMOVE_POD_SANDBOX + Event_CREATE_CONTAINER = api.Event_CREATE_CONTAINER + Event_POST_CREATE_CONTAINER = api.Event_POST_CREATE_CONTAINER + Event_START_CONTAINER = api.Event_START_CONTAINER + Event_POST_START_CONTAINER = api.Event_POST_START_CONTAINER + Event_UPDATE_CONTAINER = api.Event_UPDATE_CONTAINER + Event_POST_UPDATE_CONTAINER = api.Event_POST_UPDATE_CONTAINER + Event_STOP_CONTAINER = api.Event_STOP_CONTAINER + Event_REMOVE_CONTAINER = api.Event_REMOVE_CONTAINER + ValidEvents = api.ValidEvents + + ContainerState_CONTAINER_UNKNOWN = api.ContainerState_CONTAINER_UNKNOWN + ContainerState_CONTAINER_CREATED = api.ContainerState_CONTAINER_CREATED + ContainerState_CONTAINER_PAUSED = api.ContainerState_CONTAINER_PAUSED + ContainerState_CONTAINER_RUNNING = api.ContainerState_CONTAINER_RUNNING + ContainerState_CONTAINER_STOPPED = api.ContainerState_CONTAINER_STOPPED + ContainerState_CONTAINER_EXITED = api.ContainerState_CONTAINER_STOPPED +) + +// Aliased types for api/optional.go. +// nolint +type ( + OptionalString = api.OptionalString + OptionalInt = api.OptionalInt + OptionalInt32 = api.OptionalInt32 + OptionalUInt32 = api.OptionalUInt32 + OptionalInt64 = api.OptionalInt64 + OptionalUInt64 = api.OptionalUInt64 + OptionalBool = api.OptionalBool + OptionalFileMode = api.OptionalFileMode +) + +// Aliased functions for api/optional.go. +// nolint +var ( + String = api.String + Int = api.Int + Int32 = api.Int32 + UInt32 = api.UInt32 + Int64 = api.Int64 + UInt64 = api.UInt64 + Bool = api.Bool + FileMode = api.FileMode +) + +// Aliased functions for api/types.go. +// nolint +var ( + FromOCIMounts = api.FromOCIMounts + FromOCIHooks = api.FromOCIHooks + FromOCILinuxNamespaces = api.FromOCILinuxNamespaces + FromOCILinuxDevices = api.FromOCILinuxDevices + FromOCILinuxResources = api.FromOCILinuxResources + DupStringSlice = api.DupStringSlice + DupStringMap = api.DupStringMap + IsMarkedForRemoval = api.IsMarkedForRemoval + MarkForRemoval = api.MarkForRemoval +) diff --git a/vendor/github.com/containerd/nri/pkg/adaptation/config.go b/vendor/github.com/containerd/nri/pkg/adaptation/config.go new file mode 100644 index 000000000..049ea7bac --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/adaptation/config.go @@ -0,0 +1,95 @@ +/* + 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 adaptation + +import ( + "fmt" + "os" + "path/filepath" + + "sigs.k8s.io/yaml" +) + +const ( + // PluginConfigSubdir is the drop-in directory for plugin configuration. + PluginConfigSubdir = "conf.d" +) + +// Config is the runtime configuration for NRI. +type Config struct { + // DisableConnections disables plugin-initiated connections. + DisableConnections bool `json:"disableConnections"` + + path string + dropIn string +} + +// DefaultConfig returns the default NRI configuration for a given path. +// This configuration should be identical to what ReadConfig would return +// for an empty file at the given location. If the given path is empty, +// DefaultConfigPath is used instead. +func DefaultConfig(path string) *Config { + if path == "" { + path = DefaultConfigPath + } + return &Config{ + path: path, + dropIn: filepath.Join(filepath.Dir(path), PluginConfigSubdir), + } +} + +// ReadConfig reads the NRI runtime configuration from a file. +func ReadConfig(path string) (*Config, error) { + buf, err := os.ReadFile(path) + if os.IsNotExist(err) { + return nil, err + } + if err != nil { + return nil, fmt.Errorf("failed to read file %q: %w", path, err) + } + + cfg := &Config{} + err = yaml.UnmarshalStrict(buf, cfg) + if err != nil { + return nil, fmt.Errorf("failed to parse file %q: %w", path, err) + } + + cfg.path = path + cfg.dropIn = filepath.Join(filepath.Dir(path), PluginConfigSubdir) + + return cfg, nil +} + +func (cfg *Config) getPluginConfig(id, base string) (string, error) { + name := id + "-" + base + dropIns := []string{ + filepath.Join(cfg.dropIn, name+".conf"), + filepath.Join(cfg.dropIn, base+".conf"), + } + + for _, path := range dropIns { + buf, err := os.ReadFile(path) + if err == nil { + return string(buf), nil + } + if !os.IsNotExist(err) { + return "", fmt.Errorf("failed to read configuration for plugin %q: %w", name, err) + } + } + + return "", nil +} diff --git a/vendor/github.com/containerd/nri/pkg/adaptation/plugin.go b/vendor/github.com/containerd/nri/pkg/adaptation/plugin.go new file mode 100644 index 000000000..70600538d --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/adaptation/plugin.go @@ -0,0 +1,468 @@ +/* + 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 adaptation + +import ( + "context" + "errors" + "fmt" + stdnet "net" + "os" + "os/exec" + "path/filepath" + "strconv" + "sync" + "time" + + "github.com/containerd/nri/pkg/api" + "github.com/containerd/nri/pkg/log" + "github.com/containerd/nri/pkg/net" + "github.com/containerd/nri/pkg/net/multiplex" + "github.com/containerd/ttrpc" +) + +const ( + pluginRegistrationTimeout = 2 * time.Second + pluginRequestTimeout = 2 * time.Second +) + +type plugin struct { + sync.Mutex + idx string + base string + cfg string + pid int + cmd *exec.Cmd + mux multiplex.Mux + rpcc *ttrpc.Client + rpcl stdnet.Listener + rpcs *ttrpc.Server + events EventMask + closed bool + stub api.PluginService + regC chan error + closeC chan struct{} + r *Adaptation +} + +// Launch a pre-installed plugin with a pre-connected socketpair. +func newLaunchedPlugin(dir, idx, base, cfg string) (p *plugin, retErr error) { + name := idx + "-" + base + + sockets, err := net.NewSocketPair() + if err != nil { + return nil, fmt.Errorf("failed to create plugin connection for plugin %q: %w", name, err) + } + defer sockets.Close() + + conn, err := sockets.LocalConn() + if err != nil { + return nil, fmt.Errorf("failed to set up local connection for plugin %q: %w", name, err) + } + + peerFile := sockets.PeerFile() + defer func() { + peerFile.Close() + if retErr != nil { + conn.Close() + } + }() + + cmd := exec.Command(filepath.Join(dir, name)) + cmd.ExtraFiles = []*os.File{peerFile} + cmd.Env = []string{ + api.PluginNameEnvVar + "=" + name, + api.PluginIdxEnvVar + "=" + idx, + api.PluginSocketEnvVar + "=3", + } + + p = &plugin{ + cfg: cfg, + cmd: cmd, + idx: idx, + base: base, + regC: make(chan error, 1), + closeC: make(chan struct{}), + } + + if err = p.cmd.Start(); err != nil { + return nil, fmt.Errorf("failed launch plugin %q: %w", p.name(), err) + } + + if err = p.connect(conn); err != nil { + return nil, err + } + + return p, nil +} + +// Create a plugin (stub) for an accepted external plugin connection. +func newExternalPlugin(conn stdnet.Conn) (p *plugin, retErr error) { + p = &plugin{ + regC: make(chan error, 1), + closeC: make(chan struct{}), + } + if err := p.connect(conn); err != nil { + return nil, err + } + + return p, nil +} + +// Check if the plugin is external (was not launched by us). +func (p *plugin) isExternal() bool { + return p.cmd == nil +} + +// 'connect' a plugin, setting up multiplexing on its socket. +func (p *plugin) connect(conn stdnet.Conn) (retErr error) { + mux := multiplex.Multiplex(conn, multiplex.WithBlockedRead()) + defer func() { + if retErr != nil { + mux.Close() + } + }() + + pconn, err := mux.Open(multiplex.PluginServiceConn) + if err != nil { + return fmt.Errorf("failed to mux plugin connection for plugin %q: %w", p.name(), err) + } + rpcc := ttrpc.NewClient(pconn, ttrpc.WithOnClose( + func() { + log.Infof(noCtx, "connection to plugin %q closed", p.name()) + close(p.closeC) + p.close() + })) + defer func() { + if retErr != nil { + rpcc.Close() + } + }() + stub := api.NewPluginClient(rpcc) + + rpcs, err := ttrpc.NewServer() + if err != nil { + return fmt.Errorf("failed to create ttrpc server for plugin %q: %w", p.name(), err) + } + defer func() { + if retErr != nil { + rpcs.Close() + } + }() + + rpcl, err := mux.Listen(multiplex.RuntimeServiceConn) + if err != nil { + return fmt.Errorf("failed to create mux runtime listener for plugin %q: %w", p.name(), err) + } + + p.mux = mux + p.rpcc = rpcc + p.rpcl = rpcl + p.rpcs = rpcs + p.stub = stub + + p.pid, err = getPeerPid(p.mux.Trunk()) + if err != nil { + log.Warnf(noCtx, "failed to determine plugin pid pid: %v", err) + } + + api.RegisterRuntimeService(p.rpcs, p) + + return nil +} + +// Start Runtime service, wait for plugin to register, then configure it. +func (p *plugin) start(name, version string) error { + var err error + + go func() { + err := p.rpcs.Serve(context.Background(), p.rpcl) + if err != ttrpc.ErrServerClosed { + log.Infof(noCtx, "ttrpc server for plugin %q closed (%v)", p.name(), err) + } + p.close() + }() + + p.mux.Unblock() + + select { + case err = <-p.regC: + if err != nil { + return fmt.Errorf("failed to register plugin: %w", err) + } + case <-p.closeC: + return fmt.Errorf("failed to register plugin, connection closed: %w", err) + case <-time.After(pluginRegistrationTimeout): + p.close() + p.stop() + return errors.New("plugin registration timed out") + } + + err = p.configure(context.Background(), name, version, p.cfg) + if err != nil { + p.close() + p.stop() + return err + } + + return nil +} + +// close a plugin shutting down its multiplexed ttrpc connections. +func (p *plugin) close() { + p.Lock() + defer p.Unlock() + if p.closed { + return + } + + p.closed = true + p.mux.Close() + p.rpcc.Close() + p.rpcs.Close() + p.rpcl.Close() +} + +func (p *plugin) isClosed() bool { + p.Lock() + defer p.Unlock() + return p.closed +} + +// stop a plugin (if it was launched by us) +func (p *plugin) stop() error { + if p.isExternal() || p.cmd.Process == nil { + return nil + } + + // TODO(klihub): + // We should attempt a graceful shutdown of the process here... + // - send it SIGINT + // - give the it some slack waiting with a timeout + // - butcher it with SIGKILL after the timeout + + p.cmd.Process.Kill() + p.cmd.Process.Wait() + p.cmd.Process.Release() + + return nil +} + +// Name returns a string indentication for the plugin. +func (p *plugin) name() string { + return p.idx + "-" + p.base +} + +func (p *plugin) qualifiedName() string { + var kind, idx, base string + if p.isExternal() { + kind = "external" + } else { + kind = "pre-connected" + } + if idx = p.idx; idx == "" { + idx = "??" + } + if base = p.base; base == "" { + base = "plugin" + } + return kind + ":" + idx + "-" + base + "[" + strconv.Itoa(p.pid) + "]" +} + +// RegisterPlugin handles the plugin's registration request. +func (p *plugin) RegisterPlugin(ctx context.Context, req *RegisterPluginRequest) (*RegisterPluginResponse, error) { + if p.isExternal() { + if req.PluginName == "" { + p.regC <- fmt.Errorf("plugin %q registered empty name", p.qualifiedName()) + return &RegisterPluginResponse{}, errors.New("invalid (empty) plugin name") + } + if err := api.CheckPluginIndex(req.PluginIdx); err != nil { + p.regC <- fmt.Errorf("plugin %q registered invalid index: %w", req.PluginName, err) + return &RegisterPluginResponse{}, fmt.Errorf("invalid plugin index: %w", err) + } + p.base = req.PluginName + p.idx = req.PluginIdx + } + + log.Infof(ctx, "plugin %q registered as %q", p.qualifiedName(), p.name()) + + p.regC <- nil + return &RegisterPluginResponse{}, nil +} + +// UpdateContainers relays container update request to the runtime. +func (p *plugin) UpdateContainers(ctx context.Context, req *UpdateContainersRequest) (*UpdateContainersResponse, error) { + log.Infof(ctx, "plugin %q requested container updates", p.name()) + + failed, err := p.r.updateContainers(ctx, req.Update) + return &UpdateContainersResponse{ + Failed: failed, + }, err +} + +// configure the plugin and subscribe it for the events it requested. +func (p *plugin) configure(ctx context.Context, name, version, config string) error { + ctx, cancel := context.WithTimeout(ctx, pluginRequestTimeout) + defer cancel() + + rpl, err := p.stub.Configure(ctx, &ConfigureRequest{ + Config: config, + RuntimeName: name, + RuntimeVersion: version, + }) + if err != nil { + return fmt.Errorf("failed to configure plugin: %w", err) + } + + events := EventMask(rpl.Events) + if events != 0 { + if extra := events &^ ValidEvents; extra != 0 { + return fmt.Errorf("invalid plugin events: 0x%x", extra) + } + } else { + events = ValidEvents + } + p.events = events + + return nil +} + +// synchronize the plugin with the current state of the runtime. +func (p *plugin) synchronize(ctx context.Context, pods []*PodSandbox, containers []*Container) ([]*ContainerUpdate, error) { + log.Infof(ctx, "synchronizing plugin %s", p.name()) + + ctx, cancel := context.WithTimeout(ctx, pluginRequestTimeout) + defer cancel() + + req := &SynchronizeRequest{ + Pods: pods, + Containers: containers, + } + rpl, err := p.stub.Synchronize(ctx, req) + if err != nil { + return nil, err + } + + return rpl.Update, nil +} + +// Relay CreateContainer request to plugin. +func (p *plugin) createContainer(ctx context.Context, req *CreateContainerRequest) (*CreateContainerResponse, error) { + if !p.events.IsSet(Event_CREATE_CONTAINER) { + return nil, nil + } + + ctx, cancel := context.WithTimeout(ctx, pluginRequestTimeout) + defer cancel() + + rpl, err := p.stub.CreateContainer(ctx, req) + if err != nil { + if isFatalError(err) { + log.Errorf(ctx, "closing plugin %s, failed to handle CreateContainer request: %w", + p.name(), err) + p.close() + return nil, nil + } + return nil, err + } + + return rpl, nil +} + +// Relay UpdateContainer request to plugin. +func (p *plugin) updateContainer(ctx context.Context, req *UpdateContainerRequest) (*UpdateContainerResponse, error) { + if !p.events.IsSet(Event_UPDATE_CONTAINER) { + return nil, nil + } + + ctx, cancel := context.WithTimeout(ctx, pluginRequestTimeout) + defer cancel() + + rpl, err := p.stub.UpdateContainer(ctx, req) + if err != nil { + if isFatalError(err) { + log.Errorf(ctx, "closing plugin %s, failed to handle UpdateContainer request: %w", + p.name(), err) + p.close() + return nil, nil + } + return nil, err + } + + return rpl, nil +} + +// Relay StopContainer request to the plugin. +func (p *plugin) stopContainer(ctx context.Context, req *StopContainerRequest) (*StopContainerResponse, error) { + if !p.events.IsSet(Event_STOP_CONTAINER) { + return nil, nil + } + + ctx, cancel := context.WithTimeout(ctx, pluginRequestTimeout) + defer cancel() + + rpl, err := p.stub.StopContainer(ctx, req) + if err != nil { + if isFatalError(err) { + log.Errorf(ctx, "closing plugin %s, failed to handle StopContainer request: %w", + p.name(), err) + p.close() + return nil, nil + } + return nil, err + } + + return rpl, nil +} + +// Relay other pod or container state change events to the plugin. +func (p *plugin) StateChange(ctx context.Context, evt *StateChangeEvent) error { + if !p.events.IsSet(evt.Event) { + return nil + } + + ctx, cancel := context.WithTimeout(ctx, pluginRequestTimeout) + defer cancel() + + _, err := p.stub.StateChange(ctx, evt) + if err != nil { + if isFatalError(err) { + log.Errorf(ctx, "closing plugin %s, failed to handle event %d: %w", + p.name(), evt.Event, err) + p.close() + return nil + } + return err + } + + return nil +} + +// isFatalError returns true if the error is fatal and the plugin connection shoudld be closed. +func isFatalError(err error) bool { + switch { + case errors.Is(err, ttrpc.ErrClosed): + return true + case errors.Is(err, ttrpc.ErrServerClosed): + return true + case errors.Is(err, ttrpc.ErrProtocol): + return true + case errors.Is(err, context.DeadlineExceeded): + return true + } + return false +} diff --git a/vendor/github.com/containerd/nri/pkg/adaptation/plugin_linux.go b/vendor/github.com/containerd/nri/pkg/adaptation/plugin_linux.go new file mode 100644 index 000000000..7ad493067 --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/adaptation/plugin_linux.go @@ -0,0 +1,55 @@ +//go:build linux +// +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 adaptation + +import ( + "errors" + "fmt" + stdnet "net" + + "golang.org/x/sys/unix" +) + +// getPeerPid returns the process id at the other end of the connection. +func getPeerPid(conn stdnet.Conn) (int, error) { + var cred *unix.Ucred + + uc, ok := conn.(*stdnet.UnixConn) + if !ok { + return 0, errors.New("invalid connection, not *net.UnixConn") + } + + raw, err := uc.SyscallConn() + if err != nil { + return 0, fmt.Errorf("failed get raw unix domain connection: %w", err) + } + + ctrlErr := raw.Control(func(fd uintptr) { + cred, err = unix.GetsockoptUcred(int(fd), unix.SOL_SOCKET, unix.SO_PEERCRED) + }) + if err != nil { + return 0, fmt.Errorf("failed to get process credentials: %w", err) + } + if ctrlErr != nil { + return 0, fmt.Errorf("uc.SyscallConn().Control() failed: %w", ctrlErr) + } + + return int(cred.Pid), nil +} diff --git a/vendor/github.com/containerd/nri/pkg/adaptation/plugin_other.go b/vendor/github.com/containerd/nri/pkg/adaptation/plugin_other.go new file mode 100644 index 000000000..5f962f985 --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/adaptation/plugin_other.go @@ -0,0 +1,31 @@ +//go:build !linux +// +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 adaptation + +import ( + "fmt" + "net" + "runtime" +) + +// getPeerPid returns the process id at the other end of the connection. +func getPeerPid(conn net.Conn) (int, error) { + return 0, fmt.Errorf("getPeerPid() unimplemented on %s", runtime.GOOS) +} diff --git a/vendor/github.com/containerd/nri/pkg/adaptation/result.go b/vendor/github.com/containerd/nri/pkg/adaptation/result.go new file mode 100644 index 000000000..7a7967006 --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/adaptation/result.go @@ -0,0 +1,1245 @@ +/* + 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 adaptation + +import ( + "fmt" + "strings" +) + +type result struct { + request resultRequest + reply resultReply + updates map[string]*ContainerUpdate + owners resultOwners +} + +type resultRequest struct { + create *CreateContainerRequest + update *UpdateContainerRequest +} + +type resultReply struct { + adjust *ContainerAdjustment + update []*ContainerUpdate +} + +type resultOwners map[string]*owners + +func collectCreateContainerResult(request *CreateContainerRequest) *result { + if request.Container.Labels == nil { + request.Container.Labels = map[string]string{} + } + if request.Container.Annotations == nil { + request.Container.Annotations = map[string]string{} + } + if request.Container.Mounts == nil { + request.Container.Mounts = []*Mount{} + } + if request.Container.Env == nil { + request.Container.Env = []string{} + } + if request.Container.Hooks == nil { + request.Container.Hooks = &Hooks{} + } + if request.Container.Linux == nil { + request.Container.Linux = &LinuxContainer{} + } + if request.Container.Linux.Devices == nil { + request.Container.Linux.Devices = []*LinuxDevice{} + } + if request.Container.Linux.Resources == nil { + request.Container.Linux.Resources = &LinuxResources{} + } + if request.Container.Linux.Resources.Memory == nil { + request.Container.Linux.Resources.Memory = &LinuxMemory{} + } + if request.Container.Linux.Resources.Cpu == nil { + request.Container.Linux.Resources.Cpu = &LinuxCPU{} + } + if request.Container.Linux.Resources.Unified == nil { + request.Container.Linux.Resources.Unified = map[string]string{} + } + + return &result{ + request: resultRequest{ + create: request, + }, + reply: resultReply{ + adjust: &ContainerAdjustment{ + Annotations: map[string]string{}, + Mounts: []*Mount{}, + Env: []*KeyValue{}, + Hooks: &Hooks{}, + Linux: &LinuxContainerAdjustment{ + Devices: []*LinuxDevice{}, + Resources: &LinuxResources{ + Memory: &LinuxMemory{}, + Cpu: &LinuxCPU{}, + HugepageLimits: []*HugepageLimit{}, + Unified: map[string]string{}, + }, + }, + }, + }, + updates: map[string]*ContainerUpdate{}, + owners: resultOwners{}, + } +} + +func collectUpdateContainerResult(request *UpdateContainerRequest) *result { + if request != nil { + if request.LinuxResources == nil { + request.LinuxResources = &LinuxResources{} + } + if request.LinuxResources.Memory == nil { + request.LinuxResources.Memory = &LinuxMemory{} + } + if request.LinuxResources.Cpu == nil { + request.LinuxResources.Cpu = &LinuxCPU{} + } + } + + return &result{ + request: resultRequest{ + update: request, + }, + reply: resultReply{ + update: []*ContainerUpdate{}, + }, + updates: map[string]*ContainerUpdate{}, + owners: resultOwners{}, + } +} + +func collectStopContainerResult() *result { + return collectUpdateContainerResult(nil) +} + +func (r *result) createContainerResponse() *CreateContainerResponse { + return &CreateContainerResponse{ + Adjust: r.reply.adjust, + Update: r.reply.update, + } +} + +func (r *result) updateContainerResponse() *UpdateContainerResponse { + requested := r.updates[r.request.update.Container.Id] + return &UpdateContainerResponse{ + Update: append(r.reply.update, requested), + } +} + +func (r *result) stopContainerResponse() *StopContainerResponse { + return &StopContainerResponse{ + Update: r.reply.update, + } +} + +func (r *result) apply(response interface{}, plugin string) error { + switch rpl := response.(type) { + case *CreateContainerResponse: + if rpl == nil { + return nil + } + if err := r.adjust(rpl.Adjust, plugin); err != nil { + return err + } + if err := r.update(rpl.Update, plugin); err != nil { + return err + } + case *UpdateContainerResponse: + if rpl == nil { + return nil + } + if err := r.update(rpl.Update, plugin); err != nil { + return err + } + case *StopContainerResponse: + if rpl == nil { + return nil + } + if err := r.update(rpl.Update, plugin); err != nil { + return err + } + default: + return fmt.Errorf("cannot apply response of invalid type %T", response) + } + + return nil +} + +func (r *result) adjust(rpl *ContainerAdjustment, plugin string) error { + if rpl == nil { + return nil + } + if err := r.adjustAnnotations(rpl.Annotations, plugin); err != nil { + return err + } + if err := r.adjustMounts(rpl.Mounts, plugin); err != nil { + return err + } + if err := r.adjustEnv(rpl.Env, plugin); err != nil { + return err + } + if err := r.adjustHooks(rpl.Hooks, plugin); err != nil { + return err + } + if rpl.Linux != nil { + if err := r.adjustDevices(rpl.Linux.Devices, plugin); err != nil { + return err + } + if err := r.adjustResources(rpl.Linux.Resources, plugin); err != nil { + return err + } + if err := r.adjustCgroupsPath(rpl.Linux.CgroupsPath, plugin); err != nil { + return err + } + } + + return nil +} + +func (r *result) update(updates []*ContainerUpdate, plugin string) error { + for _, u := range updates { + reply, err := r.getContainerUpdate(u, plugin) + if err != nil { + return err + } + if err := r.updateResources(reply, u, plugin); err != nil && !u.IgnoreFailure { + return err + } + } + + return nil +} + +func (r *result) adjustAnnotations(annotations map[string]string, plugin string) error { + if len(annotations) == 0 { + return nil + } + + create, id := r.request.create, r.request.create.Container.Id + del := map[string]struct{}{} + for k := range annotations { + if key, marked := IsMarkedForRemoval(k); marked { + del[key] = struct{}{} + delete(annotations, k) + } + } + + for k, v := range annotations { + if _, ok := del[k]; ok { + r.owners.clearAnnotation(id, k) + delete(create.Container.Annotations, k) + r.reply.adjust.Annotations[MarkForRemoval(k)] = "" + } + if err := r.owners.claimAnnotation(id, k, plugin); err != nil { + return err + } + create.Container.Annotations[k] = v + r.reply.adjust.Annotations[k] = v + delete(del, k) + } + + for k := range del { + r.reply.adjust.Annotations[MarkForRemoval(k)] = "" + } + + return nil +} + +func (r *result) adjustMounts(mounts []*Mount, plugin string) error { + if len(mounts) == 0 { + return nil + } + + create, id := r.request.create, r.request.create.Container.Id + + // first split removals from the rest of adjustments + add := []*Mount{} + del := map[string]*Mount{} + mod := map[string]*Mount{} + for _, m := range mounts { + if key, marked := m.IsMarkedForRemoval(); marked { + del[key] = m + } else { + add = append(add, m) + mod[key] = m + } + } + + // next remove marked mounts from collected adjustments + cleared := []*Mount{} + for _, m := range r.reply.adjust.Mounts { + if _, removed := del[m.Destination]; removed { + r.owners.clearMount(id, m.Destination) + continue + } + cleared = append(cleared, m) + } + r.reply.adjust.Mounts = cleared + + // next remove marked and modified mounts from container creation request + cleared = []*Mount{} + for _, m := range create.Container.Mounts { + if _, removed := del[m.Destination]; removed { + continue + } + if _, modified := mod[m.Destination]; modified { + continue + } + cleared = append(cleared, m) + } + create.Container.Mounts = cleared + + // next, apply additions/modifications to collected adjustments + for _, m := range add { + if err := r.owners.claimMount(id, m.Destination, plugin); err != nil { + return err + } + r.reply.adjust.Mounts = append(r.reply.adjust.Mounts, m) + } + + // finally, apply additions/modifications to plugin container creation request + for _, m := range add { + create.Container.Mounts = append(r.reply.adjust.Mounts, m) + } + + return nil +} + +func (r *result) adjustDevices(devices []*LinuxDevice, plugin string) error { + if len(devices) == 0 { + return nil + } + + create, id := r.request.create, r.request.create.Container.Id + + // first split removals from the rest of adjustments + add := []*LinuxDevice{} + del := map[string]*LinuxDevice{} + mod := map[string]*LinuxDevice{} + for _, d := range devices { + if key, marked := d.IsMarkedForRemoval(); marked { + del[key] = d + } else { + add = append(add, d) + mod[key] = d + } + } + + // next remove marked devices from collected adjustments + cleared := []*LinuxDevice{} + for _, d := range r.reply.adjust.Linux.Devices { + if _, removed := del[d.Path]; removed { + r.owners.clearDevice(id, d.Path) + continue + } + cleared = append(cleared, d) + } + r.reply.adjust.Linux.Devices = cleared + + // next remove marked and modified devices from container creation request + cleared = []*LinuxDevice{} + for _, d := range create.Container.Linux.Devices { + if _, removed := del[d.Path]; removed { + continue + } + if _, modified := mod[d.Path]; modified { + continue + } + cleared = append(cleared, d) + } + create.Container.Linux.Devices = cleared + + // next, apply additions/modifications to collected adjustments + for _, d := range add { + if err := r.owners.claimDevice(id, d.Path, plugin); err != nil { + return err + } + r.reply.adjust.Linux.Devices = append(r.reply.adjust.Linux.Devices, d) + } + + // finally, apply additions/modifications to plugin container creation request + for _, d := range add { + create.Container.Linux.Devices = append(r.reply.adjust.Linux.Devices, d) + } + + return nil +} + +func (r *result) adjustEnv(env []*KeyValue, plugin string) error { + if len(env) == 0 { + return nil + } + + create, id := r.request.create, r.request.create.Container.Id + + // first split removals from the rest of adjustments + add := []*KeyValue{} + del := map[string]struct{}{} + mod := map[string]struct{}{} + for _, e := range env { + if key, marked := e.IsMarkedForRemoval(); marked { + del[key] = struct{}{} + } else { + add = append(add, e) + mod[key] = struct{}{} + } + } + + // next remove marked environment variables from collected adjustments + cleared := []*KeyValue{} + for _, e := range r.reply.adjust.Env { + if _, removed := del[e.Key]; removed { + r.owners.clearEnv(id, e.Key) + continue + } + cleared = append(cleared, e) + } + r.reply.adjust.Env = cleared + + // next remove marked and modified environment from container creation request + clearedEnv := []string{} + for _, e := range create.Container.Env { + key, _ := splitEnvVar(e) + if _, removed := del[key]; removed { + continue + } + if _, modified := mod[key]; modified { + continue + } + clearedEnv = append(clearedEnv, e) + } + create.Container.Env = clearedEnv + + // next, apply additions/modifications to collected adjustments + for _, e := range add { + if err := r.owners.claimEnv(id, e.Key, plugin); err != nil { + return err + } + r.reply.adjust.Env = append(r.reply.adjust.Env, e) + } + + // finally, apply additions/modifications to plugin container creation request + for _, e := range add { + create.Container.Env = append(create.Container.Env, e.ToOCI()) + } + + return nil +} + +func splitEnvVar(s string) (string, string) { + split := strings.SplitN(s, "=", 2) + if len(split) < 1 { + return "", "" + } + if len(split) != 2 { + return split[0], "" + } + return split[0], split[1] +} + +func (r *result) adjustHooks(hooks *Hooks, plugin string) error { + if hooks == nil { + return nil + } + + reply := r.reply.adjust + container := r.request.create.Container + + if h := hooks.Prestart; len(h) > 0 { + reply.Hooks.Prestart = append(reply.Hooks.Prestart, h...) + container.Hooks.Prestart = append(container.Hooks.Prestart, h...) + } + if h := hooks.Poststart; len(h) > 0 { + reply.Hooks.Poststart = append(reply.Hooks.Poststart, h...) + container.Hooks.Poststart = append(container.Hooks.Poststart, h...) + } + if h := hooks.Poststop; len(h) > 0 { + reply.Hooks.Poststop = append(reply.Hooks.Poststop, h...) + container.Hooks.Poststop = append(container.Hooks.Poststop, h...) + } + if h := hooks.CreateRuntime; len(h) > 0 { + reply.Hooks.CreateRuntime = append(reply.Hooks.CreateRuntime, h...) + container.Hooks.CreateRuntime = append(container.Hooks.CreateRuntime, h...) + } + if h := hooks.CreateContainer; len(h) > 0 { + reply.Hooks.CreateContainer = append(reply.Hooks.CreateContainer, h...) + container.Hooks.CreateContainer = append(container.Hooks.CreateContainer, h...) + } + if h := hooks.StartContainer; len(h) > 0 { + reply.Hooks.StartContainer = append(reply.Hooks.StartContainer, h...) + container.Hooks.StartContainer = append(container.Hooks.StartContainer, h...) + } + + return nil +} + +func (r *result) adjustResources(resources *LinuxResources, plugin string) error { + if resources == nil { + return nil + } + + create, id := r.request.create, r.request.create.Container.Id + container := create.Container.Linux.Resources + reply := r.reply.adjust.Linux.Resources + + if mem := resources.Memory; mem != nil { + if v := mem.GetLimit(); v != nil { + if err := r.owners.claimMemLimit(id, plugin); err != nil { + return err + } + container.Memory.Limit = Int64(v.GetValue()) + reply.Memory.Limit = Int64(v.GetValue()) + } + if v := mem.GetReservation(); v != nil { + if err := r.owners.claimMemReservation(id, plugin); err != nil { + return err + } + container.Memory.Reservation = Int64(v.GetValue()) + reply.Memory.Reservation = Int64(v.GetValue()) + } + if v := mem.GetSwap(); v != nil { + if err := r.owners.claimMemSwapLimit(id, plugin); err != nil { + return err + } + container.Memory.Swap = Int64(v.GetValue()) + reply.Memory.Swap = Int64(v.GetValue()) + } + if v := mem.GetKernel(); v != nil { + if err := r.owners.claimMemKernelLimit(id, plugin); err != nil { + return err + } + container.Memory.Kernel = Int64(v.GetValue()) + reply.Memory.Kernel = Int64(v.GetValue()) + } + if v := mem.GetKernelTcp(); v != nil { + if err := r.owners.claimMemTCPLimit(id, plugin); err != nil { + return err + } + container.Memory.KernelTcp = Int64(v.GetValue()) + reply.Memory.KernelTcp = Int64(v.GetValue()) + } + if v := mem.GetSwappiness(); v != nil { + if err := r.owners.claimMemSwappiness(id, plugin); err != nil { + return err + } + container.Memory.Swappiness = UInt64(v.GetValue()) + reply.Memory.Swappiness = UInt64(v.GetValue()) + } + if v := mem.GetDisableOomKiller(); v != nil { + if err := r.owners.claimMemDisableOomKiller(id, plugin); err != nil { + return err + } + container.Memory.DisableOomKiller = Bool(v.GetValue()) + reply.Memory.DisableOomKiller = Bool(v.GetValue()) + } + if v := mem.GetUseHierarchy(); v != nil { + if err := r.owners.claimMemUseHierarchy(id, plugin); err != nil { + return err + } + container.Memory.UseHierarchy = Bool(v.GetValue()) + reply.Memory.UseHierarchy = Bool(v.GetValue()) + } + } + if cpu := resources.Cpu; cpu != nil { + if v := cpu.GetShares(); v != nil { + if err := r.owners.claimCpuShares(id, plugin); err != nil { + return err + } + container.Cpu.Shares = UInt64(v.GetValue()) + reply.Cpu.Shares = UInt64(v.GetValue()) + } + if v := cpu.GetQuota(); v != nil { + if err := r.owners.claimCpuQuota(id, plugin); err != nil { + return err + } + container.Cpu.Quota = Int64(v.GetValue()) + reply.Cpu.Quota = Int64(v.GetValue()) + } + if v := cpu.GetPeriod(); v != nil { + if err := r.owners.claimCpuPeriod(id, plugin); err != nil { + return err + } + container.Cpu.Period = UInt64(v.GetValue()) + reply.Cpu.Period = UInt64(v.GetValue()) + } + if v := cpu.GetRealtimeRuntime(); v != nil { + if err := r.owners.claimCpuRealtimeRuntime(id, plugin); err != nil { + return err + } + container.Cpu.RealtimeRuntime = Int64(v.GetValue()) + reply.Cpu.RealtimeRuntime = Int64(v.GetValue()) + } + if v := cpu.GetRealtimePeriod(); v != nil { + if err := r.owners.claimCpuRealtimePeriod(id, plugin); err != nil { + return err + } + container.Cpu.RealtimePeriod = UInt64(v.GetValue()) + reply.Cpu.RealtimePeriod = UInt64(v.GetValue()) + } + if v := cpu.GetCpus(); v != "" { + if err := r.owners.claimCpusetCpus(id, plugin); err != nil { + return err + } + container.Cpu.Cpus = v + reply.Cpu.Cpus = v + } + if v := cpu.GetMems(); v != "" { + if err := r.owners.claimCpusetMems(id, plugin); err != nil { + return err + } + container.Cpu.Mems = v + reply.Cpu.Mems = v + } + } + + for _, l := range resources.HugepageLimits { + if err := r.owners.claimHugepageLimit(id, l.PageSize, plugin); err != nil { + return err + } + container.HugepageLimits = append(container.HugepageLimits, l) + reply.HugepageLimits = append(reply.HugepageLimits, l) + } + + if len(resources.Unified) != 0 { + for k, v := range resources.Unified { + if err := r.owners.claimUnified(id, k, plugin); err != nil { + return err + } + container.Unified[k] = v + reply.Unified[k] = v + } + } + + if v := resources.GetBlockioClass(); v != nil { + if err := r.owners.claimBlockioClass(id, plugin); err != nil { + return err + } + container.BlockioClass = String(v.GetValue()) + reply.BlockioClass = String(v.GetValue()) + } + if v := resources.GetRdtClass(); v != nil { + if err := r.owners.claimRdtClass(id, plugin); err != nil { + return err + } + container.RdtClass = String(v.GetValue()) + reply.RdtClass = String(v.GetValue()) + } + + return nil +} + +func (r *result) adjustCgroupsPath(path, plugin string) error { + if path == "" { + return nil + } + + create, id := r.request.create, r.request.create.Container.Id + + if err := r.owners.claimCgroupsPath(id, plugin); err != nil { + return err + } + + create.Container.Linux.CgroupsPath = path + r.reply.adjust.Linux.CgroupsPath = path + + return nil +} + +func (r *result) updateResources(reply, u *ContainerUpdate, plugin string) error { + if u.Linux == nil || u.Linux.Resources == nil { + return nil + } + + var resources *LinuxResources + request, id := r.request.update, u.ContainerId + + // operate on a copy: we won't touch anything on (ignored) failures + if request != nil && request.Container.Id == id { + resources = request.LinuxResources.Copy() + } else { + resources = reply.Linux.Resources.Copy() + } + + if mem := u.Linux.Resources.Memory; mem != nil { + if v := mem.GetLimit(); v != nil { + if err := r.owners.claimMemLimit(id, plugin); err != nil { + return err + } + resources.Memory.Limit = Int64(v.GetValue()) + } + if v := mem.GetReservation(); v != nil { + if err := r.owners.claimMemReservation(id, plugin); err != nil { + return err + } + resources.Memory.Reservation = Int64(v.GetValue()) + } + if v := mem.GetSwap(); v != nil { + if err := r.owners.claimMemSwapLimit(id, plugin); err != nil { + return err + } + resources.Memory.Swap = Int64(v.GetValue()) + } + if v := mem.GetKernel(); v != nil { + if err := r.owners.claimMemKernelLimit(id, plugin); err != nil { + return err + } + resources.Memory.Kernel = Int64(v.GetValue()) + } + if v := mem.GetKernelTcp(); v != nil { + if err := r.owners.claimMemTCPLimit(id, plugin); err != nil { + return err + } + resources.Memory.KernelTcp = Int64(v.GetValue()) + } + if v := mem.GetSwappiness(); v != nil { + if err := r.owners.claimMemSwappiness(id, plugin); err != nil { + return err + } + resources.Memory.Swappiness = UInt64(v.GetValue()) + } + if v := mem.GetDisableOomKiller(); v != nil { + if err := r.owners.claimMemDisableOomKiller(id, plugin); err != nil { + return err + } + resources.Memory.DisableOomKiller = Bool(v.GetValue()) + } + if v := mem.GetUseHierarchy(); v != nil { + if err := r.owners.claimMemUseHierarchy(id, plugin); err != nil { + return err + } + resources.Memory.UseHierarchy = Bool(v.GetValue()) + } + } + if cpu := u.Linux.Resources.Cpu; cpu != nil { + if v := cpu.GetShares(); v != nil { + if err := r.owners.claimCpuShares(id, plugin); err != nil { + return err + } + resources.Cpu.Shares = UInt64(v.GetValue()) + } + if v := cpu.GetQuota(); v != nil { + if err := r.owners.claimCpuQuota(id, plugin); err != nil { + return err + } + resources.Cpu.Quota = Int64(v.GetValue()) + } + if v := cpu.GetPeriod(); v != nil { + if err := r.owners.claimCpuPeriod(id, plugin); err != nil { + return err + } + resources.Cpu.Period = UInt64(v.GetValue()) + } + if v := cpu.GetRealtimeRuntime(); v != nil { + if err := r.owners.claimCpuRealtimeRuntime(id, plugin); err != nil { + return err + } + resources.Cpu.RealtimeRuntime = Int64(v.GetValue()) + } + if v := cpu.GetRealtimePeriod(); v != nil { + if err := r.owners.claimCpuRealtimePeriod(id, plugin); err != nil { + return err + } + resources.Cpu.RealtimePeriod = UInt64(v.GetValue()) + } + if v := cpu.GetCpus(); v != "" { + if err := r.owners.claimCpusetCpus(id, plugin); err != nil { + return err + } + resources.Cpu.Cpus = v + } + if v := cpu.GetMems(); v != "" { + if err := r.owners.claimCpusetMems(id, plugin); err != nil { + return err + } + resources.Cpu.Mems = v + } + } + + for _, l := range u.Linux.Resources.HugepageLimits { + if err := r.owners.claimHugepageLimit(id, l.PageSize, plugin); err != nil { + return err + } + resources.HugepageLimits = append(resources.HugepageLimits, l) + } + + if len(u.Linux.Resources.Unified) != 0 { + if resources.Unified == nil { + resources.Unified = make(map[string]string) + } + for k, v := range u.Linux.Resources.Unified { + if err := r.owners.claimUnified(id, k, plugin); err != nil { + return err + } + resources.Unified[k] = v + } + } + + if v := u.Linux.Resources.GetBlockioClass(); v != nil { + if err := r.owners.claimBlockioClass(id, plugin); err != nil { + return err + } + resources.BlockioClass = String(v.GetValue()) + } + if v := u.Linux.Resources.GetRdtClass(); v != nil { + if err := r.owners.claimRdtClass(id, plugin); err != nil { + return err + } + resources.RdtClass = String(v.GetValue()) + } + + // update request/reply from copy on success + reply.Linux.Resources = resources.Copy() + + if request != nil && request.Container.Id == id { + request.LinuxResources = resources.Copy() + } + + return nil +} + +func (r *result) getContainerUpdate(u *ContainerUpdate, plugin string) (*ContainerUpdate, error) { + id := u.ContainerId + if r.request.create != nil && r.request.create.Container != nil { + if r.request.create.Container.Id == id { + return nil, fmt.Errorf("plugin %q asked update of %q during creation", + plugin, id) + } + } + + if update, ok := r.updates[id]; ok { + update.IgnoreFailure = update.IgnoreFailure && u.IgnoreFailure + return update, nil + } + + update := &ContainerUpdate{ + ContainerId: id, + Linux: &LinuxContainerUpdate{ + Resources: &LinuxResources{ + Memory: &LinuxMemory{}, + Cpu: &LinuxCPU{}, + HugepageLimits: []*HugepageLimit{}, + Unified: map[string]string{}, + }, + }, + IgnoreFailure: u.IgnoreFailure, + } + + r.updates[id] = update + + // for update requests delay appending the requested container (in the response getter) + if r.request.update == nil || r.request.update.Container.Id != id { + r.reply.update = append(r.reply.update, update) + } + + return update, nil +} + +type owners struct { + annotations map[string]string + mounts map[string]string + devices map[string]string + env map[string]string + memLimit string + memReservation string + memSwapLimit string + memKernelLimit string + memTCPLimit string + memSwappiness string + memDisableOomKiller string + memUseHierarchy string + cpuShares string + cpuQuota string + cpuPeriod string + cpuRealtimeRuntime string + cpuRealtimePeriod string + cpusetCpus string + cpusetMems string + hugepageLimits map[string]string + blockioClass string + rdtClass string + unified map[string]string + cgroupsPath string +} + +func (ro resultOwners) ownersFor(id string) *owners { + o, ok := ro[id] + if !ok { + o = &owners{} + ro[id] = o + } + return o +} + +func (ro resultOwners) claimAnnotation(id, key, plugin string) error { + return ro.ownersFor(id).claimAnnotation(key, plugin) +} + +func (ro resultOwners) claimMount(id, destination, plugin string) error { + return ro.ownersFor(id).claimMount(destination, plugin) +} + +func (ro resultOwners) claimDevice(id, path, plugin string) error { + return ro.ownersFor(id).claimDevice(path, plugin) +} + +func (ro resultOwners) claimEnv(id, name, plugin string) error { + return ro.ownersFor(id).claimEnv(name, plugin) +} + +func (ro resultOwners) claimMemLimit(id, plugin string) error { + return ro.ownersFor(id).claimMemLimit(plugin) +} + +func (ro resultOwners) claimMemReservation(id, plugin string) error { + return ro.ownersFor(id).claimMemReservation(plugin) +} + +func (ro resultOwners) claimMemSwapLimit(id, plugin string) error { + return ro.ownersFor(id).claimMemSwapLimit(plugin) +} + +func (ro resultOwners) claimMemKernelLimit(id, plugin string) error { + return ro.ownersFor(id).claimMemKernelLimit(plugin) +} + +func (ro resultOwners) claimMemTCPLimit(id, plugin string) error { + return ro.ownersFor(id).claimMemTCPLimit(plugin) +} + +func (ro resultOwners) claimMemSwappiness(id, plugin string) error { + return ro.ownersFor(id).claimMemSwappiness(plugin) +} + +func (ro resultOwners) claimMemDisableOomKiller(id, plugin string) error { + return ro.ownersFor(id).claimMemDisableOomKiller(plugin) +} + +func (ro resultOwners) claimMemUseHierarchy(id, plugin string) error { + return ro.ownersFor(id).claimMemUseHierarchy(plugin) +} + +func (ro resultOwners) claimCpuShares(id, plugin string) error { + return ro.ownersFor(id).claimCpuShares(plugin) +} + +func (ro resultOwners) claimCpuQuota(id, plugin string) error { + return ro.ownersFor(id).claimCpuQuota(plugin) +} + +func (ro resultOwners) claimCpuPeriod(id, plugin string) error { + return ro.ownersFor(id).claimCpuPeriod(plugin) +} + +func (ro resultOwners) claimCpuRealtimeRuntime(id, plugin string) error { + return ro.ownersFor(id).claimCpuRealtimeRuntime(plugin) +} + +func (ro resultOwners) claimCpuRealtimePeriod(id, plugin string) error { + return ro.ownersFor(id).claimCpuRealtimePeriod(plugin) +} + +func (ro resultOwners) claimCpusetCpus(id, plugin string) error { + return ro.ownersFor(id).claimCpusetCpus(plugin) +} + +func (ro resultOwners) claimCpusetMems(id, plugin string) error { + return ro.ownersFor(id).claimCpusetMems(plugin) +} + +func (ro resultOwners) claimHugepageLimit(id, size, plugin string) error { + return ro.ownersFor(id).claimHugepageLimit(size, plugin) +} + +func (ro resultOwners) claimBlockioClass(id, plugin string) error { + return ro.ownersFor(id).claimBlockioClass(plugin) +} + +func (ro resultOwners) claimRdtClass(id, plugin string) error { + return ro.ownersFor(id).claimRdtClass(plugin) +} + +func (ro resultOwners) claimUnified(id, key, plugin string) error { + return ro.ownersFor(id).claimUnified(key, plugin) +} + +func (ro resultOwners) claimCgroupsPath(id, plugin string) error { + return ro.ownersFor(id).claimCgroupsPath(plugin) +} + +func (o *owners) claimAnnotation(key, plugin string) error { + if o.annotations == nil { + o.annotations = make(map[string]string) + } + if other, taken := o.annotations[key]; taken { + return conflict(plugin, other, "annotation", key) + } + o.annotations[key] = plugin + return nil +} + +func (o *owners) claimMount(destination, plugin string) error { + if o.mounts == nil { + o.mounts = make(map[string]string) + } + if other, taken := o.mounts[destination]; taken { + return conflict(plugin, other, "mount", destination) + } + o.mounts[destination] = plugin + return nil +} + +func (o *owners) claimDevice(path, plugin string) error { + if o.devices == nil { + o.devices = make(map[string]string) + } + if other, taken := o.devices[path]; taken { + return conflict(plugin, other, "device", path) + } + o.devices[path] = plugin + return nil +} + +func (o *owners) claimEnv(name, plugin string) error { + if o.env == nil { + o.env = make(map[string]string) + } + if other, taken := o.env[name]; taken { + return conflict(plugin, other, "env", name) + } + o.env[name] = plugin + return nil +} + +func (o *owners) claimMemLimit(plugin string) error { + if other := o.memLimit; other != "" { + return conflict(plugin, other, "memory limit") + } + o.memLimit = plugin + return nil +} + +func (o *owners) claimMemReservation(plugin string) error { + if other := o.memReservation; other != "" { + return conflict(plugin, other, "memory reservation") + } + o.memReservation = plugin + return nil +} + +func (o *owners) claimMemSwapLimit(plugin string) error { + if other := o.memSwapLimit; other != "" { + return conflict(plugin, other, "memory swap limit") + } + o.memSwapLimit = plugin + return nil +} + +func (o *owners) claimMemKernelLimit(plugin string) error { + if other := o.memKernelLimit; other != "" { + return conflict(plugin, other, "memory kernel limit") + } + o.memKernelLimit = plugin + return nil +} + +func (o *owners) claimMemTCPLimit(plugin string) error { + if other := o.memTCPLimit; other != "" { + return conflict(plugin, other, "memory TCP limit") + } + o.memTCPLimit = plugin + return nil +} + +func (o *owners) claimMemSwappiness(plugin string) error { + if other := o.memSwappiness; other != "" { + return conflict(plugin, other, "memory swappiness") + } + o.memSwappiness = plugin + return nil +} + +func (o *owners) claimMemDisableOomKiller(plugin string) error { + if other := o.memDisableOomKiller; other != "" { + return conflict(plugin, other, "memory disable OOM killer") + } + o.memDisableOomKiller = plugin + return nil +} + +func (o *owners) claimMemUseHierarchy(plugin string) error { + if other := o.memUseHierarchy; other != "" { + return conflict(plugin, other, "memory 'UseHierarchy'") + } + o.memUseHierarchy = plugin + return nil +} + +func (o *owners) claimCpuShares(plugin string) error { + if other := o.cpuShares; other != "" { + return conflict(plugin, other, "CPU shares") + } + o.cpuShares = plugin + return nil +} + +func (o *owners) claimCpuQuota(plugin string) error { + if other := o.cpuQuota; other != "" { + return conflict(plugin, other, "CPU quota") + } + o.cpuQuota = plugin + return nil +} + +func (o *owners) claimCpuPeriod(plugin string) error { + if other := o.cpuPeriod; other != "" { + return conflict(plugin, other, "CPU period") + } + o.cpuPeriod = plugin + return nil +} + +func (o *owners) claimCpuRealtimeRuntime(plugin string) error { + if other := o.cpuRealtimeRuntime; other != "" { + return conflict(plugin, other, "CPU realtime runtime") + } + o.cpuRealtimeRuntime = plugin + return nil +} + +func (o *owners) claimCpuRealtimePeriod(plugin string) error { + if other := o.cpuRealtimePeriod; other != "" { + return conflict(plugin, other, "CPU realtime period") + } + o.cpuRealtimePeriod = plugin + return nil +} + +func (o *owners) claimCpusetCpus(plugin string) error { + if other := o.cpusetCpus; other != "" { + return conflict(plugin, other, "CPU pinning") + } + o.cpusetCpus = plugin + return nil +} + +func (o *owners) claimCpusetMems(plugin string) error { + if other := o.cpusetMems; other != "" { + return conflict(plugin, other, "memory pinning") + } + o.cpusetMems = plugin + return nil +} + +func (o *owners) claimHugepageLimit(size, plugin string) error { + if o.hugepageLimits == nil { + o.hugepageLimits = make(map[string]string) + } + + if other, taken := o.hugepageLimits[size]; taken { + return conflict(plugin, other, "hugepage limit of size", size) + } + o.hugepageLimits[size] = plugin + return nil +} + +func (o *owners) claimBlockioClass(plugin string) error { + if other := o.blockioClass; other != "" { + return conflict(plugin, other, "block I/O class") + } + o.blockioClass = plugin + return nil +} + +func (o *owners) claimRdtClass(plugin string) error { + if other := o.rdtClass; other != "" { + return conflict(plugin, other, "RDT class") + } + o.rdtClass = plugin + return nil +} + +func (o *owners) claimUnified(key, plugin string) error { + if o.unified == nil { + o.unified = make(map[string]string) + } + if other, taken := o.unified[key]; taken { + return conflict(plugin, other, "unified resource", key) + } + o.unified[key] = plugin + return nil +} + +func (o *owners) claimCgroupsPath(plugin string) error { + if other := o.cgroupsPath; other != "" { + return conflict(plugin, other, "cgroups path") + } + o.cgroupsPath = plugin + return nil +} + +func (ro resultOwners) clearAnnotation(id, key string) { + ro.ownersFor(id).clearAnnotation(key) +} + +func (ro resultOwners) clearMount(id, destination string) { + ro.ownersFor(id).clearMount(destination) +} + +func (ro resultOwners) clearDevice(id, path string) { + ro.ownersFor(id).clearDevice(path) +} + +func (ro resultOwners) clearEnv(id, name string) { + ro.ownersFor(id).clearEnv(name) +} + +func (o *owners) clearAnnotation(key string) { + if o.annotations == nil { + return + } + delete(o.annotations, key) +} + +func (o *owners) clearMount(destination string) { + if o.mounts == nil { + return + } + delete(o.mounts, destination) +} + +func (o *owners) clearDevice(path string) { + if o.devices == nil { + return + } + delete(o.devices, path) +} + +func (o *owners) clearEnv(name string) { + if o.env == nil { + return + } + delete(o.env, name) +} + +func conflict(plugin, other, subject string, qualif ...string) error { + return fmt.Errorf("plugins %q and %q both tried to set %s", + plugin, other, strings.Join(append([]string{subject}, qualif...), " ")) +} diff --git a/vendor/github.com/containerd/nri/pkg/api/adjustment.go b/vendor/github.com/containerd/nri/pkg/api/adjustment.go new file mode 100644 index 000000000..c44b4aa5f --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/adjustment.go @@ -0,0 +1,295 @@ +/* + 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 api + +// +// Notes: +// Adjustment of metadata that is stored in maps (labels and annotations) +// currently assumes that a single plugin will never do an add prior to a +// delete for any key. IOW, it is always assumed that if both a deletion +// and an addition/setting was recorded for a key then the final desired +// state is the addition. This seems like a reasonably safe assumption. A +// removal is usually done only to protect against triggering the conflict +// in the runtime when a plugin intends to touch a key which is known to +// have been put there or already modified by another plugin. +// +// An alternative without this implicit ordering assumption would be to +// store the adjustment for such data as a sequence of add/del operations +// in a slice. At the moment that does not seem to be necessary. +// + +// AddAnnotation records the addition of the annotation key=value. +func (a *ContainerAdjustment) AddAnnotation(key, value string) { + a.initAnnotations() + a.Annotations[key] = value +} + +// RemoveAnnotation records the removal of the annotation for the given key. +// Normally it is an error for a plugin to try and alter an annotation +// touched by another plugin. However, this is not an error if the plugin +// removes that annotation prior to touching it. +func (a *ContainerAdjustment) RemoveAnnotation(key string) { + a.initAnnotations() + a.Annotations[MarkForRemoval(key)] = "" +} + +// AddMount records the addition of a mount to a container. +func (a *ContainerAdjustment) AddMount(m *Mount) { + a.Mounts = append(a.Mounts, m) // TODO: should we dup m here ? +} + +// RemoveMount records the removal of a mount from a container. +// Normally it is an error for a plugin to try and alter a mount +// touched by another plugin. However, this is not an error if the +// plugin removes that mount prior to touching it. +func (a *ContainerAdjustment) RemoveMount(ContainerPath string) { + a.Mounts = append(a.Mounts, &Mount{ + Destination: MarkForRemoval(ContainerPath), + }) +} + +// AddEnv records the addition of an environment variable to a container. +func (a *ContainerAdjustment) AddEnv(key, value string) { + a.Env = append(a.Env, &KeyValue{ + Key: key, + Value: value, + }) +} + +// RemoveEnv records the removal of an environment variable from a container. +// Normally it is an error for a plugin to try and alter an environment +// variable touched by another container. However, this is not an error if +// the plugin removes that variable prior to touching it. +func (a *ContainerAdjustment) RemoveEnv(key string) { + a.Env = append(a.Env, &KeyValue{ + Key: MarkForRemoval(key), + }) +} + +// AddHooks records the addition of the given hooks to a container. +func (a *ContainerAdjustment) AddHooks(h *Hooks) { + a.initHooks() + if h.Prestart != nil { + a.Hooks.Prestart = append(a.Hooks.Prestart, h.Prestart...) + } + if h.CreateRuntime != nil { + a.Hooks.CreateRuntime = append(a.Hooks.CreateRuntime, h.CreateRuntime...) + } + if h.CreateContainer != nil { + a.Hooks.CreateContainer = append(a.Hooks.CreateContainer, h.CreateContainer...) + } + if h.StartContainer != nil { + a.Hooks.StartContainer = append(a.Hooks.StartContainer, h.StartContainer...) + } + if h.Poststart != nil { + a.Hooks.Poststart = append(a.Hooks.Poststart, h.Poststart...) + } + if h.Poststop != nil { + a.Hooks.Poststop = append(a.Hooks.Poststop, h.Poststop...) + } +} + +// AddDevice records the addition of the given device to a container. +func (a *ContainerAdjustment) AddDevice(d *LinuxDevice) { + a.initLinux() + a.Linux.Devices = append(a.Linux.Devices, d) // TODO: should we dup d here ? +} + +// RemoveDevice records the removal of a device from a container. +// Normally it is an error for a plugin to try and alter an device +// touched by another container. However, this is not an error if +// the plugin removes that device prior to touching it. +func (a *ContainerAdjustment) RemoveDevice(path string) { + a.initLinux() + a.Linux.Devices = append(a.Linux.Devices, &LinuxDevice{ + Path: MarkForRemoval(path), + }) +} + +// SetLinuxMemoryLimit records setting the memory limit for a container. +func (a *ContainerAdjustment) SetLinuxMemoryLimit(value int64) { + a.initLinuxResourcesMemory() + a.Linux.Resources.Memory.Limit = Int64(value) +} + +// SetLinuxMemoryReservation records setting the memory reservation for a container. +func (a *ContainerAdjustment) SetLinuxMemoryReservation(value int64) { + a.initLinuxResourcesMemory() + a.Linux.Resources.Memory.Reservation = Int64(value) +} + +// SetLinuxMemorySwap records records setting the memory swap limit for a container. +func (a *ContainerAdjustment) SetLinuxMemorySwap(value int64) { + a.initLinuxResourcesMemory() + a.Linux.Resources.Memory.Swap = Int64(value) +} + +// SetLinuxMemoryKernel records setting the memory kernel limit for a container. +func (a *ContainerAdjustment) SetLinuxMemoryKernel(value int64) { + a.initLinuxResourcesMemory() + a.Linux.Resources.Memory.Kernel = Int64(value) +} + +// SetLinuxMemoryKernelTCP records setting the memory kernel TCP limit for a container. +func (a *ContainerAdjustment) SetLinuxMemoryKernelTCP(value int64) { + a.initLinuxResourcesMemory() + a.Linux.Resources.Memory.KernelTcp = Int64(value) +} + +// SetLinuxMemorySwappiness records setting the memory swappiness for a container. +func (a *ContainerAdjustment) SetLinuxMemorySwappiness(value uint64) { + a.initLinuxResourcesMemory() + a.Linux.Resources.Memory.Swappiness = UInt64(value) +} + +// SetLinuxMemoryDisableOomKiller records disabling the OOM killer for a container. +func (a *ContainerAdjustment) SetLinuxMemoryDisableOomKiller() { + a.initLinuxResourcesMemory() + a.Linux.Resources.Memory.DisableOomKiller = Bool(true) +} + +// SetLinuxMemoryUseHierarchy records enabling hierarchical memory accounting for a container. +func (a *ContainerAdjustment) SetLinuxMemoryUseHierarchy() { + a.initLinuxResourcesMemory() + a.Linux.Resources.Memory.UseHierarchy = Bool(true) +} + +// SetLinuxCPUShares records setting the scheduler's CPU shares for a container. +func (a *ContainerAdjustment) SetLinuxCPUShares(value uint64) { + a.initLinuxResourcesCPU() + a.Linux.Resources.Cpu.Shares = UInt64(value) +} + +// SetLinuxCPUQuota records setting the scheduler's CPU quota for a container. +func (a *ContainerAdjustment) SetLinuxCPUQuota(value int64) { + a.initLinuxResourcesCPU() + a.Linux.Resources.Cpu.Quota = Int64(value) +} + +// SetLinuxCPUPeriod records setting the scheduler's CPU period for a container. +func (a *ContainerAdjustment) SetLinuxCPUPeriod(value int64) { + a.initLinuxResourcesCPU() + a.Linux.Resources.Cpu.Period = UInt64(value) +} + +// SetLinuxCPURealtimeRuntime records setting the scheduler's realtime runtime for a container. +func (a *ContainerAdjustment) SetLinuxCPURealtimeRuntime(value int64) { + a.initLinuxResourcesCPU() + a.Linux.Resources.Cpu.RealtimeRuntime = Int64(value) +} + +// SetLinuxCPURealtimePeriod records setting the scheduler's realtime period for a container. +func (a *ContainerAdjustment) SetLinuxCPURealtimePeriod(value uint64) { + a.initLinuxResourcesCPU() + a.Linux.Resources.Cpu.RealtimePeriod = UInt64(value) +} + +// SetLinuxCPUSetCPUs records setting the cpuset CPUs for a container. +func (a *ContainerAdjustment) SetLinuxCPUSetCPUs(value string) { + a.initLinuxResourcesCPU() + a.Linux.Resources.Cpu.Cpus = value +} + +// SetLinuxCPUSetMems records setting the cpuset memory for a container. +func (a *ContainerAdjustment) SetLinuxCPUSetMems(value string) { + a.initLinuxResourcesCPU() + a.Linux.Resources.Cpu.Mems = value +} + +// AddLinuxHugepageLimit records adding a hugepage limit for a container. +func (a *ContainerAdjustment) AddLinuxHugepageLimit(pageSize string, value uint64) { + a.initLinuxResources() + a.Linux.Resources.HugepageLimits = append(a.Linux.Resources.HugepageLimits, + &HugepageLimit{ + PageSize: pageSize, + Limit: value, + }) +} + +// SetLinuxBlockIOClass records setting the Block I/O class for a container. +func (a *ContainerAdjustment) SetLinuxBlockIOClass(value string) { + a.initLinuxResources() + a.Linux.Resources.BlockioClass = String(value) +} + +// SetLinuxRDTClass records setting the RDT class for a container. +func (a *ContainerAdjustment) SetLinuxRDTClass(value string) { + a.initLinuxResources() + a.Linux.Resources.RdtClass = String(value) +} + +// AddLinuxUnified sets a cgroupv2 unified resource. +func (a *ContainerAdjustment) AddLinuxUnified(key, value string) { + a.initLinuxResourcesUnified() + a.Linux.Resources.Unified[key] = value +} + +// SetLinuxCgroupsPath records setting the cgroups path for a container. +func (a *ContainerAdjustment) SetLinuxCgroupsPath(value string) { + a.initLinux() + a.Linux.CgroupsPath = value +} + +// +// Initializing a container adjustment and container update. +// + +func (a *ContainerAdjustment) initAnnotations() { + if a.Annotations == nil { + a.Annotations = make(map[string]string) + } +} + +func (a *ContainerAdjustment) initHooks() { + if a.Hooks == nil { + a.Hooks = &Hooks{} + } +} + +func (a *ContainerAdjustment) initLinux() { + if a.Linux == nil { + a.Linux = &LinuxContainerAdjustment{} + } +} + +func (a *ContainerAdjustment) initLinuxResources() { + a.initLinux() + if a.Linux.Resources == nil { + a.Linux.Resources = &LinuxResources{} + } +} + +func (a *ContainerAdjustment) initLinuxResourcesMemory() { + a.initLinuxResources() + if a.Linux.Resources.Memory == nil { + a.Linux.Resources.Memory = &LinuxMemory{} + } +} + +func (a *ContainerAdjustment) initLinuxResourcesCPU() { + a.initLinuxResources() + if a.Linux.Resources.Cpu == nil { + a.Linux.Resources.Cpu = &LinuxCPU{} + } +} + +func (a *ContainerAdjustment) initLinuxResourcesUnified() { + a.initLinuxResources() + if a.Linux.Resources.Unified == nil { + a.Linux.Resources.Unified = make(map[string]string) + } +} diff --git a/vendor/github.com/containerd/nri/pkg/api/api.pb.go b/vendor/github.com/containerd/nri/pkg/api/api.pb.go new file mode 100644 index 000000000..16b941204 --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/api.pb.go @@ -0,0 +1,4295 @@ +// +//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. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.0 +// protoc v3.20.1 +// source: pkg/api/api.proto + +package api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Events that plugins can subscribe to in ConfigureResponse. +type Event int32 + +const ( + Event_UNKNOWN Event = 0 + Event_RUN_POD_SANDBOX Event = 1 + Event_STOP_POD_SANDBOX Event = 2 + Event_REMOVE_POD_SANDBOX Event = 3 + Event_CREATE_CONTAINER Event = 4 + Event_POST_CREATE_CONTAINER Event = 5 + Event_START_CONTAINER Event = 6 + Event_POST_START_CONTAINER Event = 7 + Event_UPDATE_CONTAINER Event = 8 + Event_POST_UPDATE_CONTAINER Event = 9 + Event_STOP_CONTAINER Event = 10 + Event_REMOVE_CONTAINER Event = 11 + Event_LAST Event = 12 +) + +// Enum value maps for Event. +var ( + Event_name = map[int32]string{ + 0: "UNKNOWN", + 1: "RUN_POD_SANDBOX", + 2: "STOP_POD_SANDBOX", + 3: "REMOVE_POD_SANDBOX", + 4: "CREATE_CONTAINER", + 5: "POST_CREATE_CONTAINER", + 6: "START_CONTAINER", + 7: "POST_START_CONTAINER", + 8: "UPDATE_CONTAINER", + 9: "POST_UPDATE_CONTAINER", + 10: "STOP_CONTAINER", + 11: "REMOVE_CONTAINER", + 12: "LAST", + } + Event_value = map[string]int32{ + "UNKNOWN": 0, + "RUN_POD_SANDBOX": 1, + "STOP_POD_SANDBOX": 2, + "REMOVE_POD_SANDBOX": 3, + "CREATE_CONTAINER": 4, + "POST_CREATE_CONTAINER": 5, + "START_CONTAINER": 6, + "POST_START_CONTAINER": 7, + "UPDATE_CONTAINER": 8, + "POST_UPDATE_CONTAINER": 9, + "STOP_CONTAINER": 10, + "REMOVE_CONTAINER": 11, + "LAST": 12, + } +) + +func (x Event) Enum() *Event { + p := new(Event) + *p = x + return p +} + +func (x Event) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Event) Descriptor() protoreflect.EnumDescriptor { + return file_pkg_api_api_proto_enumTypes[0].Descriptor() +} + +func (Event) Type() protoreflect.EnumType { + return &file_pkg_api_api_proto_enumTypes[0] +} + +func (x Event) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Event.Descriptor instead. +func (Event) EnumDescriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{0} +} + +// Possible container states. +type ContainerState int32 + +const ( + ContainerState_CONTAINER_UNKNOWN ContainerState = 0 + ContainerState_CONTAINER_CREATED ContainerState = 1 + ContainerState_CONTAINER_PAUSED ContainerState = 2 // is this useful/necessary ? + ContainerState_CONTAINER_RUNNING ContainerState = 3 + ContainerState_CONTAINER_STOPPED ContainerState = 4 +) + +// Enum value maps for ContainerState. +var ( + ContainerState_name = map[int32]string{ + 0: "CONTAINER_UNKNOWN", + 1: "CONTAINER_CREATED", + 2: "CONTAINER_PAUSED", + 3: "CONTAINER_RUNNING", + 4: "CONTAINER_STOPPED", + } + ContainerState_value = map[string]int32{ + "CONTAINER_UNKNOWN": 0, + "CONTAINER_CREATED": 1, + "CONTAINER_PAUSED": 2, + "CONTAINER_RUNNING": 3, + "CONTAINER_STOPPED": 4, + } +) + +func (x ContainerState) Enum() *ContainerState { + p := new(ContainerState) + *p = x + return p +} + +func (x ContainerState) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ContainerState) Descriptor() protoreflect.EnumDescriptor { + return file_pkg_api_api_proto_enumTypes[1].Descriptor() +} + +func (ContainerState) Type() protoreflect.EnumType { + return &file_pkg_api_api_proto_enumTypes[1] +} + +func (x ContainerState) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ContainerState.Descriptor instead. +func (ContainerState) EnumDescriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{1} +} + +type RegisterPluginRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the plugin to register. + PluginName string `protobuf:"bytes,1,opt,name=plugin_name,json=pluginName,proto3" json:"plugin_name,omitempty"` + // Plugin invocation index. Plugins are called in ascending index order. + PluginIdx string `protobuf:"bytes,2,opt,name=plugin_idx,json=pluginIdx,proto3" json:"plugin_idx,omitempty"` +} + +func (x *RegisterPluginRequest) Reset() { + *x = RegisterPluginRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterPluginRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterPluginRequest) ProtoMessage() {} + +func (x *RegisterPluginRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterPluginRequest.ProtoReflect.Descriptor instead. +func (*RegisterPluginRequest) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{0} +} + +func (x *RegisterPluginRequest) GetPluginName() string { + if x != nil { + return x.PluginName + } + return "" +} + +func (x *RegisterPluginRequest) GetPluginIdx() string { + if x != nil { + return x.PluginIdx + } + return "" +} + +type UpdateContainersRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // List of containers to update. + Update []*ContainerUpdate `protobuf:"bytes,1,rep,name=update,proto3" json:"update,omitempty"` + // List of containers to evict. + Evict []*ContainerEviction `protobuf:"bytes,2,rep,name=evict,proto3" json:"evict,omitempty"` +} + +func (x *UpdateContainersRequest) Reset() { + *x = UpdateContainersRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateContainersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateContainersRequest) ProtoMessage() {} + +func (x *UpdateContainersRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateContainersRequest.ProtoReflect.Descriptor instead. +func (*UpdateContainersRequest) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{1} +} + +func (x *UpdateContainersRequest) GetUpdate() []*ContainerUpdate { + if x != nil { + return x.Update + } + return nil +} + +func (x *UpdateContainersRequest) GetEvict() []*ContainerEviction { + if x != nil { + return x.Evict + } + return nil +} + +type UpdateContainersResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Containers that the runtime failed to udpate. + Failed []*ContainerUpdate `protobuf:"bytes,1,rep,name=failed,proto3" json:"failed,omitempty"` +} + +func (x *UpdateContainersResponse) Reset() { + *x = UpdateContainersResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateContainersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateContainersResponse) ProtoMessage() {} + +func (x *UpdateContainersResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateContainersResponse.ProtoReflect.Descriptor instead. +func (*UpdateContainersResponse) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{2} +} + +func (x *UpdateContainersResponse) GetFailed() []*ContainerUpdate { + if x != nil { + return x.Failed + } + return nil +} + +type ConfigureRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Any plugin-specific data, if present among the NRI configuration. + Config string `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` + // Name of the runtime NRI is running in. + RuntimeName string `protobuf:"bytes,2,opt,name=runtime_name,json=runtimeName,proto3" json:"runtime_name,omitempty"` + // Version of the runtime NRI is running in. + RuntimeVersion string `protobuf:"bytes,3,opt,name=runtime_version,json=runtimeVersion,proto3" json:"runtime_version,omitempty"` +} + +func (x *ConfigureRequest) Reset() { + *x = ConfigureRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfigureRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigureRequest) ProtoMessage() {} + +func (x *ConfigureRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigureRequest.ProtoReflect.Descriptor instead. +func (*ConfigureRequest) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{3} +} + +func (x *ConfigureRequest) GetConfig() string { + if x != nil { + return x.Config + } + return "" +} + +func (x *ConfigureRequest) GetRuntimeName() string { + if x != nil { + return x.RuntimeName + } + return "" +} + +func (x *ConfigureRequest) GetRuntimeVersion() string { + if x != nil { + return x.RuntimeVersion + } + return "" +} + +type ConfigureResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Events to subscribe the plugin for. Each bit set corresponds to an + // enumerated Event. + Events int32 `protobuf:"varint,2,opt,name=events,proto3" json:"events,omitempty"` +} + +func (x *ConfigureResponse) Reset() { + *x = ConfigureResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfigureResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigureResponse) ProtoMessage() {} + +func (x *ConfigureResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConfigureResponse.ProtoReflect.Descriptor instead. +func (*ConfigureResponse) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{4} +} + +func (x *ConfigureResponse) GetEvents() int32 { + if x != nil { + return x.Events + } + return 0 +} + +type SynchronizeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Pods known to the runtime. + Pods []*PodSandbox `protobuf:"bytes,1,rep,name=pods,proto3" json:"pods,omitempty"` + // Containers known to the runtime. + Containers []*Container `protobuf:"bytes,2,rep,name=containers,proto3" json:"containers,omitempty"` +} + +func (x *SynchronizeRequest) Reset() { + *x = SynchronizeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SynchronizeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SynchronizeRequest) ProtoMessage() {} + +func (x *SynchronizeRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SynchronizeRequest.ProtoReflect.Descriptor instead. +func (*SynchronizeRequest) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{5} +} + +func (x *SynchronizeRequest) GetPods() []*PodSandbox { + if x != nil { + return x.Pods + } + return nil +} + +func (x *SynchronizeRequest) GetContainers() []*Container { + if x != nil { + return x.Containers + } + return nil +} + +type SynchronizeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Updates to containers requested by the plugin. + Update []*ContainerUpdate `protobuf:"bytes,1,rep,name=update,proto3" json:"update,omitempty"` +} + +func (x *SynchronizeResponse) Reset() { + *x = SynchronizeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SynchronizeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SynchronizeResponse) ProtoMessage() {} + +func (x *SynchronizeResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SynchronizeResponse.ProtoReflect.Descriptor instead. +func (*SynchronizeResponse) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{6} +} + +func (x *SynchronizeResponse) GetUpdate() []*ContainerUpdate { + if x != nil { + return x.Update + } + return nil +} + +type CreateContainerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Pod of container being created. + Pod *PodSandbox `protobuf:"bytes,1,opt,name=pod,proto3" json:"pod,omitempty"` + // Container being created. + Container *Container `protobuf:"bytes,2,opt,name=container,proto3" json:"container,omitempty"` +} + +func (x *CreateContainerRequest) Reset() { + *x = CreateContainerRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateContainerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateContainerRequest) ProtoMessage() {} + +func (x *CreateContainerRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateContainerRequest.ProtoReflect.Descriptor instead. +func (*CreateContainerRequest) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{7} +} + +func (x *CreateContainerRequest) GetPod() *PodSandbox { + if x != nil { + return x.Pod + } + return nil +} + +func (x *CreateContainerRequest) GetContainer() *Container { + if x != nil { + return x.Container + } + return nil +} + +type CreateContainerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Requested adjustments to container being created. + Adjust *ContainerAdjustment `protobuf:"bytes,1,opt,name=adjust,proto3" json:"adjust,omitempty"` + // Requested updates to other existing containers. + Update []*ContainerUpdate `protobuf:"bytes,2,rep,name=update,proto3" json:"update,omitempty"` + // Requested eviction of existing containers. + Evict []*ContainerEviction `protobuf:"bytes,3,rep,name=evict,proto3" json:"evict,omitempty"` +} + +func (x *CreateContainerResponse) Reset() { + *x = CreateContainerResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateContainerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateContainerResponse) ProtoMessage() {} + +func (x *CreateContainerResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateContainerResponse.ProtoReflect.Descriptor instead. +func (*CreateContainerResponse) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{8} +} + +func (x *CreateContainerResponse) GetAdjust() *ContainerAdjustment { + if x != nil { + return x.Adjust + } + return nil +} + +func (x *CreateContainerResponse) GetUpdate() []*ContainerUpdate { + if x != nil { + return x.Update + } + return nil +} + +func (x *CreateContainerResponse) GetEvict() []*ContainerEviction { + if x != nil { + return x.Evict + } + return nil +} + +type UpdateContainerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Pod of container being updated. + Pod *PodSandbox `protobuf:"bytes,1,opt,name=pod,proto3" json:"pod,omitempty"` + // Container being updated. + Container *Container `protobuf:"bytes,2,opt,name=container,proto3" json:"container,omitempty"` + // Resources to update. + LinuxResources *LinuxResources `protobuf:"bytes,3,opt,name=linux_resources,json=linuxResources,proto3" json:"linux_resources,omitempty"` +} + +func (x *UpdateContainerRequest) Reset() { + *x = UpdateContainerRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateContainerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateContainerRequest) ProtoMessage() {} + +func (x *UpdateContainerRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateContainerRequest.ProtoReflect.Descriptor instead. +func (*UpdateContainerRequest) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{9} +} + +func (x *UpdateContainerRequest) GetPod() *PodSandbox { + if x != nil { + return x.Pod + } + return nil +} + +func (x *UpdateContainerRequest) GetContainer() *Container { + if x != nil { + return x.Container + } + return nil +} + +func (x *UpdateContainerRequest) GetLinuxResources() *LinuxResources { + if x != nil { + return x.LinuxResources + } + return nil +} + +type UpdateContainerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Requested updates to containers. + Update []*ContainerUpdate `protobuf:"bytes,1,rep,name=update,proto3" json:"update,omitempty"` + // Requested eviction of containers. + Evict []*ContainerEviction `protobuf:"bytes,2,rep,name=evict,proto3" json:"evict,omitempty"` +} + +func (x *UpdateContainerResponse) Reset() { + *x = UpdateContainerResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateContainerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateContainerResponse) ProtoMessage() {} + +func (x *UpdateContainerResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateContainerResponse.ProtoReflect.Descriptor instead. +func (*UpdateContainerResponse) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{10} +} + +func (x *UpdateContainerResponse) GetUpdate() []*ContainerUpdate { + if x != nil { + return x.Update + } + return nil +} + +func (x *UpdateContainerResponse) GetEvict() []*ContainerEviction { + if x != nil { + return x.Evict + } + return nil +} + +type StopContainerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Pod of container being stopped. + Pod *PodSandbox `protobuf:"bytes,1,opt,name=pod,proto3" json:"pod,omitempty"` + // Container being stopped. + Container *Container `protobuf:"bytes,2,opt,name=container,proto3" json:"container,omitempty"` +} + +func (x *StopContainerRequest) Reset() { + *x = StopContainerRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StopContainerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StopContainerRequest) ProtoMessage() {} + +func (x *StopContainerRequest) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StopContainerRequest.ProtoReflect.Descriptor instead. +func (*StopContainerRequest) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{11} +} + +func (x *StopContainerRequest) GetPod() *PodSandbox { + if x != nil { + return x.Pod + } + return nil +} + +func (x *StopContainerRequest) GetContainer() *Container { + if x != nil { + return x.Container + } + return nil +} + +type StopContainerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Requested updates to containers. + Update []*ContainerUpdate `protobuf:"bytes,1,rep,name=update,proto3" json:"update,omitempty"` +} + +func (x *StopContainerResponse) Reset() { + *x = StopContainerResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StopContainerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StopContainerResponse) ProtoMessage() {} + +func (x *StopContainerResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StopContainerResponse.ProtoReflect.Descriptor instead. +func (*StopContainerResponse) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{12} +} + +func (x *StopContainerResponse) GetUpdate() []*ContainerUpdate { + if x != nil { + return x.Update + } + return nil +} + +type StateChangeEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Event type of notification. + Event Event `protobuf:"varint,1,opt,name=event,proto3,enum=nri.pkg.api.v1alpha1.Event" json:"event,omitempty"` + // Pod this notification is sent for. If this event is related to a container, + // pod is set to the pod of the container. + Pod *PodSandbox `protobuf:"bytes,2,opt,name=pod,proto3" json:"pod,omitempty"` + // Container this notification is sent for. If the event is related to a pod, + // container is nil. + Container *Container `protobuf:"bytes,3,opt,name=container,proto3" json:"container,omitempty"` +} + +func (x *StateChangeEvent) Reset() { + *x = StateChangeEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StateChangeEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StateChangeEvent) ProtoMessage() {} + +func (x *StateChangeEvent) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StateChangeEvent.ProtoReflect.Descriptor instead. +func (*StateChangeEvent) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{13} +} + +func (x *StateChangeEvent) GetEvent() Event { + if x != nil { + return x.Event + } + return Event_UNKNOWN +} + +func (x *StateChangeEvent) GetPod() *PodSandbox { + if x != nil { + return x.Pod + } + return nil +} + +func (x *StateChangeEvent) GetContainer() *Container { + if x != nil { + return x.Container + } + return nil +} + +// Empty response for those *Requests that are semantically events. +type Empty struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Empty) Reset() { + *x = Empty{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Empty) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Empty) ProtoMessage() {} + +func (x *Empty) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Empty.ProtoReflect.Descriptor instead. +func (*Empty) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{14} +} + +// Pod metadata that is considered relevant for a plugin. +type PodSandbox struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Uid string `protobuf:"bytes,3,opt,name=uid,proto3" json:"uid,omitempty"` + Namespace string `protobuf:"bytes,4,opt,name=namespace,proto3" json:"namespace,omitempty"` + Labels map[string]string `protobuf:"bytes,5,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Annotations map[string]string `protobuf:"bytes,6,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + RuntimeHandler string `protobuf:"bytes,7,opt,name=runtime_handler,json=runtimeHandler,proto3" json:"runtime_handler,omitempty"` + Linux *LinuxPodSandbox `protobuf:"bytes,8,opt,name=linux,proto3" json:"linux,omitempty"` + Pid uint32 `protobuf:"varint,9,opt,name=pid,proto3" json:"pid,omitempty"` // for NRI v1 emulation +} + +func (x *PodSandbox) Reset() { + *x = PodSandbox{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PodSandbox) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PodSandbox) ProtoMessage() {} + +func (x *PodSandbox) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PodSandbox.ProtoReflect.Descriptor instead. +func (*PodSandbox) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{15} +} + +func (x *PodSandbox) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *PodSandbox) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *PodSandbox) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +func (x *PodSandbox) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +func (x *PodSandbox) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *PodSandbox) GetAnnotations() map[string]string { + if x != nil { + return x.Annotations + } + return nil +} + +func (x *PodSandbox) GetRuntimeHandler() string { + if x != nil { + return x.RuntimeHandler + } + return "" +} + +func (x *PodSandbox) GetLinux() *LinuxPodSandbox { + if x != nil { + return x.Linux + } + return nil +} + +func (x *PodSandbox) GetPid() uint32 { + if x != nil { + return x.Pid + } + return 0 +} + +// PodSandbox linux-specific metadata +type LinuxPodSandbox struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PodOverhead *LinuxResources `protobuf:"bytes,1,opt,name=pod_overhead,json=podOverhead,proto3" json:"pod_overhead,omitempty"` + PodResources *LinuxResources `protobuf:"bytes,2,opt,name=pod_resources,json=podResources,proto3" json:"pod_resources,omitempty"` + CgroupParent string `protobuf:"bytes,3,opt,name=cgroup_parent,json=cgroupParent,proto3" json:"cgroup_parent,omitempty"` + CgroupsPath string `protobuf:"bytes,4,opt,name=cgroups_path,json=cgroupsPath,proto3" json:"cgroups_path,omitempty"` // for NRI v1 emulation + Namespaces []*LinuxNamespace `protobuf:"bytes,5,rep,name=namespaces,proto3" json:"namespaces,omitempty"` // for NRI v1 emulation + Resources *LinuxResources `protobuf:"bytes,6,opt,name=resources,proto3" json:"resources,omitempty"` // for NRI v1 emulation +} + +func (x *LinuxPodSandbox) Reset() { + *x = LinuxPodSandbox{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinuxPodSandbox) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinuxPodSandbox) ProtoMessage() {} + +func (x *LinuxPodSandbox) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinuxPodSandbox.ProtoReflect.Descriptor instead. +func (*LinuxPodSandbox) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{16} +} + +func (x *LinuxPodSandbox) GetPodOverhead() *LinuxResources { + if x != nil { + return x.PodOverhead + } + return nil +} + +func (x *LinuxPodSandbox) GetPodResources() *LinuxResources { + if x != nil { + return x.PodResources + } + return nil +} + +func (x *LinuxPodSandbox) GetCgroupParent() string { + if x != nil { + return x.CgroupParent + } + return "" +} + +func (x *LinuxPodSandbox) GetCgroupsPath() string { + if x != nil { + return x.CgroupsPath + } + return "" +} + +func (x *LinuxPodSandbox) GetNamespaces() []*LinuxNamespace { + if x != nil { + return x.Namespaces + } + return nil +} + +func (x *LinuxPodSandbox) GetResources() *LinuxResources { + if x != nil { + return x.Resources + } + return nil +} + +// Container metadata that is considered relevant for a plugin. +type Container struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + PodSandboxId string `protobuf:"bytes,2,opt,name=pod_sandbox_id,json=podSandboxId,proto3" json:"pod_sandbox_id,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + State ContainerState `protobuf:"varint,4,opt,name=state,proto3,enum=nri.pkg.api.v1alpha1.ContainerState" json:"state,omitempty"` + Labels map[string]string `protobuf:"bytes,5,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Annotations map[string]string `protobuf:"bytes,6,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Args []string `protobuf:"bytes,7,rep,name=args,proto3" json:"args,omitempty"` + Env []string `protobuf:"bytes,8,rep,name=env,proto3" json:"env,omitempty"` + Mounts []*Mount `protobuf:"bytes,9,rep,name=mounts,proto3" json:"mounts,omitempty"` + Hooks *Hooks `protobuf:"bytes,10,opt,name=hooks,proto3" json:"hooks,omitempty"` + Linux *LinuxContainer `protobuf:"bytes,11,opt,name=linux,proto3" json:"linux,omitempty"` + Pid uint32 `protobuf:"varint,12,opt,name=pid,proto3" json:"pid,omitempty"` // for NRI v1 emulation +} + +func (x *Container) Reset() { + *x = Container{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Container) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Container) ProtoMessage() {} + +func (x *Container) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Container.ProtoReflect.Descriptor instead. +func (*Container) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{17} +} + +func (x *Container) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Container) GetPodSandboxId() string { + if x != nil { + return x.PodSandboxId + } + return "" +} + +func (x *Container) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Container) GetState() ContainerState { + if x != nil { + return x.State + } + return ContainerState_CONTAINER_UNKNOWN +} + +func (x *Container) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *Container) GetAnnotations() map[string]string { + if x != nil { + return x.Annotations + } + return nil +} + +func (x *Container) GetArgs() []string { + if x != nil { + return x.Args + } + return nil +} + +func (x *Container) GetEnv() []string { + if x != nil { + return x.Env + } + return nil +} + +func (x *Container) GetMounts() []*Mount { + if x != nil { + return x.Mounts + } + return nil +} + +func (x *Container) GetHooks() *Hooks { + if x != nil { + return x.Hooks + } + return nil +} + +func (x *Container) GetLinux() *LinuxContainer { + if x != nil { + return x.Linux + } + return nil +} + +func (x *Container) GetPid() uint32 { + if x != nil { + return x.Pid + } + return 0 +} + +// A container mount. +type Mount struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Destination string `protobuf:"bytes,1,opt,name=destination,proto3" json:"destination,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Source string `protobuf:"bytes,3,opt,name=source,proto3" json:"source,omitempty"` + Options []string `protobuf:"bytes,4,rep,name=options,proto3" json:"options,omitempty"` +} + +func (x *Mount) Reset() { + *x = Mount{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Mount) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Mount) ProtoMessage() {} + +func (x *Mount) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Mount.ProtoReflect.Descriptor instead. +func (*Mount) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{18} +} + +func (x *Mount) GetDestination() string { + if x != nil { + return x.Destination + } + return "" +} + +func (x *Mount) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Mount) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *Mount) GetOptions() []string { + if x != nil { + return x.Options + } + return nil +} + +// Container OCI hooks. +type Hooks struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Prestart []*Hook `protobuf:"bytes,1,rep,name=prestart,proto3" json:"prestart,omitempty"` + CreateRuntime []*Hook `protobuf:"bytes,2,rep,name=create_runtime,json=createRuntime,proto3" json:"create_runtime,omitempty"` + CreateContainer []*Hook `protobuf:"bytes,3,rep,name=create_container,json=createContainer,proto3" json:"create_container,omitempty"` + StartContainer []*Hook `protobuf:"bytes,4,rep,name=start_container,json=startContainer,proto3" json:"start_container,omitempty"` + Poststart []*Hook `protobuf:"bytes,5,rep,name=poststart,proto3" json:"poststart,omitempty"` + Poststop []*Hook `protobuf:"bytes,6,rep,name=poststop,proto3" json:"poststop,omitempty"` +} + +func (x *Hooks) Reset() { + *x = Hooks{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Hooks) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Hooks) ProtoMessage() {} + +func (x *Hooks) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Hooks.ProtoReflect.Descriptor instead. +func (*Hooks) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{19} +} + +func (x *Hooks) GetPrestart() []*Hook { + if x != nil { + return x.Prestart + } + return nil +} + +func (x *Hooks) GetCreateRuntime() []*Hook { + if x != nil { + return x.CreateRuntime + } + return nil +} + +func (x *Hooks) GetCreateContainer() []*Hook { + if x != nil { + return x.CreateContainer + } + return nil +} + +func (x *Hooks) GetStartContainer() []*Hook { + if x != nil { + return x.StartContainer + } + return nil +} + +func (x *Hooks) GetPoststart() []*Hook { + if x != nil { + return x.Poststart + } + return nil +} + +func (x *Hooks) GetPoststop() []*Hook { + if x != nil { + return x.Poststop + } + return nil +} + +// One OCI hook. +type Hook struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + Args []string `protobuf:"bytes,2,rep,name=args,proto3" json:"args,omitempty"` + Env []string `protobuf:"bytes,3,rep,name=env,proto3" json:"env,omitempty"` + Timeout *OptionalInt `protobuf:"bytes,4,opt,name=timeout,proto3" json:"timeout,omitempty"` +} + +func (x *Hook) Reset() { + *x = Hook{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Hook) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Hook) ProtoMessage() {} + +func (x *Hook) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Hook.ProtoReflect.Descriptor instead. +func (*Hook) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{20} +} + +func (x *Hook) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *Hook) GetArgs() []string { + if x != nil { + return x.Args + } + return nil +} + +func (x *Hook) GetEnv() []string { + if x != nil { + return x.Env + } + return nil +} + +func (x *Hook) GetTimeout() *OptionalInt { + if x != nil { + return x.Timeout + } + return nil +} + +// Container (linux) metadata. +type LinuxContainer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespaces []*LinuxNamespace `protobuf:"bytes,1,rep,name=namespaces,proto3" json:"namespaces,omitempty"` + Devices []*LinuxDevice `protobuf:"bytes,2,rep,name=devices,proto3" json:"devices,omitempty"` + Resources *LinuxResources `protobuf:"bytes,3,opt,name=resources,proto3" json:"resources,omitempty"` + OomScoreAdj *OptionalInt `protobuf:"bytes,4,opt,name=oom_score_adj,json=oomScoreAdj,proto3" json:"oom_score_adj,omitempty"` + CgroupsPath string `protobuf:"bytes,5,opt,name=cgroups_path,json=cgroupsPath,proto3" json:"cgroups_path,omitempty"` +} + +func (x *LinuxContainer) Reset() { + *x = LinuxContainer{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinuxContainer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinuxContainer) ProtoMessage() {} + +func (x *LinuxContainer) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinuxContainer.ProtoReflect.Descriptor instead. +func (*LinuxContainer) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{21} +} + +func (x *LinuxContainer) GetNamespaces() []*LinuxNamespace { + if x != nil { + return x.Namespaces + } + return nil +} + +func (x *LinuxContainer) GetDevices() []*LinuxDevice { + if x != nil { + return x.Devices + } + return nil +} + +func (x *LinuxContainer) GetResources() *LinuxResources { + if x != nil { + return x.Resources + } + return nil +} + +func (x *LinuxContainer) GetOomScoreAdj() *OptionalInt { + if x != nil { + return x.OomScoreAdj + } + return nil +} + +func (x *LinuxContainer) GetCgroupsPath() string { + if x != nil { + return x.CgroupsPath + } + return "" +} + +// A linux namespace. +type LinuxNamespace struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` +} + +func (x *LinuxNamespace) Reset() { + *x = LinuxNamespace{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinuxNamespace) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinuxNamespace) ProtoMessage() {} + +func (x *LinuxNamespace) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinuxNamespace.ProtoReflect.Descriptor instead. +func (*LinuxNamespace) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{22} +} + +func (x *LinuxNamespace) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *LinuxNamespace) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +// A container (linux) device. +type LinuxDevice struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Major int64 `protobuf:"varint,3,opt,name=major,proto3" json:"major,omitempty"` + Minor int64 `protobuf:"varint,4,opt,name=minor,proto3" json:"minor,omitempty"` + FileMode *OptionalFileMode `protobuf:"bytes,5,opt,name=file_mode,json=fileMode,proto3" json:"file_mode,omitempty"` + Uid *OptionalUInt32 `protobuf:"bytes,6,opt,name=uid,proto3" json:"uid,omitempty"` + Gid *OptionalUInt32 `protobuf:"bytes,7,opt,name=gid,proto3" json:"gid,omitempty"` +} + +func (x *LinuxDevice) Reset() { + *x = LinuxDevice{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinuxDevice) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinuxDevice) ProtoMessage() {} + +func (x *LinuxDevice) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinuxDevice.ProtoReflect.Descriptor instead. +func (*LinuxDevice) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{23} +} + +func (x *LinuxDevice) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *LinuxDevice) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *LinuxDevice) GetMajor() int64 { + if x != nil { + return x.Major + } + return 0 +} + +func (x *LinuxDevice) GetMinor() int64 { + if x != nil { + return x.Minor + } + return 0 +} + +func (x *LinuxDevice) GetFileMode() *OptionalFileMode { + if x != nil { + return x.FileMode + } + return nil +} + +func (x *LinuxDevice) GetUid() *OptionalUInt32 { + if x != nil { + return x.Uid + } + return nil +} + +func (x *LinuxDevice) GetGid() *OptionalUInt32 { + if x != nil { + return x.Gid + } + return nil +} + +// A linux device cgroup controller rule. +type LinuxDeviceCgroup struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Allow bool `protobuf:"varint,1,opt,name=allow,proto3" json:"allow,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Major *OptionalInt64 `protobuf:"bytes,3,opt,name=major,proto3" json:"major,omitempty"` + Minor *OptionalInt64 `protobuf:"bytes,4,opt,name=minor,proto3" json:"minor,omitempty"` + Access string `protobuf:"bytes,5,opt,name=access,proto3" json:"access,omitempty"` +} + +func (x *LinuxDeviceCgroup) Reset() { + *x = LinuxDeviceCgroup{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinuxDeviceCgroup) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinuxDeviceCgroup) ProtoMessage() {} + +func (x *LinuxDeviceCgroup) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinuxDeviceCgroup.ProtoReflect.Descriptor instead. +func (*LinuxDeviceCgroup) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{24} +} + +func (x *LinuxDeviceCgroup) GetAllow() bool { + if x != nil { + return x.Allow + } + return false +} + +func (x *LinuxDeviceCgroup) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *LinuxDeviceCgroup) GetMajor() *OptionalInt64 { + if x != nil { + return x.Major + } + return nil +} + +func (x *LinuxDeviceCgroup) GetMinor() *OptionalInt64 { + if x != nil { + return x.Minor + } + return nil +} + +func (x *LinuxDeviceCgroup) GetAccess() string { + if x != nil { + return x.Access + } + return "" +} + +// Container (linux) resources. +type LinuxResources struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Memory *LinuxMemory `protobuf:"bytes,1,opt,name=memory,proto3" json:"memory,omitempty"` + Cpu *LinuxCPU `protobuf:"bytes,2,opt,name=cpu,proto3" json:"cpu,omitempty"` + HugepageLimits []*HugepageLimit `protobuf:"bytes,3,rep,name=hugepage_limits,json=hugepageLimits,proto3" json:"hugepage_limits,omitempty"` + BlockioClass *OptionalString `protobuf:"bytes,4,opt,name=blockio_class,json=blockioClass,proto3" json:"blockio_class,omitempty"` + RdtClass *OptionalString `protobuf:"bytes,5,opt,name=rdt_class,json=rdtClass,proto3" json:"rdt_class,omitempty"` + Unified map[string]string `protobuf:"bytes,6,rep,name=unified,proto3" json:"unified,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Devices []*LinuxDeviceCgroup `protobuf:"bytes,7,rep,name=devices,proto3" json:"devices,omitempty"` // for NRI v1 emulation +} + +func (x *LinuxResources) Reset() { + *x = LinuxResources{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinuxResources) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinuxResources) ProtoMessage() {} + +func (x *LinuxResources) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinuxResources.ProtoReflect.Descriptor instead. +func (*LinuxResources) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{25} +} + +func (x *LinuxResources) GetMemory() *LinuxMemory { + if x != nil { + return x.Memory + } + return nil +} + +func (x *LinuxResources) GetCpu() *LinuxCPU { + if x != nil { + return x.Cpu + } + return nil +} + +func (x *LinuxResources) GetHugepageLimits() []*HugepageLimit { + if x != nil { + return x.HugepageLimits + } + return nil +} + +func (x *LinuxResources) GetBlockioClass() *OptionalString { + if x != nil { + return x.BlockioClass + } + return nil +} + +func (x *LinuxResources) GetRdtClass() *OptionalString { + if x != nil { + return x.RdtClass + } + return nil +} + +func (x *LinuxResources) GetUnified() map[string]string { + if x != nil { + return x.Unified + } + return nil +} + +func (x *LinuxResources) GetDevices() []*LinuxDeviceCgroup { + if x != nil { + return x.Devices + } + return nil +} + +// Memory-related parts of (linux) resources. +type LinuxMemory struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Limit *OptionalInt64 `protobuf:"bytes,1,opt,name=limit,proto3" json:"limit,omitempty"` + Reservation *OptionalInt64 `protobuf:"bytes,2,opt,name=reservation,proto3" json:"reservation,omitempty"` + Swap *OptionalInt64 `protobuf:"bytes,3,opt,name=swap,proto3" json:"swap,omitempty"` + Kernel *OptionalInt64 `protobuf:"bytes,4,opt,name=kernel,proto3" json:"kernel,omitempty"` + KernelTcp *OptionalInt64 `protobuf:"bytes,5,opt,name=kernel_tcp,json=kernelTcp,proto3" json:"kernel_tcp,omitempty"` + Swappiness *OptionalUInt64 `protobuf:"bytes,6,opt,name=swappiness,proto3" json:"swappiness,omitempty"` + DisableOomKiller *OptionalBool `protobuf:"bytes,7,opt,name=disable_oom_killer,json=disableOomKiller,proto3" json:"disable_oom_killer,omitempty"` + UseHierarchy *OptionalBool `protobuf:"bytes,8,opt,name=use_hierarchy,json=useHierarchy,proto3" json:"use_hierarchy,omitempty"` +} + +func (x *LinuxMemory) Reset() { + *x = LinuxMemory{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinuxMemory) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinuxMemory) ProtoMessage() {} + +func (x *LinuxMemory) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinuxMemory.ProtoReflect.Descriptor instead. +func (*LinuxMemory) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{26} +} + +func (x *LinuxMemory) GetLimit() *OptionalInt64 { + if x != nil { + return x.Limit + } + return nil +} + +func (x *LinuxMemory) GetReservation() *OptionalInt64 { + if x != nil { + return x.Reservation + } + return nil +} + +func (x *LinuxMemory) GetSwap() *OptionalInt64 { + if x != nil { + return x.Swap + } + return nil +} + +func (x *LinuxMemory) GetKernel() *OptionalInt64 { + if x != nil { + return x.Kernel + } + return nil +} + +func (x *LinuxMemory) GetKernelTcp() *OptionalInt64 { + if x != nil { + return x.KernelTcp + } + return nil +} + +func (x *LinuxMemory) GetSwappiness() *OptionalUInt64 { + if x != nil { + return x.Swappiness + } + return nil +} + +func (x *LinuxMemory) GetDisableOomKiller() *OptionalBool { + if x != nil { + return x.DisableOomKiller + } + return nil +} + +func (x *LinuxMemory) GetUseHierarchy() *OptionalBool { + if x != nil { + return x.UseHierarchy + } + return nil +} + +// CPU-related parts of (linux) resources. +type LinuxCPU struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Shares *OptionalUInt64 `protobuf:"bytes,1,opt,name=shares,proto3" json:"shares,omitempty"` + Quota *OptionalInt64 `protobuf:"bytes,2,opt,name=quota,proto3" json:"quota,omitempty"` + Period *OptionalUInt64 `protobuf:"bytes,3,opt,name=period,proto3" json:"period,omitempty"` + RealtimeRuntime *OptionalInt64 `protobuf:"bytes,4,opt,name=realtime_runtime,json=realtimeRuntime,proto3" json:"realtime_runtime,omitempty"` + RealtimePeriod *OptionalUInt64 `protobuf:"bytes,5,opt,name=realtime_period,json=realtimePeriod,proto3" json:"realtime_period,omitempty"` + Cpus string `protobuf:"bytes,6,opt,name=cpus,proto3" json:"cpus,omitempty"` + Mems string `protobuf:"bytes,7,opt,name=mems,proto3" json:"mems,omitempty"` +} + +func (x *LinuxCPU) Reset() { + *x = LinuxCPU{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinuxCPU) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinuxCPU) ProtoMessage() {} + +func (x *LinuxCPU) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinuxCPU.ProtoReflect.Descriptor instead. +func (*LinuxCPU) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{27} +} + +func (x *LinuxCPU) GetShares() *OptionalUInt64 { + if x != nil { + return x.Shares + } + return nil +} + +func (x *LinuxCPU) GetQuota() *OptionalInt64 { + if x != nil { + return x.Quota + } + return nil +} + +func (x *LinuxCPU) GetPeriod() *OptionalUInt64 { + if x != nil { + return x.Period + } + return nil +} + +func (x *LinuxCPU) GetRealtimeRuntime() *OptionalInt64 { + if x != nil { + return x.RealtimeRuntime + } + return nil +} + +func (x *LinuxCPU) GetRealtimePeriod() *OptionalUInt64 { + if x != nil { + return x.RealtimePeriod + } + return nil +} + +func (x *LinuxCPU) GetCpus() string { + if x != nil { + return x.Cpus + } + return "" +} + +func (x *LinuxCPU) GetMems() string { + if x != nil { + return x.Mems + } + return "" +} + +// Container huge page limit. +type HugepageLimit struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PageSize string `protobuf:"bytes,1,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + Limit uint64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` +} + +func (x *HugepageLimit) Reset() { + *x = HugepageLimit{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HugepageLimit) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HugepageLimit) ProtoMessage() {} + +func (x *HugepageLimit) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HugepageLimit.ProtoReflect.Descriptor instead. +func (*HugepageLimit) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{28} +} + +func (x *HugepageLimit) GetPageSize() string { + if x != nil { + return x.PageSize + } + return "" +} + +func (x *HugepageLimit) GetLimit() uint64 { + if x != nil { + return x.Limit + } + return 0 +} + +// Requested adjustments to a container being created. +type ContainerAdjustment struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Annotations map[string]string `protobuf:"bytes,2,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Mounts []*Mount `protobuf:"bytes,3,rep,name=mounts,proto3" json:"mounts,omitempty"` + Env []*KeyValue `protobuf:"bytes,4,rep,name=env,proto3" json:"env,omitempty"` + Hooks *Hooks `protobuf:"bytes,5,opt,name=hooks,proto3" json:"hooks,omitempty"` + Linux *LinuxContainerAdjustment `protobuf:"bytes,6,opt,name=linux,proto3" json:"linux,omitempty"` +} + +func (x *ContainerAdjustment) Reset() { + *x = ContainerAdjustment{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ContainerAdjustment) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContainerAdjustment) ProtoMessage() {} + +func (x *ContainerAdjustment) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContainerAdjustment.ProtoReflect.Descriptor instead. +func (*ContainerAdjustment) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{29} +} + +func (x *ContainerAdjustment) GetAnnotations() map[string]string { + if x != nil { + return x.Annotations + } + return nil +} + +func (x *ContainerAdjustment) GetMounts() []*Mount { + if x != nil { + return x.Mounts + } + return nil +} + +func (x *ContainerAdjustment) GetEnv() []*KeyValue { + if x != nil { + return x.Env + } + return nil +} + +func (x *ContainerAdjustment) GetHooks() *Hooks { + if x != nil { + return x.Hooks + } + return nil +} + +func (x *ContainerAdjustment) GetLinux() *LinuxContainerAdjustment { + if x != nil { + return x.Linux + } + return nil +} + +// Adjustments to (linux) resources. +type LinuxContainerAdjustment struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Devices []*LinuxDevice `protobuf:"bytes,1,rep,name=devices,proto3" json:"devices,omitempty"` + Resources *LinuxResources `protobuf:"bytes,2,opt,name=resources,proto3" json:"resources,omitempty"` + CgroupsPath string `protobuf:"bytes,3,opt,name=cgroups_path,json=cgroupsPath,proto3" json:"cgroups_path,omitempty"` +} + +func (x *LinuxContainerAdjustment) Reset() { + *x = LinuxContainerAdjustment{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinuxContainerAdjustment) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinuxContainerAdjustment) ProtoMessage() {} + +func (x *LinuxContainerAdjustment) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinuxContainerAdjustment.ProtoReflect.Descriptor instead. +func (*LinuxContainerAdjustment) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{30} +} + +func (x *LinuxContainerAdjustment) GetDevices() []*LinuxDevice { + if x != nil { + return x.Devices + } + return nil +} + +func (x *LinuxContainerAdjustment) GetResources() *LinuxResources { + if x != nil { + return x.Resources + } + return nil +} + +func (x *LinuxContainerAdjustment) GetCgroupsPath() string { + if x != nil { + return x.CgroupsPath + } + return "" +} + +// Requested update to an already created container. +type ContainerUpdate struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContainerId string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + Linux *LinuxContainerUpdate `protobuf:"bytes,2,opt,name=linux,proto3" json:"linux,omitempty"` + IgnoreFailure bool `protobuf:"varint,3,opt,name=ignore_failure,json=ignoreFailure,proto3" json:"ignore_failure,omitempty"` +} + +func (x *ContainerUpdate) Reset() { + *x = ContainerUpdate{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ContainerUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContainerUpdate) ProtoMessage() {} + +func (x *ContainerUpdate) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContainerUpdate.ProtoReflect.Descriptor instead. +func (*ContainerUpdate) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{31} +} + +func (x *ContainerUpdate) GetContainerId() string { + if x != nil { + return x.ContainerId + } + return "" +} + +func (x *ContainerUpdate) GetLinux() *LinuxContainerUpdate { + if x != nil { + return x.Linux + } + return nil +} + +func (x *ContainerUpdate) GetIgnoreFailure() bool { + if x != nil { + return x.IgnoreFailure + } + return false +} + +// Updates to (linux) resources. +type LinuxContainerUpdate struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Resources *LinuxResources `protobuf:"bytes,1,opt,name=resources,proto3" json:"resources,omitempty"` +} + +func (x *LinuxContainerUpdate) Reset() { + *x = LinuxContainerUpdate{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinuxContainerUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinuxContainerUpdate) ProtoMessage() {} + +func (x *LinuxContainerUpdate) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinuxContainerUpdate.ProtoReflect.Descriptor instead. +func (*LinuxContainerUpdate) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{32} +} + +func (x *LinuxContainerUpdate) GetResources() *LinuxResources { + if x != nil { + return x.Resources + } + return nil +} + +// Request to evict (IOW unsolicitedly stop) a container. +type ContainerEviction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Container to evict. + ContainerId string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + // Human-readable reason for eviction. + Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` +} + +func (x *ContainerEviction) Reset() { + *x = ContainerEviction{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ContainerEviction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContainerEviction) ProtoMessage() {} + +func (x *ContainerEviction) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContainerEviction.ProtoReflect.Descriptor instead. +func (*ContainerEviction) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{33} +} + +func (x *ContainerEviction) GetContainerId() string { + if x != nil { + return x.ContainerId + } + return "" +} + +func (x *ContainerEviction) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +// KeyValue represents an environment variable. +type KeyValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *KeyValue) Reset() { + *x = KeyValue{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *KeyValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeyValue) ProtoMessage() {} + +func (x *KeyValue) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KeyValue.ProtoReflect.Descriptor instead. +func (*KeyValue) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{34} +} + +func (x *KeyValue) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *KeyValue) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +// An optional string value. +type OptionalString struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *OptionalString) Reset() { + *x = OptionalString{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OptionalString) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OptionalString) ProtoMessage() {} + +func (x *OptionalString) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OptionalString.ProtoReflect.Descriptor instead. +func (*OptionalString) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{35} +} + +func (x *OptionalString) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +// An optional signed integer value. +type OptionalInt struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *OptionalInt) Reset() { + *x = OptionalInt{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OptionalInt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OptionalInt) ProtoMessage() {} + +func (x *OptionalInt) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OptionalInt.ProtoReflect.Descriptor instead. +func (*OptionalInt) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{36} +} + +func (x *OptionalInt) GetValue() int64 { + if x != nil { + return x.Value + } + return 0 +} + +// An optional 32-bit signed integer value. +type OptionalInt32 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *OptionalInt32) Reset() { + *x = OptionalInt32{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OptionalInt32) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OptionalInt32) ProtoMessage() {} + +func (x *OptionalInt32) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[37] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OptionalInt32.ProtoReflect.Descriptor instead. +func (*OptionalInt32) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{37} +} + +func (x *OptionalInt32) GetValue() int32 { + if x != nil { + return x.Value + } + return 0 +} + +// An optional 32-bit unsigned integer value. +type OptionalUInt32 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *OptionalUInt32) Reset() { + *x = OptionalUInt32{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OptionalUInt32) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OptionalUInt32) ProtoMessage() {} + +func (x *OptionalUInt32) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[38] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OptionalUInt32.ProtoReflect.Descriptor instead. +func (*OptionalUInt32) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{38} +} + +func (x *OptionalUInt32) GetValue() uint32 { + if x != nil { + return x.Value + } + return 0 +} + +// An optional 64-bit signed integer value. +type OptionalInt64 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *OptionalInt64) Reset() { + *x = OptionalInt64{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OptionalInt64) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OptionalInt64) ProtoMessage() {} + +func (x *OptionalInt64) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[39] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OptionalInt64.ProtoReflect.Descriptor instead. +func (*OptionalInt64) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{39} +} + +func (x *OptionalInt64) GetValue() int64 { + if x != nil { + return x.Value + } + return 0 +} + +// An optional 64-bit unsigned integer value. +type OptionalUInt64 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value uint64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *OptionalUInt64) Reset() { + *x = OptionalUInt64{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OptionalUInt64) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OptionalUInt64) ProtoMessage() {} + +func (x *OptionalUInt64) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[40] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OptionalUInt64.ProtoReflect.Descriptor instead. +func (*OptionalUInt64) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{40} +} + +func (x *OptionalUInt64) GetValue() uint64 { + if x != nil { + return x.Value + } + return 0 +} + +// An optional boolean value. +type OptionalBool struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *OptionalBool) Reset() { + *x = OptionalBool{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OptionalBool) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OptionalBool) ProtoMessage() {} + +func (x *OptionalBool) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[41] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OptionalBool.ProtoReflect.Descriptor instead. +func (*OptionalBool) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{41} +} + +func (x *OptionalBool) GetValue() bool { + if x != nil { + return x.Value + } + return false +} + +// An optional value of file permissions. +type OptionalFileMode struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *OptionalFileMode) Reset() { + *x = OptionalFileMode{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_api_api_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OptionalFileMode) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OptionalFileMode) ProtoMessage() {} + +func (x *OptionalFileMode) ProtoReflect() protoreflect.Message { + mi := &file_pkg_api_api_proto_msgTypes[42] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OptionalFileMode.ProtoReflect.Descriptor instead. +func (*OptionalFileMode) Descriptor() ([]byte, []int) { + return file_pkg_api_api_proto_rawDescGZIP(), []int{42} +} + +func (x *OptionalFileMode) GetValue() uint32 { + if x != nil { + return x.Value + } + return 0 +} + +var File_pkg_api_api_proto protoreflect.FileDescriptor + +var file_pkg_api_api_proto_rawDesc = []byte{ + 0x0a, 0x11, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x22, 0x57, 0x0a, 0x15, 0x52, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 0x69, 0x64, + 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x49, + 0x64, 0x78, 0x22, 0x97, 0x01, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, + 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, + 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3d, 0x0a, + 0x05, 0x65, 0x76, 0x69, 0x63, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6e, + 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x69, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x65, 0x76, 0x69, 0x63, 0x74, 0x22, 0x59, 0x0a, 0x18, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c, + 0x65, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, + 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, + 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x76, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, + 0x2b, 0x0a, 0x11, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x8b, 0x01, 0x0a, + 0x12, 0x53, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x04, 0x70, 0x6f, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x20, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, + 0x62, 0x6f, 0x78, 0x52, 0x04, 0x70, 0x6f, 0x64, 0x73, 0x12, 0x3f, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x0a, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x22, 0x54, 0x0a, 0x13, 0x53, 0x79, + 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x25, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x22, 0x8b, 0x01, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x03, 0x70, + 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, + 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x03, 0x70, 0x6f, 0x64, 0x12, + 0x3d, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0xda, + 0x01, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x06, 0x61, 0x64, + 0x6a, 0x75, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6e, 0x72, 0x69, + 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x6a, 0x75, 0x73, + 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x61, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x12, 0x3d, 0x0a, + 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, + 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3d, 0x0a, 0x05, + 0x65, 0x76, 0x69, 0x63, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6e, 0x72, + 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x69, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x65, 0x76, 0x69, 0x63, 0x74, 0x22, 0xda, 0x01, 0x0a, 0x16, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x03, 0x70, 0x6f, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, + 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x03, 0x70, 0x6f, 0x64, 0x12, 0x3d, 0x0a, 0x09, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x0f, 0x6c, 0x69, 0x6e, + 0x75, 0x78, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x0e, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x97, 0x01, 0x0a, 0x17, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x06, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x12, 0x3d, 0x0a, 0x05, 0x65, 0x76, 0x69, 0x63, 0x74, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x45, 0x76, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x65, 0x76, 0x69, + 0x63, 0x74, 0x22, 0x89, 0x01, 0x0a, 0x14, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x03, 0x70, + 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, + 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x03, 0x70, 0x6f, 0x64, 0x12, + 0x3d, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x56, + 0x0a, 0x15, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, + 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x06, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0xb8, 0x01, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x05, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x6e, 0x72, 0x69, + 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x32, + 0x0a, 0x03, 0x70, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6e, 0x72, + 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x03, 0x70, + 0x6f, 0x64, 0x12, 0x3d, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xee, 0x03, 0x0a, 0x0a, 0x50, + 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, + 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x44, 0x0a, + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, + 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x12, 0x53, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, + 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, + 0x72, 0x12, 0x3b, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x25, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x50, 0x6f, 0x64, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x12, 0x10, + 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, + 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3e, 0x0a, 0x10, 0x41, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf7, 0x02, 0x0a, 0x0f, + 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, + 0x47, 0x0a, 0x0c, 0x70, 0x6f, 0x64, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x61, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, + 0x75, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x0b, 0x70, 0x6f, 0x64, + 0x4f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x61, 0x64, 0x12, 0x49, 0x0a, 0x0d, 0x70, 0x6f, 0x64, 0x5f, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x0c, 0x70, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x44, 0x0a, 0x0a, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x73, 0x12, 0x42, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, + 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x81, 0x05, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x6f, 0x64, 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x62, + 0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x6f, 0x64, + 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x6e, + 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6e, 0x72, 0x69, 0x2e, + 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x52, + 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x08, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x33, 0x0a, 0x06, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, + 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x31, 0x0a, + 0x05, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, + 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x05, 0x68, 0x6f, 0x6f, 0x6b, 0x73, + 0x12, 0x3a, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x12, 0x10, 0x0a, 0x03, + 0x70, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x1a, 0x39, + 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6f, 0x0a, 0x05, 0x4d, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x80, 0x03, 0x0a, 0x05, 0x48, + 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0x36, 0x0a, 0x08, 0x70, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x6f, + 0x6f, 0x6b, 0x52, 0x08, 0x70, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x41, 0x0a, 0x0e, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, + 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, + 0x45, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x72, 0x69, 0x2e, + 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x43, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x0e, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x09, 0x70, + 0x6f, 0x73, 0x74, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x09, 0x70, 0x6f, 0x73, 0x74, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x36, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x74, 0x6f, + 0x70, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, + 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, + 0x6f, 0x6f, 0x6b, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x74, 0x6f, 0x70, 0x22, 0x7d, 0x0a, + 0x04, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x10, 0x0a, + 0x03, 0x65, 0x6e, 0x76, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, + 0x3b, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x21, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x49, 0x6e, 0x74, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xc1, 0x02, 0x0a, + 0x0e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, + 0x44, 0x0a, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, + 0x6e, 0x75, 0x78, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x12, 0x42, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, + 0x75, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x0d, 0x6f, 0x6f, 0x6d, 0x5f, 0x73, 0x63, + 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x64, 0x6a, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, + 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, + 0x52, 0x0b, 0x6f, 0x6f, 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x41, 0x64, 0x6a, 0x12, 0x21, 0x0a, + 0x0c, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, 0x68, + 0x22, 0x38, 0x0a, 0x0e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x96, 0x02, 0x0a, 0x0b, 0x4c, + 0x69, 0x6e, 0x75, 0x78, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x43, + 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x26, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4d, + 0x6f, 0x64, 0x65, 0x12, 0x36, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x03, 0x67, + 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, + 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x52, 0x03, + 0x67, 0x69, 0x64, 0x22, 0xcb, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x43, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x6c, + 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x12, + 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x39, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x39, + 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, + 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, + 0x36, 0x34, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x22, 0xa5, 0x04, 0x0a, 0x0e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, + 0x78, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, + 0x30, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6e, + 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x50, 0x55, 0x52, 0x03, 0x63, 0x70, + 0x75, 0x12, 0x4c, 0x0a, 0x0f, 0x68, 0x75, 0x67, 0x65, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, + 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x48, 0x75, 0x67, 0x65, 0x70, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, + 0x0e, 0x68, 0x75, 0x67, 0x65, 0x70, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, + 0x49, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6f, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x69, 0x6f, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x41, 0x0a, 0x09, 0x72, 0x64, + 0x74, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x52, 0x08, 0x72, 0x64, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x4b, 0x0a, + 0x07, 0x75, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, + 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x07, 0x75, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x07, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6e, 0x72, + 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x1a, 0x3a, 0x0a, + 0x0c, 0x55, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xaa, 0x04, 0x0a, 0x0b, 0x4c, 0x69, + 0x6e, 0x75, 0x78, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, + 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x05, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x12, 0x45, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, + 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x0b, + 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x04, 0x73, + 0x77, 0x61, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, + 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x04, + 0x73, 0x77, 0x61, 0x70, 0x12, 0x3b, 0x0a, 0x06, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x06, 0x6b, 0x65, 0x72, 0x6e, 0x65, + 0x6c, 0x12, 0x42, 0x0a, 0x0a, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x74, 0x63, 0x70, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x09, 0x6b, 0x65, 0x72, 0x6e, + 0x65, 0x6c, 0x54, 0x63, 0x70, 0x12, 0x44, 0x0a, 0x0a, 0x73, 0x77, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x65, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, + 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, + 0x0a, 0x73, 0x77, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x12, 0x50, 0x0a, 0x12, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6f, 0x6f, 0x6d, 0x5f, 0x6b, 0x69, 0x6c, 0x6c, 0x65, + 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, + 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x10, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x4f, 0x6f, 0x6d, 0x4b, 0x69, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x47, 0x0a, + 0x0d, 0x75, 0x73, 0x65, 0x5f, 0x68, 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x48, 0x69, 0x65, + 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x22, 0x88, 0x03, 0x0a, 0x08, 0x4c, 0x69, 0x6e, 0x75, 0x78, + 0x43, 0x50, 0x55, 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, + 0x73, 0x12, 0x39, 0x0a, 0x05, 0x71, 0x75, 0x6f, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x05, 0x71, 0x75, 0x6f, 0x74, 0x61, 0x12, 0x3c, 0x0a, 0x06, + 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, + 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x55, 0x49, 0x6e, 0x74, + 0x36, 0x34, 0x52, 0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x4e, 0x0a, 0x10, 0x72, 0x65, + 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x0f, 0x72, 0x65, 0x61, 0x6c, 0x74, + 0x69, 0x6d, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x4d, 0x0a, 0x0f, 0x72, 0x65, + 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x0e, 0x72, 0x65, 0x61, 0x6c, 0x74, + 0x69, 0x6d, 0x65, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x70, 0x75, + 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x70, 0x75, 0x73, 0x12, 0x12, 0x0a, + 0x04, 0x6d, 0x65, 0x6d, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x65, 0x6d, + 0x73, 0x22, 0x42, 0x0a, 0x0d, 0x48, 0x75, 0x67, 0x65, 0x70, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x6d, + 0x69, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x93, 0x03, 0x0a, 0x13, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x41, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x5c, 0x0a, + 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x41, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, + 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x33, 0x0a, 0x06, 0x6d, + 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x72, + 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, + 0x12, 0x30, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x65, + 0x6e, 0x76, 0x12, 0x31, 0x0a, 0x05, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x05, + 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0x44, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, + 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x6a, 0x75, 0x73, 0x74, + 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x1a, 0x3e, 0x0a, 0x10, 0x41, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xbe, 0x01, 0x0a, 0x18, + 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x64, + 0x6a, 0x75, 0x73, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x3b, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6e, 0x72, 0x69, 0x2e, + 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, + 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, 0x68, 0x22, 0x9d, 0x01, 0x0a, + 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x05, + 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, + 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, + 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x22, 0x5a, 0x0a, 0x14, + 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, + 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, + 0x69, 0x6e, 0x75, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x4e, 0x0a, 0x11, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, + 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x32, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x26, 0x0a, 0x0e, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x22, 0x23, 0x0a, 0x0b, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x49, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x25, 0x0a, 0x0d, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x22, 0x26, 0x0a, 0x0e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x55, 0x49, 0x6e, 0x74, + 0x33, 0x32, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x25, 0x0a, 0x0d, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0x26, 0x0a, 0x0e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x55, 0x49, 0x6e, 0x74, 0x36, + 0x34, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x24, 0x0a, 0x0c, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x42, 0x6f, 0x6f, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x28, 0x0a, + 0x10, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x4d, 0x6f, 0x64, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x9c, 0x02, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, + 0x0a, 0x0f, 0x52, 0x55, 0x4e, 0x5f, 0x50, 0x4f, 0x44, 0x5f, 0x53, 0x41, 0x4e, 0x44, 0x42, 0x4f, + 0x58, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x50, 0x4f, 0x44, 0x5f, + 0x53, 0x41, 0x4e, 0x44, 0x42, 0x4f, 0x58, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x45, 0x4d, + 0x4f, 0x56, 0x45, 0x5f, 0x50, 0x4f, 0x44, 0x5f, 0x53, 0x41, 0x4e, 0x44, 0x42, 0x4f, 0x58, 0x10, + 0x03, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x54, + 0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, 0x04, 0x12, 0x19, 0x0a, 0x15, 0x50, 0x4f, 0x53, 0x54, 0x5f, + 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, + 0x10, 0x05, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x54, + 0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, 0x06, 0x12, 0x18, 0x0a, 0x14, 0x50, 0x4f, 0x53, 0x54, 0x5f, + 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, + 0x07, 0x12, 0x14, 0x0a, 0x10, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x54, + 0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, 0x08, 0x12, 0x19, 0x0a, 0x15, 0x50, 0x4f, 0x53, 0x54, 0x5f, + 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, + 0x10, 0x09, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, + 0x49, 0x4e, 0x45, 0x52, 0x10, 0x0a, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, + 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x08, 0x0a, 0x04, + 0x4c, 0x41, 0x53, 0x54, 0x10, 0x0c, 0x2a, 0x82, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, + 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, + 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x43, 0x52, + 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4f, 0x4e, 0x54, 0x41, + 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x50, 0x41, 0x55, 0x53, 0x45, 0x44, 0x10, 0x02, 0x12, 0x15, 0x0a, + 0x11, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x52, 0x55, 0x4e, 0x4e, 0x49, + 0x4e, 0x47, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, + 0x52, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x10, 0x04, 0x32, 0xd8, 0x01, 0x0a, 0x07, + 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x5a, 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x2b, 0x2e, 0x6e, 0x72, 0x69, 0x2e, + 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x71, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, + 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xae, 0x05, 0x0a, 0x06, 0x50, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x12, 0x5c, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x12, 0x26, + 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x62, 0x0a, 0x0b, 0x53, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x65, 0x12, 0x28, + 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, + 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x53, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, + 0x1b, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x6e, + 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x6e, 0x0a, 0x0f, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x2c, 0x2e, 0x6e, + 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x6e, 0x72, 0x69, + 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x0f, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x2c, 0x2e, 0x6e, + 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x6e, 0x72, 0x69, + 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x0d, 0x53, 0x74, 0x6f, + 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x2a, 0x2e, 0x6e, 0x72, 0x69, + 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x74, + 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x12, 0x26, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x1b, 0x2e, 0x6e, 0x72, 0x69, + 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, + 0x2f, 0x6e, 0x72, 0x69, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x3b, 0x61, 0x70, 0x69, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pkg_api_api_proto_rawDescOnce sync.Once + file_pkg_api_api_proto_rawDescData = file_pkg_api_api_proto_rawDesc +) + +func file_pkg_api_api_proto_rawDescGZIP() []byte { + file_pkg_api_api_proto_rawDescOnce.Do(func() { + file_pkg_api_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_pkg_api_api_proto_rawDescData) + }) + return file_pkg_api_api_proto_rawDescData +} + +var file_pkg_api_api_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_pkg_api_api_proto_msgTypes = make([]protoimpl.MessageInfo, 49) +var file_pkg_api_api_proto_goTypes = []interface{}{ + (Event)(0), // 0: nri.pkg.api.v1alpha1.Event + (ContainerState)(0), // 1: nri.pkg.api.v1alpha1.ContainerState + (*RegisterPluginRequest)(nil), // 2: nri.pkg.api.v1alpha1.RegisterPluginRequest + (*UpdateContainersRequest)(nil), // 3: nri.pkg.api.v1alpha1.UpdateContainersRequest + (*UpdateContainersResponse)(nil), // 4: nri.pkg.api.v1alpha1.UpdateContainersResponse + (*ConfigureRequest)(nil), // 5: nri.pkg.api.v1alpha1.ConfigureRequest + (*ConfigureResponse)(nil), // 6: nri.pkg.api.v1alpha1.ConfigureResponse + (*SynchronizeRequest)(nil), // 7: nri.pkg.api.v1alpha1.SynchronizeRequest + (*SynchronizeResponse)(nil), // 8: nri.pkg.api.v1alpha1.SynchronizeResponse + (*CreateContainerRequest)(nil), // 9: nri.pkg.api.v1alpha1.CreateContainerRequest + (*CreateContainerResponse)(nil), // 10: nri.pkg.api.v1alpha1.CreateContainerResponse + (*UpdateContainerRequest)(nil), // 11: nri.pkg.api.v1alpha1.UpdateContainerRequest + (*UpdateContainerResponse)(nil), // 12: nri.pkg.api.v1alpha1.UpdateContainerResponse + (*StopContainerRequest)(nil), // 13: nri.pkg.api.v1alpha1.StopContainerRequest + (*StopContainerResponse)(nil), // 14: nri.pkg.api.v1alpha1.StopContainerResponse + (*StateChangeEvent)(nil), // 15: nri.pkg.api.v1alpha1.StateChangeEvent + (*Empty)(nil), // 16: nri.pkg.api.v1alpha1.Empty + (*PodSandbox)(nil), // 17: nri.pkg.api.v1alpha1.PodSandbox + (*LinuxPodSandbox)(nil), // 18: nri.pkg.api.v1alpha1.LinuxPodSandbox + (*Container)(nil), // 19: nri.pkg.api.v1alpha1.Container + (*Mount)(nil), // 20: nri.pkg.api.v1alpha1.Mount + (*Hooks)(nil), // 21: nri.pkg.api.v1alpha1.Hooks + (*Hook)(nil), // 22: nri.pkg.api.v1alpha1.Hook + (*LinuxContainer)(nil), // 23: nri.pkg.api.v1alpha1.LinuxContainer + (*LinuxNamespace)(nil), // 24: nri.pkg.api.v1alpha1.LinuxNamespace + (*LinuxDevice)(nil), // 25: nri.pkg.api.v1alpha1.LinuxDevice + (*LinuxDeviceCgroup)(nil), // 26: nri.pkg.api.v1alpha1.LinuxDeviceCgroup + (*LinuxResources)(nil), // 27: nri.pkg.api.v1alpha1.LinuxResources + (*LinuxMemory)(nil), // 28: nri.pkg.api.v1alpha1.LinuxMemory + (*LinuxCPU)(nil), // 29: nri.pkg.api.v1alpha1.LinuxCPU + (*HugepageLimit)(nil), // 30: nri.pkg.api.v1alpha1.HugepageLimit + (*ContainerAdjustment)(nil), // 31: nri.pkg.api.v1alpha1.ContainerAdjustment + (*LinuxContainerAdjustment)(nil), // 32: nri.pkg.api.v1alpha1.LinuxContainerAdjustment + (*ContainerUpdate)(nil), // 33: nri.pkg.api.v1alpha1.ContainerUpdate + (*LinuxContainerUpdate)(nil), // 34: nri.pkg.api.v1alpha1.LinuxContainerUpdate + (*ContainerEviction)(nil), // 35: nri.pkg.api.v1alpha1.ContainerEviction + (*KeyValue)(nil), // 36: nri.pkg.api.v1alpha1.KeyValue + (*OptionalString)(nil), // 37: nri.pkg.api.v1alpha1.OptionalString + (*OptionalInt)(nil), // 38: nri.pkg.api.v1alpha1.OptionalInt + (*OptionalInt32)(nil), // 39: nri.pkg.api.v1alpha1.OptionalInt32 + (*OptionalUInt32)(nil), // 40: nri.pkg.api.v1alpha1.OptionalUInt32 + (*OptionalInt64)(nil), // 41: nri.pkg.api.v1alpha1.OptionalInt64 + (*OptionalUInt64)(nil), // 42: nri.pkg.api.v1alpha1.OptionalUInt64 + (*OptionalBool)(nil), // 43: nri.pkg.api.v1alpha1.OptionalBool + (*OptionalFileMode)(nil), // 44: nri.pkg.api.v1alpha1.OptionalFileMode + nil, // 45: nri.pkg.api.v1alpha1.PodSandbox.LabelsEntry + nil, // 46: nri.pkg.api.v1alpha1.PodSandbox.AnnotationsEntry + nil, // 47: nri.pkg.api.v1alpha1.Container.LabelsEntry + nil, // 48: nri.pkg.api.v1alpha1.Container.AnnotationsEntry + nil, // 49: nri.pkg.api.v1alpha1.LinuxResources.UnifiedEntry + nil, // 50: nri.pkg.api.v1alpha1.ContainerAdjustment.AnnotationsEntry +} +var file_pkg_api_api_proto_depIdxs = []int32{ + 33, // 0: nri.pkg.api.v1alpha1.UpdateContainersRequest.update:type_name -> nri.pkg.api.v1alpha1.ContainerUpdate + 35, // 1: nri.pkg.api.v1alpha1.UpdateContainersRequest.evict:type_name -> nri.pkg.api.v1alpha1.ContainerEviction + 33, // 2: nri.pkg.api.v1alpha1.UpdateContainersResponse.failed:type_name -> nri.pkg.api.v1alpha1.ContainerUpdate + 17, // 3: nri.pkg.api.v1alpha1.SynchronizeRequest.pods:type_name -> nri.pkg.api.v1alpha1.PodSandbox + 19, // 4: nri.pkg.api.v1alpha1.SynchronizeRequest.containers:type_name -> nri.pkg.api.v1alpha1.Container + 33, // 5: nri.pkg.api.v1alpha1.SynchronizeResponse.update:type_name -> nri.pkg.api.v1alpha1.ContainerUpdate + 17, // 6: nri.pkg.api.v1alpha1.CreateContainerRequest.pod:type_name -> nri.pkg.api.v1alpha1.PodSandbox + 19, // 7: nri.pkg.api.v1alpha1.CreateContainerRequest.container:type_name -> nri.pkg.api.v1alpha1.Container + 31, // 8: nri.pkg.api.v1alpha1.CreateContainerResponse.adjust:type_name -> nri.pkg.api.v1alpha1.ContainerAdjustment + 33, // 9: nri.pkg.api.v1alpha1.CreateContainerResponse.update:type_name -> nri.pkg.api.v1alpha1.ContainerUpdate + 35, // 10: nri.pkg.api.v1alpha1.CreateContainerResponse.evict:type_name -> nri.pkg.api.v1alpha1.ContainerEviction + 17, // 11: nri.pkg.api.v1alpha1.UpdateContainerRequest.pod:type_name -> nri.pkg.api.v1alpha1.PodSandbox + 19, // 12: nri.pkg.api.v1alpha1.UpdateContainerRequest.container:type_name -> nri.pkg.api.v1alpha1.Container + 27, // 13: nri.pkg.api.v1alpha1.UpdateContainerRequest.linux_resources:type_name -> nri.pkg.api.v1alpha1.LinuxResources + 33, // 14: nri.pkg.api.v1alpha1.UpdateContainerResponse.update:type_name -> nri.pkg.api.v1alpha1.ContainerUpdate + 35, // 15: nri.pkg.api.v1alpha1.UpdateContainerResponse.evict:type_name -> nri.pkg.api.v1alpha1.ContainerEviction + 17, // 16: nri.pkg.api.v1alpha1.StopContainerRequest.pod:type_name -> nri.pkg.api.v1alpha1.PodSandbox + 19, // 17: nri.pkg.api.v1alpha1.StopContainerRequest.container:type_name -> nri.pkg.api.v1alpha1.Container + 33, // 18: nri.pkg.api.v1alpha1.StopContainerResponse.update:type_name -> nri.pkg.api.v1alpha1.ContainerUpdate + 0, // 19: nri.pkg.api.v1alpha1.StateChangeEvent.event:type_name -> nri.pkg.api.v1alpha1.Event + 17, // 20: nri.pkg.api.v1alpha1.StateChangeEvent.pod:type_name -> nri.pkg.api.v1alpha1.PodSandbox + 19, // 21: nri.pkg.api.v1alpha1.StateChangeEvent.container:type_name -> nri.pkg.api.v1alpha1.Container + 45, // 22: nri.pkg.api.v1alpha1.PodSandbox.labels:type_name -> nri.pkg.api.v1alpha1.PodSandbox.LabelsEntry + 46, // 23: nri.pkg.api.v1alpha1.PodSandbox.annotations:type_name -> nri.pkg.api.v1alpha1.PodSandbox.AnnotationsEntry + 18, // 24: nri.pkg.api.v1alpha1.PodSandbox.linux:type_name -> nri.pkg.api.v1alpha1.LinuxPodSandbox + 27, // 25: nri.pkg.api.v1alpha1.LinuxPodSandbox.pod_overhead:type_name -> nri.pkg.api.v1alpha1.LinuxResources + 27, // 26: nri.pkg.api.v1alpha1.LinuxPodSandbox.pod_resources:type_name -> nri.pkg.api.v1alpha1.LinuxResources + 24, // 27: nri.pkg.api.v1alpha1.LinuxPodSandbox.namespaces:type_name -> nri.pkg.api.v1alpha1.LinuxNamespace + 27, // 28: nri.pkg.api.v1alpha1.LinuxPodSandbox.resources:type_name -> nri.pkg.api.v1alpha1.LinuxResources + 1, // 29: nri.pkg.api.v1alpha1.Container.state:type_name -> nri.pkg.api.v1alpha1.ContainerState + 47, // 30: nri.pkg.api.v1alpha1.Container.labels:type_name -> nri.pkg.api.v1alpha1.Container.LabelsEntry + 48, // 31: nri.pkg.api.v1alpha1.Container.annotations:type_name -> nri.pkg.api.v1alpha1.Container.AnnotationsEntry + 20, // 32: nri.pkg.api.v1alpha1.Container.mounts:type_name -> nri.pkg.api.v1alpha1.Mount + 21, // 33: nri.pkg.api.v1alpha1.Container.hooks:type_name -> nri.pkg.api.v1alpha1.Hooks + 23, // 34: nri.pkg.api.v1alpha1.Container.linux:type_name -> nri.pkg.api.v1alpha1.LinuxContainer + 22, // 35: nri.pkg.api.v1alpha1.Hooks.prestart:type_name -> nri.pkg.api.v1alpha1.Hook + 22, // 36: nri.pkg.api.v1alpha1.Hooks.create_runtime:type_name -> nri.pkg.api.v1alpha1.Hook + 22, // 37: nri.pkg.api.v1alpha1.Hooks.create_container:type_name -> nri.pkg.api.v1alpha1.Hook + 22, // 38: nri.pkg.api.v1alpha1.Hooks.start_container:type_name -> nri.pkg.api.v1alpha1.Hook + 22, // 39: nri.pkg.api.v1alpha1.Hooks.poststart:type_name -> nri.pkg.api.v1alpha1.Hook + 22, // 40: nri.pkg.api.v1alpha1.Hooks.poststop:type_name -> nri.pkg.api.v1alpha1.Hook + 38, // 41: nri.pkg.api.v1alpha1.Hook.timeout:type_name -> nri.pkg.api.v1alpha1.OptionalInt + 24, // 42: nri.pkg.api.v1alpha1.LinuxContainer.namespaces:type_name -> nri.pkg.api.v1alpha1.LinuxNamespace + 25, // 43: nri.pkg.api.v1alpha1.LinuxContainer.devices:type_name -> nri.pkg.api.v1alpha1.LinuxDevice + 27, // 44: nri.pkg.api.v1alpha1.LinuxContainer.resources:type_name -> nri.pkg.api.v1alpha1.LinuxResources + 38, // 45: nri.pkg.api.v1alpha1.LinuxContainer.oom_score_adj:type_name -> nri.pkg.api.v1alpha1.OptionalInt + 44, // 46: nri.pkg.api.v1alpha1.LinuxDevice.file_mode:type_name -> nri.pkg.api.v1alpha1.OptionalFileMode + 40, // 47: nri.pkg.api.v1alpha1.LinuxDevice.uid:type_name -> nri.pkg.api.v1alpha1.OptionalUInt32 + 40, // 48: nri.pkg.api.v1alpha1.LinuxDevice.gid:type_name -> nri.pkg.api.v1alpha1.OptionalUInt32 + 41, // 49: nri.pkg.api.v1alpha1.LinuxDeviceCgroup.major:type_name -> nri.pkg.api.v1alpha1.OptionalInt64 + 41, // 50: nri.pkg.api.v1alpha1.LinuxDeviceCgroup.minor:type_name -> nri.pkg.api.v1alpha1.OptionalInt64 + 28, // 51: nri.pkg.api.v1alpha1.LinuxResources.memory:type_name -> nri.pkg.api.v1alpha1.LinuxMemory + 29, // 52: nri.pkg.api.v1alpha1.LinuxResources.cpu:type_name -> nri.pkg.api.v1alpha1.LinuxCPU + 30, // 53: nri.pkg.api.v1alpha1.LinuxResources.hugepage_limits:type_name -> nri.pkg.api.v1alpha1.HugepageLimit + 37, // 54: nri.pkg.api.v1alpha1.LinuxResources.blockio_class:type_name -> nri.pkg.api.v1alpha1.OptionalString + 37, // 55: nri.pkg.api.v1alpha1.LinuxResources.rdt_class:type_name -> nri.pkg.api.v1alpha1.OptionalString + 49, // 56: nri.pkg.api.v1alpha1.LinuxResources.unified:type_name -> nri.pkg.api.v1alpha1.LinuxResources.UnifiedEntry + 26, // 57: nri.pkg.api.v1alpha1.LinuxResources.devices:type_name -> nri.pkg.api.v1alpha1.LinuxDeviceCgroup + 41, // 58: nri.pkg.api.v1alpha1.LinuxMemory.limit:type_name -> nri.pkg.api.v1alpha1.OptionalInt64 + 41, // 59: nri.pkg.api.v1alpha1.LinuxMemory.reservation:type_name -> nri.pkg.api.v1alpha1.OptionalInt64 + 41, // 60: nri.pkg.api.v1alpha1.LinuxMemory.swap:type_name -> nri.pkg.api.v1alpha1.OptionalInt64 + 41, // 61: nri.pkg.api.v1alpha1.LinuxMemory.kernel:type_name -> nri.pkg.api.v1alpha1.OptionalInt64 + 41, // 62: nri.pkg.api.v1alpha1.LinuxMemory.kernel_tcp:type_name -> nri.pkg.api.v1alpha1.OptionalInt64 + 42, // 63: nri.pkg.api.v1alpha1.LinuxMemory.swappiness:type_name -> nri.pkg.api.v1alpha1.OptionalUInt64 + 43, // 64: nri.pkg.api.v1alpha1.LinuxMemory.disable_oom_killer:type_name -> nri.pkg.api.v1alpha1.OptionalBool + 43, // 65: nri.pkg.api.v1alpha1.LinuxMemory.use_hierarchy:type_name -> nri.pkg.api.v1alpha1.OptionalBool + 42, // 66: nri.pkg.api.v1alpha1.LinuxCPU.shares:type_name -> nri.pkg.api.v1alpha1.OptionalUInt64 + 41, // 67: nri.pkg.api.v1alpha1.LinuxCPU.quota:type_name -> nri.pkg.api.v1alpha1.OptionalInt64 + 42, // 68: nri.pkg.api.v1alpha1.LinuxCPU.period:type_name -> nri.pkg.api.v1alpha1.OptionalUInt64 + 41, // 69: nri.pkg.api.v1alpha1.LinuxCPU.realtime_runtime:type_name -> nri.pkg.api.v1alpha1.OptionalInt64 + 42, // 70: nri.pkg.api.v1alpha1.LinuxCPU.realtime_period:type_name -> nri.pkg.api.v1alpha1.OptionalUInt64 + 50, // 71: nri.pkg.api.v1alpha1.ContainerAdjustment.annotations:type_name -> nri.pkg.api.v1alpha1.ContainerAdjustment.AnnotationsEntry + 20, // 72: nri.pkg.api.v1alpha1.ContainerAdjustment.mounts:type_name -> nri.pkg.api.v1alpha1.Mount + 36, // 73: nri.pkg.api.v1alpha1.ContainerAdjustment.env:type_name -> nri.pkg.api.v1alpha1.KeyValue + 21, // 74: nri.pkg.api.v1alpha1.ContainerAdjustment.hooks:type_name -> nri.pkg.api.v1alpha1.Hooks + 32, // 75: nri.pkg.api.v1alpha1.ContainerAdjustment.linux:type_name -> nri.pkg.api.v1alpha1.LinuxContainerAdjustment + 25, // 76: nri.pkg.api.v1alpha1.LinuxContainerAdjustment.devices:type_name -> nri.pkg.api.v1alpha1.LinuxDevice + 27, // 77: nri.pkg.api.v1alpha1.LinuxContainerAdjustment.resources:type_name -> nri.pkg.api.v1alpha1.LinuxResources + 34, // 78: nri.pkg.api.v1alpha1.ContainerUpdate.linux:type_name -> nri.pkg.api.v1alpha1.LinuxContainerUpdate + 27, // 79: nri.pkg.api.v1alpha1.LinuxContainerUpdate.resources:type_name -> nri.pkg.api.v1alpha1.LinuxResources + 2, // 80: nri.pkg.api.v1alpha1.Runtime.RegisterPlugin:input_type -> nri.pkg.api.v1alpha1.RegisterPluginRequest + 3, // 81: nri.pkg.api.v1alpha1.Runtime.UpdateContainers:input_type -> nri.pkg.api.v1alpha1.UpdateContainersRequest + 5, // 82: nri.pkg.api.v1alpha1.Plugin.Configure:input_type -> nri.pkg.api.v1alpha1.ConfigureRequest + 7, // 83: nri.pkg.api.v1alpha1.Plugin.Synchronize:input_type -> nri.pkg.api.v1alpha1.SynchronizeRequest + 16, // 84: nri.pkg.api.v1alpha1.Plugin.Shutdown:input_type -> nri.pkg.api.v1alpha1.Empty + 9, // 85: nri.pkg.api.v1alpha1.Plugin.CreateContainer:input_type -> nri.pkg.api.v1alpha1.CreateContainerRequest + 11, // 86: nri.pkg.api.v1alpha1.Plugin.UpdateContainer:input_type -> nri.pkg.api.v1alpha1.UpdateContainerRequest + 13, // 87: nri.pkg.api.v1alpha1.Plugin.StopContainer:input_type -> nri.pkg.api.v1alpha1.StopContainerRequest + 15, // 88: nri.pkg.api.v1alpha1.Plugin.StateChange:input_type -> nri.pkg.api.v1alpha1.StateChangeEvent + 16, // 89: nri.pkg.api.v1alpha1.Runtime.RegisterPlugin:output_type -> nri.pkg.api.v1alpha1.Empty + 4, // 90: nri.pkg.api.v1alpha1.Runtime.UpdateContainers:output_type -> nri.pkg.api.v1alpha1.UpdateContainersResponse + 6, // 91: nri.pkg.api.v1alpha1.Plugin.Configure:output_type -> nri.pkg.api.v1alpha1.ConfigureResponse + 8, // 92: nri.pkg.api.v1alpha1.Plugin.Synchronize:output_type -> nri.pkg.api.v1alpha1.SynchronizeResponse + 16, // 93: nri.pkg.api.v1alpha1.Plugin.Shutdown:output_type -> nri.pkg.api.v1alpha1.Empty + 10, // 94: nri.pkg.api.v1alpha1.Plugin.CreateContainer:output_type -> nri.pkg.api.v1alpha1.CreateContainerResponse + 12, // 95: nri.pkg.api.v1alpha1.Plugin.UpdateContainer:output_type -> nri.pkg.api.v1alpha1.UpdateContainerResponse + 14, // 96: nri.pkg.api.v1alpha1.Plugin.StopContainer:output_type -> nri.pkg.api.v1alpha1.StopContainerResponse + 16, // 97: nri.pkg.api.v1alpha1.Plugin.StateChange:output_type -> nri.pkg.api.v1alpha1.Empty + 89, // [89:98] is the sub-list for method output_type + 80, // [80:89] is the sub-list for method input_type + 80, // [80:80] is the sub-list for extension type_name + 80, // [80:80] is the sub-list for extension extendee + 0, // [0:80] is the sub-list for field type_name +} + +func init() { file_pkg_api_api_proto_init() } +func file_pkg_api_api_proto_init() { + if File_pkg_api_api_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_pkg_api_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterPluginRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateContainersRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateContainersResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConfigureRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConfigureResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SynchronizeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SynchronizeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateContainerRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateContainerResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateContainerRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateContainerResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StopContainerRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StopContainerResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StateChangeEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Empty); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PodSandbox); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinuxPodSandbox); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Container); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Mount); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Hooks); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Hook); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinuxContainer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinuxNamespace); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinuxDevice); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinuxDeviceCgroup); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinuxResources); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinuxMemory); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinuxCPU); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HugepageLimit); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ContainerAdjustment); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinuxContainerAdjustment); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ContainerUpdate); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinuxContainerUpdate); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ContainerEviction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KeyValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OptionalString); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OptionalInt); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OptionalInt32); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OptionalUInt32); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OptionalInt64); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OptionalUInt64); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OptionalBool); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_api_api_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OptionalFileMode); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pkg_api_api_proto_rawDesc, + NumEnums: 2, + NumMessages: 49, + NumExtensions: 0, + NumServices: 2, + }, + GoTypes: file_pkg_api_api_proto_goTypes, + DependencyIndexes: file_pkg_api_api_proto_depIdxs, + EnumInfos: file_pkg_api_api_proto_enumTypes, + MessageInfos: file_pkg_api_api_proto_msgTypes, + }.Build() + File_pkg_api_api_proto = out.File + file_pkg_api_api_proto_rawDesc = nil + file_pkg_api_api_proto_goTypes = nil + file_pkg_api_api_proto_depIdxs = nil +} diff --git a/vendor/github.com/containerd/nri/pkg/api/api.proto b/vendor/github.com/containerd/nri/pkg/api/api.proto new file mode 100644 index 000000000..25ae8f87c --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/api.proto @@ -0,0 +1,441 @@ +/* + 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. +*/ + +syntax = "proto3"; + +package nri.pkg.api.v1alpha1; + +option go_package = "github.com/containerd/nri/pkg/api;api"; + +// Runtime service is the public API runtimes expose for NRI plugins. +// On this interface RPC requests are initiated by the plugin. This +// only covers plugin registration and unsolicited container updates. +// The rest of the API is defined by the Plugin service. +service Runtime { + // RegisterPlugin registers the plugin with the runtime. + rpc RegisterPlugin(RegisterPluginRequest) returns (Empty); + // UpdateContainers requests unsolicited updates to a set of containers. + rpc UpdateContainers(UpdateContainersRequest) returns (UpdateContainersResponse); +} + +message RegisterPluginRequest { + // Name of the plugin to register. + string plugin_name = 1; + // Plugin invocation index. Plugins are called in ascending index order. + string plugin_idx = 2; +} + +message UpdateContainersRequest { + // List of containers to update. + repeated ContainerUpdate update = 1; + // List of containers to evict. + repeated ContainerEviction evict = 2; +} + +message UpdateContainersResponse { + // Containers that the runtime failed to udpate. + repeated ContainerUpdate failed = 1; +} + + +// +// Plugin is the API NRI uses to interact with plugins. It is used to +// - configure a plugin and subscribe it for lifecycle events +// - synchronize the state of a plugin with that of the runtime +// - hook a plugin into the lifecycle events of its interest +// +// During configuration the plugin tells the runtime which lifecycle events +// it wishes to get hooked into. Once configured, the plugin is synchronized +// with the runtime by receiving the list of pods and containers known to +// the runtime. The plugin can request changes to any of the containers in +// response. After initial synchronization the plugin starts receiving the +// events it subscribed for as they occur in the runtime. For container +// creation, update, and stop events, the plugin can request changes, both +// to the container that triggered the event or any other existing container +// in the runtime. +// +// For a subset of the container lifecycle events, NRI defines an additional +// Post-variant of the event. These variants are defined for CreateContainer, +// StartContainer, and UpdateContainer. For creation and update, these events +// can be used by plugins to discover the full extent of changes applied to +// the container, including any changes made by other active plugins. +// +service Plugin { + // Configure the plugin and get its event subscription. + rpc Configure(ConfigureRequest) returns (ConfigureResponse); + + // Synchronize the plugin with the state of the runtime. + rpc Synchronize(SynchronizeRequest) returns (SynchronizeResponse); + + // Shutdown a plugin (let it know the runtime is going down). + rpc Shutdown(Empty) returns (Empty); + + // CreateContainer relays the corresponding request to the plugin. In + // response, the plugin can adjust the container being created, and + // update other containers in the runtime. Container adjustment can + // alter labels, annotations, mounts, devices, environment variables, + // OCI hooks, and assigned container resources. Updates can alter + // assigned container resources. + rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse); + + // UpdateContainer relays the corresponding request to the plugin. + // The plugin can alter how the container is updated and request updates + // to additional containers in the runtime. + rpc UpdateContainer(UpdateContainerRequest) returns (UpdateContainerResponse); + + // StopContainer relays the corresponding request to the plugin. The plugin + // can update any of the remaining containers in the runtime in response. + rpc StopContainer(StopContainerRequest) returns (StopContainerResponse); + + // StateChange relays any remaining pod or container lifecycle/state change + // events the plugin has subscribed for. These can be used to trigger any + // plugin-specific processing which needs to occur in connection with any of + // these events. + rpc StateChange(StateChangeEvent) returns (Empty); +} + +message ConfigureRequest { + // Any plugin-specific data, if present among the NRI configuration. + string config = 1; + // Name of the runtime NRI is running in. + string runtime_name = 2; + // Version of the runtime NRI is running in. + string runtime_version = 3; +} + +message ConfigureResponse { + // Events to subscribe the plugin for. Each bit set corresponds to an + // enumerated Event. + int32 events = 2; +} + +message SynchronizeRequest { + // Pods known to the runtime. + repeated PodSandbox pods = 1; + // Containers known to the runtime. + repeated Container containers = 2; +} + +message SynchronizeResponse { + // Updates to containers requested by the plugin. + repeated ContainerUpdate update = 1; +} + +message CreateContainerRequest { + // Pod of container being created. + PodSandbox pod = 1; + // Container being created. + Container container = 2; +} + +message CreateContainerResponse { + // Requested adjustments to container being created. + ContainerAdjustment adjust = 1; + // Requested updates to other existing containers. + repeated ContainerUpdate update = 2; + // Requested eviction of existing containers. + repeated ContainerEviction evict = 3; +} + +message UpdateContainerRequest { + // Pod of container being updated. + PodSandbox pod = 1; + // Container being updated. + Container container = 2; + // Resources to update. + LinuxResources linux_resources = 3; +} + +message UpdateContainerResponse { + // Requested updates to containers. + repeated ContainerUpdate update = 1; + // Requested eviction of containers. + repeated ContainerEviction evict = 2; +} + +message StopContainerRequest { + // Pod of container being stopped. + PodSandbox pod = 1; + // Container being stopped. + Container container = 2; +} + +message StopContainerResponse { + // Requested updates to containers. + repeated ContainerUpdate update = 1; +} + +message StateChangeEvent { + // Event type of notification. + Event event = 1; + // Pod this notification is sent for. If this event is related to a container, + // pod is set to the pod of the container. + PodSandbox pod = 2; + // Container this notification is sent for. If the event is related to a pod, + // container is nil. + Container container = 3; +} + +// Empty response for those *Requests that are semantically events. +message Empty {} + +// Events that plugins can subscribe to in ConfigureResponse. +enum Event { + UNKNOWN = 0; + RUN_POD_SANDBOX = 1; + STOP_POD_SANDBOX = 2; + REMOVE_POD_SANDBOX = 3; + CREATE_CONTAINER = 4; + POST_CREATE_CONTAINER = 5; + START_CONTAINER = 6; + POST_START_CONTAINER = 7; + UPDATE_CONTAINER = 8; + POST_UPDATE_CONTAINER = 9; + STOP_CONTAINER = 10; + REMOVE_CONTAINER = 11; + LAST = 12; +} + +// Pod metadata that is considered relevant for a plugin. +message PodSandbox { + string id = 1; + string name = 2; + string uid = 3; + string namespace = 4; + map labels = 5; + map annotations = 6; + string runtime_handler = 7; + LinuxPodSandbox linux = 8; + uint32 pid = 9; // for NRI v1 emulation +} + +// PodSandbox linux-specific metadata +message LinuxPodSandbox { + LinuxResources pod_overhead = 1; + LinuxResources pod_resources = 2; + string cgroup_parent = 3; + string cgroups_path = 4; // for NRI v1 emulation + repeated LinuxNamespace namespaces = 5; // for NRI v1 emulation + LinuxResources resources = 6; // for NRI v1 emulation +} + +// Container metadata that is considered relevant for a plugin. +message Container { + string id = 1; + string pod_sandbox_id = 2; + string name = 3; + ContainerState state = 4; + map labels = 5; + map annotations = 6; + repeated string args = 7; + repeated string env = 8; + repeated Mount mounts = 9; + Hooks hooks = 10; + LinuxContainer linux = 11; + uint32 pid = 12; // for NRI v1 emulation +} + +// Possible container states. +enum ContainerState { + CONTAINER_UNKNOWN = 0; + CONTAINER_CREATED = 1; + CONTAINER_PAUSED = 2; // is this useful/necessary ? + CONTAINER_RUNNING = 3; + CONTAINER_STOPPED = 4; +} + +// A container mount. +message Mount { + string destination = 1; + string type = 2; + string source = 3; + repeated string options = 4; +} + +// Container OCI hooks. +message Hooks { + repeated Hook prestart = 1; + repeated Hook create_runtime = 2; + repeated Hook create_container = 3; + repeated Hook start_container = 4; + repeated Hook poststart = 5; + repeated Hook poststop = 6; +} + +// One OCI hook. +message Hook { + string path = 1; + repeated string args = 2; + repeated string env = 3; + OptionalInt timeout = 4; +} + +// Container (linux) metadata. +message LinuxContainer { + repeated LinuxNamespace namespaces = 1; + repeated LinuxDevice devices = 2; + LinuxResources resources = 3; + OptionalInt oom_score_adj = 4; + string cgroups_path = 5; +} + +// A linux namespace. +message LinuxNamespace { + string type = 1; + string path = 2; +} + +// A container (linux) device. +message LinuxDevice { + string path = 1; + string type = 2; + int64 major = 3; + int64 minor = 4; + OptionalFileMode file_mode = 5; + OptionalUInt32 uid = 6; + OptionalUInt32 gid = 7; +} + +// A linux device cgroup controller rule. +message LinuxDeviceCgroup { + bool allow = 1; + string type = 2; + OptionalInt64 major = 3; + OptionalInt64 minor = 4; + string access = 5; +} + +// Container (linux) resources. +message LinuxResources { + LinuxMemory memory = 1; + LinuxCPU cpu = 2; + repeated HugepageLimit hugepage_limits = 3; + OptionalString blockio_class = 4; + OptionalString rdt_class = 5; + map unified = 6; + repeated LinuxDeviceCgroup devices = 7; // for NRI v1 emulation +} + +// Memory-related parts of (linux) resources. +message LinuxMemory { + OptionalInt64 limit = 1; + OptionalInt64 reservation = 2; + OptionalInt64 swap = 3; + OptionalInt64 kernel = 4; + OptionalInt64 kernel_tcp = 5; + OptionalUInt64 swappiness = 6; + OptionalBool disable_oom_killer = 7; + OptionalBool use_hierarchy = 8; +} + +// CPU-related parts of (linux) resources. +message LinuxCPU { + OptionalUInt64 shares = 1; + OptionalInt64 quota = 2; + OptionalUInt64 period = 3; + OptionalInt64 realtime_runtime = 4; + OptionalUInt64 realtime_period = 5; + string cpus = 6; + string mems = 7; +} + +// Container huge page limit. +message HugepageLimit { + string page_size = 1; + uint64 limit = 2; +} + +// Requested adjustments to a container being created. +message ContainerAdjustment { + map annotations = 2; + repeated Mount mounts = 3; + repeated KeyValue env = 4; + Hooks hooks = 5; + LinuxContainerAdjustment linux = 6; +} + +// Adjustments to (linux) resources. +message LinuxContainerAdjustment { + repeated LinuxDevice devices = 1; + LinuxResources resources = 2; + string cgroups_path = 3; +} + +// Requested update to an already created container. +message ContainerUpdate { + string container_id = 1; + LinuxContainerUpdate linux = 2; + bool ignore_failure = 3; +} + +// Updates to (linux) resources. +message LinuxContainerUpdate { + LinuxResources resources = 1; +} + +// Request to evict (IOW unsolicitedly stop) a container. +message ContainerEviction { + // Container to evict. + string container_id = 1; + // Human-readable reason for eviction. + string reason = 2; +} + +// KeyValue represents an environment variable. +message KeyValue { + string key = 1; + string value = 2; +} + +// An optional string value. +message OptionalString { + string value = 1; +} + +// An optional signed integer value. +message OptionalInt { + int64 value = 1; +} + +// An optional 32-bit signed integer value. +message OptionalInt32 { + int32 value = 1; +} + +// An optional 32-bit unsigned integer value. +message OptionalUInt32 { + uint32 value = 1; +} + +// An optional 64-bit signed integer value. +message OptionalInt64 { + int64 value = 1; +} + +// An optional 64-bit unsigned integer value. +message OptionalUInt64 { + uint64 value = 1; +} + +// An optional boolean value. +message OptionalBool { + bool value = 1; +} + +// An optional value of file permissions. +message OptionalFileMode { + uint32 value = 1; +} diff --git a/vendor/github.com/containerd/nri/pkg/api/api_ttrpc.pb.go b/vendor/github.com/containerd/nri/pkg/api/api_ttrpc.pb.go new file mode 100644 index 000000000..e6737454e --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/api_ttrpc.pb.go @@ -0,0 +1,179 @@ +// Code generated by protoc-gen-go-ttrpc. DO NOT EDIT. +// source: pkg/api/api.proto +package api + +import ( + context "context" + ttrpc "github.com/containerd/ttrpc" +) + +type RuntimeService interface { + RegisterPlugin(ctx context.Context, req *RegisterPluginRequest) (*Empty, error) + UpdateContainers(ctx context.Context, req *UpdateContainersRequest) (*UpdateContainersResponse, error) +} + +func RegisterRuntimeService(srv *ttrpc.Server, svc RuntimeService) { + srv.Register("nri.pkg.api.v1alpha1.Runtime", map[string]ttrpc.Method{ + "RegisterPlugin": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req RegisterPluginRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.RegisterPlugin(ctx, &req) + }, + "UpdateContainers": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req UpdateContainersRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.UpdateContainers(ctx, &req) + }, + }) +} + +type runtimeClient struct { + client *ttrpc.Client +} + +func NewRuntimeClient(client *ttrpc.Client) RuntimeService { + return &runtimeClient{ + client: client, + } +} +func (c *runtimeClient) RegisterPlugin(ctx context.Context, req *RegisterPluginRequest) (*Empty, error) { + var resp Empty + if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Runtime", "RegisterPlugin", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} +func (c *runtimeClient) UpdateContainers(ctx context.Context, req *UpdateContainersRequest) (*UpdateContainersResponse, error) { + var resp UpdateContainersResponse + if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Runtime", "UpdateContainers", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} + +type PluginService interface { + Configure(ctx context.Context, req *ConfigureRequest) (*ConfigureResponse, error) + Synchronize(ctx context.Context, req *SynchronizeRequest) (*SynchronizeResponse, error) + Shutdown(ctx context.Context, req *Empty) (*Empty, error) + CreateContainer(ctx context.Context, req *CreateContainerRequest) (*CreateContainerResponse, error) + UpdateContainer(ctx context.Context, req *UpdateContainerRequest) (*UpdateContainerResponse, error) + StopContainer(ctx context.Context, req *StopContainerRequest) (*StopContainerResponse, error) + StateChange(ctx context.Context, req *StateChangeEvent) (*Empty, error) +} + +func RegisterPluginService(srv *ttrpc.Server, svc PluginService) { + srv.Register("nri.pkg.api.v1alpha1.Plugin", map[string]ttrpc.Method{ + "Configure": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req ConfigureRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.Configure(ctx, &req) + }, + "Synchronize": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req SynchronizeRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.Synchronize(ctx, &req) + }, + "Shutdown": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req Empty + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.Shutdown(ctx, &req) + }, + "CreateContainer": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req CreateContainerRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.CreateContainer(ctx, &req) + }, + "UpdateContainer": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req UpdateContainerRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.UpdateContainer(ctx, &req) + }, + "StopContainer": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req StopContainerRequest + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.StopContainer(ctx, &req) + }, + "StateChange": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { + var req StateChangeEvent + if err := unmarshal(&req); err != nil { + return nil, err + } + return svc.StateChange(ctx, &req) + }, + }) +} + +type pluginClient struct { + client *ttrpc.Client +} + +func NewPluginClient(client *ttrpc.Client) PluginService { + return &pluginClient{ + client: client, + } +} +func (c *pluginClient) Configure(ctx context.Context, req *ConfigureRequest) (*ConfigureResponse, error) { + var resp ConfigureResponse + if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "Configure", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} +func (c *pluginClient) Synchronize(ctx context.Context, req *SynchronizeRequest) (*SynchronizeResponse, error) { + var resp SynchronizeResponse + if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "Synchronize", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} +func (c *pluginClient) Shutdown(ctx context.Context, req *Empty) (*Empty, error) { + var resp Empty + if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "Shutdown", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} +func (c *pluginClient) CreateContainer(ctx context.Context, req *CreateContainerRequest) (*CreateContainerResponse, error) { + var resp CreateContainerResponse + if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "CreateContainer", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} +func (c *pluginClient) UpdateContainer(ctx context.Context, req *UpdateContainerRequest) (*UpdateContainerResponse, error) { + var resp UpdateContainerResponse + if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "UpdateContainer", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} +func (c *pluginClient) StopContainer(ctx context.Context, req *StopContainerRequest) (*StopContainerResponse, error) { + var resp StopContainerResponse + if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "StopContainer", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} +func (c *pluginClient) StateChange(ctx context.Context, req *StateChangeEvent) (*Empty, error) { + var resp Empty + if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "StateChange", req, &resp); err != nil { + return nil, err + } + return &resp, nil +} diff --git a/vendor/github.com/containerd/nri/pkg/api/device.go b/vendor/github.com/containerd/nri/pkg/api/device.go new file mode 100644 index 000000000..c7307b169 --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/device.go @@ -0,0 +1,89 @@ +/* + 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 api + +import ( + rspec "github.com/opencontainers/runtime-spec/specs-go" +) + +// FromOCILinuxDevices returns a device slice from an OCI runtime Spec. +func FromOCILinuxDevices(o []rspec.LinuxDevice) []*LinuxDevice { + var devices []*LinuxDevice + for _, d := range o { + devices = append(devices, &LinuxDevice{ + Path: d.Path, + Type: d.Type, + Major: d.Major, + Minor: d.Minor, + FileMode: FileMode(d.FileMode), + Uid: UInt32(d.UID), + Gid: UInt32(d.GID), + }) + } + return devices +} + +// ToOCI returns the linux devices for an OCI runtime Spec. +func (d *LinuxDevice) ToOCI() rspec.LinuxDevice { + if d == nil { + return rspec.LinuxDevice{} + } + + return rspec.LinuxDevice{ + Path: d.Path, + Type: d.Type, + Major: d.Major, + Minor: d.Minor, + FileMode: d.FileMode.Get(), + UID: d.Uid.Get(), + GID: d.Gid.Get(), + } +} + +// AccessString returns an OCI access string for the device. +func (d *LinuxDevice) AccessString() string { + r, w, m := "r", "w", "" + + if mode := d.FileMode.Get(); mode != nil { + perm := mode.Perm() + if (perm & 0444) != 0 { + r = "r" + } + if (perm & 0222) != 0 { + w = "w" + } + } + if d.Type == "b" { + m = "m" + } + + return r + w + m +} + +// Cmp returns true if the devices are equal. +func (d *LinuxDevice) Cmp(v *LinuxDevice) bool { + if v == nil { + return false + } + return d.Major != v.Major || d.Minor != v.Minor +} + +// IsMarkedForRemoval checks if a LinuxDevice is marked for removal. +func (d *LinuxDevice) IsMarkedForRemoval() (string, bool) { + key, marked := IsMarkedForRemoval(d.Path) + return key, marked +} diff --git a/vendor/github.com/containerd/nri/pkg/api/doc.go b/vendor/github.com/containerd/nri/pkg/api/doc.go new file mode 100644 index 000000000..2413d025e --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/doc.go @@ -0,0 +1,17 @@ +/* + 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 api diff --git a/vendor/github.com/containerd/nri/pkg/api/env.go b/vendor/github.com/containerd/nri/pkg/api/env.go new file mode 100644 index 000000000..0f6e711de --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/env.go @@ -0,0 +1,60 @@ +/* + 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 api + +import ( + "strings" +) + +// ToOCI returns an OCI Env entry for the KeyValue. +func (e *KeyValue) ToOCI() string { + return e.Key + "=" + e.Value +} + +// FromOCIEnv returns KeyValues from an OCI runtime Spec environment. +func FromOCIEnv(in []string) []*KeyValue { + if in == nil { + return nil + } + out := []*KeyValue{} + for _, keyval := range in { + var key, val string + split := strings.SplitN(keyval, "=", 2) + switch len(split) { + case 0: + continue + case 1: + key = split[0] + case 2: + key = split[0] + val = split[1] + default: + val = strings.Join(split[1:], "=") + } + out = append(out, &KeyValue{ + Key: key, + Value: val, + }) + } + return out +} + +// IsMarkedForRemoval checks if an environment variable is marked for removal. +func (e *KeyValue) IsMarkedForRemoval() (string, bool) { + key, marked := IsMarkedForRemoval(e.Key) + return key, marked +} diff --git a/vendor/github.com/containerd/nri/pkg/api/event.go b/vendor/github.com/containerd/nri/pkg/api/event.go new file mode 100644 index 000000000..50909f635 --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/event.go @@ -0,0 +1,172 @@ +/* + 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 api + +import ( + "fmt" + "strings" +) + +const ( + // ValidEvents is the event mask of all valid events. + ValidEvents = EventMask((1 << (Event_LAST - 1)) - 1) +) + +// nolint +type ( + // Define *Request/*Response type aliases for *Event/Empty pairs. + + StateChangeResponse = Empty + RunPodSandboxRequest = StateChangeEvent + RunPodSandboxResponse = Empty + StopPodSandboxRequest = StateChangeEvent + StopPodSandboxResponse = Empty + RemovePodSandboxRequest = StateChangeEvent + RemovePodSandboxResponse = Empty + StartContainerRequest = StateChangeEvent + StartContainerResponse = Empty + RemoveContainerRequest = StateChangeEvent + RemoveContainerResponse = Empty + PostCreateContainerRequest = StateChangeEvent + PostCreateContainerResponse = Empty + PostStartContainerRequest = StateChangeEvent + PostStartContainerResponse = Empty + PostUpdateContainerRequest = StateChangeEvent + PostUpdateContainerResponse = Empty + + ShutdownRequest = Empty + ShutdownResponse = Empty +) + +// EventMask corresponds to a set of enumerated Events. +type EventMask int32 + +// ParseEventMask parses a string representation into an EventMask. +func ParseEventMask(events ...string) (EventMask, error) { + var mask EventMask + + bits := map[string]Event{ + "runpodsandbox": Event_RUN_POD_SANDBOX, + "stoppodsandbox": Event_STOP_POD_SANDBOX, + "removepodsandbox": Event_REMOVE_POD_SANDBOX, + "createcontainer": Event_CREATE_CONTAINER, + "postcreatecontainer": Event_POST_CREATE_CONTAINER, + "startcontainer": Event_START_CONTAINER, + "poststartcontainer": Event_POST_START_CONTAINER, + "updatecontainer": Event_UPDATE_CONTAINER, + "postupdatecontainer": Event_POST_UPDATE_CONTAINER, + "stopcontainer": Event_STOP_CONTAINER, + "removecontainer": Event_REMOVE_CONTAINER, + } + + for _, event := range events { + lcEvents := strings.ToLower(event) + for _, name := range strings.Split(lcEvents, ",") { + switch name { + case "all": + mask |= ValidEvents + continue + case "pod", "podsandbox": + for name, bit := range bits { + if strings.Contains(name, "Pod") { + mask.Set(bit) + } + } + continue + case "container": + for name, bit := range bits { + if strings.Contains(name, "Container") { + mask.Set(bit) + } + } + continue + } + + bit, ok := bits[strings.TrimSpace(name)] + if !ok { + return 0, fmt.Errorf("unknown event %q", name) + } + mask.Set(bit) + } + } + + return mask, nil +} + +// MustParseEventMask parses the given events, panic()ing on errors. +func MustParseEventMask(events ...string) EventMask { + mask, err := ParseEventMask(events...) + if err != nil { + panic(fmt.Sprintf("failed to parse events %s", strings.Join(events, " "))) + } + return mask +} + +// PrettyString returns a human-readable string representation of an EventMask. +func (m *EventMask) PrettyString() string { + names := map[Event]string{ + Event_RUN_POD_SANDBOX: "RunPodSandbox", + Event_STOP_POD_SANDBOX: "StopPodSandbox", + Event_REMOVE_POD_SANDBOX: "RemovePodSandbox", + Event_CREATE_CONTAINER: "CreateContainer", + Event_POST_CREATE_CONTAINER: "PostCreateContainer", + Event_START_CONTAINER: "StartContainer", + Event_POST_START_CONTAINER: "PostStartContainer", + Event_UPDATE_CONTAINER: "UpdateContainer", + Event_POST_UPDATE_CONTAINER: "PostUpdateContainer", + Event_STOP_CONTAINER: "StopContainer", + Event_REMOVE_CONTAINER: "RemoveContainer", + } + + mask := *m + events, sep := "", "" + + for bit := Event_UNKNOWN + 1; bit <= Event_LAST; bit++ { + if mask.IsSet(bit) { + events += sep + names[bit] + sep = "," + mask.Clear(bit) + } + } + + if mask != 0 { + events += sep + fmt.Sprintf("unknown(0x%x)", mask) + } + + return events +} + +// Set sets the given Events in the mask. +func (m *EventMask) Set(events ...Event) *EventMask { + for _, e := range events { + *m |= (1 << (e - 1)) + } + return m +} + +// Clear clears the given Events in the mask. +func (m *EventMask) Clear(events ...Event) *EventMask { + for _, e := range events { + *m &^= (1 << (e - 1)) + } + return m +} + +// IsSet check if the given Event is set in the mask. +func (m *EventMask) IsSet(e Event) bool { + return *m&(1<<(e-1)) != 0 +} diff --git a/vendor/github.com/containerd/nri/pkg/api/helpers.go b/vendor/github.com/containerd/nri/pkg/api/helpers.go new file mode 100644 index 000000000..c72127031 --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/helpers.go @@ -0,0 +1,59 @@ +/* + 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 api + +// DupStringSlice creates a copy of a string slice. +func DupStringSlice(in []string) []string { + if in == nil { + return nil + } + out := make([]string, len(in)) + copy(out, in) + return out +} + +// DupStringMap creates a copy of a map with string keys and values. +func DupStringMap(in map[string]string) map[string]string { + if in == nil { + return nil + } + out := map[string]string{} + for k, v := range in { + out[k] = v + } + return out +} + +// IsMarkedForRemoval checks if a key is marked for removal. +// +// The key can be an annotation name, a mount container path, a device path, +// or an environment variable name. These are all marked for removal in +// adjustments by preceding their corresponding key with a '-'. +func IsMarkedForRemoval(key string) (string, bool) { + if key == "" { + return "", false + } + if key[0] != '-' { + return key, false + } + return key[1:], true +} + +// MarkForRemoval returns a key marked for removal. +func MarkForRemoval(key string) string { + return "-" + key +} diff --git a/vendor/github.com/containerd/nri/pkg/api/hooks.go b/vendor/github.com/containerd/nri/pkg/api/hooks.go new file mode 100644 index 000000000..47dd96ea7 --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/hooks.go @@ -0,0 +1,103 @@ +/* + 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 api + +import ( + rspec "github.com/opencontainers/runtime-spec/specs-go" +) + +// Append appends the given hooks to the existing ones. +func (hooks *Hooks) Append(h *Hooks) *Hooks { + if h == nil { + return hooks + } + hooks.Prestart = append(hooks.Prestart, h.Prestart...) + hooks.CreateRuntime = append(hooks.CreateRuntime, h.CreateRuntime...) + hooks.CreateContainer = append(hooks.CreateContainer, h.CreateContainer...) + hooks.StartContainer = append(hooks.StartContainer, h.StartContainer...) + hooks.Poststart = append(hooks.Poststart, h.Poststart...) + hooks.Poststop = append(hooks.Poststop, h.Poststop...) + + return hooks +} + +// Hooks returns itself it any of its hooks is set. Otherwise it returns nil. +func (hooks *Hooks) Hooks() *Hooks { + if hooks == nil { + return nil + } + + if len(hooks.Prestart) > 0 { + return hooks + } + if len(hooks.CreateRuntime) > 0 { + return hooks + } + if len(hooks.CreateContainer) > 0 { + return hooks + } + if len(hooks.StartContainer) > 0 { + return hooks + } + if len(hooks.Poststart) > 0 { + return hooks + } + if len(hooks.Poststop) > 0 { + return hooks + } + + return nil +} + +// ToOCI returns the hook for an OCI runtime Spec. +func (h *Hook) ToOCI() rspec.Hook { + return rspec.Hook{ + Path: h.Path, + Args: DupStringSlice(h.Args), + Env: DupStringSlice(h.Env), + Timeout: h.Timeout.Get(), + } +} + +// FromOCIHooks returns hooks from an OCI runtime Spec. +func FromOCIHooks(o *rspec.Hooks) *Hooks { + if o == nil { + return nil + } + return &Hooks{ + Prestart: FromOCIHookSlice(o.Prestart), + CreateRuntime: FromOCIHookSlice(o.CreateRuntime), + CreateContainer: FromOCIHookSlice(o.CreateContainer), + StartContainer: FromOCIHookSlice(o.StartContainer), + Poststart: FromOCIHookSlice(o.Poststart), + Poststop: FromOCIHookSlice(o.Poststop), + } +} + +// FromOCIHookSlice returns a hook slice from an OCI runtime Spec. +func FromOCIHookSlice(o []rspec.Hook) []*Hook { + var hooks []*Hook + for _, h := range o { + hooks = append(hooks, &Hook{ + Path: h.Path, + Args: DupStringSlice(h.Args), + Env: DupStringSlice(h.Env), + Timeout: Int(h.Timeout), + }) + } + return hooks +} diff --git a/vendor/github.com/containerd/nri/pkg/api/mount.go b/vendor/github.com/containerd/nri/pkg/api/mount.go new file mode 100644 index 000000000..63fd6956a --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/mount.go @@ -0,0 +1,89 @@ +/* + 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 api + +import ( + "sort" + + rspec "github.com/opencontainers/runtime-spec/specs-go" +) + +const ( + // SELinuxRelabel is a Mount pseudo-option to request relabeling. + SELinuxRelabel = "relabel" +) + +// FromOCIMounts returns a Mount slice for an OCI runtime Spec. +func FromOCIMounts(o []rspec.Mount) []*Mount { + var mounts []*Mount + for _, m := range o { + mounts = append(mounts, &Mount{ + Destination: m.Destination, + Type: m.Type, + Source: m.Source, + Options: DupStringSlice(m.Options), + }) + } + return mounts +} + +// ToOCI returns a Mount for an OCI runtime Spec. +func (m *Mount) ToOCI(propagationQuery *string) rspec.Mount { + o := rspec.Mount{ + Destination: m.Destination, + Type: m.Type, + Source: m.Source, + Options: []string{}, + } + for _, opt := range m.Options { + o.Options = append(o.Options, opt) + if propagationQuery != nil && (opt == "rprivate" || opt == "rshared" || opt == "rslave") { + *propagationQuery = opt + } + } + return o +} + +// Cmp returns true if the mounts are equal. +func (m *Mount) Cmp(v *Mount) bool { + if v == nil { + return false + } + if m.Destination != v.Destination || m.Type != v.Type || m.Source != v.Source || + len(m.Options) != len(v.Options) { + return false + } + + mOpts := make([]string, len(m.Options)) + vOpts := make([]string, len(m.Options)) + sort.Strings(mOpts) + sort.Strings(vOpts) + + for i, o := range mOpts { + if vOpts[i] != o { + return false + } + } + + return true +} + +// IsMarkedForRemoval checks if a Mount is marked for removal. +func (m *Mount) IsMarkedForRemoval() (string, bool) { + key, marked := IsMarkedForRemoval(m.Destination) + return key, marked +} diff --git a/vendor/github.com/containerd/nri/pkg/api/namespace.go b/vendor/github.com/containerd/nri/pkg/api/namespace.go new file mode 100644 index 000000000..201106d33 --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/namespace.go @@ -0,0 +1,33 @@ +/* + 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 api + +import ( + rspec "github.com/opencontainers/runtime-spec/specs-go" +) + +// FromOCILinuxNamespaces returns a namespace slice from an OCI runtime Spec. +func FromOCILinuxNamespaces(o []rspec.LinuxNamespace) []*LinuxNamespace { + var namespaces []*LinuxNamespace + for _, ns := range o { + namespaces = append(namespaces, &LinuxNamespace{ + Type: string(ns.Type), + Path: ns.Path, + }) + } + return namespaces +} diff --git a/vendor/github.com/containerd/nri/pkg/api/optional.go b/vendor/github.com/containerd/nri/pkg/api/optional.go new file mode 100644 index 000000000..c8020f45f --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/optional.go @@ -0,0 +1,341 @@ +/* + 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 api + +import ( + "os" +) + +// +// XXX FIXME: +// +// The optional interface constructor should be updated/split up +// to avoid having to take an interface{} argument. Instead The +// optional types should have a +// - constructor taking the underlying native type +// - a Copy() function for copying them +// - a FromPointer constructor to create them from an optionally nil +// pointer to the underlying native type (to help constructing from +// structures that use a pointer to the native underlying type to +// denote optionality (OCI Spec mostly)) +// Creating from any other type should use one of these with any explicit +// cast for the argument as necessary. +// + +// String creates an Optional wrapper from its argument. +func String(v interface{}) *OptionalString { + var value string + + switch o := v.(type) { + case string: + value = o + case *string: + if o == nil { + return nil + } + value = *o + case *OptionalString: + if o == nil { + return nil + } + value = o.Value + default: + return nil + } + + return &OptionalString{ + Value: value, + } +} + +// Get returns nil if its value is unset or a pointer to the value itself. +func (o *OptionalString) Get() *string { + if o == nil { + return nil + } + v := o.Value + return &v +} + +// Int creates an Optional wrapper from its argument. +func Int(v interface{}) *OptionalInt { + var value int64 + + switch o := v.(type) { + case int: + value = int64(o) + case *int: + if o == nil { + return nil + } + value = int64(*o) + case *OptionalInt: + if o == nil { + return nil + } + value = o.Value + default: + return nil + } + + return &OptionalInt{ + Value: value, + } +} + +// Get returns nil if its value is unset or a pointer to the value itself. +func (o *OptionalInt) Get() *int { + if o == nil { + return nil + } + v := int(o.Value) + return &v +} + +// Int32 creates an Optional wrapper from its argument. +func Int32(v interface{}) *OptionalInt32 { + var value int32 + + switch o := v.(type) { + case int32: + value = o + case *int32: + if o == nil { + return nil + } + value = *o + case *OptionalInt32: + if o == nil { + return nil + } + value = o.Value + default: + return nil + } + + return &OptionalInt32{ + Value: value, + } +} + +// Get returns nil if its value is unset or a pointer to the value itself. +func (o *OptionalInt32) Get() *int32 { + if o == nil { + return nil + } + v := o.Value + return &v +} + +// UInt32 creates an Optional wrapper from its argument. +func UInt32(v interface{}) *OptionalUInt32 { + var value uint32 + + switch o := v.(type) { + case uint32: + value = o + case *uint32: + if o == nil { + return nil + } + value = *o + case *OptionalUInt32: + if o == nil { + return nil + } + value = o.Value + default: + return nil + } + + return &OptionalUInt32{ + Value: value, + } +} + +// Get returns nil if its value is unset or a pointer to the value itself. +func (o *OptionalUInt32) Get() *uint32 { + if o == nil { + return nil + } + v := o.Value + return &v +} + +// Int64 creates an Optional wrapper from its argument. +func Int64(v interface{}) *OptionalInt64 { + var value int64 + + switch o := v.(type) { + case int: + value = int64(o) + case uint: + value = int64(o) + case uint64: + value = int64(o) + case int64: + value = o + case *int64: + if o == nil { + return nil + } + value = *o + case *uint64: + if o == nil { + return nil + } + value = int64(*o) + case *OptionalInt64: + if o == nil { + return nil + } + value = o.Value + default: + return nil + } + + return &OptionalInt64{ + Value: value, + } +} + +// Get returns nil if its value is unset or a pointer to the value itself. +func (o *OptionalInt64) Get() *int64 { + if o == nil { + return nil + } + v := o.Value + return &v +} + +// UInt64 creates an Optional wrapper from its argument. +func UInt64(v interface{}) *OptionalUInt64 { + var value uint64 + + switch o := v.(type) { + case int: + value = uint64(o) + case uint: + value = uint64(o) + case int64: + value = uint64(o) + case uint64: + value = o + case *int64: + if o == nil { + return nil + } + value = uint64(*o) + case *uint64: + if o == nil { + return nil + } + value = *o + case *OptionalUInt64: + if o == nil { + return nil + } + value = o.Value + default: + return nil + } + + return &OptionalUInt64{ + Value: value, + } +} + +// Get returns nil if its value is unset or a pointer to the value itself. +func (o *OptionalUInt64) Get() *uint64 { + if o == nil { + return nil + } + v := o.Value + return &v +} + +// Bool creates an Optional wrapper from its argument. +func Bool(v interface{}) *OptionalBool { + var value bool + + switch o := v.(type) { + case bool: + value = o + case *bool: + if o == nil { + return nil + } + value = *o + case *OptionalBool: + if o == nil { + return nil + } + value = o.Value + default: + return nil + } + + return &OptionalBool{ + Value: value, + } +} + +// Get returns nil if its value is unset or a pointer to the value itself. +func (o *OptionalBool) Get() *bool { + if o == nil { + return nil + } + v := o.Value + return &v +} + +// FileMode creates an Optional wrapper from its argument. +func FileMode(v interface{}) *OptionalFileMode { + var value os.FileMode + + switch o := v.(type) { + case *os.FileMode: + if o == nil { + return nil + } + value = *o + case os.FileMode: + value = o + case *OptionalFileMode: + if o == nil { + return nil + } + value = os.FileMode(o.Value) + case uint32: + value = os.FileMode(o) + default: + return nil + } + + return &OptionalFileMode{ + Value: uint32(value), + } +} + +// Get returns nil if its value is unset or a pointer to the value itself. +func (o *OptionalFileMode) Get() *os.FileMode { + if o == nil { + return nil + } + v := os.FileMode(o.Value) + return &v +} diff --git a/vendor/github.com/containerd/nri/pkg/api/plugin.go b/vendor/github.com/containerd/nri/pkg/api/plugin.go new file mode 100644 index 000000000..16aab20dc --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/plugin.go @@ -0,0 +1,58 @@ +/* + 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 api + +import ( + "fmt" + "strings" +) + +const ( + // DefaultSocketPath is the default socket path for external plugins. + DefaultSocketPath = "/var/run/nri.sock" + // PluginSocketEnvVar is used to inform plugins about pre-connected sockets. + PluginSocketEnvVar = "NRI_PLUGIN_SOCKET" + // PluginNameEnvVar is used to inform NRI-launched plugins about their name. + PluginNameEnvVar = "NRI_PLUGIN_NAME" + // PluginIdxEnvVar is used to inform NRI-launched plugins about their ID. + PluginIdxEnvVar = "NRI_PLUGIN_IDX" +) + +// ParsePluginName parses the (file)name of a plugin into an index and a base. +func ParsePluginName(name string) (string, string, error) { + split := strings.SplitN(name, "-", 2) + if len(split) < 2 { + return "", "", fmt.Errorf("invalid plugin name %q, idx-pluginname expected", name) + } + + if err := CheckPluginIndex(split[0]); err != nil { + return "", "", err + } + + return split[0], split[1], nil +} + +// CheckPluginIndex checks the validity of a plugin index. +func CheckPluginIndex(idx string) error { + if len(idx) != 2 { + return fmt.Errorf("invalid plugin index %q, must be 2 digits", idx) + } + if !('0' <= idx[0] && idx[0] <= '9') || !('0' <= idx[1] && idx[1] <= '9') { + return fmt.Errorf("invalid plugin index %q (not [0-9][0-9])", idx) + } + return nil +} diff --git a/vendor/github.com/containerd/nri/pkg/api/resources.go b/vendor/github.com/containerd/nri/pkg/api/resources.go new file mode 100644 index 000000000..1aa9cb0d0 --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/resources.go @@ -0,0 +1,230 @@ +/* + 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 api + +import ( + rspec "github.com/opencontainers/runtime-spec/specs-go" + cri "k8s.io/cri-api/pkg/apis/runtime/v1" +) + +// FromOCILinuxResources returns resources from an OCI runtime Spec. +func FromOCILinuxResources(o *rspec.LinuxResources, ann map[string]string) *LinuxResources { + if o == nil { + return nil + } + l := &LinuxResources{} + if m := o.Memory; m != nil { + l.Memory = &LinuxMemory{ + Limit: Int64(m.Limit), + Reservation: Int64(m.Reservation), + Swap: Int64(m.Swap), + Kernel: Int64(m.Kernel), + KernelTcp: Int64(m.KernelTCP), + Swappiness: UInt64(m.Swappiness), + DisableOomKiller: Bool(m.DisableOOMKiller), + UseHierarchy: Bool(m.UseHierarchy), + } + } + if c := o.CPU; c != nil { + l.Cpu = &LinuxCPU{ + Shares: UInt64(c.Shares), + Quota: Int64(c.Quota), + Period: UInt64(c.Period), + RealtimeRuntime: Int64(c.RealtimeRuntime), + RealtimePeriod: UInt64(c.RealtimePeriod), + Cpus: c.Cpus, + Mems: c.Mems, + } + } + for _, h := range o.HugepageLimits { + l.HugepageLimits = append(l.HugepageLimits, &HugepageLimit{ + PageSize: h.Pagesize, + Limit: h.Limit, + }) + } + for _, d := range o.Devices { + l.Devices = append(l.Devices, &LinuxDeviceCgroup{ + Allow: d.Allow, + Type: d.Type, + Major: Int64(d.Major), + Minor: Int64(d.Minor), + Access: d.Access, + }) + } + return l +} + +func FromCRILinuxResources(c *cri.LinuxContainerResources) *LinuxResources { + if c == nil { + return nil + } + shares, quota, period := uint64(c.CpuShares), c.CpuQuota, uint64(c.CpuPeriod) + r := &LinuxResources{ + Cpu: &LinuxCPU{ + Shares: UInt64(&shares), + Quota: Int64("a), + Period: UInt64(&period), + Cpus: c.CpusetCpus, + Mems: c.CpusetMems, + }, + Memory: &LinuxMemory{ + Limit: Int64(&c.MemoryLimitInBytes), + }, + } + for _, l := range c.HugepageLimits { + r.HugepageLimits = append(r.HugepageLimits, + &HugepageLimit{ + PageSize: l.PageSize, + Limit: l.Limit, + }) + } + return r +} + +// ToOCI returns resources for an OCI runtime Spec. +func (r *LinuxResources) ToOCI() *rspec.LinuxResources { + if r == nil { + return nil + } + o := &rspec.LinuxResources{} + if r.Memory != nil { + o.Memory = &rspec.LinuxMemory{ + Limit: r.Memory.Limit.Get(), + Reservation: r.Memory.Reservation.Get(), + Swap: r.Memory.Swap.Get(), + Kernel: r.Memory.Kernel.Get(), + KernelTCP: r.Memory.KernelTcp.Get(), + Swappiness: r.Memory.Swappiness.Get(), + DisableOOMKiller: r.Memory.DisableOomKiller.Get(), + UseHierarchy: r.Memory.UseHierarchy.Get(), + } + } + if r.Cpu != nil { + o.CPU = &rspec.LinuxCPU{ + Shares: r.Cpu.Shares.Get(), + Quota: r.Cpu.Quota.Get(), + Period: r.Cpu.Period.Get(), + RealtimeRuntime: r.Cpu.RealtimeRuntime.Get(), + RealtimePeriod: r.Cpu.RealtimePeriod.Get(), + Cpus: r.Cpu.Cpus, + Mems: r.Cpu.Mems, + } + } + for _, l := range r.HugepageLimits { + o.HugepageLimits = append(o.HugepageLimits, rspec.LinuxHugepageLimit{ + Pagesize: l.PageSize, + Limit: l.Limit, + }) + } + if len(r.Unified) != 0 { + o.Unified = make(map[string]string) + for k, v := range r.Unified { + o.Unified[k] = v + } + } + for _, d := range r.Devices { + o.Devices = append(o.Devices, rspec.LinuxDeviceCgroup{ + Allow: d.Allow, + Type: d.Type, + Major: d.Major.Get(), + Minor: d.Minor.Get(), + Access: d.Access, + }) + } + + return o +} + +// ToCRI returns resources for CRI. +func (r *LinuxResources) ToCRI(oomScoreAdj int64) *cri.LinuxContainerResources { + if r == nil { + return nil + } + o := &cri.LinuxContainerResources{} + if r.Memory != nil { + o.MemoryLimitInBytes = r.Memory.GetLimit().GetValue() + o.OomScoreAdj = oomScoreAdj + } + if r.Cpu != nil { + o.CpuShares = int64(r.Cpu.GetShares().GetValue()) + o.CpuPeriod = int64(r.Cpu.GetPeriod().GetValue()) + o.CpuQuota = r.Cpu.GetQuota().GetValue() + o.CpusetCpus = r.Cpu.Cpus + o.CpusetMems = r.Cpu.Mems + } + for _, l := range r.HugepageLimits { + o.HugepageLimits = append(o.HugepageLimits, &cri.HugepageLimit{ + PageSize: l.PageSize, + Limit: l.Limit, + }) + } + if len(r.Unified) != 0 { + o.Unified = make(map[string]string) + for k, v := range r.Unified { + o.Unified[k] = v + } + } + + return o +} + +// Copy creates a copy of the resources. +func (r *LinuxResources) Copy() *LinuxResources { + if r == nil { + return nil + } + o := &LinuxResources{} + if r.Memory != nil { + o.Memory = &LinuxMemory{ + Limit: Int64(r.Memory.GetLimit()), + Reservation: Int64(r.Memory.GetReservation()), + Swap: Int64(r.Memory.GetSwap()), + Kernel: Int64(r.Memory.GetKernel()), + KernelTcp: Int64(r.Memory.GetKernelTcp()), + Swappiness: UInt64(r.Memory.GetSwappiness()), + DisableOomKiller: Bool(r.Memory.GetDisableOomKiller()), + UseHierarchy: Bool(r.Memory.GetUseHierarchy()), + } + } + if r.Cpu != nil { + o.Cpu = &LinuxCPU{ + Shares: UInt64(r.Cpu.GetShares()), + Quota: Int64(r.Cpu.GetQuota()), + Period: UInt64(r.Cpu.GetPeriod()), + RealtimeRuntime: Int64(r.Cpu.GetRealtimeRuntime()), + RealtimePeriod: UInt64(r.Cpu.GetRealtimePeriod()), + Cpus: r.Cpu.GetCpus(), + Mems: r.Cpu.GetMems(), + } + } + for _, l := range r.HugepageLimits { + o.HugepageLimits = append(o.HugepageLimits, &HugepageLimit{ + PageSize: l.PageSize, + Limit: l.Limit, + }) + } + if len(r.Unified) != 0 { + o.Unified = make(map[string]string) + for k, v := range r.Unified { + o.Unified[k] = v + } + } + o.BlockioClass = String(r.BlockioClass) + o.RdtClass = String(r.RdtClass) + + return o +} diff --git a/vendor/github.com/containerd/nri/pkg/api/update.go b/vendor/github.com/containerd/nri/pkg/api/update.go new file mode 100644 index 000000000..9bfe1bf7d --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/api/update.go @@ -0,0 +1,186 @@ +/* + 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 api + +//nolint +// SetContainerId sets the id of the container to update. +func (u *ContainerUpdate) SetContainerId(id string) { + u.ContainerId = id +} + +// SetLinuxMemoryLimit records setting the memory limit for a container. +func (u *ContainerUpdate) SetLinuxMemoryLimit(value int64) { + u.initLinuxResourcesMemory() + u.Linux.Resources.Memory.Limit = Int64(value) +} + +// SetLinuxMemoryReservation records setting the memory reservation for a container. +func (u *ContainerUpdate) SetLinuxMemoryReservation(value int64) { + u.initLinuxResourcesMemory() + u.Linux.Resources.Memory.Reservation = Int64(value) +} + +// SetLinuxMemorySwap records records setting the memory swap limit for a container. +func (u *ContainerUpdate) SetLinuxMemorySwap(value int64) { + u.initLinuxResourcesMemory() + u.Linux.Resources.Memory.Swap = Int64(value) +} + +// SetLinuxMemoryKernel records setting the memory kernel limit for a container. +func (u *ContainerUpdate) SetLinuxMemoryKernel(value int64) { + u.initLinuxResourcesMemory() + u.Linux.Resources.Memory.Kernel = Int64(value) +} + +// SetLinuxMemoryKernelTCP records setting the memory kernel TCP limit for a container. +func (u *ContainerUpdate) SetLinuxMemoryKernelTCP(value int64) { + u.initLinuxResourcesMemory() + u.Linux.Resources.Memory.KernelTcp = Int64(value) +} + +// SetLinuxMemorySwappiness records setting the memory swappiness for a container. +func (u *ContainerUpdate) SetLinuxMemorySwappiness(value uint64) { + u.initLinuxResourcesMemory() + u.Linux.Resources.Memory.Swappiness = UInt64(value) +} + +// SetLinuxMemoryDisableOomKiller records disabling the OOM killer for a container. +func (u *ContainerUpdate) SetLinuxMemoryDisableOomKiller() { + u.initLinuxResourcesMemory() + u.Linux.Resources.Memory.DisableOomKiller = Bool(true) +} + +// SetLinuxMemoryUseHierarchy records enabling hierarchical memory accounting for a container. +func (u *ContainerUpdate) SetLinuxMemoryUseHierarchy() { + u.initLinuxResourcesMemory() + u.Linux.Resources.Memory.UseHierarchy = Bool(true) +} + +// SetLinuxCPUShares records setting the scheduler's CPU shares for a container. +func (u *ContainerUpdate) SetLinuxCPUShares(value uint64) { + u.initLinuxResourcesCPU() + u.Linux.Resources.Cpu.Shares = UInt64(value) +} + +// SetLinuxCPUQuota records setting the scheduler's CPU quota for a container. +func (u *ContainerUpdate) SetLinuxCPUQuota(value int64) { + u.initLinuxResourcesCPU() + u.Linux.Resources.Cpu.Quota = Int64(value) +} + +// SetLinuxCPUPeriod records setting the scheduler's CPU period for a container. +func (u *ContainerUpdate) SetLinuxCPUPeriod(value int64) { + u.initLinuxResourcesCPU() + u.Linux.Resources.Cpu.Period = UInt64(value) +} + +// SetLinuxCPURealtimeRuntime records setting the scheduler's realtime runtime for a container. +func (u *ContainerUpdate) SetLinuxCPURealtimeRuntime(value int64) { + u.initLinuxResourcesCPU() + u.Linux.Resources.Cpu.RealtimeRuntime = Int64(value) +} + +// SetLinuxCPURealtimePeriod records setting the scheduler's realtime period for a container. +func (u *ContainerUpdate) SetLinuxCPURealtimePeriod(value uint64) { + u.initLinuxResourcesCPU() + u.Linux.Resources.Cpu.RealtimePeriod = UInt64(value) +} + +// SetLinuxCPUSetCPUs records setting the cpuset CPUs for a container. +func (u *ContainerUpdate) SetLinuxCPUSetCPUs(value string) { + u.initLinuxResourcesCPU() + u.Linux.Resources.Cpu.Cpus = value +} + +// SetLinuxCPUSetMems records setting the cpuset memory for a container. +func (u *ContainerUpdate) SetLinuxCPUSetMems(value string) { + u.initLinuxResourcesCPU() + u.Linux.Resources.Cpu.Mems = value +} + +// AddLinuxHugepageLimit records adding a hugepage limit for a container. +func (u *ContainerUpdate) AddLinuxHugepageLimit(pageSize string, value uint64) { + u.initLinuxResources() + u.Linux.Resources.HugepageLimits = append(u.Linux.Resources.HugepageLimits, + &HugepageLimit{ + PageSize: pageSize, + Limit: value, + }) +} + +// SetLinuxBlockIOClass records setting the Block I/O class for a container. +func (u *ContainerUpdate) SetLinuxBlockIOClass(value string) { + u.initLinuxResources() + u.Linux.Resources.BlockioClass = String(value) +} + +// SetLinuxRDTClass records setting the RDT class for a container. +func (u *ContainerUpdate) SetLinuxRDTClass(value string) { + u.initLinuxResources() + u.Linux.Resources.RdtClass = String(value) +} + +// AddLinuxUnified sets a cgroupv2 unified resource. +func (u *ContainerUpdate) AddLinuxUnified(key, value string) { + u.initLinuxResourcesUnified() + u.Linux.Resources.Unified[key] = value +} + +// SetIgnoreFailure marks an Update as ignored for failures. +// Such updates will not prevent the related container operation +// from succeeding if the update fails. +func (u *ContainerUpdate) SetIgnoreFailure() { + u.IgnoreFailure = true +} + +// +// Initializing a container update. +// + +func (u *ContainerUpdate) initLinux() { + if u.Linux == nil { + u.Linux = &LinuxContainerUpdate{} + } +} + +func (u *ContainerUpdate) initLinuxResources() { + u.initLinux() + if u.Linux.Resources == nil { + u.Linux.Resources = &LinuxResources{} + } +} + +func (u *ContainerUpdate) initLinuxResourcesMemory() { + u.initLinuxResources() + if u.Linux.Resources.Memory == nil { + u.Linux.Resources.Memory = &LinuxMemory{} + } +} + +func (u *ContainerUpdate) initLinuxResourcesCPU() { + u.initLinuxResources() + if u.Linux.Resources.Cpu == nil { + u.Linux.Resources.Cpu = &LinuxCPU{} + } +} + +func (u *ContainerUpdate) initLinuxResourcesUnified() { + u.initLinuxResources() + if u.Linux.Resources.Unified == nil { + u.Linux.Resources.Unified = make(map[string]string) + } +} diff --git a/vendor/github.com/containerd/nri/pkg/log/log.go b/vendor/github.com/containerd/nri/pkg/log/log.go new file mode 100644 index 000000000..91337b59e --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/log/log.go @@ -0,0 +1,87 @@ +/* + 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 log + +import ( + "context" + + "github.com/sirupsen/logrus" +) + +var ( + log Logger = &fallbackLogger{} +) + +// Logger is the interface NRI uses for logging. +type Logger interface { + Debugf(ctx context.Context, format string, args ...interface{}) + Infof(ctx context.Context, format string, args ...interface{}) + Warnf(ctx context.Context, format string, args ...interface{}) + Errorf(ctx context.Context, format string, args ...interface{}) +} + +// Set the logger used by NRI. +func Set(l Logger) { + log = l +} + +// Get the logger used by NRI. +func Get() Logger { + return log +} + +// Debugf logs a formatted debug message. +func Debugf(ctx context.Context, format string, args ...interface{}) { + log.Debugf(ctx, format, args...) +} + +// Infof logs a formatted informational message. +func Infof(ctx context.Context, format string, args ...interface{}) { + log.Infof(ctx, format, args...) +} + +// Warnf logs a formatted warning message. +func Warnf(ctx context.Context, format string, args ...interface{}) { + log.Warnf(ctx, format, args...) +} + +// Errorf logs a formatted error message. +func Errorf(ctx context.Context, format string, args ...interface{}) { + log.Errorf(ctx, format, args...) +} + +type fallbackLogger struct{} + +// Debugf logs a formatted debug message. +func (f *fallbackLogger) Debugf(ctx context.Context, format string, args ...interface{}) { + logrus.WithContext(ctx).Debugf(format, args...) +} + +// Infof logs a formatted informational message. +func (f *fallbackLogger) Infof(ctx context.Context, format string, args ...interface{}) { + logrus.WithContext(ctx).Infof(format, args...) +} + +// Warnf logs a formatted warning message. +func (f *fallbackLogger) Warnf(ctx context.Context, format string, args ...interface{}) { + logrus.WithContext(ctx).Warnf(format, args...) +} + +// Errorf logs a formatted error message. +func (f *fallbackLogger) Errorf(ctx context.Context, format string, args ...interface{}) { + logrus.WithContext(ctx).Errorf(format, args...) +} diff --git a/vendor/github.com/containerd/nri/pkg/net/conn.go b/vendor/github.com/containerd/nri/pkg/net/conn.go new file mode 100644 index 000000000..db7d2bc62 --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/net/conn.go @@ -0,0 +1,93 @@ +/* + 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 net + +import ( + "fmt" + "io" + "net" + "os" + "strconv" + "sync" +) + +// NewFdConn creates a net.Conn for the given (socket) fd. +func NewFdConn(fd int) (net.Conn, error) { + f := os.NewFile(uintptr(fd), "fd #"+strconv.Itoa(fd)) + + conn, err := net.FileConn(f) + if err != nil { + return nil, fmt.Errorf("failed to create net.Conn for fd #%d: %w", fd, err) + } + f.Close() + + return conn, nil +} + +// connListener wraps a pre-connected socket in a net.Listener. +type connListener struct { + next chan net.Conn + conn net.Conn + addr net.Addr + lock sync.RWMutex // for Close() + closed bool +} + +// NewConnListener wraps an existing net.Conn in a net.Listener. +// +// The first call to Accept() on the listener will return the wrapped +// connection. Subsequent calls to Accept() block until the listener +// is closed, then return io.EOF. Close() closes the listener and the +// wrapped connection. +func NewConnListener(conn net.Conn) net.Listener { + next := make(chan net.Conn, 1) + next <- conn + + return &connListener{ + next: next, + conn: conn, + addr: conn.LocalAddr(), + } +} + +// Accept returns the wrapped connection when it is called the first +// time. Later calls to Accept block until the listener is closed, then +// return io.EOF. +func (l *connListener) Accept() (net.Conn, error) { + conn := <-l.next + if conn == nil { + return nil, io.EOF + } + return conn, nil +} + +// Close closes the listener and the wrapped connection. +func (l *connListener) Close() error { + l.lock.Lock() + defer l.lock.Unlock() + if l.closed { + return nil + } + close(l.next) + l.closed = true + return l.conn.Close() +} + +// Addr returns the local address of the wrapped connection. +func (l *connListener) Addr() net.Addr { + return l.addr +} diff --git a/vendor/github.com/containerd/nri/pkg/net/multiplex/mux.go b/vendor/github.com/containerd/nri/pkg/net/multiplex/mux.go new file mode 100644 index 000000000..fcce69f04 --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/net/multiplex/mux.go @@ -0,0 +1,444 @@ +/* + 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 multiplex + +import ( + "encoding/binary" + "errors" + "fmt" + "io" + "net" + "sync" + "syscall" + "time" + + nrinet "github.com/containerd/nri/pkg/net" + "github.com/containerd/ttrpc" +) + +// Mux multiplexes several logical connections over a single net.Conn. +// +// Connections are identified within a Mux by ConnIDs which are simple +// 32-bit unsigned integers. Opening a connection returns a net.Conn +// corrponding to the ConnID. This can then be used to write and read +// data through the connection with the Mux performing multiplexing +// and demultiplexing of data. +// +// Writing to a connection is fully synchronous. The caller can safely +// reuse the buffer once the call returns. Reading from a connection +// returns the oldest demultiplexed buffer for the connection, blocking +// if the connections incoming queue is empty. If any incoming queue is +// ever overflown the underlying trunk and all multiplexed connections +// are closed and an error is recorded. This error is later returned by +// any subsequent read from any connection. All connections of the Mux +// have the same fixed incoming queue length which can be configured +// using the WithReadQueueLength Option during Mux creation. +// +// The Mux interface also provides functions that emulate net.Dial and +// net.Listen for a connection. Usually these can be used for passing +// multiplexed connections to packages that insist to Dial or Accept +// themselves for connection establishment. +// +// Note that opening a connection is a virtual operation in the sense +// that it has no effects outside the Mux. It is performed without any +// signalling or other communication. It merely acquires the net.Conn +// corresponding to the connection and blindly assumes that the same +// ConnID is or will be opened at the other end of the Mux. +type Mux interface { + // Open the connection for the given ConnID. + Open(ConnID) (net.Conn, error) + + // Close the Mux and all connections associated with it. + Close() error + + // Dialer returns a net.Dial-like function for the connection. + // + // Calling the returned function (with arguments) will return a + // net.Conn for the connection. + Dialer(ConnID) func(string, string) (net.Conn, error) + + // Listener returns a net.Listener for the connection. The first + // call to Accept() on the listener will return a net.Conn for the + // connection. Subsequent calls to Accept() will block until the + // connection is closed then return io.EOF. + Listen(ConnID) (net.Listener, error) + + // Trunk returns the trunk connection for the Mux. + Trunk() net.Conn + + // Unblock unblocks the Mux reader. + Unblock() +} + +// ConnID uniquely identifies a logical connection within a Mux. +type ConnID uint32 + +const ( + // ConnID 0 is reserved for future use. + reservedConnID ConnID = iota + // LowestConnID is the lowest externally usable ConnID. + LowestConnID +) + +// Option to apply to a Mux. +type Option func(*mux) + +// WithBlockedRead causes the Mux to be blocked for reading until gets Unblock()'ed. +func WithBlockedRead() Option { + return func(m *mux) { + if m.blockC == nil { + m.blockC = make(chan struct{}) + } + } +} + +// WithReadQueueLength overrides the default read queue size. +func WithReadQueueLength(length int) Option { + return func(m *mux) { + m.qlen = length + } +} + +// Multiplex returns a multiplexer for the given connection. +func Multiplex(trunk net.Conn, options ...Option) Mux { + return newMux(trunk, options...) +} + +// mux is our implementation of Mux. +type mux struct { + trunk net.Conn + writeLock sync.Mutex + conns map[ConnID]*conn + connLock sync.RWMutex + qlen int + errOnce sync.Once + err error + unblkOnce sync.Once + blockC chan struct{} + closeOnce sync.Once + doneC chan struct{} +} + +const ( + // default read queue length for a single connection + readQueueLen = 256 + // length of frame header: 4-byte ConnID, 4-byte payload length + headerLen = 8 + // max. allowed payload size + maxPayloadSize = 1 << 24 +) + +// conn represents a single multiplexed connection. +type conn struct { + id ConnID + mux *mux + readC chan []byte + closeOnce sync.Once + doneC chan error +} + +func newMux(trunk net.Conn, options ...Option) *mux { + m := &mux{ + trunk: trunk, + conns: make(map[ConnID]*conn), + qlen: readQueueLen, + doneC: make(chan struct{}), + } + + for _, o := range options { + o(m) + } + + if m.blockC == nil { + WithBlockedRead()(m) + m.Unblock() + } + + go m.reader() + + return m +} + +func (m *mux) Trunk() net.Conn { + return m.trunk +} + +func (m *mux) Unblock() { + m.unblkOnce.Do(func() { + close(m.blockC) + }) +} + +func (m *mux) Open(id ConnID) (net.Conn, error) { + if id == reservedConnID { + return nil, fmt.Errorf("ConnID %d is reserved", id) + } + + m.connLock.Lock() + defer m.connLock.Unlock() + + c, ok := m.conns[id] + if !ok { + c = &conn{ + id: id, + mux: m, + doneC: make(chan error, 1), + readC: make(chan []byte, m.qlen), + } + m.conns[id] = c + } + + return c, nil +} + +func (m *mux) Close() error { + m.closeOnce.Do(func() { + m.connLock.Lock() + defer m.connLock.Unlock() + for _, conn := range m.conns { + conn.close() + } + close(m.doneC) + m.trunk.Close() + }) + + return nil +} + +func (m *mux) Dialer(id ConnID) func(string, string) (net.Conn, error) { + return func(string, string) (net.Conn, error) { + return m.Open(id) + } +} + +func (m *mux) Listen(id ConnID) (net.Listener, error) { + conn, err := m.Open(id) + if err != nil { + return nil, err + } + return nrinet.NewConnListener(conn), nil +} + +func (m *mux) write(id ConnID, buf []byte) (int, error) { + var hdr [headerLen]byte + + if len(buf) > maxPayloadSize { + return 0, syscall.EMSGSIZE + } + + binary.BigEndian.PutUint32(hdr[0:4], uint32(id)) + binary.BigEndian.PutUint32(hdr[4:8], uint32(len(buf))) + + m.writeLock.Lock() + defer m.writeLock.Unlock() + + n, err := m.trunk.Write(hdr[:]) + if err != nil { + err = fmt.Errorf("failed to write header to trunk: %w", err) + if n != 0 { + m.setError(err) + m.Close() + } + return 0, err + } + + n, err = m.trunk.Write(buf) + if err != nil { + err = fmt.Errorf("failed to write payload to trunk: %w", err) + if n != 0 { + m.setError(err) + m.Close() + } + } + + return n, err +} + +func (m *mux) reader() { + var ( + hdr [headerLen]byte + cid uint32 + cnt uint32 + buf []byte + err error + ) + + <-m.blockC + + for { + select { + case <-m.doneC: + return + default: + } + + _, err = io.ReadFull(m.trunk, hdr[:]) + if err != nil { + switch { + case errors.Is(err, io.EOF): + case errors.Is(err, ttrpc.ErrClosed): + err = io.EOF + case errors.Is(err, ttrpc.ErrServerClosed): + err = io.EOF + case errors.Is(err, net.ErrClosed): + err = io.EOF + default: + err = fmt.Errorf("failed to read header from trunk: %w", err) + } + m.setError(err) + m.Close() + return + } + + cid = binary.BigEndian.Uint32(hdr[0:4]) + cnt = binary.BigEndian.Uint32(hdr[4:8]) + buf = make([]byte, int(cnt)) + + _, err = io.ReadFull(m.trunk, buf) + if err != nil { + switch { + case errors.Is(err, io.EOF): + case errors.Is(err, ttrpc.ErrClosed): + err = io.EOF + case errors.Is(err, ttrpc.ErrServerClosed): + err = io.EOF + case errors.Is(err, net.ErrClosed): + err = io.EOF + default: + err = fmt.Errorf("failed to read payload from trunk: %w", err) + } + m.setError(err) + m.Close() + return + } + + m.connLock.RLock() + conn, ok := m.conns[ConnID(cid)] + m.connLock.RUnlock() + if ok { + select { + case conn.readC <- buf: + default: + m.setError(errors.New("failed to queue payload for reading")) + m.Close() + return + } + } + } +} + +func (m *mux) setError(err error) { + m.errOnce.Do(func() { + m.err = err + }) +} + +// nolint +func (m *mux) error() error { + m.errOnce.Do(func() { + if m.err == nil { + m.err = io.EOF + } + }) + return m.err +} + +// +// multiplexed connections +// + +// Reads reads the next message from the multiplexed connection. +func (c *conn) Read(buf []byte) (int, error) { + var ( + msg []byte + err error + ok bool + ) + + select { + case err, ok = <-c.doneC: + if !ok || err == nil { + err = c.mux.error() + } + return 0, err + case msg, ok = <-c.readC: + if !ok { + return 0, c.mux.error() + } + if cap(buf) < len(msg) { + return 0, syscall.ENOMEM + } + } + + copy(buf, msg) + return len(msg), nil +} + +// Write writes the given data to the multiplexed connection. +func (c *conn) Write(b []byte) (int, error) { + select { + case err := <-c.doneC: + if err == nil { + err = io.EOF + } + return 0, err + default: + } + return c.mux.write(c.id, b) +} + +// Close closes the multiplexed connection. +func (c *conn) Close() error { + c.mux.connLock.Lock() + defer c.mux.connLock.Unlock() + if c.mux.conns[c.id] == c { + delete(c.mux.conns, c.id) + } + return c.close() +} + +func (c *conn) close() error { + c.closeOnce.Do(func() { + close(c.doneC) + }) + return nil +} + +// LocalAddr is the unimplemented stub for the corresponding net.Conn function. +func (c *conn) LocalAddr() net.Addr { + return nil +} + +// RemoteAddr is the unimplemented stub for the corresponding net.Conn function. +func (c *conn) RemoteAddr() net.Addr { + return nil +} + +// SetDeadline is the unimplemented stub for the corresponding net.Conn function. +func (c *conn) SetDeadline(t time.Time) error { + return nil +} + +// SetReadDeadline is the unimplemented stub for the corresponding net.Conn function. +func (c *conn) SetReadDeadline(t time.Time) error { + return nil +} + +// SetWriteDeadline is the unimplemented stub for the corresponding net.Conn function. +func (c *conn) SetWriteDeadline(t time.Time) error { + return nil +} diff --git a/vendor/github.com/containerd/nri/pkg/net/multiplex/ttrpc.go b/vendor/github.com/containerd/nri/pkg/net/multiplex/ttrpc.go new file mode 100644 index 000000000..c600cb1b2 --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/net/multiplex/ttrpc.go @@ -0,0 +1,24 @@ +/* + 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 multiplex + +const ( + // PluginServiceConn is the mux connection ID for NRI plugin services. + PluginServiceConn ConnID = iota + 1 + // RuntimeServiceConn is the mux connection ID for NRI runtime services. + RuntimeServiceConn +) diff --git a/vendor/github.com/containerd/nri/pkg/net/socketpair_unix.go b/vendor/github.com/containerd/nri/pkg/net/socketpair_unix.go new file mode 100644 index 000000000..f0ca8a1bf --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/net/socketpair_unix.go @@ -0,0 +1,98 @@ +//go:build !windows +// +build !windows + +/* + 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 net + +import ( + "fmt" + "net" + "os" + + syscall "golang.org/x/sys/unix" +) + +const ( + local = 0 + peer = 1 +) + +// SocketPair contains the file descriptors of a connected pair of sockets. +type SocketPair [2]int + +// NewSocketPair returns a connected pair of sockets. +func NewSocketPair() (SocketPair, error) { + fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0) + if err != nil { + return [2]int{-1, -1}, fmt.Errorf("failed to create socketpair: %w", err) + } + + return fds, nil +} + +// LocalFile returns the socketpair fd for local usage as an *os.File. +func (fds SocketPair) LocalFile() *os.File { + return os.NewFile(uintptr(fds[local]), fds.fileName()+"[0]") +} + +// PeerFile returns the socketpair fd for peer usage as an *os.File. +func (fds SocketPair) PeerFile() *os.File { + return os.NewFile(uintptr(fds[peer]), fds.fileName()+"[1]") +} + +// LocalConn returns a net.Conn for the local end of the socketpair. +func (fds SocketPair) LocalConn() (net.Conn, error) { + file := fds.LocalFile() + defer file.Close() + conn, err := net.FileConn(file) + if err != nil { + return nil, fmt.Errorf("failed to create net.Conn for %s[0]: %w", fds.fileName(), err) + } + return conn, nil +} + +// PeerConn returns a net.Conn for the peer end of the socketpair. +func (fds SocketPair) PeerConn() (net.Conn, error) { + file := fds.PeerFile() + defer file.Close() + conn, err := net.FileConn(file) + if err != nil { + return nil, fmt.Errorf("failed to create net.Conn for %s[1]: %w", fds.fileName(), err) + } + return conn, nil +} + +// Close closes both ends of the socketpair. +func (fds SocketPair) Close() { + fds.LocalClose() + fds.PeerClose() +} + +// LocalClose closes the local end of the socketpair. +func (fds SocketPair) LocalClose() { + syscall.Close(fds[local]) +} + +// PeerClose closes the peer end of the socketpair. +func (fds SocketPair) PeerClose() { + syscall.Close(fds[peer]) +} + +func (fds SocketPair) fileName() string { + return fmt.Sprintf("socketpair-#%d:%d[0]", fds[local], fds[peer]) +} diff --git a/vendor/github.com/containerd/nri/pkg/net/socketpair_windows.go b/vendor/github.com/containerd/nri/pkg/net/socketpair_windows.go new file mode 100644 index 000000000..c3185ca2a --- /dev/null +++ b/vendor/github.com/containerd/nri/pkg/net/socketpair_windows.go @@ -0,0 +1,198 @@ +//go:build windows +// +build windows + +/* + 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 net + +import ( + "fmt" + "net" + "os" + "unsafe" + + sys "golang.org/x/sys/windows" +) + +// SocketPair contains a connected pair of sockets. +type SocketPair [2]sys.Handle + +const ( + local = 0 + peer = 1 +) + +// NewSocketPair returns a connected pair of sockets. +func NewSocketPair() (SocketPair, error) { + /* return [2]sys.Handle{sys.InvalidHandle, sys.InvalidHandle}, + errors.New("failed to emulatesocketpair, unimplemented for windows")*/ + + // untested: return emulateWithPreConnect() + return emulateWithPreConnect() +} + +func emulateWithPreConnect() (SocketPair, error) { + var ( + invalid = SocketPair{sys.InvalidHandle, sys.InvalidHandle} + sa sys.SockaddrInet4 + //sn sys.Sockaddr + l sys.Handle + a sys.Handle + p sys.Handle + err error + ) + + l, err = socket(sys.AF_INET, sys.SOCK_STREAM, 0) + if err != nil { + return invalid, fmt.Errorf("failed to emulate socketpair (local Socket()): %w", err) + } + defer func() { + if err != nil { + sys.CloseHandle(l) + } + }() + + sa.Addr[0] = 127 + sa.Addr[3] = 1 + sa.Port = 9999 + + err = sys.Bind(l, &sa) + if err != nil { + return invalid, fmt.Errorf("failed to emulate socketpair (Bind()): %w", err) + } + + /*sn, err = sys.Getsockname(l) + if err != nil { + return invalid, fmt.Errorf("failed to emulate socketpair (Getsockname()): %w", err) + }*/ + + p, err = socket(sys.AF_INET, sys.SOCK_STREAM, 0) + if err != nil { + return invalid, fmt.Errorf("failed to emulate socketpair (peer Socket()): %w", err) + } + + defer func() { + if err != nil { + sys.CloseHandle(p) + } + }() + + err = sys.Listen(l, 0) + if err != nil { + return invalid, fmt.Errorf("failed to emulate socketpair (Listen()): %w", err) + } + + go func() { + err = connect(p, &sa) + }() + + a, err = accept(l, sys.AF_INET, sys.SOCK_STREAM, 0) + if err != nil { + return invalid, fmt.Errorf("failed to emualte socketpair (Accept()): %w", err) + } + defer func() { + if err != nil { + sys.CloseHandle(a) + } + }() + + sys.CloseHandle(l) + return SocketPair{a, p}, nil +} + +// Close closes both ends of the socketpair. +func (sp SocketPair) Close() { + sp.LocalClose() + sp.PeerClose() +} + +// LocalFile returns the socketpair fd for local usage as an *os.File. +func (sp SocketPair) LocalFile() *os.File { + return os.NewFile(uintptr(sp[local]), sp.fileName()+"[0]") +} + +// PeerFile returns the socketpair fd for peer usage as an *os.File. +func (sp SocketPair) PeerFile() *os.File { + return os.NewFile(uintptr(sp[peer]), sp.fileName()+"[1]") +} + +// LocalConn returns a net.Conn for the local end of the socketpair. +func (sp SocketPair) LocalConn() (net.Conn, error) { + file := sp.LocalFile() + defer file.Close() + conn, err := net.FileConn(file) + if err != nil { + return nil, fmt.Errorf("failed to create net.Conn for %s[0]: %w", sp.fileName(), err) + } + return conn, nil +} + +// PeerConn returns a net.Conn for the peer end of the socketpair. +func (sp SocketPair) PeerConn() (net.Conn, error) { + file := sp.PeerFile() + defer file.Close() + conn, err := net.FileConn(file) + if err != nil { + return nil, fmt.Errorf("failed to create net.Conn for %s[1]: %w", sp.fileName(), err) + } + return conn, nil +} + +// LocalClose closes the local end of the socketpair. +func (sp SocketPair) LocalClose() { + sys.CloseHandle(sp[local]) +} + +// PeerClose closes the peer end of the socketpair. +func (sp SocketPair) PeerClose() { + sys.CloseHandle(sp[peer]) +} + +func (sp SocketPair) fileName() string { + return fmt.Sprintf("socketpair-#%d:%d[0]", sp[local], sp[peer]) +} + +func socket(domain, typ, proto int) (sys.Handle, error) { + return sys.WSASocket(int32(domain), int32(typ), int32(proto), nil, 0, sys.WSA_FLAG_OVERLAPPED) +} + +func connect(s sys.Handle, sa sys.Sockaddr) error { + o := &sys.Overlapped{} + return sys.ConnectEx(s, sa, nil, 0, nil, o) +} + +func accept(l sys.Handle, domain, typ, proto int) (sys.Handle, error) { + var ( + a sys.Handle + err error + buf = [1024]byte{} + overlap = sys.Overlapped{} + cnt = uint32(16 + 256) + ) + + a, err = socket(sys.AF_INET, sys.SOCK_STREAM, 0) + if err != nil { + return sys.InvalidHandle, fmt.Errorf("failed to emulate socketpair (accept): %w", err) + } + + err = sys.AcceptEx(l, a, (*byte)(unsafe.Pointer(&buf)), 0, cnt, cnt, &cnt, &overlap) + if err != nil { + return sys.InvalidHandle, fmt.Errorf("failed to emulate socketpair (AcceptEx()): %w", err) + } + + return a, nil +} diff --git a/vendor/github.com/containerd/nri/types/v1/types.go b/vendor/github.com/containerd/nri/types/v1/types.go index c46827807..0c3d0d95a 100644 --- a/vendor/github.com/containerd/nri/types/v1/types.go +++ b/vendor/github.com/containerd/nri/types/v1/types.go @@ -18,8 +18,7 @@ package v1 import ( "encoding/json" - - "github.com/pkg/errors" + "errors" ) // Plugin type and configuration diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go index 6a7a91e55..7e9122103 100644 --- a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go +++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go @@ -12,10 +12,12 @@ type Spec struct { Root *Root `json:"root,omitempty"` // Hostname configures the container's hostname. Hostname string `json:"hostname,omitempty"` + // Domainname configures the container's domainname. + Domainname string `json:"domainname,omitempty"` // Mounts configures additional mounts (on top of Root). Mounts []Mount `json:"mounts,omitempty"` // Hooks configures callbacks for container lifecycle events. - Hooks *Hooks `json:"hooks,omitempty" platform:"linux,solaris"` + Hooks *Hooks `json:"hooks,omitempty" platform:"linux,solaris,zos"` // Annotations contains arbitrary metadata for the container. Annotations map[string]string `json:"annotations,omitempty"` @@ -27,6 +29,8 @@ type Spec struct { Windows *Windows `json:"windows,omitempty" platform:"windows"` // VM specifies configuration for virtual-machine-based containers. VM *VM `json:"vm,omitempty" platform:"vm"` + // ZOS is platform-specific configuration for z/OS based containers. + ZOS *ZOS `json:"zos,omitempty" platform:"zos"` } // Process contains information to start a specific application inside the container. @@ -49,7 +53,7 @@ type Process struct { // Capabilities are Linux capabilities that are kept for the process. Capabilities *LinuxCapabilities `json:"capabilities,omitempty" platform:"linux"` // Rlimits specifies rlimit options to apply to the process. - Rlimits []POSIXRlimit `json:"rlimits,omitempty" platform:"linux,solaris"` + Rlimits []POSIXRlimit `json:"rlimits,omitempty" platform:"linux,solaris,zos"` // NoNewPrivileges controls whether additional privileges could be gained by processes in the container. NoNewPrivileges bool `json:"noNewPrivileges,omitempty" platform:"linux"` // ApparmorProfile specifies the apparmor profile for the container. @@ -86,11 +90,11 @@ type Box struct { // User specifies specific user (and group) information for the container process. type User struct { // UID is the user id. - UID uint32 `json:"uid" platform:"linux,solaris"` + UID uint32 `json:"uid" platform:"linux,solaris,zos"` // GID is the group id. - GID uint32 `json:"gid" platform:"linux,solaris"` + GID uint32 `json:"gid" platform:"linux,solaris,zos"` // Umask is the umask for the init process. - Umask *uint32 `json:"umask,omitempty" platform:"linux,solaris"` + Umask *uint32 `json:"umask,omitempty" platform:"linux,solaris,zos"` // AdditionalGids are additional group ids set for the container's process. AdditionalGids []uint32 `json:"additionalGids,omitempty" platform:"linux,solaris"` // Username is the user name. @@ -110,11 +114,16 @@ type Mount struct { // Destination is the absolute path where the mount will be placed in the container. Destination string `json:"destination"` // Type specifies the mount kind. - Type string `json:"type,omitempty" platform:"linux,solaris"` + Type string `json:"type,omitempty" platform:"linux,solaris,zos"` // Source specifies the source path of the mount. Source string `json:"source,omitempty"` // Options are fstab style mount options. Options []string `json:"options,omitempty"` + + // UID/GID mappings used for changing file owners w/o calling chown, fs should support it. + // Every mount point could have its own mapping. + UIDMappings []LinuxIDMapping `json:"uidMappings,omitempty" platform:"linux"` + GIDMappings []LinuxIDMapping `json:"gidMappings,omitempty" platform:"linux"` } // Hook specifies a command that is run at a particular event in the lifecycle of a container @@ -178,7 +187,7 @@ type Linux struct { // MountLabel specifies the selinux context for the mounts in the container. MountLabel string `json:"mountLabel,omitempty"` // IntelRdt contains Intel Resource Director Technology (RDT) information for - // handling resource constraints (e.g., L3 cache, memory bandwidth) for the container + // handling resource constraints and monitoring metrics (e.g., L3 cache, memory bandwidth) for the container IntelRdt *LinuxIntelRdt `json:"intelRdt,omitempty"` // Personality contains configuration for the Linux personality syscall Personality *LinuxPersonality `json:"personality,omitempty"` @@ -250,8 +259,8 @@ type LinuxInterfacePriority struct { Priority uint32 `json:"priority"` } -// linuxBlockIODevice holds major:minor format supported in blkio cgroup -type linuxBlockIODevice struct { +// LinuxBlockIODevice holds major:minor format supported in blkio cgroup +type LinuxBlockIODevice struct { // Major is the device's major number. Major int64 `json:"major"` // Minor is the device's minor number. @@ -260,7 +269,7 @@ type linuxBlockIODevice struct { // LinuxWeightDevice struct holds a `major:minor weight` pair for weightDevice type LinuxWeightDevice struct { - linuxBlockIODevice + LinuxBlockIODevice // Weight is the bandwidth rate for the device. Weight *uint16 `json:"weight,omitempty"` // LeafWeight is the bandwidth rate for the device while competing with the cgroup's child cgroups, CFQ scheduler only @@ -269,7 +278,7 @@ type LinuxWeightDevice struct { // LinuxThrottleDevice struct holds a `major:minor rate_per_second` pair type LinuxThrottleDevice struct { - linuxBlockIODevice + LinuxBlockIODevice // Rate is the IO rate limit per cgroup per device Rate uint64 `json:"rate"` } @@ -328,6 +337,8 @@ type LinuxCPU struct { Cpus string `json:"cpus,omitempty"` // List of memory nodes in the cpuset. Default is to use any available memory node. Mems string `json:"mems,omitempty"` + // cgroups are configured with minimum weight, 0: default behavior, 1: SCHED_IDLE. + Idle *int64 `json:"idle,omitempty"` } // LinuxPids for Linux cgroup 'pids' resource management (Linux 4.3) @@ -522,11 +533,21 @@ type WindowsMemoryResources struct { // WindowsCPUResources contains CPU resource management settings. type WindowsCPUResources struct { - // Number of CPUs available to the container. + // Count is the number of CPUs available to the container. It represents the + // fraction of the configured processor `count` in a container in relation + // to the processors available in the host. The fraction ultimately + // determines the portion of processor cycles that the threads in a + // container can use during each scheduling interval, as the number of + // cycles per 10,000 cycles. Count *uint64 `json:"count,omitempty"` - // CPU shares (relative weight to other containers with cpu shares). + // Shares limits the share of processor time given to the container relative + // to other workloads on the processor. The processor `shares` (`weight` at + // the platform level) is a value between 0 and 10000. Shares *uint16 `json:"shares,omitempty"` - // Specifies the portion of processor cycles that this container can use as a percentage times 100. + // Maximum determines the portion of processor cycles that the threads in a + // container can use during each scheduling interval, as the number of + // cycles per 10,000 cycles. Set processor `maximum` to a percentage times + // 100. Maximum *uint16 `json:"maximum,omitempty"` } @@ -613,6 +634,19 @@ type Arch string // LinuxSeccompFlag is a flag to pass to seccomp(2). type LinuxSeccompFlag string +const ( + // LinuxSeccompFlagLog is a seccomp flag to request all returned + // actions except SECCOMP_RET_ALLOW to be logged. An administrator may + // override this filter flag by preventing specific actions from being + // logged via the /proc/sys/kernel/seccomp/actions_logged file. (since + // Linux 4.14) + LinuxSeccompFlagLog LinuxSeccompFlag = "SECCOMP_FILTER_FLAG_LOG" + + // LinuxSeccompFlagSpecAllow can be used to disable Speculative Store + // Bypass mitigation. (since Linux 4.17) + LinuxSeccompFlagSpecAllow LinuxSeccompFlag = "SECCOMP_FILTER_FLAG_SPEC_ALLOW" +) + // Additional architectures permitted to be used for system calls // By default only the native architecture of the kernel is permitted const ( @@ -683,8 +717,9 @@ type LinuxSyscall struct { Args []LinuxSeccompArg `json:"args,omitempty"` } -// LinuxIntelRdt has container runtime resource constraints for Intel RDT -// CAT and MBA features which introduced in Linux 4.10 and 4.12 kernel +// LinuxIntelRdt has container runtime resource constraints for Intel RDT CAT and MBA +// features and flags enabling Intel RDT CMT and MBM features. +// Intel RDT features are available in Linux 4.14 and newer kernel versions. type LinuxIntelRdt struct { // The identity for RDT Class of Service ClosID string `json:"closID,omitempty"` @@ -697,4 +732,36 @@ type LinuxIntelRdt struct { // The unit of memory bandwidth is specified in "percentages" by // default, and in "MBps" if MBA Software Controller is enabled. MemBwSchema string `json:"memBwSchema,omitempty"` + + // EnableCMT is the flag to indicate if the Intel RDT CMT is enabled. CMT (Cache Monitoring Technology) supports monitoring of + // the last-level cache (LLC) occupancy for the container. + EnableCMT bool `json:"enableCMT,omitempty"` + + // EnableMBM is the flag to indicate if the Intel RDT MBM is enabled. MBM (Memory Bandwidth Monitoring) supports monitoring of + // total and local memory bandwidth for the container. + EnableMBM bool `json:"enableMBM,omitempty"` +} + +// ZOS contains platform-specific configuration for z/OS based containers. +type ZOS struct { + // Devices are a list of device nodes that are created for the container + Devices []ZOSDevice `json:"devices,omitempty"` +} + +// ZOSDevice represents the mknod information for a z/OS special device file +type ZOSDevice struct { + // Path to the device. + Path string `json:"path"` + // Device type, block, char, etc. + Type string `json:"type"` + // Major is the device's major number. + Major int64 `json:"major"` + // Minor is the device's minor number. + Minor int64 `json:"minor"` + // FileMode permission bits for the device. + FileMode *os.FileMode `json:"fileMode,omitempty"` + // UID of the device. + UID *uint32 `json:"uid,omitempty"` + // Gid of the device. + GID *uint32 `json:"gid,omitempty"` } diff --git a/vendor/github.com/opencontainers/runtime-tools/error/error.go b/vendor/github.com/opencontainers/runtime-tools/error/error.go deleted file mode 100644 index f7eac6639..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/error/error.go +++ /dev/null @@ -1,122 +0,0 @@ -// Package error implements generic tooling for tracking RFC 2119 -// violations and linking back to the appropriate specification section. -package error - -import ( - "fmt" - "strings" -) - -// Level represents the RFC 2119 compliance levels -type Level int - -const ( - // MAY-level - - // May represents 'MAY' in RFC 2119. - May Level = iota - // Optional represents 'OPTIONAL' in RFC 2119. - Optional - - // SHOULD-level - - // Should represents 'SHOULD' in RFC 2119. - Should - // ShouldNot represents 'SHOULD NOT' in RFC 2119. - ShouldNot - // Recommended represents 'RECOMMENDED' in RFC 2119. - Recommended - // NotRecommended represents 'NOT RECOMMENDED' in RFC 2119. - NotRecommended - - // MUST-level - - // Must represents 'MUST' in RFC 2119 - Must - // MustNot represents 'MUST NOT' in RFC 2119. - MustNot - // Shall represents 'SHALL' in RFC 2119. - Shall - // ShallNot represents 'SHALL NOT' in RFC 2119. - ShallNot - // Required represents 'REQUIRED' in RFC 2119. - Required -) - -// Error represents an error with compliance level and specification reference. -type Error struct { - // Level represents the RFC 2119 compliance level. - Level Level - - // Reference is a URL for the violated specification requirement. - Reference string - - // Err holds additional details about the violation. - Err error -} - -// ParseLevel takes a string level and returns the RFC 2119 compliance level constant. -func ParseLevel(level string) (Level, error) { - switch strings.ToUpper(level) { - case "MAY": - fallthrough - case "OPTIONAL": - return May, nil - case "SHOULD": - fallthrough - case "SHOULDNOT": - fallthrough - case "RECOMMENDED": - fallthrough - case "NOTRECOMMENDED": - return Should, nil - case "MUST": - fallthrough - case "MUSTNOT": - fallthrough - case "SHALL": - fallthrough - case "SHALLNOT": - fallthrough - case "REQUIRED": - return Must, nil - } - - var l Level - return l, fmt.Errorf("%q is not a valid compliance level", level) -} - -// String takes a RFC 2119 compliance level constant and returns a string representation. -func (level Level) String() string { - switch level { - case May: - return "MAY" - case Optional: - return "OPTIONAL" - case Should: - return "SHOULD" - case ShouldNot: - return "SHOULD NOT" - case Recommended: - return "RECOMMENDED" - case NotRecommended: - return "NOT RECOMMENDED" - case Must: - return "MUST" - case MustNot: - return "MUST NOT" - case Shall: - return "SHALL" - case ShallNot: - return "SHALL NOT" - case Required: - return "REQUIRED" - } - - panic(fmt.Sprintf("%d is not a valid compliance level", level)) -} - -// Error returns the error message with specification reference. -func (err *Error) Error() string { - return fmt.Sprintf("%s\nRefer to: %s", err.Err.Error(), err.Reference) -} diff --git a/vendor/github.com/opencontainers/runtime-tools/filepath/abs.go b/vendor/github.com/opencontainers/runtime-tools/filepath/abs.go deleted file mode 100644 index e4ab7453f..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/filepath/abs.go +++ /dev/null @@ -1,48 +0,0 @@ -package filepath - -import ( - "regexp" - "strings" -) - -var windowsAbs = regexp.MustCompile(`^[a-zA-Z]:\\.*$`) - -// Abs is a version of path/filepath's Abs with an explicit operating -// system and current working directory. -func Abs(os, path, cwd string) (_ string, err error) { - if IsAbs(os, path) { - return Clean(os, path), nil - } - return Clean(os, Join(os, cwd, path)), nil -} - -// IsAbs is a version of path/filepath's IsAbs with an explicit -// operating system. -func IsAbs(os, path string) bool { - if os == "windows" { - // FIXME: copy hideous logic from Go's - // src/path/filepath/path_windows.go into somewhere where we can - // put 3-clause BSD licensed code. - return windowsAbs.MatchString(path) - } - sep := Separator(os) - - // POSIX has [1]: - // - // > If a pathname begins with two successive characters, - // > the first component following the leading characters - // > may be interpreted in an implementation-defined manner, - // > although more than two leading characters shall be - // > treated as a single character. - // - // And Boost treats // as non-absolute [2], but Linux [3,4], Python - // [5] and Go [6] all treat // as absolute. - // - // [1]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13 - // [2]: https://github.com/boostorg/filesystem/blob/boost-1.64.0/test/path_test.cpp#L861 - // [3]: http://man7.org/linux/man-pages/man7/path_resolution.7.html - // [4]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/path-lookup.md?h=v4.12#n41 - // [5]: https://github.com/python/cpython/blob/v3.6.1/Lib/posixpath.py#L64-L66 - // [6]: https://go.googlesource.com/go/+/go1.8.3/src/path/path.go#199 - return strings.HasPrefix(path, string(sep)) -} diff --git a/vendor/github.com/opencontainers/runtime-tools/filepath/ancestor.go b/vendor/github.com/opencontainers/runtime-tools/filepath/ancestor.go deleted file mode 100644 index 896cd8206..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/filepath/ancestor.go +++ /dev/null @@ -1,32 +0,0 @@ -package filepath - -import ( - "fmt" - "strings" -) - -// IsAncestor returns true when pathB is an strict ancestor of pathA, -// and false where the paths are equal or pathB is outside of pathA. -// Paths that are not absolute will be made absolute with Abs. -func IsAncestor(os, pathA, pathB, cwd string) (_ bool, err error) { - if pathA == pathB { - return false, nil - } - - pathA, err = Abs(os, pathA, cwd) - if err != nil { - return false, err - } - pathB, err = Abs(os, pathB, cwd) - if err != nil { - return false, err - } - sep := Separator(os) - if !strings.HasSuffix(pathA, string(sep)) { - pathA = fmt.Sprintf("%s%c", pathA, sep) - } - if pathA == pathB { - return false, nil - } - return strings.HasPrefix(pathB, pathA), nil -} diff --git a/vendor/github.com/opencontainers/runtime-tools/filepath/clean.go b/vendor/github.com/opencontainers/runtime-tools/filepath/clean.go deleted file mode 100644 index d5dd65ae1..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/filepath/clean.go +++ /dev/null @@ -1,74 +0,0 @@ -package filepath - -import ( - "fmt" - "strings" -) - -// Clean is an explicit-OS version of path/filepath's Clean. -func Clean(os, path string) string { - abs := IsAbs(os, path) - sep := Separator(os) - elements := strings.Split(path, string(sep)) - - // Replace multiple Separator elements with a single one. - for i := 0; i < len(elements); i++ { - if len(elements[i]) == 0 { - elements = append(elements[:i], elements[i+1:]...) - i-- - } - } - - // Eliminate each . path name element (the current directory). - for i := 0; i < len(elements); i++ { - if elements[i] == "." && len(elements) > 1 { - elements = append(elements[:i], elements[i+1:]...) - i-- - } - } - - // Eliminate each inner .. path name element (the parent directory) - // along with the non-.. element that precedes it. - for i := 1; i < len(elements); i++ { - if i == 1 && abs && sep == '\\' { - continue - } - if i > 0 && elements[i] == ".." { - elements = append(elements[:i-1], elements[i+1:]...) - i -= 2 - } - } - - // Eliminate .. elements that begin a rooted path: - // that is, replace "/.." by "/" at the beginning of a path, - // assuming Separator is '/'. - offset := 0 - if sep == '\\' { - offset = 1 - } - if abs { - for len(elements) > offset && elements[offset] == ".." { - elements = append(elements[:offset], elements[offset+1:]...) - } - } - - cleaned := strings.Join(elements, string(sep)) - if abs { - if sep == '/' { - cleaned = fmt.Sprintf("%c%s", sep, cleaned) - } else if len(elements) == 1 { - cleaned = fmt.Sprintf("%s%c", cleaned, sep) - } - } - - // If the result of this process is an empty string, Clean returns - // the string ".". - if len(cleaned) == 0 { - cleaned = "." - } - - if cleaned == path { - return path - } - return Clean(os, cleaned) -} diff --git a/vendor/github.com/opencontainers/runtime-tools/filepath/doc.go b/vendor/github.com/opencontainers/runtime-tools/filepath/doc.go deleted file mode 100644 index 7ee085bf4..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/filepath/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Package filepath implements Go's filepath package with explicit -// operating systems (and for some functions and explicit working -// directory). This allows tools built for one OS to operate on paths -// targeting another OS. For example, a Linux build can determine -// whether a path is absolute on Linux or on Windows. -package filepath diff --git a/vendor/github.com/opencontainers/runtime-tools/filepath/join.go b/vendor/github.com/opencontainers/runtime-tools/filepath/join.go deleted file mode 100644 index b865d237c..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/filepath/join.go +++ /dev/null @@ -1,9 +0,0 @@ -package filepath - -import "strings" - -// Join is an explicit-OS version of path/filepath's Join. -func Join(os string, elem ...string) string { - sep := Separator(os) - return Clean(os, strings.Join(elem, string(sep))) -} diff --git a/vendor/github.com/opencontainers/runtime-tools/filepath/separator.go b/vendor/github.com/opencontainers/runtime-tools/filepath/separator.go deleted file mode 100644 index 2c5e8905a..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/filepath/separator.go +++ /dev/null @@ -1,9 +0,0 @@ -package filepath - -// Separator is an explicit-OS version of path/filepath's Separator. -func Separator(os string) rune { - if os == "windows" { - return '\\' - } - return '/' -} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/config.go b/vendor/github.com/opencontainers/runtime-tools/generate/config.go index f68bdde37..48f281d28 100644 --- a/vendor/github.com/opencontainers/runtime-tools/generate/config.go +++ b/vendor/github.com/opencontainers/runtime-tools/generate/config.go @@ -123,6 +123,13 @@ func (g *Generator) initConfigLinuxResourcesPids() { } } +func (g *Generator) initConfigLinuxResourcesUnified() { + g.initConfigLinuxResources() + if g.Config.Linux.Resources.Unified == nil { + g.Config.Linux.Resources.Unified = map[string]string{} + } +} + func (g *Generator) initConfigSolaris() { g.initConfig() if g.Config.Solaris == nil { @@ -185,24 +192,3 @@ func (g *Generator) initConfigVM() { g.Config.VM = &rspec.VM{} } } - -func (g *Generator) initConfigVMHypervisor() { - g.initConfigVM() - if &g.Config.VM.Hypervisor == nil { - g.Config.VM.Hypervisor = rspec.VMHypervisor{} - } -} - -func (g *Generator) initConfigVMKernel() { - g.initConfigVM() - if &g.Config.VM.Kernel == nil { - g.Config.VM.Kernel = rspec.VMKernel{} - } -} - -func (g *Generator) initConfigVMImage() { - g.initConfigVM() - if &g.Config.VM.Image == nil { - g.Config.VM.Image = rspec.VMImage{} - } -} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/generate.go b/vendor/github.com/opencontainers/runtime-tools/generate/generate.go index 70241013c..4d66b320d 100644 --- a/vendor/github.com/opencontainers/runtime-tools/generate/generate.go +++ b/vendor/github.com/opencontainers/runtime-tools/generate/generate.go @@ -10,7 +10,7 @@ import ( rspec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate/seccomp" - "github.com/opencontainers/runtime-tools/validate" + capsCheck "github.com/opencontainers/runtime-tools/validate/capabilities" "github.com/syndtr/gocapability/capability" ) @@ -42,7 +42,7 @@ type ExportOptions struct { // New creates a configuration Generator with the default // configuration for the target operating system. func New(os string) (generator Generator, err error) { - if os != "linux" && os != "solaris" && os != "windows" { + if os != "linux" && os != "solaris" && os != "windows" && os != "freebsd" { return generator, fmt.Errorf("no defaults configured for %s", os) } @@ -72,7 +72,7 @@ func New(os string) (generator Generator, err error) { } } - if os == "linux" || os == "solaris" { + if os == "linux" || os == "solaris" || os == "freebsd" { config.Process.User = rspec.User{} config.Process.Env = []string{ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", @@ -182,7 +182,7 @@ func New(os string) (generator Generator, err error) { Destination: "/dev", Type: "tmpfs", Source: "tmpfs", - Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"}, + Options: []string{"nosuid", "noexec", "strictatime", "mode=755", "size=65536k"}, }, { Destination: "/dev/pts", @@ -237,6 +237,21 @@ func New(os string) (generator Generator, err error) { }, Seccomp: seccomp.DefaultProfile(&config), } + } else if os == "freebsd" { + config.Mounts = []rspec.Mount{ + { + Destination: "/dev", + Type: "devfs", + Source: "devfs", + Options: []string{"ruleset=4"}, + }, + { + Destination: "/dev/fd", + Type: "fdescfs", + Source: "fdesc", + Options: []string{}, + }, + } } envCache := map[string]int{} @@ -249,10 +264,6 @@ func New(os string) (generator Generator, err error) { // NewFromSpec creates a configuration Generator from a given // configuration. -// -// Deprecated: Replace with: -// -// generator := Generator{Config: config} func NewFromSpec(config *rspec.Spec) Generator { envCache := map[string]int{} if config != nil && config.Process != nil { @@ -444,6 +455,13 @@ func (g *Generator) SetProcessUsername(username string) { g.Config.Process.User.Username = username } +// SetProcessUmask sets g.Config.Process.User.Umask. +func (g *Generator) SetProcessUmask(umask uint32) { + g.initConfigProcess() + u := umask + g.Config.Process.User.Umask = &u +} + // SetProcessGID sets g.Config.Process.User.GID. func (g *Generator) SetProcessGID(gid uint32) { g.initConfigProcess() @@ -597,6 +615,12 @@ func (g *Generator) SetLinuxCgroupsPath(path string) { g.Config.Linux.CgroupsPath = path } +// SetLinuxIntelRdtClosID sets g.Config.Linux.IntelRdt.ClosID +func (g *Generator) SetLinuxIntelRdtClosID(clos string) { + g.initConfigLinuxIntelRdt() + g.Config.Linux.IntelRdt.ClosID = clos +} + // SetLinuxIntelRdtL3CacheSchema sets g.Config.Linux.IntelRdt.L3CacheSchema func (g *Generator) SetLinuxIntelRdtL3CacheSchema(schema string) { g.initConfigLinuxIntelRdt() @@ -844,6 +868,28 @@ func (g *Generator) DropLinuxResourcesHugepageLimit(pageSize string) { } } +// AddLinuxResourcesUnified sets the g.Config.Linux.Resources.Unified +func (g *Generator) SetLinuxResourcesUnified(unified map[string]string) { + g.initConfigLinuxResourcesUnified() + for k, v := range unified { + g.Config.Linux.Resources.Unified[k] = v + } +} + +// AddLinuxResourcesUnified adds or updates the key-value pair from g.Config.Linux.Resources.Unified +func (g *Generator) AddLinuxResourcesUnified(key, val string) { + g.initConfigLinuxResourcesUnified() + g.Config.Linux.Resources.Unified[key] = val +} + +// DropLinuxResourcesUnified drops a key-value pair from g.Config.Linux.Resources.Unified +func (g *Generator) DropLinuxResourcesUnified(key string) { + if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.Unified == nil { + return + } + delete(g.Config.Linux.Resources.Unified, key) +} + // SetLinuxResourcesMemoryLimit sets g.Config.Linux.Resources.Memory.Limit. func (g *Generator) SetLinuxResourcesMemoryLimit(limit int64) { g.initConfigLinuxResourcesMemory() @@ -1018,10 +1064,9 @@ func (g *Generator) ClearPreStartHooks() { } // AddPreStartHook add a prestart hook into g.Config.Hooks.Prestart. -func (g *Generator) AddPreStartHook(preStartHook rspec.Hook) error { +func (g *Generator) AddPreStartHook(preStartHook rspec.Hook) { g.initConfigHooks() g.Config.Hooks.Prestart = append(g.Config.Hooks.Prestart, preStartHook) - return nil } // ClearPostStopHooks clear g.Config.Hooks.Poststop. @@ -1033,10 +1078,9 @@ func (g *Generator) ClearPostStopHooks() { } // AddPostStopHook adds a poststop hook into g.Config.Hooks.Poststop. -func (g *Generator) AddPostStopHook(postStopHook rspec.Hook) error { +func (g *Generator) AddPostStopHook(postStopHook rspec.Hook) { g.initConfigHooks() g.Config.Hooks.Poststop = append(g.Config.Hooks.Poststop, postStopHook) - return nil } // ClearPostStartHooks clear g.Config.Hooks.Poststart. @@ -1048,10 +1092,9 @@ func (g *Generator) ClearPostStartHooks() { } // AddPostStartHook adds a poststart hook into g.Config.Hooks.Poststart. -func (g *Generator) AddPostStartHook(postStartHook rspec.Hook) error { +func (g *Generator) AddPostStartHook(postStartHook rspec.Hook) { g.initConfigHooks() g.Config.Hooks.Poststart = append(g.Config.Hooks.Poststart, postStartHook) - return nil } // AddMount adds a mount into g.Config.Mounts. @@ -1093,7 +1136,7 @@ func (g *Generator) SetupPrivileged(privileged bool) { if privileged { // Add all capabilities in privileged mode. var finalCapList []string for _, cap := range capability.List() { - if g.HostSpecific && cap > validate.LastCap() { + if g.HostSpecific && cap > capsCheck.LastCap() { continue } finalCapList = append(finalCapList, fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String()))) @@ -1127,7 +1170,7 @@ func (g *Generator) ClearProcessCapabilities() { // AddProcessCapability adds a process capability into all 5 capability sets. func (g *Generator) AddProcessCapability(c string) error { cp := strings.ToUpper(c) - if err := validate.CapValid(cp, g.HostSpecific); err != nil { + if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil { return err } @@ -1190,7 +1233,7 @@ func (g *Generator) AddProcessCapability(c string) error { // AddProcessCapabilityAmbient adds a process capability into g.Config.Process.Capabilities.Ambient. func (g *Generator) AddProcessCapabilityAmbient(c string) error { cp := strings.ToUpper(c) - if err := validate.CapValid(cp, g.HostSpecific); err != nil { + if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil { return err } @@ -1214,7 +1257,7 @@ func (g *Generator) AddProcessCapabilityAmbient(c string) error { // AddProcessCapabilityBounding adds a process capability into g.Config.Process.Capabilities.Bounding. func (g *Generator) AddProcessCapabilityBounding(c string) error { cp := strings.ToUpper(c) - if err := validate.CapValid(cp, g.HostSpecific); err != nil { + if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil { return err } @@ -1237,7 +1280,7 @@ func (g *Generator) AddProcessCapabilityBounding(c string) error { // AddProcessCapabilityEffective adds a process capability into g.Config.Process.Capabilities.Effective. func (g *Generator) AddProcessCapabilityEffective(c string) error { cp := strings.ToUpper(c) - if err := validate.CapValid(cp, g.HostSpecific); err != nil { + if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil { return err } @@ -1260,7 +1303,7 @@ func (g *Generator) AddProcessCapabilityEffective(c string) error { // AddProcessCapabilityInheritable adds a process capability into g.Config.Process.Capabilities.Inheritable. func (g *Generator) AddProcessCapabilityInheritable(c string) error { cp := strings.ToUpper(c) - if err := validate.CapValid(cp, g.HostSpecific); err != nil { + if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil { return err } @@ -1283,7 +1326,7 @@ func (g *Generator) AddProcessCapabilityInheritable(c string) error { // AddProcessCapabilityPermitted adds a process capability into g.Config.Process.Capabilities.Permitted. func (g *Generator) AddProcessCapabilityPermitted(c string) error { cp := strings.ToUpper(c) - if err := validate.CapValid(cp, g.HostSpecific); err != nil { + if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil { return err } @@ -1336,7 +1379,7 @@ func (g *Generator) DropProcessCapability(c string) error { } } - return validate.CapValid(cp, false) + return capsCheck.CapValid(cp, false) } // DropProcessCapabilityAmbient drops a process capability from g.Config.Process.Capabilities.Ambient. @@ -1352,7 +1395,7 @@ func (g *Generator) DropProcessCapabilityAmbient(c string) error { } } - return validate.CapValid(cp, false) + return capsCheck.CapValid(cp, false) } // DropProcessCapabilityBounding drops a process capability from g.Config.Process.Capabilities.Bounding. @@ -1368,7 +1411,7 @@ func (g *Generator) DropProcessCapabilityBounding(c string) error { } } - return validate.CapValid(cp, false) + return capsCheck.CapValid(cp, false) } // DropProcessCapabilityEffective drops a process capability from g.Config.Process.Capabilities.Effective. @@ -1384,7 +1427,7 @@ func (g *Generator) DropProcessCapabilityEffective(c string) error { } } - return validate.CapValid(cp, false) + return capsCheck.CapValid(cp, false) } // DropProcessCapabilityInheritable drops a process capability from g.Config.Process.Capabilities.Inheritable. @@ -1400,7 +1443,7 @@ func (g *Generator) DropProcessCapabilityInheritable(c string) error { } } - return validate.CapValid(cp, false) + return capsCheck.CapValid(cp, false) } // DropProcessCapabilityPermitted drops a process capability from g.Config.Process.Capabilities.Permitted. @@ -1416,7 +1459,7 @@ func (g *Generator) DropProcessCapabilityPermitted(c string) error { } } - return validate.CapValid(cp, false) + return capsCheck.CapValid(cp, false) } func mapStrToNamespace(ns string, path string) (rspec.LinuxNamespace, error) { @@ -1495,9 +1538,6 @@ func (g *Generator) AddDevice(device rspec.LinuxDevice) { g.Config.Linux.Devices[i] = device return } - if dev.Type == device.Type && dev.Major == device.Major && dev.Minor == device.Minor { - fmt.Fprintln(os.Stderr, "WARNING: The same type, major and minor should not be used for multiple devices.") - } } g.Config.Linux.Devices = append(g.Config.Linux.Devices, device) @@ -1556,12 +1596,8 @@ func (g *Generator) RemoveLinuxResourcesDevice(allow bool, devType string, major return } } - return } -// strPtr returns the pointer pointing to the string s. -func strPtr(s string) *string { return &s } - // SetSyscallAction adds rules for syscalls with the specified action func (g *Generator) SetSyscallAction(arguments seccomp.SyscallOpts) error { g.initConfigLinuxSeccomp() @@ -1581,6 +1617,12 @@ func (g *Generator) SetDefaultSeccompActionForce(action string) error { return seccomp.ParseDefaultActionForce(action, g.Config.Linux.Seccomp) } +// SetDomainName sets g.Config.Domainname +func (g *Generator) SetDomainName(domain string) { + g.initConfig() + g.Config.Domainname = domain +} + // SetSeccompArchitecture sets the supported seccomp architectures func (g *Generator) SetSeccompArchitecture(architecture string) error { g.initConfigLinuxSeccomp() @@ -1687,14 +1729,14 @@ func (g *Generator) SetVMHypervisorPath(path string) error { if !strings.HasPrefix(path, "/") { return fmt.Errorf("hypervisorPath %v is not an absolute path", path) } - g.initConfigVMHypervisor() + g.initConfigVM() g.Config.VM.Hypervisor.Path = path return nil } // SetVMHypervisorParameters sets g.Config.VM.Hypervisor.Parameters func (g *Generator) SetVMHypervisorParameters(parameters []string) { - g.initConfigVMHypervisor() + g.initConfigVM() g.Config.VM.Hypervisor.Parameters = parameters } @@ -1703,14 +1745,14 @@ func (g *Generator) SetVMKernelPath(path string) error { if !strings.HasPrefix(path, "/") { return fmt.Errorf("kernelPath %v is not an absolute path", path) } - g.initConfigVMKernel() + g.initConfigVM() g.Config.VM.Kernel.Path = path return nil } // SetVMKernelParameters sets g.Config.VM.Kernel.Parameters func (g *Generator) SetVMKernelParameters(parameters []string) { - g.initConfigVMKernel() + g.initConfigVM() g.Config.VM.Kernel.Parameters = parameters } @@ -1719,7 +1761,7 @@ func (g *Generator) SetVMKernelInitRD(initrd string) error { if !strings.HasPrefix(initrd, "/") { return fmt.Errorf("kernelInitrd %v is not an absolute path", initrd) } - g.initConfigVMKernel() + g.initConfigVM() g.Config.VM.Kernel.InitRD = initrd return nil } @@ -1729,7 +1771,7 @@ func (g *Generator) SetVMImagePath(path string) error { if !strings.HasPrefix(path, "/") { return fmt.Errorf("imagePath %v is not an absolute path", path) } - g.initConfigVMImage() + g.initConfigVM() g.Config.VM.Image.Path = path return nil } @@ -1745,7 +1787,7 @@ func (g *Generator) SetVMImageFormat(format string) error { default: return fmt.Errorf("Commonly supported formats are: raw, qcow2, vdi, vmdk, vhd") } - g.initConfigVMImage() + g.initConfigVM() g.Config.VM.Image.Format = format return nil } diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/consts.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/consts.go index eade5718e..f28d8f587 100644 --- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/consts.go +++ b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/consts.go @@ -4,9 +4,4 @@ const ( seccompOverwrite = "overwrite" seccompAppend = "append" nothing = "nothing" - kill = "kill" - trap = "trap" - trace = "trace" - allow = "allow" - errno = "errno" ) diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go index 5fee5a3b2..345a32a61 100644 --- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go +++ b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go @@ -151,6 +151,9 @@ func DefaultProfile(rs *specs.Spec) *rspec.LinuxSeccomp { "io_submit", "ipc", "kill", + "landlock_add_rule", + "landlock_create_ruleset", + "landlock_restrict_self", "lchown", "lchown32", "lgetxattr", @@ -303,6 +306,7 @@ func DefaultProfile(rs *specs.Spec) *rspec.LinuxSeccomp { "stat64", "statfs", "statfs64", + "statx", "symlink", "symlinkat", "sync", @@ -353,11 +357,23 @@ func DefaultProfile(rs *specs.Spec) *rspec.LinuxSeccomp { Value: 0x0, Op: rspec.OpEqualTo, }, + }, + }, + { + Names: []string{"personality"}, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{ { Index: 0, Value: 0x0008, Op: rspec.OpEqualTo, }, + }, + }, + { + Names: []string{"personality"}, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{ { Index: 0, Value: 0xffffffff, @@ -512,7 +528,7 @@ func DefaultProfile(rs *specs.Spec) *rspec.LinuxSeccomp { Args: []rspec.LinuxSeccompArg{ { Index: sysCloneFlagsIndex, - Value: CloneNewNS | CloneNewUTS | CloneNewIPC | CloneNewUser | CloneNewPID | CloneNewNet, + Value: CloneNewNS | CloneNewUTS | CloneNewIPC | CloneNewUser | CloneNewPID | CloneNewNet | CloneNewCgroup, ValueTwo: 0, Op: rspec.OpMaskedEqual, }, @@ -566,6 +582,20 @@ func DefaultProfile(rs *specs.Spec) *rspec.LinuxSeccomp { }, }...) /* Flags parameter of the clone syscall is the 2nd on s390 */ + syscalls = append(syscalls, []rspec.LinuxSyscall{ + { + Names: []string{"clone"}, + Action: rspec.ActAllow, + Args: []rspec.LinuxSeccompArg{ + { + Index: 1, + Value: 2080505856, + ValueTwo: 0, + Op: rspec.OpMaskedEqual, + }, + }, + }, + }...) } return &rspec.LinuxSeccomp{ diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_linux.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_linux.go index 311587437..5ca9a6dae 100644 --- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_linux.go +++ b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_linux.go @@ -1,15 +1,17 @@ +//go:build linux // +build linux package seccomp -import "syscall" +import "golang.org/x/sys/unix" // System values passed through on linux const ( - CloneNewIPC = syscall.CLONE_NEWIPC - CloneNewNet = syscall.CLONE_NEWNET - CloneNewNS = syscall.CLONE_NEWNS - CloneNewPID = syscall.CLONE_NEWPID - CloneNewUser = syscall.CLONE_NEWUSER - CloneNewUTS = syscall.CLONE_NEWUTS + CloneNewIPC = unix.CLONE_NEWIPC + CloneNewNet = unix.CLONE_NEWNET + CloneNewNS = unix.CLONE_NEWNS + CloneNewPID = unix.CLONE_NEWPID + CloneNewUser = unix.CLONE_NEWUSER + CloneNewUTS = unix.CLONE_NEWUTS + CloneNewCgroup = unix.CLONE_NEWCGROUP ) diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_unsupported.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_unsupported.go index 589b81c16..b8c1bc26e 100644 --- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_unsupported.go +++ b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_unsupported.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux package seccomp diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/syscall_compare.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/syscall_compare.go index dbf2aec1c..5e84653a9 100644 --- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/syscall_compare.go +++ b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/syscall_compare.go @@ -92,22 +92,6 @@ func identical(config1, config2 *rspec.LinuxSyscall) bool { return reflect.DeepEqual(config1, config2) } -func identicalExceptAction(config1, config2 *rspec.LinuxSyscall) bool { - samename := sameName(config1, config2) - sameAction := sameAction(config1, config2) - sameArgs := sameArgs(config1, config2) - - return samename && !sameAction && sameArgs -} - -func identicalExceptArgs(config1, config2 *rspec.LinuxSyscall) bool { - samename := sameName(config1, config2) - sameAction := sameAction(config1, config2) - sameArgs := sameArgs(config1, config2) - - return samename && sameAction && !sameArgs -} - func sameName(config1, config2 *rspec.LinuxSyscall) bool { return reflect.DeepEqual(config1.Names, config2.Names) } diff --git a/vendor/github.com/opencontainers/runtime-tools/specerror/bundle.go b/vendor/github.com/opencontainers/runtime-tools/specerror/bundle.go deleted file mode 100644 index dbe32af3d..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/specerror/bundle.go +++ /dev/null @@ -1,29 +0,0 @@ -package specerror - -import ( - "fmt" - - rfc2119 "github.com/opencontainers/runtime-tools/error" -) - -// define error codes -const ( - // ConfigInRootBundleDir represents "This REQUIRED file MUST reside in the root of the bundle directory" - ConfigInRootBundleDir Code = 0xa001 + iota - // ConfigConstName represents "This REQUIRED file MUST be named `config.json`." - ConfigConstName - // ArtifactsInSingleDir represents "When supplied, while these artifacts MUST all be present in a single directory on the local filesystem, that directory itself is not part of the bundle." - ArtifactsInSingleDir -) - -var ( - containerFormatRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "bundle.md#container-format"), nil - } -) - -func init() { - register(ConfigInRootBundleDir, rfc2119.Must, containerFormatRef) - register(ConfigConstName, rfc2119.Must, containerFormatRef) - register(ArtifactsInSingleDir, rfc2119.Must, containerFormatRef) -} diff --git a/vendor/github.com/opencontainers/runtime-tools/specerror/config-linux.go b/vendor/github.com/opencontainers/runtime-tools/specerror/config-linux.go deleted file mode 100644 index aa2a284ce..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/specerror/config-linux.go +++ /dev/null @@ -1,134 +0,0 @@ -package specerror - -import ( - "fmt" - - rfc2119 "github.com/opencontainers/runtime-tools/error" -) - -// define error codes -const ( - // DefaultFilesystems represents "The following filesystems SHOULD be made available in each container's filesystem:" - DefaultFilesystems Code = 0xc001 + iota - // NSPathAbs represents "This value MUST be an absolute path in the runtime mount namespace." - NSPathAbs - // NSProcInPath represents "The runtime MUST place the container process in the namespace associated with that `path`." - NSProcInPath - // NSPathMatchTypeError represents "The runtime MUST generate an error if `path` is not associated with a namespace of type `type`." - NSPathMatchTypeError - // NSNewNSWithoutPath represents "If `path` is not specified, the runtime MUST create a new container namespace of type `type`." - NSNewNSWithoutPath - // NSInheritWithoutType represents "If a namespace type is not specified in the `namespaces` array, the container MUST inherit the runtime namespace of that type." - NSInheritWithoutType - // NSErrorOnDup represents "If a `namespaces` field contains duplicated namespaces with same `type`, the runtime MUST generate an error." - NSErrorOnDup - // UserNSMapOwnershipRO represents "The runtime SHOULD NOT modify the ownership of referenced filesystems to realize the mapping." - UserNSMapOwnershipRO - // DevicesAvailable represents "devices (array of objects, OPTIONAL) lists devices that MUST be available in the container." - DevicesAvailable - // DevicesFileNotMatch represents "If a file already exists at `path` that does not match the requested device, the runtime MUST generate an error." - DevicesFileNotMatch - // DevicesMajMinRequired represents "`major, minor` (int64, REQUIRED unless `type` is `p`) - major, minor numbers for the device." - DevicesMajMinRequired - // DevicesErrorOnDup represents "The same `type`, `major` and `minor` SHOULD NOT be used for multiple devices." - DevicesErrorOnDup - // DefaultDevices represents "In addition to any devices configured with this setting, the runtime MUST also supply default devices." - DefaultDevices - // CgroupsPathAbsOrRel represents "The value of `cgroupsPath` MUST be either an absolute path or a relative path." - CgroupsPathAbsOrRel - // CgroupsAbsPathRelToMount represents "In the case of an absolute path (starting with `/`), the runtime MUST take the path to be relative to the cgroups mount point." - CgroupsAbsPathRelToMount - // CgroupsPathAttach represents "If the value is specified, the runtime MUST consistently attach to the same place in the cgroups hierarchy given the same value of `cgroupsPath`." - CgroupsPathAttach - // CgroupsPathError represents "Runtimes MAY consider certain `cgroupsPath` values to be invalid, and MUST generate an error if this is the case." - CgroupsPathError - // DevicesApplyInOrder represents "The runtime MUST apply entries in the listed order." - DevicesApplyInOrder - // BlkIOWeightOrLeafWeightExist represents "You MUST specify at least one of `weight` or `leafWeight` in a given entry, and MAY specify both." - BlkIOWeightOrLeafWeightExist - // IntelRdtPIDWrite represents "If `intelRdt` is set, the runtime MUST write the container process ID to the `/tasks` file in a mounted `resctrl` pseudo-filesystem, using the container ID from `start` and creating the `container-id` directory if necessary." - IntelRdtPIDWrite - // IntelRdtNoMountedResctrlError represents "If no mounted `resctrl` pseudo-filesystem is available in the runtime mount namespace, the runtime MUST generate an error." - IntelRdtNoMountedResctrlError - // NotManipResctrlWithoutIntelRdt represents "If `intelRdt` is not set, the runtime MUST NOT manipulate any `resctrl` pseudo-filesystems." - NotManipResctrlWithoutIntelRdt - // IntelRdtL3CacheSchemaWrite represents "If `l3CacheSchema` is set, runtimes MUST write the value to the `schemata` file in the `` directory discussed in `intelRdt`." - IntelRdtL3CacheSchemaWrite - // IntelRdtL3CacheSchemaNotWrite represents "If `l3CacheSchema` is not set, runtimes MUST NOT write to `schemata` files in any `resctrl` pseudo-filesystems." - IntelRdtL3CacheSchemaNotWrite - // SeccSyscallsNamesRequired represents "`names` MUST contain at least one entry." - SeccSyscallsNamesRequired - // MaskedPathsAbs represents "maskedPaths (array of strings, OPTIONAL) will mask over the provided paths inside the container so that they cannot be read. The values MUST be absolute paths in the container namespace." - MaskedPathsAbs - // ReadonlyPathsAbs represents "readonlyPaths (array of strings, OPTIONAL) will set the provided paths as readonly inside the container. The values MUST be absolute paths in the container namespace." - ReadonlyPathsAbs -) - -var ( - defaultFilesystemsRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config-linux.md#default-filesystems"), nil - } - namespacesRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config-linux.md#namespaces"), nil - } - userNamespaceMappingsRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config-linux.md#user-namespace-mappings"), nil - } - devicesRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config-linux.md#devices"), nil - } - defaultDevicesRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config-linux.md#default-devices"), nil - } - cgroupsPathRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config-linux.md#cgroups-path"), nil - } - deviceWhitelistRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config-linux.md#device-whitelist"), nil - } - blockIoRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config-linux.md#block-io"), nil - } - intelrdtRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config-linux.md#intelrdt"), nil - } - seccompRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config-linux.md#seccomp"), nil - } - maskedPathsRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config-linux.md#masked-paths"), nil - } - readonlyPathsRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config-linux.md#readonly-paths"), nil - } -) - -func init() { - register(DefaultFilesystems, rfc2119.Should, defaultFilesystemsRef) - register(NSPathAbs, rfc2119.Must, namespacesRef) - register(NSProcInPath, rfc2119.Must, namespacesRef) - register(NSPathMatchTypeError, rfc2119.Must, namespacesRef) - register(NSNewNSWithoutPath, rfc2119.Must, namespacesRef) - register(NSInheritWithoutType, rfc2119.Must, namespacesRef) - register(NSErrorOnDup, rfc2119.Must, namespacesRef) - register(UserNSMapOwnershipRO, rfc2119.Should, userNamespaceMappingsRef) - register(DevicesAvailable, rfc2119.Must, devicesRef) - register(DevicesFileNotMatch, rfc2119.Must, devicesRef) - register(DevicesMajMinRequired, rfc2119.Required, devicesRef) - register(DevicesErrorOnDup, rfc2119.Should, devicesRef) - register(DefaultDevices, rfc2119.Must, defaultDevicesRef) - register(CgroupsPathAbsOrRel, rfc2119.Must, cgroupsPathRef) - register(CgroupsAbsPathRelToMount, rfc2119.Must, cgroupsPathRef) - register(CgroupsPathAttach, rfc2119.Must, cgroupsPathRef) - register(CgroupsPathError, rfc2119.Must, cgroupsPathRef) - register(DevicesApplyInOrder, rfc2119.Must, deviceWhitelistRef) - register(BlkIOWeightOrLeafWeightExist, rfc2119.Must, blockIoRef) - register(IntelRdtPIDWrite, rfc2119.Must, intelrdtRef) - register(IntelRdtNoMountedResctrlError, rfc2119.Must, intelrdtRef) - register(NotManipResctrlWithoutIntelRdt, rfc2119.Must, intelrdtRef) - register(IntelRdtL3CacheSchemaWrite, rfc2119.Must, intelrdtRef) - register(IntelRdtL3CacheSchemaNotWrite, rfc2119.Must, intelrdtRef) - register(SeccSyscallsNamesRequired, rfc2119.Must, seccompRef) - register(MaskedPathsAbs, rfc2119.Must, maskedPathsRef) - register(ReadonlyPathsAbs, rfc2119.Must, readonlyPathsRef) -} diff --git a/vendor/github.com/opencontainers/runtime-tools/specerror/config-windows.go b/vendor/github.com/opencontainers/runtime-tools/specerror/config-windows.go deleted file mode 100644 index c8134867d..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/specerror/config-windows.go +++ /dev/null @@ -1,32 +0,0 @@ -package specerror - -import ( - "fmt" - - rfc2119 "github.com/opencontainers/runtime-tools/error" -) - -// define error codes -const ( - // WindowsLayerFoldersRequired represents "`layerFolders` MUST contain at least one entry." - WindowsLayerFoldersRequired Code = 0xd001 + iota - // WindowsHyperVPresent represents "If present, the container MUST be run with Hyper-V isolation." - WindowsHyperVPresent - // WindowsHyperVOmit represents "If omitted, the container MUST be run as a Windows Server container." - WindowsHyperVOmit -) - -var ( - layerfoldersRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config-windows.md#layerfolders"), nil - } - hypervRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config-windows.md#hyperv"), nil - } -) - -func init() { - register(WindowsLayerFoldersRequired, rfc2119.Must, layerfoldersRef) - register(WindowsHyperVPresent, rfc2119.Must, hypervRef) - register(WindowsHyperVOmit, rfc2119.Must, hypervRef) -} diff --git a/vendor/github.com/opencontainers/runtime-tools/specerror/config.go b/vendor/github.com/opencontainers/runtime-tools/specerror/config.go deleted file mode 100644 index 5357ab59f..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/specerror/config.go +++ /dev/null @@ -1,188 +0,0 @@ -package specerror - -import ( - "fmt" - - rfc2119 "github.com/opencontainers/runtime-tools/error" -) - -// define error codes -const ( - // SpecVersionInSemVer represents "`ociVersion` (string, REQUIRED) MUST be in SemVer v2.0.0 format and specifies the version of the Open Container Initiative Runtime Specification with which the bundle complies." - SpecVersionInSemVer Code = 0xb001 + iota - // RootOnWindowsRequired represents "On Windows, for Windows Server Containers, this field is REQUIRED." - RootOnWindowsRequired - // RootOnHyperVNotSet represents "For Hyper-V Containers, this field MUST NOT be set." - RootOnHyperVNotSet - // RootOnNonWindowsRequired represents "On all other platforms, this field is REQUIRED." - RootOnNonWindowsRequired - // RootPathOnWindowsGUID represents "On Windows, `path` MUST be a volume GUID path." - RootPathOnWindowsGUID - // RootPathOnPosixConvention represents "The value SHOULD be the conventional `rootfs`." - RootPathOnPosixConvention - // RootPathExist represents "A directory MUST exist at the path declared by the field." - RootPathExist - // RootReadonlyImplement represents "`readonly` (bool, OPTIONAL) If true then the root filesystem MUST be read-only inside the container, defaults to false." - RootReadonlyImplement - // RootReadonlyOnWindowsFalse represents "* On Windows, this field MUST be omitted or false." - RootReadonlyOnWindowsFalse - // MountsInOrder represents "The runtime MUST mount entries in the listed order." - MountsInOrder - // MountsDestAbs represents "Destination of mount point: path inside container. This value MUST be an absolute path." - MountsDestAbs - // MountsDestOnWindowsNotNested represents "Windows: one mount destination MUST NOT be nested within another mount (e.g., c:\\foo and c:\\foo\\bar)." - MountsDestOnWindowsNotNested - // MountsOptionsOnWindowsROSupport represents "Windows: runtimes MUST support `ro`, mounting the filesystem read-only when `ro` is given." - MountsOptionsOnWindowsROSupport - // ProcRequiredAtStart represents "This property is REQUIRED when `start` is called." - ProcRequiredAtStart - // ProcConsoleSizeIgnore represents "Runtimes MUST ignore `consoleSize` if `terminal` is `false` or unset." - ProcConsoleSizeIgnore - // ProcCwdAbs represents "cwd (string, REQUIRED) is the working directory that will be set for the executable. This value MUST be an absolute path." - ProcCwdAbs - // ProcArgsOneEntryRequired represents "This specification extends the IEEE standard in that at least one entry is REQUIRED, and that entry is used with the same semantics as `execvp`'s *file*." - ProcArgsOneEntryRequired - // PosixProcRlimitsTypeGenError represents "The runtime MUST generate an error for any values which cannot be mapped to a relevant kernel interface." - PosixProcRlimitsTypeGenError - // PosixProcRlimitsTypeGet represents "For each entry in `rlimits`, a `getrlimit(3)` on `type` MUST succeed." - PosixProcRlimitsTypeGet - // PosixProcRlimitsTypeValueError represents "valid values are defined in the ... man page" - PosixProcRlimitsTypeValueError - // PosixProcRlimitsSoftMatchCur represents "`rlim.rlim_cur` MUST match the configured value." - PosixProcRlimitsSoftMatchCur - // PosixProcRlimitsHardMatchMax represents "`rlim.rlim_max` MUST match the configured value." - PosixProcRlimitsHardMatchMax - // PosixProcRlimitsErrorOnDup represents "If `rlimits` contains duplicated entries with same `type`, the runtime MUST generate an error." - PosixProcRlimitsErrorOnDup - // LinuxProcCapError represents "Any value which cannot be mapped to a relevant kernel interface MUST cause an error." - LinuxProcCapError - // LinuxProcOomScoreAdjSet represents "If `oomScoreAdj` is set, the runtime MUST set `oom_score_adj` to the given value." - LinuxProcOomScoreAdjSet - // LinuxProcOomScoreAdjNotSet represents "If `oomScoreAdj` is not set, the runtime MUST NOT change the value of `oom_score_adj`." - LinuxProcOomScoreAdjNotSet - // PlatformSpecConfOnWindowsSet represents "This MUST be set if the target platform of this spec is `windows`." - PlatformSpecConfOnWindowsSet - // PosixHooksPathAbs represents "This specification extends the IEEE standard in that `path` MUST be absolute." - PosixHooksPathAbs - // PosixHooksTimeoutPositive represents "If set, `timeout` MUST be greater than zero." - PosixHooksTimeoutPositive - // PosixHooksCalledInOrder represents "Hooks MUST be called in the listed order." - PosixHooksCalledInOrder - // PosixHooksStateToStdin represents "The state of the container MUST be passed to hooks over stdin so that they may do work appropriate to the current state of the container." - PosixHooksStateToStdin - // PrestartTiming represents "The pre-start hooks MUST be called after the `start` operation is called but before the user-specified program command is executed." - PrestartTiming - // PoststartTiming represents "The post-start hooks MUST be called after the user-specified process is executed but before the `start` operation returns." - PoststartTiming - // PoststopTiming represents "The post-stop hooks MUST be called after the container is deleted but before the `delete` operation returns." - PoststopTiming - // AnnotationsKeyValueMap represents "Annotations MUST be a key-value map." - AnnotationsKeyValueMap - // AnnotationsKeyString represents "Keys MUST be strings." - AnnotationsKeyString - // AnnotationsKeyRequired represents "Keys MUST NOT be an empty string." - AnnotationsKeyRequired - // AnnotationsKeyReversedDomain represents "Keys SHOULD be named using a reverse domain notation - e.g. `com.example.myKey`." - AnnotationsKeyReversedDomain - // AnnotationsKeyReservedNS represents "Keys using the `org.opencontainers` namespace are reserved and MUST NOT be used by subsequent specifications." - AnnotationsKeyReservedNS - // AnnotationsKeyIgnoreUnknown represents "Implementations that are reading/processing this configuration file MUST NOT generate an error if they encounter an unknown annotation key." - AnnotationsKeyIgnoreUnknown - // AnnotationsValueString represents "Values MUST be strings." - AnnotationsValueString - // ExtensibilityIgnoreUnknownProp represents "Runtimes that are reading or processing this configuration file MUST NOT generate an error if they encounter an unknown property." - ExtensibilityIgnoreUnknownProp - // ValidValues represents "Runtimes that are reading or processing this configuration file MUST generate an error when invalid or unsupported values are encountered." - ValidValues -) - -var ( - specificationVersionRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config.md#specification-version"), nil - } - rootRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config.md#root"), nil - } - mountsRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config.md#mounts"), nil - } - processRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config.md#process"), nil - } - posixProcessRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config.md#posix-process"), nil - } - linuxProcessRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config.md#linux-process"), nil - } - platformSpecificConfigurationRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config.md#platform-specific-configuration"), nil - } - posixPlatformHooksRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config.md#posix-platform-hooks"), nil - } - prestartRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config.md#prestart"), nil - } - poststartRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config.md#poststart"), nil - } - poststopRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config.md#poststop"), nil - } - annotationsRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config.md#annotations"), nil - } - extensibilityRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config.md#extensibility"), nil - } - validValuesRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "config.md#valid-values"), nil - } -) - -func init() { - register(SpecVersionInSemVer, rfc2119.Must, specificationVersionRef) - register(RootOnWindowsRequired, rfc2119.Required, rootRef) - register(RootOnHyperVNotSet, rfc2119.Must, rootRef) - register(RootOnNonWindowsRequired, rfc2119.Required, rootRef) - register(RootPathOnWindowsGUID, rfc2119.Must, rootRef) - register(RootPathOnPosixConvention, rfc2119.Should, rootRef) - register(RootPathExist, rfc2119.Must, rootRef) - register(RootReadonlyImplement, rfc2119.Must, rootRef) - register(RootReadonlyOnWindowsFalse, rfc2119.Must, rootRef) - register(MountsInOrder, rfc2119.Must, mountsRef) - register(MountsDestAbs, rfc2119.Must, mountsRef) - register(MountsDestOnWindowsNotNested, rfc2119.Must, mountsRef) - register(MountsOptionsOnWindowsROSupport, rfc2119.Must, mountsRef) - register(ProcRequiredAtStart, rfc2119.Required, processRef) - register(ProcConsoleSizeIgnore, rfc2119.Must, processRef) - register(ProcCwdAbs, rfc2119.Must, processRef) - register(ProcArgsOneEntryRequired, rfc2119.Required, processRef) - register(PosixProcRlimitsTypeGenError, rfc2119.Must, posixProcessRef) - register(PosixProcRlimitsTypeGet, rfc2119.Must, posixProcessRef) - register(PosixProcRlimitsTypeValueError, rfc2119.Should, posixProcessRef) - register(PosixProcRlimitsSoftMatchCur, rfc2119.Must, posixProcessRef) - register(PosixProcRlimitsHardMatchMax, rfc2119.Must, posixProcessRef) - register(PosixProcRlimitsErrorOnDup, rfc2119.Must, posixProcessRef) - register(LinuxProcCapError, rfc2119.Must, linuxProcessRef) - register(LinuxProcOomScoreAdjSet, rfc2119.Must, linuxProcessRef) - register(LinuxProcOomScoreAdjNotSet, rfc2119.Must, linuxProcessRef) - register(PlatformSpecConfOnWindowsSet, rfc2119.Must, platformSpecificConfigurationRef) - register(PosixHooksPathAbs, rfc2119.Must, posixPlatformHooksRef) - register(PosixHooksTimeoutPositive, rfc2119.Must, posixPlatformHooksRef) - register(PosixHooksCalledInOrder, rfc2119.Must, posixPlatformHooksRef) - register(PosixHooksStateToStdin, rfc2119.Must, posixPlatformHooksRef) - register(PrestartTiming, rfc2119.Must, prestartRef) - register(PoststartTiming, rfc2119.Must, poststartRef) - register(PoststopTiming, rfc2119.Must, poststopRef) - register(AnnotationsKeyValueMap, rfc2119.Must, annotationsRef) - register(AnnotationsKeyString, rfc2119.Must, annotationsRef) - register(AnnotationsKeyRequired, rfc2119.Must, annotationsRef) - register(AnnotationsKeyReversedDomain, rfc2119.Should, annotationsRef) - register(AnnotationsKeyReservedNS, rfc2119.Must, annotationsRef) - register(AnnotationsKeyIgnoreUnknown, rfc2119.Must, annotationsRef) - register(AnnotationsValueString, rfc2119.Must, annotationsRef) - register(ExtensibilityIgnoreUnknownProp, rfc2119.Must, extensibilityRef) - register(ValidValues, rfc2119.Must, validValuesRef) -} diff --git a/vendor/github.com/opencontainers/runtime-tools/specerror/error.go b/vendor/github.com/opencontainers/runtime-tools/specerror/error.go deleted file mode 100644 index 5de9492d9..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/specerror/error.go +++ /dev/null @@ -1,152 +0,0 @@ -// Package specerror implements runtime-spec-specific tooling for -// tracking RFC 2119 violations. -package specerror - -import ( - "fmt" - - "github.com/hashicorp/go-multierror" - rfc2119 "github.com/opencontainers/runtime-tools/error" -) - -const referenceTemplate = "https://github.com/opencontainers/runtime-spec/blob/v%s/%s" - -// Code represents the spec violation, enumerating both -// configuration violations and runtime violations. -type Code int64 - -const ( - // NonError represents that an input is not an error - NonError Code = 0x1a001 + iota - // NonRFCError represents that an error is not a rfc2119 error - NonRFCError -) - -type errorTemplate struct { - Level rfc2119.Level - Reference func(version string) (reference string, err error) -} - -// Error represents a runtime-spec violation. -type Error struct { - // Err holds the RFC 2119 violation. - Err rfc2119.Error - - // Code is a matchable holds a Code - Code Code -} - -// LevelErrors represents Errors filtered into fatal and warnings. -type LevelErrors struct { - // Warnings holds Errors that were below a compliance-level threshold. - Warnings []*Error - - // Error holds errors that were at or above a compliance-level - // threshold, as well as errors that are not Errors. - Error *multierror.Error -} - -var ociErrors = map[Code]errorTemplate{} - -func register(code Code, level rfc2119.Level, ref func(versiong string) (string, error)) { - if _, ok := ociErrors[code]; ok { - panic(fmt.Sprintf("should not regist a same code twice: %v", code)) - } - - ociErrors[code] = errorTemplate{Level: level, Reference: ref} -} - -// Error returns the error message with specification reference. -func (err *Error) Error() string { - return err.Err.Error() -} - -// NewRFCError creates an rfc2119.Error referencing a spec violation. -// -// A version string (for the version of the spec that was violated) -// must be set to get a working URL. -func NewRFCError(code Code, err error, version string) (*rfc2119.Error, error) { - template := ociErrors[code] - reference, err2 := template.Reference(version) - if err2 != nil { - return nil, err2 - } - return &rfc2119.Error{ - Level: template.Level, - Reference: reference, - Err: err, - }, nil -} - -// NewRFCErrorOrPanic creates an rfc2119.Error referencing a spec -// violation and panics on failure. This is handy for situations -// where you can't be bothered to check NewRFCError for failure. -func NewRFCErrorOrPanic(code Code, err error, version string) *rfc2119.Error { - rfcError, err2 := NewRFCError(code, err, version) - if err2 != nil { - panic(err2.Error()) - } - return rfcError -} - -// NewError creates an Error referencing a spec violation. The error -// can be cast to an *Error for extracting structured information -// about the level of the violation and a reference to the violated -// spec condition. -// -// A version string (for the version of the spec that was violated) -// must be set to get a working URL. -func NewError(code Code, err error, version string) error { - rfcError, err2 := NewRFCError(code, err, version) - if err2 != nil { - return err2 - } - return &Error{ - Err: *rfcError, - Code: code, - } -} - -// FindError finds an error from a source error (multiple error) and -// returns the error code if found. -// If the source error is nil or empty, return NonError. -// If the source error is not a multiple error, return NonRFCError. -func FindError(err error, code Code) Code { - if err == nil { - return NonError - } - - if merr, ok := err.(*multierror.Error); ok { - if merr.ErrorOrNil() == nil { - return NonError - } - for _, e := range merr.Errors { - if rfcErr, ok := e.(*Error); ok { - if rfcErr.Code == code { - return code - } - } - } - } - return NonRFCError -} - -// SplitLevel removes RFC 2119 errors with a level less than 'level' -// from the source error. If the source error is not a multierror, it -// is returned unchanged. -func SplitLevel(errIn error, level rfc2119.Level) (levelErrors LevelErrors, errOut error) { - merr, ok := errIn.(*multierror.Error) - if !ok { - return levelErrors, errIn - } - for _, err := range merr.Errors { - e, ok := err.(*Error) - if ok && e.Err.Level < level { - fmt.Println(e) - levelErrors.Warnings = append(levelErrors.Warnings, e) - continue - } - levelErrors.Error = multierror.Append(levelErrors.Error, err) - } - return levelErrors, nil -} diff --git a/vendor/github.com/opencontainers/runtime-tools/specerror/runtime-linux.go b/vendor/github.com/opencontainers/runtime-tools/specerror/runtime-linux.go deleted file mode 100644 index 8eb259ba1..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/specerror/runtime-linux.go +++ /dev/null @@ -1,23 +0,0 @@ -package specerror - -import ( - "fmt" - - rfc2119 "github.com/opencontainers/runtime-tools/error" -) - -// define error codes -const ( - // DefaultRuntimeLinuxSymlinks represents "While creating the container (step 2 in the lifecycle), runtimes MUST create default symlinks if the source file exists after processing `mounts`." - DefaultRuntimeLinuxSymlinks Code = 0xf001 + iota -) - -var ( - devSymbolicLinksRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "runtime-linux.md#dev-symbolic-links"), nil - } -) - -func init() { - register(DefaultRuntimeLinuxSymlinks, rfc2119.Must, devSymbolicLinksRef) -} diff --git a/vendor/github.com/opencontainers/runtime-tools/specerror/runtime.go b/vendor/github.com/opencontainers/runtime-tools/specerror/runtime.go deleted file mode 100644 index 383aea63c..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/specerror/runtime.go +++ /dev/null @@ -1,179 +0,0 @@ -package specerror - -import ( - "fmt" - - rfc2119 "github.com/opencontainers/runtime-tools/error" -) - -// define error codes -const ( - // EntityOperSameContainer represents "The entity using a runtime to create a container MUST be able to use the operations defined in this specification against that same container." - EntityOperSameContainer Code = 0xe001 + iota - // StateIDUniq represents "`id` (string, REQUIRED) is the container's ID. This MUST be unique across all containers on this host." - StateIDUniq - // StateNewStatus represents "Additional values MAY be defined by the runtime, however, they MUST be used to represent new runtime states not defined above." - StateNewStatus - // DefaultStateJSONPattern represents "When serialized in JSON, the format MUST adhere to the default pattern." - DefaultStateJSONPattern - // EnvCreateImplement represents "The container's runtime environment MUST be created according to the configuration in `config.json`." - EnvCreateImplement - // EnvCreateError represents "If the runtime is unable to create the environment specified in the `config.json`, it MUST generate an error." - EnvCreateError - // ProcNotRunAtResRequest represents "While the resources requested in the `config.json` MUST be created, the user-specified program (from `process`) MUST NOT be run at this time." - ProcNotRunAtResRequest - // ConfigUpdatesWithoutAffect represents "Any updates to `config.json` after this step MUST NOT affect the container." - ConfigUpdatesWithoutAffect - // PrestartHooksInvoke represents "The prestart hooks MUST be invoked by the runtime." - PrestartHooksInvoke - // PrestartHookFailGenError represents "If any prestart hook fails, the runtime MUST generate an error, stop the container, and continue the lifecycle at step 9." - PrestartHookFailGenError - // ProcImplement represents "The runtime MUST run the user-specified program, as specified by `process`." - ProcImplement - // PoststartHooksInvoke represents "The poststart hooks MUST be invoked by the runtime." - PoststartHooksInvoke - // PoststartHookFailGenWarn represents "If any poststart hook fails, the runtime MUST log a warning, but the remaining hooks and lifecycle continue as if the hook had succeeded." - PoststartHookFailGenWarn - // UndoCreateSteps represents "The container MUST be destroyed by undoing the steps performed during create phase (step 2)." - UndoCreateSteps - // PoststopHooksInvoke represents "The poststop hooks MUST be invoked by the runtime." - PoststopHooksInvoke - // PoststopHookFailGenWarn represents "If any poststop hook fails, the runtime MUST log a warning, but the remaining hooks and lifecycle continue as if the hook had succeeded." - PoststopHookFailGenWarn - // ErrorsLeaveStateUnchange represents "Unless otherwise stated, generating an error MUST leave the state of the environment as if the operation were never attempted - modulo any possible trivial ancillary changes such as logging." - ErrorsLeaveStateUnchange - // WarnsLeaveFlowUnchange represents "Unless otherwise stated, logging a warning does not change the flow of the operation; it MUST continue as if the warning had not been logged." - WarnsLeaveFlowUnchange - // DefaultOperations represents "Unless otherwise stated, runtimes MUST support the default operations." - DefaultOperations - // QueryWithoutIDGenError represents "This operation MUST generate an error if it is not provided the ID of a container." - QueryWithoutIDGenError - // QueryNonExistGenError represents "Attempting to query a container that does not exist MUST generate an error." - QueryNonExistGenError - // QueryStateImplement represents "This operation MUST return the state of a container as specified in the State section." - QueryStateImplement - // CreateWithBundlePathAndID represents "This operation MUST generate an error if it is not provided a path to the bundle and the container ID to associate with the container." - CreateWithBundlePathAndID - // CreateWithUniqueID represents "If the ID provided is not unique across all containers within the scope of the runtime, or is not valid in any other way, the implementation MUST generate an error and a new container MUST NOT be created." - CreateWithUniqueID - // CreateNewContainer represents "This operation MUST create a new container." - CreateNewContainer - // PropsApplyExceptProcOnCreate represents "All of the properties configured in `config.json` except for `process` MUST be applied." - PropsApplyExceptProcOnCreate - // ProcArgsApplyUntilStart represents `process.args` MUST NOT be applied until triggered by the `start` operation." - ProcArgsApplyUntilStart - // PropApplyFailGenError represents "If the runtime cannot apply a property as specified in the configuration, it MUST generate an error." - PropApplyFailGenError - // PropApplyFailNotCreate represents "If the runtime cannot apply a property as specified in the configuration, a new container MUST NOT be created." - PropApplyFailNotCreate - // StartWithoutIDGenError represents "`start` operation MUST generate an error if it is not provided the container ID." - StartWithoutIDGenError - // StartNotCreatedHaveNoEffect represents "Attempting to `start` a container that is not `created` MUST have no effect on the container." - StartNotCreatedHaveNoEffect - // StartNotCreatedGenError represents "Attempting to `start` a container that is not `created` MUST generate an error." - StartNotCreatedGenError - // StartProcImplement represents "`start` operation MUST run the user-specified program as specified by `process`." - StartProcImplement - // StartWithProcUnsetGenError represents "`start` operation MUST generate an error if `process` was not set." - StartWithProcUnsetGenError - // KillWithoutIDGenError represents "`kill` operation MUST generate an error if it is not provided the container ID." - KillWithoutIDGenError - // KillNonCreateRunHaveNoEffect represents "Attempting to send a signal to a container that is neither `created` nor `running` MUST have no effect on the container." - KillNonCreateRunHaveNoEffect - // KillNonCreateRunGenError represents "Attempting to send a signal to a container that is neither `created` nor `running` MUST generate an error." - KillNonCreateRunGenError - // KillSignalImplement represents "`kill` operation MUST send the specified signal to the container process." - KillSignalImplement - // DeleteWithoutIDGenError represents "`delete` operation MUST generate an error if it is not provided the container ID." - DeleteWithoutIDGenError - // DeleteNonStopHaveNoEffect represents "Attempting to `delete` a container that is not `stopped` MUST have no effect on the container." - DeleteNonStopHaveNoEffect - // DeleteNonStopGenError represents "Attempting to `delete` a container that is not `stopped` MUST generate an error." - DeleteNonStopGenError - // DeleteResImplement represents "Deleting a container MUST delete the resources that were created during the `create` step." - DeleteResImplement - // DeleteOnlyCreatedRes represents "Note that resources associated with the container, but not created by this container, MUST NOT be deleted." - DeleteOnlyCreatedRes -) - -var ( - scopeOfAContainerRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "runtime.md#scope-of-a-container"), nil - } - stateRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "runtime.md#state"), nil - } - lifecycleRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "runtime.md#lifecycle"), nil - } - errorsRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "runtime.md#errors"), nil - } - warningsRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "runtime.md#warnings"), nil - } - operationsRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "runtime.md#operations"), nil - } - queryStateRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "runtime.md#query-state"), nil - } - createRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "runtime.md#create"), nil - } - startRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "runtime.md#start"), nil - } - killRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "runtime.md#kill"), nil - } - deleteRef = func(version string) (reference string, err error) { - return fmt.Sprintf(referenceTemplate, version, "runtime.md#delete"), nil - } -) - -func init() { - register(EntityOperSameContainer, rfc2119.Must, scopeOfAContainerRef) - register(StateIDUniq, rfc2119.Must, stateRef) - register(StateNewStatus, rfc2119.Must, stateRef) - register(DefaultStateJSONPattern, rfc2119.Must, stateRef) - register(EnvCreateImplement, rfc2119.Must, lifecycleRef) - register(EnvCreateError, rfc2119.Must, lifecycleRef) - register(ProcNotRunAtResRequest, rfc2119.Must, lifecycleRef) - register(ConfigUpdatesWithoutAffect, rfc2119.Must, lifecycleRef) - register(PrestartHooksInvoke, rfc2119.Must, lifecycleRef) - register(PrestartHookFailGenError, rfc2119.Must, lifecycleRef) - register(ProcImplement, rfc2119.Must, lifecycleRef) - register(PoststartHooksInvoke, rfc2119.Must, lifecycleRef) - register(PoststartHookFailGenWarn, rfc2119.Must, lifecycleRef) - register(UndoCreateSteps, rfc2119.Must, lifecycleRef) - register(PoststopHooksInvoke, rfc2119.Must, lifecycleRef) - register(PoststopHookFailGenWarn, rfc2119.Must, lifecycleRef) - register(ErrorsLeaveStateUnchange, rfc2119.Must, errorsRef) - register(WarnsLeaveFlowUnchange, rfc2119.Must, warningsRef) - register(DefaultOperations, rfc2119.Must, operationsRef) - register(QueryWithoutIDGenError, rfc2119.Must, queryStateRef) - register(QueryNonExistGenError, rfc2119.Must, queryStateRef) - register(QueryStateImplement, rfc2119.Must, queryStateRef) - register(CreateWithBundlePathAndID, rfc2119.Must, createRef) - register(CreateWithUniqueID, rfc2119.Must, createRef) - register(CreateNewContainer, rfc2119.Must, createRef) - register(PropsApplyExceptProcOnCreate, rfc2119.Must, createRef) - register(ProcArgsApplyUntilStart, rfc2119.Must, createRef) - register(PropApplyFailGenError, rfc2119.Must, createRef) - register(PropApplyFailNotCreate, rfc2119.Must, createRef) - register(StartWithoutIDGenError, rfc2119.Must, startRef) - register(StartNotCreatedHaveNoEffect, rfc2119.Must, startRef) - register(StartNotCreatedGenError, rfc2119.Must, startRef) - register(StartProcImplement, rfc2119.Must, startRef) - register(StartWithProcUnsetGenError, rfc2119.Must, startRef) - register(KillWithoutIDGenError, rfc2119.Must, killRef) - register(KillNonCreateRunHaveNoEffect, rfc2119.Must, killRef) - register(KillNonCreateRunGenError, rfc2119.Must, killRef) - register(KillSignalImplement, rfc2119.Must, killRef) - register(DeleteWithoutIDGenError, rfc2119.Must, deleteRef) - register(DeleteNonStopHaveNoEffect, rfc2119.Must, deleteRef) - register(DeleteNonStopGenError, rfc2119.Must, deleteRef) - register(DeleteResImplement, rfc2119.Must, deleteRef) - register(DeleteOnlyCreatedRes, rfc2119.Must, deleteRef) -} diff --git a/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate.go b/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate.go new file mode 100644 index 000000000..7fa47b77c --- /dev/null +++ b/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate.go @@ -0,0 +1,31 @@ +package capabilities + +import ( + "fmt" + "strings" + + "github.com/syndtr/gocapability/capability" +) + +// CapValid checks whether a capability is valid +func CapValid(c string, hostSpecific bool) error { + isValid := false + + if !strings.HasPrefix(c, "CAP_") { + return fmt.Errorf("capability %s must start with CAP_", c) + } + for _, cap := range capability.List() { + if c == fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String())) { + if hostSpecific && cap > LastCap() { + return fmt.Errorf("%s is not supported on the current host", c) + } + isValid = true + break + } + } + + if !isValid { + return fmt.Errorf("invalid capability: %s", c) + } + return nil +} diff --git a/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate_linux.go b/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate_linux.go new file mode 100644 index 000000000..f6cb0d550 --- /dev/null +++ b/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate_linux.go @@ -0,0 +1,16 @@ +package capabilities + +import ( + "github.com/syndtr/gocapability/capability" +) + +// LastCap return last cap of system +func LastCap() capability.Cap { + last := capability.CAP_LAST_CAP + // hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap + if last == capability.Cap(63) { + last = capability.CAP_BLOCK_SUSPEND + } + + return last +} diff --git a/vendor/github.com/opencontainers/runtime-tools/validate/validate_unsupported.go b/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate_unsupported.go similarity index 64% rename from vendor/github.com/opencontainers/runtime-tools/validate/validate_unsupported.go rename to vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate_unsupported.go index f150c326c..00f8e1b61 100644 --- a/vendor/github.com/opencontainers/runtime-tools/validate/validate_unsupported.go +++ b/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate_unsupported.go @@ -1,3 +1,4 @@ +//go:build !linux // +build !linux package validate @@ -10,8 +11,3 @@ import ( func LastCap() capability.Cap { return capability.Cap(-1) } - -// CheckLinux is a noop on this platform -func (v *Validator) CheckLinux() (errs error) { - return nil -} diff --git a/vendor/github.com/opencontainers/runtime-tools/validate/validate.go b/vendor/github.com/opencontainers/runtime-tools/validate/validate.go deleted file mode 100644 index e2e820979..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/validate/validate.go +++ /dev/null @@ -1,838 +0,0 @@ -package validate - -import ( - "bufio" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "net" - "os" - "path/filepath" - "reflect" - "regexp" - "runtime" - "strings" - "unicode" - "unicode/utf8" - - "github.com/blang/semver" - "github.com/hashicorp/go-multierror" - rspec "github.com/opencontainers/runtime-spec/specs-go" - osFilepath "github.com/opencontainers/runtime-tools/filepath" - "github.com/sirupsen/logrus" - "github.com/syndtr/gocapability/capability" - - "github.com/opencontainers/runtime-tools/specerror" - "github.com/xeipuuv/gojsonschema" -) - -const specConfig = "config.json" - -var ( - // http://pubs.opengroup.org/onlinepubs/9699919799/functions/getrlimit.html - posixRlimits = []string{ - "RLIMIT_AS", - "RLIMIT_CORE", - "RLIMIT_CPU", - "RLIMIT_DATA", - "RLIMIT_FSIZE", - "RLIMIT_NOFILE", - "RLIMIT_STACK", - } - - // https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man2/getrlimit.2?h=man-pages-4.13 - linuxRlimits = append(posixRlimits, []string{ - "RLIMIT_MEMLOCK", - "RLIMIT_MSGQUEUE", - "RLIMIT_NICE", - "RLIMIT_NPROC", - "RLIMIT_RSS", - "RLIMIT_RTPRIO", - "RLIMIT_RTTIME", - "RLIMIT_SIGPENDING", - }...) - - configSchemaTemplate = "https://raw.githubusercontent.com/opencontainers/runtime-spec/v%s/schema/config-schema.json" -) - -// Validator represents a validator for runtime bundle -type Validator struct { - spec *rspec.Spec - bundlePath string - HostSpecific bool - platform string -} - -// NewValidator creates a Validator -func NewValidator(spec *rspec.Spec, bundlePath string, hostSpecific bool, platform string) (Validator, error) { - if hostSpecific && platform != runtime.GOOS { - return Validator{}, fmt.Errorf("When hostSpecific is set, platform must be same as the host platform") - } - return Validator{ - spec: spec, - bundlePath: bundlePath, - HostSpecific: hostSpecific, - platform: platform, - }, nil -} - -// NewValidatorFromPath creates a Validator with specified bundle path -func NewValidatorFromPath(bundlePath string, hostSpecific bool, platform string) (Validator, error) { - if bundlePath == "" { - return Validator{}, fmt.Errorf("bundle path shouldn't be empty") - } - - if _, err := os.Stat(bundlePath); err != nil { - return Validator{}, err - } - - configPath := filepath.Join(bundlePath, specConfig) - content, err := ioutil.ReadFile(configPath) - if err != nil { - return Validator{}, specerror.NewError(specerror.ConfigInRootBundleDir, err, rspec.Version) - } - if !utf8.Valid(content) { - return Validator{}, fmt.Errorf("%q is not encoded in UTF-8", configPath) - } - var spec rspec.Spec - if err = json.Unmarshal(content, &spec); err != nil { - return Validator{}, err - } - - return NewValidator(&spec, bundlePath, hostSpecific, platform) -} - -// CheckAll checks all parts of runtime bundle -func (v *Validator) CheckAll() error { - var errs *multierror.Error - errs = multierror.Append(errs, v.CheckJSONSchema()) - errs = multierror.Append(errs, v.CheckPlatform()) - errs = multierror.Append(errs, v.CheckRoot()) - errs = multierror.Append(errs, v.CheckMandatoryFields()) - errs = multierror.Append(errs, v.CheckSemVer()) - errs = multierror.Append(errs, v.CheckMounts()) - errs = multierror.Append(errs, v.CheckProcess()) - errs = multierror.Append(errs, v.CheckLinux()) - errs = multierror.Append(errs, v.CheckAnnotations()) - if v.platform == "linux" || v.platform == "solaris" { - errs = multierror.Append(errs, v.CheckHooks()) - } - - return errs.ErrorOrNil() -} - -// JSONSchemaURL returns the URL for the JSON Schema specifying the -// configuration format. It consumes configSchemaTemplate, but we -// provide it as a function to isolate consumers from inconsistent -// naming as runtime-spec evolves. -func JSONSchemaURL(version string) (url string, err error) { - ver, err := semver.Parse(version) - if err != nil { - return "", specerror.NewError(specerror.SpecVersionInSemVer, err, rspec.Version) - } - configRenamedToConfigSchemaVersion, err := semver.Parse("1.0.0-rc2") // config.json became config-schema.json in 1.0.0-rc2 - if ver.Compare(configRenamedToConfigSchemaVersion) == -1 { - return "", fmt.Errorf("unsupported configuration version (older than %s)", configRenamedToConfigSchemaVersion) - } - return fmt.Sprintf(configSchemaTemplate, version), nil -} - -// CheckJSONSchema validates the configuration against the -// runtime-spec JSON Schema, using the version of the schema that -// matches the configuration's declared version. -func (v *Validator) CheckJSONSchema() (errs error) { - logrus.Debugf("check JSON schema") - - url, err := JSONSchemaURL(v.spec.Version) - if err != nil { - errs = multierror.Append(errs, err) - return errs - } - - schemaLoader := gojsonschema.NewReferenceLoader(url) - documentLoader := gojsonschema.NewGoLoader(v.spec) - result, err := gojsonschema.Validate(schemaLoader, documentLoader) - if err != nil { - errs = multierror.Append(errs, err) - return errs - } - - if !result.Valid() { - for _, resultError := range result.Errors() { - errs = multierror.Append(errs, errors.New(resultError.String())) - } - } - - return errs -} - -// CheckRoot checks status of v.spec.Root -func (v *Validator) CheckRoot() (errs error) { - logrus.Debugf("check root") - - if v.platform == "windows" && v.spec.Windows != nil { - if v.spec.Windows.HyperV != nil { - if v.spec.Root != nil { - errs = multierror.Append(errs, - specerror.NewError(specerror.RootOnHyperVNotSet, fmt.Errorf("for Hyper-V containers, Root must not be set"), rspec.Version)) - } - return - } else if v.spec.Root == nil { - errs = multierror.Append(errs, - specerror.NewError(specerror.RootOnWindowsRequired, fmt.Errorf("on Windows, for Windows Server Containers, this field is REQUIRED"), rspec.Version)) - return - } - } else if v.platform != "windows" && v.spec.Root == nil { - errs = multierror.Append(errs, - specerror.NewError(specerror.RootOnNonWindowsRequired, fmt.Errorf("on all other platforms, this field is REQUIRED"), rspec.Version)) - return - } - - if v.platform == "windows" { - matched, err := regexp.MatchString(`\\\\[?]\\Volume[{][a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}[}]\\`, v.spec.Root.Path) - if err != nil { - errs = multierror.Append(errs, err) - } else if !matched { - errs = multierror.Append(errs, - specerror.NewError(specerror.RootPathOnWindowsGUID, fmt.Errorf("root.path is %q, but it MUST be a volume GUID path when target platform is windows", v.spec.Root.Path), rspec.Version)) - } - - if v.spec.Root.Readonly { - errs = multierror.Append(errs, - specerror.NewError(specerror.RootReadonlyOnWindowsFalse, fmt.Errorf("root.readonly field MUST be omitted or false when target platform is windows"), rspec.Version)) - } - - return - } - - absBundlePath, err := filepath.Abs(v.bundlePath) - if err != nil { - errs = multierror.Append(errs, fmt.Errorf("unable to convert %q to an absolute path", v.bundlePath)) - return - } - - if filepath.Base(v.spec.Root.Path) != "rootfs" { - errs = multierror.Append(errs, - specerror.NewError(specerror.RootPathOnPosixConvention, fmt.Errorf("path name should be the conventional 'rootfs'"), rspec.Version)) - } - - var rootfsPath string - var absRootPath string - if filepath.IsAbs(v.spec.Root.Path) { - rootfsPath = v.spec.Root.Path - absRootPath = filepath.Clean(rootfsPath) - } else { - var err error - rootfsPath = filepath.Join(v.bundlePath, v.spec.Root.Path) - absRootPath, err = filepath.Abs(rootfsPath) - if err != nil { - errs = multierror.Append(errs, fmt.Errorf("unable to convert %q to an absolute path", rootfsPath)) - return - } - } - - if fi, err := os.Stat(rootfsPath); err != nil { - errs = multierror.Append(errs, - specerror.NewError(specerror.RootPathExist, fmt.Errorf("cannot find the root path %q", rootfsPath), rspec.Version)) - } else if !fi.IsDir() { - errs = multierror.Append(errs, - specerror.NewError(specerror.RootPathExist, fmt.Errorf("root.path %q is not a directory", rootfsPath), rspec.Version)) - } - - rootParent := filepath.Dir(absRootPath) - if absRootPath == string(filepath.Separator) || rootParent != absBundlePath { - errs = multierror.Append(errs, - specerror.NewError(specerror.ArtifactsInSingleDir, fmt.Errorf("root.path is %q, but it MUST be a child of %q", v.spec.Root.Path, absBundlePath), rspec.Version)) - } - - return -} - -// CheckSemVer checks v.spec.Version -func (v *Validator) CheckSemVer() (errs error) { - logrus.Debugf("check semver") - - version := v.spec.Version - _, err := semver.Parse(version) - if err != nil { - errs = multierror.Append(errs, - specerror.NewError(specerror.SpecVersionInSemVer, fmt.Errorf("%q is not valid SemVer: %s", version, err.Error()), rspec.Version)) - } - if version != rspec.Version { - errs = multierror.Append(errs, fmt.Errorf("validate currently only handles version %s, but the supplied configuration targets %s", rspec.Version, version)) - } - - return -} - -// CheckHooks check v.spec.Hooks -func (v *Validator) CheckHooks() (errs error) { - logrus.Debugf("check hooks") - - if v.platform != "linux" && v.platform != "solaris" { - errs = multierror.Append(errs, fmt.Errorf("For %q platform, the configuration structure does not support hooks", v.platform)) - return - } - - if v.spec.Hooks != nil { - errs = multierror.Append(errs, v.checkEventHooks("prestart", v.spec.Hooks.Prestart, v.HostSpecific)) - errs = multierror.Append(errs, v.checkEventHooks("poststart", v.spec.Hooks.Poststart, v.HostSpecific)) - errs = multierror.Append(errs, v.checkEventHooks("poststop", v.spec.Hooks.Poststop, v.HostSpecific)) - } - - return -} - -func (v *Validator) checkEventHooks(hookType string, hooks []rspec.Hook, hostSpecific bool) (errs error) { - for i, hook := range hooks { - if !osFilepath.IsAbs(v.platform, hook.Path) { - errs = multierror.Append(errs, - specerror.NewError( - specerror.PosixHooksPathAbs, - fmt.Errorf("hooks.%s[%d].path %v: is not absolute path", - hookType, i, hook.Path), - rspec.Version)) - } - - if hostSpecific { - fi, err := os.Stat(hook.Path) - if err != nil { - errs = multierror.Append(errs, fmt.Errorf("cannot find %s hook: %v", hookType, hook.Path)) - } - if fi.Mode()&0111 == 0 { - errs = multierror.Append(errs, fmt.Errorf("the %s hook %v: is not executable", hookType, hook.Path)) - } - } - - for _, env := range hook.Env { - if !envValid(env) { - errs = multierror.Append(errs, fmt.Errorf("env %q for hook %v is in the invalid form", env, hook.Path)) - } - } - } - - return -} - -// CheckProcess checks v.spec.Process -func (v *Validator) CheckProcess() (errs error) { - logrus.Debugf("check process") - - if v.spec.Process == nil { - return - } - - process := v.spec.Process - if !osFilepath.IsAbs(v.platform, process.Cwd) { - errs = multierror.Append(errs, - specerror.NewError( - specerror.ProcCwdAbs, - fmt.Errorf("cwd %q is not an absolute path", process.Cwd), - rspec.Version)) - } - - for _, env := range process.Env { - if !envValid(env) { - errs = multierror.Append(errs, fmt.Errorf("env %q should be in the form of 'key=value'. The left hand side must consist solely of letters, digits, and underscores '_'", env)) - } - } - - if len(process.Args) == 0 { - errs = multierror.Append(errs, - specerror.NewError( - specerror.ProcArgsOneEntryRequired, - fmt.Errorf("args must not be empty"), - rspec.Version)) - } else { - if filepath.IsAbs(process.Args[0]) && v.spec.Root != nil { - var rootfsPath string - if filepath.IsAbs(v.spec.Root.Path) { - rootfsPath = v.spec.Root.Path - } else { - rootfsPath = filepath.Join(v.bundlePath, v.spec.Root.Path) - } - absPath := filepath.Join(rootfsPath, process.Args[0]) - fileinfo, err := os.Stat(absPath) - if os.IsNotExist(err) { - logrus.Warnf("executable %q is not available in rootfs currently", process.Args[0]) - } else if err != nil { - errs = multierror.Append(errs, err) - } else { - m := fileinfo.Mode() - if m.IsDir() || m&0111 == 0 { - errs = multierror.Append(errs, fmt.Errorf("arg %q is not executable", process.Args[0])) - } - } - } - } - - if v.platform == "linux" || v.platform == "solaris" { - errs = multierror.Append(errs, v.CheckRlimits()) - } - - if v.platform == "linux" { - if v.spec.Process.Capabilities != nil { - errs = multierror.Append(errs, v.CheckCapabilities()) - } - - if len(process.ApparmorProfile) > 0 { - profilePath := filepath.Join(v.bundlePath, v.spec.Root.Path, "/etc/apparmor.d", process.ApparmorProfile) - _, err := os.Stat(profilePath) - if err != nil { - errs = multierror.Append(errs, err) - } - } - } - - return -} - -// CheckCapabilities checks v.spec.Process.Capabilities -func (v *Validator) CheckCapabilities() (errs error) { - if v.platform != "linux" { - errs = multierror.Append(errs, fmt.Errorf("For %q platform, the configuration structure does not support process.capabilities", v.platform)) - return - } - - process := v.spec.Process - var effective, permitted, inheritable, ambient bool - caps := make(map[string][]string) - - for _, cap := range process.Capabilities.Bounding { - caps[cap] = append(caps[cap], "bounding") - } - for _, cap := range process.Capabilities.Effective { - caps[cap] = append(caps[cap], "effective") - } - for _, cap := range process.Capabilities.Inheritable { - caps[cap] = append(caps[cap], "inheritable") - } - for _, cap := range process.Capabilities.Permitted { - caps[cap] = append(caps[cap], "permitted") - } - for _, cap := range process.Capabilities.Ambient { - caps[cap] = append(caps[cap], "ambient") - } - - for capability, owns := range caps { - if err := CapValid(capability, v.HostSpecific); err != nil { - errs = multierror.Append(errs, fmt.Errorf("capability %q is not valid, man capabilities(7)", capability)) - } - - effective, permitted, ambient, inheritable = false, false, false, false - for _, set := range owns { - if set == "effective" { - effective = true - continue - } - if set == "inheritable" { - inheritable = true - continue - } - if set == "permitted" { - permitted = true - continue - } - if set == "ambient" { - ambient = true - continue - } - } - if effective && !permitted { - errs = multierror.Append(errs, fmt.Errorf("effective capability %q is not allowed, as it's not permitted", capability)) - } - if ambient && !(permitted && inheritable) { - errs = multierror.Append(errs, fmt.Errorf("ambient capability %q is not allowed, as it's not permitted and inheribate", capability)) - } - } - - return -} - -// CheckRlimits checks v.spec.Process.Rlimits -func (v *Validator) CheckRlimits() (errs error) { - if v.platform != "linux" && v.platform != "solaris" { - errs = multierror.Append(errs, fmt.Errorf("For %q platform, the configuration structure does not support process.rlimits", v.platform)) - return - } - - process := v.spec.Process - for index, rlimit := range process.Rlimits { - for i := index + 1; i < len(process.Rlimits); i++ { - if process.Rlimits[index].Type == process.Rlimits[i].Type { - errs = multierror.Append(errs, - specerror.NewError( - specerror.PosixProcRlimitsErrorOnDup, - fmt.Errorf("rlimit can not contain the same type %q", - process.Rlimits[index].Type), - rspec.Version)) - } - } - errs = multierror.Append(errs, v.rlimitValid(rlimit)) - } - - return -} - -func supportedMountTypes(OS string, hostSpecific bool) (map[string]bool, error) { - supportedTypes := make(map[string]bool) - - if OS != "linux" && OS != "windows" { - logrus.Warnf("%v is not supported to check mount type", OS) - return nil, nil - } else if OS == "windows" { - supportedTypes["ntfs"] = true - return supportedTypes, nil - } - - if hostSpecific { - f, err := os.Open("/proc/filesystems") - if err != nil { - return nil, err - } - defer f.Close() - - s := bufio.NewScanner(f) - for s.Scan() { - if err := s.Err(); err != nil { - return supportedTypes, err - } - - text := s.Text() - parts := strings.Split(text, "\t") - if len(parts) > 1 { - supportedTypes[parts[1]] = true - } else { - supportedTypes[parts[0]] = true - } - } - - supportedTypes["bind"] = true - - return supportedTypes, nil - } - logrus.Warn("Checking linux mount types without --host-specific is not supported yet") - return nil, nil -} - -// CheckMounts checks v.spec.Mounts -func (v *Validator) CheckMounts() (errs error) { - logrus.Debugf("check mounts") - - supportedTypes, err := supportedMountTypes(v.platform, v.HostSpecific) - if err != nil { - errs = multierror.Append(errs, err) - return - } - - for i, mountA := range v.spec.Mounts { - if supportedTypes != nil && !supportedTypes[mountA.Type] { - errs = multierror.Append(errs, fmt.Errorf("unsupported mount type %q", mountA.Type)) - } - if !osFilepath.IsAbs(v.platform, mountA.Destination) { - errs = multierror.Append(errs, - specerror.NewError( - specerror.MountsDestAbs, - fmt.Errorf("mounts[%d].destination %q is not absolute", - i, - mountA.Destination), - rspec.Version)) - } - for j, mountB := range v.spec.Mounts { - if i == j { - continue - } - // whether B.Desination is nested within A.Destination - nested, err := osFilepath.IsAncestor(v.platform, mountA.Destination, mountB.Destination, ".") - if err != nil { - errs = multierror.Append(errs, err) - continue - } - if nested { - if v.platform == "windows" && i < j { - errs = multierror.Append(errs, - specerror.NewError( - specerror.MountsDestOnWindowsNotNested, - fmt.Errorf("on Windows, %v nested within %v is forbidden", - mountB.Destination, mountA.Destination), - rspec.Version)) - } - if i > j { - logrus.Warnf("%v will be covered by %v", mountB.Destination, mountA.Destination) - } - } - } - } - - return -} - -// CheckPlatform checks v.platform -func (v *Validator) CheckPlatform() (errs error) { - logrus.Debugf("check platform") - - if v.platform != "linux" && v.platform != "solaris" && v.platform != "windows" { - errs = multierror.Append(errs, fmt.Errorf("platform %q is not supported", v.platform)) - return - } - - if v.HostSpecific && v.platform != runtime.GOOS { - errs = multierror.Append(errs, fmt.Errorf("platform %q differs from the host %q, skipping host-specific checks", v.platform, runtime.GOOS)) - v.HostSpecific = false - } - - if v.platform == "windows" { - if v.spec.Windows == nil { - errs = multierror.Append(errs, - specerror.NewError( - specerror.PlatformSpecConfOnWindowsSet, - fmt.Errorf("'windows' MUST be set when platform is `windows`"), - rspec.Version)) - } - } - - return -} - -// CheckLinuxResources checks v.spec.Linux.Resources -func (v *Validator) CheckLinuxResources() (errs error) { - logrus.Debugf("check linux resources") - - r := v.spec.Linux.Resources - if r.Memory != nil { - if r.Memory.Limit != nil && r.Memory.Swap != nil && uint64(*r.Memory.Limit) > uint64(*r.Memory.Swap) { - errs = multierror.Append(errs, fmt.Errorf("minimum memoryswap should be larger than memory limit")) - } - if r.Memory.Limit != nil && r.Memory.Reservation != nil && uint64(*r.Memory.Reservation) > uint64(*r.Memory.Limit) { - errs = multierror.Append(errs, fmt.Errorf("minimum memory limit should be larger than memory reservation")) - } - } - if r.Network != nil && v.HostSpecific { - var exist bool - interfaces, err := net.Interfaces() - if err != nil { - errs = multierror.Append(errs, err) - return - } - for _, prio := range r.Network.Priorities { - exist = false - for _, ni := range interfaces { - if prio.Name == ni.Name { - exist = true - break - } - } - if !exist { - errs = multierror.Append(errs, fmt.Errorf("interface %s does not exist currently", prio.Name)) - } - } - } - for index := 0; index < len(r.Devices); index++ { - switch r.Devices[index].Type { - case "a", "b", "c", "": - default: - errs = multierror.Append(errs, fmt.Errorf("type of devices %s is invalid", r.Devices[index].Type)) - } - - access := []byte(r.Devices[index].Access) - for i := 0; i < len(access); i++ { - switch access[i] { - case 'r', 'w', 'm': - default: - errs = multierror.Append(errs, fmt.Errorf("access %s is invalid", r.Devices[index].Access)) - return - } - } - } - - if r.BlockIO != nil && r.BlockIO.WeightDevice != nil { - for i, weightDevice := range r.BlockIO.WeightDevice { - if weightDevice.Weight == nil && weightDevice.LeafWeight == nil { - errs = multierror.Append(errs, - specerror.NewError( - specerror.BlkIOWeightOrLeafWeightExist, - fmt.Errorf("linux.resources.blockIO.weightDevice[%d] specifies neither weight nor leafWeight", i), - rspec.Version)) - } - } - } - - return -} - -// CheckAnnotations checks v.spec.Annotations -func (v *Validator) CheckAnnotations() (errs error) { - logrus.Debugf("check annotations") - - reversedDomain := regexp.MustCompile(`^[A-Za-z]{2,6}(\.[A-Za-z0-9-]{1,63})+$`) - for key := range v.spec.Annotations { - if strings.HasPrefix(key, "org.opencontainers") { - errs = multierror.Append(errs, - specerror.NewError( - specerror.AnnotationsKeyReservedNS, - fmt.Errorf("key %q is reserved", key), - rspec.Version)) - } - - if !reversedDomain.MatchString(key) { - errs = multierror.Append(errs, - specerror.NewError( - specerror.AnnotationsKeyReversedDomain, - fmt.Errorf("key %q SHOULD be named using a reverse domain notation", key), - rspec.Version)) - } - } - - return -} - -// CapValid checks whether a capability is valid -func CapValid(c string, hostSpecific bool) error { - isValid := false - - if !strings.HasPrefix(c, "CAP_") { - return fmt.Errorf("capability %s must start with CAP_", c) - } - for _, cap := range capability.List() { - if c == fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String())) { - if hostSpecific && cap > LastCap() { - return fmt.Errorf("%s is not supported on the current host", c) - } - isValid = true - break - } - } - - if !isValid { - return fmt.Errorf("invalid capability: %s", c) - } - return nil -} - -func envValid(env string) bool { - items := strings.Split(env, "=") - if len(items) < 2 { - return false - } - for i, ch := range strings.TrimSpace(items[0]) { - if !unicode.IsDigit(ch) && !unicode.IsLetter(ch) && ch != '_' { - return false - } - if i == 0 && unicode.IsDigit(ch) { - logrus.Warnf("Env %v: variable name beginning with digit is not recommended.", env) - } - } - return true -} - -func (v *Validator) rlimitValid(rlimit rspec.POSIXRlimit) (errs error) { - if rlimit.Hard < rlimit.Soft { - errs = multierror.Append(errs, fmt.Errorf("hard limit of rlimit %s should not be less than soft limit", rlimit.Type)) - } - - if v.platform == "linux" { - for _, val := range linuxRlimits { - if val == rlimit.Type { - return - } - } - errs = multierror.Append(errs, specerror.NewError(specerror.PosixProcRlimitsTypeValueError, fmt.Errorf("rlimit type %q may not be valid", rlimit.Type), v.spec.Version)) - } else if v.platform == "solaris" { - for _, val := range posixRlimits { - if val == rlimit.Type { - return - } - } - errs = multierror.Append(errs, specerror.NewError(specerror.PosixProcRlimitsTypeValueError, fmt.Errorf("rlimit type %q may not be valid", rlimit.Type), v.spec.Version)) - } else { - logrus.Warnf("process.rlimits validation not yet implemented for platform %q", v.platform) - } - - return -} - -func isStruct(t reflect.Type) bool { - return t.Kind() == reflect.Struct -} - -func isStructPtr(t reflect.Type) bool { - return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct -} - -func checkMandatoryUnit(field reflect.Value, tagField reflect.StructField, parent string) (errs error) { - mandatory := !strings.Contains(tagField.Tag.Get("json"), "omitempty") - switch field.Kind() { - case reflect.Ptr: - if mandatory && field.IsNil() { - errs = multierror.Append(errs, fmt.Errorf("'%s.%s' should not be empty", parent, tagField.Name)) - } - case reflect.String: - if mandatory && (field.Len() == 0) { - errs = multierror.Append(errs, fmt.Errorf("'%s.%s' should not be empty", parent, tagField.Name)) - } - case reflect.Slice: - if mandatory && (field.IsNil() || field.Len() == 0) { - errs = multierror.Append(errs, fmt.Errorf("'%s.%s' should not be empty", parent, tagField.Name)) - return - } - for index := 0; index < field.Len(); index++ { - mValue := field.Index(index) - if mValue.CanInterface() { - errs = multierror.Append(errs, checkMandatory(mValue.Interface())) - } - } - case reflect.Map: - if mandatory && (field.IsNil() || field.Len() == 0) { - errs = multierror.Append(errs, fmt.Errorf("'%s.%s' should not be empty", parent, tagField.Name)) - return - } - keys := field.MapKeys() - for index := 0; index < len(keys); index++ { - mValue := field.MapIndex(keys[index]) - if mValue.CanInterface() { - errs = multierror.Append(errs, checkMandatory(mValue.Interface())) - } - } - default: - } - - return -} - -func checkMandatory(obj interface{}) (errs error) { - objT := reflect.TypeOf(obj) - objV := reflect.ValueOf(obj) - if isStructPtr(objT) { - objT = objT.Elem() - objV = objV.Elem() - } else if !isStruct(objT) { - return - } - - for i := 0; i < objT.NumField(); i++ { - t := objT.Field(i).Type - if isStructPtr(t) && objV.Field(i).IsNil() { - if !strings.Contains(objT.Field(i).Tag.Get("json"), "omitempty") { - errs = multierror.Append(errs, fmt.Errorf("'%s.%s' should not be empty", objT.Name(), objT.Field(i).Name)) - } - } else if (isStruct(t) || isStructPtr(t)) && objV.Field(i).CanInterface() { - errs = multierror.Append(errs, checkMandatory(objV.Field(i).Interface())) - } else { - errs = multierror.Append(errs, checkMandatoryUnit(objV.Field(i), objT.Field(i), objT.Name())) - } - - } - return -} - -// CheckMandatoryFields checks mandatory field of container's config file -func (v *Validator) CheckMandatoryFields() error { - logrus.Debugf("check mandatory fields") - - if v.spec == nil { - return fmt.Errorf("Spec can't be nil") - } - - return checkMandatory(v.spec) -} diff --git a/vendor/github.com/opencontainers/runtime-tools/validate/validate_linux.go b/vendor/github.com/opencontainers/runtime-tools/validate/validate_linux.go deleted file mode 100644 index dcefafae7..000000000 --- a/vendor/github.com/opencontainers/runtime-tools/validate/validate_linux.go +++ /dev/null @@ -1,237 +0,0 @@ -// +build linux - -package validate - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "strings" - "syscall" - - "github.com/syndtr/gocapability/capability" - - multierror "github.com/hashicorp/go-multierror" - rspec "github.com/opencontainers/runtime-spec/specs-go" - osFilepath "github.com/opencontainers/runtime-tools/filepath" - "github.com/opencontainers/runtime-tools/specerror" - "github.com/opencontainers/selinux/go-selinux/label" - "github.com/sirupsen/logrus" -) - -// LastCap return last cap of system -func LastCap() capability.Cap { - last := capability.CAP_LAST_CAP - // hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap - if last == capability.Cap(63) { - last = capability.CAP_BLOCK_SUSPEND - } - - return last -} - -func deviceValid(d rspec.LinuxDevice) bool { - switch d.Type { - case "b", "c", "u": - if d.Major <= 0 || d.Minor <= 0 { - return false - } - case "p": - if d.Major != 0 || d.Minor != 0 { - return false - } - default: - return false - } - return true -} - -// CheckLinux checks v.spec.Linux -func (v *Validator) CheckLinux() (errs error) { - logrus.Debugf("check linux") - - if v.spec.Linux == nil { - return - } - - var nsTypeList = map[rspec.LinuxNamespaceType]struct { - num int - newExist bool - }{ - rspec.PIDNamespace: {0, false}, - rspec.NetworkNamespace: {0, false}, - rspec.MountNamespace: {0, false}, - rspec.IPCNamespace: {0, false}, - rspec.UTSNamespace: {0, false}, - rspec.UserNamespace: {0, false}, - rspec.CgroupNamespace: {0, false}, - } - - for index := 0; index < len(v.spec.Linux.Namespaces); index++ { - ns := v.spec.Linux.Namespaces[index] - if ns.Path != "" && !osFilepath.IsAbs(v.platform, ns.Path) { - errs = multierror.Append(errs, specerror.NewError(specerror.NSPathAbs, fmt.Errorf("namespace.path %q is not an absolute path", ns.Path), rspec.Version)) - } - - tmpItem := nsTypeList[ns.Type] - tmpItem.num = tmpItem.num + 1 - if tmpItem.num > 1 { - errs = multierror.Append(errs, specerror.NewError(specerror.NSErrorOnDup, fmt.Errorf("duplicated namespace %q", ns.Type), rspec.Version)) - } - - if len(ns.Path) == 0 { - tmpItem.newExist = true - } - nsTypeList[ns.Type] = tmpItem - } - - if (len(v.spec.Linux.UIDMappings) > 0 || len(v.spec.Linux.GIDMappings) > 0) && !nsTypeList[rspec.UserNamespace].newExist { - errs = multierror.Append(errs, errors.New("the UID/GID mappings requires a new User namespace to be specified as well")) - } - - for k := range v.spec.Linux.Sysctl { - if strings.HasPrefix(k, "net.") && !nsTypeList[rspec.NetworkNamespace].newExist { - errs = multierror.Append(errs, fmt.Errorf("sysctl %v requires a new Network namespace to be specified as well", k)) - } - if strings.HasPrefix(k, "fs.mqueue.") { - if !nsTypeList[rspec.MountNamespace].newExist || !nsTypeList[rspec.IPCNamespace].newExist { - errs = multierror.Append(errs, fmt.Errorf("sysctl %v requires a new IPC namespace and Mount namespace to be specified as well", k)) - } - } - } - - if v.platform == "linux" && !nsTypeList[rspec.UTSNamespace].newExist && v.spec.Hostname != "" { - errs = multierror.Append(errs, fmt.Errorf("on Linux, hostname requires a new UTS namespace to be specified as well")) - } - - // Linux devices validation - devList := make(map[string]bool) - devTypeList := make(map[string]bool) - for index := 0; index < len(v.spec.Linux.Devices); index++ { - device := v.spec.Linux.Devices[index] - if !deviceValid(device) { - errs = multierror.Append(errs, fmt.Errorf("device %v is invalid", device)) - } - - if _, exists := devList[device.Path]; exists { - errs = multierror.Append(errs, fmt.Errorf("device %s is duplicated", device.Path)) - } else { - var rootfsPath string - if filepath.IsAbs(v.spec.Root.Path) { - rootfsPath = v.spec.Root.Path - } else { - rootfsPath = filepath.Join(v.bundlePath, v.spec.Root.Path) - } - absPath := filepath.Join(rootfsPath, device.Path) - fi, err := os.Stat(absPath) - if os.IsNotExist(err) { - devList[device.Path] = true - } else if err != nil { - errs = multierror.Append(errs, err) - } else { - fStat, ok := fi.Sys().(*syscall.Stat_t) - if !ok { - errs = multierror.Append(errs, specerror.NewError(specerror.DevicesAvailable, - fmt.Errorf("cannot determine state for device %s", device.Path), rspec.Version)) - continue - } - var devType string - switch fStat.Mode & syscall.S_IFMT { - case syscall.S_IFCHR: - devType = "c" - case syscall.S_IFBLK: - devType = "b" - case syscall.S_IFIFO: - devType = "p" - default: - devType = "unmatched" - } - if devType != device.Type || (devType == "c" && device.Type == "u") { - errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch, - fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version)) - continue - } - if devType != "p" { - dev := fStat.Rdev - major := (dev >> 8) & 0xfff - minor := (dev & 0xff) | ((dev >> 12) & 0xfff00) - if int64(major) != device.Major || int64(minor) != device.Minor { - errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch, - fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version)) - continue - } - } - if device.FileMode != nil { - expectedPerm := *device.FileMode & os.ModePerm - actualPerm := fi.Mode() & os.ModePerm - if expectedPerm != actualPerm { - errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch, - fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version)) - continue - } - } - if device.UID != nil { - if *device.UID != fStat.Uid { - errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch, - fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version)) - continue - } - } - if device.GID != nil { - if *device.GID != fStat.Gid { - errs = multierror.Append(errs, specerror.NewError(specerror.DevicesFileNotMatch, - fmt.Errorf("unmatched %s already exists in filesystem", device.Path), rspec.Version)) - continue - } - } - } - } - - // unify u->c when comparing, they are synonyms - var devID string - if device.Type == "u" { - devID = fmt.Sprintf("%s:%d:%d", "c", device.Major, device.Minor) - } else { - devID = fmt.Sprintf("%s:%d:%d", device.Type, device.Major, device.Minor) - } - - if _, exists := devTypeList[devID]; exists { - logrus.Warnf("%v", specerror.NewError(specerror.DevicesErrorOnDup, fmt.Errorf("type:%s, major:%d and minor:%d for linux devices is duplicated", device.Type, device.Major, device.Minor), rspec.Version)) - } else { - devTypeList[devID] = true - } - } - - if v.spec.Linux.Resources != nil { - errs = multierror.Append(errs, v.CheckLinuxResources()) - } - - for _, maskedPath := range v.spec.Linux.MaskedPaths { - if !strings.HasPrefix(maskedPath, "/") { - errs = multierror.Append(errs, - specerror.NewError( - specerror.MaskedPathsAbs, - fmt.Errorf("maskedPath %v is not an absolute path", maskedPath), - rspec.Version)) - } - } - - for _, readonlyPath := range v.spec.Linux.ReadonlyPaths { - if !strings.HasPrefix(readonlyPath, "/") { - errs = multierror.Append(errs, - specerror.NewError( - specerror.ReadonlyPathsAbs, - fmt.Errorf("readonlyPath %v is not an absolute path", readonlyPath), - rspec.Version)) - } - } - - if v.spec.Linux.MountLabel != "" { - if err := label.Validate(v.spec.Linux.MountLabel); err != nil { - errs = multierror.Append(errs, fmt.Errorf("mountLabel %v is invalid", v.spec.Linux.MountLabel)) - } - } - - return -} diff --git a/vendor/github.com/xeipuuv/gojsonpointer/LICENSE-APACHE-2.0.txt b/vendor/github.com/xeipuuv/gojsonpointer/LICENSE-APACHE-2.0.txt deleted file mode 100644 index 55ede8a42..000000000 --- a/vendor/github.com/xeipuuv/gojsonpointer/LICENSE-APACHE-2.0.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2015 xeipuuv - - 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. diff --git a/vendor/github.com/xeipuuv/gojsonpointer/README.md b/vendor/github.com/xeipuuv/gojsonpointer/README.md deleted file mode 100644 index 00059242c..000000000 --- a/vendor/github.com/xeipuuv/gojsonpointer/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# gojsonpointer -An implementation of JSON Pointer - Go language - -## Usage - jsonText := `{ - "name": "Bobby B", - "occupation": { - "title" : "King", - "years" : 15, - "heir" : "Joffrey B" - } - }` - - var jsonDocument map[string]interface{} - json.Unmarshal([]byte(jsonText), &jsonDocument) - - //create a JSON pointer - pointerString := "/occupation/title" - pointer, _ := NewJsonPointer(pointerString) - - //SET a new value for the "title" in the document - pointer.Set(jsonDocument, "Supreme Leader of Westeros") - - //GET the new "title" from the document - title, _, _ := pointer.Get(jsonDocument) - fmt.Println(title) //outputs "Supreme Leader of Westeros" - - //DELETE the "heir" from the document - deletePointer := NewJsonPointer("/occupation/heir") - deletePointer.Delete(jsonDocument) - - b, _ := json.Marshal(jsonDocument) - fmt.Println(string(b)) - //outputs `{"name":"Bobby B","occupation":{"title":"Supreme Leader of Westeros","years":15}}` - - -## References -http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07 - -### Note -The 4.Evaluation part of the previous reference, starting with 'If the currently referenced value is a JSON array, the reference token MUST contain either...' is not implemented. diff --git a/vendor/github.com/xeipuuv/gojsonpointer/pointer.go b/vendor/github.com/xeipuuv/gojsonpointer/pointer.go deleted file mode 100644 index 7faf5d7f9..000000000 --- a/vendor/github.com/xeipuuv/gojsonpointer/pointer.go +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) -// -// 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. - -// author xeipuuv -// author-github https://github.com/xeipuuv -// author-mail xeipuuv@gmail.com -// -// repository-name gojsonpointer -// repository-desc An implementation of JSON Pointer - Go language -// -// description Main and unique file. -// -// created 25-02-2013 - -package gojsonpointer - -import ( - "errors" - "fmt" - "reflect" - "strconv" - "strings" -) - -const ( - const_empty_pointer = `` - const_pointer_separator = `/` - - const_invalid_start = `JSON pointer must be empty or start with a "` + const_pointer_separator + `"` -) - -type implStruct struct { - mode string // "SET" or "GET" - - inDocument interface{} - - setInValue interface{} - - getOutNode interface{} - getOutKind reflect.Kind - outError error -} - -type JsonPointer struct { - referenceTokens []string -} - -// NewJsonPointer parses the given string JSON pointer and returns an object -func NewJsonPointer(jsonPointerString string) (p JsonPointer, err error) { - - // Pointer to the root of the document - if len(jsonPointerString) == 0 { - // Keep referenceTokens nil - return - } - if jsonPointerString[0] != '/' { - return p, errors.New(const_invalid_start) - } - - p.referenceTokens = strings.Split(jsonPointerString[1:], const_pointer_separator) - return -} - -// Uses the pointer to retrieve a value from a JSON document -func (p *JsonPointer) Get(document interface{}) (interface{}, reflect.Kind, error) { - - is := &implStruct{mode: "GET", inDocument: document} - p.implementation(is) - return is.getOutNode, is.getOutKind, is.outError - -} - -// Uses the pointer to update a value from a JSON document -func (p *JsonPointer) Set(document interface{}, value interface{}) (interface{}, error) { - - is := &implStruct{mode: "SET", inDocument: document, setInValue: value} - p.implementation(is) - return document, is.outError - -} - -// Uses the pointer to delete a value from a JSON document -func (p *JsonPointer) Delete(document interface{}) (interface{}, error) { - is := &implStruct{mode: "DEL", inDocument: document} - p.implementation(is) - return document, is.outError -} - -// Both Get and Set functions use the same implementation to avoid code duplication -func (p *JsonPointer) implementation(i *implStruct) { - - kind := reflect.Invalid - - // Full document when empty - if len(p.referenceTokens) == 0 { - i.getOutNode = i.inDocument - i.outError = nil - i.getOutKind = kind - i.outError = nil - return - } - - node := i.inDocument - - previousNodes := make([]interface{}, len(p.referenceTokens)) - previousTokens := make([]string, len(p.referenceTokens)) - - for ti, token := range p.referenceTokens { - - isLastToken := ti == len(p.referenceTokens)-1 - previousNodes[ti] = node - previousTokens[ti] = token - - switch v := node.(type) { - - case map[string]interface{}: - decodedToken := decodeReferenceToken(token) - if _, ok := v[decodedToken]; ok { - node = v[decodedToken] - if isLastToken && i.mode == "SET" { - v[decodedToken] = i.setInValue - } else if isLastToken && i.mode =="DEL" { - delete(v,decodedToken) - } - } else if (isLastToken && i.mode == "SET") { - v[decodedToken] = i.setInValue - } else { - i.outError = fmt.Errorf("Object has no key '%s'", decodedToken) - i.getOutKind = reflect.Map - i.getOutNode = nil - return - } - - case []interface{}: - tokenIndex, err := strconv.Atoi(token) - if err != nil { - i.outError = fmt.Errorf("Invalid array index '%s'", token) - i.getOutKind = reflect.Slice - i.getOutNode = nil - return - } - if tokenIndex < 0 || tokenIndex >= len(v) { - i.outError = fmt.Errorf("Out of bound array[0,%d] index '%d'", len(v), tokenIndex) - i.getOutKind = reflect.Slice - i.getOutNode = nil - return - } - - node = v[tokenIndex] - if isLastToken && i.mode == "SET" { - v[tokenIndex] = i.setInValue - } else if isLastToken && i.mode =="DEL" { - v[tokenIndex] = v[len(v)-1] - v[len(v)-1] = nil - v = v[:len(v)-1] - previousNodes[ti-1].(map[string]interface{})[previousTokens[ti-1]] = v - } - - default: - i.outError = fmt.Errorf("Invalid token reference '%s'", token) - i.getOutKind = reflect.ValueOf(node).Kind() - i.getOutNode = nil - return - } - - } - - i.getOutNode = node - i.getOutKind = reflect.ValueOf(node).Kind() - i.outError = nil -} - -// Pointer to string representation function -func (p *JsonPointer) String() string { - - if len(p.referenceTokens) == 0 { - return const_empty_pointer - } - - pointerString := const_pointer_separator + strings.Join(p.referenceTokens, const_pointer_separator) - - return pointerString -} - -// Specific JSON pointer encoding here -// ~0 => ~ -// ~1 => / -// ... and vice versa - -func decodeReferenceToken(token string) string { - step1 := strings.Replace(token, `~1`, `/`, -1) - step2 := strings.Replace(step1, `~0`, `~`, -1) - return step2 -} - -func encodeReferenceToken(token string) string { - step1 := strings.Replace(token, `~`, `~0`, -1) - step2 := strings.Replace(step1, `/`, `~1`, -1) - return step2 -} diff --git a/vendor/github.com/xeipuuv/gojsonreference/LICENSE-APACHE-2.0.txt b/vendor/github.com/xeipuuv/gojsonreference/LICENSE-APACHE-2.0.txt deleted file mode 100644 index 55ede8a42..000000000 --- a/vendor/github.com/xeipuuv/gojsonreference/LICENSE-APACHE-2.0.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2015 xeipuuv - - 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. diff --git a/vendor/github.com/xeipuuv/gojsonreference/README.md b/vendor/github.com/xeipuuv/gojsonreference/README.md deleted file mode 100644 index 9ab6e1eb1..000000000 --- a/vendor/github.com/xeipuuv/gojsonreference/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# gojsonreference -An implementation of JSON Reference - Go language - -## Dependencies -https://github.com/xeipuuv/gojsonpointer - -## References -http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07 - -http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03 diff --git a/vendor/github.com/xeipuuv/gojsonreference/reference.go b/vendor/github.com/xeipuuv/gojsonreference/reference.go deleted file mode 100644 index 645729130..000000000 --- a/vendor/github.com/xeipuuv/gojsonreference/reference.go +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) -// -// 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. - -// author xeipuuv -// author-github https://github.com/xeipuuv -// author-mail xeipuuv@gmail.com -// -// repository-name gojsonreference -// repository-desc An implementation of JSON Reference - Go language -// -// description Main and unique file. -// -// created 26-02-2013 - -package gojsonreference - -import ( - "errors" - "net/url" - "path/filepath" - "runtime" - "strings" - - "github.com/xeipuuv/gojsonpointer" -) - -const ( - const_fragment_char = `#` -) - -func NewJsonReference(jsonReferenceString string) (JsonReference, error) { - - var r JsonReference - err := r.parse(jsonReferenceString) - return r, err - -} - -type JsonReference struct { - referenceUrl *url.URL - referencePointer gojsonpointer.JsonPointer - - HasFullUrl bool - HasUrlPathOnly bool - HasFragmentOnly bool - HasFileScheme bool - HasFullFilePath bool -} - -func (r *JsonReference) GetUrl() *url.URL { - return r.referenceUrl -} - -func (r *JsonReference) GetPointer() *gojsonpointer.JsonPointer { - return &r.referencePointer -} - -func (r *JsonReference) String() string { - - if r.referenceUrl != nil { - return r.referenceUrl.String() - } - - if r.HasFragmentOnly { - return const_fragment_char + r.referencePointer.String() - } - - return r.referencePointer.String() -} - -func (r *JsonReference) IsCanonical() bool { - return (r.HasFileScheme && r.HasFullFilePath) || (!r.HasFileScheme && r.HasFullUrl) -} - -// "Constructor", parses the given string JSON reference -func (r *JsonReference) parse(jsonReferenceString string) (err error) { - - r.referenceUrl, err = url.Parse(jsonReferenceString) - if err != nil { - return - } - refUrl := r.referenceUrl - - if refUrl.Scheme != "" && refUrl.Host != "" { - r.HasFullUrl = true - } else { - if refUrl.Path != "" { - r.HasUrlPathOnly = true - } else if refUrl.RawQuery == "" && refUrl.Fragment != "" { - r.HasFragmentOnly = true - } - } - - r.HasFileScheme = refUrl.Scheme == "file" - if runtime.GOOS == "windows" { - // on Windows, a file URL may have an extra leading slash, and if it - // doesn't then its first component will be treated as the host by the - // Go runtime - if refUrl.Host == "" && strings.HasPrefix(refUrl.Path, "/") { - r.HasFullFilePath = filepath.IsAbs(refUrl.Path[1:]) - } else { - r.HasFullFilePath = filepath.IsAbs(refUrl.Host + refUrl.Path) - } - } else { - r.HasFullFilePath = filepath.IsAbs(refUrl.Path) - } - - // invalid json-pointer error means url has no json-pointer fragment. simply ignore error - r.referencePointer, _ = gojsonpointer.NewJsonPointer(refUrl.Fragment) - - return -} - -// Creates a new reference from a parent and a child -// If the child cannot inherit from the parent, an error is returned -func (r *JsonReference) Inherits(child JsonReference) (*JsonReference, error) { - if child.GetUrl() == nil { - return nil, errors.New("childUrl is nil!") - } - - if r.GetUrl() == nil { - return nil, errors.New("parentUrl is nil!") - } - - // Get a copy of the parent url to make sure we do not modify the original. - // URL reference resolving fails if the fragment of the child is empty, but the parent's is not. - // The fragment of the child must be used, so the fragment of the parent is manually removed. - parentUrl := *r.GetUrl() - parentUrl.Fragment = "" - - ref, err := NewJsonReference(parentUrl.ResolveReference(child.GetUrl()).String()) - if err != nil { - return nil, err - } - return &ref, err -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/.gitignore b/vendor/github.com/xeipuuv/gojsonschema/.gitignore deleted file mode 100644 index 68e993ce3..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.sw[nop] -*.iml -.vscode/ diff --git a/vendor/github.com/xeipuuv/gojsonschema/.travis.yml b/vendor/github.com/xeipuuv/gojsonschema/.travis.yml deleted file mode 100644 index 3289001cd..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go -go: - - "1.11" - - "1.12" - - "1.13" -before_install: - - go get github.com/xeipuuv/gojsonreference - - go get github.com/xeipuuv/gojsonpointer - - go get github.com/stretchr/testify/assert diff --git a/vendor/github.com/xeipuuv/gojsonschema/LICENSE-APACHE-2.0.txt b/vendor/github.com/xeipuuv/gojsonschema/LICENSE-APACHE-2.0.txt deleted file mode 100644 index 55ede8a42..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/LICENSE-APACHE-2.0.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2015 xeipuuv - - 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. diff --git a/vendor/github.com/xeipuuv/gojsonschema/README.md b/vendor/github.com/xeipuuv/gojsonschema/README.md deleted file mode 100644 index 758f26df0..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/README.md +++ /dev/null @@ -1,466 +0,0 @@ -[![GoDoc](https://godoc.org/github.com/xeipuuv/gojsonschema?status.svg)](https://godoc.org/github.com/xeipuuv/gojsonschema) -[![Build Status](https://travis-ci.org/xeipuuv/gojsonschema.svg)](https://travis-ci.org/xeipuuv/gojsonschema) -[![Go Report Card](https://goreportcard.com/badge/github.com/xeipuuv/gojsonschema)](https://goreportcard.com/report/github.com/xeipuuv/gojsonschema) - -# gojsonschema - -## Description - -An implementation of JSON Schema for the Go programming language. Supports draft-04, draft-06 and draft-07. - -References : - -* http://json-schema.org -* http://json-schema.org/latest/json-schema-core.html -* http://json-schema.org/latest/json-schema-validation.html - -## Installation - -``` -go get github.com/xeipuuv/gojsonschema -``` - -Dependencies : -* [github.com/xeipuuv/gojsonpointer](https://github.com/xeipuuv/gojsonpointer) -* [github.com/xeipuuv/gojsonreference](https://github.com/xeipuuv/gojsonreference) -* [github.com/stretchr/testify/assert](https://github.com/stretchr/testify#assert-package) - -## Usage - -### Example - -```go - -package main - -import ( - "fmt" - "github.com/xeipuuv/gojsonschema" -) - -func main() { - - schemaLoader := gojsonschema.NewReferenceLoader("file:///home/me/schema.json") - documentLoader := gojsonschema.NewReferenceLoader("file:///home/me/document.json") - - result, err := gojsonschema.Validate(schemaLoader, documentLoader) - if err != nil { - panic(err.Error()) - } - - if result.Valid() { - fmt.Printf("The document is valid\n") - } else { - fmt.Printf("The document is not valid. see errors :\n") - for _, desc := range result.Errors() { - fmt.Printf("- %s\n", desc) - } - } -} - - -``` - -#### Loaders - -There are various ways to load your JSON data. -In order to load your schemas and documents, -first declare an appropriate loader : - -* Web / HTTP, using a reference : - -```go -loader := gojsonschema.NewReferenceLoader("http://www.some_host.com/schema.json") -``` - -* Local file, using a reference : - -```go -loader := gojsonschema.NewReferenceLoader("file:///home/me/schema.json") -``` - -References use the URI scheme, the prefix (file://) and a full path to the file are required. - -* JSON strings : - -```go -loader := gojsonschema.NewStringLoader(`{"type": "string"}`) -``` - -* Custom Go types : - -```go -m := map[string]interface{}{"type": "string"} -loader := gojsonschema.NewGoLoader(m) -``` - -And - -```go -type Root struct { - Users []User `json:"users"` -} - -type User struct { - Name string `json:"name"` -} - -... - -data := Root{} -data.Users = append(data.Users, User{"John"}) -data.Users = append(data.Users, User{"Sophia"}) -data.Users = append(data.Users, User{"Bill"}) - -loader := gojsonschema.NewGoLoader(data) -``` - -#### Validation - -Once the loaders are set, validation is easy : - -```go -result, err := gojsonschema.Validate(schemaLoader, documentLoader) -``` - -Alternatively, you might want to load a schema only once and process to multiple validations : - -```go -schema, err := gojsonschema.NewSchema(schemaLoader) -... -result1, err := schema.Validate(documentLoader1) -... -result2, err := schema.Validate(documentLoader2) -... -// etc ... -``` - -To check the result : - -```go - if result.Valid() { - fmt.Printf("The document is valid\n") - } else { - fmt.Printf("The document is not valid. see errors :\n") - for _, err := range result.Errors() { - // Err implements the ResultError interface - fmt.Printf("- %s\n", err) - } - } -``` - - -## Loading local schemas - -By default `file` and `http(s)` references to external schemas are loaded automatically via the file system or via http(s). An external schema can also be loaded using a `SchemaLoader`. - -```go - sl := gojsonschema.NewSchemaLoader() - loader1 := gojsonschema.NewStringLoader(`{ "type" : "string" }`) - err := sl.AddSchema("http://some_host.com/string.json", loader1) -``` - -Alternatively if your schema already has an `$id` you can use the `AddSchemas` function -```go - loader2 := gojsonschema.NewStringLoader(`{ - "$id" : "http://some_host.com/maxlength.json", - "maxLength" : 5 - }`) - err = sl.AddSchemas(loader2) -``` - -The main schema should be passed to the `Compile` function. This main schema can then directly reference the added schemas without needing to download them. -```go - loader3 := gojsonschema.NewStringLoader(`{ - "$id" : "http://some_host.com/main.json", - "allOf" : [ - { "$ref" : "http://some_host.com/string.json" }, - { "$ref" : "http://some_host.com/maxlength.json" } - ] - }`) - - schema, err := sl.Compile(loader3) - - documentLoader := gojsonschema.NewStringLoader(`"hello world"`) - - result, err := schema.Validate(documentLoader) -``` - -It's also possible to pass a `ReferenceLoader` to the `Compile` function that references a loaded schema. - -```go -err = sl.AddSchemas(loader3) -schema, err := sl.Compile(gojsonschema.NewReferenceLoader("http://some_host.com/main.json")) -``` - -Schemas added by `AddSchema` and `AddSchemas` are only validated when the entire schema is compiled, unless meta-schema validation is used. - -## Using a specific draft -By default `gojsonschema` will try to detect the draft of a schema by using the `$schema` keyword and parse it in a strict draft-04, draft-06 or draft-07 mode. If `$schema` is missing, or the draft version is not explicitely set, a hybrid mode is used which merges together functionality of all drafts into one mode. - -Autodectection can be turned off with the `AutoDetect` property. Specific draft versions can be specified with the `Draft` property. - -```go -sl := gojsonschema.NewSchemaLoader() -sl.Draft = gojsonschema.Draft7 -sl.AutoDetect = false -``` - -If autodetection is on (default), a draft-07 schema can savely reference draft-04 schemas and vice-versa, as long as `$schema` is specified in all schemas. - -## Meta-schema validation -Schemas that are added using the `AddSchema`, `AddSchemas` and `Compile` can be validated against their meta-schema by setting the `Validate` property. - -The following example will produce an error as `multipleOf` must be a number. If `Validate` is off (default), this error is only returned at the `Compile` step. - -```go -sl := gojsonschema.NewSchemaLoader() -sl.Validate = true -err := sl.AddSchemas(gojsonschema.NewStringLoader(`{ - $id" : "http://some_host.com/invalid.json", - "$schema": "http://json-schema.org/draft-07/schema#", - "multipleOf" : true -}`)) - ``` -``` - ``` - -Errors returned by meta-schema validation are more readable and contain more information, which helps significantly if you are developing a schema. - -Meta-schema validation also works with a custom `$schema`. In case `$schema` is missing, or `AutoDetect` is set to `false`, the meta-schema of the used draft is used. - - -## Working with Errors - -The library handles string error codes which you can customize by creating your own gojsonschema.locale and setting it -```go -gojsonschema.Locale = YourCustomLocale{} -``` - -However, each error contains additional contextual information. - -Newer versions of `gojsonschema` may have new additional errors, so code that uses a custom locale will need to be updated when this happens. - -**err.Type()**: *string* Returns the "type" of error that occurred. Note you can also type check. See below - -Note: An error of RequiredType has an err.Type() return value of "required" - - "required": RequiredError - "invalid_type": InvalidTypeError - "number_any_of": NumberAnyOfError - "number_one_of": NumberOneOfError - "number_all_of": NumberAllOfError - "number_not": NumberNotError - "missing_dependency": MissingDependencyError - "internal": InternalError - "const": ConstEror - "enum": EnumError - "array_no_additional_items": ArrayNoAdditionalItemsError - "array_min_items": ArrayMinItemsError - "array_max_items": ArrayMaxItemsError - "unique": ItemsMustBeUniqueError - "contains" : ArrayContainsError - "array_min_properties": ArrayMinPropertiesError - "array_max_properties": ArrayMaxPropertiesError - "additional_property_not_allowed": AdditionalPropertyNotAllowedError - "invalid_property_pattern": InvalidPropertyPatternError - "invalid_property_name": InvalidPropertyNameError - "string_gte": StringLengthGTEError - "string_lte": StringLengthLTEError - "pattern": DoesNotMatchPatternError - "multiple_of": MultipleOfError - "number_gte": NumberGTEError - "number_gt": NumberGTError - "number_lte": NumberLTEError - "number_lt": NumberLTError - "condition_then" : ConditionThenError - "condition_else" : ConditionElseError - -**err.Value()**: *interface{}* Returns the value given - -**err.Context()**: *gojsonschema.JsonContext* Returns the context. This has a String() method that will print something like this: (root).firstName - -**err.Field()**: *string* Returns the fieldname in the format firstName, or for embedded properties, person.firstName. This returns the same as the String() method on *err.Context()* but removes the (root). prefix. - -**err.Description()**: *string* The error description. This is based on the locale you are using. See the beginning of this section for overwriting the locale with a custom implementation. - -**err.DescriptionFormat()**: *string* The error description format. This is relevant if you are adding custom validation errors afterwards to the result. - -**err.Details()**: *gojsonschema.ErrorDetails* Returns a map[string]interface{} of additional error details specific to the error. For example, GTE errors will have a "min" value, LTE will have a "max" value. See errors.go for a full description of all the error details. Every error always contains a "field" key that holds the value of *err.Field()* - -Note in most cases, the err.Details() will be used to generate replacement strings in your locales, and not used directly. These strings follow the text/template format i.e. -``` -{{.field}} must be greater than or equal to {{.min}} -``` - -The library allows you to specify custom template functions, should you require more complex error message handling. -```go -gojsonschema.ErrorTemplateFuncs = map[string]interface{}{ - "allcaps": func(s string) string { - return strings.ToUpper(s) - }, -} -``` - -Given the above definition, you can use the custom function `"allcaps"` in your localization templates: -``` -{{allcaps .field}} must be greater than or equal to {{.min}} -``` - -The above error message would then be rendered with the `field` value in capital letters. For example: -``` -"PASSWORD must be greater than or equal to 8" -``` - -Learn more about what types of template functions you can use in `ErrorTemplateFuncs` by referring to Go's [text/template FuncMap](https://golang.org/pkg/text/template/#FuncMap) type. - -## Formats -JSON Schema allows for optional "format" property to validate instances against well-known formats. gojsonschema ships with all of the formats defined in the spec that you can use like this: - -````json -{"type": "string", "format": "email"} -```` - -Not all formats defined in draft-07 are available. Implemented formats are: - -* `date` -* `time` -* `date-time` -* `hostname`. Subdomains that start with a number are also supported, but this means that it doesn't strictly follow [RFC1034](http://tools.ietf.org/html/rfc1034#section-3.5) and has the implication that ipv4 addresses are also recognized as valid hostnames. -* `email`. Go's email parser deviates slightly from [RFC5322](https://tools.ietf.org/html/rfc5322). Includes unicode support. -* `idn-email`. Same caveat as `email`. -* `ipv4` -* `ipv6` -* `uri`. Includes unicode support. -* `uri-reference`. Includes unicode support. -* `iri` -* `iri-reference` -* `uri-template` -* `uuid` -* `regex`. Go uses the [RE2](https://github.com/google/re2/wiki/Syntax) engine and is not [ECMA262](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf) compatible. -* `json-pointer` -* `relative-json-pointer` - -`email`, `uri` and `uri-reference` use the same validation code as their unicode counterparts `idn-email`, `iri` and `iri-reference`. If you rely on unicode support you should use the specific -unicode enabled formats for the sake of interoperability as other implementations might not support unicode in the regular formats. - -The validation code for `uri`, `idn-email` and their relatives use mostly standard library code. - -For repetitive or more complex formats, you can create custom format checkers and add them to gojsonschema like this: - -```go -// Define the format checker -type RoleFormatChecker struct {} - -// Ensure it meets the gojsonschema.FormatChecker interface -func (f RoleFormatChecker) IsFormat(input interface{}) bool { - - asString, ok := input.(string) - if ok == false { - return false - } - - return strings.HasPrefix("ROLE_", asString) -} - -// Add it to the library -gojsonschema.FormatCheckers.Add("role", RoleFormatChecker{}) -```` - -Now to use in your json schema: -````json -{"type": "string", "format": "role"} -```` - -Another example would be to check if the provided integer matches an id on database: - -JSON schema: -```json -{"type": "integer", "format": "ValidUserId"} -``` - -```go -// Define the format checker -type ValidUserIdFormatChecker struct {} - -// Ensure it meets the gojsonschema.FormatChecker interface -func (f ValidUserIdFormatChecker) IsFormat(input interface{}) bool { - - asFloat64, ok := input.(float64) // Numbers are always float64 here - if ok == false { - return false - } - - // XXX - // do the magic on the database looking for the int(asFloat64) - - return true -} - -// Add it to the library -gojsonschema.FormatCheckers.Add("ValidUserId", ValidUserIdFormatChecker{}) -```` - -Formats can also be removed, for example if you want to override one of the formats that is defined by default. - -```go -gojsonschema.FormatCheckers.Remove("hostname") -``` - - -## Additional custom validation -After the validation has run and you have the results, you may add additional -errors using `Result.AddError`. This is useful to maintain the same format within the resultset instead -of having to add special exceptions for your own errors. Below is an example. - -```go -type AnswerInvalidError struct { - gojsonschema.ResultErrorFields -} - -func newAnswerInvalidError(context *gojsonschema.JsonContext, value interface{}, details gojsonschema.ErrorDetails) *AnswerInvalidError { - err := AnswerInvalidError{} - err.SetContext(context) - err.SetType("custom_invalid_error") - // it is important to use SetDescriptionFormat() as this is used to call SetDescription() after it has been parsed - // using the description of err will be overridden by this. - err.SetDescriptionFormat("Answer to the Ultimate Question of Life, the Universe, and Everything is {{.answer}}") - err.SetValue(value) - err.SetDetails(details) - - return &err -} - -func main() { - // ... - schema, err := gojsonschema.NewSchema(schemaLoader) - result, err := gojsonschema.Validate(schemaLoader, documentLoader) - - if true { // some validation - jsonContext := gojsonschema.NewJsonContext("question", nil) - errDetail := gojsonschema.ErrorDetails{ - "answer": 42, - } - result.AddError( - newAnswerInvalidError( - gojsonschema.NewJsonContext("answer", jsonContext), - 52, - errDetail, - ), - errDetail, - ) - } - - return result, err - -} -``` - -This is especially useful if you want to add validation beyond what the -json schema drafts can provide such business specific logic. - -## Uses - -gojsonschema uses the following test suite : - -https://github.com/json-schema/JSON-Schema-Test-Suite diff --git a/vendor/github.com/xeipuuv/gojsonschema/draft.go b/vendor/github.com/xeipuuv/gojsonschema/draft.go deleted file mode 100644 index 61298e7aa..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/draft.go +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2018 johandorland ( https://github.com/johandorland ) -// -// 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 gojsonschema - -import ( - "errors" - "math" - "reflect" - - "github.com/xeipuuv/gojsonreference" -) - -// Draft is a JSON-schema draft version -type Draft int - -// Supported Draft versions -const ( - Draft4 Draft = 4 - Draft6 Draft = 6 - Draft7 Draft = 7 - Hybrid Draft = math.MaxInt32 -) - -type draftConfig struct { - Version Draft - MetaSchemaURL string - MetaSchema string -} -type draftConfigs []draftConfig - -var drafts draftConfigs - -func init() { - drafts = []draftConfig{ - { - Version: Draft4, - MetaSchemaURL: "http://json-schema.org/draft-04/schema", - MetaSchema: `{"id":"http://json-schema.org/draft-04/schema#","$schema":"http://json-schema.org/draft-04/schema#","description":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"positiveInteger":{"type":"integer","minimum":0},"positiveIntegerDefault0":{"allOf":[{"$ref":"#/definitions/positiveInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"minItems":1,"uniqueItems":true}},"type":"object","properties":{"id":{"type":"string"},"$schema":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"default":{},"multipleOf":{"type":"number","minimum":0,"exclusiveMinimum":true},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"boolean","default":false},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"boolean","default":false},"maxLength":{"$ref":"#/definitions/positiveInteger"},"minLength":{"$ref":"#/definitions/positiveIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"anyOf":[{"type":"boolean"},{"$ref":"#"}],"default":{}},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":{}},"maxItems":{"$ref":"#/definitions/positiveInteger"},"minItems":{"$ref":"#/definitions/positiveIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"maxProperties":{"$ref":"#/definitions/positiveInteger"},"minProperties":{"$ref":"#/definitions/positiveIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"anyOf":[{"type":"boolean"},{"$ref":"#"}],"default":{}},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"enum":{"type":"array","minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"dependencies":{"exclusiveMaximum":["maximum"],"exclusiveMinimum":["minimum"]},"default":{}}`, - }, - { - Version: Draft6, - MetaSchemaURL: "http://json-schema.org/draft-06/schema", - MetaSchema: `{"$schema":"http://json-schema.org/draft-06/schema#","$id":"http://json-schema.org/draft-06/schema#","title":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"nonNegativeInteger":{"type":"integer","minimum":0},"nonNegativeIntegerDefault0":{"allOf":[{"$ref":"#/definitions/nonNegativeInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"uniqueItems":true,"default":[]}},"type":["object","boolean"],"properties":{"$id":{"type":"string","format":"uri-reference"},"$schema":{"type":"string","format":"uri"},"$ref":{"type":"string","format":"uri-reference"},"title":{"type":"string"},"description":{"type":"string"},"default":{},"examples":{"type":"array","items":{}},"multipleOf":{"type":"number","exclusiveMinimum":0},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"number"},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"number"},"maxLength":{"$ref":"#/definitions/nonNegativeInteger"},"minLength":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"$ref":"#"},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":{}},"maxItems":{"$ref":"#/definitions/nonNegativeInteger"},"minItems":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"contains":{"$ref":"#"},"maxProperties":{"$ref":"#/definitions/nonNegativeInteger"},"minProperties":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"$ref":"#"},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"propertyNames":{"$ref":"#"},"const":{},"enum":{"type":"array","minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"default":{}}`, - }, - { - Version: Draft7, - MetaSchemaURL: "http://json-schema.org/draft-07/schema", - MetaSchema: `{"$schema":"http://json-schema.org/draft-07/schema#","$id":"http://json-schema.org/draft-07/schema#","title":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"nonNegativeInteger":{"type":"integer","minimum":0},"nonNegativeIntegerDefault0":{"allOf":[{"$ref":"#/definitions/nonNegativeInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"uniqueItems":true,"default":[]}},"type":["object","boolean"],"properties":{"$id":{"type":"string","format":"uri-reference"},"$schema":{"type":"string","format":"uri"},"$ref":{"type":"string","format":"uri-reference"},"$comment":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"default":true,"readOnly":{"type":"boolean","default":false},"examples":{"type":"array","items":true},"multipleOf":{"type":"number","exclusiveMinimum":0},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"number"},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"number"},"maxLength":{"$ref":"#/definitions/nonNegativeInteger"},"minLength":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"$ref":"#"},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":true},"maxItems":{"$ref":"#/definitions/nonNegativeInteger"},"minItems":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"contains":{"$ref":"#"},"maxProperties":{"$ref":"#/definitions/nonNegativeInteger"},"minProperties":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"$ref":"#"},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"propertyNames":{"format":"regex"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"propertyNames":{"$ref":"#"},"const":true,"enum":{"type":"array","items":true,"minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"contentMediaType":{"type":"string"},"contentEncoding":{"type":"string"},"if":{"$ref":"#"},"then":{"$ref":"#"},"else":{"$ref":"#"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"default":true}`, - }, - } -} - -func (dc draftConfigs) GetMetaSchema(url string) string { - for _, config := range dc { - if config.MetaSchemaURL == url { - return config.MetaSchema - } - } - return "" -} -func (dc draftConfigs) GetDraftVersion(url string) *Draft { - for _, config := range dc { - if config.MetaSchemaURL == url { - return &config.Version - } - } - return nil -} -func (dc draftConfigs) GetSchemaURL(draft Draft) string { - for _, config := range dc { - if config.Version == draft { - return config.MetaSchemaURL - } - } - return "" -} - -func parseSchemaURL(documentNode interface{}) (string, *Draft, error) { - - if isKind(documentNode, reflect.Bool) { - return "", nil, nil - } - - if !isKind(documentNode, reflect.Map) { - return "", nil, errors.New("schema is invalid") - } - - m := documentNode.(map[string]interface{}) - - if existsMapKey(m, KEY_SCHEMA) { - if !isKind(m[KEY_SCHEMA], reflect.String) { - return "", nil, errors.New(formatErrorDescription( - Locale.MustBeOfType(), - ErrorDetails{ - "key": KEY_SCHEMA, - "type": TYPE_STRING, - }, - )) - } - - schemaReference, err := gojsonreference.NewJsonReference(m[KEY_SCHEMA].(string)) - - if err != nil { - return "", nil, err - } - - schema := schemaReference.String() - - return schema, drafts.GetDraftVersion(schema), nil - } - - return "", nil, nil -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/errors.go b/vendor/github.com/xeipuuv/gojsonschema/errors.go deleted file mode 100644 index e4e9814f3..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/errors.go +++ /dev/null @@ -1,364 +0,0 @@ -package gojsonschema - -import ( - "bytes" - "sync" - "text/template" -) - -var errorTemplates = errorTemplate{template.New("errors-new"), sync.RWMutex{}} - -// template.Template is not thread-safe for writing, so some locking is done -// sync.RWMutex is used for efficiently locking when new templates are created -type errorTemplate struct { - *template.Template - sync.RWMutex -} - -type ( - - // FalseError. ErrorDetails: - - FalseError struct { - ResultErrorFields - } - - // RequiredError indicates that a required field is missing - // ErrorDetails: property string - RequiredError struct { - ResultErrorFields - } - - // InvalidTypeError indicates that a field has the incorrect type - // ErrorDetails: expected, given - InvalidTypeError struct { - ResultErrorFields - } - - // NumberAnyOfError is produced in case of a failing "anyOf" validation - // ErrorDetails: - - NumberAnyOfError struct { - ResultErrorFields - } - - // NumberOneOfError is produced in case of a failing "oneOf" validation - // ErrorDetails: - - NumberOneOfError struct { - ResultErrorFields - } - - // NumberAllOfError is produced in case of a failing "allOf" validation - // ErrorDetails: - - NumberAllOfError struct { - ResultErrorFields - } - - // NumberNotError is produced if a "not" validation failed - // ErrorDetails: - - NumberNotError struct { - ResultErrorFields - } - - // MissingDependencyError is produced in case of a "missing dependency" problem - // ErrorDetails: dependency - MissingDependencyError struct { - ResultErrorFields - } - - // InternalError indicates an internal error - // ErrorDetails: error - InternalError struct { - ResultErrorFields - } - - // ConstError indicates a const error - // ErrorDetails: allowed - ConstError struct { - ResultErrorFields - } - - // EnumError indicates an enum error - // ErrorDetails: allowed - EnumError struct { - ResultErrorFields - } - - // ArrayNoAdditionalItemsError is produced if additional items were found, but not allowed - // ErrorDetails: - - ArrayNoAdditionalItemsError struct { - ResultErrorFields - } - - // ArrayMinItemsError is produced if an array contains less items than the allowed minimum - // ErrorDetails: min - ArrayMinItemsError struct { - ResultErrorFields - } - - // ArrayMaxItemsError is produced if an array contains more items than the allowed maximum - // ErrorDetails: max - ArrayMaxItemsError struct { - ResultErrorFields - } - - // ItemsMustBeUniqueError is produced if an array requires unique items, but contains non-unique items - // ErrorDetails: type, i, j - ItemsMustBeUniqueError struct { - ResultErrorFields - } - - // ArrayContainsError is produced if an array contains invalid items - // ErrorDetails: - ArrayContainsError struct { - ResultErrorFields - } - - // ArrayMinPropertiesError is produced if an object contains less properties than the allowed minimum - // ErrorDetails: min - ArrayMinPropertiesError struct { - ResultErrorFields - } - - // ArrayMaxPropertiesError is produced if an object contains more properties than the allowed maximum - // ErrorDetails: max - ArrayMaxPropertiesError struct { - ResultErrorFields - } - - // AdditionalPropertyNotAllowedError is produced if an object has additional properties, but not allowed - // ErrorDetails: property - AdditionalPropertyNotAllowedError struct { - ResultErrorFields - } - - // InvalidPropertyPatternError is produced if an pattern was found - // ErrorDetails: property, pattern - InvalidPropertyPatternError struct { - ResultErrorFields - } - - // InvalidPropertyNameError is produced if an invalid-named property was found - // ErrorDetails: property - InvalidPropertyNameError struct { - ResultErrorFields - } - - // StringLengthGTEError is produced if a string is shorter than the minimum required length - // ErrorDetails: min - StringLengthGTEError struct { - ResultErrorFields - } - - // StringLengthLTEError is produced if a string is longer than the maximum allowed length - // ErrorDetails: max - StringLengthLTEError struct { - ResultErrorFields - } - - // DoesNotMatchPatternError is produced if a string does not match the defined pattern - // ErrorDetails: pattern - DoesNotMatchPatternError struct { - ResultErrorFields - } - - // DoesNotMatchFormatError is produced if a string does not match the defined format - // ErrorDetails: format - DoesNotMatchFormatError struct { - ResultErrorFields - } - - // MultipleOfError is produced if a number is not a multiple of the defined multipleOf - // ErrorDetails: multiple - MultipleOfError struct { - ResultErrorFields - } - - // NumberGTEError is produced if a number is lower than the allowed minimum - // ErrorDetails: min - NumberGTEError struct { - ResultErrorFields - } - - // NumberGTError is produced if a number is lower than, or equal to the specified minimum, and exclusiveMinimum is set - // ErrorDetails: min - NumberGTError struct { - ResultErrorFields - } - - // NumberLTEError is produced if a number is higher than the allowed maximum - // ErrorDetails: max - NumberLTEError struct { - ResultErrorFields - } - - // NumberLTError is produced if a number is higher than, or equal to the specified maximum, and exclusiveMaximum is set - // ErrorDetails: max - NumberLTError struct { - ResultErrorFields - } - - // ConditionThenError is produced if a condition's "then" validation is invalid - // ErrorDetails: - - ConditionThenError struct { - ResultErrorFields - } - - // ConditionElseError is produced if a condition's "else" condition is invalid - // ErrorDetails: - - ConditionElseError struct { - ResultErrorFields - } -) - -// newError takes a ResultError type and sets the type, context, description, details, value, and field -func newError(err ResultError, context *JsonContext, value interface{}, locale locale, details ErrorDetails) { - var t string - var d string - switch err.(type) { - case *FalseError: - t = "false" - d = locale.False() - case *RequiredError: - t = "required" - d = locale.Required() - case *InvalidTypeError: - t = "invalid_type" - d = locale.InvalidType() - case *NumberAnyOfError: - t = "number_any_of" - d = locale.NumberAnyOf() - case *NumberOneOfError: - t = "number_one_of" - d = locale.NumberOneOf() - case *NumberAllOfError: - t = "number_all_of" - d = locale.NumberAllOf() - case *NumberNotError: - t = "number_not" - d = locale.NumberNot() - case *MissingDependencyError: - t = "missing_dependency" - d = locale.MissingDependency() - case *InternalError: - t = "internal" - d = locale.Internal() - case *ConstError: - t = "const" - d = locale.Const() - case *EnumError: - t = "enum" - d = locale.Enum() - case *ArrayNoAdditionalItemsError: - t = "array_no_additional_items" - d = locale.ArrayNoAdditionalItems() - case *ArrayMinItemsError: - t = "array_min_items" - d = locale.ArrayMinItems() - case *ArrayMaxItemsError: - t = "array_max_items" - d = locale.ArrayMaxItems() - case *ItemsMustBeUniqueError: - t = "unique" - d = locale.Unique() - case *ArrayContainsError: - t = "contains" - d = locale.ArrayContains() - case *ArrayMinPropertiesError: - t = "array_min_properties" - d = locale.ArrayMinProperties() - case *ArrayMaxPropertiesError: - t = "array_max_properties" - d = locale.ArrayMaxProperties() - case *AdditionalPropertyNotAllowedError: - t = "additional_property_not_allowed" - d = locale.AdditionalPropertyNotAllowed() - case *InvalidPropertyPatternError: - t = "invalid_property_pattern" - d = locale.InvalidPropertyPattern() - case *InvalidPropertyNameError: - t = "invalid_property_name" - d = locale.InvalidPropertyName() - case *StringLengthGTEError: - t = "string_gte" - d = locale.StringGTE() - case *StringLengthLTEError: - t = "string_lte" - d = locale.StringLTE() - case *DoesNotMatchPatternError: - t = "pattern" - d = locale.DoesNotMatchPattern() - case *DoesNotMatchFormatError: - t = "format" - d = locale.DoesNotMatchFormat() - case *MultipleOfError: - t = "multiple_of" - d = locale.MultipleOf() - case *NumberGTEError: - t = "number_gte" - d = locale.NumberGTE() - case *NumberGTError: - t = "number_gt" - d = locale.NumberGT() - case *NumberLTEError: - t = "number_lte" - d = locale.NumberLTE() - case *NumberLTError: - t = "number_lt" - d = locale.NumberLT() - case *ConditionThenError: - t = "condition_then" - d = locale.ConditionThen() - case *ConditionElseError: - t = "condition_else" - d = locale.ConditionElse() - } - - err.SetType(t) - err.SetContext(context) - err.SetValue(value) - err.SetDetails(details) - err.SetDescriptionFormat(d) - details["field"] = err.Field() - - if _, exists := details["context"]; !exists && context != nil { - details["context"] = context.String() - } - - err.SetDescription(formatErrorDescription(err.DescriptionFormat(), details)) -} - -// formatErrorDescription takes a string in the default text/template -// format and converts it to a string with replacements. The fields come -// from the ErrorDetails struct and vary for each type of error. -func formatErrorDescription(s string, details ErrorDetails) string { - - var tpl *template.Template - var descrAsBuffer bytes.Buffer - var err error - - errorTemplates.RLock() - tpl = errorTemplates.Lookup(s) - errorTemplates.RUnlock() - - if tpl == nil { - errorTemplates.Lock() - tpl = errorTemplates.New(s) - - if ErrorTemplateFuncs != nil { - tpl.Funcs(ErrorTemplateFuncs) - } - - tpl, err = tpl.Parse(s) - errorTemplates.Unlock() - - if err != nil { - return err.Error() - } - } - - err = tpl.Execute(&descrAsBuffer, details) - if err != nil { - return err.Error() - } - - return descrAsBuffer.String() -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/format_checkers.go b/vendor/github.com/xeipuuv/gojsonschema/format_checkers.go deleted file mode 100644 index 873ffc7d7..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/format_checkers.go +++ /dev/null @@ -1,368 +0,0 @@ -package gojsonschema - -import ( - "net" - "net/mail" - "net/url" - "regexp" - "strings" - "sync" - "time" -) - -type ( - // FormatChecker is the interface all formatters added to FormatCheckerChain must implement - FormatChecker interface { - // IsFormat checks if input has the correct format and type - IsFormat(input interface{}) bool - } - - // FormatCheckerChain holds the formatters - FormatCheckerChain struct { - formatters map[string]FormatChecker - } - - // EmailFormatChecker verifies email address formats - EmailFormatChecker struct{} - - // IPV4FormatChecker verifies IP addresses in the IPv4 format - IPV4FormatChecker struct{} - - // IPV6FormatChecker verifies IP addresses in the IPv6 format - IPV6FormatChecker struct{} - - // DateTimeFormatChecker verifies date/time formats per RFC3339 5.6 - // - // Valid formats: - // Partial Time: HH:MM:SS - // Full Date: YYYY-MM-DD - // Full Time: HH:MM:SSZ-07:00 - // Date Time: YYYY-MM-DDTHH:MM:SSZ-0700 - // - // Where - // YYYY = 4DIGIT year - // MM = 2DIGIT month ; 01-12 - // DD = 2DIGIT day-month ; 01-28, 01-29, 01-30, 01-31 based on month/year - // HH = 2DIGIT hour ; 00-23 - // MM = 2DIGIT ; 00-59 - // SS = 2DIGIT ; 00-58, 00-60 based on leap second rules - // T = Literal - // Z = Literal - // - // Note: Nanoseconds are also suported in all formats - // - // http://tools.ietf.org/html/rfc3339#section-5.6 - DateTimeFormatChecker struct{} - - // DateFormatChecker verifies date formats - // - // Valid format: - // Full Date: YYYY-MM-DD - // - // Where - // YYYY = 4DIGIT year - // MM = 2DIGIT month ; 01-12 - // DD = 2DIGIT day-month ; 01-28, 01-29, 01-30, 01-31 based on month/year - DateFormatChecker struct{} - - // TimeFormatChecker verifies time formats - // - // Valid formats: - // Partial Time: HH:MM:SS - // Full Time: HH:MM:SSZ-07:00 - // - // Where - // HH = 2DIGIT hour ; 00-23 - // MM = 2DIGIT ; 00-59 - // SS = 2DIGIT ; 00-58, 00-60 based on leap second rules - // T = Literal - // Z = Literal - TimeFormatChecker struct{} - - // URIFormatChecker validates a URI with a valid Scheme per RFC3986 - URIFormatChecker struct{} - - // URIReferenceFormatChecker validates a URI or relative-reference per RFC3986 - URIReferenceFormatChecker struct{} - - // URITemplateFormatChecker validates a URI template per RFC6570 - URITemplateFormatChecker struct{} - - // HostnameFormatChecker validates a hostname is in the correct format - HostnameFormatChecker struct{} - - // UUIDFormatChecker validates a UUID is in the correct format - UUIDFormatChecker struct{} - - // RegexFormatChecker validates a regex is in the correct format - RegexFormatChecker struct{} - - // JSONPointerFormatChecker validates a JSON Pointer per RFC6901 - JSONPointerFormatChecker struct{} - - // RelativeJSONPointerFormatChecker validates a relative JSON Pointer is in the correct format - RelativeJSONPointerFormatChecker struct{} -) - -var ( - // FormatCheckers holds the valid formatters, and is a public variable - // so library users can add custom formatters - FormatCheckers = FormatCheckerChain{ - formatters: map[string]FormatChecker{ - "date": DateFormatChecker{}, - "time": TimeFormatChecker{}, - "date-time": DateTimeFormatChecker{}, - "hostname": HostnameFormatChecker{}, - "email": EmailFormatChecker{}, - "idn-email": EmailFormatChecker{}, - "ipv4": IPV4FormatChecker{}, - "ipv6": IPV6FormatChecker{}, - "uri": URIFormatChecker{}, - "uri-reference": URIReferenceFormatChecker{}, - "iri": URIFormatChecker{}, - "iri-reference": URIReferenceFormatChecker{}, - "uri-template": URITemplateFormatChecker{}, - "uuid": UUIDFormatChecker{}, - "regex": RegexFormatChecker{}, - "json-pointer": JSONPointerFormatChecker{}, - "relative-json-pointer": RelativeJSONPointerFormatChecker{}, - }, - } - - // Regex credit: https://www.socketloop.com/tutorials/golang-validate-hostname - rxHostname = regexp.MustCompile(`^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$`) - - // Use a regex to make sure curly brackets are balanced properly after validating it as a AURI - rxURITemplate = regexp.MustCompile("^([^{]*({[^}]*})?)*$") - - rxUUID = regexp.MustCompile("^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$") - - rxJSONPointer = regexp.MustCompile("^(?:/(?:[^~/]|~0|~1)*)*$") - - rxRelJSONPointer = regexp.MustCompile("^(?:0|[1-9][0-9]*)(?:#|(?:/(?:[^~/]|~0|~1)*)*)$") - - lock = new(sync.RWMutex) -) - -// Add adds a FormatChecker to the FormatCheckerChain -// The name used will be the value used for the format key in your json schema -func (c *FormatCheckerChain) Add(name string, f FormatChecker) *FormatCheckerChain { - lock.Lock() - c.formatters[name] = f - lock.Unlock() - - return c -} - -// Remove deletes a FormatChecker from the FormatCheckerChain (if it exists) -func (c *FormatCheckerChain) Remove(name string) *FormatCheckerChain { - lock.Lock() - delete(c.formatters, name) - lock.Unlock() - - return c -} - -// Has checks to see if the FormatCheckerChain holds a FormatChecker with the given name -func (c *FormatCheckerChain) Has(name string) bool { - lock.RLock() - _, ok := c.formatters[name] - lock.RUnlock() - - return ok -} - -// IsFormat will check an input against a FormatChecker with the given name -// to see if it is the correct format -func (c *FormatCheckerChain) IsFormat(name string, input interface{}) bool { - lock.RLock() - f, ok := c.formatters[name] - lock.RUnlock() - - // If a format is unrecognized it should always pass validation - if !ok { - return true - } - - return f.IsFormat(input) -} - -// IsFormat checks if input is a correctly formatted e-mail address -func (f EmailFormatChecker) IsFormat(input interface{}) bool { - asString, ok := input.(string) - if !ok { - return false - } - - _, err := mail.ParseAddress(asString) - return err == nil -} - -// IsFormat checks if input is a correctly formatted IPv4-address -func (f IPV4FormatChecker) IsFormat(input interface{}) bool { - asString, ok := input.(string) - if !ok { - return false - } - - // Credit: https://github.com/asaskevich/govalidator - ip := net.ParseIP(asString) - return ip != nil && strings.Contains(asString, ".") -} - -// IsFormat checks if input is a correctly formatted IPv6=address -func (f IPV6FormatChecker) IsFormat(input interface{}) bool { - asString, ok := input.(string) - if !ok { - return false - } - - // Credit: https://github.com/asaskevich/govalidator - ip := net.ParseIP(asString) - return ip != nil && strings.Contains(asString, ":") -} - -// IsFormat checks if input is a correctly formatted date/time per RFC3339 5.6 -func (f DateTimeFormatChecker) IsFormat(input interface{}) bool { - asString, ok := input.(string) - if !ok { - return false - } - - formats := []string{ - "15:04:05", - "15:04:05Z07:00", - "2006-01-02", - time.RFC3339, - time.RFC3339Nano, - } - - for _, format := range formats { - if _, err := time.Parse(format, asString); err == nil { - return true - } - } - - return false -} - -// IsFormat checks if input is a correctly formatted date (YYYY-MM-DD) -func (f DateFormatChecker) IsFormat(input interface{}) bool { - asString, ok := input.(string) - if !ok { - return false - } - _, err := time.Parse("2006-01-02", asString) - return err == nil -} - -// IsFormat checks if input correctly formatted time (HH:MM:SS or HH:MM:SSZ-07:00) -func (f TimeFormatChecker) IsFormat(input interface{}) bool { - asString, ok := input.(string) - if !ok { - return false - } - - if _, err := time.Parse("15:04:05Z07:00", asString); err == nil { - return true - } - - _, err := time.Parse("15:04:05", asString) - return err == nil -} - -// IsFormat checks if input is correctly formatted URI with a valid Scheme per RFC3986 -func (f URIFormatChecker) IsFormat(input interface{}) bool { - asString, ok := input.(string) - if !ok { - return false - } - - u, err := url.Parse(asString) - - if err != nil || u.Scheme == "" { - return false - } - - return !strings.Contains(asString, `\`) -} - -// IsFormat checks if input is a correctly formatted URI or relative-reference per RFC3986 -func (f URIReferenceFormatChecker) IsFormat(input interface{}) bool { - asString, ok := input.(string) - if !ok { - return false - } - - _, err := url.Parse(asString) - return err == nil && !strings.Contains(asString, `\`) -} - -// IsFormat checks if input is a correctly formatted URI template per RFC6570 -func (f URITemplateFormatChecker) IsFormat(input interface{}) bool { - asString, ok := input.(string) - if !ok { - return false - } - - u, err := url.Parse(asString) - if err != nil || strings.Contains(asString, `\`) { - return false - } - - return rxURITemplate.MatchString(u.Path) -} - -// IsFormat checks if input is a correctly formatted hostname -func (f HostnameFormatChecker) IsFormat(input interface{}) bool { - asString, ok := input.(string) - if !ok { - return false - } - - return rxHostname.MatchString(asString) && len(asString) < 256 -} - -// IsFormat checks if input is a correctly formatted UUID -func (f UUIDFormatChecker) IsFormat(input interface{}) bool { - asString, ok := input.(string) - if !ok { - return false - } - - return rxUUID.MatchString(asString) -} - -// IsFormat checks if input is a correctly formatted regular expression -func (f RegexFormatChecker) IsFormat(input interface{}) bool { - asString, ok := input.(string) - if !ok { - return false - } - - if asString == "" { - return true - } - _, err := regexp.Compile(asString) - return err == nil -} - -// IsFormat checks if input is a correctly formatted JSON Pointer per RFC6901 -func (f JSONPointerFormatChecker) IsFormat(input interface{}) bool { - asString, ok := input.(string) - if !ok { - return false - } - - return rxJSONPointer.MatchString(asString) -} - -// IsFormat checks if input is a correctly formatted relative JSON Pointer -func (f RelativeJSONPointerFormatChecker) IsFormat(input interface{}) bool { - asString, ok := input.(string) - if !ok { - return false - } - - return rxRelJSONPointer.MatchString(asString) -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/glide.yaml b/vendor/github.com/xeipuuv/gojsonschema/glide.yaml deleted file mode 100644 index ab6fb867c..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/glide.yaml +++ /dev/null @@ -1,13 +0,0 @@ -package: github.com/xeipuuv/gojsonschema -license: Apache 2.0 -import: -- package: github.com/xeipuuv/gojsonschema - -- package: github.com/xeipuuv/gojsonpointer - -- package: github.com/xeipuuv/gojsonreference - -testImport: -- package: github.com/stretchr/testify - subpackages: - - assert diff --git a/vendor/github.com/xeipuuv/gojsonschema/internalLog.go b/vendor/github.com/xeipuuv/gojsonschema/internalLog.go deleted file mode 100644 index 4ef7a8d03..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/internalLog.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) -// -// 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. - -// author xeipuuv -// author-github https://github.com/xeipuuv -// author-mail xeipuuv@gmail.com -// -// repository-name gojsonschema -// repository-desc An implementation of JSON Schema, based on IETF's draft v4 - Go language. -// -// description Very simple log wrapper. -// Used for debugging/testing purposes. -// -// created 01-01-2015 - -package gojsonschema - -import ( - "log" -) - -const internalLogEnabled = false - -func internalLog(format string, v ...interface{}) { - log.Printf(format, v...) -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/jsonContext.go b/vendor/github.com/xeipuuv/gojsonschema/jsonContext.go deleted file mode 100644 index 0e979707b..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/jsonContext.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2013 MongoDB, Inc. -// -// 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. - -// author tolsen -// author-github https://github.com/tolsen -// -// repository-name gojsonschema -// repository-desc An implementation of JSON Schema, based on IETF's draft v4 - Go language. -// -// description Implements a persistent (immutable w/ shared structure) singly-linked list of strings for the purpose of storing a json context -// -// created 04-09-2013 - -package gojsonschema - -import "bytes" - -// JsonContext implements a persistent linked-list of strings -type JsonContext struct { - head string - tail *JsonContext -} - -// NewJsonContext creates a new JsonContext -func NewJsonContext(head string, tail *JsonContext) *JsonContext { - return &JsonContext{head, tail} -} - -// String displays the context in reverse. -// This plays well with the data structure's persistent nature with -// Cons and a json document's tree structure. -func (c *JsonContext) String(del ...string) string { - byteArr := make([]byte, 0, c.stringLen()) - buf := bytes.NewBuffer(byteArr) - c.writeStringToBuffer(buf, del) - - return buf.String() -} - -func (c *JsonContext) stringLen() int { - length := 0 - if c.tail != nil { - length = c.tail.stringLen() + 1 // add 1 for "." - } - - length += len(c.head) - return length -} - -func (c *JsonContext) writeStringToBuffer(buf *bytes.Buffer, del []string) { - if c.tail != nil { - c.tail.writeStringToBuffer(buf, del) - - if len(del) > 0 { - buf.WriteString(del[0]) - } else { - buf.WriteString(".") - } - } - - buf.WriteString(c.head) -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/jsonLoader.go b/vendor/github.com/xeipuuv/gojsonschema/jsonLoader.go deleted file mode 100644 index 5d88af263..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/jsonLoader.go +++ /dev/null @@ -1,386 +0,0 @@ -// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) -// -// 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. - -// author xeipuuv -// author-github https://github.com/xeipuuv -// author-mail xeipuuv@gmail.com -// -// repository-name gojsonschema -// repository-desc An implementation of JSON Schema, based on IETF's draft v4 - Go language. -// -// description Different strategies to load JSON files. -// Includes References (file and HTTP), JSON strings and Go types. -// -// created 01-02-2015 - -package gojsonschema - -import ( - "bytes" - "encoding/json" - "errors" - "io" - "io/ioutil" - "net/http" - "net/url" - "os" - "path/filepath" - "runtime" - "strings" - - "github.com/xeipuuv/gojsonreference" -) - -var osFS = osFileSystem(os.Open) - -// JSONLoader defines the JSON loader interface -type JSONLoader interface { - JsonSource() interface{} - LoadJSON() (interface{}, error) - JsonReference() (gojsonreference.JsonReference, error) - LoaderFactory() JSONLoaderFactory -} - -// JSONLoaderFactory defines the JSON loader factory interface -type JSONLoaderFactory interface { - // New creates a new JSON loader for the given source - New(source string) JSONLoader -} - -// DefaultJSONLoaderFactory is the default JSON loader factory -type DefaultJSONLoaderFactory struct { -} - -// FileSystemJSONLoaderFactory is a JSON loader factory that uses http.FileSystem -type FileSystemJSONLoaderFactory struct { - fs http.FileSystem -} - -// New creates a new JSON loader for the given source -func (d DefaultJSONLoaderFactory) New(source string) JSONLoader { - return &jsonReferenceLoader{ - fs: osFS, - source: source, - } -} - -// New creates a new JSON loader for the given source -func (f FileSystemJSONLoaderFactory) New(source string) JSONLoader { - return &jsonReferenceLoader{ - fs: f.fs, - source: source, - } -} - -// osFileSystem is a functional wrapper for os.Open that implements http.FileSystem. -type osFileSystem func(string) (*os.File, error) - -// Opens a file with the given name -func (o osFileSystem) Open(name string) (http.File, error) { - return o(name) -} - -// JSON Reference loader -// references are used to load JSONs from files and HTTP - -type jsonReferenceLoader struct { - fs http.FileSystem - source string -} - -func (l *jsonReferenceLoader) JsonSource() interface{} { - return l.source -} - -func (l *jsonReferenceLoader) JsonReference() (gojsonreference.JsonReference, error) { - return gojsonreference.NewJsonReference(l.JsonSource().(string)) -} - -func (l *jsonReferenceLoader) LoaderFactory() JSONLoaderFactory { - return &FileSystemJSONLoaderFactory{ - fs: l.fs, - } -} - -// NewReferenceLoader returns a JSON reference loader using the given source and the local OS file system. -func NewReferenceLoader(source string) JSONLoader { - return &jsonReferenceLoader{ - fs: osFS, - source: source, - } -} - -// NewReferenceLoaderFileSystem returns a JSON reference loader using the given source and file system. -func NewReferenceLoaderFileSystem(source string, fs http.FileSystem) JSONLoader { - return &jsonReferenceLoader{ - fs: fs, - source: source, - } -} - -func (l *jsonReferenceLoader) LoadJSON() (interface{}, error) { - - var err error - - reference, err := gojsonreference.NewJsonReference(l.JsonSource().(string)) - if err != nil { - return nil, err - } - - refToURL := reference - refToURL.GetUrl().Fragment = "" - - var document interface{} - - if reference.HasFileScheme { - - filename := strings.TrimPrefix(refToURL.String(), "file://") - filename, err = url.QueryUnescape(filename) - - if err != nil { - return nil, err - } - - if runtime.GOOS == "windows" { - // on Windows, a file URL may have an extra leading slash, use slashes - // instead of backslashes, and have spaces escaped - filename = strings.TrimPrefix(filename, "/") - filename = filepath.FromSlash(filename) - } - - document, err = l.loadFromFile(filename) - if err != nil { - return nil, err - } - - } else { - - document, err = l.loadFromHTTP(refToURL.String()) - if err != nil { - return nil, err - } - - } - - return document, nil - -} - -func (l *jsonReferenceLoader) loadFromHTTP(address string) (interface{}, error) { - - // returned cached versions for metaschemas for drafts 4, 6 and 7 - // for performance and allow for easier offline use - if metaSchema := drafts.GetMetaSchema(address); metaSchema != "" { - return decodeJSONUsingNumber(strings.NewReader(metaSchema)) - } - - resp, err := http.Get(address) - if err != nil { - return nil, err - } - - // must return HTTP Status 200 OK - if resp.StatusCode != http.StatusOK { - return nil, errors.New(formatErrorDescription(Locale.HttpBadStatus(), ErrorDetails{"status": resp.Status})) - } - - bodyBuff, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - return decodeJSONUsingNumber(bytes.NewReader(bodyBuff)) -} - -func (l *jsonReferenceLoader) loadFromFile(path string) (interface{}, error) { - f, err := l.fs.Open(path) - if err != nil { - return nil, err - } - defer f.Close() - - bodyBuff, err := ioutil.ReadAll(f) - if err != nil { - return nil, err - } - - return decodeJSONUsingNumber(bytes.NewReader(bodyBuff)) - -} - -// JSON string loader - -type jsonStringLoader struct { - source string -} - -func (l *jsonStringLoader) JsonSource() interface{} { - return l.source -} - -func (l *jsonStringLoader) JsonReference() (gojsonreference.JsonReference, error) { - return gojsonreference.NewJsonReference("#") -} - -func (l *jsonStringLoader) LoaderFactory() JSONLoaderFactory { - return &DefaultJSONLoaderFactory{} -} - -// NewStringLoader creates a new JSONLoader, taking a string as source -func NewStringLoader(source string) JSONLoader { - return &jsonStringLoader{source: source} -} - -func (l *jsonStringLoader) LoadJSON() (interface{}, error) { - - return decodeJSONUsingNumber(strings.NewReader(l.JsonSource().(string))) - -} - -// JSON bytes loader - -type jsonBytesLoader struct { - source []byte -} - -func (l *jsonBytesLoader) JsonSource() interface{} { - return l.source -} - -func (l *jsonBytesLoader) JsonReference() (gojsonreference.JsonReference, error) { - return gojsonreference.NewJsonReference("#") -} - -func (l *jsonBytesLoader) LoaderFactory() JSONLoaderFactory { - return &DefaultJSONLoaderFactory{} -} - -// NewBytesLoader creates a new JSONLoader, taking a `[]byte` as source -func NewBytesLoader(source []byte) JSONLoader { - return &jsonBytesLoader{source: source} -} - -func (l *jsonBytesLoader) LoadJSON() (interface{}, error) { - return decodeJSONUsingNumber(bytes.NewReader(l.JsonSource().([]byte))) -} - -// JSON Go (types) loader -// used to load JSONs from the code as maps, interface{}, structs ... - -type jsonGoLoader struct { - source interface{} -} - -func (l *jsonGoLoader) JsonSource() interface{} { - return l.source -} - -func (l *jsonGoLoader) JsonReference() (gojsonreference.JsonReference, error) { - return gojsonreference.NewJsonReference("#") -} - -func (l *jsonGoLoader) LoaderFactory() JSONLoaderFactory { - return &DefaultJSONLoaderFactory{} -} - -// NewGoLoader creates a new JSONLoader from a given Go struct -func NewGoLoader(source interface{}) JSONLoader { - return &jsonGoLoader{source: source} -} - -func (l *jsonGoLoader) LoadJSON() (interface{}, error) { - - // convert it to a compliant JSON first to avoid types "mismatches" - - jsonBytes, err := json.Marshal(l.JsonSource()) - if err != nil { - return nil, err - } - - return decodeJSONUsingNumber(bytes.NewReader(jsonBytes)) - -} - -type jsonIOLoader struct { - buf *bytes.Buffer -} - -// NewReaderLoader creates a new JSON loader using the provided io.Reader -func NewReaderLoader(source io.Reader) (JSONLoader, io.Reader) { - buf := &bytes.Buffer{} - return &jsonIOLoader{buf: buf}, io.TeeReader(source, buf) -} - -// NewWriterLoader creates a new JSON loader using the provided io.Writer -func NewWriterLoader(source io.Writer) (JSONLoader, io.Writer) { - buf := &bytes.Buffer{} - return &jsonIOLoader{buf: buf}, io.MultiWriter(source, buf) -} - -func (l *jsonIOLoader) JsonSource() interface{} { - return l.buf.String() -} - -func (l *jsonIOLoader) LoadJSON() (interface{}, error) { - return decodeJSONUsingNumber(l.buf) -} - -func (l *jsonIOLoader) JsonReference() (gojsonreference.JsonReference, error) { - return gojsonreference.NewJsonReference("#") -} - -func (l *jsonIOLoader) LoaderFactory() JSONLoaderFactory { - return &DefaultJSONLoaderFactory{} -} - -// JSON raw loader -// In case the JSON is already marshalled to interface{} use this loader -// This is used for testing as otherwise there is no guarantee the JSON is marshalled -// "properly" by using https://golang.org/pkg/encoding/json/#Decoder.UseNumber -type jsonRawLoader struct { - source interface{} -} - -// NewRawLoader creates a new JSON raw loader for the given source -func NewRawLoader(source interface{}) JSONLoader { - return &jsonRawLoader{source: source} -} -func (l *jsonRawLoader) JsonSource() interface{} { - return l.source -} -func (l *jsonRawLoader) LoadJSON() (interface{}, error) { - return l.source, nil -} -func (l *jsonRawLoader) JsonReference() (gojsonreference.JsonReference, error) { - return gojsonreference.NewJsonReference("#") -} -func (l *jsonRawLoader) LoaderFactory() JSONLoaderFactory { - return &DefaultJSONLoaderFactory{} -} - -func decodeJSONUsingNumber(r io.Reader) (interface{}, error) { - - var document interface{} - - decoder := json.NewDecoder(r) - decoder.UseNumber() - - err := decoder.Decode(&document) - if err != nil { - return nil, err - } - - return document, nil - -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/locales.go b/vendor/github.com/xeipuuv/gojsonschema/locales.go deleted file mode 100644 index a416225cd..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/locales.go +++ /dev/null @@ -1,472 +0,0 @@ -// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) -// -// 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. - -// author xeipuuv -// author-github https://github.com/xeipuuv -// author-mail xeipuuv@gmail.com -// -// repository-name gojsonschema -// repository-desc An implementation of JSON Schema, based on IETF's draft v4 - Go language. -// -// description Contains const string and messages. -// -// created 01-01-2015 - -package gojsonschema - -type ( - // locale is an interface for defining custom error strings - locale interface { - - // False returns a format-string for "false" schema validation errors - False() string - - // Required returns a format-string for "required" schema validation errors - Required() string - - // InvalidType returns a format-string for "invalid type" schema validation errors - InvalidType() string - - // NumberAnyOf returns a format-string for "anyOf" schema validation errors - NumberAnyOf() string - - // NumberOneOf returns a format-string for "oneOf" schema validation errors - NumberOneOf() string - - // NumberAllOf returns a format-string for "allOf" schema validation errors - NumberAllOf() string - - // NumberNot returns a format-string to format a NumberNotError - NumberNot() string - - // MissingDependency returns a format-string for "missing dependency" schema validation errors - MissingDependency() string - - // Internal returns a format-string for internal errors - Internal() string - - // Const returns a format-string to format a ConstError - Const() string - - // Enum returns a format-string to format an EnumError - Enum() string - - // ArrayNotEnoughItems returns a format-string to format an error for arrays having not enough items to match positional list of schema - ArrayNotEnoughItems() string - - // ArrayNoAdditionalItems returns a format-string to format an ArrayNoAdditionalItemsError - ArrayNoAdditionalItems() string - - // ArrayMinItems returns a format-string to format an ArrayMinItemsError - ArrayMinItems() string - - // ArrayMaxItems returns a format-string to format an ArrayMaxItemsError - ArrayMaxItems() string - - // Unique returns a format-string to format an ItemsMustBeUniqueError - Unique() string - - // ArrayContains returns a format-string to format an ArrayContainsError - ArrayContains() string - - // ArrayMinProperties returns a format-string to format an ArrayMinPropertiesError - ArrayMinProperties() string - - // ArrayMaxProperties returns a format-string to format an ArrayMaxPropertiesError - ArrayMaxProperties() string - - // AdditionalPropertyNotAllowed returns a format-string to format an AdditionalPropertyNotAllowedError - AdditionalPropertyNotAllowed() string - - // InvalidPropertyPattern returns a format-string to format an InvalidPropertyPatternError - InvalidPropertyPattern() string - - // InvalidPropertyName returns a format-string to format an InvalidPropertyNameError - InvalidPropertyName() string - - // StringGTE returns a format-string to format an StringLengthGTEError - StringGTE() string - - // StringLTE returns a format-string to format an StringLengthLTEError - StringLTE() string - - // DoesNotMatchPattern returns a format-string to format an DoesNotMatchPatternError - DoesNotMatchPattern() string - - // DoesNotMatchFormat returns a format-string to format an DoesNotMatchFormatError - DoesNotMatchFormat() string - - // MultipleOf returns a format-string to format an MultipleOfError - MultipleOf() string - - // NumberGTE returns a format-string to format an NumberGTEError - NumberGTE() string - - // NumberGT returns a format-string to format an NumberGTError - NumberGT() string - - // NumberLTE returns a format-string to format an NumberLTEError - NumberLTE() string - - // NumberLT returns a format-string to format an NumberLTError - NumberLT() string - - // Schema validations - - // RegexPattern returns a format-string to format a regex-pattern error - RegexPattern() string - - // GreaterThanZero returns a format-string to format an error where a number must be greater than zero - GreaterThanZero() string - - // MustBeOfA returns a format-string to format an error where a value is of the wrong type - MustBeOfA() string - - // MustBeOfAn returns a format-string to format an error where a value is of the wrong type - MustBeOfAn() string - - // CannotBeUsedWithout returns a format-string to format a "cannot be used without" error - CannotBeUsedWithout() string - - // CannotBeGT returns a format-string to format an error where a value are greater than allowed - CannotBeGT() string - - // MustBeOfType returns a format-string to format an error where a value does not match the required type - MustBeOfType() string - - // MustBeValidRegex returns a format-string to format an error where a regex is invalid - MustBeValidRegex() string - - // MustBeValidFormat returns a format-string to format an error where a value does not match the expected format - MustBeValidFormat() string - - // MustBeGTEZero returns a format-string to format an error where a value must be greater or equal than 0 - MustBeGTEZero() string - - // KeyCannotBeGreaterThan returns a format-string to format an error where a key is greater than the maximum allowed - KeyCannotBeGreaterThan() string - - // KeyItemsMustBeOfType returns a format-string to format an error where a key is of the wrong type - KeyItemsMustBeOfType() string - - // KeyItemsMustBeUnique returns a format-string to format an error where keys are not unique - KeyItemsMustBeUnique() string - - // ReferenceMustBeCanonical returns a format-string to format a "reference must be canonical" error - ReferenceMustBeCanonical() string - - // NotAValidType returns a format-string to format an invalid type error - NotAValidType() string - - // Duplicated returns a format-string to format an error where types are duplicated - Duplicated() string - - // HttpBadStatus returns a format-string for errors when loading a schema using HTTP - HttpBadStatus() string - - // ParseError returns a format-string for JSON parsing errors - ParseError() string - - // ConditionThen returns a format-string for ConditionThenError errors - ConditionThen() string - - // ConditionElse returns a format-string for ConditionElseError errors - ConditionElse() string - - // ErrorFormat returns a format string for errors - ErrorFormat() string - } - - // DefaultLocale is the default locale for this package - DefaultLocale struct{} -) - -// False returns a format-string for "false" schema validation errors -func (l DefaultLocale) False() string { - return "False always fails validation" -} - -// Required returns a format-string for "required" schema validation errors -func (l DefaultLocale) Required() string { - return `{{.property}} is required` -} - -// InvalidType returns a format-string for "invalid type" schema validation errors -func (l DefaultLocale) InvalidType() string { - return `Invalid type. Expected: {{.expected}}, given: {{.given}}` -} - -// NumberAnyOf returns a format-string for "anyOf" schema validation errors -func (l DefaultLocale) NumberAnyOf() string { - return `Must validate at least one schema (anyOf)` -} - -// NumberOneOf returns a format-string for "oneOf" schema validation errors -func (l DefaultLocale) NumberOneOf() string { - return `Must validate one and only one schema (oneOf)` -} - -// NumberAllOf returns a format-string for "allOf" schema validation errors -func (l DefaultLocale) NumberAllOf() string { - return `Must validate all the schemas (allOf)` -} - -// NumberNot returns a format-string to format a NumberNotError -func (l DefaultLocale) NumberNot() string { - return `Must not validate the schema (not)` -} - -// MissingDependency returns a format-string for "missing dependency" schema validation errors -func (l DefaultLocale) MissingDependency() string { - return `Has a dependency on {{.dependency}}` -} - -// Internal returns a format-string for internal errors -func (l DefaultLocale) Internal() string { - return `Internal Error {{.error}}` -} - -// Const returns a format-string to format a ConstError -func (l DefaultLocale) Const() string { - return `{{.field}} does not match: {{.allowed}}` -} - -// Enum returns a format-string to format an EnumError -func (l DefaultLocale) Enum() string { - return `{{.field}} must be one of the following: {{.allowed}}` -} - -// ArrayNoAdditionalItems returns a format-string to format an ArrayNoAdditionalItemsError -func (l DefaultLocale) ArrayNoAdditionalItems() string { - return `No additional items allowed on array` -} - -// ArrayNotEnoughItems returns a format-string to format an error for arrays having not enough items to match positional list of schema -func (l DefaultLocale) ArrayNotEnoughItems() string { - return `Not enough items on array to match positional list of schema` -} - -// ArrayMinItems returns a format-string to format an ArrayMinItemsError -func (l DefaultLocale) ArrayMinItems() string { - return `Array must have at least {{.min}} items` -} - -// ArrayMaxItems returns a format-string to format an ArrayMaxItemsError -func (l DefaultLocale) ArrayMaxItems() string { - return `Array must have at most {{.max}} items` -} - -// Unique returns a format-string to format an ItemsMustBeUniqueError -func (l DefaultLocale) Unique() string { - return `{{.type}} items[{{.i}},{{.j}}] must be unique` -} - -// ArrayContains returns a format-string to format an ArrayContainsError -func (l DefaultLocale) ArrayContains() string { - return `At least one of the items must match` -} - -// ArrayMinProperties returns a format-string to format an ArrayMinPropertiesError -func (l DefaultLocale) ArrayMinProperties() string { - return `Must have at least {{.min}} properties` -} - -// ArrayMaxProperties returns a format-string to format an ArrayMaxPropertiesError -func (l DefaultLocale) ArrayMaxProperties() string { - return `Must have at most {{.max}} properties` -} - -// AdditionalPropertyNotAllowed returns a format-string to format an AdditionalPropertyNotAllowedError -func (l DefaultLocale) AdditionalPropertyNotAllowed() string { - return `Additional property {{.property}} is not allowed` -} - -// InvalidPropertyPattern returns a format-string to format an InvalidPropertyPatternError -func (l DefaultLocale) InvalidPropertyPattern() string { - return `Property "{{.property}}" does not match pattern {{.pattern}}` -} - -// InvalidPropertyName returns a format-string to format an InvalidPropertyNameError -func (l DefaultLocale) InvalidPropertyName() string { - return `Property name of "{{.property}}" does not match` -} - -// StringGTE returns a format-string to format an StringLengthGTEError -func (l DefaultLocale) StringGTE() string { - return `String length must be greater than or equal to {{.min}}` -} - -// StringLTE returns a format-string to format an StringLengthLTEError -func (l DefaultLocale) StringLTE() string { - return `String length must be less than or equal to {{.max}}` -} - -// DoesNotMatchPattern returns a format-string to format an DoesNotMatchPatternError -func (l DefaultLocale) DoesNotMatchPattern() string { - return `Does not match pattern '{{.pattern}}'` -} - -// DoesNotMatchFormat returns a format-string to format an DoesNotMatchFormatError -func (l DefaultLocale) DoesNotMatchFormat() string { - return `Does not match format '{{.format}}'` -} - -// MultipleOf returns a format-string to format an MultipleOfError -func (l DefaultLocale) MultipleOf() string { - return `Must be a multiple of {{.multiple}}` -} - -// NumberGTE returns the format string to format a NumberGTEError -func (l DefaultLocale) NumberGTE() string { - return `Must be greater than or equal to {{.min}}` -} - -// NumberGT returns the format string to format a NumberGTError -func (l DefaultLocale) NumberGT() string { - return `Must be greater than {{.min}}` -} - -// NumberLTE returns the format string to format a NumberLTEError -func (l DefaultLocale) NumberLTE() string { - return `Must be less than or equal to {{.max}}` -} - -// NumberLT returns the format string to format a NumberLTError -func (l DefaultLocale) NumberLT() string { - return `Must be less than {{.max}}` -} - -// Schema validators - -// RegexPattern returns a format-string to format a regex-pattern error -func (l DefaultLocale) RegexPattern() string { - return `Invalid regex pattern '{{.pattern}}'` -} - -// GreaterThanZero returns a format-string to format an error where a number must be greater than zero -func (l DefaultLocale) GreaterThanZero() string { - return `{{.number}} must be strictly greater than 0` -} - -// MustBeOfA returns a format-string to format an error where a value is of the wrong type -func (l DefaultLocale) MustBeOfA() string { - return `{{.x}} must be of a {{.y}}` -} - -// MustBeOfAn returns a format-string to format an error where a value is of the wrong type -func (l DefaultLocale) MustBeOfAn() string { - return `{{.x}} must be of an {{.y}}` -} - -// CannotBeUsedWithout returns a format-string to format a "cannot be used without" error -func (l DefaultLocale) CannotBeUsedWithout() string { - return `{{.x}} cannot be used without {{.y}}` -} - -// CannotBeGT returns a format-string to format an error where a value are greater than allowed -func (l DefaultLocale) CannotBeGT() string { - return `{{.x}} cannot be greater than {{.y}}` -} - -// MustBeOfType returns a format-string to format an error where a value does not match the required type -func (l DefaultLocale) MustBeOfType() string { - return `{{.key}} must be of type {{.type}}` -} - -// MustBeValidRegex returns a format-string to format an error where a regex is invalid -func (l DefaultLocale) MustBeValidRegex() string { - return `{{.key}} must be a valid regex` -} - -// MustBeValidFormat returns a format-string to format an error where a value does not match the expected format -func (l DefaultLocale) MustBeValidFormat() string { - return `{{.key}} must be a valid format {{.given}}` -} - -// MustBeGTEZero returns a format-string to format an error where a value must be greater or equal than 0 -func (l DefaultLocale) MustBeGTEZero() string { - return `{{.key}} must be greater than or equal to 0` -} - -// KeyCannotBeGreaterThan returns a format-string to format an error where a value is greater than the maximum allowed -func (l DefaultLocale) KeyCannotBeGreaterThan() string { - return `{{.key}} cannot be greater than {{.y}}` -} - -// KeyItemsMustBeOfType returns a format-string to format an error where a key is of the wrong type -func (l DefaultLocale) KeyItemsMustBeOfType() string { - return `{{.key}} items must be {{.type}}` -} - -// KeyItemsMustBeUnique returns a format-string to format an error where keys are not unique -func (l DefaultLocale) KeyItemsMustBeUnique() string { - return `{{.key}} items must be unique` -} - -// ReferenceMustBeCanonical returns a format-string to format a "reference must be canonical" error -func (l DefaultLocale) ReferenceMustBeCanonical() string { - return `Reference {{.reference}} must be canonical` -} - -// NotAValidType returns a format-string to format an invalid type error -func (l DefaultLocale) NotAValidType() string { - return `has a primitive type that is NOT VALID -- given: {{.given}} Expected valid values are:{{.expected}}` -} - -// Duplicated returns a format-string to format an error where types are duplicated -func (l DefaultLocale) Duplicated() string { - return `{{.type}} type is duplicated` -} - -// HttpBadStatus returns a format-string for errors when loading a schema using HTTP -func (l DefaultLocale) HttpBadStatus() string { - return `Could not read schema from HTTP, response status is {{.status}}` -} - -// ErrorFormat returns a format string for errors -// Replacement options: field, description, context, value -func (l DefaultLocale) ErrorFormat() string { - return `{{.field}}: {{.description}}` -} - -// ParseError returns a format-string for JSON parsing errors -func (l DefaultLocale) ParseError() string { - return `Expected: {{.expected}}, given: Invalid JSON` -} - -// ConditionThen returns a format-string for ConditionThenError errors -// If/Else -func (l DefaultLocale) ConditionThen() string { - return `Must validate "then" as "if" was valid` -} - -// ConditionElse returns a format-string for ConditionElseError errors -func (l DefaultLocale) ConditionElse() string { - return `Must validate "else" as "if" was not valid` -} - -// constants -const ( - STRING_NUMBER = "number" - STRING_ARRAY_OF_STRINGS = "array of strings" - STRING_ARRAY_OF_SCHEMAS = "array of schemas" - STRING_SCHEMA = "valid schema" - STRING_SCHEMA_OR_ARRAY_OF_STRINGS = "schema or array of strings" - STRING_PROPERTIES = "properties" - STRING_DEPENDENCY = "dependency" - STRING_PROPERTY = "property" - STRING_UNDEFINED = "undefined" - STRING_CONTEXT_ROOT = "(root)" - STRING_ROOT_SCHEMA_PROPERTY = "(root)" -) diff --git a/vendor/github.com/xeipuuv/gojsonschema/result.go b/vendor/github.com/xeipuuv/gojsonschema/result.go deleted file mode 100644 index 0a0179148..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/result.go +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) -// -// 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. - -// author xeipuuv -// author-github https://github.com/xeipuuv -// author-mail xeipuuv@gmail.com -// -// repository-name gojsonschema -// repository-desc An implementation of JSON Schema, based on IETF's draft v4 - Go language. -// -// description Result and ResultError implementations. -// -// created 01-01-2015 - -package gojsonschema - -import ( - "fmt" - "strings" -) - -type ( - // ErrorDetails is a map of details specific to each error. - // While the values will vary, every error will contain a "field" value - ErrorDetails map[string]interface{} - - // ResultError is the interface that library errors must implement - ResultError interface { - // Field returns the field name without the root context - // i.e. firstName or person.firstName instead of (root).firstName or (root).person.firstName - Field() string - // SetType sets the error-type - SetType(string) - // Type returns the error-type - Type() string - // SetContext sets the JSON-context for the error - SetContext(*JsonContext) - // Context returns the JSON-context of the error - Context() *JsonContext - // SetDescription sets a description for the error - SetDescription(string) - // Description returns the description of the error - Description() string - // SetDescriptionFormat sets the format for the description in the default text/template format - SetDescriptionFormat(string) - // DescriptionFormat returns the format for the description in the default text/template format - DescriptionFormat() string - // SetValue sets the value related to the error - SetValue(interface{}) - // Value returns the value related to the error - Value() interface{} - // SetDetails sets the details specific to the error - SetDetails(ErrorDetails) - // Details returns details about the error - Details() ErrorDetails - // String returns a string representation of the error - String() string - } - - // ResultErrorFields holds the fields for each ResultError implementation. - // ResultErrorFields implements the ResultError interface, so custom errors - // can be defined by just embedding this type - ResultErrorFields struct { - errorType string // A string with the type of error (i.e. invalid_type) - context *JsonContext // Tree like notation of the part that failed the validation. ex (root).a.b ... - description string // A human readable error message - descriptionFormat string // A format for human readable error message - value interface{} // Value given by the JSON file that is the source of the error - details ErrorDetails - } - - // Result holds the result of a validation - Result struct { - errors []ResultError - // Scores how well the validation matched. Useful in generating - // better error messages for anyOf and oneOf. - score int - } -) - -// Field returns the field name without the root context -// i.e. firstName or person.firstName instead of (root).firstName or (root).person.firstName -func (v *ResultErrorFields) Field() string { - return strings.TrimPrefix(v.context.String(), STRING_ROOT_SCHEMA_PROPERTY+".") -} - -// SetType sets the error-type -func (v *ResultErrorFields) SetType(errorType string) { - v.errorType = errorType -} - -// Type returns the error-type -func (v *ResultErrorFields) Type() string { - return v.errorType -} - -// SetContext sets the JSON-context for the error -func (v *ResultErrorFields) SetContext(context *JsonContext) { - v.context = context -} - -// Context returns the JSON-context of the error -func (v *ResultErrorFields) Context() *JsonContext { - return v.context -} - -// SetDescription sets a description for the error -func (v *ResultErrorFields) SetDescription(description string) { - v.description = description -} - -// Description returns the description of the error -func (v *ResultErrorFields) Description() string { - return v.description -} - -// SetDescriptionFormat sets the format for the description in the default text/template format -func (v *ResultErrorFields) SetDescriptionFormat(descriptionFormat string) { - v.descriptionFormat = descriptionFormat -} - -// DescriptionFormat returns the format for the description in the default text/template format -func (v *ResultErrorFields) DescriptionFormat() string { - return v.descriptionFormat -} - -// SetValue sets the value related to the error -func (v *ResultErrorFields) SetValue(value interface{}) { - v.value = value -} - -// Value returns the value related to the error -func (v *ResultErrorFields) Value() interface{} { - return v.value -} - -// SetDetails sets the details specific to the error -func (v *ResultErrorFields) SetDetails(details ErrorDetails) { - v.details = details -} - -// Details returns details about the error -func (v *ResultErrorFields) Details() ErrorDetails { - return v.details -} - -// String returns a string representation of the error -func (v ResultErrorFields) String() string { - // as a fallback, the value is displayed go style - valueString := fmt.Sprintf("%v", v.value) - - // marshal the go value value to json - if v.value == nil { - valueString = TYPE_NULL - } else { - if vs, err := marshalToJSONString(v.value); err == nil { - if vs == nil { - valueString = TYPE_NULL - } else { - valueString = *vs - } - } - } - - return formatErrorDescription(Locale.ErrorFormat(), ErrorDetails{ - "context": v.context.String(), - "description": v.description, - "value": valueString, - "field": v.Field(), - }) -} - -// Valid indicates if no errors were found -func (v *Result) Valid() bool { - return len(v.errors) == 0 -} - -// Errors returns the errors that were found -func (v *Result) Errors() []ResultError { - return v.errors -} - -// AddError appends a fully filled error to the error set -// SetDescription() will be called with the result of the parsed err.DescriptionFormat() -func (v *Result) AddError(err ResultError, details ErrorDetails) { - if _, exists := details["context"]; !exists && err.Context() != nil { - details["context"] = err.Context().String() - } - - err.SetDescription(formatErrorDescription(err.DescriptionFormat(), details)) - - v.errors = append(v.errors, err) -} - -func (v *Result) addInternalError(err ResultError, context *JsonContext, value interface{}, details ErrorDetails) { - newError(err, context, value, Locale, details) - v.errors = append(v.errors, err) - v.score -= 2 // results in a net -1 when added to the +1 we get at the end of the validation function -} - -// Used to copy errors from a sub-schema to the main one -func (v *Result) mergeErrors(otherResult *Result) { - v.errors = append(v.errors, otherResult.Errors()...) - v.score += otherResult.score -} - -func (v *Result) incrementScore() { - v.score++ -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/schema.go b/vendor/github.com/xeipuuv/gojsonschema/schema.go deleted file mode 100644 index 9e93cd795..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/schema.go +++ /dev/null @@ -1,1087 +0,0 @@ -// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) -// -// 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. - -// author xeipuuv -// author-github https://github.com/xeipuuv -// author-mail xeipuuv@gmail.com -// -// repository-name gojsonschema -// repository-desc An implementation of JSON Schema, based on IETF's draft v4 - Go language. -// -// description Defines Schema, the main entry to every subSchema. -// Contains the parsing logic and error checking. -// -// created 26-02-2013 - -package gojsonschema - -import ( - "errors" - "math/big" - "reflect" - "regexp" - "text/template" - - "github.com/xeipuuv/gojsonreference" -) - -var ( - // Locale is the default locale to use - // Library users can overwrite with their own implementation - Locale locale = DefaultLocale{} - - // ErrorTemplateFuncs allows you to define custom template funcs for use in localization. - ErrorTemplateFuncs template.FuncMap -) - -// NewSchema instances a schema using the given JSONLoader -func NewSchema(l JSONLoader) (*Schema, error) { - return NewSchemaLoader().Compile(l) -} - -// Schema holds a schema -type Schema struct { - documentReference gojsonreference.JsonReference - rootSchema *subSchema - pool *schemaPool - referencePool *schemaReferencePool -} - -func (d *Schema) parse(document interface{}, draft Draft) error { - d.rootSchema = &subSchema{property: STRING_ROOT_SCHEMA_PROPERTY, draft: &draft} - return d.parseSchema(document, d.rootSchema) -} - -// SetRootSchemaName sets the root-schema name -func (d *Schema) SetRootSchemaName(name string) { - d.rootSchema.property = name -} - -// Parses a subSchema -// -// Pretty long function ( sorry :) )... but pretty straight forward, repetitive and boring -// Not much magic involved here, most of the job is to validate the key names and their values, -// then the values are copied into subSchema struct -// -func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema) error { - - if currentSchema.draft == nil { - if currentSchema.parent == nil { - return errors.New("Draft not set") - } - currentSchema.draft = currentSchema.parent.draft - } - - // As of draft 6 "true" is equivalent to an empty schema "{}" and false equals "{"not":{}}" - if *currentSchema.draft >= Draft6 && isKind(documentNode, reflect.Bool) { - b := documentNode.(bool) - currentSchema.pass = &b - return nil - } - - if !isKind(documentNode, reflect.Map) { - return errors.New(formatErrorDescription( - Locale.ParseError(), - ErrorDetails{ - "expected": STRING_SCHEMA, - }, - )) - } - - m := documentNode.(map[string]interface{}) - - if currentSchema.parent == nil { - currentSchema.ref = &d.documentReference - currentSchema.id = &d.documentReference - } - - if currentSchema.id == nil && currentSchema.parent != nil { - currentSchema.id = currentSchema.parent.id - } - - // In draft 6 the id keyword was renamed to $id - // Hybrid mode uses the old id by default - var keyID string - - switch *currentSchema.draft { - case Draft4: - keyID = KEY_ID - case Hybrid: - keyID = KEY_ID_NEW - if existsMapKey(m, KEY_ID) { - keyID = KEY_ID - } - default: - keyID = KEY_ID_NEW - } - if existsMapKey(m, keyID) && !isKind(m[keyID], reflect.String) { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": TYPE_STRING, - "given": keyID, - }, - )) - } - if k, ok := m[keyID].(string); ok { - jsonReference, err := gojsonreference.NewJsonReference(k) - if err != nil { - return err - } - if currentSchema == d.rootSchema { - currentSchema.id = &jsonReference - } else { - ref, err := currentSchema.parent.id.Inherits(jsonReference) - if err != nil { - return err - } - currentSchema.id = ref - } - } - - // definitions - if existsMapKey(m, KEY_DEFINITIONS) { - if isKind(m[KEY_DEFINITIONS], reflect.Map, reflect.Bool) { - for _, dv := range m[KEY_DEFINITIONS].(map[string]interface{}) { - if isKind(dv, reflect.Map, reflect.Bool) { - - newSchema := &subSchema{property: KEY_DEFINITIONS, parent: currentSchema} - - err := d.parseSchema(dv, newSchema) - - if err != nil { - return err - } - } else { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": STRING_ARRAY_OF_SCHEMAS, - "given": KEY_DEFINITIONS, - }, - )) - } - } - } else { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": STRING_ARRAY_OF_SCHEMAS, - "given": KEY_DEFINITIONS, - }, - )) - } - - } - - // title - if existsMapKey(m, KEY_TITLE) && !isKind(m[KEY_TITLE], reflect.String) { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": TYPE_STRING, - "given": KEY_TITLE, - }, - )) - } - if k, ok := m[KEY_TITLE].(string); ok { - currentSchema.title = &k - } - - // description - if existsMapKey(m, KEY_DESCRIPTION) && !isKind(m[KEY_DESCRIPTION], reflect.String) { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": TYPE_STRING, - "given": KEY_DESCRIPTION, - }, - )) - } - if k, ok := m[KEY_DESCRIPTION].(string); ok { - currentSchema.description = &k - } - - // $ref - if existsMapKey(m, KEY_REF) && !isKind(m[KEY_REF], reflect.String) { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": TYPE_STRING, - "given": KEY_REF, - }, - )) - } - - if k, ok := m[KEY_REF].(string); ok { - - jsonReference, err := gojsonreference.NewJsonReference(k) - if err != nil { - return err - } - - currentSchema.ref = &jsonReference - - if sch, ok := d.referencePool.Get(currentSchema.ref.String()); ok { - currentSchema.refSchema = sch - } else { - err := d.parseReference(documentNode, currentSchema) - - if err != nil { - return err - } - - return nil - } - } - - // type - if existsMapKey(m, KEY_TYPE) { - if isKind(m[KEY_TYPE], reflect.String) { - if k, ok := m[KEY_TYPE].(string); ok { - err := currentSchema.types.Add(k) - if err != nil { - return err - } - } - } else { - if isKind(m[KEY_TYPE], reflect.Slice) { - arrayOfTypes := m[KEY_TYPE].([]interface{}) - for _, typeInArray := range arrayOfTypes { - if reflect.ValueOf(typeInArray).Kind() != reflect.String { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": TYPE_STRING + "/" + STRING_ARRAY_OF_STRINGS, - "given": KEY_TYPE, - }, - )) - } - if err := currentSchema.types.Add(typeInArray.(string)); err != nil { - return err - } - } - - } else { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": TYPE_STRING + "/" + STRING_ARRAY_OF_STRINGS, - "given": KEY_TYPE, - }, - )) - } - } - } - - // properties - if existsMapKey(m, KEY_PROPERTIES) { - err := d.parseProperties(m[KEY_PROPERTIES], currentSchema) - if err != nil { - return err - } - } - - // additionalProperties - if existsMapKey(m, KEY_ADDITIONAL_PROPERTIES) { - if isKind(m[KEY_ADDITIONAL_PROPERTIES], reflect.Bool) { - currentSchema.additionalProperties = m[KEY_ADDITIONAL_PROPERTIES].(bool) - } else if isKind(m[KEY_ADDITIONAL_PROPERTIES], reflect.Map) { - newSchema := &subSchema{property: KEY_ADDITIONAL_PROPERTIES, parent: currentSchema, ref: currentSchema.ref} - currentSchema.additionalProperties = newSchema - err := d.parseSchema(m[KEY_ADDITIONAL_PROPERTIES], newSchema) - if err != nil { - return errors.New(err.Error()) - } - } else { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": TYPE_BOOLEAN + "/" + STRING_SCHEMA, - "given": KEY_ADDITIONAL_PROPERTIES, - }, - )) - } - } - - // patternProperties - if existsMapKey(m, KEY_PATTERN_PROPERTIES) { - if isKind(m[KEY_PATTERN_PROPERTIES], reflect.Map) { - patternPropertiesMap := m[KEY_PATTERN_PROPERTIES].(map[string]interface{}) - if len(patternPropertiesMap) > 0 { - currentSchema.patternProperties = make(map[string]*subSchema) - for k, v := range patternPropertiesMap { - _, err := regexp.MatchString(k, "") - if err != nil { - return errors.New(formatErrorDescription( - Locale.RegexPattern(), - ErrorDetails{"pattern": k}, - )) - } - newSchema := &subSchema{property: k, parent: currentSchema, ref: currentSchema.ref} - err = d.parseSchema(v, newSchema) - if err != nil { - return errors.New(err.Error()) - } - currentSchema.patternProperties[k] = newSchema - } - } - } else { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": STRING_SCHEMA, - "given": KEY_PATTERN_PROPERTIES, - }, - )) - } - } - - // propertyNames - if existsMapKey(m, KEY_PROPERTY_NAMES) && *currentSchema.draft >= Draft6 { - if isKind(m[KEY_PROPERTY_NAMES], reflect.Map, reflect.Bool) { - newSchema := &subSchema{property: KEY_PROPERTY_NAMES, parent: currentSchema, ref: currentSchema.ref} - currentSchema.propertyNames = newSchema - err := d.parseSchema(m[KEY_PROPERTY_NAMES], newSchema) - if err != nil { - return err - } - } else { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": STRING_SCHEMA, - "given": KEY_PATTERN_PROPERTIES, - }, - )) - } - } - - // dependencies - if existsMapKey(m, KEY_DEPENDENCIES) { - err := d.parseDependencies(m[KEY_DEPENDENCIES], currentSchema) - if err != nil { - return err - } - } - - // items - if existsMapKey(m, KEY_ITEMS) { - if isKind(m[KEY_ITEMS], reflect.Slice) { - for _, itemElement := range m[KEY_ITEMS].([]interface{}) { - if isKind(itemElement, reflect.Map, reflect.Bool) { - newSchema := &subSchema{parent: currentSchema, property: KEY_ITEMS} - newSchema.ref = currentSchema.ref - currentSchema.itemsChildren = append(currentSchema.itemsChildren, newSchema) - err := d.parseSchema(itemElement, newSchema) - if err != nil { - return err - } - } else { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": STRING_SCHEMA + "/" + STRING_ARRAY_OF_SCHEMAS, - "given": KEY_ITEMS, - }, - )) - } - currentSchema.itemsChildrenIsSingleSchema = false - } - } else if isKind(m[KEY_ITEMS], reflect.Map, reflect.Bool) { - newSchema := &subSchema{parent: currentSchema, property: KEY_ITEMS} - newSchema.ref = currentSchema.ref - currentSchema.itemsChildren = append(currentSchema.itemsChildren, newSchema) - err := d.parseSchema(m[KEY_ITEMS], newSchema) - if err != nil { - return err - } - currentSchema.itemsChildrenIsSingleSchema = true - } else { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": STRING_SCHEMA + "/" + STRING_ARRAY_OF_SCHEMAS, - "given": KEY_ITEMS, - }, - )) - } - } - - // additionalItems - if existsMapKey(m, KEY_ADDITIONAL_ITEMS) { - if isKind(m[KEY_ADDITIONAL_ITEMS], reflect.Bool) { - currentSchema.additionalItems = m[KEY_ADDITIONAL_ITEMS].(bool) - } else if isKind(m[KEY_ADDITIONAL_ITEMS], reflect.Map) { - newSchema := &subSchema{property: KEY_ADDITIONAL_ITEMS, parent: currentSchema, ref: currentSchema.ref} - currentSchema.additionalItems = newSchema - err := d.parseSchema(m[KEY_ADDITIONAL_ITEMS], newSchema) - if err != nil { - return errors.New(err.Error()) - } - } else { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": TYPE_BOOLEAN + "/" + STRING_SCHEMA, - "given": KEY_ADDITIONAL_ITEMS, - }, - )) - } - } - - // validation : number / integer - - if existsMapKey(m, KEY_MULTIPLE_OF) { - multipleOfValue := mustBeNumber(m[KEY_MULTIPLE_OF]) - if multipleOfValue == nil { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": STRING_NUMBER, - "given": KEY_MULTIPLE_OF, - }, - )) - } - if multipleOfValue.Cmp(big.NewRat(0, 1)) <= 0 { - return errors.New(formatErrorDescription( - Locale.GreaterThanZero(), - ErrorDetails{"number": KEY_MULTIPLE_OF}, - )) - } - currentSchema.multipleOf = multipleOfValue - } - - if existsMapKey(m, KEY_MINIMUM) { - minimumValue := mustBeNumber(m[KEY_MINIMUM]) - if minimumValue == nil { - return errors.New(formatErrorDescription( - Locale.MustBeOfA(), - ErrorDetails{"x": KEY_MINIMUM, "y": STRING_NUMBER}, - )) - } - currentSchema.minimum = minimumValue - } - - if existsMapKey(m, KEY_EXCLUSIVE_MINIMUM) { - switch *currentSchema.draft { - case Draft4: - if !isKind(m[KEY_EXCLUSIVE_MINIMUM], reflect.Bool) { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": TYPE_BOOLEAN, - "given": KEY_EXCLUSIVE_MINIMUM, - }, - )) - } - if currentSchema.minimum == nil { - return errors.New(formatErrorDescription( - Locale.CannotBeUsedWithout(), - ErrorDetails{"x": KEY_EXCLUSIVE_MINIMUM, "y": KEY_MINIMUM}, - )) - } - if m[KEY_EXCLUSIVE_MINIMUM].(bool) { - currentSchema.exclusiveMinimum = currentSchema.minimum - currentSchema.minimum = nil - } - case Hybrid: - if isKind(m[KEY_EXCLUSIVE_MINIMUM], reflect.Bool) { - if currentSchema.minimum == nil { - return errors.New(formatErrorDescription( - Locale.CannotBeUsedWithout(), - ErrorDetails{"x": KEY_EXCLUSIVE_MINIMUM, "y": KEY_MINIMUM}, - )) - } - if m[KEY_EXCLUSIVE_MINIMUM].(bool) { - currentSchema.exclusiveMinimum = currentSchema.minimum - currentSchema.minimum = nil - } - } else if isJSONNumber(m[KEY_EXCLUSIVE_MINIMUM]) { - currentSchema.exclusiveMinimum = mustBeNumber(m[KEY_EXCLUSIVE_MINIMUM]) - } else { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": TYPE_BOOLEAN + "/" + TYPE_NUMBER, - "given": KEY_EXCLUSIVE_MINIMUM, - }, - )) - } - default: - if isJSONNumber(m[KEY_EXCLUSIVE_MINIMUM]) { - currentSchema.exclusiveMinimum = mustBeNumber(m[KEY_EXCLUSIVE_MINIMUM]) - } else { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": TYPE_NUMBER, - "given": KEY_EXCLUSIVE_MINIMUM, - }, - )) - } - } - } - - if existsMapKey(m, KEY_MAXIMUM) { - maximumValue := mustBeNumber(m[KEY_MAXIMUM]) - if maximumValue == nil { - return errors.New(formatErrorDescription( - Locale.MustBeOfA(), - ErrorDetails{"x": KEY_MAXIMUM, "y": STRING_NUMBER}, - )) - } - currentSchema.maximum = maximumValue - } - - if existsMapKey(m, KEY_EXCLUSIVE_MAXIMUM) { - switch *currentSchema.draft { - case Draft4: - if !isKind(m[KEY_EXCLUSIVE_MAXIMUM], reflect.Bool) { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": TYPE_BOOLEAN, - "given": KEY_EXCLUSIVE_MAXIMUM, - }, - )) - } - if currentSchema.maximum == nil { - return errors.New(formatErrorDescription( - Locale.CannotBeUsedWithout(), - ErrorDetails{"x": KEY_EXCLUSIVE_MAXIMUM, "y": KEY_MAXIMUM}, - )) - } - if m[KEY_EXCLUSIVE_MAXIMUM].(bool) { - currentSchema.exclusiveMaximum = currentSchema.maximum - currentSchema.maximum = nil - } - case Hybrid: - if isKind(m[KEY_EXCLUSIVE_MAXIMUM], reflect.Bool) { - if currentSchema.maximum == nil { - return errors.New(formatErrorDescription( - Locale.CannotBeUsedWithout(), - ErrorDetails{"x": KEY_EXCLUSIVE_MAXIMUM, "y": KEY_MAXIMUM}, - )) - } - if m[KEY_EXCLUSIVE_MAXIMUM].(bool) { - currentSchema.exclusiveMaximum = currentSchema.maximum - currentSchema.maximum = nil - } - } else if isJSONNumber(m[KEY_EXCLUSIVE_MAXIMUM]) { - currentSchema.exclusiveMaximum = mustBeNumber(m[KEY_EXCLUSIVE_MAXIMUM]) - } else { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": TYPE_BOOLEAN + "/" + TYPE_NUMBER, - "given": KEY_EXCLUSIVE_MAXIMUM, - }, - )) - } - default: - if isJSONNumber(m[KEY_EXCLUSIVE_MAXIMUM]) { - currentSchema.exclusiveMaximum = mustBeNumber(m[KEY_EXCLUSIVE_MAXIMUM]) - } else { - return errors.New(formatErrorDescription( - Locale.InvalidType(), - ErrorDetails{ - "expected": TYPE_NUMBER, - "given": KEY_EXCLUSIVE_MAXIMUM, - }, - )) - } - } - } - - // validation : string - - if existsMapKey(m, KEY_MIN_LENGTH) { - minLengthIntegerValue := mustBeInteger(m[KEY_MIN_LENGTH]) - if minLengthIntegerValue == nil { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_MIN_LENGTH, "y": TYPE_INTEGER}, - )) - } - if *minLengthIntegerValue < 0 { - return errors.New(formatErrorDescription( - Locale.MustBeGTEZero(), - ErrorDetails{"key": KEY_MIN_LENGTH}, - )) - } - currentSchema.minLength = minLengthIntegerValue - } - - if existsMapKey(m, KEY_MAX_LENGTH) { - maxLengthIntegerValue := mustBeInteger(m[KEY_MAX_LENGTH]) - if maxLengthIntegerValue == nil { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_MAX_LENGTH, "y": TYPE_INTEGER}, - )) - } - if *maxLengthIntegerValue < 0 { - return errors.New(formatErrorDescription( - Locale.MustBeGTEZero(), - ErrorDetails{"key": KEY_MAX_LENGTH}, - )) - } - currentSchema.maxLength = maxLengthIntegerValue - } - - if currentSchema.minLength != nil && currentSchema.maxLength != nil { - if *currentSchema.minLength > *currentSchema.maxLength { - return errors.New(formatErrorDescription( - Locale.CannotBeGT(), - ErrorDetails{"x": KEY_MIN_LENGTH, "y": KEY_MAX_LENGTH}, - )) - } - } - - if existsMapKey(m, KEY_PATTERN) { - if isKind(m[KEY_PATTERN], reflect.String) { - regexpObject, err := regexp.Compile(m[KEY_PATTERN].(string)) - if err != nil { - return errors.New(formatErrorDescription( - Locale.MustBeValidRegex(), - ErrorDetails{"key": KEY_PATTERN}, - )) - } - currentSchema.pattern = regexpObject - } else { - return errors.New(formatErrorDescription( - Locale.MustBeOfA(), - ErrorDetails{"x": KEY_PATTERN, "y": TYPE_STRING}, - )) - } - } - - if existsMapKey(m, KEY_FORMAT) { - formatString, ok := m[KEY_FORMAT].(string) - if !ok { - return errors.New(formatErrorDescription( - Locale.MustBeOfType(), - ErrorDetails{"key": KEY_FORMAT, "type": TYPE_STRING}, - )) - } - currentSchema.format = formatString - } - - // validation : object - - if existsMapKey(m, KEY_MIN_PROPERTIES) { - minPropertiesIntegerValue := mustBeInteger(m[KEY_MIN_PROPERTIES]) - if minPropertiesIntegerValue == nil { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_MIN_PROPERTIES, "y": TYPE_INTEGER}, - )) - } - if *minPropertiesIntegerValue < 0 { - return errors.New(formatErrorDescription( - Locale.MustBeGTEZero(), - ErrorDetails{"key": KEY_MIN_PROPERTIES}, - )) - } - currentSchema.minProperties = minPropertiesIntegerValue - } - - if existsMapKey(m, KEY_MAX_PROPERTIES) { - maxPropertiesIntegerValue := mustBeInteger(m[KEY_MAX_PROPERTIES]) - if maxPropertiesIntegerValue == nil { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_MAX_PROPERTIES, "y": TYPE_INTEGER}, - )) - } - if *maxPropertiesIntegerValue < 0 { - return errors.New(formatErrorDescription( - Locale.MustBeGTEZero(), - ErrorDetails{"key": KEY_MAX_PROPERTIES}, - )) - } - currentSchema.maxProperties = maxPropertiesIntegerValue - } - - if currentSchema.minProperties != nil && currentSchema.maxProperties != nil { - if *currentSchema.minProperties > *currentSchema.maxProperties { - return errors.New(formatErrorDescription( - Locale.KeyCannotBeGreaterThan(), - ErrorDetails{"key": KEY_MIN_PROPERTIES, "y": KEY_MAX_PROPERTIES}, - )) - } - } - - if existsMapKey(m, KEY_REQUIRED) { - if isKind(m[KEY_REQUIRED], reflect.Slice) { - requiredValues := m[KEY_REQUIRED].([]interface{}) - for _, requiredValue := range requiredValues { - if isKind(requiredValue, reflect.String) { - if isStringInSlice(currentSchema.required, requiredValue.(string)) { - return errors.New(formatErrorDescription( - Locale.KeyItemsMustBeUnique(), - ErrorDetails{"key": KEY_REQUIRED}, - )) - } - currentSchema.required = append(currentSchema.required, requiredValue.(string)) - } else { - return errors.New(formatErrorDescription( - Locale.KeyItemsMustBeOfType(), - ErrorDetails{"key": KEY_REQUIRED, "type": TYPE_STRING}, - )) - } - } - } else { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_REQUIRED, "y": TYPE_ARRAY}, - )) - } - } - - // validation : array - - if existsMapKey(m, KEY_MIN_ITEMS) { - minItemsIntegerValue := mustBeInteger(m[KEY_MIN_ITEMS]) - if minItemsIntegerValue == nil { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_MIN_ITEMS, "y": TYPE_INTEGER}, - )) - } - if *minItemsIntegerValue < 0 { - return errors.New(formatErrorDescription( - Locale.MustBeGTEZero(), - ErrorDetails{"key": KEY_MIN_ITEMS}, - )) - } - currentSchema.minItems = minItemsIntegerValue - } - - if existsMapKey(m, KEY_MAX_ITEMS) { - maxItemsIntegerValue := mustBeInteger(m[KEY_MAX_ITEMS]) - if maxItemsIntegerValue == nil { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_MAX_ITEMS, "y": TYPE_INTEGER}, - )) - } - if *maxItemsIntegerValue < 0 { - return errors.New(formatErrorDescription( - Locale.MustBeGTEZero(), - ErrorDetails{"key": KEY_MAX_ITEMS}, - )) - } - currentSchema.maxItems = maxItemsIntegerValue - } - - if existsMapKey(m, KEY_UNIQUE_ITEMS) { - if isKind(m[KEY_UNIQUE_ITEMS], reflect.Bool) { - currentSchema.uniqueItems = m[KEY_UNIQUE_ITEMS].(bool) - } else { - return errors.New(formatErrorDescription( - Locale.MustBeOfA(), - ErrorDetails{"x": KEY_UNIQUE_ITEMS, "y": TYPE_BOOLEAN}, - )) - } - } - - if existsMapKey(m, KEY_CONTAINS) && *currentSchema.draft >= Draft6 { - newSchema := &subSchema{property: KEY_CONTAINS, parent: currentSchema, ref: currentSchema.ref} - currentSchema.contains = newSchema - err := d.parseSchema(m[KEY_CONTAINS], newSchema) - if err != nil { - return err - } - } - - // validation : all - - if existsMapKey(m, KEY_CONST) && *currentSchema.draft >= Draft6 { - is, err := marshalWithoutNumber(m[KEY_CONST]) - if err != nil { - return err - } - currentSchema._const = is - } - - if existsMapKey(m, KEY_ENUM) { - if isKind(m[KEY_ENUM], reflect.Slice) { - for _, v := range m[KEY_ENUM].([]interface{}) { - is, err := marshalWithoutNumber(v) - if err != nil { - return err - } - if isStringInSlice(currentSchema.enum, *is) { - return errors.New(formatErrorDescription( - Locale.KeyItemsMustBeUnique(), - ErrorDetails{"key": KEY_ENUM}, - )) - } - currentSchema.enum = append(currentSchema.enum, *is) - } - } else { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_ENUM, "y": TYPE_ARRAY}, - )) - } - } - - // validation : subSchema - - if existsMapKey(m, KEY_ONE_OF) { - if isKind(m[KEY_ONE_OF], reflect.Slice) { - for _, v := range m[KEY_ONE_OF].([]interface{}) { - newSchema := &subSchema{property: KEY_ONE_OF, parent: currentSchema, ref: currentSchema.ref} - currentSchema.oneOf = append(currentSchema.oneOf, newSchema) - err := d.parseSchema(v, newSchema) - if err != nil { - return err - } - } - } else { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_ONE_OF, "y": TYPE_ARRAY}, - )) - } - } - - if existsMapKey(m, KEY_ANY_OF) { - if isKind(m[KEY_ANY_OF], reflect.Slice) { - for _, v := range m[KEY_ANY_OF].([]interface{}) { - newSchema := &subSchema{property: KEY_ANY_OF, parent: currentSchema, ref: currentSchema.ref} - currentSchema.anyOf = append(currentSchema.anyOf, newSchema) - err := d.parseSchema(v, newSchema) - if err != nil { - return err - } - } - } else { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_ANY_OF, "y": TYPE_ARRAY}, - )) - } - } - - if existsMapKey(m, KEY_ALL_OF) { - if isKind(m[KEY_ALL_OF], reflect.Slice) { - for _, v := range m[KEY_ALL_OF].([]interface{}) { - newSchema := &subSchema{property: KEY_ALL_OF, parent: currentSchema, ref: currentSchema.ref} - currentSchema.allOf = append(currentSchema.allOf, newSchema) - err := d.parseSchema(v, newSchema) - if err != nil { - return err - } - } - } else { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_ANY_OF, "y": TYPE_ARRAY}, - )) - } - } - - if existsMapKey(m, KEY_NOT) { - if isKind(m[KEY_NOT], reflect.Map, reflect.Bool) { - newSchema := &subSchema{property: KEY_NOT, parent: currentSchema, ref: currentSchema.ref} - currentSchema.not = newSchema - err := d.parseSchema(m[KEY_NOT], newSchema) - if err != nil { - return err - } - } else { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_NOT, "y": TYPE_OBJECT}, - )) - } - } - - if *currentSchema.draft >= Draft7 { - if existsMapKey(m, KEY_IF) { - if isKind(m[KEY_IF], reflect.Map, reflect.Bool) { - newSchema := &subSchema{property: KEY_IF, parent: currentSchema, ref: currentSchema.ref} - currentSchema._if = newSchema - err := d.parseSchema(m[KEY_IF], newSchema) - if err != nil { - return err - } - } else { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_IF, "y": TYPE_OBJECT}, - )) - } - } - - if existsMapKey(m, KEY_THEN) { - if isKind(m[KEY_THEN], reflect.Map, reflect.Bool) { - newSchema := &subSchema{property: KEY_THEN, parent: currentSchema, ref: currentSchema.ref} - currentSchema._then = newSchema - err := d.parseSchema(m[KEY_THEN], newSchema) - if err != nil { - return err - } - } else { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_THEN, "y": TYPE_OBJECT}, - )) - } - } - - if existsMapKey(m, KEY_ELSE) { - if isKind(m[KEY_ELSE], reflect.Map, reflect.Bool) { - newSchema := &subSchema{property: KEY_ELSE, parent: currentSchema, ref: currentSchema.ref} - currentSchema._else = newSchema - err := d.parseSchema(m[KEY_ELSE], newSchema) - if err != nil { - return err - } - } else { - return errors.New(formatErrorDescription( - Locale.MustBeOfAn(), - ErrorDetails{"x": KEY_ELSE, "y": TYPE_OBJECT}, - )) - } - } - } - - return nil -} - -func (d *Schema) parseReference(documentNode interface{}, currentSchema *subSchema) error { - var ( - refdDocumentNode interface{} - dsp *schemaPoolDocument - err error - ) - - newSchema := &subSchema{property: KEY_REF, parent: currentSchema, ref: currentSchema.ref} - - d.referencePool.Add(currentSchema.ref.String(), newSchema) - - dsp, err = d.pool.GetDocument(*currentSchema.ref) - if err != nil { - return err - } - newSchema.id = currentSchema.ref - - refdDocumentNode = dsp.Document - newSchema.draft = dsp.Draft - - if err != nil { - return err - } - - if !isKind(refdDocumentNode, reflect.Map, reflect.Bool) { - return errors.New(formatErrorDescription( - Locale.MustBeOfType(), - ErrorDetails{"key": STRING_SCHEMA, "type": TYPE_OBJECT}, - )) - } - - err = d.parseSchema(refdDocumentNode, newSchema) - if err != nil { - return err - } - - currentSchema.refSchema = newSchema - - return nil - -} - -func (d *Schema) parseProperties(documentNode interface{}, currentSchema *subSchema) error { - - if !isKind(documentNode, reflect.Map) { - return errors.New(formatErrorDescription( - Locale.MustBeOfType(), - ErrorDetails{"key": STRING_PROPERTIES, "type": TYPE_OBJECT}, - )) - } - - m := documentNode.(map[string]interface{}) - for k := range m { - schemaProperty := k - newSchema := &subSchema{property: schemaProperty, parent: currentSchema, ref: currentSchema.ref} - currentSchema.propertiesChildren = append(currentSchema.propertiesChildren, newSchema) - err := d.parseSchema(m[k], newSchema) - if err != nil { - return err - } - } - - return nil -} - -func (d *Schema) parseDependencies(documentNode interface{}, currentSchema *subSchema) error { - - if !isKind(documentNode, reflect.Map) { - return errors.New(formatErrorDescription( - Locale.MustBeOfType(), - ErrorDetails{"key": KEY_DEPENDENCIES, "type": TYPE_OBJECT}, - )) - } - - m := documentNode.(map[string]interface{}) - currentSchema.dependencies = make(map[string]interface{}) - - for k := range m { - switch reflect.ValueOf(m[k]).Kind() { - - case reflect.Slice: - values := m[k].([]interface{}) - var valuesToRegister []string - - for _, value := range values { - if !isKind(value, reflect.String) { - return errors.New(formatErrorDescription( - Locale.MustBeOfType(), - ErrorDetails{ - "key": STRING_DEPENDENCY, - "type": STRING_SCHEMA_OR_ARRAY_OF_STRINGS, - }, - )) - } - valuesToRegister = append(valuesToRegister, value.(string)) - currentSchema.dependencies[k] = valuesToRegister - } - - case reflect.Map, reflect.Bool: - depSchema := &subSchema{property: k, parent: currentSchema, ref: currentSchema.ref} - err := d.parseSchema(m[k], depSchema) - if err != nil { - return err - } - currentSchema.dependencies[k] = depSchema - - default: - return errors.New(formatErrorDescription( - Locale.MustBeOfType(), - ErrorDetails{ - "key": STRING_DEPENDENCY, - "type": STRING_SCHEMA_OR_ARRAY_OF_STRINGS, - }, - )) - } - - } - - return nil -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/schemaLoader.go b/vendor/github.com/xeipuuv/gojsonschema/schemaLoader.go deleted file mode 100644 index 20db0c1f9..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/schemaLoader.go +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright 2018 johandorland ( https://github.com/johandorland ) -// -// 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 gojsonschema - -import ( - "bytes" - "errors" - - "github.com/xeipuuv/gojsonreference" -) - -// SchemaLoader is used to load schemas -type SchemaLoader struct { - pool *schemaPool - AutoDetect bool - Validate bool - Draft Draft -} - -// NewSchemaLoader creates a new NewSchemaLoader -func NewSchemaLoader() *SchemaLoader { - - ps := &SchemaLoader{ - pool: &schemaPool{ - schemaPoolDocuments: make(map[string]*schemaPoolDocument), - }, - AutoDetect: true, - Validate: false, - Draft: Hybrid, - } - ps.pool.autoDetect = &ps.AutoDetect - - return ps -} - -func (sl *SchemaLoader) validateMetaschema(documentNode interface{}) error { - - var ( - schema string - err error - ) - if sl.AutoDetect { - schema, _, err = parseSchemaURL(documentNode) - if err != nil { - return err - } - } - - // If no explicit "$schema" is used, use the default metaschema associated with the draft used - if schema == "" { - if sl.Draft == Hybrid { - return nil - } - schema = drafts.GetSchemaURL(sl.Draft) - } - - //Disable validation when loading the metaschema to prevent an infinite recursive loop - sl.Validate = false - - metaSchema, err := sl.Compile(NewReferenceLoader(schema)) - - if err != nil { - return err - } - - sl.Validate = true - - result := metaSchema.validateDocument(documentNode) - - if !result.Valid() { - var res bytes.Buffer - for _, err := range result.Errors() { - res.WriteString(err.String()) - res.WriteString("\n") - } - return errors.New(res.String()) - } - - return nil -} - -// AddSchemas adds an arbritrary amount of schemas to the schema cache. As this function does not require -// an explicit URL, every schema should contain an $id, so that it can be referenced by the main schema -func (sl *SchemaLoader) AddSchemas(loaders ...JSONLoader) error { - emptyRef, _ := gojsonreference.NewJsonReference("") - - for _, loader := range loaders { - doc, err := loader.LoadJSON() - - if err != nil { - return err - } - - if sl.Validate { - if err := sl.validateMetaschema(doc); err != nil { - return err - } - } - - // Directly use the Recursive function, so that it get only added to the schema pool by $id - // and not by the ref of the document as it's empty - if err = sl.pool.parseReferences(doc, emptyRef, false); err != nil { - return err - } - } - - return nil -} - -//AddSchema adds a schema under the provided URL to the schema cache -func (sl *SchemaLoader) AddSchema(url string, loader JSONLoader) error { - - ref, err := gojsonreference.NewJsonReference(url) - - if err != nil { - return err - } - - doc, err := loader.LoadJSON() - - if err != nil { - return err - } - - if sl.Validate { - if err := sl.validateMetaschema(doc); err != nil { - return err - } - } - - return sl.pool.parseReferences(doc, ref, true) -} - -// Compile loads and compiles a schema -func (sl *SchemaLoader) Compile(rootSchema JSONLoader) (*Schema, error) { - - ref, err := rootSchema.JsonReference() - - if err != nil { - return nil, err - } - - d := Schema{} - d.pool = sl.pool - d.pool.jsonLoaderFactory = rootSchema.LoaderFactory() - d.documentReference = ref - d.referencePool = newSchemaReferencePool() - - var doc interface{} - if ref.String() != "" { - // Get document from schema pool - spd, err := d.pool.GetDocument(d.documentReference) - if err != nil { - return nil, err - } - doc = spd.Document - } else { - // Load JSON directly - doc, err = rootSchema.LoadJSON() - if err != nil { - return nil, err - } - // References need only be parsed if loading JSON directly - // as pool.GetDocument already does this for us if loading by reference - err = sl.pool.parseReferences(doc, ref, true) - if err != nil { - return nil, err - } - } - - if sl.Validate { - if err := sl.validateMetaschema(doc); err != nil { - return nil, err - } - } - - draft := sl.Draft - if sl.AutoDetect { - _, detectedDraft, err := parseSchemaURL(doc) - if err != nil { - return nil, err - } - if detectedDraft != nil { - draft = *detectedDraft - } - } - - err = d.parse(doc, draft) - if err != nil { - return nil, err - } - - return &d, nil -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/schemaPool.go b/vendor/github.com/xeipuuv/gojsonschema/schemaPool.go deleted file mode 100644 index 35b1cc630..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/schemaPool.go +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) -// -// 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. - -// author xeipuuv -// author-github https://github.com/xeipuuv -// author-mail xeipuuv@gmail.com -// -// repository-name gojsonschema -// repository-desc An implementation of JSON Schema, based on IETF's draft v4 - Go language. -// -// description Defines resources pooling. -// Eases referencing and avoids downloading the same resource twice. -// -// created 26-02-2013 - -package gojsonschema - -import ( - "errors" - "fmt" - "reflect" - - "github.com/xeipuuv/gojsonreference" -) - -type schemaPoolDocument struct { - Document interface{} - Draft *Draft -} - -type schemaPool struct { - schemaPoolDocuments map[string]*schemaPoolDocument - jsonLoaderFactory JSONLoaderFactory - autoDetect *bool -} - -func (p *schemaPool) parseReferences(document interface{}, ref gojsonreference.JsonReference, pooled bool) error { - - var ( - draft *Draft - err error - reference = ref.String() - ) - // Only the root document should be added to the schema pool if pooled is true - if _, ok := p.schemaPoolDocuments[reference]; pooled && ok { - return fmt.Errorf("Reference already exists: \"%s\"", reference) - } - - if *p.autoDetect { - _, draft, err = parseSchemaURL(document) - if err != nil { - return err - } - } - - err = p.parseReferencesRecursive(document, ref, draft) - - if pooled { - p.schemaPoolDocuments[reference] = &schemaPoolDocument{Document: document, Draft: draft} - } - - return err -} - -func (p *schemaPool) parseReferencesRecursive(document interface{}, ref gojsonreference.JsonReference, draft *Draft) error { - // parseReferencesRecursive parses a JSON document and resolves all $id and $ref references. - // For $ref references it takes into account the $id scope it is in and replaces - // the reference by the absolute resolved reference - - // When encountering errors it fails silently. Error handling is done when the schema - // is syntactically parsed and any error encountered here should also come up there. - switch m := document.(type) { - case []interface{}: - for _, v := range m { - p.parseReferencesRecursive(v, ref, draft) - } - case map[string]interface{}: - localRef := &ref - - keyID := KEY_ID_NEW - if existsMapKey(m, KEY_ID) { - keyID = KEY_ID - } - if existsMapKey(m, keyID) && isKind(m[keyID], reflect.String) { - jsonReference, err := gojsonreference.NewJsonReference(m[keyID].(string)) - if err == nil { - localRef, err = ref.Inherits(jsonReference) - if err == nil { - if _, ok := p.schemaPoolDocuments[localRef.String()]; ok { - return fmt.Errorf("Reference already exists: \"%s\"", localRef.String()) - } - p.schemaPoolDocuments[localRef.String()] = &schemaPoolDocument{Document: document, Draft: draft} - } - } - } - - if existsMapKey(m, KEY_REF) && isKind(m[KEY_REF], reflect.String) { - jsonReference, err := gojsonreference.NewJsonReference(m[KEY_REF].(string)) - if err == nil { - absoluteRef, err := localRef.Inherits(jsonReference) - if err == nil { - m[KEY_REF] = absoluteRef.String() - } - } - } - - for k, v := range m { - // const and enums should be interpreted literally, so ignore them - if k == KEY_CONST || k == KEY_ENUM { - continue - } - // Something like a property or a dependency is not a valid schema, as it might describe properties named "$ref", "$id" or "const", etc - // Therefore don't treat it like a schema. - if k == KEY_PROPERTIES || k == KEY_DEPENDENCIES || k == KEY_PATTERN_PROPERTIES { - if child, ok := v.(map[string]interface{}); ok { - for _, v := range child { - p.parseReferencesRecursive(v, *localRef, draft) - } - } - } else { - p.parseReferencesRecursive(v, *localRef, draft) - } - } - } - return nil -} - -func (p *schemaPool) GetDocument(reference gojsonreference.JsonReference) (*schemaPoolDocument, error) { - - var ( - spd *schemaPoolDocument - draft *Draft - ok bool - err error - ) - - if internalLogEnabled { - internalLog("Get Document ( %s )", reference.String()) - } - - // Create a deep copy, so we can remove the fragment part later on without altering the original - refToURL, _ := gojsonreference.NewJsonReference(reference.String()) - - // First check if the given fragment is a location independent identifier - // http://json-schema.org/latest/json-schema-core.html#rfc.section.8.2.3 - - if spd, ok = p.schemaPoolDocuments[refToURL.String()]; ok { - if internalLogEnabled { - internalLog(" From pool") - } - return spd, nil - } - - // If the given reference is not a location independent identifier, - // strip the fragment and look for a document with it's base URI - - refToURL.GetUrl().Fragment = "" - - if cachedSpd, ok := p.schemaPoolDocuments[refToURL.String()]; ok { - document, _, err := reference.GetPointer().Get(cachedSpd.Document) - - if err != nil { - return nil, err - } - - if internalLogEnabled { - internalLog(" From pool") - } - - spd = &schemaPoolDocument{Document: document, Draft: cachedSpd.Draft} - p.schemaPoolDocuments[reference.String()] = spd - - return spd, nil - } - - // It is not possible to load anything remotely that is not canonical... - if !reference.IsCanonical() { - return nil, errors.New(formatErrorDescription( - Locale.ReferenceMustBeCanonical(), - ErrorDetails{"reference": reference.String()}, - )) - } - - jsonReferenceLoader := p.jsonLoaderFactory.New(reference.String()) - document, err := jsonReferenceLoader.LoadJSON() - - if err != nil { - return nil, err - } - - // add the whole document to the pool for potential re-use - p.parseReferences(document, refToURL, true) - - _, draft, _ = parseSchemaURL(document) - - // resolve the potential fragment and also cache it - document, _, err = reference.GetPointer().Get(document) - - if err != nil { - return nil, err - } - - return &schemaPoolDocument{Document: document, Draft: draft}, nil -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/schemaReferencePool.go b/vendor/github.com/xeipuuv/gojsonschema/schemaReferencePool.go deleted file mode 100644 index 6e5e1b5cd..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/schemaReferencePool.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) -// -// 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. - -// author xeipuuv -// author-github https://github.com/xeipuuv -// author-mail xeipuuv@gmail.com -// -// repository-name gojsonschema -// repository-desc An implementation of JSON Schema, based on IETF's draft v4 - Go language. -// -// description Pool of referenced schemas. -// -// created 25-06-2013 - -package gojsonschema - -import ( - "fmt" -) - -type schemaReferencePool struct { - documents map[string]*subSchema -} - -func newSchemaReferencePool() *schemaReferencePool { - - p := &schemaReferencePool{} - p.documents = make(map[string]*subSchema) - - return p -} - -func (p *schemaReferencePool) Get(ref string) (r *subSchema, o bool) { - - if internalLogEnabled { - internalLog(fmt.Sprintf("Schema Reference ( %s )", ref)) - } - - if sch, ok := p.documents[ref]; ok { - if internalLogEnabled { - internalLog(fmt.Sprintf(" From pool")) - } - return sch, true - } - - return nil, false -} - -func (p *schemaReferencePool) Add(ref string, sch *subSchema) { - - if internalLogEnabled { - internalLog(fmt.Sprintf("Add Schema Reference %s to pool", ref)) - } - if _, ok := p.documents[ref]; !ok { - p.documents[ref] = sch - } -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/schemaType.go b/vendor/github.com/xeipuuv/gojsonschema/schemaType.go deleted file mode 100644 index 36b447a29..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/schemaType.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) -// -// 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. - -// author xeipuuv -// author-github https://github.com/xeipuuv -// author-mail xeipuuv@gmail.com -// -// repository-name gojsonschema -// repository-desc An implementation of JSON Schema, based on IETF's draft v4 - Go language. -// -// description Helper structure to handle schema types, and the combination of them. -// -// created 28-02-2013 - -package gojsonschema - -import ( - "errors" - "fmt" - "strings" -) - -type jsonSchemaType struct { - types []string -} - -// Is the schema typed ? that is containing at least one type -// When not typed, the schema does not need any type validation -func (t *jsonSchemaType) IsTyped() bool { - return len(t.types) > 0 -} - -func (t *jsonSchemaType) Add(etype string) error { - - if !isStringInSlice(JSON_TYPES, etype) { - return errors.New(formatErrorDescription(Locale.NotAValidType(), ErrorDetails{"given": "/" + etype + "/", "expected": JSON_TYPES})) - } - - if t.Contains(etype) { - return errors.New(formatErrorDescription(Locale.Duplicated(), ErrorDetails{"type": etype})) - } - - t.types = append(t.types, etype) - - return nil -} - -func (t *jsonSchemaType) Contains(etype string) bool { - - for _, v := range t.types { - if v == etype { - return true - } - } - - return false -} - -func (t *jsonSchemaType) String() string { - - if len(t.types) == 0 { - return STRING_UNDEFINED // should never happen - } - - // Displayed as a list [type1,type2,...] - if len(t.types) > 1 { - return fmt.Sprintf("[%s]", strings.Join(t.types, ",")) - } - - // Only one type: name only - return t.types[0] -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/subSchema.go b/vendor/github.com/xeipuuv/gojsonschema/subSchema.go deleted file mode 100644 index ec779812c..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/subSchema.go +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) -// -// 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. - -// author xeipuuv -// author-github https://github.com/xeipuuv -// author-mail xeipuuv@gmail.com -// -// repository-name gojsonschema -// repository-desc An implementation of JSON Schema, based on IETF's draft v4 - Go language. -// -// description Defines the structure of a sub-subSchema. -// A sub-subSchema can contain other sub-schemas. -// -// created 27-02-2013 - -package gojsonschema - -import ( - "github.com/xeipuuv/gojsonreference" - "math/big" - "regexp" -) - -// Constants -const ( - KEY_SCHEMA = "$schema" - KEY_ID = "id" - KEY_ID_NEW = "$id" - KEY_REF = "$ref" - KEY_TITLE = "title" - KEY_DESCRIPTION = "description" - KEY_TYPE = "type" - KEY_ITEMS = "items" - KEY_ADDITIONAL_ITEMS = "additionalItems" - KEY_PROPERTIES = "properties" - KEY_PATTERN_PROPERTIES = "patternProperties" - KEY_ADDITIONAL_PROPERTIES = "additionalProperties" - KEY_PROPERTY_NAMES = "propertyNames" - KEY_DEFINITIONS = "definitions" - KEY_MULTIPLE_OF = "multipleOf" - KEY_MINIMUM = "minimum" - KEY_MAXIMUM = "maximum" - KEY_EXCLUSIVE_MINIMUM = "exclusiveMinimum" - KEY_EXCLUSIVE_MAXIMUM = "exclusiveMaximum" - KEY_MIN_LENGTH = "minLength" - KEY_MAX_LENGTH = "maxLength" - KEY_PATTERN = "pattern" - KEY_FORMAT = "format" - KEY_MIN_PROPERTIES = "minProperties" - KEY_MAX_PROPERTIES = "maxProperties" - KEY_DEPENDENCIES = "dependencies" - KEY_REQUIRED = "required" - KEY_MIN_ITEMS = "minItems" - KEY_MAX_ITEMS = "maxItems" - KEY_UNIQUE_ITEMS = "uniqueItems" - KEY_CONTAINS = "contains" - KEY_CONST = "const" - KEY_ENUM = "enum" - KEY_ONE_OF = "oneOf" - KEY_ANY_OF = "anyOf" - KEY_ALL_OF = "allOf" - KEY_NOT = "not" - KEY_IF = "if" - KEY_THEN = "then" - KEY_ELSE = "else" -) - -type subSchema struct { - draft *Draft - - // basic subSchema meta properties - id *gojsonreference.JsonReference - title *string - description *string - - property string - - // Quick pass/fail for boolean schemas - pass *bool - - // Types associated with the subSchema - types jsonSchemaType - - // Reference url - ref *gojsonreference.JsonReference - // Schema referenced - refSchema *subSchema - - // hierarchy - parent *subSchema - itemsChildren []*subSchema - itemsChildrenIsSingleSchema bool - propertiesChildren []*subSchema - - // validation : number / integer - multipleOf *big.Rat - maximum *big.Rat - exclusiveMaximum *big.Rat - minimum *big.Rat - exclusiveMinimum *big.Rat - - // validation : string - minLength *int - maxLength *int - pattern *regexp.Regexp - format string - - // validation : object - minProperties *int - maxProperties *int - required []string - - dependencies map[string]interface{} - additionalProperties interface{} - patternProperties map[string]*subSchema - propertyNames *subSchema - - // validation : array - minItems *int - maxItems *int - uniqueItems bool - contains *subSchema - - additionalItems interface{} - - // validation : all - _const *string //const is a golang keyword - enum []string - - // validation : subSchema - oneOf []*subSchema - anyOf []*subSchema - allOf []*subSchema - not *subSchema - _if *subSchema // if/else are golang keywords - _then *subSchema - _else *subSchema -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/types.go b/vendor/github.com/xeipuuv/gojsonschema/types.go deleted file mode 100644 index 0e6fd5173..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/types.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) -// -// 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. - -// author xeipuuv -// author-github https://github.com/xeipuuv -// author-mail xeipuuv@gmail.com -// -// repository-name gojsonschema -// repository-desc An implementation of JSON Schema, based on IETF's draft v4 - Go language. -// -// description Contains const types for schema and JSON. -// -// created 28-02-2013 - -package gojsonschema - -// Type constants -const ( - TYPE_ARRAY = `array` - TYPE_BOOLEAN = `boolean` - TYPE_INTEGER = `integer` - TYPE_NUMBER = `number` - TYPE_NULL = `null` - TYPE_OBJECT = `object` - TYPE_STRING = `string` -) - -// JSON_TYPES hosts the list of type that are supported in JSON -var JSON_TYPES []string - -// SCHEMA_TYPES hosts the list of type that are supported in schemas -var SCHEMA_TYPES []string - -func init() { - JSON_TYPES = []string{ - TYPE_ARRAY, - TYPE_BOOLEAN, - TYPE_INTEGER, - TYPE_NUMBER, - TYPE_NULL, - TYPE_OBJECT, - TYPE_STRING} - - SCHEMA_TYPES = []string{ - TYPE_ARRAY, - TYPE_BOOLEAN, - TYPE_INTEGER, - TYPE_NUMBER, - TYPE_OBJECT, - TYPE_STRING} -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/utils.go b/vendor/github.com/xeipuuv/gojsonschema/utils.go deleted file mode 100644 index a17d22e3b..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/utils.go +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) -// -// 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. - -// author xeipuuv -// author-github https://github.com/xeipuuv -// author-mail xeipuuv@gmail.com -// -// repository-name gojsonschema -// repository-desc An implementation of JSON Schema, based on IETF's draft v4 - Go language. -// -// description Various utility functions. -// -// created 26-02-2013 - -package gojsonschema - -import ( - "encoding/json" - "math/big" - "reflect" -) - -func isKind(what interface{}, kinds ...reflect.Kind) bool { - target := what - if isJSONNumber(what) { - // JSON Numbers are strings! - target = *mustBeNumber(what) - } - targetKind := reflect.ValueOf(target).Kind() - for _, kind := range kinds { - if targetKind == kind { - return true - } - } - return false -} - -func existsMapKey(m map[string]interface{}, k string) bool { - _, ok := m[k] - return ok -} - -func isStringInSlice(s []string, what string) bool { - for i := range s { - if s[i] == what { - return true - } - } - return false -} - -// indexStringInSlice returns the index of the first instance of 'what' in s or -1 if it is not found in s. -func indexStringInSlice(s []string, what string) int { - for i := range s { - if s[i] == what { - return i - } - } - return -1 -} - -func marshalToJSONString(value interface{}) (*string, error) { - - mBytes, err := json.Marshal(value) - if err != nil { - return nil, err - } - - sBytes := string(mBytes) - return &sBytes, nil -} - -func marshalWithoutNumber(value interface{}) (*string, error) { - - // The JSON is decoded using https://golang.org/pkg/encoding/json/#Decoder.UseNumber - // This means the numbers are internally still represented as strings and therefore 1.00 is unequal to 1 - // One way to eliminate these differences is to decode and encode the JSON one more time without Decoder.UseNumber - // so that these differences in representation are removed - - jsonString, err := marshalToJSONString(value) - if err != nil { - return nil, err - } - - var document interface{} - - err = json.Unmarshal([]byte(*jsonString), &document) - if err != nil { - return nil, err - } - - return marshalToJSONString(document) -} - -func isJSONNumber(what interface{}) bool { - - switch what.(type) { - - case json.Number: - return true - } - - return false -} - -func checkJSONInteger(what interface{}) (isInt bool) { - - jsonNumber := what.(json.Number) - - bigFloat, isValidNumber := new(big.Rat).SetString(string(jsonNumber)) - - return isValidNumber && bigFloat.IsInt() - -} - -// same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER -const ( - maxJSONFloat = float64(1<<53 - 1) // 9007199254740991.0 2^53 - 1 - minJSONFloat = -float64(1<<53 - 1) //-9007199254740991.0 -2^53 - 1 -) - -func mustBeInteger(what interface{}) *int { - - if isJSONNumber(what) { - - number := what.(json.Number) - - isInt := checkJSONInteger(number) - - if isInt { - - int64Value, err := number.Int64() - if err != nil { - return nil - } - - int32Value := int(int64Value) - return &int32Value - } - - } - - return nil -} - -func mustBeNumber(what interface{}) *big.Rat { - - if isJSONNumber(what) { - number := what.(json.Number) - float64Value, success := new(big.Rat).SetString(string(number)) - if success { - return float64Value - } - } - - return nil - -} - -func convertDocumentNode(val interface{}) interface{} { - - if lval, ok := val.([]interface{}); ok { - - res := []interface{}{} - for _, v := range lval { - res = append(res, convertDocumentNode(v)) - } - - return res - - } - - if mval, ok := val.(map[interface{}]interface{}); ok { - - res := map[string]interface{}{} - - for k, v := range mval { - res[k.(string)] = convertDocumentNode(v) - } - - return res - - } - - return val -} diff --git a/vendor/github.com/xeipuuv/gojsonschema/validation.go b/vendor/github.com/xeipuuv/gojsonschema/validation.go deleted file mode 100644 index 74091bca1..000000000 --- a/vendor/github.com/xeipuuv/gojsonschema/validation.go +++ /dev/null @@ -1,858 +0,0 @@ -// Copyright 2015 xeipuuv ( https://github.com/xeipuuv ) -// -// 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. - -// author xeipuuv -// author-github https://github.com/xeipuuv -// author-mail xeipuuv@gmail.com -// -// repository-name gojsonschema -// repository-desc An implementation of JSON Schema, based on IETF's draft v4 - Go language. -// -// description Extends Schema and subSchema, implements the validation phase. -// -// created 28-02-2013 - -package gojsonschema - -import ( - "encoding/json" - "math/big" - "reflect" - "regexp" - "strconv" - "strings" - "unicode/utf8" -) - -// Validate loads and validates a JSON schema -func Validate(ls JSONLoader, ld JSONLoader) (*Result, error) { - // load schema - schema, err := NewSchema(ls) - if err != nil { - return nil, err - } - return schema.Validate(ld) -} - -// Validate loads and validates a JSON document -func (v *Schema) Validate(l JSONLoader) (*Result, error) { - root, err := l.LoadJSON() - if err != nil { - return nil, err - } - return v.validateDocument(root), nil -} - -func (v *Schema) validateDocument(root interface{}) *Result { - result := &Result{} - context := NewJsonContext(STRING_CONTEXT_ROOT, nil) - v.rootSchema.validateRecursive(v.rootSchema, root, result, context) - return result -} - -func (v *subSchema) subValidateWithContext(document interface{}, context *JsonContext) *Result { - result := &Result{} - v.validateRecursive(v, document, result, context) - return result -} - -// Walker function to validate the json recursively against the subSchema -func (v *subSchema) validateRecursive(currentSubSchema *subSchema, currentNode interface{}, result *Result, context *JsonContext) { - - if internalLogEnabled { - internalLog("validateRecursive %s", context.String()) - internalLog(" %v", currentNode) - } - - // Handle true/false schema as early as possible as all other fields will be nil - if currentSubSchema.pass != nil { - if !*currentSubSchema.pass { - result.addInternalError( - new(FalseError), - context, - currentNode, - ErrorDetails{}, - ) - } - return - } - - // Handle referenced schemas, returns directly when a $ref is found - if currentSubSchema.refSchema != nil { - v.validateRecursive(currentSubSchema.refSchema, currentNode, result, context) - return - } - - // Check for null value - if currentNode == nil { - if currentSubSchema.types.IsTyped() && !currentSubSchema.types.Contains(TYPE_NULL) { - result.addInternalError( - new(InvalidTypeError), - context, - currentNode, - ErrorDetails{ - "expected": currentSubSchema.types.String(), - "given": TYPE_NULL, - }, - ) - return - } - - currentSubSchema.validateSchema(currentSubSchema, currentNode, result, context) - v.validateCommon(currentSubSchema, currentNode, result, context) - - } else { // Not a null value - - if isJSONNumber(currentNode) { - - value := currentNode.(json.Number) - - isInt := checkJSONInteger(value) - - validType := currentSubSchema.types.Contains(TYPE_NUMBER) || (isInt && currentSubSchema.types.Contains(TYPE_INTEGER)) - - if currentSubSchema.types.IsTyped() && !validType { - - givenType := TYPE_INTEGER - if !isInt { - givenType = TYPE_NUMBER - } - - result.addInternalError( - new(InvalidTypeError), - context, - currentNode, - ErrorDetails{ - "expected": currentSubSchema.types.String(), - "given": givenType, - }, - ) - return - } - - currentSubSchema.validateSchema(currentSubSchema, value, result, context) - v.validateNumber(currentSubSchema, value, result, context) - v.validateCommon(currentSubSchema, value, result, context) - v.validateString(currentSubSchema, value, result, context) - - } else { - - rValue := reflect.ValueOf(currentNode) - rKind := rValue.Kind() - - switch rKind { - - // Slice => JSON array - - case reflect.Slice: - - if currentSubSchema.types.IsTyped() && !currentSubSchema.types.Contains(TYPE_ARRAY) { - result.addInternalError( - new(InvalidTypeError), - context, - currentNode, - ErrorDetails{ - "expected": currentSubSchema.types.String(), - "given": TYPE_ARRAY, - }, - ) - return - } - - castCurrentNode := currentNode.([]interface{}) - - currentSubSchema.validateSchema(currentSubSchema, castCurrentNode, result, context) - - v.validateArray(currentSubSchema, castCurrentNode, result, context) - v.validateCommon(currentSubSchema, castCurrentNode, result, context) - - // Map => JSON object - - case reflect.Map: - if currentSubSchema.types.IsTyped() && !currentSubSchema.types.Contains(TYPE_OBJECT) { - result.addInternalError( - new(InvalidTypeError), - context, - currentNode, - ErrorDetails{ - "expected": currentSubSchema.types.String(), - "given": TYPE_OBJECT, - }, - ) - return - } - - castCurrentNode, ok := currentNode.(map[string]interface{}) - if !ok { - castCurrentNode = convertDocumentNode(currentNode).(map[string]interface{}) - } - - currentSubSchema.validateSchema(currentSubSchema, castCurrentNode, result, context) - - v.validateObject(currentSubSchema, castCurrentNode, result, context) - v.validateCommon(currentSubSchema, castCurrentNode, result, context) - - for _, pSchema := range currentSubSchema.propertiesChildren { - nextNode, ok := castCurrentNode[pSchema.property] - if ok { - subContext := NewJsonContext(pSchema.property, context) - v.validateRecursive(pSchema, nextNode, result, subContext) - } - } - - // Simple JSON values : string, number, boolean - - case reflect.Bool: - - if currentSubSchema.types.IsTyped() && !currentSubSchema.types.Contains(TYPE_BOOLEAN) { - result.addInternalError( - new(InvalidTypeError), - context, - currentNode, - ErrorDetails{ - "expected": currentSubSchema.types.String(), - "given": TYPE_BOOLEAN, - }, - ) - return - } - - value := currentNode.(bool) - - currentSubSchema.validateSchema(currentSubSchema, value, result, context) - v.validateNumber(currentSubSchema, value, result, context) - v.validateCommon(currentSubSchema, value, result, context) - v.validateString(currentSubSchema, value, result, context) - - case reflect.String: - - if currentSubSchema.types.IsTyped() && !currentSubSchema.types.Contains(TYPE_STRING) { - result.addInternalError( - new(InvalidTypeError), - context, - currentNode, - ErrorDetails{ - "expected": currentSubSchema.types.String(), - "given": TYPE_STRING, - }, - ) - return - } - - value := currentNode.(string) - - currentSubSchema.validateSchema(currentSubSchema, value, result, context) - v.validateNumber(currentSubSchema, value, result, context) - v.validateCommon(currentSubSchema, value, result, context) - v.validateString(currentSubSchema, value, result, context) - - } - - } - - } - - result.incrementScore() -} - -// Different kinds of validation there, subSchema / common / array / object / string... -func (v *subSchema) validateSchema(currentSubSchema *subSchema, currentNode interface{}, result *Result, context *JsonContext) { - - if internalLogEnabled { - internalLog("validateSchema %s", context.String()) - internalLog(" %v", currentNode) - } - - if len(currentSubSchema.anyOf) > 0 { - - validatedAnyOf := false - var bestValidationResult *Result - - for _, anyOfSchema := range currentSubSchema.anyOf { - if !validatedAnyOf { - validationResult := anyOfSchema.subValidateWithContext(currentNode, context) - validatedAnyOf = validationResult.Valid() - - if !validatedAnyOf && (bestValidationResult == nil || validationResult.score > bestValidationResult.score) { - bestValidationResult = validationResult - } - } - } - if !validatedAnyOf { - - result.addInternalError(new(NumberAnyOfError), context, currentNode, ErrorDetails{}) - - if bestValidationResult != nil { - // add error messages of closest matching subSchema as - // that's probably the one the user was trying to match - result.mergeErrors(bestValidationResult) - } - } - } - - if len(currentSubSchema.oneOf) > 0 { - - nbValidated := 0 - var bestValidationResult *Result - - for _, oneOfSchema := range currentSubSchema.oneOf { - validationResult := oneOfSchema.subValidateWithContext(currentNode, context) - if validationResult.Valid() { - nbValidated++ - } else if nbValidated == 0 && (bestValidationResult == nil || validationResult.score > bestValidationResult.score) { - bestValidationResult = validationResult - } - } - - if nbValidated != 1 { - - result.addInternalError(new(NumberOneOfError), context, currentNode, ErrorDetails{}) - - if nbValidated == 0 { - // add error messages of closest matching subSchema as - // that's probably the one the user was trying to match - result.mergeErrors(bestValidationResult) - } - } - - } - - if len(currentSubSchema.allOf) > 0 { - nbValidated := 0 - - for _, allOfSchema := range currentSubSchema.allOf { - validationResult := allOfSchema.subValidateWithContext(currentNode, context) - if validationResult.Valid() { - nbValidated++ - } - result.mergeErrors(validationResult) - } - - if nbValidated != len(currentSubSchema.allOf) { - result.addInternalError(new(NumberAllOfError), context, currentNode, ErrorDetails{}) - } - } - - if currentSubSchema.not != nil { - validationResult := currentSubSchema.not.subValidateWithContext(currentNode, context) - if validationResult.Valid() { - result.addInternalError(new(NumberNotError), context, currentNode, ErrorDetails{}) - } - } - - if currentSubSchema.dependencies != nil && len(currentSubSchema.dependencies) > 0 { - if isKind(currentNode, reflect.Map) { - for elementKey := range currentNode.(map[string]interface{}) { - if dependency, ok := currentSubSchema.dependencies[elementKey]; ok { - switch dependency := dependency.(type) { - - case []string: - for _, dependOnKey := range dependency { - if _, dependencyResolved := currentNode.(map[string]interface{})[dependOnKey]; !dependencyResolved { - result.addInternalError( - new(MissingDependencyError), - context, - currentNode, - ErrorDetails{"dependency": dependOnKey}, - ) - } - } - - case *subSchema: - dependency.validateRecursive(dependency, currentNode, result, context) - } - } - } - } - } - - if currentSubSchema._if != nil { - validationResultIf := currentSubSchema._if.subValidateWithContext(currentNode, context) - if currentSubSchema._then != nil && validationResultIf.Valid() { - validationResultThen := currentSubSchema._then.subValidateWithContext(currentNode, context) - if !validationResultThen.Valid() { - result.addInternalError(new(ConditionThenError), context, currentNode, ErrorDetails{}) - result.mergeErrors(validationResultThen) - } - } - if currentSubSchema._else != nil && !validationResultIf.Valid() { - validationResultElse := currentSubSchema._else.subValidateWithContext(currentNode, context) - if !validationResultElse.Valid() { - result.addInternalError(new(ConditionElseError), context, currentNode, ErrorDetails{}) - result.mergeErrors(validationResultElse) - } - } - } - - result.incrementScore() -} - -func (v *subSchema) validateCommon(currentSubSchema *subSchema, value interface{}, result *Result, context *JsonContext) { - - if internalLogEnabled { - internalLog("validateCommon %s", context.String()) - internalLog(" %v", value) - } - - // const: - if currentSubSchema._const != nil { - vString, err := marshalWithoutNumber(value) - if err != nil { - result.addInternalError(new(InternalError), context, value, ErrorDetails{"error": err}) - } - if *vString != *currentSubSchema._const { - result.addInternalError(new(ConstError), - context, - value, - ErrorDetails{ - "allowed": *currentSubSchema._const, - }, - ) - } - } - - // enum: - if len(currentSubSchema.enum) > 0 { - vString, err := marshalWithoutNumber(value) - if err != nil { - result.addInternalError(new(InternalError), context, value, ErrorDetails{"error": err}) - } - if !isStringInSlice(currentSubSchema.enum, *vString) { - result.addInternalError( - new(EnumError), - context, - value, - ErrorDetails{ - "allowed": strings.Join(currentSubSchema.enum, ", "), - }, - ) - } - } - - result.incrementScore() -} - -func (v *subSchema) validateArray(currentSubSchema *subSchema, value []interface{}, result *Result, context *JsonContext) { - - if internalLogEnabled { - internalLog("validateArray %s", context.String()) - internalLog(" %v", value) - } - - nbValues := len(value) - - // TODO explain - if currentSubSchema.itemsChildrenIsSingleSchema { - for i := range value { - subContext := NewJsonContext(strconv.Itoa(i), context) - validationResult := currentSubSchema.itemsChildren[0].subValidateWithContext(value[i], subContext) - result.mergeErrors(validationResult) - } - } else { - if currentSubSchema.itemsChildren != nil && len(currentSubSchema.itemsChildren) > 0 { - - nbItems := len(currentSubSchema.itemsChildren) - - // while we have both schemas and values, check them against each other - for i := 0; i != nbItems && i != nbValues; i++ { - subContext := NewJsonContext(strconv.Itoa(i), context) - validationResult := currentSubSchema.itemsChildren[i].subValidateWithContext(value[i], subContext) - result.mergeErrors(validationResult) - } - - if nbItems < nbValues { - // we have less schemas than elements in the instance array, - // but that might be ok if "additionalItems" is specified. - - switch currentSubSchema.additionalItems.(type) { - case bool: - if !currentSubSchema.additionalItems.(bool) { - result.addInternalError(new(ArrayNoAdditionalItemsError), context, value, ErrorDetails{}) - } - case *subSchema: - additionalItemSchema := currentSubSchema.additionalItems.(*subSchema) - for i := nbItems; i != nbValues; i++ { - subContext := NewJsonContext(strconv.Itoa(i), context) - validationResult := additionalItemSchema.subValidateWithContext(value[i], subContext) - result.mergeErrors(validationResult) - } - } - } - } - } - - // minItems & maxItems - if currentSubSchema.minItems != nil { - if nbValues < int(*currentSubSchema.minItems) { - result.addInternalError( - new(ArrayMinItemsError), - context, - value, - ErrorDetails{"min": *currentSubSchema.minItems}, - ) - } - } - if currentSubSchema.maxItems != nil { - if nbValues > int(*currentSubSchema.maxItems) { - result.addInternalError( - new(ArrayMaxItemsError), - context, - value, - ErrorDetails{"max": *currentSubSchema.maxItems}, - ) - } - } - - // uniqueItems: - if currentSubSchema.uniqueItems { - var stringifiedItems = make(map[string]int) - for j, v := range value { - vString, err := marshalWithoutNumber(v) - if err != nil { - result.addInternalError(new(InternalError), context, value, ErrorDetails{"err": err}) - } - if i, ok := stringifiedItems[*vString]; ok { - result.addInternalError( - new(ItemsMustBeUniqueError), - context, - value, - ErrorDetails{"type": TYPE_ARRAY, "i": i, "j": j}, - ) - } - stringifiedItems[*vString] = j - } - } - - // contains: - - if currentSubSchema.contains != nil { - validatedOne := false - var bestValidationResult *Result - - for i, v := range value { - subContext := NewJsonContext(strconv.Itoa(i), context) - - validationResult := currentSubSchema.contains.subValidateWithContext(v, subContext) - if validationResult.Valid() { - validatedOne = true - break - } else { - if bestValidationResult == nil || validationResult.score > bestValidationResult.score { - bestValidationResult = validationResult - } - } - } - if !validatedOne { - result.addInternalError( - new(ArrayContainsError), - context, - value, - ErrorDetails{}, - ) - if bestValidationResult != nil { - result.mergeErrors(bestValidationResult) - } - } - } - - result.incrementScore() -} - -func (v *subSchema) validateObject(currentSubSchema *subSchema, value map[string]interface{}, result *Result, context *JsonContext) { - - if internalLogEnabled { - internalLog("validateObject %s", context.String()) - internalLog(" %v", value) - } - - // minProperties & maxProperties: - if currentSubSchema.minProperties != nil { - if len(value) < int(*currentSubSchema.minProperties) { - result.addInternalError( - new(ArrayMinPropertiesError), - context, - value, - ErrorDetails{"min": *currentSubSchema.minProperties}, - ) - } - } - if currentSubSchema.maxProperties != nil { - if len(value) > int(*currentSubSchema.maxProperties) { - result.addInternalError( - new(ArrayMaxPropertiesError), - context, - value, - ErrorDetails{"max": *currentSubSchema.maxProperties}, - ) - } - } - - // required: - for _, requiredProperty := range currentSubSchema.required { - _, ok := value[requiredProperty] - if ok { - result.incrementScore() - } else { - result.addInternalError( - new(RequiredError), - context, - value, - ErrorDetails{"property": requiredProperty}, - ) - } - } - - // additionalProperty & patternProperty: - for pk := range value { - - // Check whether this property is described by "properties" - found := false - for _, spValue := range currentSubSchema.propertiesChildren { - if pk == spValue.property { - found = true - } - } - - // Check whether this property is described by "patternProperties" - ppMatch := v.validatePatternProperty(currentSubSchema, pk, value[pk], result, context) - - // If it is not described by neither "properties" nor "patternProperties" it must pass "additionalProperties" - if !found && !ppMatch { - switch ap := currentSubSchema.additionalProperties.(type) { - case bool: - // Handle the boolean case separately as it's cleaner to return a specific error than failing to pass the false schema - if !ap { - result.addInternalError( - new(AdditionalPropertyNotAllowedError), - context, - value[pk], - ErrorDetails{"property": pk}, - ) - - } - case *subSchema: - validationResult := ap.subValidateWithContext(value[pk], NewJsonContext(pk, context)) - result.mergeErrors(validationResult) - } - } - } - - // propertyNames: - if currentSubSchema.propertyNames != nil { - for pk := range value { - validationResult := currentSubSchema.propertyNames.subValidateWithContext(pk, context) - if !validationResult.Valid() { - result.addInternalError(new(InvalidPropertyNameError), - context, - value, ErrorDetails{ - "property": pk, - }) - result.mergeErrors(validationResult) - } - } - } - - result.incrementScore() -} - -func (v *subSchema) validatePatternProperty(currentSubSchema *subSchema, key string, value interface{}, result *Result, context *JsonContext) bool { - - if internalLogEnabled { - internalLog("validatePatternProperty %s", context.String()) - internalLog(" %s %v", key, value) - } - - validated := false - - for pk, pv := range currentSubSchema.patternProperties { - if matches, _ := regexp.MatchString(pk, key); matches { - validated = true - subContext := NewJsonContext(key, context) - validationResult := pv.subValidateWithContext(value, subContext) - result.mergeErrors(validationResult) - } - } - - if !validated { - return false - } - - result.incrementScore() - return true -} - -func (v *subSchema) validateString(currentSubSchema *subSchema, value interface{}, result *Result, context *JsonContext) { - - // Ignore JSON numbers - if isJSONNumber(value) { - return - } - - // Ignore non strings - if !isKind(value, reflect.String) { - return - } - - if internalLogEnabled { - internalLog("validateString %s", context.String()) - internalLog(" %v", value) - } - - stringValue := value.(string) - - // minLength & maxLength: - if currentSubSchema.minLength != nil { - if utf8.RuneCount([]byte(stringValue)) < int(*currentSubSchema.minLength) { - result.addInternalError( - new(StringLengthGTEError), - context, - value, - ErrorDetails{"min": *currentSubSchema.minLength}, - ) - } - } - if currentSubSchema.maxLength != nil { - if utf8.RuneCount([]byte(stringValue)) > int(*currentSubSchema.maxLength) { - result.addInternalError( - new(StringLengthLTEError), - context, - value, - ErrorDetails{"max": *currentSubSchema.maxLength}, - ) - } - } - - // pattern: - if currentSubSchema.pattern != nil { - if !currentSubSchema.pattern.MatchString(stringValue) { - result.addInternalError( - new(DoesNotMatchPatternError), - context, - value, - ErrorDetails{"pattern": currentSubSchema.pattern}, - ) - - } - } - - // format - if currentSubSchema.format != "" { - if !FormatCheckers.IsFormat(currentSubSchema.format, stringValue) { - result.addInternalError( - new(DoesNotMatchFormatError), - context, - value, - ErrorDetails{"format": currentSubSchema.format}, - ) - } - } - - result.incrementScore() -} - -func (v *subSchema) validateNumber(currentSubSchema *subSchema, value interface{}, result *Result, context *JsonContext) { - - // Ignore non numbers - if !isJSONNumber(value) { - return - } - - if internalLogEnabled { - internalLog("validateNumber %s", context.String()) - internalLog(" %v", value) - } - - number := value.(json.Number) - float64Value, _ := new(big.Rat).SetString(string(number)) - - // multipleOf: - if currentSubSchema.multipleOf != nil { - if q := new(big.Rat).Quo(float64Value, currentSubSchema.multipleOf); !q.IsInt() { - result.addInternalError( - new(MultipleOfError), - context, - number, - ErrorDetails{ - "multiple": new(big.Float).SetRat(currentSubSchema.multipleOf), - }, - ) - } - } - - //maximum & exclusiveMaximum: - if currentSubSchema.maximum != nil { - if float64Value.Cmp(currentSubSchema.maximum) == 1 { - result.addInternalError( - new(NumberLTEError), - context, - number, - ErrorDetails{ - "max": new(big.Float).SetRat(currentSubSchema.maximum), - }, - ) - } - } - if currentSubSchema.exclusiveMaximum != nil { - if float64Value.Cmp(currentSubSchema.exclusiveMaximum) >= 0 { - result.addInternalError( - new(NumberLTError), - context, - number, - ErrorDetails{ - "max": new(big.Float).SetRat(currentSubSchema.exclusiveMaximum), - }, - ) - } - } - - //minimum & exclusiveMinimum: - if currentSubSchema.minimum != nil { - if float64Value.Cmp(currentSubSchema.minimum) == -1 { - result.addInternalError( - new(NumberGTEError), - context, - number, - ErrorDetails{ - "min": new(big.Float).SetRat(currentSubSchema.minimum), - }, - ) - } - } - if currentSubSchema.exclusiveMinimum != nil { - if float64Value.Cmp(currentSubSchema.exclusiveMinimum) <= 0 { - result.addInternalError( - new(NumberGTError), - context, - number, - ErrorDetails{ - "min": new(big.Float).SetRat(currentSubSchema.exclusiveMinimum), - }, - ) - } - } - - // format - if currentSubSchema.format != "" { - if !FormatCheckers.IsFormat(currentSubSchema.format, float64Value) { - result.addInternalError( - new(DoesNotMatchFormatError), - context, - value, - ErrorDetails{"format": currentSubSchema.format}, - ) - } - } - - result.incrementScore() -} diff --git a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go index 2ed25a750..42adb8f69 100644 --- a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go +++ b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go @@ -87,7 +87,11 @@ func NewReader(r io.Reader) (io.Reader, error) { // Read reads export data from in, decodes it, and returns type // information for the package. -// The package name is specified by path. +// +// The package path (effectively its linker symbol prefix) is +// specified by path, since unlike the package name, this information +// may not be recorded in the export data. +// // File position information is added to fset. // // Read may inspect and add to the imports map to ensure that references diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go index 4caa0f55d..6e4c066b6 100644 --- a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go @@ -51,6 +51,8 @@ const ( iexportVersionPosCol = 1 iexportVersionGo1_18 = 2 iexportVersionGenerics = 2 + + iexportVersionCurrent = 2 ) type ident struct { @@ -96,7 +98,7 @@ func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data } func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data []byte, bundle bool, path string) (pkgs []*types.Package, err error) { - const currentVersion = 1 + const currentVersion = iexportVersionCurrent version := int64(-1) if !debug { defer func() { diff --git a/vendor/modules.txt b/vendor/modules.txt index 9e779b51e..e4d9b9da4 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -59,9 +59,6 @@ github.com/Microsoft/hcsshim/pkg/ociwclayer # github.com/beorn7/perks v1.0.1 ## explicit; go 1.11 github.com/beorn7/perks/quantile -# github.com/blang/semver v3.5.1+incompatible -## explicit -github.com/blang/semver # github.com/blang/semver/v4 v4.0.0 ## explicit; go 1.14 github.com/blang/semver/v4 @@ -129,9 +126,14 @@ github.com/containerd/go-runc ## explicit; go 1.16 github.com/containerd/imgcrypt github.com/containerd/imgcrypt/images/encryption -# github.com/containerd/nri v0.1.0 -## explicit; go 1.14 +# github.com/containerd/nri v0.2.0 => github.com/klihub/nri v0.0.0-20221122201439-2b09b4ad5cf3 +## explicit; go 1.18 github.com/containerd/nri +github.com/containerd/nri/pkg/adaptation +github.com/containerd/nri/pkg/api +github.com/containerd/nri/pkg/log +github.com/containerd/nri/pkg/net +github.com/containerd/nri/pkg/net/multiplex github.com/containerd/nri/types/v1 # github.com/containerd/ttrpc v1.1.1-0.20220420014843-944ef4a40df3 ## explicit; go 1.13 @@ -333,17 +335,14 @@ github.com/opencontainers/image-spec/specs-go/v1 ## explicit; go 1.16 github.com/opencontainers/runc/libcontainer/devices github.com/opencontainers/runc/libcontainer/user -# github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 +# github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb ## explicit github.com/opencontainers/runtime-spec/specs-go -# github.com/opencontainers/runtime-tools v0.0.0-20190417131837-cd1349b7c47e -## explicit -github.com/opencontainers/runtime-tools/error -github.com/opencontainers/runtime-tools/filepath +# github.com/opencontainers/runtime-tools v0.9.0 => github.com/opencontainers/runtime-tools v0.0.0-20221026201742-946c877fa809 +## explicit; go 1.16 github.com/opencontainers/runtime-tools/generate github.com/opencontainers/runtime-tools/generate/seccomp -github.com/opencontainers/runtime-tools/specerror -github.com/opencontainers/runtime-tools/validate +github.com/opencontainers/runtime-tools/validate/capabilities # github.com/opencontainers/selinux v1.10.2 ## explicit; go 1.13 github.com/opencontainers/selinux/go-selinux @@ -409,15 +408,6 @@ github.com/vishvananda/netlink/nl # github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f ## explicit; go 1.12 github.com/vishvananda/netns -# github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f -## explicit -github.com/xeipuuv/gojsonpointer -# github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 -## explicit -github.com/xeipuuv/gojsonreference -# github.com/xeipuuv/gojsonschema v1.2.0 -## explicit -github.com/xeipuuv/gojsonschema # go.etcd.io/bbolt v1.3.6 ## explicit; go 1.12 go.etcd.io/bbolt @@ -538,7 +528,7 @@ golang.org/x/text/unicode/norm # golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 ## explicit golang.org/x/time/rate -# golang.org/x/tools v0.1.13-0.20221007141809-02bef08ac854 +# golang.org/x/tools v0.2.0 ## explicit; go 1.18 golang.org/x/tools/cmd/stringer golang.org/x/tools/go/gcexportdata @@ -798,3 +788,5 @@ sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.3.0 ## explicit; go 1.12 sigs.k8s.io/yaml +# github.com/containerd/nri => github.com/klihub/nri v0.0.0-20221122201439-2b09b4ad5cf3 +# github.com/opencontainers/runtime-tools => github.com/opencontainers/runtime-tools v0.0.0-20221026201742-946c877fa809