Merge pull request #8152 from bart0sh/PR007-upgrade-CDI-to-0.5.4
update CDI version to v0.5.4
This commit is contained in:
commit
e0a05b56e5
4
go.mod
4
go.mod
@ -7,7 +7,7 @@ require (
|
|||||||
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652
|
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652
|
||||||
github.com/Microsoft/go-winio v0.6.0
|
github.com/Microsoft/go-winio v0.6.0
|
||||||
github.com/Microsoft/hcsshim v0.10.0-rc.5
|
github.com/Microsoft/hcsshim v0.10.0-rc.5
|
||||||
github.com/container-orchestrated-devices/container-device-interface v0.5.1
|
github.com/container-orchestrated-devices/container-device-interface v0.5.4
|
||||||
github.com/containerd/aufs v1.0.0
|
github.com/containerd/aufs v1.0.0
|
||||||
github.com/containerd/btrfs/v2 v2.0.0
|
github.com/containerd/btrfs/v2 v2.0.0
|
||||||
github.com/containerd/cgroups/v3 v3.0.0
|
github.com/containerd/cgroups/v3 v3.0.0
|
||||||
@ -50,7 +50,7 @@ require (
|
|||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb
|
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb
|
||||||
// ATM the runtime-tools commit we need are beyond the latest tag.
|
// 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.
|
// We use a replace to handle that until a new version is tagged.
|
||||||
github.com/opencontainers/runtime-tools v0.9.0
|
github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626
|
||||||
github.com/opencontainers/selinux v1.10.2
|
github.com/opencontainers/selinux v1.10.2
|
||||||
github.com/pelletier/go-toml v1.9.5
|
github.com/pelletier/go-toml v1.9.5
|
||||||
github.com/prometheus/client_golang v1.13.0
|
github.com/prometheus/client_golang v1.13.0
|
||||||
|
4
go.sum
4
go.sum
@ -176,8 +176,8 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:z
|
|||||||
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
|
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
|
||||||
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
|
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
|
||||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
||||||
github.com/container-orchestrated-devices/container-device-interface v0.5.1 h1:nXIUTrlEgGcA/n2geY3J7yyaGGhkocSlMkKPS4Qp4c0=
|
github.com/container-orchestrated-devices/container-device-interface v0.5.4 h1:PqQGqJqQttMP5oJ/qNGEg8JttlHqGY3xDbbcKb5T9E8=
|
||||||
github.com/container-orchestrated-devices/container-device-interface v0.5.1/go.mod h1:ZToWfSyUH5l9Rk7/bjkUUkNLz4b1mE+CVUVafuikDPY=
|
github.com/container-orchestrated-devices/container-device-interface v0.5.4/go.mod h1:DjE95rfPiiSmG7uVXtg0z6MnPm/Lx4wxKCIts0ZE0vg=
|
||||||
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
|
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
|
||||||
github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
|
github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
|
||||||
github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||||
|
@ -450,8 +450,6 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
|
|||||||
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
||||||
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
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/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||||
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
|
|
||||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
|
||||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||||
github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
|
github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
|
||||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||||
@ -493,7 +491,7 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH
|
|||||||
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
|
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
|
||||||
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
|
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
|
||||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
||||||
github.com/container-orchestrated-devices/container-device-interface v0.5.1/go.mod h1:ZToWfSyUH5l9Rk7/bjkUUkNLz4b1mE+CVUVafuikDPY=
|
github.com/container-orchestrated-devices/container-device-interface v0.5.4/go.mod h1:DjE95rfPiiSmG7uVXtg0z6MnPm/Lx4wxKCIts0ZE0vg=
|
||||||
github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
|
||||||
github.com/containerd/btrfs/v2 v2.0.0/go.mod h1:swkD/7j9HApWpzl8OHfrHNxppPd9l44DFZdF94BUj9k=
|
github.com/containerd/btrfs/v2 v2.0.0/go.mod h1:swkD/7j9HApWpzl8OHfrHNxppPd9l44DFZdF94BUj9k=
|
||||||
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
|
||||||
@ -886,7 +884,6 @@ github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmt
|
|||||||
github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo=
|
github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo=
|
||||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
|
||||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
@ -915,7 +912,6 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
|
|||||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
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.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
|
||||||
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
|
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/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 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||||
@ -1009,7 +1005,6 @@ github.com/opencontainers/selinux v1.10.2/go.mod h1:cARutUbaUrlRClyvxOICCgKixCs6
|
|||||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
|
||||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||||
@ -1096,17 +1091,14 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B
|
|||||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
|
||||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||||
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
|
|
||||||
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
|
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
|
||||||
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
|
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
|
||||||
github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
|
||||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
@ -1114,7 +1106,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
|
|||||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||||
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
|
||||||
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
|
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
|
||||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
@ -1176,11 +1167,8 @@ github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go
|
|||||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||||
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
||||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
|
||||||
go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
|
go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
|
||||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
|
||||||
go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
|
||||||
go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU=
|
go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU=
|
||||||
go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
|
go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
|
||||||
go.etcd.io/etcd/pkg/v3 v3.5.4/go.mod h1:OI+TtO+Aa3nhQSppMbwE4ld3uF1/fqqwbpfndbbrEe0=
|
go.etcd.io/etcd/pkg/v3 v3.5.4/go.mod h1:OI+TtO+Aa3nhQSppMbwE4ld3uF1/fqqwbpfndbbrEe0=
|
||||||
@ -1387,7 +1375,6 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ
|
|||||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
@ -1673,7 +1660,6 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q
|
|||||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
||||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
||||||
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
|
|
||||||
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
|
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
|
||||||
google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
|
google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
|
||||||
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
|
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
|
||||||
@ -1897,7 +1883,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
|||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||||
|
@ -1757,7 +1757,7 @@ func TestCDIInjections(t *testing.T) {
|
|||||||
{description: "expect properly injected resolvable CDI devices",
|
{description: "expect properly injected resolvable CDI devices",
|
||||||
cdiSpecFiles: []string{
|
cdiSpecFiles: []string{
|
||||||
`
|
`
|
||||||
cdiVersion: "0.2.0"
|
cdiVersion: "0.3.0"
|
||||||
kind: "vendor1.com/device"
|
kind: "vendor1.com/device"
|
||||||
devices:
|
devices:
|
||||||
- name: foo
|
- name: foo
|
||||||
@ -1774,7 +1774,7 @@ containerEdits:
|
|||||||
- "VENDOR1=present"
|
- "VENDOR1=present"
|
||||||
`,
|
`,
|
||||||
`
|
`
|
||||||
cdiVersion: "0.2.0"
|
cdiVersion: "0.3.0"
|
||||||
kind: "vendor2.com/device"
|
kind: "vendor2.com/device"
|
||||||
devices:
|
devices:
|
||||||
- name: bar
|
- name: bar
|
||||||
|
@ -1757,7 +1757,7 @@ func TestCDIInjections(t *testing.T) {
|
|||||||
{description: "expect properly injected resolvable CDI devices",
|
{description: "expect properly injected resolvable CDI devices",
|
||||||
cdiSpecFiles: []string{
|
cdiSpecFiles: []string{
|
||||||
`
|
`
|
||||||
cdiVersion: "0.2.0"
|
cdiVersion: "0.3.0"
|
||||||
kind: "vendor1.com/device"
|
kind: "vendor1.com/device"
|
||||||
devices:
|
devices:
|
||||||
- name: foo
|
- name: foo
|
||||||
@ -1774,7 +1774,7 @@ containerEdits:
|
|||||||
- "VENDOR1=present"
|
- "VENDOR1=present"
|
||||||
`,
|
`,
|
||||||
`
|
`
|
||||||
cdiVersion: "0.2.0"
|
cdiVersion: "0.3.0"
|
||||||
kind: "vendor2.com/device"
|
kind: "vendor2.com/device"
|
||||||
devices:
|
devices:
|
||||||
- name: bar
|
- name: bar
|
||||||
|
82
vendor/github.com/container-orchestrated-devices/container-device-interface/internal/multierror/multierror.go
generated
vendored
Normal file
82
vendor/github.com/container-orchestrated-devices/container-device-interface/internal/multierror/multierror.go
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2022 The CDI 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 multierror
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// New combines several errors into a single error. Parameters that are nil are
|
||||||
|
// ignored. If no errors are passed in or all parameters are nil, then the
|
||||||
|
// result is also nil.
|
||||||
|
func New(errors ...error) error {
|
||||||
|
// Filter out nil entries.
|
||||||
|
numErrors := 0
|
||||||
|
for _, err := range errors {
|
||||||
|
if err != nil {
|
||||||
|
errors[numErrors] = err
|
||||||
|
numErrors++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if numErrors == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return multiError(errors[0:numErrors])
|
||||||
|
}
|
||||||
|
|
||||||
|
// multiError is the underlying implementation used by New.
|
||||||
|
//
|
||||||
|
// Beware that a null multiError is not the same as a nil error.
|
||||||
|
type multiError []error
|
||||||
|
|
||||||
|
// multiError returns all individual error strings concatenated with "\n"
|
||||||
|
func (e multiError) Error() string {
|
||||||
|
var builder strings.Builder
|
||||||
|
for i, err := range e {
|
||||||
|
if i > 0 {
|
||||||
|
_, _ = builder.WriteString("\n")
|
||||||
|
}
|
||||||
|
_, _ = builder.WriteString(err.Error())
|
||||||
|
}
|
||||||
|
return builder.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append returns a new multi error all errors concatenated. Errors that are
|
||||||
|
// multi errors get flattened, nil is ignored.
|
||||||
|
func Append(err error, errors ...error) error {
|
||||||
|
var result multiError
|
||||||
|
if m, ok := err.(multiError); ok {
|
||||||
|
result = m
|
||||||
|
} else if err != nil {
|
||||||
|
result = append(result, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, e := range errors {
|
||||||
|
if e == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if m, ok := e.(multiError); ok {
|
||||||
|
result = append(result, m...)
|
||||||
|
} else {
|
||||||
|
result = append(result, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(result) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
@ -17,9 +17,9 @@
|
|||||||
package cdi
|
package cdi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -34,14 +34,14 @@ const (
|
|||||||
func UpdateAnnotations(annotations map[string]string, plugin string, deviceID string, devices []string) (map[string]string, error) {
|
func UpdateAnnotations(annotations map[string]string, plugin string, deviceID string, devices []string) (map[string]string, error) {
|
||||||
key, err := AnnotationKey(plugin, deviceID)
|
key, err := AnnotationKey(plugin, deviceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return annotations, errors.Wrap(err, "CDI annotation failed")
|
return annotations, fmt.Errorf("CDI annotation failed: %w", err)
|
||||||
}
|
}
|
||||||
if _, ok := annotations[key]; ok {
|
if _, ok := annotations[key]; ok {
|
||||||
return annotations, errors.Errorf("CDI annotation failed, key %q used", key)
|
return annotations, fmt.Errorf("CDI annotation failed, key %q used", key)
|
||||||
}
|
}
|
||||||
value, err := AnnotationValue(devices)
|
value, err := AnnotationValue(devices)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return annotations, errors.Wrap(err, "CDI annotation failed")
|
return annotations, fmt.Errorf("CDI annotation failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if annotations == nil {
|
if annotations == nil {
|
||||||
@ -70,7 +70,7 @@ func ParseAnnotations(annotations map[string]string) ([]string, []string, error)
|
|||||||
}
|
}
|
||||||
for _, d := range strings.Split(value, ",") {
|
for _, d := range strings.Split(value, ",") {
|
||||||
if !IsQualifiedName(d) {
|
if !IsQualifiedName(d) {
|
||||||
return nil, nil, errors.Errorf("invalid CDI device name %q", d)
|
return nil, nil, fmt.Errorf("invalid CDI device name %q", d)
|
||||||
}
|
}
|
||||||
devices = append(devices, d)
|
devices = append(devices, d)
|
||||||
}
|
}
|
||||||
@ -98,11 +98,11 @@ func AnnotationKey(pluginName, deviceID string) (string, error) {
|
|||||||
name := pluginName + "_" + strings.ReplaceAll(deviceID, "/", "_")
|
name := pluginName + "_" + strings.ReplaceAll(deviceID, "/", "_")
|
||||||
|
|
||||||
if len(name) > maxNameLen {
|
if len(name) > maxNameLen {
|
||||||
return "", errors.Errorf("invalid plugin+deviceID %q, too long", name)
|
return "", fmt.Errorf("invalid plugin+deviceID %q, too long", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c := rune(name[0]); !isAlphaNumeric(c) {
|
if c := rune(name[0]); !isAlphaNumeric(c) {
|
||||||
return "", errors.Errorf("invalid name %q, first '%c' should be alphanumeric",
|
return "", fmt.Errorf("invalid name %q, first '%c' should be alphanumeric",
|
||||||
name, c)
|
name, c)
|
||||||
}
|
}
|
||||||
if len(name) > 2 {
|
if len(name) > 2 {
|
||||||
@ -111,13 +111,13 @@ func AnnotationKey(pluginName, deviceID string) (string, error) {
|
|||||||
case isAlphaNumeric(c):
|
case isAlphaNumeric(c):
|
||||||
case c == '_' || c == '-' || c == '.':
|
case c == '_' || c == '-' || c == '.':
|
||||||
default:
|
default:
|
||||||
return "", errors.Errorf("invalid name %q, invalid charcter '%c'",
|
return "", fmt.Errorf("invalid name %q, invalid charcter '%c'",
|
||||||
name, c)
|
name, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if c := rune(name[len(name)-1]); !isAlphaNumeric(c) {
|
if c := rune(name[len(name)-1]); !isAlphaNumeric(c) {
|
||||||
return "", errors.Errorf("invalid name %q, last '%c' should be alphanumeric",
|
return "", fmt.Errorf("invalid name %q, last '%c' should be alphanumeric",
|
||||||
name, c)
|
name, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
106
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache.go
generated
vendored
106
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache.go
generated
vendored
@ -17,16 +17,19 @@
|
|||||||
package cdi
|
package cdi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/container-orchestrated-devices/container-device-interface/internal/multierror"
|
||||||
cdi "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
cdi "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
"github.com/fsnotify/fsnotify"
|
"github.com/fsnotify/fsnotify"
|
||||||
"github.com/hashicorp/go-multierror"
|
|
||||||
oci "github.com/opencontainers/runtime-spec/specs-go"
|
oci "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Option is an option to change some aspect of default CDI behavior.
|
// Option is an option to change some aspect of default CDI behavior.
|
||||||
@ -93,7 +96,7 @@ func (c *Cache) configure(options ...Option) error {
|
|||||||
|
|
||||||
for _, o := range options {
|
for _, o := range options {
|
||||||
if err = o(c); err != nil {
|
if err = o(c); err != nil {
|
||||||
return errors.Wrapf(err, "failed to apply cache options")
|
return fmt.Errorf("failed to apply cache options: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,8 +126,8 @@ func (c *Cache) Refresh() error {
|
|||||||
|
|
||||||
// collect and return cached errors, much like refresh() does it
|
// collect and return cached errors, much like refresh() does it
|
||||||
var result error
|
var result error
|
||||||
for _, err := range c.errors {
|
for _, errors := range c.errors {
|
||||||
result = multierror.Append(result, err...)
|
result = multierror.Append(result, errors...)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -155,7 +158,7 @@ func (c *Cache) refresh() error {
|
|||||||
return false
|
return false
|
||||||
case devPrio == oldPrio:
|
case devPrio == oldPrio:
|
||||||
devPath, oldPath := devSpec.GetPath(), oldSpec.GetPath()
|
devPath, oldPath := devSpec.GetPath(), oldSpec.GetPath()
|
||||||
collectError(errors.Errorf("conflicting device %q (specs %q, %q)",
|
collectError(fmt.Errorf("conflicting device %q (specs %q, %q)",
|
||||||
name, devPath, oldPath), devPath, oldPath)
|
name, devPath, oldPath), devPath, oldPath)
|
||||||
conflicts[name] = struct{}{}
|
conflicts[name] = struct{}{}
|
||||||
}
|
}
|
||||||
@ -165,7 +168,7 @@ func (c *Cache) refresh() error {
|
|||||||
_ = scanSpecDirs(c.specDirs, func(path string, priority int, spec *Spec, err error) error {
|
_ = scanSpecDirs(c.specDirs, func(path string, priority int, spec *Spec, err error) error {
|
||||||
path = filepath.Clean(path)
|
path = filepath.Clean(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
collectError(errors.Wrapf(err, "failed to load CDI Spec"), path)
|
collectError(fmt.Errorf("failed to load CDI Spec %w", err), path)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,11 +197,7 @@ func (c *Cache) refresh() error {
|
|||||||
c.devices = devices
|
c.devices = devices
|
||||||
c.errors = specErrors
|
c.errors = specErrors
|
||||||
|
|
||||||
if len(result) > 0 {
|
return multierror.New(result...)
|
||||||
return multierror.Append(nil, result...)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshIfRequired triggers a refresh if necessary.
|
// RefreshIfRequired triggers a refresh if necessary.
|
||||||
@ -219,7 +218,7 @@ func (c *Cache) InjectDevices(ociSpec *oci.Spec, devices ...string) ([]string, e
|
|||||||
var unresolved []string
|
var unresolved []string
|
||||||
|
|
||||||
if ociSpec == nil {
|
if ociSpec == nil {
|
||||||
return devices, errors.Errorf("can't inject devices, nil OCI Spec")
|
return devices, fmt.Errorf("can't inject devices, nil OCI Spec")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Lock()
|
c.Lock()
|
||||||
@ -244,22 +243,33 @@ func (c *Cache) InjectDevices(ociSpec *oci.Spec, devices ...string) ([]string, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
if unresolved != nil {
|
if unresolved != nil {
|
||||||
return unresolved, errors.Errorf("unresolvable CDI devices %s",
|
return unresolved, fmt.Errorf("unresolvable CDI devices %s",
|
||||||
strings.Join(devices, ", "))
|
strings.Join(devices, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := edits.Apply(ociSpec); err != nil {
|
if err := edits.Apply(ociSpec); err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to inject devices")
|
return nil, fmt.Errorf("failed to inject devices: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteSpec writes a Spec file with the given content. Priority is used
|
// highestPrioritySpecDir returns the Spec directory with highest priority
|
||||||
// as an index into the list of Spec directories to pick a directory for
|
// and its priority.
|
||||||
// the file, adjusting for any under- or overflows. If name has a "json"
|
func (c *Cache) highestPrioritySpecDir() (string, int) {
|
||||||
// or "yaml" extension it choses the encoding. Otherwise JSON encoding
|
if len(c.specDirs) == 0 {
|
||||||
// is used with a "json" extension.
|
return "", -1
|
||||||
|
}
|
||||||
|
|
||||||
|
prio := len(c.specDirs) - 1
|
||||||
|
dir := c.specDirs[prio]
|
||||||
|
|
||||||
|
return dir, prio
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteSpec writes a Spec file with the given content into the highest
|
||||||
|
// priority Spec directory. If name has a "json" or "yaml" extension it
|
||||||
|
// choses the encoding. Otherwise the default YAML encoding is used.
|
||||||
func (c *Cache) WriteSpec(raw *cdi.Spec, name string) error {
|
func (c *Cache) WriteSpec(raw *cdi.Spec, name string) error {
|
||||||
var (
|
var (
|
||||||
specDir string
|
specDir string
|
||||||
@ -269,23 +279,51 @@ func (c *Cache) WriteSpec(raw *cdi.Spec, name string) error {
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(c.specDirs) == 0 {
|
specDir, prio = c.highestPrioritySpecDir()
|
||||||
|
if specDir == "" {
|
||||||
return errors.New("no Spec directories to write to")
|
return errors.New("no Spec directories to write to")
|
||||||
}
|
}
|
||||||
|
|
||||||
prio = len(c.specDirs) - 1
|
|
||||||
specDir = c.specDirs[prio]
|
|
||||||
path = filepath.Join(specDir, name)
|
path = filepath.Join(specDir, name)
|
||||||
if ext := filepath.Ext(path); ext != ".json" && ext != ".yaml" {
|
if ext := filepath.Ext(path); ext != ".json" && ext != ".yaml" {
|
||||||
path += ".json"
|
path += defaultSpecExt
|
||||||
}
|
}
|
||||||
|
|
||||||
spec, err = NewSpec(raw, path, prio)
|
spec, err = newSpec(raw, path, prio)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return spec.Write(true)
|
return spec.write(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveSpec removes a Spec with the given name from the highest
|
||||||
|
// priority Spec directory. This function can be used to remove a
|
||||||
|
// Spec previously written by WriteSpec(). If the file exists and
|
||||||
|
// its removal fails RemoveSpec returns an error.
|
||||||
|
func (c *Cache) RemoveSpec(name string) error {
|
||||||
|
var (
|
||||||
|
specDir string
|
||||||
|
path string
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
specDir, _ = c.highestPrioritySpecDir()
|
||||||
|
if specDir == "" {
|
||||||
|
return errors.New("no Spec directories to remove from")
|
||||||
|
}
|
||||||
|
|
||||||
|
path = filepath.Join(specDir, name)
|
||||||
|
if ext := filepath.Ext(path); ext != ".json" && ext != ".yaml" {
|
||||||
|
path += defaultSpecExt
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.Remove(path)
|
||||||
|
if err != nil && errors.Is(err, fs.ErrNotExist) {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDevice returns the cached device for the given qualified name.
|
// GetDevice returns the cached device for the given qualified name.
|
||||||
@ -370,7 +408,17 @@ func (c *Cache) GetVendorSpecs(vendor string) []*Spec {
|
|||||||
// GetSpecErrors returns all errors encountered for the spec during the
|
// GetSpecErrors returns all errors encountered for the spec during the
|
||||||
// last cache refresh.
|
// last cache refresh.
|
||||||
func (c *Cache) GetSpecErrors(spec *Spec) []error {
|
func (c *Cache) GetSpecErrors(spec *Spec) []error {
|
||||||
return c.errors[spec.GetPath()]
|
var errors []error
|
||||||
|
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
|
|
||||||
|
if errs, ok := c.errors[spec.GetPath()]; ok {
|
||||||
|
errors = make([]error, len(errs))
|
||||||
|
copy(errors, errs)
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetErrors returns all errors encountered during the last
|
// GetErrors returns all errors encountered during the last
|
||||||
@ -436,7 +484,7 @@ func (w *watch) setup(dirs []string, dirErrors map[string]error) {
|
|||||||
w.watcher, err = fsnotify.NewWatcher()
|
w.watcher, err = fsnotify.NewWatcher()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
for _, dir := range dirs {
|
for _, dir := range dirs {
|
||||||
dirErrors[dir] = errors.Wrap(err, "failed to create watcher")
|
dirErrors[dir] = fmt.Errorf("failed to create watcher: %w", err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -519,7 +567,7 @@ func (w *watch) update(dirErrors map[string]error, removed ...string) bool {
|
|||||||
update = true
|
update = true
|
||||||
} else {
|
} else {
|
||||||
w.tracked[dir] = false
|
w.tracked[dir] = false
|
||||||
dirErrors[dir] = errors.Wrap(err, "failed to monitor for changes")
|
dirErrors[dir] = fmt.Errorf("failed to monitor for changes: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache_test_unix.go
generated
vendored
Normal file
26
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache_test_unix.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//go:build !windows
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI 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 cdi
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
func osSync() {
|
||||||
|
syscall.Sync()
|
||||||
|
}
|
22
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache_test_windows.go
generated
vendored
Normal file
22
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/cache_test_windows.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI 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 cdi
|
||||||
|
|
||||||
|
func osSync() {}
|
@ -17,18 +17,16 @@
|
|||||||
package cdi
|
package cdi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
"github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
oci "github.com/opencontainers/runtime-spec/specs-go"
|
oci "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
ocigen "github.com/opencontainers/runtime-tools/generate"
|
ocigen "github.com/opencontainers/runtime-tools/generate"
|
||||||
|
|
||||||
runc "github.com/opencontainers/runc/libcontainer/devices"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -142,7 +140,7 @@ func (e *ContainerEdits) Apply(spec *oci.Spec) error {
|
|||||||
ensureOCIHooks(spec)
|
ensureOCIHooks(spec)
|
||||||
spec.Hooks.StartContainer = append(spec.Hooks.StartContainer, h.ToOCI())
|
spec.Hooks.StartContainer = append(spec.Hooks.StartContainer, h.ToOCI())
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("unknown hook name %q", h.HookName)
|
return fmt.Errorf("unknown hook name %q", h.HookName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +154,7 @@ func (e *ContainerEdits) Validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := ValidateEnv(e.Env); err != nil {
|
if err := ValidateEnv(e.Env); err != nil {
|
||||||
return errors.Wrap(err, "invalid container edits")
|
return fmt.Errorf("invalid container edits: %w", err)
|
||||||
}
|
}
|
||||||
for _, d := range e.DeviceNodes {
|
for _, d := range e.DeviceNodes {
|
||||||
if err := (&DeviceNode{d}).Validate(); err != nil {
|
if err := (&DeviceNode{d}).Validate(); err != nil {
|
||||||
@ -211,7 +209,7 @@ func (e *ContainerEdits) isEmpty() bool {
|
|||||||
func ValidateEnv(env []string) error {
|
func ValidateEnv(env []string) error {
|
||||||
for _, v := range env {
|
for _, v := range env {
|
||||||
if strings.IndexByte(v, byte('=')) <= 0 {
|
if strings.IndexByte(v, byte('=')) <= 0 {
|
||||||
return errors.Errorf("invalid environment variable %q", v)
|
return fmt.Errorf("invalid environment variable %q", v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -236,11 +234,11 @@ func (d *DeviceNode) Validate() error {
|
|||||||
return errors.New("invalid (empty) device path")
|
return errors.New("invalid (empty) device path")
|
||||||
}
|
}
|
||||||
if _, ok := validTypes[d.Type]; !ok {
|
if _, ok := validTypes[d.Type]; !ok {
|
||||||
return errors.Errorf("device %q: invalid type %q", d.Path, d.Type)
|
return fmt.Errorf("device %q: invalid type %q", d.Path, d.Type)
|
||||||
}
|
}
|
||||||
for _, bit := range d.Permissions {
|
for _, bit := range d.Permissions {
|
||||||
if bit != 'r' && bit != 'w' && bit != 'm' {
|
if bit != 'r' && bit != 'w' && bit != 'm' {
|
||||||
return errors.Errorf("device %q: invalid persmissions %q",
|
return fmt.Errorf("device %q: invalid persmissions %q",
|
||||||
d.Path, d.Permissions)
|
d.Path, d.Permissions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,13 +253,13 @@ type Hook struct {
|
|||||||
// Validate a hook.
|
// Validate a hook.
|
||||||
func (h *Hook) Validate() error {
|
func (h *Hook) Validate() error {
|
||||||
if _, ok := validHookNames[h.HookName]; !ok {
|
if _, ok := validHookNames[h.HookName]; !ok {
|
||||||
return errors.Errorf("invalid hook name %q", h.HookName)
|
return fmt.Errorf("invalid hook name %q", h.HookName)
|
||||||
}
|
}
|
||||||
if h.Path == "" {
|
if h.Path == "" {
|
||||||
return errors.Errorf("invalid hook %q with empty path", h.HookName)
|
return fmt.Errorf("invalid hook %q with empty path", h.HookName)
|
||||||
}
|
}
|
||||||
if err := ValidateEnv(h.Env); err != nil {
|
if err := ValidateEnv(h.Env); err != nil {
|
||||||
return errors.Wrapf(err, "invalid hook %q", h.HookName)
|
return fmt.Errorf("invalid hook %q: %w", h.HookName, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -289,37 +287,6 @@ func ensureOCIHooks(spec *oci.Spec) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fillMissingInfo fills in missing mandatory attributes from the host device.
|
|
||||||
func (d *DeviceNode) fillMissingInfo() error {
|
|
||||||
if d.HostPath == "" {
|
|
||||||
d.HostPath = d.Path
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.Type != "" && (d.Major != 0 || d.Type == "p") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
hostDev, err := runc.DeviceFromPath(d.HostPath, "rwm")
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, "failed to stat CDI host device %q", d.HostPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.Type == "" {
|
|
||||||
d.Type = string(hostDev.Type)
|
|
||||||
} else {
|
|
||||||
if d.Type != string(hostDev.Type) {
|
|
||||||
return errors.Errorf("CDI device (%q, %q), host type mismatch (%s, %s)",
|
|
||||||
d.Path, d.HostPath, d.Type, string(hostDev.Type))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if d.Major == 0 && d.Type != "p" {
|
|
||||||
d.Major = hostDev.Major
|
|
||||||
d.Minor = hostDev.Minor
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// sortMounts sorts the mounts in the given OCI Spec.
|
// sortMounts sorts the mounts in the given OCI Spec.
|
||||||
func sortMounts(specgen *ocigen.Generator) {
|
func sortMounts(specgen *ocigen.Generator) {
|
||||||
mounts := specgen.Mounts()
|
mounts := specgen.Mounts()
|
||||||
@ -331,7 +298,8 @@ func sortMounts(specgen *ocigen.Generator) {
|
|||||||
// orderedMounts defines how to sort an OCI Spec Mount slice.
|
// orderedMounts defines how to sort an OCI Spec Mount slice.
|
||||||
// This is the almost the same implementation sa used by CRI-O and Docker,
|
// This is the almost the same implementation sa used by CRI-O and Docker,
|
||||||
// with a minor tweak for stable sorting order (easier to test):
|
// with a minor tweak for stable sorting order (easier to test):
|
||||||
// https://github.com/moby/moby/blob/17.05.x/daemon/volumes.go#L26
|
//
|
||||||
|
// https://github.com/moby/moby/blob/17.05.x/daemon/volumes.go#L26
|
||||||
type orderedMounts []oci.Mount
|
type orderedMounts []oci.Mount
|
||||||
|
|
||||||
// Len returns the number of mounts. Used in sorting.
|
// Len returns the number of mounts. Used in sorting.
|
||||||
|
57
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits_unix.go
generated
vendored
Normal file
57
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits_unix.go
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
//go:build !windows
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI 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 cdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
runc "github.com/opencontainers/runc/libcontainer/devices"
|
||||||
|
)
|
||||||
|
|
||||||
|
// fillMissingInfo fills in missing mandatory attributes from the host device.
|
||||||
|
func (d *DeviceNode) fillMissingInfo() error {
|
||||||
|
if d.HostPath == "" {
|
||||||
|
d.HostPath = d.Path
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.Type != "" && (d.Major != 0 || d.Type == "p") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
hostDev, err := runc.DeviceFromPath(d.HostPath, "rwm")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to stat CDI host device %q: %w", d.HostPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.Type == "" {
|
||||||
|
d.Type = string(hostDev.Type)
|
||||||
|
} else {
|
||||||
|
if d.Type != string(hostDev.Type) {
|
||||||
|
return fmt.Errorf("CDI device (%q, %q), host type mismatch (%s, %s)",
|
||||||
|
d.Path, d.HostPath, d.Type, string(hostDev.Type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if d.Major == 0 && d.Type != "p" {
|
||||||
|
d.Major = hostDev.Major
|
||||||
|
d.Minor = hostDev.Minor
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
27
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits_windows.go
generated
vendored
Normal file
27
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/container-edits_windows.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//go:build windows
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright © 2021 The CDI 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 cdi
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// fillMissingInfo fills in missing mandatory attributes from the host device.
|
||||||
|
func (d *DeviceNode) fillMissingInfo() error {
|
||||||
|
return fmt.Errorf("unimplemented")
|
||||||
|
}
|
@ -17,9 +17,10 @@
|
|||||||
package cdi
|
package cdi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
cdi "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
cdi "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
oci "github.com/opencontainers/runtime-spec/specs-go"
|
oci "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Device represents a CDI device of a Spec.
|
// Device represents a CDI device of a Spec.
|
||||||
@ -69,10 +70,10 @@ func (d *Device) validate() error {
|
|||||||
}
|
}
|
||||||
edits := d.edits()
|
edits := d.edits()
|
||||||
if edits.isEmpty() {
|
if edits.isEmpty() {
|
||||||
return errors.Errorf("invalid device, empty device edits")
|
return fmt.Errorf("invalid device, empty device edits")
|
||||||
}
|
}
|
||||||
if err := edits.Validate(); err != nil {
|
if err := edits.Validate(); err != nil {
|
||||||
return errors.Wrapf(err, "invalid device %q", d.Name)
|
return fmt.Errorf("invalid device %q: %w", d.Name, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
125
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/doc.go
generated
vendored
125
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/doc.go
generated
vendored
@ -46,7 +46,6 @@
|
|||||||
// "fmt"
|
// "fmt"
|
||||||
// "strings"
|
// "strings"
|
||||||
//
|
//
|
||||||
// "github.com/pkg/errors"
|
|
||||||
// log "github.com/sirupsen/logrus"
|
// log "github.com/sirupsen/logrus"
|
||||||
//
|
//
|
||||||
// "github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
|
// "github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
|
||||||
@ -58,7 +57,7 @@
|
|||||||
//
|
//
|
||||||
// unresolved, err := cdi.GetRegistry().InjectDevices(spec, devices)
|
// unresolved, err := cdi.GetRegistry().InjectDevices(spec, devices)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return errors.Wrap(err, "CDI device injection failed")
|
// return fmt.Errorf("CDI device injection failed: %w", err)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// log.Debug("CDI-updated OCI Spec: %s", dumpSpec(spec))
|
// log.Debug("CDI-updated OCI Spec: %s", dumpSpec(spec))
|
||||||
@ -90,7 +89,6 @@
|
|||||||
// "fmt"
|
// "fmt"
|
||||||
// "strings"
|
// "strings"
|
||||||
//
|
//
|
||||||
// "github.com/pkg/errors"
|
|
||||||
// log "github.com/sirupsen/logrus"
|
// log "github.com/sirupsen/logrus"
|
||||||
//
|
//
|
||||||
// "github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
|
// "github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
|
||||||
@ -115,7 +113,7 @@
|
|||||||
//
|
//
|
||||||
// unresolved, err := registry.InjectDevices(spec, devices)
|
// unresolved, err := registry.InjectDevices(spec, devices)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return errors.Wrap(err, "CDI device injection failed")
|
// return fmt.Errorf("CDI device injection failed: %w", err)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// log.Debug("CDI-updated OCI Spec: %s", dumpSpec(spec))
|
// log.Debug("CDI-updated OCI Spec: %s", dumpSpec(spec))
|
||||||
@ -124,10 +122,15 @@
|
|||||||
//
|
//
|
||||||
// Generated Spec Files, Multiple Directories, Device Precedence
|
// Generated Spec Files, Multiple Directories, Device Precedence
|
||||||
//
|
//
|
||||||
// There are systems where the set of available or usable CDI devices
|
// It is often necessary to generate Spec files dynamically. On some
|
||||||
// changes dynamically and this needs to be reflected in the CDI Specs.
|
// systems the available or usable set of CDI devices might change
|
||||||
// This is done by dynamically regenerating CDI Spec files which are
|
// dynamically which then needs to be reflected in CDI Specs. For
|
||||||
// affected by these changes.
|
// some device classes it makes sense to enumerate the available
|
||||||
|
// devices at every boot and generate Spec file entries for each
|
||||||
|
// device found. Some CDI devices might need special client- or
|
||||||
|
// request-specific configuration which can only be fulfilled by
|
||||||
|
// dynamically generated client-specific entries in transient Spec
|
||||||
|
// files.
|
||||||
//
|
//
|
||||||
// CDI can collect Spec files from multiple directories. Spec files are
|
// CDI can collect Spec files from multiple directories. Spec files are
|
||||||
// automatically assigned priorities according to which directory they
|
// automatically assigned priorities according to which directory they
|
||||||
@ -141,7 +144,111 @@
|
|||||||
// separating dynamically generated CDI Spec files from static ones.
|
// separating dynamically generated CDI Spec files from static ones.
|
||||||
// The default directories are '/etc/cdi' and '/var/run/cdi'. By putting
|
// The default directories are '/etc/cdi' and '/var/run/cdi'. By putting
|
||||||
// dynamically generated Spec files under '/var/run/cdi', those take
|
// dynamically generated Spec files under '/var/run/cdi', those take
|
||||||
// precedence over static ones in '/etc/cdi'.
|
// precedence over static ones in '/etc/cdi'. With this scheme, static
|
||||||
|
// Spec files, typically installed by distro-specific packages, go into
|
||||||
|
// '/etc/cdi' while all the dynamically generated Spec files, transient
|
||||||
|
// or other, go into '/var/run/cdi'.
|
||||||
|
//
|
||||||
|
// Spec File Generation
|
||||||
|
//
|
||||||
|
// CDI offers two functions for writing and removing dynamically generated
|
||||||
|
// Specs from CDI Spec directories. These functions, WriteSpec() and
|
||||||
|
// RemoveSpec() implicitly follow the principle of separating dynamic Specs
|
||||||
|
// from the rest and therefore always write to and remove Specs from the
|
||||||
|
// last configured directory.
|
||||||
|
//
|
||||||
|
// Corresponding functions are also provided for generating names for Spec
|
||||||
|
// files. These functions follow a simple naming convention to ensure that
|
||||||
|
// multiple entities generating Spec files simultaneously on the same host
|
||||||
|
// do not end up using conflicting Spec file names. GenerateSpecName(),
|
||||||
|
// GenerateNameForSpec(), GenerateTransientSpecName(), and
|
||||||
|
// GenerateTransientNameForSpec() all generate names which can be passed
|
||||||
|
// as such to WriteSpec() and subsequently to RemoveSpec().
|
||||||
|
//
|
||||||
|
// Generating a Spec file for a vendor/device class can be done with a
|
||||||
|
// code snippet similar to the following:
|
||||||
|
//
|
||||||
|
// import (
|
||||||
|
// "fmt"
|
||||||
|
// ...
|
||||||
|
// "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
|
// "github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// func generateDeviceSpecs() error {
|
||||||
|
// registry := cdi.GetRegistry()
|
||||||
|
// spec := &specs.Spec{
|
||||||
|
// Version: specs.CurrentVersion,
|
||||||
|
// Kind: vendor+"/"+class,
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for _, dev := range enumerateDevices() {
|
||||||
|
// spec.Devices = append(spec.Devices, specs.Device{
|
||||||
|
// Name: dev.Name,
|
||||||
|
// ContainerEdits: getContainerEditsForDevice(dev),
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// specName, err := cdi.GenerateNameForSpec(spec)
|
||||||
|
// if err != nil {
|
||||||
|
// return fmt.Errorf("failed to generate Spec name: %w", err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return registry.SpecDB().WriteSpec(spec, specName)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Similary, generating and later cleaning up transient Spec files can be
|
||||||
|
// done with code fragments similar to the following. These transient Spec
|
||||||
|
// files are temporary Spec files with container-specific parametrization.
|
||||||
|
// They are typically created before the associated container is created
|
||||||
|
// and removed once that container is removed.
|
||||||
|
//
|
||||||
|
// import (
|
||||||
|
// "fmt"
|
||||||
|
// ...
|
||||||
|
// "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
|
// "github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// func generateTransientSpec(ctr Container) error {
|
||||||
|
// registry := cdi.GetRegistry()
|
||||||
|
// devices := getContainerDevs(ctr, vendor, class)
|
||||||
|
// spec := &specs.Spec{
|
||||||
|
// Version: specs.CurrentVersion,
|
||||||
|
// Kind: vendor+"/"+class,
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for _, dev := range devices {
|
||||||
|
// spec.Devices = append(spec.Devices, specs.Device{
|
||||||
|
// // the generated name needs to be unique within the
|
||||||
|
// // vendor/class domain on the host/node.
|
||||||
|
// Name: generateUniqueDevName(dev, ctr),
|
||||||
|
// ContainerEdits: getEditsForContainer(dev),
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // transientID is expected to guarantee that the Spec file name
|
||||||
|
// // generated using <vendor, class, transientID> is unique within
|
||||||
|
// // the host/node. If more than one device is allocated with the
|
||||||
|
// // same vendor/class domain, either all generated Spec entries
|
||||||
|
// // should go to a single Spec file (like in this sample snippet),
|
||||||
|
// // or transientID should be unique for each generated Spec file.
|
||||||
|
// transientID := getSomeSufficientlyUniqueIDForContainer(ctr)
|
||||||
|
// specName, err := cdi.GenerateNameForTransientSpec(vendor, class, transientID)
|
||||||
|
// if err != nil {
|
||||||
|
// return fmt.Errorf("failed to generate Spec name: %w", err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return registry.SpecDB().WriteSpec(spec, specName)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func removeTransientSpec(ctr Container) error {
|
||||||
|
// registry := cdi.GetRegistry()
|
||||||
|
// transientID := getSomeSufficientlyUniqueIDForContainer(ctr)
|
||||||
|
// specName := cdi.GenerateNameForTransientSpec(vendor, class, transientID)
|
||||||
|
//
|
||||||
|
// return registry.SpecDB().RemoveSpec(specName)
|
||||||
|
// }
|
||||||
//
|
//
|
||||||
// CDI Spec Validation
|
// CDI Spec Validation
|
||||||
//
|
//
|
||||||
|
@ -17,9 +17,8 @@
|
|||||||
package cdi
|
package cdi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// QualifiedName returns the qualified name for a device.
|
// QualifiedName returns the qualified name for a device.
|
||||||
@ -50,23 +49,23 @@ func ParseQualifiedName(device string) (string, string, string, error) {
|
|||||||
vendor, class, name := ParseDevice(device)
|
vendor, class, name := ParseDevice(device)
|
||||||
|
|
||||||
if vendor == "" {
|
if vendor == "" {
|
||||||
return "", "", device, errors.Errorf("unqualified device %q, missing vendor", device)
|
return "", "", device, fmt.Errorf("unqualified device %q, missing vendor", device)
|
||||||
}
|
}
|
||||||
if class == "" {
|
if class == "" {
|
||||||
return "", "", device, errors.Errorf("unqualified device %q, missing class", device)
|
return "", "", device, fmt.Errorf("unqualified device %q, missing class", device)
|
||||||
}
|
}
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return "", "", device, errors.Errorf("unqualified device %q, missing device name", device)
|
return "", "", device, fmt.Errorf("unqualified device %q, missing device name", device)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ValidateVendorName(vendor); err != nil {
|
if err := ValidateVendorName(vendor); err != nil {
|
||||||
return "", "", device, errors.Wrapf(err, "invalid device %q", device)
|
return "", "", device, fmt.Errorf("invalid device %q: %w", device, err)
|
||||||
}
|
}
|
||||||
if err := ValidateClassName(class); err != nil {
|
if err := ValidateClassName(class); err != nil {
|
||||||
return "", "", device, errors.Wrapf(err, "invalid device %q", device)
|
return "", "", device, fmt.Errorf("invalid device %q: %w", device, err)
|
||||||
}
|
}
|
||||||
if err := ValidateDeviceName(name); err != nil {
|
if err := ValidateDeviceName(name); err != nil {
|
||||||
return "", "", device, errors.Wrapf(err, "invalid device %q", device)
|
return "", "", device, fmt.Errorf("invalid device %q: %w", device, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return vendor, class, name, nil
|
return vendor, class, name, nil
|
||||||
@ -115,22 +114,22 @@ func ParseQualifier(kind string) (string, string) {
|
|||||||
// - underscore, dash, and dot ('_', '-', and '.')
|
// - underscore, dash, and dot ('_', '-', and '.')
|
||||||
func ValidateVendorName(vendor string) error {
|
func ValidateVendorName(vendor string) error {
|
||||||
if vendor == "" {
|
if vendor == "" {
|
||||||
return errors.Errorf("invalid (empty) vendor name")
|
return fmt.Errorf("invalid (empty) vendor name")
|
||||||
}
|
}
|
||||||
if !isLetter(rune(vendor[0])) {
|
if !isLetter(rune(vendor[0])) {
|
||||||
return errors.Errorf("invalid vendor %q, should start with letter", vendor)
|
return fmt.Errorf("invalid vendor %q, should start with letter", vendor)
|
||||||
}
|
}
|
||||||
for _, c := range string(vendor[1 : len(vendor)-1]) {
|
for _, c := range string(vendor[1 : len(vendor)-1]) {
|
||||||
switch {
|
switch {
|
||||||
case isAlphaNumeric(c):
|
case isAlphaNumeric(c):
|
||||||
case c == '_' || c == '-' || c == '.':
|
case c == '_' || c == '-' || c == '.':
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("invalid character '%c' in vendor name %q",
|
return fmt.Errorf("invalid character '%c' in vendor name %q",
|
||||||
c, vendor)
|
c, vendor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !isAlphaNumeric(rune(vendor[len(vendor)-1])) {
|
if !isAlphaNumeric(rune(vendor[len(vendor)-1])) {
|
||||||
return errors.Errorf("invalid vendor %q, should end with a letter or digit", vendor)
|
return fmt.Errorf("invalid vendor %q, should end with a letter or digit", vendor)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -143,22 +142,22 @@ func ValidateVendorName(vendor string) error {
|
|||||||
// - underscore and dash ('_', '-')
|
// - underscore and dash ('_', '-')
|
||||||
func ValidateClassName(class string) error {
|
func ValidateClassName(class string) error {
|
||||||
if class == "" {
|
if class == "" {
|
||||||
return errors.Errorf("invalid (empty) device class")
|
return fmt.Errorf("invalid (empty) device class")
|
||||||
}
|
}
|
||||||
if !isLetter(rune(class[0])) {
|
if !isLetter(rune(class[0])) {
|
||||||
return errors.Errorf("invalid class %q, should start with letter", class)
|
return fmt.Errorf("invalid class %q, should start with letter", class)
|
||||||
}
|
}
|
||||||
for _, c := range string(class[1 : len(class)-1]) {
|
for _, c := range string(class[1 : len(class)-1]) {
|
||||||
switch {
|
switch {
|
||||||
case isAlphaNumeric(c):
|
case isAlphaNumeric(c):
|
||||||
case c == '_' || c == '-':
|
case c == '_' || c == '-':
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("invalid character '%c' in device class %q",
|
return fmt.Errorf("invalid character '%c' in device class %q",
|
||||||
c, class)
|
c, class)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !isAlphaNumeric(rune(class[len(class)-1])) {
|
if !isAlphaNumeric(rune(class[len(class)-1])) {
|
||||||
return errors.Errorf("invalid class %q, should end with a letter or digit", class)
|
return fmt.Errorf("invalid class %q, should end with a letter or digit", class)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -170,10 +169,10 @@ func ValidateClassName(class string) error {
|
|||||||
// - underscore, dash, dot, colon ('_', '-', '.', ':')
|
// - underscore, dash, dot, colon ('_', '-', '.', ':')
|
||||||
func ValidateDeviceName(name string) error {
|
func ValidateDeviceName(name string) error {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return errors.Errorf("invalid (empty) device name")
|
return fmt.Errorf("invalid (empty) device name")
|
||||||
}
|
}
|
||||||
if !isAlphaNumeric(rune(name[0])) {
|
if !isAlphaNumeric(rune(name[0])) {
|
||||||
return errors.Errorf("invalid class %q, should start with a letter or digit", name)
|
return fmt.Errorf("invalid class %q, should start with a letter or digit", name)
|
||||||
}
|
}
|
||||||
if len(name) == 1 {
|
if len(name) == 1 {
|
||||||
return nil
|
return nil
|
||||||
@ -183,12 +182,12 @@ func ValidateDeviceName(name string) error {
|
|||||||
case isAlphaNumeric(c):
|
case isAlphaNumeric(c):
|
||||||
case c == '_' || c == '-' || c == '.' || c == ':':
|
case c == '_' || c == '-' || c == '.' || c == ':':
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("invalid character '%c' in device name %q",
|
return fmt.Errorf("invalid character '%c' in device name %q",
|
||||||
c, name)
|
c, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !isAlphaNumeric(rune(name[len(name)-1])) {
|
if !isAlphaNumeric(rune(name[len(name)-1])) {
|
||||||
return errors.Errorf("invalid name %q, should end with a letter or digit", name)
|
return fmt.Errorf("invalid name %q, should end with a letter or digit", name)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -107,6 +107,7 @@ type RegistrySpecDB interface {
|
|||||||
GetVendorSpecs(vendor string) []*Spec
|
GetVendorSpecs(vendor string) []*Spec
|
||||||
GetSpecErrors(*Spec) []error
|
GetSpecErrors(*Spec) []error
|
||||||
WriteSpec(raw *cdi.Spec, name string) error
|
WriteSpec(raw *cdi.Spec, name string) error
|
||||||
|
RemoveSpec(name string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type registry struct {
|
type registry struct {
|
||||||
|
146
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/spec.go
generated
vendored
146
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/spec.go
generated
vendored
@ -18,29 +18,28 @@ package cdi
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
oci "github.com/opencontainers/runtime-spec/specs-go"
|
oci "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"sigs.k8s.io/yaml"
|
"sigs.k8s.io/yaml"
|
||||||
|
|
||||||
cdi "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
cdi "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
const (
|
||||||
// Valid CDI Spec versions.
|
// defaultSpecExt is the file extension for the default encoding.
|
||||||
validSpecVersions = map[string]struct{}{
|
defaultSpecExt = ".yaml"
|
||||||
"0.1.0": {},
|
)
|
||||||
"0.2.0": {},
|
|
||||||
"0.3.0": {},
|
|
||||||
"0.4.0": {},
|
|
||||||
"0.5.0": {},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
var (
|
||||||
// Externally set CDI Spec validation function.
|
// Externally set CDI Spec validation function.
|
||||||
specValidator func(*cdi.Spec) error
|
specValidator func(*cdi.Spec) error
|
||||||
|
validatorLock sync.RWMutex
|
||||||
)
|
)
|
||||||
|
|
||||||
// Spec represents a single CDI Spec. It is usually loaded from a
|
// Spec represents a single CDI Spec. It is usually loaded from a
|
||||||
@ -67,18 +66,18 @@ func ReadSpec(path string, priority int) (*Spec, error) {
|
|||||||
case os.IsNotExist(err):
|
case os.IsNotExist(err):
|
||||||
return nil, err
|
return nil, err
|
||||||
case err != nil:
|
case err != nil:
|
||||||
return nil, errors.Wrapf(err, "failed to read CDI Spec %q", path)
|
return nil, fmt.Errorf("failed to read CDI Spec %q: %w", path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
raw, err := ParseSpec(data)
|
raw, err := ParseSpec(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to parse CDI Spec %q", path)
|
return nil, fmt.Errorf("failed to parse CDI Spec %q: %w", path, err)
|
||||||
}
|
}
|
||||||
if raw == nil {
|
if raw == nil {
|
||||||
return nil, errors.Errorf("failed to parse CDI Spec %q, no Spec data", path)
|
return nil, fmt.Errorf("failed to parse CDI Spec %q, no Spec data", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
spec, err := NewSpec(raw, path, priority)
|
spec, err := newSpec(raw, path, priority)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -86,11 +85,11 @@ func ReadSpec(path string, priority int) (*Spec, error) {
|
|||||||
return spec, nil
|
return spec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSpec creates a new Spec from the given CDI Spec data. The
|
// newSpec creates a new Spec from the given CDI Spec data. The
|
||||||
// Spec is marked as loaded from the given path with the given
|
// Spec is marked as loaded from the given path with the given
|
||||||
// priority. If Spec data validation fails NewSpec returns a nil
|
// priority. If Spec data validation fails newSpec returns a nil
|
||||||
// Spec and an error.
|
// Spec and an error.
|
||||||
func NewSpec(raw *cdi.Spec, path string, priority int) (*Spec, error) {
|
func newSpec(raw *cdi.Spec, path string, priority int) (*Spec, error) {
|
||||||
err := validateSpec(raw)
|
err := validateSpec(raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -102,18 +101,22 @@ func NewSpec(raw *cdi.Spec, path string, priority int) (*Spec, error) {
|
|||||||
priority: priority,
|
priority: priority,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ext := filepath.Ext(spec.path); ext != ".yaml" && ext != ".json" {
|
||||||
|
spec.path += defaultSpecExt
|
||||||
|
}
|
||||||
|
|
||||||
spec.vendor, spec.class = ParseQualifier(spec.Kind)
|
spec.vendor, spec.class = ParseQualifier(spec.Kind)
|
||||||
|
|
||||||
if spec.devices, err = spec.validate(); err != nil {
|
if spec.devices, err = spec.validate(); err != nil {
|
||||||
return nil, errors.Wrap(err, "invalid CDI Spec")
|
return nil, fmt.Errorf("invalid CDI Spec: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return spec, nil
|
return spec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the CDI Spec to the file associated with it during instantiation
|
// Write the CDI Spec to the file associated with it during instantiation
|
||||||
// by NewSpec() or ReadSpec().
|
// by newSpec() or ReadSpec().
|
||||||
func (s *Spec) Write(overwrite bool) error {
|
func (s *Spec) write(overwrite bool) error {
|
||||||
var (
|
var (
|
||||||
data []byte
|
data []byte
|
||||||
dir string
|
dir string
|
||||||
@ -132,30 +135,30 @@ func (s *Spec) Write(overwrite bool) error {
|
|||||||
data, err = json.Marshal(s.Spec)
|
data, err = json.Marshal(s.Spec)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to marshal Spec file")
|
return fmt.Errorf("failed to marshal Spec file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
dir = filepath.Dir(s.path)
|
dir = filepath.Dir(s.path)
|
||||||
err = os.MkdirAll(dir, 0o755)
|
err = os.MkdirAll(dir, 0o755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to create Spec dir")
|
return fmt.Errorf("failed to create Spec dir: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp, err = os.CreateTemp(dir, "spec.*.tmp")
|
tmp, err = os.CreateTemp(dir, "spec.*.tmp")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to create Spec file")
|
return fmt.Errorf("failed to create Spec file: %w", err)
|
||||||
}
|
}
|
||||||
_, err = tmp.Write(data)
|
_, err = tmp.Write(data)
|
||||||
tmp.Close()
|
tmp.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to write Spec file")
|
return fmt.Errorf("failed to write Spec file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = renameIn(dir, filepath.Base(tmp.Name()), filepath.Base(s.path), overwrite)
|
err = renameIn(dir, filepath.Base(tmp.Name()), filepath.Base(s.path), overwrite)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
os.Remove(tmp.Name())
|
os.Remove(tmp.Name())
|
||||||
err = errors.Wrap(err, "failed to write Spec file")
|
err = fmt.Errorf("failed to write Spec file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
@ -201,6 +204,15 @@ func (s *Spec) validate() (map[string]*Device, error) {
|
|||||||
if err := validateVersion(s.Version); err != nil {
|
if err := validateVersion(s.Version); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
minVersion, err := MinimumRequiredVersion(s.Spec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not determine minumum required version: %v", err)
|
||||||
|
}
|
||||||
|
if newVersion(minVersion).IsGreaterThan(newVersion(s.Version)) {
|
||||||
|
return nil, fmt.Errorf("the spec version must be at least v%v", minVersion)
|
||||||
|
}
|
||||||
|
|
||||||
if err := ValidateVendorName(s.vendor); err != nil {
|
if err := ValidateVendorName(s.vendor); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -215,10 +227,10 @@ func (s *Spec) validate() (map[string]*Device, error) {
|
|||||||
for _, d := range s.Devices {
|
for _, d := range s.Devices {
|
||||||
dev, err := newDevice(s, d)
|
dev, err := newDevice(s, d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed add device %q", d.Name)
|
return nil, fmt.Errorf("failed add device %q: %w", d.Name, err)
|
||||||
}
|
}
|
||||||
if _, conflict := devices[d.Name]; conflict {
|
if _, conflict := devices[d.Name]; conflict {
|
||||||
return nil, errors.Errorf("invalid spec, multiple device %q", d.Name)
|
return nil, fmt.Errorf("invalid spec, multiple device %q", d.Name)
|
||||||
}
|
}
|
||||||
devices[d.Name] = dev
|
devices[d.Name] = dev
|
||||||
}
|
}
|
||||||
@ -228,8 +240,8 @@ func (s *Spec) validate() (map[string]*Device, error) {
|
|||||||
|
|
||||||
// validateVersion checks whether the specified spec version is supported.
|
// validateVersion checks whether the specified spec version is supported.
|
||||||
func validateVersion(version string) error {
|
func validateVersion(version string) error {
|
||||||
if _, ok := validSpecVersions[version]; !ok {
|
if !validSpecVersions.isValidVersion(version) {
|
||||||
return errors.Errorf("invalid version %q", version)
|
return fmt.Errorf("invalid version %q", version)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -240,26 +252,96 @@ func ParseSpec(data []byte) (*cdi.Spec, error) {
|
|||||||
var raw *cdi.Spec
|
var raw *cdi.Spec
|
||||||
err := yaml.UnmarshalStrict(data, &raw)
|
err := yaml.UnmarshalStrict(data, &raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to unmarshal CDI Spec")
|
return nil, fmt.Errorf("failed to unmarshal CDI Spec: %w", err)
|
||||||
}
|
}
|
||||||
return raw, nil
|
return raw, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSpecValidator sets a CDI Spec validator function. This function
|
// SetSpecValidator sets a CDI Spec validator function. This function
|
||||||
// is used for extra CDI Spec content validation whenever a Spec file
|
// is used for extra CDI Spec content validation whenever a Spec file
|
||||||
// loaded (using ReadSpec() or NewSpec()) or written (Spec.Write()).
|
// loaded (using ReadSpec() or written (using WriteSpec()).
|
||||||
func SetSpecValidator(fn func(*cdi.Spec) error) {
|
func SetSpecValidator(fn func(*cdi.Spec) error) {
|
||||||
|
validatorLock.Lock()
|
||||||
|
defer validatorLock.Unlock()
|
||||||
specValidator = fn
|
specValidator = fn
|
||||||
}
|
}
|
||||||
|
|
||||||
// validateSpec validates the Spec using the extneral validator.
|
// validateSpec validates the Spec using the extneral validator.
|
||||||
func validateSpec(raw *cdi.Spec) error {
|
func validateSpec(raw *cdi.Spec) error {
|
||||||
|
validatorLock.RLock()
|
||||||
|
defer validatorLock.RUnlock()
|
||||||
|
|
||||||
if specValidator == nil {
|
if specValidator == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := specValidator(raw)
|
err := specValidator(raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Spec validation failed")
|
return fmt.Errorf("Spec validation failed: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenerateSpecName generates a vendor+class scoped Spec file name. The
|
||||||
|
// name can be passed to WriteSpec() to write a Spec file to the file
|
||||||
|
// system.
|
||||||
|
//
|
||||||
|
// vendor and class should match the vendor and class of the CDI Spec.
|
||||||
|
// The file name is generated without a ".json" or ".yaml" extension.
|
||||||
|
// The caller can append the desired extension to choose a particular
|
||||||
|
// encoding. Otherwise WriteSpec() will use its default encoding.
|
||||||
|
//
|
||||||
|
// This function always returns the same name for the same vendor/class
|
||||||
|
// combination. Therefore it cannot be used as such to generate multiple
|
||||||
|
// Spec file names for a single vendor and class.
|
||||||
|
func GenerateSpecName(vendor, class string) string {
|
||||||
|
return vendor + "-" + class
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateTransientSpecName generates a vendor+class scoped transient
|
||||||
|
// Spec file name. The name can be passed to WriteSpec() to write a Spec
|
||||||
|
// file to the file system.
|
||||||
|
//
|
||||||
|
// Transient Specs are those whose lifecycle is tied to that of some
|
||||||
|
// external entity, for instance a container. vendor and class should
|
||||||
|
// match the vendor and class of the CDI Spec. transientID should be
|
||||||
|
// unique among all CDI users on the same host that might generate
|
||||||
|
// transient Spec files using the same vendor/class combination. If
|
||||||
|
// the external entity to which the lifecycle of the tranient Spec
|
||||||
|
// is tied to has a unique ID of its own, then this is usually a
|
||||||
|
// good choice for transientID.
|
||||||
|
//
|
||||||
|
// The file name is generated without a ".json" or ".yaml" extension.
|
||||||
|
// The caller can append the desired extension to choose a particular
|
||||||
|
// encoding. Otherwise WriteSpec() will use its default encoding.
|
||||||
|
func GenerateTransientSpecName(vendor, class, transientID string) string {
|
||||||
|
transientID = strings.ReplaceAll(transientID, "/", "_")
|
||||||
|
return GenerateSpecName(vendor, class) + "_" + transientID
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateNameForSpec generates a name for the given Spec using
|
||||||
|
// GenerateSpecName with the vendor and class taken from the Spec.
|
||||||
|
// On success it returns the generated name and a nil error. If
|
||||||
|
// the Spec does not contain a valid vendor or class, it returns
|
||||||
|
// an empty name and a non-nil error.
|
||||||
|
func GenerateNameForSpec(raw *cdi.Spec) (string, error) {
|
||||||
|
vendor, class := ParseQualifier(raw.Kind)
|
||||||
|
if vendor == "" {
|
||||||
|
return "", fmt.Errorf("invalid vendor/class %q in Spec", raw.Kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
return GenerateSpecName(vendor, class), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateNameForTransientSpec generates a name for the given transient
|
||||||
|
// Spec using GenerateTransientSpecName with the vendor and class taken
|
||||||
|
// from the Spec. On success it returns the generated name and a nil error.
|
||||||
|
// If the Spec does not contain a valid vendor or class, it returns an
|
||||||
|
// an empty name and a non-nil error.
|
||||||
|
func GenerateNameForTransientSpec(raw *cdi.Spec, transientID string) (string, error) {
|
||||||
|
vendor, class := ParseQualifier(raw.Kind)
|
||||||
|
if vendor == "" {
|
||||||
|
return "", fmt.Errorf("invalid vendor/class %q in Spec", raw.Kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
return GenerateTransientSpecName(vendor, class, transientID), nil
|
||||||
|
}
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
package cdi
|
package cdi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ func renameIn(dir, src, dst string, overwrite bool) error {
|
|||||||
|
|
||||||
dirf, err := os.Open(dir)
|
dirf, err := os.Open(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "rename failed")
|
return fmt.Errorf("rename failed: %w", err)
|
||||||
}
|
}
|
||||||
defer dirf.Close()
|
defer dirf.Close()
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ func renameIn(dir, src, dst string, overwrite bool) error {
|
|||||||
dirFd := int(dirf.Fd())
|
dirFd := int(dirf.Fd())
|
||||||
err = unix.Renameat2(dirFd, src, dirFd, dst, flags)
|
err = unix.Renameat2(dirFd, src, dirFd, dst, flags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "rename failed")
|
return fmt.Errorf("rename failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
160
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/version.go
generated
vendored
Normal file
160
vendor/github.com/container-orchestrated-devices/container-device-interface/pkg/cdi/version.go
generated
vendored
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
Copyright © The CDI 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 cdi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/mod/semver"
|
||||||
|
|
||||||
|
cdi "github.com/container-orchestrated-devices/container-device-interface/specs-go"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// CurrentVersion is the current version of the CDI Spec.
|
||||||
|
CurrentVersion = cdi.CurrentVersion
|
||||||
|
|
||||||
|
// vCurrent is the current version as a semver-comparable type
|
||||||
|
vCurrent version = "v" + CurrentVersion
|
||||||
|
|
||||||
|
// These represent the released versions of the CDI specification
|
||||||
|
v010 version = "v0.1.0"
|
||||||
|
v020 version = "v0.2.0"
|
||||||
|
v030 version = "v0.3.0"
|
||||||
|
v040 version = "v0.4.0"
|
||||||
|
v050 version = "v0.5.0"
|
||||||
|
|
||||||
|
// vEarliest is the earliest supported version of the CDI specification
|
||||||
|
vEarliest version = v030
|
||||||
|
)
|
||||||
|
|
||||||
|
// validSpecVersions stores a map of spec versions to functions to check the required versions.
|
||||||
|
// Adding new fields / spec versions requires that a `requiredFunc` be implemented and
|
||||||
|
// this map be updated.
|
||||||
|
var validSpecVersions = requiredVersionMap{
|
||||||
|
v010: nil,
|
||||||
|
v020: nil,
|
||||||
|
v030: nil,
|
||||||
|
v040: requiresV040,
|
||||||
|
v050: requiresV050,
|
||||||
|
}
|
||||||
|
|
||||||
|
// MinimumRequiredVersion determines the minumum spec version for the input spec.
|
||||||
|
func MinimumRequiredVersion(spec *cdi.Spec) (string, error) {
|
||||||
|
minVersion := validSpecVersions.requiredVersion(spec)
|
||||||
|
return minVersion.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// version represents a semantic version string
|
||||||
|
type version string
|
||||||
|
|
||||||
|
// newVersion creates a version that can be used for semantic version comparisons.
|
||||||
|
func newVersion(v string) version {
|
||||||
|
return version("v" + strings.TrimPrefix(v, "v"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string representation of the version.
|
||||||
|
// This trims a leading v if present.
|
||||||
|
func (v version) String() string {
|
||||||
|
return strings.TrimPrefix(string(v), "v")
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsGreaterThan checks with a version is greater than the specified version.
|
||||||
|
func (v version) IsGreaterThan(o version) bool {
|
||||||
|
return semver.Compare(string(v), string(o)) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsLatest checks whether the version is the latest supported version
|
||||||
|
func (v version) IsLatest() bool {
|
||||||
|
return v == vCurrent
|
||||||
|
}
|
||||||
|
|
||||||
|
type requiredFunc func(*cdi.Spec) bool
|
||||||
|
|
||||||
|
type requiredVersionMap map[version]requiredFunc
|
||||||
|
|
||||||
|
// isValidVersion checks whether the specified version is valid.
|
||||||
|
// A version is valid if it is contained in the required version map.
|
||||||
|
func (r requiredVersionMap) isValidVersion(specVersion string) bool {
|
||||||
|
_, ok := validSpecVersions[newVersion(specVersion)]
|
||||||
|
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// requiredVersion returns the minimum version required for the given spec
|
||||||
|
func (r requiredVersionMap) requiredVersion(spec *cdi.Spec) version {
|
||||||
|
minVersion := vEarliest
|
||||||
|
|
||||||
|
for v, isRequired := range validSpecVersions {
|
||||||
|
if isRequired == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if isRequired(spec) && v.IsGreaterThan(minVersion) {
|
||||||
|
minVersion = v
|
||||||
|
}
|
||||||
|
// If we have already detected the latest version then no later version could be detected
|
||||||
|
if minVersion.IsLatest() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return minVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
// requiresV050 returns true if the spec uses v0.5.0 features
|
||||||
|
func requiresV050(spec *cdi.Spec) bool {
|
||||||
|
var edits []*cdi.ContainerEdits
|
||||||
|
|
||||||
|
for _, d := range spec.Devices {
|
||||||
|
// The v0.5.0 spec allowed device names to start with a digit instead of requiring a letter
|
||||||
|
if len(d.Name) > 0 && !isLetter(rune(d.Name[0])) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
edits = append(edits, &d.ContainerEdits)
|
||||||
|
}
|
||||||
|
|
||||||
|
edits = append(edits, &spec.ContainerEdits)
|
||||||
|
for _, e := range edits {
|
||||||
|
for _, dn := range e.DeviceNodes {
|
||||||
|
// The HostPath field was added in v0.5.0
|
||||||
|
if dn.HostPath != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// requiresV040 returns true if the spec uses v0.4.0 features
|
||||||
|
func requiresV040(spec *cdi.Spec) bool {
|
||||||
|
var edits []*cdi.ContainerEdits
|
||||||
|
|
||||||
|
for _, d := range spec.Devices {
|
||||||
|
edits = append(edits, &d.ContainerEdits)
|
||||||
|
}
|
||||||
|
|
||||||
|
edits = append(edits, &spec.ContainerEdits)
|
||||||
|
for _, e := range edits {
|
||||||
|
for _, m := range e.Mounts {
|
||||||
|
// The Type field was added in v0.4.0
|
||||||
|
if m.Type != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
5
vendor/modules.txt
vendored
5
vendor/modules.txt
vendored
@ -76,8 +76,9 @@ github.com/cilium/ebpf/internal
|
|||||||
github.com/cilium/ebpf/internal/sys
|
github.com/cilium/ebpf/internal/sys
|
||||||
github.com/cilium/ebpf/internal/unix
|
github.com/cilium/ebpf/internal/unix
|
||||||
github.com/cilium/ebpf/link
|
github.com/cilium/ebpf/link
|
||||||
# github.com/container-orchestrated-devices/container-device-interface v0.5.1
|
# github.com/container-orchestrated-devices/container-device-interface v0.5.4
|
||||||
## explicit; go 1.17
|
## explicit; go 1.17
|
||||||
|
github.com/container-orchestrated-devices/container-device-interface/internal/multierror
|
||||||
github.com/container-orchestrated-devices/container-device-interface/pkg/cdi
|
github.com/container-orchestrated-devices/container-device-interface/pkg/cdi
|
||||||
github.com/container-orchestrated-devices/container-device-interface/specs-go
|
github.com/container-orchestrated-devices/container-device-interface/specs-go
|
||||||
# github.com/containerd/aufs v1.0.0
|
# github.com/containerd/aufs v1.0.0
|
||||||
@ -348,7 +349,7 @@ github.com/opencontainers/runc/libcontainer/user
|
|||||||
# github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb
|
# github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb
|
||||||
## explicit
|
## explicit
|
||||||
github.com/opencontainers/runtime-spec/specs-go
|
github.com/opencontainers/runtime-spec/specs-go
|
||||||
# github.com/opencontainers/runtime-tools v0.9.0 => github.com/opencontainers/runtime-tools v0.0.0-20221026201742-946c877fa809
|
# github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626 => github.com/opencontainers/runtime-tools v0.0.0-20221026201742-946c877fa809
|
||||||
## explicit; go 1.16
|
## explicit; go 1.16
|
||||||
github.com/opencontainers/runtime-tools/generate
|
github.com/opencontainers/runtime-tools/generate
|
||||||
github.com/opencontainers/runtime-tools/generate/seccomp
|
github.com/opencontainers/runtime-tools/generate/seccomp
|
||||||
|
Loading…
Reference in New Issue
Block a user