mirror of https://github.com/kubernetes/kops.git
Merge pull request #11860 from olemarkus/update-helm
Update helm to v3.6.1
This commit is contained in:
commit
a0438915dc
2
go.mod
2
go.mod
|
|
@ -83,7 +83,7 @@ require (
|
|||
gopkg.in/gcfg.v1 v1.2.3
|
||||
gopkg.in/inf.v0 v0.9.1
|
||||
gopkg.in/square/go-jose.v2 v2.5.1
|
||||
helm.sh/helm/v3 v3.5.1
|
||||
helm.sh/helm/v3 v3.6.1
|
||||
k8s.io/api v0.21.1
|
||||
k8s.io/apimachinery v0.21.1
|
||||
k8s.io/cli-runtime v0.21.1
|
||||
|
|
|
|||
68
go.sum
68
go.sum
|
|
@ -98,12 +98,10 @@ github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp
|
|||
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
|
||||
github.com/MakeNowJust/heredoc/v2 v2.0.1 h1:rlCHh70XXXv7toz95ajQWOWQnN4WNLt0TdpZYIR/J6A=
|
||||
github.com/MakeNowJust/heredoc/v2 v2.0.1/go.mod h1:6/2Abh5s+hc3g9nbWLe9ObDIOhaRrqsyY9MWy+4JdRM=
|
||||
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Masterminds/sprig/v3 v3.2.0/go.mod h1:tWhwTbUTndesPNeF0C900vKoq283u6zp4APT9vaF3SI=
|
||||
github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
|
||||
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
|
||||
github.com/Masterminds/squirrel v1.5.0/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
|
|
@ -111,11 +109,13 @@ github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHS
|
|||
github.com/MichaelTJones/walk v0.0.0-20161122175330-4748e29d5718/go.mod h1:VVwKsx9Dc8rNG55BWqogoJzGubjKnRoXdUvpGbWqeCc=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
github.com/Microsoft/go-winio v0.4.15 h1:qkLXKzb1QoVatRyd/YlXZ/Kg0m5K3SPuoD82jjSOaBc=
|
||||
github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
|
||||
github.com/Microsoft/hcsshim v0.8.10-0.20200715222032-5eafd1556990 h1:1xpVY4dSUSbW3PcSGxZJhI8Z+CJiqbd933kM7HIinTc=
|
||||
github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
|
||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/Microsoft/hcsshim v0.8.10-0.20200715222032-5eafd1556990/go.mod h1:ay/0dTb7NsG8QMDfsRfLHgZo/6xAJShLe1+ePPflihk=
|
||||
github.com/Microsoft/hcsshim v0.8.14 h1:lbPVK25c1cu5xTLITwpUcxoA9vKrKErASPYygvouJns=
|
||||
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
|
|
@ -188,7 +188,6 @@ github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3
|
|||
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
||||
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.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
|
|
@ -235,20 +234,17 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:z
|
|||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/container-storage-interface/spec v1.2.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
|
||||
github.com/container-storage-interface/spec v1.3.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
|
||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
||||
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 h1:qWj4qVYZ95vLWwqyNJCQg7rDsG5wPdze0UaPolH7DUk=
|
||||
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
|
||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||
github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw=
|
||||
github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.4.4 h1:rtRG4N6Ct7GNssATwgpvMGfnjnwfjnu/Zs9W3Ikzq+M=
|
||||
github.com/containerd/containerd v1.4.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41 h1:kIFnQBO7rQ0XkMe6xEwbybYHBEaWmh/f++laI6Emt7M=
|
||||
github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY=
|
||||
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7 h1:6ejg6Lkk8dskcM7wQ28gONkukbQkM4qpj4RnYbpFzrI=
|
||||
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
|
||||
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.4.1 h1:5e7heayhB7CcgdTkqfZqrNaNv15gABwr3Q2jBTbLlt4=
|
||||
|
|
@ -290,8 +286,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
|
||||
github.com/deislabs/oras v0.8.1 h1:If674KraJVpujYR00rzdi0QAmW4BxzMJPVAZJKuhQ0c=
|
||||
github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC4G4As=
|
||||
github.com/deislabs/oras v0.11.1 h1:oo2J/3vXdcti8cjFi8ghMOkx0OacONxHC8dhJ17NdJ0=
|
||||
github.com/deislabs/oras v0.11.1/go.mod h1:39lCtf8Q6WDC7ul9cnyWXONNzKvabEKk+AX+L0ImnQk=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
||||
github.com/denverdino/aliyungo v0.0.0-20210425065611-55bee4942cba h1:3g+YC/AyMKyPBDTKKMxTHekNFhBZPSxa/ckOPjOJPuU=
|
||||
|
|
@ -307,14 +303,14 @@ github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi
|
|||
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
|
||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492 h1:FwssHbCDJD025h+BchanCwE1Q8fyMgqDr2mOQAWOLGw=
|
||||
github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v20.10.5+incompatible h1:bjflayQbWg+xOkF2WPEAOi4Y7zWhR7ptoPhV/VqLVDE=
|
||||
github.com/docker/cli v20.10.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.6+incompatible h1:oXI3Vas8TI8Eu/EjH4srKHJBVqraSzJybhxY7Om9faQ=
|
||||
github.com/docker/docker v20.10.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
|
|
@ -474,7 +470,6 @@ github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8z
|
|||
github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q=
|
||||
github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godror/godror v0.13.3/go.mod h1:2ouUT4kdhUBk7TAkHWD4SN0CdI0pgEQbo8FVHhbSKWg=
|
||||
|
|
@ -615,7 +610,6 @@ github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBt
|
|||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
|
|
@ -631,7 +625,6 @@ github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjh
|
|||
github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g=
|
||||
github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
|
||||
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
|
||||
|
|
@ -713,7 +706,7 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
|
|||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
|
||||
github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
|
|
@ -760,9 +753,8 @@ github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3v
|
|||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
|
||||
|
|
@ -806,9 +798,9 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
|
|||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
|
|
@ -823,8 +815,9 @@ github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7
|
|||
github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY=
|
||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/copystructure v1.1.1 h1:Bp6x9R1Wn16SIz3OfeDr0b7RnCG2OB66Y7PQyC/cvq4=
|
||||
github.com/mitchellh/copystructure v1.1.1/go.mod h1:EBArHfARyrSWO/+Wyr9zwEkc6XMFB9XyNgFNmRkZZU4=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
|
|
@ -841,8 +834,9 @@ github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
|
|||
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||
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/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE=
|
||||
github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/moby/ipvs v1.0.1/go.mod h1:2pngiyseZbIKXNv7hsKj3O9UEz30c53MT9005gt2hxQ=
|
||||
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
|
|
@ -896,7 +890,6 @@ github.com/onsi/ginkgo v1.4.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
|||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
|
|
@ -918,7 +911,6 @@ github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je4
|
|||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
|
|
@ -927,10 +919,8 @@ github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM
|
|||
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
|
||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
|
||||
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
|
|
@ -960,7 +950,6 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0
|
|||
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
|
|
@ -1007,7 +996,6 @@ github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R
|
|||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
|
|
@ -1051,13 +1039,13 @@ github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXY
|
|||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
|
||||
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
|
||||
|
|
@ -1117,7 +1105,6 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
|
|||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/thecodeteam/goscaleio v0.1.0/go.mod h1:68sdkZAsK8bvEwBlbQnlLS+xU+hvLYM/iQ8KXej1AwM=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
|
|
@ -1126,7 +1113,6 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1
|
|||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
|
|
@ -1148,7 +1134,6 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP
|
|||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
|
|
@ -1211,7 +1196,6 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
|||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U=
|
||||
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
||||
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
|
@ -1233,7 +1217,6 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
|
|
@ -1399,7 +1382,6 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -1711,7 +1693,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
|||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
@ -1726,7 +1707,6 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
|
|||
gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/gcfg.v1 v1.2.3 h1:m8OOJ4ccYHnx2f4gQwpno8nAX5OGOh7RLaaz0pj3Ogs=
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
||||
gopkg.in/godo.v2 v2.0.9/go.mod h1:wgvPPKLsWN0hPIJ4JyxvFGGbIW3fJMSrXhdvSuZ1z/8=
|
||||
gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
|
|
@ -1773,8 +1753,8 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81
|
|||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
helm.sh/helm/v3 v3.5.1 h1:XPn6xyH4Lcbx0sdUsVttt2E9jH2oJddpLLZtQH0XNfQ=
|
||||
helm.sh/helm/v3 v3.5.1/go.mod h1:bjwXfmGAF+SEuJZ2AtN1xmTuz4FqaNYOJrXP+vtj6Tw=
|
||||
helm.sh/helm/v3 v3.6.1 h1:TQ6q4pAatXr7qh2fbLcb0oNd0I3J7kv26oo5cExKTtc=
|
||||
helm.sh/helm/v3 v3.6.1/go.mod h1:mIIus8EOqj+obtycw3sidsR4ORr2aFDmXMSI3k+oeVY=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
|
|||
|
|
@ -154,7 +154,6 @@ github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy86
|
|||
github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Masterminds/sprig/v3 v3.0.2/go.mod h1:oesJ8kPONMONaZgtiHNzUShJbksypC5kWczhZAf6+aU=
|
||||
github.com/Masterminds/sprig/v3 v3.2.0/go.mod h1:tWhwTbUTndesPNeF0C900vKoq283u6zp4APT9vaF3SI=
|
||||
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
|
||||
github.com/Masterminds/squirrel v1.5.0/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
|
||||
|
|
@ -162,9 +161,12 @@ github.com/MichaelTJones/walk v0.0.0-20161122175330-4748e29d5718/go.mod h1:VVwKs
|
|||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
|
||||
github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
|
||||
github.com/Microsoft/hcsshim v0.8.10-0.20200715222032-5eafd1556990/go.mod h1:ay/0dTb7NsG8QMDfsRfLHgZo/6xAJShLe1+ePPflihk=
|
||||
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
|
|
@ -314,10 +316,10 @@ github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.
|
|||
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.3.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.4.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY=
|
||||
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
|
||||
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.0.0-20201217071531-2b97b583765b/go.mod h1:E9uVkkBKf0EaC39j2JVW9EzdNhYvpz6eQIjILHebruk=
|
||||
|
|
@ -366,6 +368,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
|
||||
github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC4G4As=
|
||||
github.com/deislabs/oras v0.11.1/go.mod h1:39lCtf8Q6WDC7ul9cnyWXONNzKvabEKk+AX+L0ImnQk=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
||||
|
|
@ -383,6 +386,7 @@ github.com/djherbis/atime v1.0.0/go.mod h1:5W+KBIuTwVGcqjIfaTwt+KSYX1o6uep8dteve
|
|||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v20.10.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
|
|
@ -390,6 +394,7 @@ github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r
|
|||
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v1.4.2-0.20191219165747-a9416c67da9f/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.6+incompatible h1:oXI3Vas8TI8Eu/EjH4srKHJBVqraSzJybhxY7Om9faQ=
|
||||
github.com/docker/docker v20.10.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
|
|
@ -882,8 +887,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
|
|||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
|
||||
github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
|
|
@ -954,7 +959,7 @@ github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6Fm
|
|||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
|
|
@ -1006,8 +1011,10 @@ github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
|
|||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-shellwords v1.0.9/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
|
||||
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
|
||||
|
|
@ -1028,6 +1035,7 @@ github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfv
|
|||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/copystructure v1.1.1/go.mod h1:EBArHfARyrSWO/+Wyr9zwEkc6XMFB9XyNgFNmRkZZU4=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
|
|
@ -1046,6 +1054,7 @@ github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxd
|
|||
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/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mmarkdown/mmark v2.0.40+incompatible/go.mod h1:Uvmoz7tvsWpr7bMVxIpqZPyN3FbOtzDmnsJDFp7ltJs=
|
||||
github.com/moby/ipvs v1.0.1/go.mod h1:2pngiyseZbIKXNv7hsKj3O9UEz30c53MT9005gt2hxQ=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
|
|
@ -1308,8 +1317,9 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
|||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
|
||||
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
|
||||
|
|
@ -2149,7 +2159,7 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81
|
|||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
helm.sh/helm/v3 v3.1.1/go.mod h1:WYsFJuMASa/4XUqLyv54s0U/f3mlAaRErGmyy4z921g=
|
||||
helm.sh/helm/v3 v3.5.1/go.mod h1:bjwXfmGAF+SEuJZ2AtN1xmTuz4FqaNYOJrXP+vtj6Tw=
|
||||
helm.sh/helm/v3 v3.6.1/go.mod h1:mIIus8EOqj+obtycw3sidsR4ORr2aFDmXMSI3k+oeVY=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ module github.com/Microsoft/go-winio
|
|||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/sirupsen/logrus v1.4.1
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
|
||||
|
|
@ -12,7 +12,5 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
|
|||
|
|
@ -429,10 +429,10 @@ type PipeConfig struct {
|
|||
// when the pipe is in message mode.
|
||||
MessageMode bool
|
||||
|
||||
// InputBufferSize specifies the size the input buffer, in bytes.
|
||||
// InputBufferSize specifies the size of the input buffer, in bytes.
|
||||
InputBufferSize int32
|
||||
|
||||
// OutputBufferSize specifies the size the input buffer, in bytes.
|
||||
// OutputBufferSize specifies the size of the output buffer, in bytes.
|
||||
OutputBufferSize int32
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"grantvmgroupaccess.go",
|
||||
"syscall_windows.go",
|
||||
"zsyscall_windows.go",
|
||||
],
|
||||
importmap = "k8s.io/kops/vendor/github.com/Microsoft/go-winio/pkg/security",
|
||||
importpath = "github.com/Microsoft/go-winio/pkg/security",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
] + select({
|
||||
"@io_bazel_rules_go//go/platform:windows": [
|
||||
"//vendor/golang.org/x/sys/windows:go_default_library",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
)
|
||||
159
vendor/github.com/Microsoft/go-winio/pkg/security/grantvmgroupaccess.go
generated
vendored
Normal file
159
vendor/github.com/Microsoft/go-winio/pkg/security/grantvmgroupaccess.go
generated
vendored
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
package security
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type (
|
||||
accessMask uint32
|
||||
accessMode uint32
|
||||
desiredAccess uint32
|
||||
inheritMode uint32
|
||||
objectType uint32
|
||||
shareMode uint32
|
||||
securityInformation uint32
|
||||
trusteeForm uint32
|
||||
trusteeType uint32
|
||||
|
||||
explicitAccess struct {
|
||||
accessPermissions accessMask
|
||||
accessMode accessMode
|
||||
inheritance inheritMode
|
||||
trustee trustee
|
||||
}
|
||||
|
||||
trustee struct {
|
||||
multipleTrustee *trustee
|
||||
multipleTrusteeOperation int32
|
||||
trusteeForm trusteeForm
|
||||
trusteeType trusteeType
|
||||
name uintptr
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
accessMaskDesiredPermission accessMask = 1 << 31 // GENERIC_READ
|
||||
|
||||
accessModeGrant accessMode = 1
|
||||
|
||||
desiredAccessReadControl desiredAccess = 0x20000
|
||||
desiredAccessWriteDac desiredAccess = 0x40000
|
||||
|
||||
gvmga = "GrantVmGroupAccess:"
|
||||
|
||||
inheritModeNoInheritance inheritMode = 0x0
|
||||
inheritModeSubContainersAndObjectsInherit inheritMode = 0x3
|
||||
|
||||
objectTypeFileObject objectType = 0x1
|
||||
|
||||
securityInformationDACL securityInformation = 0x4
|
||||
|
||||
shareModeRead shareMode = 0x1
|
||||
shareModeWrite shareMode = 0x2
|
||||
|
||||
sidVmGroup = "S-1-5-83-0"
|
||||
|
||||
trusteeFormIsSid trusteeForm = 0
|
||||
|
||||
trusteeTypeWellKnownGroup trusteeType = 5
|
||||
)
|
||||
|
||||
// GrantVMGroupAccess sets the DACL for a specified file or directory to
|
||||
// include Grant ACE entries for the VM Group SID. This is a golang re-
|
||||
// implementation of the same function in vmcompute, just not exported in
|
||||
// RS5. Which kind of sucks. Sucks a lot :/
|
||||
func GrantVmGroupAccess(name string) error {
|
||||
// Stat (to determine if `name` is a directory).
|
||||
s, err := os.Stat(name)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "%s os.Stat %s", gvmga, name)
|
||||
}
|
||||
|
||||
// Get a handle to the file/directory. Must defer Close on success.
|
||||
fd, err := createFile(name, s.IsDir())
|
||||
if err != nil {
|
||||
return err // Already wrapped
|
||||
}
|
||||
defer syscall.CloseHandle(fd)
|
||||
|
||||
// Get the current DACL and Security Descriptor. Must defer LocalFree on success.
|
||||
ot := objectTypeFileObject
|
||||
si := securityInformationDACL
|
||||
sd := uintptr(0)
|
||||
origDACL := uintptr(0)
|
||||
if err := getSecurityInfo(fd, uint32(ot), uint32(si), nil, nil, &origDACL, nil, &sd); err != nil {
|
||||
return errors.Wrapf(err, "%s GetSecurityInfo %s", gvmga, name)
|
||||
}
|
||||
defer syscall.LocalFree((syscall.Handle)(unsafe.Pointer(sd)))
|
||||
|
||||
// Generate a new DACL which is the current DACL with the required ACEs added.
|
||||
// Must defer LocalFree on success.
|
||||
newDACL, err := generateDACLWithAcesAdded(name, s.IsDir(), origDACL)
|
||||
if err != nil {
|
||||
return err // Already wrapped
|
||||
}
|
||||
defer syscall.LocalFree((syscall.Handle)(unsafe.Pointer(newDACL)))
|
||||
|
||||
// And finally use SetSecurityInfo to apply the updated DACL.
|
||||
if err := setSecurityInfo(fd, uint32(ot), uint32(si), uintptr(0), uintptr(0), newDACL, uintptr(0)); err != nil {
|
||||
return errors.Wrapf(err, "%s SetSecurityInfo %s", gvmga, name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createFile is a helper function to call [Nt]CreateFile to get a handle to
|
||||
// the file or directory.
|
||||
func createFile(name string, isDir bool) (syscall.Handle, error) {
|
||||
namep := syscall.StringToUTF16(name)
|
||||
da := uint32(desiredAccessReadControl | desiredAccessWriteDac)
|
||||
sm := uint32(shareModeRead | shareModeWrite)
|
||||
fa := uint32(syscall.FILE_ATTRIBUTE_NORMAL)
|
||||
if isDir {
|
||||
fa = uint32(fa | syscall.FILE_FLAG_BACKUP_SEMANTICS)
|
||||
}
|
||||
fd, err := syscall.CreateFile(&namep[0], da, sm, nil, syscall.OPEN_EXISTING, fa, 0)
|
||||
if err != nil {
|
||||
return 0, errors.Wrapf(err, "%s syscall.CreateFile %s", gvmga, name)
|
||||
}
|
||||
return fd, nil
|
||||
}
|
||||
|
||||
// generateDACLWithAcesAdded generates a new DACL with the two needed ACEs added.
|
||||
// The caller is responsible for LocalFree of the returned DACL on success.
|
||||
func generateDACLWithAcesAdded(name string, isDir bool, origDACL uintptr) (uintptr, error) {
|
||||
// Generate pointers to the SIDs based on the string SIDs
|
||||
sid, err := syscall.StringToSid(sidVmGroup)
|
||||
if err != nil {
|
||||
return 0, errors.Wrapf(err, "%s syscall.StringToSid %s %s", gvmga, name, sidVmGroup)
|
||||
}
|
||||
|
||||
inheritance := inheritModeNoInheritance
|
||||
if isDir {
|
||||
inheritance = inheritModeSubContainersAndObjectsInherit
|
||||
}
|
||||
|
||||
eaArray := []explicitAccess{
|
||||
explicitAccess{
|
||||
accessPermissions: accessMaskDesiredPermission,
|
||||
accessMode: accessModeGrant,
|
||||
inheritance: inheritance,
|
||||
trustee: trustee{
|
||||
trusteeForm: trusteeFormIsSid,
|
||||
trusteeType: trusteeTypeWellKnownGroup,
|
||||
name: uintptr(unsafe.Pointer(sid)),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
modifiedDACL := uintptr(0)
|
||||
if err := setEntriesInAcl(uintptr(uint32(1)), uintptr(unsafe.Pointer(&eaArray[0])), origDACL, &modifiedDACL); err != nil {
|
||||
return 0, errors.Wrapf(err, "%s SetEntriesInAcl %s", gvmga, name)
|
||||
}
|
||||
|
||||
return modifiedDACL, nil
|
||||
}
|
||||
7
vendor/github.com/Microsoft/go-winio/pkg/security/syscall_windows.go
generated
vendored
Normal file
7
vendor/github.com/Microsoft/go-winio/pkg/security/syscall_windows.go
generated
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package security
|
||||
|
||||
//go:generate go run mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go
|
||||
|
||||
//sys getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidOwner **uintptr, ppsidGroup **uintptr, ppDacl *uintptr, ppSacl *uintptr, ppSecurityDescriptor *uintptr) (err error) [failretval!=0] = advapi32.GetSecurityInfo
|
||||
//sys setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (err error) [failretval!=0] = advapi32.SetSecurityInfo
|
||||
//sys setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *uintptr) (err error) [failretval!=0] = advapi32.SetEntriesInAclW
|
||||
81
vendor/github.com/Microsoft/go-winio/pkg/security/zsyscall_windows.go
generated
vendored
Normal file
81
vendor/github.com/Microsoft/go-winio/pkg/security/zsyscall_windows.go
generated
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
// Code generated mksyscall_windows.exe DO NOT EDIT
|
||||
|
||||
package security
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
// Do the interface allocations only once for common
|
||||
// Errno values.
|
||||
const (
|
||||
errnoERROR_IO_PENDING = 997
|
||||
)
|
||||
|
||||
var (
|
||||
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
|
||||
)
|
||||
|
||||
// errnoErr returns common boxed Errno values, to prevent
|
||||
// allocations at runtime.
|
||||
func errnoErr(e syscall.Errno) error {
|
||||
switch e {
|
||||
case 0:
|
||||
return nil
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
var (
|
||||
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||
|
||||
procGetSecurityInfo = modadvapi32.NewProc("GetSecurityInfo")
|
||||
procSetSecurityInfo = modadvapi32.NewProc("SetSecurityInfo")
|
||||
procSetEntriesInAclW = modadvapi32.NewProc("SetEntriesInAclW")
|
||||
)
|
||||
|
||||
func getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidOwner **uintptr, ppsidGroup **uintptr, ppDacl *uintptr, ppSacl *uintptr, ppSecurityDescriptor *uintptr) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(unsafe.Pointer(ppsidOwner)), uintptr(unsafe.Pointer(ppsidGroup)), uintptr(unsafe.Pointer(ppDacl)), uintptr(unsafe.Pointer(ppSacl)), uintptr(unsafe.Pointer(ppSecurityDescriptor)), 0)
|
||||
if r1 != 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procSetSecurityInfo.Addr(), 7, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(psidOwner), uintptr(psidGroup), uintptr(pDacl), uintptr(pSacl), 0, 0)
|
||||
if r1 != 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *uintptr) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procSetEntriesInAclW.Addr(), 4, uintptr(count), uintptr(pListOfEEs), uintptr(oldAcl), uintptr(unsafe.Pointer(newAcl)), 0, 0)
|
||||
if r1 != 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
@ -9,5 +9,13 @@ go_library(
|
|||
importmap = "k8s.io/kops/vendor/github.com/Microsoft/go-winio/vhd",
|
||||
importpath = "github.com/Microsoft/go-winio/vhd",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//vendor/golang.org/x/sys/windows:go_default_library"],
|
||||
deps = [
|
||||
"//vendor/golang.org/x/sys/windows:go_default_library",
|
||||
] + select({
|
||||
"@io_bazel_rules_go//go/platform:windows": [
|
||||
"//vendor/github.com/Microsoft/go-winio/pkg/guid:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,150 +2,323 @@
|
|||
|
||||
package vhd
|
||||
|
||||
import "syscall"
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
|
||||
"github.com/Microsoft/go-winio/pkg/guid"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
//go:generate go run mksyscall_windows.go -output zvhd.go vhd.go
|
||||
|
||||
//sys createVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) [failretval != 0] = VirtDisk.CreateVirtualDisk
|
||||
//sys openVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) [failretval != 0] = VirtDisk.OpenVirtualDisk
|
||||
//sys detachVirtualDisk(handle syscall.Handle, flags uint32, providerSpecificFlags uint32) (err error) [failretval != 0] = VirtDisk.DetachVirtualDisk
|
||||
|
||||
type virtualStorageType struct {
|
||||
DeviceID uint32
|
||||
VendorID [16]byte
|
||||
}
|
||||
//sys createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (err error) [failretval != 0] = virtdisk.CreateVirtualDisk
|
||||
//sys openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (err error) [failretval != 0] = virtdisk.OpenVirtualDisk
|
||||
//sys attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (err error) [failretval != 0] = virtdisk.AttachVirtualDisk
|
||||
//sys detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (err error) [failretval != 0] = virtdisk.DetachVirtualDisk
|
||||
//sys getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (err error) [failretval != 0] = virtdisk.GetVirtualDiskPhysicalPath
|
||||
|
||||
type (
|
||||
createVirtualDiskFlag uint32
|
||||
VirtualDiskAccessMask uint32
|
||||
CreateVirtualDiskFlag uint32
|
||||
VirtualDiskFlag uint32
|
||||
AttachVirtualDiskFlag uint32
|
||||
DetachVirtualDiskFlag uint32
|
||||
VirtualDiskAccessMask uint32
|
||||
)
|
||||
|
||||
const (
|
||||
// Flags for creating a VHD (not exported)
|
||||
createVirtualDiskFlagNone createVirtualDiskFlag = 0
|
||||
createVirtualDiskFlagFullPhysicalAllocation createVirtualDiskFlag = 1
|
||||
createVirtualDiskFlagPreventWritesToSourceDisk createVirtualDiskFlag = 2
|
||||
createVirtualDiskFlagDoNotCopyMetadataFromParent createVirtualDiskFlag = 4
|
||||
type VirtualStorageType struct {
|
||||
DeviceID uint32
|
||||
VendorID guid.GUID
|
||||
}
|
||||
|
||||
// Access Mask for opening a VHD
|
||||
VirtualDiskAccessNone VirtualDiskAccessMask = 0
|
||||
VirtualDiskAccessAttachRO VirtualDiskAccessMask = 65536
|
||||
VirtualDiskAccessAttachRW VirtualDiskAccessMask = 131072
|
||||
VirtualDiskAccessDetach VirtualDiskAccessMask = 262144
|
||||
VirtualDiskAccessGetInfo VirtualDiskAccessMask = 524288
|
||||
VirtualDiskAccessCreate VirtualDiskAccessMask = 1048576
|
||||
VirtualDiskAccessMetaOps VirtualDiskAccessMask = 2097152
|
||||
VirtualDiskAccessRead VirtualDiskAccessMask = 851968
|
||||
VirtualDiskAccessAll VirtualDiskAccessMask = 4128768
|
||||
VirtualDiskAccessWritable VirtualDiskAccessMask = 3276800
|
||||
|
||||
// Flags for opening a VHD
|
||||
OpenVirtualDiskFlagNone VirtualDiskFlag = 0
|
||||
OpenVirtualDiskFlagNoParents VirtualDiskFlag = 0x1
|
||||
OpenVirtualDiskFlagBlankFile VirtualDiskFlag = 0x2
|
||||
OpenVirtualDiskFlagBootDrive VirtualDiskFlag = 0x4
|
||||
OpenVirtualDiskFlagCachedIO VirtualDiskFlag = 0x8
|
||||
OpenVirtualDiskFlagCustomDiffChain VirtualDiskFlag = 0x10
|
||||
OpenVirtualDiskFlagParentCachedIO VirtualDiskFlag = 0x20
|
||||
OpenVirtualDiskFlagVhdSetFileOnly VirtualDiskFlag = 0x40
|
||||
OpenVirtualDiskFlagIgnoreRelativeParentLocator VirtualDiskFlag = 0x80
|
||||
OpenVirtualDiskFlagNoWriteHardening VirtualDiskFlag = 0x100
|
||||
)
|
||||
|
||||
type createVersion2 struct {
|
||||
UniqueID [16]byte // GUID
|
||||
type CreateVersion2 struct {
|
||||
UniqueID guid.GUID
|
||||
MaximumSize uint64
|
||||
BlockSizeInBytes uint32
|
||||
SectorSizeInBytes uint32
|
||||
PhysicalSectorSizeInByte uint32
|
||||
ParentPath *uint16 // string
|
||||
SourcePath *uint16 // string
|
||||
OpenFlags uint32
|
||||
ParentVirtualStorageType virtualStorageType
|
||||
SourceVirtualStorageType virtualStorageType
|
||||
ResiliencyGUID [16]byte // GUID
|
||||
ParentVirtualStorageType VirtualStorageType
|
||||
SourceVirtualStorageType VirtualStorageType
|
||||
ResiliencyGUID guid.GUID
|
||||
}
|
||||
|
||||
type createVirtualDiskParameters struct {
|
||||
type CreateVirtualDiskParameters struct {
|
||||
Version uint32 // Must always be set to 2
|
||||
Version2 createVersion2
|
||||
Version2 CreateVersion2
|
||||
}
|
||||
|
||||
type openVersion2 struct {
|
||||
GetInfoOnly int32 // bool but 4-byte aligned
|
||||
ReadOnly int32 // bool but 4-byte aligned
|
||||
ResiliencyGUID [16]byte // GUID
|
||||
type OpenVersion2 struct {
|
||||
GetInfoOnly bool
|
||||
ReadOnly bool
|
||||
ResiliencyGUID guid.GUID
|
||||
}
|
||||
|
||||
type openVirtualDiskParameters struct {
|
||||
type OpenVirtualDiskParameters struct {
|
||||
Version uint32 // Must always be set to 2
|
||||
Version2 openVersion2
|
||||
Version2 OpenVersion2
|
||||
}
|
||||
|
||||
// CreateVhdx will create a simple vhdx file at the given path using default values.
|
||||
type AttachVersion2 struct {
|
||||
RestrictedOffset uint64
|
||||
RestrictedLength uint64
|
||||
}
|
||||
|
||||
type AttachVirtualDiskParameters struct {
|
||||
Version uint32 // Must always be set to 2
|
||||
Version2 AttachVersion2
|
||||
}
|
||||
|
||||
const (
|
||||
VIRTUAL_STORAGE_TYPE_DEVICE_VHDX = 0x3
|
||||
|
||||
// Access Mask for opening a VHD
|
||||
VirtualDiskAccessNone VirtualDiskAccessMask = 0x00000000
|
||||
VirtualDiskAccessAttachRO VirtualDiskAccessMask = 0x00010000
|
||||
VirtualDiskAccessAttachRW VirtualDiskAccessMask = 0x00020000
|
||||
VirtualDiskAccessDetach VirtualDiskAccessMask = 0x00040000
|
||||
VirtualDiskAccessGetInfo VirtualDiskAccessMask = 0x00080000
|
||||
VirtualDiskAccessCreate VirtualDiskAccessMask = 0x00100000
|
||||
VirtualDiskAccessMetaOps VirtualDiskAccessMask = 0x00200000
|
||||
VirtualDiskAccessRead VirtualDiskAccessMask = 0x000d0000
|
||||
VirtualDiskAccessAll VirtualDiskAccessMask = 0x003f0000
|
||||
VirtualDiskAccessWritable VirtualDiskAccessMask = 0x00320000
|
||||
|
||||
// Flags for creating a VHD
|
||||
CreateVirtualDiskFlagNone CreateVirtualDiskFlag = 0x0
|
||||
CreateVirtualDiskFlagFullPhysicalAllocation CreateVirtualDiskFlag = 0x1
|
||||
CreateVirtualDiskFlagPreventWritesToSourceDisk CreateVirtualDiskFlag = 0x2
|
||||
CreateVirtualDiskFlagDoNotCopyMetadataFromParent CreateVirtualDiskFlag = 0x4
|
||||
CreateVirtualDiskFlagCreateBackingStorage CreateVirtualDiskFlag = 0x8
|
||||
CreateVirtualDiskFlagUseChangeTrackingSourceLimit CreateVirtualDiskFlag = 0x10
|
||||
CreateVirtualDiskFlagPreserveParentChangeTrackingState CreateVirtualDiskFlag = 0x20
|
||||
CreateVirtualDiskFlagVhdSetUseOriginalBackingStorage CreateVirtualDiskFlag = 0x40
|
||||
CreateVirtualDiskFlagSparseFile CreateVirtualDiskFlag = 0x80
|
||||
CreateVirtualDiskFlagPmemCompatible CreateVirtualDiskFlag = 0x100
|
||||
CreateVirtualDiskFlagSupportCompressedVolumes CreateVirtualDiskFlag = 0x200
|
||||
|
||||
// Flags for opening a VHD
|
||||
OpenVirtualDiskFlagNone VirtualDiskFlag = 0x00000000
|
||||
OpenVirtualDiskFlagNoParents VirtualDiskFlag = 0x00000001
|
||||
OpenVirtualDiskFlagBlankFile VirtualDiskFlag = 0x00000002
|
||||
OpenVirtualDiskFlagBootDrive VirtualDiskFlag = 0x00000004
|
||||
OpenVirtualDiskFlagCachedIO VirtualDiskFlag = 0x00000008
|
||||
OpenVirtualDiskFlagCustomDiffChain VirtualDiskFlag = 0x00000010
|
||||
OpenVirtualDiskFlagParentCachedIO VirtualDiskFlag = 0x00000020
|
||||
OpenVirtualDiskFlagVhdsetFileOnly VirtualDiskFlag = 0x00000040
|
||||
OpenVirtualDiskFlagIgnoreRelativeParentLocator VirtualDiskFlag = 0x00000080
|
||||
OpenVirtualDiskFlagNoWriteHardening VirtualDiskFlag = 0x00000100
|
||||
OpenVirtualDiskFlagSupportCompressedVolumes VirtualDiskFlag = 0x00000200
|
||||
|
||||
// Flags for attaching a VHD
|
||||
AttachVirtualDiskFlagNone AttachVirtualDiskFlag = 0x00000000
|
||||
AttachVirtualDiskFlagReadOnly AttachVirtualDiskFlag = 0x00000001
|
||||
AttachVirtualDiskFlagNoDriveLetter AttachVirtualDiskFlag = 0x00000002
|
||||
AttachVirtualDiskFlagPermanentLifetime AttachVirtualDiskFlag = 0x00000004
|
||||
AttachVirtualDiskFlagNoLocalHost AttachVirtualDiskFlag = 0x00000008
|
||||
AttachVirtualDiskFlagNoSecurityDescriptor AttachVirtualDiskFlag = 0x00000010
|
||||
AttachVirtualDiskFlagBypassDefaultEncryptionPolicy AttachVirtualDiskFlag = 0x00000020
|
||||
AttachVirtualDiskFlagNonPnp AttachVirtualDiskFlag = 0x00000040
|
||||
AttachVirtualDiskFlagRestrictedRange AttachVirtualDiskFlag = 0x00000080
|
||||
AttachVirtualDiskFlagSinglePartition AttachVirtualDiskFlag = 0x00000100
|
||||
AttachVirtualDiskFlagRegisterVolume AttachVirtualDiskFlag = 0x00000200
|
||||
|
||||
// Flags for detaching a VHD
|
||||
DetachVirtualDiskFlagNone DetachVirtualDiskFlag = 0x0
|
||||
)
|
||||
|
||||
// CreateVhdx is a helper function to create a simple vhdx file at the given path using
|
||||
// default values.
|
||||
func CreateVhdx(path string, maxSizeInGb, blockSizeInMb uint32) error {
|
||||
var (
|
||||
defaultType virtualStorageType
|
||||
handle syscall.Handle
|
||||
)
|
||||
|
||||
parameters := createVirtualDiskParameters{
|
||||
params := CreateVirtualDiskParameters{
|
||||
Version: 2,
|
||||
Version2: createVersion2{
|
||||
Version2: CreateVersion2{
|
||||
MaximumSize: uint64(maxSizeInGb) * 1024 * 1024 * 1024,
|
||||
BlockSizeInBytes: blockSizeInMb * 1024 * 1024,
|
||||
},
|
||||
}
|
||||
|
||||
if err := createVirtualDisk(
|
||||
&defaultType,
|
||||
path,
|
||||
uint32(VirtualDiskAccessNone),
|
||||
nil,
|
||||
uint32(createVirtualDiskFlagNone),
|
||||
0,
|
||||
¶meters,
|
||||
nil,
|
||||
&handle); err != nil {
|
||||
handle, err := CreateVirtualDisk(path, VirtualDiskAccessNone, CreateVirtualDiskFlagNone, ¶ms)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := syscall.CloseHandle(handle); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DetachVhd detaches a mounted container layer vhd found at `path`.
|
||||
// DetachVirtualDisk detaches a virtual hard disk by handle.
|
||||
func DetachVirtualDisk(handle syscall.Handle) (err error) {
|
||||
if err := detachVirtualDisk(handle, 0, 0); err != nil {
|
||||
return errors.Wrap(err, "failed to detach virtual disk")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DetachVhd detaches a vhd found at `path`.
|
||||
func DetachVhd(path string) error {
|
||||
handle, err := OpenVirtualDisk(
|
||||
path,
|
||||
VirtualDiskAccessNone,
|
||||
OpenVirtualDiskFlagCachedIO|OpenVirtualDiskFlagIgnoreRelativeParentLocator)
|
||||
|
||||
OpenVirtualDiskFlagCachedIO|OpenVirtualDiskFlagIgnoreRelativeParentLocator,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer syscall.CloseHandle(handle)
|
||||
return detachVirtualDisk(handle, 0, 0)
|
||||
return DetachVirtualDisk(handle)
|
||||
}
|
||||
|
||||
// AttachVirtualDisk attaches a virtual hard disk for use.
|
||||
func AttachVirtualDisk(handle syscall.Handle, attachVirtualDiskFlag AttachVirtualDiskFlag, parameters *AttachVirtualDiskParameters) (err error) {
|
||||
if parameters.Version != 2 {
|
||||
return fmt.Errorf("only version 2 VHDs are supported, found version: %d", parameters.Version)
|
||||
}
|
||||
if err := attachVirtualDisk(
|
||||
handle,
|
||||
nil,
|
||||
uint32(attachVirtualDiskFlag),
|
||||
0,
|
||||
parameters,
|
||||
nil,
|
||||
); err != nil {
|
||||
return errors.Wrap(err, "failed to attach virtual disk")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AttachVhd attaches a virtual hard disk at `path` for use.
|
||||
func AttachVhd(path string) (err error) {
|
||||
handle, err := OpenVirtualDisk(
|
||||
path,
|
||||
VirtualDiskAccessNone,
|
||||
OpenVirtualDiskFlagCachedIO|OpenVirtualDiskFlagIgnoreRelativeParentLocator,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer syscall.CloseHandle(handle)
|
||||
params := AttachVirtualDiskParameters{Version: 2}
|
||||
if err := AttachVirtualDisk(
|
||||
handle,
|
||||
AttachVirtualDiskFlagNone,
|
||||
¶ms,
|
||||
); err != nil {
|
||||
return errors.Wrap(err, "failed to attach virtual disk")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// OpenVirtualDisk obtains a handle to a VHD opened with supplied access mask and flags.
|
||||
func OpenVirtualDisk(path string, accessMask VirtualDiskAccessMask, flag VirtualDiskFlag) (syscall.Handle, error) {
|
||||
var (
|
||||
defaultType virtualStorageType
|
||||
handle syscall.Handle
|
||||
)
|
||||
parameters := openVirtualDiskParameters{Version: 2}
|
||||
if err := openVirtualDisk(
|
||||
&defaultType,
|
||||
path,
|
||||
uint32(accessMask),
|
||||
uint32(flag),
|
||||
func OpenVirtualDisk(vhdPath string, virtualDiskAccessMask VirtualDiskAccessMask, openVirtualDiskFlags VirtualDiskFlag) (syscall.Handle, error) {
|
||||
parameters := OpenVirtualDiskParameters{Version: 2}
|
||||
handle, err := OpenVirtualDiskWithParameters(
|
||||
vhdPath,
|
||||
virtualDiskAccessMask,
|
||||
openVirtualDiskFlags,
|
||||
¶meters,
|
||||
&handle); err != nil {
|
||||
)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return handle, nil
|
||||
}
|
||||
|
||||
// OpenVirtualDiskWithParameters obtains a handle to a VHD opened with supplied access mask, flags and parameters.
|
||||
func OpenVirtualDiskWithParameters(vhdPath string, virtualDiskAccessMask VirtualDiskAccessMask, openVirtualDiskFlags VirtualDiskFlag, parameters *OpenVirtualDiskParameters) (syscall.Handle, error) {
|
||||
var (
|
||||
handle syscall.Handle
|
||||
defaultType VirtualStorageType
|
||||
)
|
||||
if parameters.Version != 2 {
|
||||
return handle, fmt.Errorf("only version 2 VHDs are supported, found version: %d", parameters.Version)
|
||||
}
|
||||
if err := openVirtualDisk(
|
||||
&defaultType,
|
||||
vhdPath,
|
||||
uint32(virtualDiskAccessMask),
|
||||
uint32(openVirtualDiskFlags),
|
||||
parameters,
|
||||
&handle,
|
||||
); err != nil {
|
||||
return 0, errors.Wrap(err, "failed to open virtual disk")
|
||||
}
|
||||
return handle, nil
|
||||
}
|
||||
|
||||
// CreateVirtualDisk creates a virtual harddisk and returns a handle to the disk.
|
||||
func CreateVirtualDisk(path string, virtualDiskAccessMask VirtualDiskAccessMask, createVirtualDiskFlags CreateVirtualDiskFlag, parameters *CreateVirtualDiskParameters) (syscall.Handle, error) {
|
||||
var (
|
||||
handle syscall.Handle
|
||||
defaultType VirtualStorageType
|
||||
)
|
||||
if parameters.Version != 2 {
|
||||
return handle, fmt.Errorf("only version 2 VHDs are supported, found version: %d", parameters.Version)
|
||||
}
|
||||
|
||||
if err := createVirtualDisk(
|
||||
&defaultType,
|
||||
path,
|
||||
uint32(virtualDiskAccessMask),
|
||||
nil,
|
||||
uint32(createVirtualDiskFlags),
|
||||
0,
|
||||
parameters,
|
||||
nil,
|
||||
&handle,
|
||||
); err != nil {
|
||||
return handle, errors.Wrap(err, "failed to create virtual disk")
|
||||
}
|
||||
return handle, nil
|
||||
}
|
||||
|
||||
// GetVirtualDiskPhysicalPath takes a handle to a virtual hard disk and returns the physical
|
||||
// path of the disk on the machine. This path is in the form \\.\PhysicalDriveX where X is an integer
|
||||
// that represents the particular enumeration of the physical disk on the caller's system.
|
||||
func GetVirtualDiskPhysicalPath(handle syscall.Handle) (_ string, err error) {
|
||||
var (
|
||||
diskPathSizeInBytes uint32 = 256 * 2 // max path length 256 wide chars
|
||||
diskPhysicalPathBuf [256]uint16
|
||||
)
|
||||
if err := getVirtualDiskPhysicalPath(
|
||||
handle,
|
||||
&diskPathSizeInBytes,
|
||||
&diskPhysicalPathBuf[0],
|
||||
); err != nil {
|
||||
return "", errors.Wrap(err, "failed to get disk physical path")
|
||||
}
|
||||
return windows.UTF16ToString(diskPhysicalPathBuf[:]), nil
|
||||
}
|
||||
|
||||
// CreateDiffVhd is a helper function to create a differencing virtual disk.
|
||||
func CreateDiffVhd(diffVhdPath, baseVhdPath string, blockSizeInMB uint32) error {
|
||||
// Setting `ParentPath` is how to signal to create a differencing disk.
|
||||
createParams := &CreateVirtualDiskParameters{
|
||||
Version: 2,
|
||||
Version2: CreateVersion2{
|
||||
ParentPath: windows.StringToUTF16Ptr(baseVhdPath),
|
||||
BlockSizeInBytes: blockSizeInMB * 1024 * 1024,
|
||||
OpenFlags: uint32(OpenVirtualDiskFlagCachedIO),
|
||||
},
|
||||
}
|
||||
|
||||
vhdHandle, err := CreateVirtualDisk(
|
||||
diffVhdPath,
|
||||
VirtualDiskAccessNone,
|
||||
CreateVirtualDiskFlagNone,
|
||||
createParams,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create differencing vhd: %s", err)
|
||||
}
|
||||
if err := syscall.CloseHandle(vhdHandle); err != nil {
|
||||
return fmt.Errorf("failed to close differencing vhd handle: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,24 +37,26 @@ func errnoErr(e syscall.Errno) error {
|
|||
}
|
||||
|
||||
var (
|
||||
modVirtDisk = windows.NewLazySystemDLL("VirtDisk.dll")
|
||||
modvirtdisk = windows.NewLazySystemDLL("virtdisk.dll")
|
||||
|
||||
procCreateVirtualDisk = modVirtDisk.NewProc("CreateVirtualDisk")
|
||||
procOpenVirtualDisk = modVirtDisk.NewProc("OpenVirtualDisk")
|
||||
procDetachVirtualDisk = modVirtDisk.NewProc("DetachVirtualDisk")
|
||||
procCreateVirtualDisk = modvirtdisk.NewProc("CreateVirtualDisk")
|
||||
procOpenVirtualDisk = modvirtdisk.NewProc("OpenVirtualDisk")
|
||||
procAttachVirtualDisk = modvirtdisk.NewProc("AttachVirtualDisk")
|
||||
procDetachVirtualDisk = modvirtdisk.NewProc("DetachVirtualDisk")
|
||||
procGetVirtualDiskPhysicalPath = modvirtdisk.NewProc("GetVirtualDiskPhysicalPath")
|
||||
)
|
||||
|
||||
func createVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) {
|
||||
func createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _createVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, securityDescriptor, flags, providerSpecificFlags, parameters, o, handle)
|
||||
return _createVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, securityDescriptor, createVirtualDiskFlags, providerSpecificFlags, parameters, overlapped, handle)
|
||||
}
|
||||
|
||||
func _createVirtualDisk(virtualStorageType *virtualStorageType, path *uint16, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procCreateVirtualDisk.Addr(), 9, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(flags), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(handle)))
|
||||
func _createVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procCreateVirtualDisk.Addr(), 9, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(createVirtualDiskFlags), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(handle)))
|
||||
if r1 != 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
|
|
@ -65,17 +67,17 @@ func _createVirtualDisk(virtualStorageType *virtualStorageType, path *uint16, vi
|
|||
return
|
||||
}
|
||||
|
||||
func openVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) {
|
||||
func openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _openVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, flags, parameters, handle)
|
||||
return _openVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, openVirtualDiskFlags, parameters, handle)
|
||||
}
|
||||
|
||||
func _openVirtualDisk(virtualStorageType *virtualStorageType, path *uint16, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procOpenVirtualDisk.Addr(), 6, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(flags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(handle)))
|
||||
func _openVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procOpenVirtualDisk.Addr(), 6, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(openVirtualDiskFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(handle)))
|
||||
if r1 != 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
|
|
@ -86,8 +88,32 @@ func _openVirtualDisk(virtualStorageType *virtualStorageType, path *uint16, virt
|
|||
return
|
||||
}
|
||||
|
||||
func detachVirtualDisk(handle syscall.Handle, flags uint32, providerSpecificFlags uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procDetachVirtualDisk.Addr(), 3, uintptr(handle), uintptr(flags), uintptr(providerSpecificFlags))
|
||||
func attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procAttachVirtualDisk.Addr(), 6, uintptr(handle), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(attachVirtualDiskFlag), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped)))
|
||||
if r1 != 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procDetachVirtualDisk.Addr(), 3, uintptr(handle), uintptr(detachVirtualDiskFlags), uintptr(providerSpecificFlags))
|
||||
if r1 != 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procGetVirtualDiskPhysicalPath.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(diskPathSizeInBytes)), uintptr(unsafe.Pointer(buffer)))
|
||||
if r1 != 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
* text=auto eol=lf
|
||||
|
|
@ -18,6 +18,7 @@ build_script:
|
|||
- go build ./cmd/runhcs
|
||||
- go build ./cmd/tar2ext4
|
||||
- go build ./cmd/wclayer
|
||||
- go build ./cmd/device-util
|
||||
- go build ./internal/tools/grantvmgroupaccess
|
||||
- go build ./internal/tools/uvmboot
|
||||
- go build ./internal/tools/zapdir
|
||||
|
|
@ -33,6 +34,7 @@ artifacts:
|
|||
- path: 'containerd-shim-runhcs-v1.exe'
|
||||
- path: 'runhcs.exe'
|
||||
- path: 'tar2ext4.exe'
|
||||
- path: 'device-util.exe'
|
||||
- path: 'wclayer.exe'
|
||||
- path: 'grantvmgroupaccess.exe'
|
||||
- path: 'uvmboot.exe'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"attach.go",
|
||||
"destroy.go",
|
||||
"detach.go",
|
||||
"export.go",
|
||||
"format.go",
|
||||
"helpers.go",
|
||||
"import.go",
|
||||
"initialize.go",
|
||||
"mount.go",
|
||||
"setup.go",
|
||||
"storage.go",
|
||||
"zsyscall_windows.go",
|
||||
],
|
||||
importmap = "k8s.io/kops/vendor/github.com/Microsoft/hcsshim/computestorage",
|
||||
importpath = "github.com/Microsoft/hcsshim/computestorage",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/Microsoft/go-winio/pkg/security:go_default_library",
|
||||
"//vendor/github.com/Microsoft/go-winio/vhd:go_default_library",
|
||||
"//vendor/github.com/Microsoft/hcsshim/internal/interop:go_default_library",
|
||||
"//vendor/github.com/Microsoft/hcsshim/internal/oc:go_default_library",
|
||||
"//vendor/github.com/Microsoft/hcsshim/internal/schema2:go_default_library",
|
||||
"//vendor/github.com/Microsoft/hcsshim/osversion:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/go.opencensus.io/trace:go_default_library",
|
||||
"//vendor/golang.org/x/sys/windows:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package computestorage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/oc"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// AttachLayerStorageFilter sets up the layer storage filter on a writable
|
||||
// container layer.
|
||||
//
|
||||
// `layerPath` is a path to a directory the writable layer is mounted. If the
|
||||
// path does not end in a `\` the platform will append it automatically.
|
||||
//
|
||||
// `layerData` is the parent read-only layer data.
|
||||
func AttachLayerStorageFilter(ctx context.Context, layerPath string, layerData LayerData) (err error) {
|
||||
title := "hcsshim.AttachLayerStorageFilter"
|
||||
ctx, span := trace.StartSpan(ctx, title)
|
||||
defer span.End()
|
||||
defer func() { oc.SetSpanStatus(span, err) }()
|
||||
span.AddAttributes(
|
||||
trace.StringAttribute("layerPath", layerPath),
|
||||
)
|
||||
|
||||
bytes, err := json.Marshal(layerData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = hcsAttachLayerStorageFilter(layerPath, string(bytes))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to attach layer storage filter: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package computestorage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/oc"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// DestroyLayer deletes a container layer.
|
||||
//
|
||||
// `layerPath` is a path to a directory containing the layer to export.
|
||||
func DestroyLayer(ctx context.Context, layerPath string) (err error) {
|
||||
title := "hcsshim.DestroyLayer"
|
||||
ctx, span := trace.StartSpan(ctx, title)
|
||||
defer span.End()
|
||||
defer func() { oc.SetSpanStatus(span, err) }()
|
||||
span.AddAttributes(trace.StringAttribute("layerPath", layerPath))
|
||||
|
||||
err = hcsDestroyLayer(layerPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to destroy layer: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package computestorage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/oc"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// DetachLayerStorageFilter detaches the layer storage filter on a writable container layer.
|
||||
//
|
||||
// `layerPath` is a path to a directory containing the layer to export.
|
||||
func DetachLayerStorageFilter(ctx context.Context, layerPath string) (err error) {
|
||||
title := "hcsshim.DetachLayerStorageFilter"
|
||||
ctx, span := trace.StartSpan(ctx, title)
|
||||
defer span.End()
|
||||
defer func() { oc.SetSpanStatus(span, err) }()
|
||||
span.AddAttributes(trace.StringAttribute("layerPath", layerPath))
|
||||
|
||||
err = hcsDetachLayerStorageFilter(layerPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to detach layer storage filter: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package computestorage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/oc"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// ExportLayer exports a container layer.
|
||||
//
|
||||
// `layerPath` is a path to a directory containing the layer to export.
|
||||
//
|
||||
// `exportFolderPath` is a pre-existing folder to export the layer to.
|
||||
//
|
||||
// `layerData` is the parent layer data.
|
||||
//
|
||||
// `options` are the export options applied to the exported layer.
|
||||
func ExportLayer(ctx context.Context, layerPath, exportFolderPath string, layerData LayerData, options ExportLayerOptions) (err error) {
|
||||
title := "hcsshim.ExportLayer"
|
||||
ctx, span := trace.StartSpan(ctx, title)
|
||||
defer span.End()
|
||||
defer func() { oc.SetSpanStatus(span, err) }()
|
||||
span.AddAttributes(
|
||||
trace.StringAttribute("layerPath", layerPath),
|
||||
trace.StringAttribute("exportFolderPath", exportFolderPath),
|
||||
)
|
||||
|
||||
ldbytes, err := json.Marshal(layerData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
obytes, err := json.Marshal(options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = hcsExportLayer(layerPath, exportFolderPath, string(ldbytes), string(obytes))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to export layer: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package computestorage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/oc"
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// FormatWritableLayerVhd formats a virtual disk for use as a writable container layer.
|
||||
//
|
||||
// If the VHD is not mounted it will be temporarily mounted.
|
||||
func FormatWritableLayerVhd(ctx context.Context, vhdHandle windows.Handle) (err error) {
|
||||
title := "hcsshim.FormatWritableLayerVhd"
|
||||
ctx, span := trace.StartSpan(ctx, title)
|
||||
defer span.End()
|
||||
defer func() { oc.SetSpanStatus(span, err) }()
|
||||
|
||||
err = hcsFormatWritableLayerVhd(vhdHandle)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to format writable layer vhd: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
package computestorage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
"github.com/Microsoft/go-winio/pkg/security"
|
||||
"github.com/Microsoft/go-winio/vhd"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const defaultVHDXBlockSizeInMB = 1
|
||||
|
||||
// SetupContainerBaseLayer is a helper to setup a containers scratch. It
|
||||
// will create and format the vhdx's inside and the size is configurable with the sizeInGB
|
||||
// parameter.
|
||||
//
|
||||
// `layerPath` is the path to the base container layer on disk.
|
||||
//
|
||||
// `baseVhdPath` is the path to where the base vhdx for the base layer should be created.
|
||||
//
|
||||
// `diffVhdPath` is the path where the differencing disk for the base layer should be created.
|
||||
//
|
||||
// `sizeInGB` is the size in gigabytes to make the base vhdx.
|
||||
func SetupContainerBaseLayer(ctx context.Context, layerPath, baseVhdPath, diffVhdPath string, sizeInGB uint64) (err error) {
|
||||
var (
|
||||
hivesPath = filepath.Join(layerPath, "Hives")
|
||||
layoutPath = filepath.Join(layerPath, "Layout")
|
||||
)
|
||||
|
||||
// We need to remove the hives directory and layout file as `SetupBaseOSLayer` fails if these files
|
||||
// already exist. `SetupBaseOSLayer` will create these files internally. We also remove the base and
|
||||
// differencing disks if they exist in case we're asking for a different size.
|
||||
if _, err := os.Stat(hivesPath); err == nil {
|
||||
if err := os.RemoveAll(hivesPath); err != nil {
|
||||
return errors.Wrap(err, "failed to remove prexisting hives directory")
|
||||
}
|
||||
}
|
||||
if _, err := os.Stat(layoutPath); err == nil {
|
||||
if err := os.RemoveAll(layoutPath); err != nil {
|
||||
return errors.Wrap(err, "failed to remove prexisting layout file")
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := os.Stat(baseVhdPath); err == nil {
|
||||
if err := os.RemoveAll(baseVhdPath); err != nil {
|
||||
return errors.Wrap(err, "failed to remove base vhdx path")
|
||||
}
|
||||
}
|
||||
if _, err := os.Stat(diffVhdPath); err == nil {
|
||||
if err := os.RemoveAll(diffVhdPath); err != nil {
|
||||
return errors.Wrap(err, "failed to remove differencing vhdx")
|
||||
}
|
||||
}
|
||||
|
||||
createParams := &vhd.CreateVirtualDiskParameters{
|
||||
Version: 2,
|
||||
Version2: vhd.CreateVersion2{
|
||||
MaximumSize: sizeInGB * 1024 * 1024 * 1024,
|
||||
BlockSizeInBytes: defaultVHDXBlockSizeInMB * 1024 * 1024,
|
||||
},
|
||||
}
|
||||
handle, err := vhd.CreateVirtualDisk(baseVhdPath, vhd.VirtualDiskAccessNone, vhd.CreateVirtualDiskFlagNone, createParams)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create vhdx")
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
syscall.CloseHandle(handle)
|
||||
os.RemoveAll(baseVhdPath)
|
||||
if os.Stat(diffVhdPath); err == nil {
|
||||
os.RemoveAll(diffVhdPath)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if err = FormatWritableLayerVhd(ctx, windows.Handle(handle)); err != nil {
|
||||
return err
|
||||
}
|
||||
// Base vhd handle must be closed before calling SetupBaseLayer in case of Container layer
|
||||
if err = syscall.CloseHandle(handle); err != nil {
|
||||
return errors.Wrap(err, "failed to close vhdx handle")
|
||||
}
|
||||
|
||||
options := OsLayerOptions{
|
||||
Type: OsLayerTypeContainer,
|
||||
}
|
||||
|
||||
// SetupBaseOSLayer expects an empty vhd handle for a container layer and will
|
||||
// error out otherwise.
|
||||
if err = SetupBaseOSLayer(ctx, layerPath, 0, options); err != nil {
|
||||
return err
|
||||
}
|
||||
// Create the differencing disk that will be what's copied for the final rw layer
|
||||
// for a container.
|
||||
if err = vhd.CreateDiffVhd(diffVhdPath, baseVhdPath, defaultVHDXBlockSizeInMB); err != nil {
|
||||
return errors.Wrap(err, "failed to create differencing disk")
|
||||
}
|
||||
|
||||
if err = security.GrantVmGroupAccess(baseVhdPath); err != nil {
|
||||
return errors.Wrapf(err, "failed to grant vm group access to %s", baseVhdPath)
|
||||
}
|
||||
if err = security.GrantVmGroupAccess(diffVhdPath); err != nil {
|
||||
return errors.Wrapf(err, "failed to grant vm group access to %s", diffVhdPath)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetupUtilityVMBaseLayer is a helper to setup a UVMs scratch space. It will create and format
|
||||
// the vhdx inside and the size is configurable by the sizeInGB parameter.
|
||||
//
|
||||
// `uvmPath` is the path to the UtilityVM filesystem.
|
||||
//
|
||||
// `baseVhdPath` is the path to where the base vhdx for the UVM should be created.
|
||||
//
|
||||
// `diffVhdPath` is the path where the differencing disk for the UVM should be created.
|
||||
//
|
||||
// `sizeInGB` specifies the size in gigabytes to make the base vhdx.
|
||||
func SetupUtilityVMBaseLayer(ctx context.Context, uvmPath, baseVhdPath, diffVhdPath string, sizeInGB uint64) (err error) {
|
||||
// Remove the base and differencing disks if they exist in case we're asking for a different size.
|
||||
if _, err := os.Stat(baseVhdPath); err == nil {
|
||||
if err := os.RemoveAll(baseVhdPath); err != nil {
|
||||
return errors.Wrap(err, "failed to remove base vhdx")
|
||||
}
|
||||
}
|
||||
if _, err := os.Stat(diffVhdPath); err == nil {
|
||||
if err := os.RemoveAll(diffVhdPath); err != nil {
|
||||
return errors.Wrap(err, "failed to remove differencing vhdx")
|
||||
}
|
||||
}
|
||||
|
||||
// Just create the vhdx for utilityVM layer, no need to format it.
|
||||
createParams := &vhd.CreateVirtualDiskParameters{
|
||||
Version: 2,
|
||||
Version2: vhd.CreateVersion2{
|
||||
MaximumSize: sizeInGB * 1024 * 1024 * 1024,
|
||||
BlockSizeInBytes: defaultVHDXBlockSizeInMB * 1024 * 1024,
|
||||
},
|
||||
}
|
||||
handle, err := vhd.CreateVirtualDisk(baseVhdPath, vhd.VirtualDiskAccessNone, vhd.CreateVirtualDiskFlagNone, createParams)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create vhdx")
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
syscall.CloseHandle(handle)
|
||||
os.RemoveAll(baseVhdPath)
|
||||
if os.Stat(diffVhdPath); err == nil {
|
||||
os.RemoveAll(diffVhdPath)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// If it is a UtilityVM layer then the base vhdx must be attached when calling
|
||||
// `SetupBaseOSLayer`
|
||||
attachParams := &vhd.AttachVirtualDiskParameters{
|
||||
Version: 2,
|
||||
}
|
||||
if err := vhd.AttachVirtualDisk(handle, vhd.AttachVirtualDiskFlagNone, attachParams); err != nil {
|
||||
return errors.Wrapf(err, "failed to attach virtual disk")
|
||||
}
|
||||
|
||||
options := OsLayerOptions{
|
||||
Type: OsLayerTypeVM,
|
||||
}
|
||||
if err := SetupBaseOSLayer(ctx, uvmPath, windows.Handle(handle), options); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Detach and close the handle after setting up the layer as we don't need the handle
|
||||
// for anything else and we no longer need to be attached either.
|
||||
if err = vhd.DetachVirtualDisk(handle); err != nil {
|
||||
return errors.Wrap(err, "failed to detach vhdx")
|
||||
}
|
||||
if err = syscall.CloseHandle(handle); err != nil {
|
||||
return errors.Wrap(err, "failed to close vhdx handle")
|
||||
}
|
||||
|
||||
// Create the differencing disk that will be what's copied for the final rw layer
|
||||
// for a container.
|
||||
if err = vhd.CreateDiffVhd(diffVhdPath, baseVhdPath, defaultVHDXBlockSizeInMB); err != nil {
|
||||
return errors.Wrap(err, "failed to create differencing disk")
|
||||
}
|
||||
|
||||
if err := security.GrantVmGroupAccess(baseVhdPath); err != nil {
|
||||
return errors.Wrapf(err, "failed to grant vm group access to %s", baseVhdPath)
|
||||
}
|
||||
if err := security.GrantVmGroupAccess(diffVhdPath); err != nil {
|
||||
return errors.Wrapf(err, "failed to grant vm group access to %s", diffVhdPath)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package computestorage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/oc"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// ImportLayer imports a container layer.
|
||||
//
|
||||
// `layerPath` is a path to a directory to import the layer to. If the directory
|
||||
// does not exist it will be automatically created.
|
||||
//
|
||||
// `sourceFolderpath` is a pre-existing folder that contains the layer to
|
||||
// import.
|
||||
//
|
||||
// `layerData` is the parent layer data.
|
||||
func ImportLayer(ctx context.Context, layerPath, sourceFolderPath string, layerData LayerData) (err error) {
|
||||
title := "hcsshim.ImportLayer"
|
||||
ctx, span := trace.StartSpan(ctx, title)
|
||||
defer span.End()
|
||||
defer func() { oc.SetSpanStatus(span, err) }()
|
||||
span.AddAttributes(
|
||||
trace.StringAttribute("layerPath", layerPath),
|
||||
trace.StringAttribute("sourceFolderPath", sourceFolderPath),
|
||||
)
|
||||
|
||||
bytes, err := json.Marshal(layerData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = hcsImportLayer(layerPath, sourceFolderPath, string(bytes))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to import layer: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package computestorage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/oc"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// InitializeWritableLayer initializes a writable layer for a container.
|
||||
//
|
||||
// `layerPath` is a path to a directory the layer is mounted. If the
|
||||
// path does not end in a `\` the platform will append it automatically.
|
||||
//
|
||||
// `layerData` is the parent read-only layer data.
|
||||
func InitializeWritableLayer(ctx context.Context, layerPath string, layerData LayerData) (err error) {
|
||||
title := "hcsshim.InitializeWritableLayer"
|
||||
ctx, span := trace.StartSpan(ctx, title)
|
||||
defer span.End()
|
||||
defer func() { oc.SetSpanStatus(span, err) }()
|
||||
span.AddAttributes(
|
||||
trace.StringAttribute("layerPath", layerPath),
|
||||
)
|
||||
|
||||
bytes, err := json.Marshal(layerData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Options are not used in the platform as of RS5
|
||||
err = hcsInitializeWritableLayer(layerPath, string(bytes), "")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to intitialize container layer: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package computestorage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/interop"
|
||||
"github.com/Microsoft/hcsshim/internal/oc"
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// GetLayerVhdMountPath returns the volume path for a virtual disk of a writable container layer.
|
||||
func GetLayerVhdMountPath(ctx context.Context, vhdHandle windows.Handle) (path string, err error) {
|
||||
title := "hcsshim.GetLayerVhdMountPath"
|
||||
ctx, span := trace.StartSpan(ctx, title)
|
||||
defer span.End()
|
||||
defer func() { oc.SetSpanStatus(span, err) }()
|
||||
|
||||
var mountPath *uint16
|
||||
err = hcsGetLayerVhdMountPath(vhdHandle, &mountPath)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get vhd mount path: %s", err)
|
||||
}
|
||||
path = interop.ConvertAndFreeCoTaskMemString(mountPath)
|
||||
return path, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package computestorage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/oc"
|
||||
"github.com/Microsoft/hcsshim/osversion"
|
||||
"go.opencensus.io/trace"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// SetupBaseOSLayer sets up a layer that contains a base OS for a container.
|
||||
//
|
||||
// `layerPath` is a path to a directory containing the layer.
|
||||
//
|
||||
// `vhdHandle` is an empty file handle of `options.Type == OsLayerTypeContainer`
|
||||
// or else it is a file handle to the 'SystemTemplateBase.vhdx' if `options.Type
|
||||
// == OsLayerTypeVm`.
|
||||
//
|
||||
// `options` are the options applied while processing the layer.
|
||||
func SetupBaseOSLayer(ctx context.Context, layerPath string, vhdHandle windows.Handle, options OsLayerOptions) (err error) {
|
||||
title := "hcsshim.SetupBaseOSLayer"
|
||||
ctx, span := trace.StartSpan(ctx, title)
|
||||
defer span.End()
|
||||
defer func() { oc.SetSpanStatus(span, err) }()
|
||||
span.AddAttributes(
|
||||
trace.StringAttribute("layerPath", layerPath),
|
||||
)
|
||||
|
||||
bytes, err := json.Marshal(options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = hcsSetupBaseOSLayer(layerPath, vhdHandle, string(bytes))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to setup base OS layer: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetupBaseOSVolume sets up a volume that contains a base OS for a container.
|
||||
//
|
||||
// `layerPath` is a path to a directory containing the layer.
|
||||
//
|
||||
// `volumePath` is the path to the volume to be used for setup.
|
||||
//
|
||||
// `options` are the options applied while processing the layer.
|
||||
func SetupBaseOSVolume(ctx context.Context, layerPath, volumePath string, options OsLayerOptions) (err error) {
|
||||
if osversion.Get().Build < 19645 {
|
||||
return errors.New("SetupBaseOSVolume is not present on builds older than 19645")
|
||||
}
|
||||
title := "hcsshim.SetupBaseOSVolume"
|
||||
ctx, span := trace.StartSpan(ctx, title)
|
||||
defer span.End()
|
||||
defer func() { oc.SetSpanStatus(span, err) }()
|
||||
span.AddAttributes(
|
||||
trace.StringAttribute("layerPath", layerPath),
|
||||
trace.StringAttribute("volumePath", volumePath),
|
||||
)
|
||||
|
||||
bytes, err := json.Marshal(options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = hcsSetupBaseOSVolume(layerPath, volumePath, string(bytes))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to setup base OS layer: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// Package computestorage is a wrapper around the HCS storage APIs. These are new storage APIs introduced
|
||||
// separate from the original graphdriver calls intended to give more freedom around creating
|
||||
// and managing container layers and scratch spaces.
|
||||
package computestorage
|
||||
|
||||
import (
|
||||
hcsschema "github.com/Microsoft/hcsshim/internal/schema2"
|
||||
)
|
||||
|
||||
//go:generate go run ../mksyscall_windows.go -output zsyscall_windows.go storage.go
|
||||
|
||||
//sys hcsImportLayer(layerPath string, sourceFolderPath string, layerData string) (hr error) = computestorage.HcsImportLayer?
|
||||
//sys hcsExportLayer(layerPath string, exportFolderPath string, layerData string, options string) (hr error) = computestorage.HcsExportLayer?
|
||||
//sys hcsDestroyLayer(layerPath string) (hr error) = computestorage.HcsDestoryLayer?
|
||||
//sys hcsSetupBaseOSLayer(layerPath string, handle windows.Handle, options string) (hr error) = computestorage.HcsSetupBaseOSLayer?
|
||||
//sys hcsInitializeWritableLayer(writableLayerPath string, layerData string, options string) (hr error) = computestorage.HcsInitializeWritableLayer?
|
||||
//sys hcsAttachLayerStorageFilter(layerPath string, layerData string) (hr error) = computestorage.HcsAttachLayerStorageFilter?
|
||||
//sys hcsDetachLayerStorageFilter(layerPath string) (hr error) = computestorage.HcsDetachLayerStorageFilter?
|
||||
//sys hcsFormatWritableLayerVhd(handle windows.Handle) (hr error) = computestorage.HcsFormatWritableLayerVhd?
|
||||
//sys hcsGetLayerVhdMountPath(vhdHandle windows.Handle, mountPath **uint16) (hr error) = computestorage.HcsGetLayerVhdMountPath?
|
||||
//sys hcsSetupBaseOSVolume(layerPath string, volumePath string, options string) (hr error) = computestorage.HcsSetupBaseOSVolume?
|
||||
|
||||
// LayerData is the data used to describe parent layer information.
|
||||
type LayerData struct {
|
||||
SchemaVersion hcsschema.Version `json:"SchemaVersion,omitempty"`
|
||||
Layers []hcsschema.Layer `json:"Layers,omitempty"`
|
||||
}
|
||||
|
||||
// ExportLayerOptions are the set of options that are used with the `computestorage.HcsExportLayer` syscall.
|
||||
type ExportLayerOptions struct {
|
||||
IsWritableLayer bool `json:"IsWritableLayer,omitempty"`
|
||||
}
|
||||
|
||||
// OsLayerType is the type of layer being operated on.
|
||||
type OsLayerType string
|
||||
|
||||
const (
|
||||
// OsLayerTypeContainer is a container layer.
|
||||
OsLayerTypeContainer OsLayerType = "Container"
|
||||
// OsLayerTypeVM is a virtual machine layer.
|
||||
OsLayerTypeVM OsLayerType = "Vm"
|
||||
)
|
||||
|
||||
// OsLayerOptions are the set of options that are used with the `SetupBaseOSLayer` and
|
||||
// `SetupBaseOSVolume` calls.
|
||||
type OsLayerOptions struct {
|
||||
Type OsLayerType `json:"Type,omitempty"`
|
||||
DisableCiCacheOptimization bool `json:"DisableCiCacheOptimization,omitempty"`
|
||||
SkipUpdateBcdForBoot bool `json:"SkipUpdateBcdForBoot,omitempty"`
|
||||
}
|
||||
319
vendor/github.com/Microsoft/hcsshim/computestorage/zsyscall_windows.go
generated
vendored
Normal file
319
vendor/github.com/Microsoft/hcsshim/computestorage/zsyscall_windows.go
generated
vendored
Normal file
|
|
@ -0,0 +1,319 @@
|
|||
// Code generated mksyscall_windows.exe DO NOT EDIT
|
||||
|
||||
package computestorage
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
// Do the interface allocations only once for common
|
||||
// Errno values.
|
||||
const (
|
||||
errnoERROR_IO_PENDING = 997
|
||||
)
|
||||
|
||||
var (
|
||||
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
|
||||
)
|
||||
|
||||
// errnoErr returns common boxed Errno values, to prevent
|
||||
// allocations at runtime.
|
||||
func errnoErr(e syscall.Errno) error {
|
||||
switch e {
|
||||
case 0:
|
||||
return nil
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
var (
|
||||
modcomputestorage = windows.NewLazySystemDLL("computestorage.dll")
|
||||
|
||||
procHcsImportLayer = modcomputestorage.NewProc("HcsImportLayer")
|
||||
procHcsExportLayer = modcomputestorage.NewProc("HcsExportLayer")
|
||||
procHcsDestoryLayer = modcomputestorage.NewProc("HcsDestoryLayer")
|
||||
procHcsSetupBaseOSLayer = modcomputestorage.NewProc("HcsSetupBaseOSLayer")
|
||||
procHcsInitializeWritableLayer = modcomputestorage.NewProc("HcsInitializeWritableLayer")
|
||||
procHcsAttachLayerStorageFilter = modcomputestorage.NewProc("HcsAttachLayerStorageFilter")
|
||||
procHcsDetachLayerStorageFilter = modcomputestorage.NewProc("HcsDetachLayerStorageFilter")
|
||||
procHcsFormatWritableLayerVhd = modcomputestorage.NewProc("HcsFormatWritableLayerVhd")
|
||||
procHcsGetLayerVhdMountPath = modcomputestorage.NewProc("HcsGetLayerVhdMountPath")
|
||||
procHcsSetupBaseOSVolume = modcomputestorage.NewProc("HcsSetupBaseOSVolume")
|
||||
)
|
||||
|
||||
func hcsImportLayer(layerPath string, sourceFolderPath string, layerData string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(layerPath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(sourceFolderPath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p2 *uint16
|
||||
_p2, hr = syscall.UTF16PtrFromString(layerData)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _hcsImportLayer(_p0, _p1, _p2)
|
||||
}
|
||||
|
||||
func _hcsImportLayer(layerPath *uint16, sourceFolderPath *uint16, layerData *uint16) (hr error) {
|
||||
if hr = procHcsImportLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsImportLayer.Addr(), 3, uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(sourceFolderPath)), uintptr(unsafe.Pointer(layerData)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func hcsExportLayer(layerPath string, exportFolderPath string, layerData string, options string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(layerPath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(exportFolderPath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p2 *uint16
|
||||
_p2, hr = syscall.UTF16PtrFromString(layerData)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p3 *uint16
|
||||
_p3, hr = syscall.UTF16PtrFromString(options)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _hcsExportLayer(_p0, _p1, _p2, _p3)
|
||||
}
|
||||
|
||||
func _hcsExportLayer(layerPath *uint16, exportFolderPath *uint16, layerData *uint16, options *uint16) (hr error) {
|
||||
if hr = procHcsExportLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHcsExportLayer.Addr(), 4, uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(exportFolderPath)), uintptr(unsafe.Pointer(layerData)), uintptr(unsafe.Pointer(options)), 0, 0)
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func hcsDestroyLayer(layerPath string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(layerPath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _hcsDestroyLayer(_p0)
|
||||
}
|
||||
|
||||
func _hcsDestroyLayer(layerPath *uint16) (hr error) {
|
||||
if hr = procHcsDestoryLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsDestoryLayer.Addr(), 1, uintptr(unsafe.Pointer(layerPath)), 0, 0)
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func hcsSetupBaseOSLayer(layerPath string, handle windows.Handle, options string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(layerPath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(options)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _hcsSetupBaseOSLayer(_p0, handle, _p1)
|
||||
}
|
||||
|
||||
func _hcsSetupBaseOSLayer(layerPath *uint16, handle windows.Handle, options *uint16) (hr error) {
|
||||
if hr = procHcsSetupBaseOSLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsSetupBaseOSLayer.Addr(), 3, uintptr(unsafe.Pointer(layerPath)), uintptr(handle), uintptr(unsafe.Pointer(options)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func hcsInitializeWritableLayer(writableLayerPath string, layerData string, options string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(writableLayerPath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(layerData)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p2 *uint16
|
||||
_p2, hr = syscall.UTF16PtrFromString(options)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _hcsInitializeWritableLayer(_p0, _p1, _p2)
|
||||
}
|
||||
|
||||
func _hcsInitializeWritableLayer(writableLayerPath *uint16, layerData *uint16, options *uint16) (hr error) {
|
||||
if hr = procHcsInitializeWritableLayer.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsInitializeWritableLayer.Addr(), 3, uintptr(unsafe.Pointer(writableLayerPath)), uintptr(unsafe.Pointer(layerData)), uintptr(unsafe.Pointer(options)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func hcsAttachLayerStorageFilter(layerPath string, layerData string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(layerPath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(layerData)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _hcsAttachLayerStorageFilter(_p0, _p1)
|
||||
}
|
||||
|
||||
func _hcsAttachLayerStorageFilter(layerPath *uint16, layerData *uint16) (hr error) {
|
||||
if hr = procHcsAttachLayerStorageFilter.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsAttachLayerStorageFilter.Addr(), 2, uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(layerData)), 0)
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func hcsDetachLayerStorageFilter(layerPath string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(layerPath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _hcsDetachLayerStorageFilter(_p0)
|
||||
}
|
||||
|
||||
func _hcsDetachLayerStorageFilter(layerPath *uint16) (hr error) {
|
||||
if hr = procHcsDetachLayerStorageFilter.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsDetachLayerStorageFilter.Addr(), 1, uintptr(unsafe.Pointer(layerPath)), 0, 0)
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func hcsFormatWritableLayerVhd(handle windows.Handle) (hr error) {
|
||||
if hr = procHcsFormatWritableLayerVhd.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsFormatWritableLayerVhd.Addr(), 1, uintptr(handle), 0, 0)
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func hcsGetLayerVhdMountPath(vhdHandle windows.Handle, mountPath **uint16) (hr error) {
|
||||
if hr = procHcsGetLayerVhdMountPath.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsGetLayerVhdMountPath.Addr(), 2, uintptr(vhdHandle), uintptr(unsafe.Pointer(mountPath)), 0)
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func hcsSetupBaseOSVolume(layerPath string, volumePath string, options string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(layerPath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(volumePath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p2 *uint16
|
||||
_p2, hr = syscall.UTF16PtrFromString(options)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _hcsSetupBaseOSVolume(_p0, _p1, _p2)
|
||||
}
|
||||
|
||||
func _hcsSetupBaseOSVolume(layerPath *uint16, volumePath *uint16, options *uint16) (hr error) {
|
||||
if hr = procHcsSetupBaseOSVolume.Find(); hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsSetupBaseOSVolume.Addr(), 3, uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(volumePath)), uintptr(unsafe.Pointer(options)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ module github.com/Microsoft/hcsshim
|
|||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5
|
||||
github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331
|
||||
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59
|
||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1
|
||||
github.com/containerd/containerd v1.3.2
|
||||
|
|
@ -26,7 +26,7 @@ require (
|
|||
go.opencensus.io v0.22.0
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 // indirect
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58
|
||||
golang.org/x/sys v0.0.0-20200120151820-655fe14d7479
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 // indirect
|
||||
google.golang.org/grpc v1.23.1
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA=
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20200908182639-5b44b70ab3ab h1:9pygWVFqbY9lPxM0peffumuVDyMuIMzNLyO9uFjJuQo=
|
||||
github.com/Microsoft/go-winio v0.4.15-0.20200908182639-5b44b70ab3ab/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331 h1:3YnB7Hpmh1lPecPE8doMOtYCrMdrpedZOvxfuNES/Vk=
|
||||
github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 h1:qWj4qVYZ95vLWwqyNJCQg7rDsG5wPdze0UaPolH7DUk=
|
||||
|
|
@ -121,6 +123,8 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200120151820-655fe14d7479 h1:LhLiKguPgZL+Tglay4GhVtfF0kb8cvOJ0dHTCBO8YNI=
|
||||
golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
|
|
|
|||
|
|
@ -7,11 +7,9 @@ go_library(
|
|||
"errors.go",
|
||||
"process.go",
|
||||
"service.go",
|
||||
"syscall.go",
|
||||
"system.go",
|
||||
"utils.go",
|
||||
"waithelper.go",
|
||||
"zsyscall_windows.go",
|
||||
],
|
||||
importmap = "k8s.io/kops/vendor/github.com/Microsoft/hcsshim/internal/hcs",
|
||||
importpath = "github.com/Microsoft/hcsshim/internal/hcs",
|
||||
|
|
@ -19,6 +17,7 @@ go_library(
|
|||
deps = [
|
||||
"//vendor/github.com/Microsoft/go-winio:go_default_library",
|
||||
"//vendor/github.com/Microsoft/go-winio/vhd:go_default_library",
|
||||
"//vendor/github.com/Microsoft/hcsshim/computestorage:go_default_library",
|
||||
"//vendor/github.com/Microsoft/hcsshim/internal/cow:go_default_library",
|
||||
"//vendor/github.com/Microsoft/hcsshim/internal/interop:go_default_library",
|
||||
"//vendor/github.com/Microsoft/hcsshim/internal/log:go_default_library",
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
package hcs
|
||||
|
||||
//go:generate go run ../../mksyscall_windows.go -output zsyscall_windows.go syscall.go
|
||||
|
||||
//sys hcsFormatWritableLayerVhd(handle uintptr) (hr error) = computestorage.HcsFormatWritableLayerVhd
|
||||
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/Microsoft/go-winio"
|
||||
diskutil "github.com/Microsoft/go-winio/vhd"
|
||||
"github.com/Microsoft/hcsshim/computestorage"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
|
@ -36,7 +37,7 @@ func makeOpenFiles(hs []syscall.Handle) (_ []io.ReadWriteCloser, err error) {
|
|||
return fs, nil
|
||||
}
|
||||
|
||||
// creates a VHD formatted with NTFS of size `sizeGB` at the given `vhdPath`.
|
||||
// CreateNTFSVHD creates a VHD formatted with NTFS of size `sizeGB` at the given `vhdPath`.
|
||||
func CreateNTFSVHD(ctx context.Context, vhdPath string, sizeGB uint32) (err error) {
|
||||
if err := diskutil.CreateVhdx(vhdPath, sizeGB, 1); err != nil {
|
||||
return errors.Wrap(err, "failed to create VHD")
|
||||
|
|
@ -53,7 +54,7 @@ func CreateNTFSVHD(ctx context.Context, vhdPath string, sizeGB uint32) (err erro
|
|||
}
|
||||
}()
|
||||
|
||||
if err := hcsFormatWritableLayerVhd(uintptr(vhd)); err != nil {
|
||||
if err := computestorage.FormatWritableLayerVhd(ctx, windows.Handle(vhd)); err != nil {
|
||||
return errors.Wrap(err, "failed to format VHD")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
// Code generated mksyscall_windows.exe DO NOT EDIT
|
||||
|
||||
package hcs
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
// Do the interface allocations only once for common
|
||||
// Errno values.
|
||||
const (
|
||||
errnoERROR_IO_PENDING = 997
|
||||
)
|
||||
|
||||
var (
|
||||
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
|
||||
)
|
||||
|
||||
// errnoErr returns common boxed Errno values, to prevent
|
||||
// allocations at runtime.
|
||||
func errnoErr(e syscall.Errno) error {
|
||||
switch e {
|
||||
case 0:
|
||||
return nil
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
var (
|
||||
modcomputestorage = windows.NewLazySystemDLL("computestorage.dll")
|
||||
|
||||
procHcsFormatWritableLayerVhd = modcomputestorage.NewProc("HcsFormatWritableLayerVhd")
|
||||
)
|
||||
|
||||
func hcsFormatWritableLayerVhd(handle uintptr) (hr error) {
|
||||
r0, _, _ := syscall.Syscall(procHcsFormatWritableLayerVhd.Addr(), 1, uintptr(handle), 0, 0)
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
@ -27,9 +27,10 @@ type namespaceResourceRequest struct {
|
|||
}
|
||||
|
||||
type Namespace struct {
|
||||
ID string
|
||||
IsDefault bool `json:",omitempty"`
|
||||
ResourceList []NamespaceResource `json:",omitempty"`
|
||||
ID string
|
||||
IsDefault bool `json:",omitempty"`
|
||||
ResourceList []NamespaceResource `json:",omitempty"`
|
||||
CompartmentId uint32 `json:",omitempty"`
|
||||
}
|
||||
|
||||
func issueNamespaceRequest(id *string, method, subpath string, request interface{}) (*Namespace, error) {
|
||||
|
|
|
|||
|
|
@ -2,20 +2,13 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
|||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"safeopen.go",
|
||||
"zsyscall_windows.go",
|
||||
],
|
||||
srcs = ["safeopen.go"],
|
||||
importmap = "k8s.io/kops/vendor/github.com/Microsoft/hcsshim/internal/safefile",
|
||||
importpath = "github.com/Microsoft/hcsshim/internal/safefile",
|
||||
visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"],
|
||||
deps = [
|
||||
"//vendor/github.com/Microsoft/go-winio:go_default_library",
|
||||
"//vendor/github.com/Microsoft/hcsshim/internal/longpath:go_default_library",
|
||||
] + select({
|
||||
"@io_bazel_rules_go//go/platform:windows": [
|
||||
"//vendor/golang.org/x/sys/windows:go_default_library",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
"//vendor/github.com/Microsoft/hcsshim/internal/winapi:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -11,72 +11,11 @@ import (
|
|||
"unsafe"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/longpath"
|
||||
"github.com/Microsoft/hcsshim/internal/winapi"
|
||||
|
||||
winio "github.com/Microsoft/go-winio"
|
||||
)
|
||||
|
||||
//go:generate go run $GOROOT\src\syscall\mksyscall_windows.go -output zsyscall_windows.go safeopen.go
|
||||
|
||||
//sys ntCreateFile(handle *uintptr, accessMask uint32, oa *objectAttributes, iosb *ioStatusBlock, allocationSize *uint64, fileAttributes uint32, shareAccess uint32, createDisposition uint32, createOptions uint32, eaBuffer *byte, eaLength uint32) (status uint32) = ntdll.NtCreateFile
|
||||
//sys ntSetInformationFile(handle uintptr, iosb *ioStatusBlock, information uintptr, length uint32, class uint32) (status uint32) = ntdll.NtSetInformationFile
|
||||
//sys rtlNtStatusToDosError(status uint32) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb
|
||||
//sys localAlloc(flags uint32, size int) (ptr uintptr) = kernel32.LocalAlloc
|
||||
//sys localFree(ptr uintptr) = kernel32.LocalFree
|
||||
|
||||
type ioStatusBlock struct {
|
||||
Status, Information uintptr
|
||||
}
|
||||
|
||||
type objectAttributes struct {
|
||||
Length uintptr
|
||||
RootDirectory uintptr
|
||||
ObjectName uintptr
|
||||
Attributes uintptr
|
||||
SecurityDescriptor uintptr
|
||||
SecurityQoS uintptr
|
||||
}
|
||||
|
||||
type unicodeString struct {
|
||||
Length uint16
|
||||
MaximumLength uint16
|
||||
Buffer uintptr
|
||||
}
|
||||
|
||||
type fileLinkInformation struct {
|
||||
ReplaceIfExists bool
|
||||
RootDirectory uintptr
|
||||
FileNameLength uint32
|
||||
FileName [1]uint16
|
||||
}
|
||||
|
||||
type fileDispositionInformationEx struct {
|
||||
Flags uintptr
|
||||
}
|
||||
|
||||
const (
|
||||
_FileLinkInformation = 11
|
||||
_FileDispositionInformationEx = 64
|
||||
|
||||
FILE_READ_ATTRIBUTES = 0x0080
|
||||
FILE_WRITE_ATTRIBUTES = 0x0100
|
||||
DELETE = 0x10000
|
||||
|
||||
FILE_OPEN = 1
|
||||
FILE_CREATE = 2
|
||||
|
||||
FILE_DIRECTORY_FILE = 0x00000001
|
||||
FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020
|
||||
FILE_DELETE_ON_CLOSE = 0x00001000
|
||||
FILE_OPEN_FOR_BACKUP_INTENT = 0x00004000
|
||||
FILE_OPEN_REPARSE_POINT = 0x00200000
|
||||
|
||||
FILE_DISPOSITION_DELETE = 0x00000001
|
||||
|
||||
_OBJ_DONT_REPARSE = 0x1000
|
||||
|
||||
_STATUS_REPARSE_POINT_ENCOUNTERED = 0xC000050B
|
||||
)
|
||||
|
||||
func OpenRoot(path string) (*os.File, error) {
|
||||
longpath, err := longpath.LongAbs(path)
|
||||
if err != nil {
|
||||
|
|
@ -85,16 +24,24 @@ func OpenRoot(path string) (*os.File, error) {
|
|||
return winio.OpenForBackup(longpath, syscall.GENERIC_READ, syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE, syscall.OPEN_EXISTING)
|
||||
}
|
||||
|
||||
func ntRelativePath(path string) ([]uint16, error) {
|
||||
func cleanGoStringRelativePath(path string) (string, error) {
|
||||
path = filepath.Clean(path)
|
||||
if strings.Contains(path, ":") {
|
||||
// Since alternate data streams must follow the file they
|
||||
// are attached to, finding one here (out of order) is invalid.
|
||||
return nil, errors.New("path contains invalid character `:`")
|
||||
return "", errors.New("path contains invalid character `:`")
|
||||
}
|
||||
fspath := filepath.FromSlash(path)
|
||||
if len(fspath) > 0 && fspath[0] == '\\' {
|
||||
return nil, errors.New("expected relative path")
|
||||
return "", errors.New("expected relative path")
|
||||
}
|
||||
return fspath, nil
|
||||
}
|
||||
|
||||
func ntRelativePath(path string) ([]uint16, error) {
|
||||
fspath, err := cleanGoStringRelativePath(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
path16 := utf16.Encode(([]rune)(fspath))
|
||||
|
|
@ -110,11 +57,11 @@ func ntRelativePath(path string) ([]uint16, error) {
|
|||
func openRelativeInternal(path string, root *os.File, accessMask uint32, shareFlags uint32, createDisposition uint32, flags uint32) (*os.File, error) {
|
||||
var (
|
||||
h uintptr
|
||||
iosb ioStatusBlock
|
||||
oa objectAttributes
|
||||
iosb winapi.IOStatusBlock
|
||||
oa winapi.ObjectAttributes
|
||||
)
|
||||
|
||||
path16, err := ntRelativePath(path)
|
||||
cleanRelativePath, err := cleanGoStringRelativePath(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -123,20 +70,16 @@ func openRelativeInternal(path string, root *os.File, accessMask uint32, shareFl
|
|||
return nil, errors.New("missing root directory")
|
||||
}
|
||||
|
||||
upathBuffer := localAlloc(0, int(unsafe.Sizeof(unicodeString{}))+len(path16)*2)
|
||||
defer localFree(upathBuffer)
|
||||
|
||||
upath := (*unicodeString)(unsafe.Pointer(upathBuffer))
|
||||
upath.Length = uint16(len(path16) * 2)
|
||||
upath.MaximumLength = upath.Length
|
||||
upath.Buffer = upathBuffer + unsafe.Sizeof(*upath)
|
||||
copy((*[32768]uint16)(unsafe.Pointer(upath.Buffer))[:], path16)
|
||||
pathUnicode, err := winapi.NewUnicodeString(cleanRelativePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
oa.Length = unsafe.Sizeof(oa)
|
||||
oa.ObjectName = upathBuffer
|
||||
oa.ObjectName = uintptr(unsafe.Pointer(pathUnicode))
|
||||
oa.RootDirectory = uintptr(root.Fd())
|
||||
oa.Attributes = _OBJ_DONT_REPARSE
|
||||
status := ntCreateFile(
|
||||
oa.Attributes = winapi.OBJ_DONT_REPARSE
|
||||
status := winapi.NtCreateFile(
|
||||
&h,
|
||||
accessMask|syscall.SYNCHRONIZE,
|
||||
&oa,
|
||||
|
|
@ -145,12 +88,12 @@ func openRelativeInternal(path string, root *os.File, accessMask uint32, shareFl
|
|||
0,
|
||||
shareFlags,
|
||||
createDisposition,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT|FILE_SYNCHRONOUS_IO_NONALERT|flags,
|
||||
winapi.FILE_OPEN_FOR_BACKUP_INTENT|winapi.FILE_SYNCHRONOUS_IO_NONALERT|flags,
|
||||
nil,
|
||||
0,
|
||||
)
|
||||
if status != 0 {
|
||||
return nil, rtlNtStatusToDosError(status)
|
||||
return nil, winapi.RtlNtStatusToDosError(status)
|
||||
}
|
||||
|
||||
fullPath, err := longpath.LongAbs(filepath.Join(root.Name(), path))
|
||||
|
|
@ -182,7 +125,7 @@ func LinkRelative(oldname string, oldroot *os.File, newname string, newroot *os.
|
|||
oldroot,
|
||||
syscall.FILE_WRITE_ATTRIBUTES,
|
||||
syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
|
||||
FILE_OPEN,
|
||||
winapi.FILE_OPEN,
|
||||
0,
|
||||
)
|
||||
if err != nil {
|
||||
|
|
@ -199,8 +142,8 @@ func LinkRelative(oldname string, oldroot *os.File, newname string, newroot *os.
|
|||
newroot,
|
||||
syscall.GENERIC_READ,
|
||||
syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
|
||||
FILE_OPEN,
|
||||
FILE_DIRECTORY_FILE)
|
||||
winapi.FILE_OPEN,
|
||||
winapi.FILE_DIRECTORY_FILE)
|
||||
if err != nil {
|
||||
return &os.LinkError{Op: "link", Old: oldf.Name(), New: filepath.Join(newroot.Name(), newname), Err: err}
|
||||
}
|
||||
|
|
@ -211,7 +154,7 @@ func LinkRelative(oldname string, oldroot *os.File, newname string, newroot *os.
|
|||
return err
|
||||
}
|
||||
if (fi.FileAttributes & syscall.FILE_ATTRIBUTE_REPARSE_POINT) != 0 {
|
||||
return &os.LinkError{Op: "link", Old: oldf.Name(), New: filepath.Join(newroot.Name(), newname), Err: rtlNtStatusToDosError(_STATUS_REPARSE_POINT_ENCOUNTERED)}
|
||||
return &os.LinkError{Op: "link", Old: oldf.Name(), New: filepath.Join(newroot.Name(), newname), Err: winapi.RtlNtStatusToDosError(winapi.STATUS_REPARSE_POINT_ENCOUNTERED)}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -227,24 +170,25 @@ func LinkRelative(oldname string, oldroot *os.File, newname string, newroot *os.
|
|||
return err
|
||||
}
|
||||
|
||||
size := int(unsafe.Offsetof(fileLinkInformation{}.FileName)) + len(newbase16)*2
|
||||
linkinfoBuffer := localAlloc(0, size)
|
||||
defer localFree(linkinfoBuffer)
|
||||
linkinfo := (*fileLinkInformation)(unsafe.Pointer(linkinfoBuffer))
|
||||
size := int(unsafe.Offsetof(winapi.FileLinkInformation{}.FileName)) + len(newbase16)*2
|
||||
linkinfoBuffer := winapi.LocalAlloc(0, size)
|
||||
defer winapi.LocalFree(linkinfoBuffer)
|
||||
|
||||
linkinfo := (*winapi.FileLinkInformation)(unsafe.Pointer(linkinfoBuffer))
|
||||
linkinfo.RootDirectory = parent.Fd()
|
||||
linkinfo.FileNameLength = uint32(len(newbase16) * 2)
|
||||
copy((*[32768]uint16)(unsafe.Pointer(&linkinfo.FileName[0]))[:], newbase16)
|
||||
|
||||
var iosb ioStatusBlock
|
||||
status := ntSetInformationFile(
|
||||
var iosb winapi.IOStatusBlock
|
||||
status := winapi.NtSetInformationFile(
|
||||
oldf.Fd(),
|
||||
&iosb,
|
||||
linkinfoBuffer,
|
||||
uint32(size),
|
||||
_FileLinkInformation,
|
||||
winapi.FileLinkInformationClass,
|
||||
)
|
||||
if status != 0 {
|
||||
return &os.LinkError{Op: "link", Old: oldf.Name(), New: filepath.Join(parent.Name(), newbase), Err: rtlNtStatusToDosError(status)}
|
||||
return &os.LinkError{Op: "link", Old: oldf.Name(), New: filepath.Join(parent.Name(), newbase), Err: winapi.RtlNtStatusToDosError(status)}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -252,17 +196,17 @@ func LinkRelative(oldname string, oldroot *os.File, newname string, newroot *os.
|
|||
|
||||
// deleteOnClose marks a file to be deleted when the handle is closed.
|
||||
func deleteOnClose(f *os.File) error {
|
||||
disposition := fileDispositionInformationEx{Flags: FILE_DISPOSITION_DELETE}
|
||||
var iosb ioStatusBlock
|
||||
status := ntSetInformationFile(
|
||||
disposition := winapi.FileDispositionInformationEx{Flags: winapi.FILE_DISPOSITION_DELETE}
|
||||
var iosb winapi.IOStatusBlock
|
||||
status := winapi.NtSetInformationFile(
|
||||
f.Fd(),
|
||||
&iosb,
|
||||
uintptr(unsafe.Pointer(&disposition)),
|
||||
uint32(unsafe.Sizeof(disposition)),
|
||||
_FileDispositionInformationEx,
|
||||
winapi.FileDispositionInformationExClass,
|
||||
)
|
||||
if status != 0 {
|
||||
return rtlNtStatusToDosError(status)
|
||||
return winapi.RtlNtStatusToDosError(status)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -291,10 +235,10 @@ func RemoveRelative(path string, root *os.File) error {
|
|||
f, err := openRelativeInternal(
|
||||
path,
|
||||
root,
|
||||
FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES|DELETE,
|
||||
winapi.FILE_READ_ATTRIBUTES|winapi.FILE_WRITE_ATTRIBUTES|winapi.DELETE,
|
||||
syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
|
||||
FILE_OPEN,
|
||||
FILE_OPEN_REPARSE_POINT)
|
||||
winapi.FILE_OPEN,
|
||||
winapi.FILE_OPEN_REPARSE_POINT)
|
||||
if err == nil {
|
||||
defer f.Close()
|
||||
err = deleteOnClose(f)
|
||||
|
|
@ -385,8 +329,8 @@ func MkdirRelative(path string, root *os.File) error {
|
|||
root,
|
||||
0,
|
||||
syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
|
||||
FILE_CREATE,
|
||||
FILE_DIRECTORY_FILE)
|
||||
winapi.FILE_CREATE,
|
||||
winapi.FILE_DIRECTORY_FILE)
|
||||
if err == nil {
|
||||
f.Close()
|
||||
} else {
|
||||
|
|
@ -401,10 +345,10 @@ func LstatRelative(path string, root *os.File) (os.FileInfo, error) {
|
|||
f, err := openRelativeInternal(
|
||||
path,
|
||||
root,
|
||||
FILE_READ_ATTRIBUTES,
|
||||
winapi.FILE_READ_ATTRIBUTES,
|
||||
syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
|
||||
FILE_OPEN,
|
||||
FILE_OPEN_REPARSE_POINT)
|
||||
winapi.FILE_OPEN,
|
||||
winapi.FILE_OPEN_REPARSE_POINT)
|
||||
if err != nil {
|
||||
return nil, &os.PathError{Op: "stat", Path: filepath.Join(root.Name(), path), Err: err}
|
||||
}
|
||||
|
|
@ -421,7 +365,7 @@ func EnsureNotReparsePointRelative(path string, root *os.File) error {
|
|||
root,
|
||||
0,
|
||||
syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
|
||||
FILE_OPEN,
|
||||
winapi.FILE_OPEN,
|
||||
0)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -1,79 +0,0 @@
|
|||
// Code generated by 'go generate'; DO NOT EDIT.
|
||||
|
||||
package safefile
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
// Do the interface allocations only once for common
|
||||
// Errno values.
|
||||
const (
|
||||
errnoERROR_IO_PENDING = 997
|
||||
)
|
||||
|
||||
var (
|
||||
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
|
||||
)
|
||||
|
||||
// errnoErr returns common boxed Errno values, to prevent
|
||||
// allocations at runtime.
|
||||
func errnoErr(e syscall.Errno) error {
|
||||
switch e {
|
||||
case 0:
|
||||
return nil
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
var (
|
||||
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
|
||||
procNtCreateFile = modntdll.NewProc("NtCreateFile")
|
||||
procNtSetInformationFile = modntdll.NewProc("NtSetInformationFile")
|
||||
procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
|
||||
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
||||
procLocalFree = modkernel32.NewProc("LocalFree")
|
||||
)
|
||||
|
||||
func ntCreateFile(handle *uintptr, accessMask uint32, oa *objectAttributes, iosb *ioStatusBlock, allocationSize *uint64, fileAttributes uint32, shareAccess uint32, createDisposition uint32, createOptions uint32, eaBuffer *byte, eaLength uint32) (status uint32) {
|
||||
r0, _, _ := syscall.Syscall12(procNtCreateFile.Addr(), 11, uintptr(unsafe.Pointer(handle)), uintptr(accessMask), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(allocationSize)), uintptr(fileAttributes), uintptr(shareAccess), uintptr(createDisposition), uintptr(createOptions), uintptr(unsafe.Pointer(eaBuffer)), uintptr(eaLength), 0)
|
||||
status = uint32(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func ntSetInformationFile(handle uintptr, iosb *ioStatusBlock, information uintptr, length uint32, class uint32) (status uint32) {
|
||||
r0, _, _ := syscall.Syscall6(procNtSetInformationFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(information), uintptr(length), uintptr(class), 0)
|
||||
status = uint32(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func rtlNtStatusToDosError(status uint32) (winerr error) {
|
||||
r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
|
||||
if r0 != 0 {
|
||||
winerr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func localAlloc(flags uint32, size int) (ptr uintptr) {
|
||||
r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(flags), uintptr(size), 0)
|
||||
ptr = uintptr(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func localFree(ptr uintptr) {
|
||||
syscall.Syscall(procLocalFree.Addr(), 1, uintptr(ptr), 0, 0)
|
||||
return
|
||||
}
|
||||
|
|
@ -22,6 +22,14 @@ go_library(
|
|||
"container_credential_guard_state.go",
|
||||
"container_credential_guard_system_info.go",
|
||||
"container_memory_information.go",
|
||||
"cpu_group.go",
|
||||
"cpu_group_affinity.go",
|
||||
"cpu_group_config.go",
|
||||
"cpu_group_configurations.go",
|
||||
"cpu_group_operations.go",
|
||||
"cpu_group_property.go",
|
||||
"create_group_operation.go",
|
||||
"delete_group_operation.go",
|
||||
"device.go",
|
||||
"devices.go",
|
||||
"enhanced_mode_video.go",
|
||||
|
|
@ -31,6 +39,7 @@ go_library(
|
|||
"guest_crash_reporting.go",
|
||||
"guest_os.go",
|
||||
"guest_state.go",
|
||||
"host_processor_modify_request.go",
|
||||
"hosted_system.go",
|
||||
"hv_socket.go",
|
||||
"hv_socket_2.go",
|
||||
|
|
@ -98,6 +107,7 @@ go_library(
|
|||
"virtual_smb_share.go",
|
||||
"virtual_smb_share_options.go",
|
||||
"vm_memory.go",
|
||||
"vm_processor_limits.go",
|
||||
"windows_crash_reporting.go",
|
||||
],
|
||||
importmap = "k8s.io/kops/vendor/github.com/Microsoft/hcsshim/internal/schema2",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* HCS API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
// CPU groups allow Hyper-V administrators to better manage and allocate the host's CPU resources across guest virtual machines
|
||||
type CpuGroup struct {
|
||||
Id string `json:"Id,omitempty"`
|
||||
}
|
||||
15
vendor/github.com/Microsoft/hcsshim/internal/schema2/cpu_group_affinity.go
generated
vendored
Normal file
15
vendor/github.com/Microsoft/hcsshim/internal/schema2/cpu_group_affinity.go
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* HCS API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type CpuGroupAffinity struct {
|
||||
LogicalProcessorCount int32 `json:"LogicalProcessorCount,omitempty"`
|
||||
LogicalProcessors []int32 `json:"LogicalProcessors,omitempty"`
|
||||
}
|
||||
18
vendor/github.com/Microsoft/hcsshim/internal/schema2/cpu_group_config.go
generated
vendored
Normal file
18
vendor/github.com/Microsoft/hcsshim/internal/schema2/cpu_group_config.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* HCS API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type CpuGroupConfig struct {
|
||||
GroupId string `json:"GroupId,omitempty"`
|
||||
Affinity *CpuGroupAffinity `json:"Affinity,omitempty"`
|
||||
GroupProperties []CpuGroupProperty `json:"GroupProperties,omitempty"`
|
||||
// Hypervisor CPU group IDs exposed to clients
|
||||
HypervisorGroupId int32 `json:"HypervisorGroupId,omitempty"`
|
||||
}
|
||||
15
vendor/github.com/Microsoft/hcsshim/internal/schema2/cpu_group_configurations.go
generated
vendored
Normal file
15
vendor/github.com/Microsoft/hcsshim/internal/schema2/cpu_group_configurations.go
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* HCS API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
// Structure used to return cpu groups for a Service property query
|
||||
type CpuGroupConfigurations struct {
|
||||
CpuGroups []CpuGroupConfig `json:"CpuGroups,omitempty"`
|
||||
}
|
||||
18
vendor/github.com/Microsoft/hcsshim/internal/schema2/cpu_group_operations.go
generated
vendored
Normal file
18
vendor/github.com/Microsoft/hcsshim/internal/schema2/cpu_group_operations.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* HCS API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type CPUGroupOperation string
|
||||
|
||||
const (
|
||||
CreateGroup CPUGroupOperation = "CreateGroup"
|
||||
DeleteGroup CPUGroupOperation = "DeleteGroup"
|
||||
SetProperty CPUGroupOperation = "SetProperty"
|
||||
)
|
||||
15
vendor/github.com/Microsoft/hcsshim/internal/schema2/cpu_group_property.go
generated
vendored
Normal file
15
vendor/github.com/Microsoft/hcsshim/internal/schema2/cpu_group_property.go
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* HCS API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
type CpuGroupProperty struct {
|
||||
PropertyCode uint32 `json:"PropertyCode,omitempty"`
|
||||
PropertyValue uint32 `json:"PropertyValue,omitempty"`
|
||||
}
|
||||
17
vendor/github.com/Microsoft/hcsshim/internal/schema2/create_group_operation.go
generated
vendored
Normal file
17
vendor/github.com/Microsoft/hcsshim/internal/schema2/create_group_operation.go
generated
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* HCS API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
// Create group operation settings
|
||||
type CreateGroupOperation struct {
|
||||
GroupId string `json:"GroupId,omitempty"`
|
||||
LogicalProcessorCount uint32 `json:"LogicalProcessorCount,omitempty"`
|
||||
LogicalProcessors []uint32 `json:"LogicalProcessors,omitempty"`
|
||||
}
|
||||
15
vendor/github.com/Microsoft/hcsshim/internal/schema2/delete_group_operation.go
generated
vendored
Normal file
15
vendor/github.com/Microsoft/hcsshim/internal/schema2/delete_group_operation.go
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* HCS API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
// Delete group operation settings
|
||||
type DeleteGroupOperation struct {
|
||||
GroupId string `json:"GroupId,omitempty"`
|
||||
}
|
||||
16
vendor/github.com/Microsoft/hcsshim/internal/schema2/host_processor_modify_request.go
generated
vendored
Normal file
16
vendor/github.com/Microsoft/hcsshim/internal/schema2/host_processor_modify_request.go
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* HCS API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
// Structure used to request a service processor modification
|
||||
type HostProcessorModificationRequest struct {
|
||||
Operation CPUGroupOperation `json:"Operation,omitempty"`
|
||||
OperationDetails interface{} `json:"OperationDetails,omitempty"`
|
||||
}
|
||||
6
vendor/github.com/Microsoft/hcsshim/internal/schema2/hv_socket_service_config.go
generated
vendored
6
vendor/github.com/Microsoft/hcsshim/internal/schema2/hv_socket_service_config.go
generated
vendored
|
|
@ -19,4 +19,10 @@ type HvSocketServiceConfig struct {
|
|||
|
||||
// If true, HvSocket will process wildcard binds for this service/system combination. Wildcard binds are secured in the registry at SOFTWARE/Microsoft/Windows NT/CurrentVersion/Virtualization/HvSocket/WildcardDescriptors
|
||||
AllowWildcardBinds bool `json:"AllowWildcardBinds,omitempty"`
|
||||
|
||||
// Disabled controls whether the HvSocket service is accepting connection requests.
|
||||
// This set to true will make the service refuse all incoming connections as well as cancel
|
||||
// any connections already established. The service itself will still be active however
|
||||
// and can be re-enabled at a future time.
|
||||
Disabled bool `json:"Disabled,omitempty"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
package hcsschema
|
||||
|
||||
type LogicalProcessor struct {
|
||||
LpIndex uint32 `json:"LogicalProcessorCount,omitempty"`
|
||||
LpIndex uint32 `json:"LpIndex,omitempty"`
|
||||
NodeNumber uint8 `json:"NodeNumber, omitempty"`
|
||||
PackageId uint32 `json:"PackageId, omitempty"`
|
||||
CoreId uint32 `json:"CoreId, omitempty"`
|
||||
|
|
|
|||
|
|
@ -10,5 +10,5 @@
|
|||
package hcsschema
|
||||
|
||||
type Memory struct {
|
||||
SizeInMB int32 `json:"SizeInMB,omitempty"`
|
||||
SizeInMB uint64 `json:"SizeInMB,omitempty"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
package hcsschema
|
||||
|
||||
type Memory2 struct {
|
||||
SizeInMB int32 `json:"SizeInMB,omitempty"`
|
||||
SizeInMB uint64 `json:"SizeInMB,omitempty"`
|
||||
|
||||
AllowOvercommit bool `json:"AllowOvercommit,omitempty"`
|
||||
|
||||
|
|
|
|||
|
|
@ -22,4 +22,5 @@ const (
|
|||
PTGuestConnection PropertyType = "GuestConnection"
|
||||
PTICHeartbeatStatus PropertyType = "ICHeartbeatStatus"
|
||||
PTProcessorTopology PropertyType = "ProcessorTopology"
|
||||
PTCPUGroup PropertyType = "CpuGroup"
|
||||
)
|
||||
|
|
|
|||
22
vendor/github.com/Microsoft/hcsshim/internal/schema2/vm_processor_limits.go
generated
vendored
Normal file
22
vendor/github.com/Microsoft/hcsshim/internal/schema2/vm_processor_limits.go
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* HCS API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.4
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
// ProcessorLimits is used when modifying processor scheduling limits of a virtual machine.
|
||||
type ProcessorLimits struct {
|
||||
// Maximum amount of host CPU resources that the virtual machine can use.
|
||||
Limit uint64 `json:"Limit,omitempty"`
|
||||
// Value describing the relative priority of this virtual machine compared to other virtual machines.
|
||||
Weight uint64 `json:"Weight,omitempty"`
|
||||
// Minimum amount of host CPU resources that the virtual machine is guaranteed.
|
||||
Reservation uint64 `json:"Reservation,omitempty"`
|
||||
// Provides the target maximum CPU frequency, in MHz, for a virtual machine.
|
||||
MaximumFrequencyMHz uint32 `json:"MaximumFrequencyMHz,omitempty"`
|
||||
}
|
||||
|
|
@ -38,6 +38,7 @@ go_library(
|
|||
"//vendor/github.com/Microsoft/hcsshim/internal/longpath:go_default_library",
|
||||
"//vendor/github.com/Microsoft/hcsshim/internal/oc:go_default_library",
|
||||
"//vendor/github.com/Microsoft/hcsshim/internal/safefile:go_default_library",
|
||||
"//vendor/github.com/Microsoft/hcsshim/internal/winapi:go_default_library",
|
||||
"//vendor/github.com/Microsoft/hcsshim/osversion:go_default_library",
|
||||
"//vendor/github.com/sirupsen/logrus:go_default_library",
|
||||
"//vendor/go.opencensus.io/trace:go_default_library",
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/Microsoft/hcsshim/internal/hcserror"
|
||||
"github.com/Microsoft/hcsshim/internal/oc"
|
||||
"github.com/Microsoft/hcsshim/internal/safefile"
|
||||
"github.com/Microsoft/hcsshim/internal/winapi"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
|
|
@ -37,7 +38,7 @@ type dirInfo struct {
|
|||
func reapplyDirectoryTimes(root *os.File, dis []dirInfo) error {
|
||||
for i := range dis {
|
||||
di := &dis[len(dis)-i-1] // reverse order: process child directories first
|
||||
f, err := safefile.OpenRelative(di.path, root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, safefile.FILE_OPEN, safefile.FILE_DIRECTORY_FILE|syscall.FILE_FLAG_OPEN_REPARSE_POINT)
|
||||
f, err := safefile.OpenRelative(di.path, root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, winapi.FILE_OPEN, winapi.FILE_DIRECTORY_FILE|syscall.FILE_FLAG_OPEN_REPARSE_POINT)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -93,12 +94,12 @@ func (w *baseLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) (err e
|
|||
|
||||
extraFlags := uint32(0)
|
||||
if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
|
||||
extraFlags |= safefile.FILE_DIRECTORY_FILE
|
||||
extraFlags |= winapi.FILE_DIRECTORY_FILE
|
||||
w.dirInfo = append(w.dirInfo, dirInfo{name, *fileInfo})
|
||||
}
|
||||
|
||||
mode := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | winio.WRITE_DAC | winio.WRITE_OWNER | winio.ACCESS_SYSTEM_SECURITY)
|
||||
f, err = safefile.OpenRelative(name, w.root, mode, syscall.FILE_SHARE_READ, safefile.FILE_CREATE, extraFlags)
|
||||
f, err = safefile.OpenRelative(name, w.root, mode, syscall.FILE_SHARE_READ, winapi.FILE_CREATE, extraFlags)
|
||||
if err != nil {
|
||||
return hcserror.New(err, "Failed to safefile.OpenRelative", name)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,7 @@ import (
|
|||
)
|
||||
|
||||
// CreateScratchLayer creates and populates new read-write layer for use by a container.
|
||||
// This requires both the id of the direct parent layer, as well as the full list
|
||||
// of paths to all parent layers up to the base (and including the direct parent
|
||||
// whose id was provided).
|
||||
// This requires the full list of paths to all parent layers up to the base
|
||||
func CreateScratchLayer(ctx context.Context, path string, parentLayerPaths []string) (err error) {
|
||||
title := "hcsshim::CreateScratchLayer"
|
||||
ctx, span := trace.StartSpan(ctx, title)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/Microsoft/go-winio"
|
||||
"github.com/Microsoft/hcsshim/internal/longpath"
|
||||
"github.com/Microsoft/hcsshim/internal/safefile"
|
||||
"github.com/Microsoft/hcsshim/internal/winapi"
|
||||
)
|
||||
|
||||
var errorIterationCanceled = errors.New("")
|
||||
|
|
@ -472,8 +473,8 @@ func copyFileWithMetadata(srcRoot, destRoot *os.File, subPath string, isDir bool
|
|||
srcRoot,
|
||||
syscall.GENERIC_READ|winio.ACCESS_SYSTEM_SECURITY,
|
||||
syscall.FILE_SHARE_READ,
|
||||
safefile.FILE_OPEN,
|
||||
safefile.FILE_OPEN_REPARSE_POINT)
|
||||
winapi.FILE_OPEN,
|
||||
winapi.FILE_OPEN_REPARSE_POINT)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -488,14 +489,14 @@ func copyFileWithMetadata(srcRoot, destRoot *os.File, subPath string, isDir bool
|
|||
|
||||
extraFlags := uint32(0)
|
||||
if isDir {
|
||||
extraFlags |= safefile.FILE_DIRECTORY_FILE
|
||||
extraFlags |= winapi.FILE_DIRECTORY_FILE
|
||||
}
|
||||
dest, err := safefile.OpenRelative(
|
||||
subPath,
|
||||
destRoot,
|
||||
syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY,
|
||||
syscall.FILE_SHARE_READ,
|
||||
safefile.FILE_CREATE,
|
||||
winapi.FILE_CREATE,
|
||||
extraFlags)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -595,7 +596,7 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
|
|||
if !hasPathPrefix(name, utilityVMFilesPath) && name != utilityVMFilesPath {
|
||||
return errors.New("invalid UtilityVM layer")
|
||||
}
|
||||
createDisposition := uint32(safefile.FILE_OPEN)
|
||||
createDisposition := uint32(winapi.FILE_OPEN)
|
||||
if (fileInfo.FileAttributes & syscall.FILE_ATTRIBUTE_DIRECTORY) != 0 {
|
||||
st, err := safefile.LstatRelative(name, w.destRoot)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
|
|
@ -622,7 +623,7 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
|
|||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
createDisposition = safefile.FILE_CREATE
|
||||
createDisposition = winapi.FILE_CREATE
|
||||
}
|
||||
|
||||
f, err := safefile.OpenRelative(
|
||||
|
|
@ -631,7 +632,7 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
|
|||
syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY,
|
||||
syscall.FILE_SHARE_READ,
|
||||
createDisposition,
|
||||
safefile.FILE_OPEN_REPARSE_POINT,
|
||||
winapi.FILE_OPEN_REPARSE_POINT,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -668,7 +669,7 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro
|
|||
w.currentIsDir = true
|
||||
}
|
||||
|
||||
f, err := safefile.OpenRelative(fname, w.root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, safefile.FILE_CREATE, 0)
|
||||
f, err := safefile.OpenRelative(fname, w.root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, winapi.FILE_CREATE, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// Package wclayer provides bindings to HCS's legacy layer management API and
|
||||
// provides a higher level interface around these calls for container layer
|
||||
// management.
|
||||
package wclayer
|
||||
|
||||
import "github.com/Microsoft/go-winio/pkg/guid"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"devices.go",
|
||||
"errors.go",
|
||||
"filesystem.go",
|
||||
"iocp.go",
|
||||
"jobobject.go",
|
||||
"logon.go",
|
||||
"memory.go",
|
||||
"net.go",
|
||||
"path.go",
|
||||
"process.go",
|
||||
"processor.go",
|
||||
"utils.go",
|
||||
"winapi.go",
|
||||
"zsyscall_windows.go",
|
||||
],
|
||||
importmap = "k8s.io/kops/vendor/github.com/Microsoft/hcsshim/internal/winapi",
|
||||
importpath = "github.com/Microsoft/hcsshim/internal/winapi",
|
||||
visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"],
|
||||
deps = [
|
||||
"//vendor/github.com/Microsoft/go-winio/pkg/guid:go_default_library",
|
||||
"//vendor/golang.org/x/sys/windows:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package winapi
|
||||
|
||||
import "github.com/Microsoft/go-winio/pkg/guid"
|
||||
|
||||
//sys CMGetDeviceIDListSize(pulLen *uint32, pszFilter *byte, uFlags uint32) (hr error) = cfgmgr32.CM_Get_Device_ID_List_SizeA
|
||||
//sys CMGetDeviceIDList(pszFilter *byte, buffer *byte, bufferLen uint32, uFlags uint32) (hr error)= cfgmgr32.CM_Get_Device_ID_ListA
|
||||
//sys CMLocateDevNode(pdnDevInst *uint32, pDeviceID string, uFlags uint32) (hr error) = cfgmgr32.CM_Locate_DevNodeW
|
||||
//sys CMGetDevNodeProperty(dnDevInst uint32, propertyKey *DevPropKey, propertyType *uint32, propertyBuffer *uint16, propertyBufferSize *uint32, uFlags uint32) (hr error) = cfgmgr32.CM_Get_DevNode_PropertyW
|
||||
|
||||
type DevPropKey struct {
|
||||
Fmtid guid.GUID
|
||||
Pid uint32
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package winapi
|
||||
|
||||
import "syscall"
|
||||
|
||||
//sys RtlNtStatusToDosError(status uint32) (winerr error) = ntdll.RtlNtStatusToDosError
|
||||
|
||||
const (
|
||||
STATUS_REPARSE_POINT_ENCOUNTERED = 0xC000050B
|
||||
ERROR_NO_MORE_ITEMS = 0x103
|
||||
ERROR_MORE_DATA syscall.Errno = 234
|
||||
)
|
||||
|
||||
func NTSuccess(status uint32) bool {
|
||||
return status == 0
|
||||
}
|
||||
110
vendor/github.com/Microsoft/hcsshim/internal/winapi/filesystem.go
generated
vendored
Normal file
110
vendor/github.com/Microsoft/hcsshim/internal/winapi/filesystem.go
generated
vendored
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
package winapi
|
||||
|
||||
//sys NtCreateFile(handle *uintptr, accessMask uint32, oa *ObjectAttributes, iosb *IOStatusBlock, allocationSize *uint64, fileAttributes uint32, shareAccess uint32, createDisposition uint32, createOptions uint32, eaBuffer *byte, eaLength uint32) (status uint32) = ntdll.NtCreateFile
|
||||
//sys NtSetInformationFile(handle uintptr, iosb *IOStatusBlock, information uintptr, length uint32, class uint32) (status uint32) = ntdll.NtSetInformationFile
|
||||
|
||||
//sys NtOpenDirectoryObject(handle *uintptr, accessMask uint32, oa *ObjectAttributes) (status uint32) = ntdll.NtOpenDirectoryObject
|
||||
//sys NtQueryDirectoryObject(handle uintptr, buffer *byte, length uint32, singleEntry bool, restartScan bool, context *uint32, returnLength *uint32)(status uint32) = ntdll.NtQueryDirectoryObject
|
||||
|
||||
const (
|
||||
FileLinkInformationClass = 11
|
||||
FileDispositionInformationExClass = 64
|
||||
|
||||
FILE_READ_ATTRIBUTES = 0x0080
|
||||
FILE_WRITE_ATTRIBUTES = 0x0100
|
||||
DELETE = 0x10000
|
||||
|
||||
FILE_OPEN = 1
|
||||
FILE_CREATE = 2
|
||||
|
||||
FILE_LIST_DIRECTORY = 0x00000001
|
||||
FILE_DIRECTORY_FILE = 0x00000001
|
||||
FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020
|
||||
FILE_OPEN_FOR_BACKUP_INTENT = 0x00004000
|
||||
FILE_OPEN_REPARSE_POINT = 0x00200000
|
||||
|
||||
FILE_DISPOSITION_DELETE = 0x00000001
|
||||
|
||||
OBJ_DONT_REPARSE = 0x1000
|
||||
|
||||
STATUS_MORE_ENTRIES = 0x105
|
||||
STATUS_NO_MORE_ENTRIES = 0x8000001a
|
||||
)
|
||||
|
||||
// Select entries from FILE_INFO_BY_HANDLE_CLASS.
|
||||
//
|
||||
// C declaration:
|
||||
// typedef enum _FILE_INFO_BY_HANDLE_CLASS {
|
||||
// FileBasicInfo,
|
||||
// FileStandardInfo,
|
||||
// FileNameInfo,
|
||||
// FileRenameInfo,
|
||||
// FileDispositionInfo,
|
||||
// FileAllocationInfo,
|
||||
// FileEndOfFileInfo,
|
||||
// FileStreamInfo,
|
||||
// FileCompressionInfo,
|
||||
// FileAttributeTagInfo,
|
||||
// FileIdBothDirectoryInfo,
|
||||
// FileIdBothDirectoryRestartInfo,
|
||||
// FileIoPriorityHintInfo,
|
||||
// FileRemoteProtocolInfo,
|
||||
// FileFullDirectoryInfo,
|
||||
// FileFullDirectoryRestartInfo,
|
||||
// FileStorageInfo,
|
||||
// FileAlignmentInfo,
|
||||
// FileIdInfo,
|
||||
// FileIdExtdDirectoryInfo,
|
||||
// FileIdExtdDirectoryRestartInfo,
|
||||
// FileDispositionInfoEx,
|
||||
// FileRenameInfoEx,
|
||||
// FileCaseSensitiveInfo,
|
||||
// FileNormalizedNameInfo,
|
||||
// MaximumFileInfoByHandleClass
|
||||
// } FILE_INFO_BY_HANDLE_CLASS, *PFILE_INFO_BY_HANDLE_CLASS;
|
||||
//
|
||||
// Documentation: https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ne-minwinbase-file_info_by_handle_class
|
||||
const (
|
||||
FileIdInfo = 18
|
||||
)
|
||||
|
||||
type FileDispositionInformationEx struct {
|
||||
Flags uintptr
|
||||
}
|
||||
|
||||
type IOStatusBlock struct {
|
||||
Status, Information uintptr
|
||||
}
|
||||
|
||||
type ObjectAttributes struct {
|
||||
Length uintptr
|
||||
RootDirectory uintptr
|
||||
ObjectName uintptr
|
||||
Attributes uintptr
|
||||
SecurityDescriptor uintptr
|
||||
SecurityQoS uintptr
|
||||
}
|
||||
|
||||
type ObjectDirectoryInformation struct {
|
||||
Name UnicodeString
|
||||
TypeName UnicodeString
|
||||
}
|
||||
|
||||
type FileLinkInformation struct {
|
||||
ReplaceIfExists bool
|
||||
RootDirectory uintptr
|
||||
FileNameLength uint32
|
||||
FileName [1]uint16
|
||||
}
|
||||
|
||||
// C declaration:
|
||||
// typedef struct _FILE_ID_INFO {
|
||||
// ULONGLONG VolumeSerialNumber;
|
||||
// FILE_ID_128 FileId;
|
||||
// } FILE_ID_INFO, *PFILE_ID_INFO;
|
||||
//
|
||||
// Documentation: https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_id_info
|
||||
type FILE_ID_INFO struct {
|
||||
VolumeSerialNumber uint64
|
||||
FileID [16]byte
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package winapi
|
||||
|
||||
//sys GetQueuedCompletionStatus(cphandle windows.Handle, qty *uint32, key *uintptr, overlapped **windows.Overlapped, timeout uint32) (err error)
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
package winapi
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// Messages that can be received from an assigned io completion port.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_associate_completion_port
|
||||
const (
|
||||
JOB_OBJECT_MSG_END_OF_JOB_TIME uint32 = 1
|
||||
JOB_OBJECT_MSG_END_OF_PROCESS_TIME uint32 = 2
|
||||
JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT uint32 = 3
|
||||
JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO uint32 = 4
|
||||
JOB_OBJECT_MSG_NEW_PROCESS uint32 = 6
|
||||
JOB_OBJECT_MSG_EXIT_PROCESS uint32 = 7
|
||||
JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS uint32 = 8
|
||||
JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT uint32 = 9
|
||||
JOB_OBJECT_MSG_JOB_MEMORY_LIMIT uint32 = 10
|
||||
JOB_OBJECT_MSG_NOTIFICATION_LIMIT uint32 = 11
|
||||
)
|
||||
|
||||
// IO limit flags
|
||||
//
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/jobapi2/ns-jobapi2-jobobject_io_rate_control_information
|
||||
const JOB_OBJECT_IO_RATE_CONTROL_ENABLE = 0x1
|
||||
|
||||
const JOBOBJECT_IO_ATTRIBUTION_CONTROL_ENABLE uint32 = 0x1
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_cpu_rate_control_information
|
||||
const (
|
||||
JOB_OBJECT_CPU_RATE_CONTROL_ENABLE uint32 = 1 << iota
|
||||
JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED
|
||||
JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP
|
||||
JOB_OBJECT_CPU_RATE_CONTROL_NOTIFY
|
||||
JOB_OBJECT_CPU_RATE_CONTROL_MIN_MAX_RATE
|
||||
)
|
||||
|
||||
// JobObjectInformationClass values. Used for a call to QueryInformationJobObject
|
||||
//
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/jobapi2/nf-jobapi2-queryinformationjobobject
|
||||
const (
|
||||
JobObjectBasicAccountingInformation uint32 = 1
|
||||
JobObjectBasicProcessIdList uint32 = 3
|
||||
JobObjectBasicAndIoAccountingInformation uint32 = 8
|
||||
JobObjectLimitViolationInformation uint32 = 13
|
||||
JobObjectMemoryUsageInformation uint32 = 28
|
||||
JobObjectNotificationLimitInformation2 uint32 = 33
|
||||
JobObjectIoAttribution uint32 = 42
|
||||
)
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_basic_limit_information
|
||||
type JOBOBJECT_BASIC_LIMIT_INFORMATION struct {
|
||||
PerProcessUserTimeLimit int64
|
||||
PerJobUserTimeLimit int64
|
||||
LimitFlags uint32
|
||||
MinimumWorkingSetSize uintptr
|
||||
MaximumWorkingSetSize uintptr
|
||||
ActiveProcessLimit uint32
|
||||
Affinity uintptr
|
||||
PriorityClass uint32
|
||||
SchedulingClass uint32
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_cpu_rate_control_information
|
||||
type JOBOBJECT_CPU_RATE_CONTROL_INFORMATION struct {
|
||||
ControlFlags uint32
|
||||
Value uint32
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/jobapi2/ns-jobapi2-jobobject_io_rate_control_information
|
||||
type JOBOBJECT_IO_RATE_CONTROL_INFORMATION struct {
|
||||
MaxIops int64
|
||||
MaxBandwidth int64
|
||||
ReservationIops int64
|
||||
BaseIOSize uint32
|
||||
VolumeName string
|
||||
ControlFlags uint32
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_basic_process_id_list
|
||||
type JOBOBJECT_BASIC_PROCESS_ID_LIST struct {
|
||||
NumberOfAssignedProcesses uint32
|
||||
NumberOfProcessIdsInList uint32
|
||||
ProcessIdList [1]uintptr
|
||||
}
|
||||
|
||||
// AllPids returns all the process Ids in the job object.
|
||||
func (p *JOBOBJECT_BASIC_PROCESS_ID_LIST) AllPids() []uintptr {
|
||||
return (*[(1 << 27) - 1]uintptr)(unsafe.Pointer(&p.ProcessIdList[0]))[:p.NumberOfProcessIdsInList]
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_basic_accounting_information
|
||||
type JOBOBJECT_BASIC_ACCOUNTING_INFORMATION struct {
|
||||
TotalUserTime int64
|
||||
TotalKernelTime int64
|
||||
ThisPeriodTotalUserTime int64
|
||||
ThisPeriodTotalKernelTime int64
|
||||
TotalPageFaultCount uint32
|
||||
TotalProcesses uint32
|
||||
ActiveProcesses uint32
|
||||
TotalTerminateProcesses uint32
|
||||
}
|
||||
|
||||
//https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_basic_and_io_accounting_information
|
||||
type JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION struct {
|
||||
BasicInfo JOBOBJECT_BASIC_ACCOUNTING_INFORMATION
|
||||
IoInfo windows.IO_COUNTERS
|
||||
}
|
||||
|
||||
// typedef struct _JOBOBJECT_MEMORY_USAGE_INFORMATION {
|
||||
// ULONG64 JobMemory;
|
||||
// ULONG64 PeakJobMemoryUsed;
|
||||
// } JOBOBJECT_MEMORY_USAGE_INFORMATION, *PJOBOBJECT_MEMORY_USAGE_INFORMATION;
|
||||
//
|
||||
type JOBOBJECT_MEMORY_USAGE_INFORMATION struct {
|
||||
JobMemory uint64
|
||||
PeakJobMemoryUsed uint64
|
||||
}
|
||||
|
||||
// typedef struct _JOBOBJECT_IO_ATTRIBUTION_STATS {
|
||||
// ULONG_PTR IoCount;
|
||||
// ULONGLONG TotalNonOverlappedQueueTime;
|
||||
// ULONGLONG TotalNonOverlappedServiceTime;
|
||||
// ULONGLONG TotalSize;
|
||||
// } JOBOBJECT_IO_ATTRIBUTION_STATS, *PJOBOBJECT_IO_ATTRIBUTION_STATS;
|
||||
//
|
||||
type JOBOBJECT_IO_ATTRIBUTION_STATS struct {
|
||||
IoCount uintptr
|
||||
TotalNonOverlappedQueueTime uint64
|
||||
TotalNonOverlappedServiceTime uint64
|
||||
TotalSize uint64
|
||||
}
|
||||
|
||||
// typedef struct _JOBOBJECT_IO_ATTRIBUTION_INFORMATION {
|
||||
// ULONG ControlFlags;
|
||||
// JOBOBJECT_IO_ATTRIBUTION_STATS ReadStats;
|
||||
// JOBOBJECT_IO_ATTRIBUTION_STATS WriteStats;
|
||||
// } JOBOBJECT_IO_ATTRIBUTION_INFORMATION, *PJOBOBJECT_IO_ATTRIBUTION_INFORMATION;
|
||||
//
|
||||
type JOBOBJECT_IO_ATTRIBUTION_INFORMATION struct {
|
||||
ControlFlags uint32
|
||||
ReadStats JOBOBJECT_IO_ATTRIBUTION_STATS
|
||||
WriteStats JOBOBJECT_IO_ATTRIBUTION_STATS
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_associate_completion_port
|
||||
type JOBOBJECT_ASSOCIATE_COMPLETION_PORT struct {
|
||||
CompletionKey windows.Handle
|
||||
CompletionPort windows.Handle
|
||||
}
|
||||
|
||||
// BOOL IsProcessInJob(
|
||||
// HANDLE ProcessHandle,
|
||||
// HANDLE JobHandle,
|
||||
// PBOOL Result
|
||||
// );
|
||||
//
|
||||
//sys IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result *bool) (err error) = kernel32.IsProcessInJob
|
||||
|
||||
// BOOL QueryInformationJobObject(
|
||||
// HANDLE hJob,
|
||||
// JOBOBJECTINFOCLASS JobObjectInformationClass,
|
||||
// LPVOID lpJobObjectInformation,
|
||||
// DWORD cbJobObjectInformationLength,
|
||||
// LPDWORD lpReturnLength
|
||||
// );
|
||||
//
|
||||
//sys QueryInformationJobObject(jobHandle windows.Handle, infoClass uint32, jobObjectInfo uintptr, jobObjectInformationLength uint32, lpReturnLength *uint32) (err error) = kernel32.QueryInformationJobObject
|
||||
|
||||
// HANDLE OpenJobObjectW(
|
||||
// DWORD dwDesiredAccess,
|
||||
// BOOL bInheritHandle,
|
||||
// LPCWSTR lpName
|
||||
// );
|
||||
//
|
||||
//sys OpenJobObject(desiredAccess uint32, inheritHandle bool, lpName *uint16) (handle windows.Handle, err error) = kernel32.OpenJobObjectW
|
||||
|
||||
// DWORD SetIoRateControlInformationJobObject(
|
||||
// HANDLE hJob,
|
||||
// JOBOBJECT_IO_RATE_CONTROL_INFORMATION *IoRateControlInfo
|
||||
// );
|
||||
//
|
||||
//sys SetIoRateControlInformationJobObject(jobHandle windows.Handle, ioRateControlInfo *JOBOBJECT_IO_RATE_CONTROL_INFORMATION) (ret uint32, err error) = kernel32.SetIoRateControlInformationJobObject
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package winapi
|
||||
|
||||
// BOOL LogonUserA(
|
||||
// LPCWSTR lpszUsername,
|
||||
// LPCWSTR lpszDomain,
|
||||
// LPCWSTR lpszPassword,
|
||||
// DWORD dwLogonType,
|
||||
// DWORD dwLogonProvider,
|
||||
// PHANDLE phToken
|
||||
// );
|
||||
//
|
||||
//sys LogonUser(username *uint16, domain *uint16, password *uint16, logonType uint32, logonProvider uint32, token *windows.Token) (err error) = advapi32.LogonUserW
|
||||
|
||||
// Logon types
|
||||
const (
|
||||
LOGON32_LOGON_INTERACTIVE uint32 = 2
|
||||
LOGON32_LOGON_NETWORK uint32 = 3
|
||||
LOGON32_LOGON_BATCH uint32 = 4
|
||||
LOGON32_LOGON_SERVICE uint32 = 5
|
||||
LOGON32_LOGON_UNLOCK uint32 = 7
|
||||
LOGON32_LOGON_NETWORK_CLEARTEXT uint32 = 8
|
||||
LOGON32_LOGON_NEW_CREDENTIALS uint32 = 9
|
||||
)
|
||||
|
||||
// Logon providers
|
||||
const (
|
||||
LOGON32_PROVIDER_DEFAULT uint32 = 0
|
||||
LOGON32_PROVIDER_WINNT40 uint32 = 2
|
||||
LOGON32_PROVIDER_WINNT50 uint32 = 3
|
||||
)
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package winapi
|
||||
|
||||
// VOID RtlMoveMemory(
|
||||
// _Out_ VOID UNALIGNED *Destination,
|
||||
// _In_ const VOID UNALIGNED *Source,
|
||||
// _In_ SIZE_T Length
|
||||
// );
|
||||
//sys RtlMoveMemory(destination *byte, source *byte, length uintptr) (err error) = kernel32.RtlMoveMemory
|
||||
|
||||
//sys LocalAlloc(flags uint32, size int) (ptr uintptr) = kernel32.LocalAlloc
|
||||
//sys LocalFree(ptr uintptr) = kernel32.LocalFree
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package winapi
|
||||
|
||||
//sys SetJobCompartmentId(handle windows.Handle, compartmentId uint32) (win32Err error) = iphlpapi.SetJobCompartmentId
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package winapi
|
||||
|
||||
// DWORD SearchPathW(
|
||||
// LPCWSTR lpPath,
|
||||
// LPCWSTR lpFileName,
|
||||
// LPCWSTR lpExtension,
|
||||
// DWORD nBufferLength,
|
||||
// LPWSTR lpBuffer,
|
||||
// LPWSTR *lpFilePart
|
||||
// );
|
||||
//sys SearchPath(lpPath *uint16, lpFileName *uint16, lpExtension *uint16, nBufferLength uint32, lpBuffer *uint16, lpFilePath **uint16) (size uint32, err error) = kernel32.SearchPathW
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package winapi
|
||||
|
||||
const PROCESS_ALL_ACCESS uint32 = 2097151
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package winapi
|
||||
|
||||
// Get count from all processor groups.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/procthread/processor-groups
|
||||
const ALL_PROCESSOR_GROUPS = 0xFFFF
|
||||
|
||||
//sys GetActiveProcessorCount(groupNumber uint16) (amount uint32) = kernel32.GetActiveProcessorCount
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package winapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type UnicodeString struct {
|
||||
Length uint16
|
||||
MaximumLength uint16
|
||||
Buffer *uint16
|
||||
}
|
||||
|
||||
//String converts a UnicodeString to a golang string
|
||||
func (uni UnicodeString) String() string {
|
||||
p := (*[0xffff]uint16)(unsafe.Pointer(uni.Buffer))
|
||||
|
||||
// UnicodeString is not guaranteed to be null terminated, therefore
|
||||
// use the UnicodeString's Length field
|
||||
lengthInChars := uni.Length / 2
|
||||
return syscall.UTF16ToString(p[:lengthInChars])
|
||||
}
|
||||
|
||||
// NewUnicodeString allocates a new UnicodeString and copies `s` into
|
||||
// the buffer of the new UnicodeString.
|
||||
func NewUnicodeString(s string) (*UnicodeString, error) {
|
||||
ws := utf16.Encode(([]rune)(s))
|
||||
if len(ws) > 32767 {
|
||||
return nil, syscall.ENAMETOOLONG
|
||||
}
|
||||
|
||||
uni := &UnicodeString{
|
||||
Length: uint16(len(ws) * 2),
|
||||
MaximumLength: uint16(len(ws) * 2),
|
||||
Buffer: &make([]uint16, len(ws))[0],
|
||||
}
|
||||
copy((*[32768]uint16)(unsafe.Pointer(uni.Buffer))[:], ws)
|
||||
return uni, nil
|
||||
}
|
||||
|
||||
// ConvertStringSetToSlice is a helper function used to convert the contents of
|
||||
// `buf` into a string slice. `buf` contains a set of null terminated strings
|
||||
// with an additional null at the end to indicate the end of the set.
|
||||
func ConvertStringSetToSlice(buf []byte) ([]string, error) {
|
||||
var results []string
|
||||
prev := 0
|
||||
for i := range buf {
|
||||
if buf[i] == 0 {
|
||||
if prev == i {
|
||||
// found two null characters in a row, return result
|
||||
return results, nil
|
||||
}
|
||||
results = append(results, string(buf[prev:i]))
|
||||
prev = i + 1
|
||||
}
|
||||
}
|
||||
return nil, errors.New("string set malformed: missing null terminator at end of buffer")
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
// Package winapi contains various low-level bindings to Windows APIs. It can
|
||||
// be thought of as an extension to golang.org/x/sys/windows.
|
||||
package winapi
|
||||
|
||||
//go:generate go run ..\..\mksyscall_windows.go -output zsyscall_windows.go net.go iocp.go jobobject.go path.go logon.go memory.go processor.go devices.go filesystem.go errors.go
|
||||
294
vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go
generated
vendored
Normal file
294
vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go
generated
vendored
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
// Code generated mksyscall_windows.exe DO NOT EDIT
|
||||
|
||||
package winapi
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
// Do the interface allocations only once for common
|
||||
// Errno values.
|
||||
const (
|
||||
errnoERROR_IO_PENDING = 997
|
||||
)
|
||||
|
||||
var (
|
||||
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
|
||||
)
|
||||
|
||||
// errnoErr returns common boxed Errno values, to prevent
|
||||
// allocations at runtime.
|
||||
func errnoErr(e syscall.Errno) error {
|
||||
switch e {
|
||||
case 0:
|
||||
return nil
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
var (
|
||||
modiphlpapi = windows.NewLazySystemDLL("iphlpapi.dll")
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||
modcfgmgr32 = windows.NewLazySystemDLL("cfgmgr32.dll")
|
||||
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||
|
||||
procSetJobCompartmentId = modiphlpapi.NewProc("SetJobCompartmentId")
|
||||
procIsProcessInJob = modkernel32.NewProc("IsProcessInJob")
|
||||
procQueryInformationJobObject = modkernel32.NewProc("QueryInformationJobObject")
|
||||
procOpenJobObjectW = modkernel32.NewProc("OpenJobObjectW")
|
||||
procSetIoRateControlInformationJobObject = modkernel32.NewProc("SetIoRateControlInformationJobObject")
|
||||
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
||||
procSearchPathW = modkernel32.NewProc("SearchPathW")
|
||||
procLogonUserW = modadvapi32.NewProc("LogonUserW")
|
||||
procRtlMoveMemory = modkernel32.NewProc("RtlMoveMemory")
|
||||
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
||||
procLocalFree = modkernel32.NewProc("LocalFree")
|
||||
procGetActiveProcessorCount = modkernel32.NewProc("GetActiveProcessorCount")
|
||||
procCM_Get_Device_ID_List_SizeA = modcfgmgr32.NewProc("CM_Get_Device_ID_List_SizeA")
|
||||
procCM_Get_Device_ID_ListA = modcfgmgr32.NewProc("CM_Get_Device_ID_ListA")
|
||||
procCM_Locate_DevNodeW = modcfgmgr32.NewProc("CM_Locate_DevNodeW")
|
||||
procCM_Get_DevNode_PropertyW = modcfgmgr32.NewProc("CM_Get_DevNode_PropertyW")
|
||||
procNtCreateFile = modntdll.NewProc("NtCreateFile")
|
||||
procNtSetInformationFile = modntdll.NewProc("NtSetInformationFile")
|
||||
procNtOpenDirectoryObject = modntdll.NewProc("NtOpenDirectoryObject")
|
||||
procNtQueryDirectoryObject = modntdll.NewProc("NtQueryDirectoryObject")
|
||||
procRtlNtStatusToDosError = modntdll.NewProc("RtlNtStatusToDosError")
|
||||
)
|
||||
|
||||
func SetJobCompartmentId(handle windows.Handle, compartmentId uint32) (win32Err error) {
|
||||
r0, _, _ := syscall.Syscall(procSetJobCompartmentId.Addr(), 2, uintptr(handle), uintptr(compartmentId), 0)
|
||||
if r0 != 0 {
|
||||
win32Err = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result *bool) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procIsProcessInJob.Addr(), 3, uintptr(procHandle), uintptr(jobHandle), uintptr(unsafe.Pointer(result)))
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func QueryInformationJobObject(jobHandle windows.Handle, infoClass uint32, jobObjectInfo uintptr, jobObjectInformationLength uint32, lpReturnLength *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procQueryInformationJobObject.Addr(), 5, uintptr(jobHandle), uintptr(infoClass), uintptr(jobObjectInfo), uintptr(jobObjectInformationLength), uintptr(unsafe.Pointer(lpReturnLength)), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func OpenJobObject(desiredAccess uint32, inheritHandle bool, lpName *uint16) (handle windows.Handle, err error) {
|
||||
var _p0 uint32
|
||||
if inheritHandle {
|
||||
_p0 = 1
|
||||
} else {
|
||||
_p0 = 0
|
||||
}
|
||||
r0, _, e1 := syscall.Syscall(procOpenJobObjectW.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(lpName)))
|
||||
handle = windows.Handle(r0)
|
||||
if handle == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SetIoRateControlInformationJobObject(jobHandle windows.Handle, ioRateControlInfo *JOBOBJECT_IO_RATE_CONTROL_INFORMATION) (ret uint32, err error) {
|
||||
r0, _, e1 := syscall.Syscall(procSetIoRateControlInformationJobObject.Addr(), 2, uintptr(jobHandle), uintptr(unsafe.Pointer(ioRateControlInfo)), 0)
|
||||
ret = uint32(r0)
|
||||
if ret == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetQueuedCompletionStatus(cphandle windows.Handle, qty *uint32, key *uintptr, overlapped **windows.Overlapped, timeout uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0)
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SearchPath(lpPath *uint16, lpFileName *uint16, lpExtension *uint16, nBufferLength uint32, lpBuffer *uint16, lpFilePath **uint16) (size uint32, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(procSearchPathW.Addr(), 6, uintptr(unsafe.Pointer(lpPath)), uintptr(unsafe.Pointer(lpFileName)), uintptr(unsafe.Pointer(lpExtension)), uintptr(nBufferLength), uintptr(unsafe.Pointer(lpBuffer)), uintptr(unsafe.Pointer(lpFilePath)))
|
||||
size = uint32(r0)
|
||||
if size == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func LogonUser(username *uint16, domain *uint16, password *uint16, logonType uint32, logonProvider uint32, token *windows.Token) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procLogonUserW.Addr(), 6, uintptr(unsafe.Pointer(username)), uintptr(unsafe.Pointer(domain)), uintptr(unsafe.Pointer(password)), uintptr(logonType), uintptr(logonProvider), uintptr(unsafe.Pointer(token)))
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func RtlMoveMemory(destination *byte, source *byte, length uintptr) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procRtlMoveMemory.Addr(), 3, uintptr(unsafe.Pointer(destination)), uintptr(unsafe.Pointer(source)), uintptr(length))
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func LocalAlloc(flags uint32, size int) (ptr uintptr) {
|
||||
r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(flags), uintptr(size), 0)
|
||||
ptr = uintptr(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func LocalFree(ptr uintptr) {
|
||||
syscall.Syscall(procLocalFree.Addr(), 1, uintptr(ptr), 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func GetActiveProcessorCount(groupNumber uint16) (amount uint32) {
|
||||
r0, _, _ := syscall.Syscall(procGetActiveProcessorCount.Addr(), 1, uintptr(groupNumber), 0, 0)
|
||||
amount = uint32(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func CMGetDeviceIDListSize(pulLen *uint32, pszFilter *byte, uFlags uint32) (hr error) {
|
||||
r0, _, _ := syscall.Syscall(procCM_Get_Device_ID_List_SizeA.Addr(), 3, uintptr(unsafe.Pointer(pulLen)), uintptr(unsafe.Pointer(pszFilter)), uintptr(uFlags))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func CMGetDeviceIDList(pszFilter *byte, buffer *byte, bufferLen uint32, uFlags uint32) (hr error) {
|
||||
r0, _, _ := syscall.Syscall6(procCM_Get_Device_ID_ListA.Addr(), 4, uintptr(unsafe.Pointer(pszFilter)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferLen), uintptr(uFlags), 0, 0)
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func CMLocateDevNode(pdnDevInst *uint32, pDeviceID string, uFlags uint32) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(pDeviceID)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _CMLocateDevNode(pdnDevInst, _p0, uFlags)
|
||||
}
|
||||
|
||||
func _CMLocateDevNode(pdnDevInst *uint32, pDeviceID *uint16, uFlags uint32) (hr error) {
|
||||
r0, _, _ := syscall.Syscall(procCM_Locate_DevNodeW.Addr(), 3, uintptr(unsafe.Pointer(pdnDevInst)), uintptr(unsafe.Pointer(pDeviceID)), uintptr(uFlags))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func CMGetDevNodeProperty(dnDevInst uint32, propertyKey *DevPropKey, propertyType *uint32, propertyBuffer *uint16, propertyBufferSize *uint32, uFlags uint32) (hr error) {
|
||||
r0, _, _ := syscall.Syscall6(procCM_Get_DevNode_PropertyW.Addr(), 6, uintptr(dnDevInst), uintptr(unsafe.Pointer(propertyKey)), uintptr(unsafe.Pointer(propertyType)), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(unsafe.Pointer(propertyBufferSize)), uintptr(uFlags))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func NtCreateFile(handle *uintptr, accessMask uint32, oa *ObjectAttributes, iosb *IOStatusBlock, allocationSize *uint64, fileAttributes uint32, shareAccess uint32, createDisposition uint32, createOptions uint32, eaBuffer *byte, eaLength uint32) (status uint32) {
|
||||
r0, _, _ := syscall.Syscall12(procNtCreateFile.Addr(), 11, uintptr(unsafe.Pointer(handle)), uintptr(accessMask), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(allocationSize)), uintptr(fileAttributes), uintptr(shareAccess), uintptr(createDisposition), uintptr(createOptions), uintptr(unsafe.Pointer(eaBuffer)), uintptr(eaLength), 0)
|
||||
status = uint32(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func NtSetInformationFile(handle uintptr, iosb *IOStatusBlock, information uintptr, length uint32, class uint32) (status uint32) {
|
||||
r0, _, _ := syscall.Syscall6(procNtSetInformationFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(information), uintptr(length), uintptr(class), 0)
|
||||
status = uint32(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func NtOpenDirectoryObject(handle *uintptr, accessMask uint32, oa *ObjectAttributes) (status uint32) {
|
||||
r0, _, _ := syscall.Syscall(procNtOpenDirectoryObject.Addr(), 3, uintptr(unsafe.Pointer(handle)), uintptr(accessMask), uintptr(unsafe.Pointer(oa)))
|
||||
status = uint32(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func NtQueryDirectoryObject(handle uintptr, buffer *byte, length uint32, singleEntry bool, restartScan bool, context *uint32, returnLength *uint32) (status uint32) {
|
||||
var _p0 uint32
|
||||
if singleEntry {
|
||||
_p0 = 1
|
||||
} else {
|
||||
_p0 = 0
|
||||
}
|
||||
var _p1 uint32
|
||||
if restartScan {
|
||||
_p1 = 1
|
||||
} else {
|
||||
_p1 = 0
|
||||
}
|
||||
r0, _, _ := syscall.Syscall9(procNtQueryDirectoryObject.Addr(), 7, uintptr(handle), uintptr(unsafe.Pointer(buffer)), uintptr(length), uintptr(_p0), uintptr(_p1), uintptr(unsafe.Pointer(context)), uintptr(unsafe.Pointer(returnLength)), 0, 0)
|
||||
status = uint32(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func RtlNtStatusToDosError(status uint32) (winerr error) {
|
||||
r0, _, _ := syscall.Syscall(procRtlNtStatusToDosError.Addr(), 1, uintptr(status), 0, 0)
|
||||
if r0 != 0 {
|
||||
winerr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
@ -24,4 +24,15 @@ const (
|
|||
// V19H1 (version 1903) corresponds to Windows Server 1903 (semi-annual
|
||||
// channel).
|
||||
V19H1 = 18362
|
||||
|
||||
// V19H2 (version 1909) corresponds to Windows Server 1909 (semi-annual
|
||||
// channel).
|
||||
V19H2 = 18363
|
||||
|
||||
// V20H1 (version 2004) corresponds to Windows Server 2004 (semi-annual
|
||||
// channel).
|
||||
V20H1 = 19041
|
||||
|
||||
// V20H2 corresponds to Windows Server 20H2 (semi-annual channel).
|
||||
V20H2 = 19042
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,15 +21,7 @@ type Client struct {
|
|||
// Credentials are read from the first config and fall backs to next.
|
||||
// All changes will only be written to the first config file.
|
||||
func NewClient(configPaths ...string) (auth.Client, error) {
|
||||
var configs []*configfile.ConfigFile
|
||||
for _, path := range configPaths {
|
||||
cfg, err := loadConfigFile(path)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, path)
|
||||
}
|
||||
configs = append(configs, cfg)
|
||||
}
|
||||
if len(configs) == 0 {
|
||||
if len(configPaths) == 0 {
|
||||
cfg, err := config.Load(config.Dir())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -37,7 +29,19 @@ func NewClient(configPaths ...string) (auth.Client, error) {
|
|||
if !cfg.ContainsAuth() {
|
||||
cfg.CredentialsStore = credentials.DetectDefaultStore(cfg.CredentialsStore)
|
||||
}
|
||||
configs = []*configfile.ConfigFile{cfg}
|
||||
|
||||
return &Client{
|
||||
configs: []*configfile.ConfigFile{cfg},
|
||||
}, nil
|
||||
}
|
||||
|
||||
var configs []*configfile.ConfigFile
|
||||
for _, path := range configPaths {
|
||||
cfg, err := loadConfigFile(path)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, path)
|
||||
}
|
||||
configs = append(configs, cfg)
|
||||
}
|
||||
|
||||
return &Client{
|
||||
|
|
|
|||
|
|
@ -4,12 +4,20 @@ go_library(
|
|||
name = "go_default_library",
|
||||
srcs = [
|
||||
"consts.go",
|
||||
"decompressstore.go",
|
||||
"errors.go",
|
||||
"file.go",
|
||||
"gunzip.go",
|
||||
"interface.go",
|
||||
"iowriter.go",
|
||||
"memory.go",
|
||||
"multireader.go",
|
||||
"multiwriter.go",
|
||||
"oci.go",
|
||||
"opts.go",
|
||||
"passthrough.go",
|
||||
"readerat.go",
|
||||
"untar.go",
|
||||
"utils.go",
|
||||
],
|
||||
importmap = "k8s.io/kops/vendor/github.com/deislabs/oras/pkg/content",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
package content
|
||||
|
||||
import ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
import (
|
||||
"github.com/opencontainers/go-digest"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultBlobMediaType specifies the default blob media type
|
||||
|
|
@ -26,3 +29,14 @@ const (
|
|||
// Reference: https://github.com/opencontainers/image-spec/blob/master/image-layout.md#indexjson-file
|
||||
OCIImageIndexFile = "index.json"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultBlocksize default size of each slice of bytes read in each write through in gunzipand untar.
|
||||
// Simply uses the same size as io.Copy()
|
||||
DefaultBlocksize = 32768
|
||||
)
|
||||
|
||||
const (
|
||||
// what you get for a blank digest
|
||||
BlankHash = digest.Digest("sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,143 @@
|
|||
package content
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
ctrcontent "github.com/containerd/containerd/content"
|
||||
)
|
||||
|
||||
// DecompressStore store to decompress content and extract from tar, if needed, wrapping
|
||||
// another store. By default, a FileStore will simply take each artifact and write it to
|
||||
// a file, as a MemoryStore will do into memory. If the artifact is gzipped or tarred,
|
||||
// you might want to store the actual object inside tar or gzip. Wrap your Store
|
||||
// with DecompressStore, and it will check the media-type and, if relevant,
|
||||
// gunzip and/or untar.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// fileStore := NewFileStore(rootPath)
|
||||
// decompressStore := store.NewDecompressStore(fileStore, WithBlocksize(blocksize))
|
||||
//
|
||||
// The above example works if there is no tar, i.e. each artifact is just a single file, perhaps gzipped,
|
||||
// or if there is only one file in each tar archive. In other words, when each content.Writer has only one target output stream.
|
||||
// However, if you have multiple files in each tar archive, each archive of which is an artifact layer, then
|
||||
// you need a way to select how to handle each file in the tar archive. In other words, when each content.Writer has more than one
|
||||
// target output stream. In that case, use the following example:
|
||||
//
|
||||
// multiStore := NewMultiStore(rootPath) // some store that can handle different filenames
|
||||
// decompressStore := store.NewDecompressStore(multiStore, WithBlocksize(blocksize), WithMultiWriterIngester())
|
||||
//
|
||||
type DecompressStore struct {
|
||||
ingester ctrcontent.Ingester
|
||||
blocksize int
|
||||
multiWriterIngester bool
|
||||
}
|
||||
|
||||
func NewDecompressStore(ingester ctrcontent.Ingester, opts ...WriterOpt) DecompressStore {
|
||||
// we have to reprocess the opts to find the blocksize
|
||||
var wOpts WriterOpts
|
||||
for _, opt := range opts {
|
||||
if err := opt(&wOpts); err != nil {
|
||||
// TODO: we probably should handle errors here
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return DecompressStore{ingester, wOpts.Blocksize, wOpts.MultiWriterIngester}
|
||||
}
|
||||
|
||||
// Writer get a writer
|
||||
func (d DecompressStore) Writer(ctx context.Context, opts ...ctrcontent.WriterOpt) (ctrcontent.Writer, error) {
|
||||
// the logic is straightforward:
|
||||
// - if there is a desc in the opts, and the mediatype is tar or tar+gzip, then pass the correct decompress writer
|
||||
// - else, pass the regular writer
|
||||
var (
|
||||
writer ctrcontent.Writer
|
||||
err error
|
||||
multiIngester MultiWriterIngester
|
||||
ok bool
|
||||
)
|
||||
|
||||
// check to see if we are supposed to use a MultiWriterIngester
|
||||
if d.multiWriterIngester {
|
||||
multiIngester, ok = d.ingester.(MultiWriterIngester)
|
||||
if !ok {
|
||||
return nil, errors.New("configured to use multiwriter ingester, but ingester does not implement multiwriter")
|
||||
}
|
||||
}
|
||||
|
||||
// we have to reprocess the opts to find the desc
|
||||
var wOpts ctrcontent.WriterOpts
|
||||
for _, opt := range opts {
|
||||
if err := opt(&wOpts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// figure out if compression and/or archive exists
|
||||
desc := wOpts.Desc
|
||||
// before we pass it down, we need to strip anything we are removing here
|
||||
// and possibly update the digest, since the store indexes things by digest
|
||||
hasGzip, hasTar, modifiedMediaType := checkCompression(desc.MediaType)
|
||||
wOpts.Desc.MediaType = modifiedMediaType
|
||||
opts = append(opts, ctrcontent.WithDescriptor(wOpts.Desc))
|
||||
// determine if we pass it blocksize, only if positive
|
||||
writerOpts := []WriterOpt{}
|
||||
if d.blocksize > 0 {
|
||||
writerOpts = append(writerOpts, WithBlocksize(d.blocksize))
|
||||
}
|
||||
|
||||
writer, err = d.ingester.Writer(ctx, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// do we need to wrap with an untar writer?
|
||||
if hasTar {
|
||||
// if not multiingester, get a regular writer
|
||||
if multiIngester == nil {
|
||||
writer = NewUntarWriter(writer, writerOpts...)
|
||||
} else {
|
||||
writers, err := multiIngester.Writers(ctx, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
writer = NewUntarWriterByName(writers, writerOpts...)
|
||||
}
|
||||
}
|
||||
if hasGzip {
|
||||
if writer == nil {
|
||||
writer, err = d.ingester.Writer(ctx, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
writer = NewGunzipWriter(writer, writerOpts...)
|
||||
}
|
||||
return writer, nil
|
||||
}
|
||||
|
||||
// checkCompression check if the mediatype uses gzip compression or tar.
|
||||
// Returns if it has gzip and/or tar, as well as the base media type without
|
||||
// those suffixes.
|
||||
func checkCompression(mediaType string) (gzip, tar bool, mt string) {
|
||||
mt = mediaType
|
||||
gzipSuffix := "+gzip"
|
||||
gzipAltSuffix := ".gzip"
|
||||
tarSuffix := ".tar"
|
||||
switch {
|
||||
case strings.HasSuffix(mt, gzipSuffix):
|
||||
mt = mt[:len(mt)-len(gzipSuffix)]
|
||||
gzip = true
|
||||
case strings.HasSuffix(mt, gzipAltSuffix):
|
||||
mt = mt[:len(mt)-len(gzipAltSuffix)]
|
||||
gzip = true
|
||||
}
|
||||
|
||||
if strings.HasSuffix(mt, tarSuffix) {
|
||||
mt = mt[:len(mt)-len(tarSuffix)]
|
||||
tar = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
@ -31,19 +31,28 @@ type FileStore struct {
|
|||
// Reproducible enables stripping times from added files
|
||||
Reproducible bool
|
||||
|
||||
root string
|
||||
descriptor *sync.Map // map[digest.Digest]ocispec.Descriptor
|
||||
pathMap *sync.Map
|
||||
tmpFiles *sync.Map
|
||||
root string
|
||||
descriptor *sync.Map // map[digest.Digest]ocispec.Descriptor
|
||||
pathMap *sync.Map
|
||||
tmpFiles *sync.Map
|
||||
ignoreNoName bool
|
||||
}
|
||||
|
||||
// NewFileStore creats a new file store
|
||||
func NewFileStore(rootPath string) *FileStore {
|
||||
func NewFileStore(rootPath string, opts ...WriterOpt) *FileStore {
|
||||
// we have to process the opts to find if they told us to change defaults
|
||||
wOpts := DefaultWriterOpts()
|
||||
for _, opt := range opts {
|
||||
if err := opt(&wOpts); err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return &FileStore{
|
||||
root: rootPath,
|
||||
descriptor: &sync.Map{},
|
||||
pathMap: &sync.Map{},
|
||||
tmpFiles: &sync.Map{},
|
||||
root: rootPath,
|
||||
descriptor: &sync.Map{},
|
||||
pathMap: &sync.Map{},
|
||||
tmpFiles: &sync.Map{},
|
||||
ignoreNoName: wOpts.IgnoreNoName,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -198,7 +207,14 @@ func (s *FileStore) Writer(ctx context.Context, opts ...content.WriterOpt) (cont
|
|||
|
||||
name, ok := ResolveName(desc)
|
||||
if !ok {
|
||||
return nil, ErrNoName
|
||||
// if we were not told to ignore NoName, then return an error
|
||||
if !s.ignoreNoName {
|
||||
return nil, ErrNoName
|
||||
}
|
||||
|
||||
// just return a nil writer - we do not want to calculate the hash, so just use
|
||||
// whatever was passed in the descriptor
|
||||
return NewIoContentWriter(ioutil.Discard, WithOutputHash(desc.Digest)), nil
|
||||
}
|
||||
path, err := s.resolveWritePath(name)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
package content
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
)
|
||||
|
||||
// NewGunzipWriter wrap a writer with a gunzip, so that the stream is gunzipped
|
||||
//
|
||||
// By default, it calculates the hash when writing. If the option `skipHash` is true,
|
||||
// it will skip doing the hash. Skipping the hash is intended to be used only
|
||||
// if you are confident about the validity of the data being passed to the writer,
|
||||
// and wish to save on the hashing time.
|
||||
func NewGunzipWriter(writer content.Writer, opts ...WriterOpt) content.Writer {
|
||||
// process opts for default
|
||||
wOpts := DefaultWriterOpts()
|
||||
for _, opt := range opts {
|
||||
if err := opt(&wOpts); err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return NewPassthroughWriter(writer, func(r io.Reader, w io.Writer, done chan<- error) {
|
||||
gr, err := gzip.NewReader(r)
|
||||
if err != nil {
|
||||
done <- fmt.Errorf("error creating gzip reader: %v", err)
|
||||
return
|
||||
}
|
||||
// write out the uncompressed data
|
||||
b := make([]byte, wOpts.Blocksize, wOpts.Blocksize)
|
||||
for {
|
||||
var n int
|
||||
n, err = gr.Read(b)
|
||||
if err != nil && err != io.EOF {
|
||||
err = fmt.Errorf("GunzipWriter data read error: %v\n", err)
|
||||
break
|
||||
}
|
||||
l := n
|
||||
if n > len(b) {
|
||||
l = len(b)
|
||||
}
|
||||
if _, err2 := w.Write(b[:l]); err2 != nil {
|
||||
err = fmt.Errorf("GunzipWriter: error writing to underlying writer: %v", err2)
|
||||
break
|
||||
}
|
||||
if err == io.EOF {
|
||||
// clear the error
|
||||
err = nil
|
||||
break
|
||||
}
|
||||
}
|
||||
gr.Close()
|
||||
done <- err
|
||||
}, opts...)
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
package content
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// IoContentWriter writer that wraps an io.Writer, so the results can be streamed to
|
||||
// an open io.Writer. For example, can be used to pull a layer and write it to a file, or device.
|
||||
type IoContentWriter struct {
|
||||
writer io.Writer
|
||||
digester digest.Digester
|
||||
size int64
|
||||
hash *digest.Digest
|
||||
}
|
||||
|
||||
// NewIoContentWriter create a new IoContentWriter.
|
||||
//
|
||||
// By default, it calculates the hash when writing. If the option `skipHash` is true,
|
||||
// it will skip doing the hash. Skipping the hash is intended to be used only
|
||||
// if you are confident about the validity of the data being passed to the writer,
|
||||
// and wish to save on the hashing time.
|
||||
func NewIoContentWriter(writer io.Writer, opts ...WriterOpt) content.Writer {
|
||||
w := writer
|
||||
if w == nil {
|
||||
w = ioutil.Discard
|
||||
}
|
||||
// process opts for default
|
||||
wOpts := DefaultWriterOpts()
|
||||
for _, opt := range opts {
|
||||
if err := opt(&wOpts); err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
ioc := &IoContentWriter{
|
||||
writer: w,
|
||||
digester: digest.Canonical.Digester(),
|
||||
// we take the OutputHash, since the InputHash goes to the passthrough writer,
|
||||
// which then passes the processed output to us
|
||||
hash: wOpts.OutputHash,
|
||||
}
|
||||
return NewPassthroughWriter(ioc, func(r io.Reader, w io.Writer, done chan<- error) {
|
||||
// write out the data to the io writer
|
||||
var (
|
||||
err error
|
||||
)
|
||||
// we could use io.Copy, but calling it with the default blocksize is identical to
|
||||
// io.CopyBuffer. Otherwise, we would need some way to let the user flag "I want to use
|
||||
// io.Copy", when it should not matter to them
|
||||
b := make([]byte, wOpts.Blocksize, wOpts.Blocksize)
|
||||
_, err = io.CopyBuffer(w, r, b)
|
||||
done <- err
|
||||
}, opts...)
|
||||
}
|
||||
|
||||
func (w *IoContentWriter) Write(p []byte) (n int, err error) {
|
||||
n, err = w.writer.Write(p)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
w.size += int64(n)
|
||||
if w.hash == nil {
|
||||
w.digester.Hash().Write(p[:n])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (w *IoContentWriter) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Digest may return empty digest or panics until committed.
|
||||
func (w *IoContentWriter) Digest() digest.Digest {
|
||||
return w.digester.Digest()
|
||||
}
|
||||
|
||||
// Commit commits the blob (but no roll-back is guaranteed on an error).
|
||||
// size and expected can be zero-value when unknown.
|
||||
// Commit always closes the writer, even on error.
|
||||
// ErrAlreadyExists aborts the writer.
|
||||
func (w *IoContentWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status returns the current state of write
|
||||
func (w *IoContentWriter) Status() (content.Status, error) {
|
||||
return content.Status{}, nil
|
||||
}
|
||||
|
||||
// Truncate updates the size of the target blob
|
||||
func (w *IoContentWriter) Truncate(size int64) error {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package content
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// MultiReader store to read content from multiple stores. It finds the content by asking each underlying
|
||||
// store to find the content, which it does based on the hash.
|
||||
//
|
||||
// Example:
|
||||
// fileStore := NewFileStore(rootPath)
|
||||
// memoryStore := NewMemoryStore()
|
||||
// // load up content in fileStore and memoryStore
|
||||
// multiStore := MultiReader([]content.Provider{fileStore, memoryStore})
|
||||
//
|
||||
// You now can use multiStore anywhere that content.Provider is accepted
|
||||
type MultiReader struct {
|
||||
stores []content.Provider
|
||||
}
|
||||
|
||||
// AddStore add a store to read from
|
||||
func (m *MultiReader) AddStore(store ...content.Provider) {
|
||||
m.stores = append(m.stores, store...)
|
||||
}
|
||||
|
||||
// ReaderAt get a reader
|
||||
func (m MultiReader) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.ReaderAt, error) {
|
||||
for _, store := range m.stores {
|
||||
r, err := store.ReaderAt(ctx, desc)
|
||||
if r != nil && err == nil {
|
||||
return r, nil
|
||||
}
|
||||
}
|
||||
// we did not find any
|
||||
return nil, fmt.Errorf("not found")
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package content
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ctrcontent "github.com/containerd/containerd/content"
|
||||
)
|
||||
|
||||
// MultiWriterIngester an ingester that can provide a single writer or multiple writers for a single
|
||||
// descriptor. Useful when the target of a descriptor can have multiple items within it, e.g. a layer
|
||||
// that is a tar file with multiple files, each of which should go to a different stream, some of which
|
||||
// should not be handled at all.
|
||||
type MultiWriterIngester interface {
|
||||
ctrcontent.Ingester
|
||||
Writers(ctx context.Context, opts ...ctrcontent.WriterOpt) (func(string) (ctrcontent.Writer, error), error)
|
||||
}
|
||||
|
|
@ -98,6 +98,8 @@ func (s *OCIStore) AddReference(name string, desc ocispec.Descriptor) {
|
|||
}
|
||||
|
||||
if _, ok := s.nameMap[name]; ok {
|
||||
s.nameMap[name] = desc
|
||||
|
||||
for i, ref := range s.index.Manifests {
|
||||
if name == ref.Annotations[ocispec.AnnotationRefName] {
|
||||
s.index.Manifests[i] = desc
|
||||
|
|
@ -107,11 +109,12 @@ func (s *OCIStore) AddReference(name string, desc ocispec.Descriptor) {
|
|||
|
||||
// Process should not reach here.
|
||||
// Fallthrough to `Add` scenario and recover.
|
||||
s.index.Manifests = append(s.index.Manifests, desc)
|
||||
return
|
||||
}
|
||||
|
||||
s.index.Manifests = append(s.index.Manifests, desc)
|
||||
s.nameMap[name] = desc
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteReference deletes an reference from index.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,97 @@
|
|||
package content
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
type WriterOpts struct {
|
||||
InputHash *digest.Digest
|
||||
OutputHash *digest.Digest
|
||||
Blocksize int
|
||||
MultiWriterIngester bool
|
||||
IgnoreNoName bool
|
||||
}
|
||||
|
||||
type WriterOpt func(*WriterOpts) error
|
||||
|
||||
func DefaultWriterOpts() WriterOpts {
|
||||
return WriterOpts{
|
||||
InputHash: nil,
|
||||
OutputHash: nil,
|
||||
Blocksize: DefaultBlocksize,
|
||||
IgnoreNoName: true,
|
||||
}
|
||||
}
|
||||
|
||||
// WithInputHash provide the expected input hash to a writer. Writers
|
||||
// may suppress their own calculation of a hash on the stream, taking this
|
||||
// hash instead. If the Writer processes the data before passing it on to another
|
||||
// Writer layer, this is the hash of the *input* stream.
|
||||
//
|
||||
// To have a blank hash, use WithInputHash(BlankHash).
|
||||
func WithInputHash(hash digest.Digest) WriterOpt {
|
||||
return func(w *WriterOpts) error {
|
||||
w.InputHash = &hash
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithOutputHash provide the expected output hash to a writer. Writers
|
||||
// may suppress their own calculation of a hash on the stream, taking this
|
||||
// hash instead. If the Writer processes the data before passing it on to another
|
||||
// Writer layer, this is the hash of the *output* stream.
|
||||
//
|
||||
// To have a blank hash, use WithInputHash(BlankHash).
|
||||
func WithOutputHash(hash digest.Digest) WriterOpt {
|
||||
return func(w *WriterOpts) error {
|
||||
w.OutputHash = &hash
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithBlocksize set the blocksize used by the processor of data.
|
||||
// The default is DefaultBlocksize, which is the same as that used by io.Copy.
|
||||
// Includes a safety check to ensure the caller doesn't actively set it to <= 0.
|
||||
func WithBlocksize(blocksize int) WriterOpt {
|
||||
return func(w *WriterOpts) error {
|
||||
if blocksize <= 0 {
|
||||
return errors.New("blocksize must be greater than or equal to 0")
|
||||
}
|
||||
w.Blocksize = blocksize
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithMultiWriterIngester the passed ingester also implements MultiWriter
|
||||
// and should be used as such. If this is set to true, but the ingester does not
|
||||
// implement MultiWriter, calling Writer should return an error.
|
||||
func WithMultiWriterIngester() WriterOpt {
|
||||
return func(w *WriterOpts) error {
|
||||
w.MultiWriterIngester = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithErrorOnNoName some ingesters, when creating a Writer, do not return an error if
|
||||
// the descriptor does not have a valid name on the descriptor. Passing WithErrorOnNoName
|
||||
// tells the writer to return an error instead of passing the data to a nil writer.
|
||||
func WithErrorOnNoName() WriterOpt {
|
||||
return func(w *WriterOpts) error {
|
||||
w.IgnoreNoName = false
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithIgnoreNoName some ingesters, when creating a Writer, return an error if
|
||||
// the descriptor does not have a valid name on the descriptor. Passing WithIgnoreNoName
|
||||
// tells the writer not to return an error, but rather to pass the data to a nil writer.
|
||||
//
|
||||
// Deprecated: Use WithErrorOnNoName
|
||||
func WithIgnoreNoName() WriterOpt {
|
||||
return func(w *WriterOpts) error {
|
||||
w.IgnoreNoName = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,271 @@
|
|||
package content
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// PassthroughWriter takes an input stream and passes it through to an underlying writer,
|
||||
// while providing the ability to manipulate the stream before it gets passed through
|
||||
type PassthroughWriter struct {
|
||||
writer content.Writer
|
||||
pipew *io.PipeWriter
|
||||
digester digest.Digester
|
||||
size int64
|
||||
underlyingWriter *underlyingWriter
|
||||
reader *io.PipeReader
|
||||
hash *digest.Digest
|
||||
done chan error
|
||||
}
|
||||
|
||||
// NewPassthroughWriter creates a pass-through writer that allows for processing
|
||||
// the content via an arbitrary function. The function should do whatever processing it
|
||||
// wants, reading from the Reader to the Writer. When done, it must indicate via
|
||||
// sending an error or nil to the Done
|
||||
func NewPassthroughWriter(writer content.Writer, f func(r io.Reader, w io.Writer, done chan<- error), opts ...WriterOpt) content.Writer {
|
||||
// process opts for default
|
||||
wOpts := DefaultWriterOpts()
|
||||
for _, opt := range opts {
|
||||
if err := opt(&wOpts); err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
r, w := io.Pipe()
|
||||
pw := &PassthroughWriter{
|
||||
writer: writer,
|
||||
pipew: w,
|
||||
digester: digest.Canonical.Digester(),
|
||||
underlyingWriter: &underlyingWriter{
|
||||
writer: writer,
|
||||
digester: digest.Canonical.Digester(),
|
||||
hash: wOpts.OutputHash,
|
||||
},
|
||||
reader: r,
|
||||
hash: wOpts.InputHash,
|
||||
done: make(chan error, 1),
|
||||
}
|
||||
go f(r, pw.underlyingWriter, pw.done)
|
||||
return pw
|
||||
}
|
||||
|
||||
func (pw *PassthroughWriter) Write(p []byte) (n int, err error) {
|
||||
n, err = pw.pipew.Write(p)
|
||||
if pw.hash == nil {
|
||||
pw.digester.Hash().Write(p[:n])
|
||||
}
|
||||
pw.size += int64(n)
|
||||
return
|
||||
}
|
||||
|
||||
func (pw *PassthroughWriter) Close() error {
|
||||
if pw.pipew != nil {
|
||||
pw.pipew.Close()
|
||||
}
|
||||
pw.writer.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Digest may return empty digest or panics until committed.
|
||||
func (pw *PassthroughWriter) Digest() digest.Digest {
|
||||
if pw.hash != nil {
|
||||
return *pw.hash
|
||||
}
|
||||
return pw.digester.Digest()
|
||||
}
|
||||
|
||||
// Commit commits the blob (but no roll-back is guaranteed on an error).
|
||||
// size and expected can be zero-value when unknown.
|
||||
// Commit always closes the writer, even on error.
|
||||
// ErrAlreadyExists aborts the writer.
|
||||
func (pw *PassthroughWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
|
||||
if pw.pipew != nil {
|
||||
pw.pipew.Close()
|
||||
}
|
||||
err := <-pw.done
|
||||
if pw.reader != nil {
|
||||
pw.reader.Close()
|
||||
}
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
// Some underlying writers will validate an expected digest, so we need the option to pass it
|
||||
// that digest. That is why we caluclate the digest of the underlying writer throughout the write process.
|
||||
return pw.writer.Commit(ctx, pw.underlyingWriter.size, pw.underlyingWriter.Digest(), opts...)
|
||||
}
|
||||
|
||||
// Status returns the current state of write
|
||||
func (pw *PassthroughWriter) Status() (content.Status, error) {
|
||||
return pw.writer.Status()
|
||||
}
|
||||
|
||||
// Truncate updates the size of the target blob
|
||||
func (pw *PassthroughWriter) Truncate(size int64) error {
|
||||
return pw.writer.Truncate(size)
|
||||
}
|
||||
|
||||
// underlyingWriter implementation of io.Writer to write to the underlying
|
||||
// io.Writer
|
||||
type underlyingWriter struct {
|
||||
writer content.Writer
|
||||
digester digest.Digester
|
||||
size int64
|
||||
hash *digest.Digest
|
||||
}
|
||||
|
||||
// Write write to the underlying writer
|
||||
func (u *underlyingWriter) Write(p []byte) (int, error) {
|
||||
n, err := u.writer.Write(p)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if u.hash == nil {
|
||||
u.digester.Hash().Write(p)
|
||||
}
|
||||
u.size += int64(len(p))
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Size get total size written
|
||||
func (u *underlyingWriter) Size() int64 {
|
||||
return u.size
|
||||
}
|
||||
|
||||
// Digest may return empty digest or panics until committed.
|
||||
func (u *underlyingWriter) Digest() digest.Digest {
|
||||
if u.hash != nil {
|
||||
return *u.hash
|
||||
}
|
||||
return u.digester.Digest()
|
||||
}
|
||||
|
||||
// PassthroughMultiWriter single writer that passes through to multiple writers, allowing the passthrough
|
||||
// function to select which writer to use.
|
||||
type PassthroughMultiWriter struct {
|
||||
writers []*PassthroughWriter
|
||||
pipew *io.PipeWriter
|
||||
digester digest.Digester
|
||||
size int64
|
||||
reader *io.PipeReader
|
||||
hash *digest.Digest
|
||||
done chan error
|
||||
startedAt time.Time
|
||||
updatedAt time.Time
|
||||
}
|
||||
|
||||
func NewPassthroughMultiWriter(writers func(name string) (content.Writer, error), f func(r io.Reader, getwriter func(name string) io.Writer, done chan<- error), opts ...WriterOpt) content.Writer {
|
||||
// process opts for default
|
||||
wOpts := DefaultWriterOpts()
|
||||
for _, opt := range opts {
|
||||
if err := opt(&wOpts); err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
r, w := io.Pipe()
|
||||
|
||||
pmw := &PassthroughMultiWriter{
|
||||
startedAt: time.Now(),
|
||||
updatedAt: time.Now(),
|
||||
done: make(chan error, 1),
|
||||
digester: digest.Canonical.Digester(),
|
||||
hash: wOpts.InputHash,
|
||||
pipew: w,
|
||||
reader: r,
|
||||
}
|
||||
|
||||
// get our output writers
|
||||
getwriter := func(name string) io.Writer {
|
||||
writer, err := writers(name)
|
||||
if err != nil || writer == nil {
|
||||
return nil
|
||||
}
|
||||
pw := &PassthroughWriter{
|
||||
writer: writer,
|
||||
digester: digest.Canonical.Digester(),
|
||||
underlyingWriter: &underlyingWriter{
|
||||
writer: writer,
|
||||
digester: digest.Canonical.Digester(),
|
||||
hash: wOpts.OutputHash,
|
||||
},
|
||||
done: make(chan error, 1),
|
||||
}
|
||||
pmw.writers = append(pmw.writers, pw)
|
||||
return pw.underlyingWriter
|
||||
}
|
||||
go f(r, getwriter, pmw.done)
|
||||
return pmw
|
||||
}
|
||||
|
||||
func (pmw *PassthroughMultiWriter) Write(p []byte) (n int, err error) {
|
||||
n, err = pmw.pipew.Write(p)
|
||||
if pmw.hash == nil {
|
||||
pmw.digester.Hash().Write(p[:n])
|
||||
}
|
||||
pmw.size += int64(n)
|
||||
pmw.updatedAt = time.Now()
|
||||
return
|
||||
}
|
||||
|
||||
func (pmw *PassthroughMultiWriter) Close() error {
|
||||
pmw.pipew.Close()
|
||||
for _, w := range pmw.writers {
|
||||
w.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Digest may return empty digest or panics until committed.
|
||||
func (pmw *PassthroughMultiWriter) Digest() digest.Digest {
|
||||
if pmw.hash != nil {
|
||||
return *pmw.hash
|
||||
}
|
||||
return pmw.digester.Digest()
|
||||
}
|
||||
|
||||
// Commit commits the blob (but no roll-back is guaranteed on an error).
|
||||
// size and expected can be zero-value when unknown.
|
||||
// Commit always closes the writer, even on error.
|
||||
// ErrAlreadyExists aborts the writer.
|
||||
func (pmw *PassthroughMultiWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
|
||||
pmw.pipew.Close()
|
||||
err := <-pmw.done
|
||||
if pmw.reader != nil {
|
||||
pmw.reader.Close()
|
||||
}
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
// Some underlying writers will validate an expected digest, so we need the option to pass it
|
||||
// that digest. That is why we caluclate the digest of the underlying writer throughout the write process.
|
||||
for _, w := range pmw.writers {
|
||||
// maybe this should be Commit(ctx, pw.underlyingWriter.size, pw.underlyingWriter.Digest(), opts...)
|
||||
w.done <- err
|
||||
if err := w.Commit(ctx, size, expected, opts...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status returns the current state of write
|
||||
func (pmw *PassthroughMultiWriter) Status() (content.Status, error) {
|
||||
return content.Status{
|
||||
StartedAt: pmw.startedAt,
|
||||
UpdatedAt: pmw.updatedAt,
|
||||
Total: pmw.size,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Truncate updates the size of the target blob, but cannot do anything with a multiwriter
|
||||
func (pmw *PassthroughMultiWriter) Truncate(size int64) error {
|
||||
return errors.New("truncate unavailable on multiwriter")
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
package content
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
)
|
||||
|
||||
// NewUntarWriter wrap a writer with an untar, so that the stream is untarred
|
||||
//
|
||||
// By default, it calculates the hash when writing. If the option `skipHash` is true,
|
||||
// it will skip doing the hash. Skipping the hash is intended to be used only
|
||||
// if you are confident about the validity of the data being passed to the writer,
|
||||
// and wish to save on the hashing time.
|
||||
func NewUntarWriter(writer content.Writer, opts ...WriterOpt) content.Writer {
|
||||
// process opts for default
|
||||
wOpts := DefaultWriterOpts()
|
||||
for _, opt := range opts {
|
||||
if err := opt(&wOpts); err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return NewPassthroughWriter(writer, func(r io.Reader, w io.Writer, done chan<- error) {
|
||||
tr := tar.NewReader(r)
|
||||
var err error
|
||||
for {
|
||||
_, err := tr.Next()
|
||||
if err == io.EOF {
|
||||
// clear the error, since we do not pass an io.EOF
|
||||
err = nil
|
||||
break // End of archive
|
||||
}
|
||||
if err != nil {
|
||||
// pass the error on
|
||||
err = fmt.Errorf("UntarWriter tar file header read error: %v", err)
|
||||
break
|
||||
}
|
||||
// write out the untarred data
|
||||
// we can handle io.EOF, just go to the next file
|
||||
// any other errors should stop and get reported
|
||||
b := make([]byte, wOpts.Blocksize, wOpts.Blocksize)
|
||||
for {
|
||||
var n int
|
||||
n, err = tr.Read(b)
|
||||
if err != nil && err != io.EOF {
|
||||
err = fmt.Errorf("UntarWriter file data read error: %v\n", err)
|
||||
break
|
||||
}
|
||||
l := n
|
||||
if n > len(b) {
|
||||
l = len(b)
|
||||
}
|
||||
if _, err2 := w.Write(b[:l]); err2 != nil {
|
||||
err = fmt.Errorf("UntarWriter error writing to underlying writer: %v", err2)
|
||||
break
|
||||
}
|
||||
if err == io.EOF {
|
||||
// go to the next file
|
||||
break
|
||||
}
|
||||
}
|
||||
// did we break with a non-nil and non-EOF error?
|
||||
if err != nil && err != io.EOF {
|
||||
break
|
||||
}
|
||||
}
|
||||
done <- err
|
||||
}, opts...)
|
||||
}
|
||||
|
||||
// NewUntarWriterByName wrap multiple writers with an untar, so that the stream is untarred and passed
|
||||
// to the appropriate writer, based on the filename. If a filename is not found, it is up to the called func
|
||||
// to determine how to process it.
|
||||
func NewUntarWriterByName(writers func(string) (content.Writer, error), opts ...WriterOpt) content.Writer {
|
||||
// process opts for default
|
||||
wOpts := DefaultWriterOpts()
|
||||
for _, opt := range opts {
|
||||
if err := opt(&wOpts); err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// need a PassthroughMultiWriter here
|
||||
return NewPassthroughMultiWriter(writers, func(r io.Reader, getwriter func(name string) io.Writer, done chan<- error) {
|
||||
tr := tar.NewReader(r)
|
||||
var err error
|
||||
for {
|
||||
header, err := tr.Next()
|
||||
if err == io.EOF {
|
||||
// clear the error, since we do not pass an io.EOF
|
||||
err = nil
|
||||
break // End of archive
|
||||
}
|
||||
if err != nil {
|
||||
// pass the error on
|
||||
err = fmt.Errorf("UntarWriter tar file header read error: %v", err)
|
||||
break
|
||||
}
|
||||
// get the filename
|
||||
filename := header.Name
|
||||
|
||||
// get the writer for this filename
|
||||
w := getwriter(filename)
|
||||
if w == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// write out the untarred data
|
||||
// we can handle io.EOF, just go to the next file
|
||||
// any other errors should stop and get reported
|
||||
b := make([]byte, wOpts.Blocksize, wOpts.Blocksize)
|
||||
for {
|
||||
var n int
|
||||
n, err = tr.Read(b)
|
||||
if err != nil && err != io.EOF {
|
||||
err = fmt.Errorf("UntarWriter file data read error: %v\n", err)
|
||||
break
|
||||
}
|
||||
l := n
|
||||
if n > len(b) {
|
||||
l = len(b)
|
||||
}
|
||||
if _, err2 := w.Write(b[:l]); err2 != nil {
|
||||
err = fmt.Errorf("UntarWriter error writing to underlying writer at for name '%s': %v", filename, err2)
|
||||
break
|
||||
}
|
||||
if err == io.EOF {
|
||||
// go to the next file
|
||||
break
|
||||
}
|
||||
}
|
||||
// did we break with a non-nil and non-EOF error?
|
||||
if err != nil && err != io.EOF {
|
||||
break
|
||||
}
|
||||
}
|
||||
done <- err
|
||||
}, opts...)
|
||||
}
|
||||
|
|
@ -101,15 +101,24 @@ func extractTarDirectory(root, prefix string, r io.Reader) error {
|
|||
|
||||
// Name check
|
||||
name := header.Name
|
||||
path, err := filepath.Rel(prefix, name)
|
||||
path, err := ensureBasePath(root, prefix, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.HasPrefix(path, "../") {
|
||||
return fmt.Errorf("%q does not have prefix %q", name, prefix)
|
||||
}
|
||||
path = filepath.Join(root, path)
|
||||
|
||||
// Link check
|
||||
switch header.Typeflag {
|
||||
case tar.TypeLink, tar.TypeSymlink:
|
||||
link := header.Linkname
|
||||
if !filepath.IsAbs(link) {
|
||||
link = filepath.Join(filepath.Dir(name), link)
|
||||
}
|
||||
if _, err := ensureBasePath(root, prefix, link); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Create content
|
||||
switch header.Typeflag {
|
||||
case tar.TypeReg:
|
||||
|
|
@ -132,6 +141,34 @@ func extractTarDirectory(root, prefix string, r io.Reader) error {
|
|||
}
|
||||
}
|
||||
|
||||
// ensureBasePath ensures the target path is in the base path,
|
||||
// returning its relative path to the base path.
|
||||
func ensureBasePath(root, base, target string) (string, error) {
|
||||
path, err := filepath.Rel(base, target)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
cleanPath := filepath.ToSlash(filepath.Clean(path))
|
||||
if cleanPath == ".." || strings.HasPrefix(cleanPath, "../") {
|
||||
return "", fmt.Errorf("%q is outside of %q", target, base)
|
||||
}
|
||||
|
||||
// No symbolic link allowed in the relative path
|
||||
dir := filepath.Dir(path)
|
||||
for dir != "." {
|
||||
if info, err := os.Lstat(filepath.Join(root, dir)); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return "", err
|
||||
}
|
||||
} else if info.Mode()&os.ModeSymlink != 0 {
|
||||
return "", fmt.Errorf("no symbolic link allowed between %q and %q", base, target)
|
||||
}
|
||||
dir = filepath.Dir(dir)
|
||||
}
|
||||
|
||||
return path, nil
|
||||
}
|
||||
|
||||
func writeFile(path string, r io.Reader, perm os.FileMode) error {
|
||||
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ go_library(
|
|||
"//vendor/github.com/opencontainers/image-spec/specs-go:go_default_library",
|
||||
"//vendor/github.com/opencontainers/image-spec/specs-go/v1:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/golang.org/x/sync/errgroup:go_default_library",
|
||||
"//vendor/golang.org/x/sync/semaphore:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import (
|
|||
// Common errors
|
||||
var (
|
||||
ErrResolverUndefined = errors.New("resolver undefined")
|
||||
ErrEmptyDescriptors = errors.New("empty descriptors")
|
||||
)
|
||||
|
||||
// Path validation related errors
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ func fetchContent(ctx context.Context, fetcher remotes.Fetcher, desc ocispec.Des
|
|||
|
||||
store := opts.contentProvideIngester
|
||||
if store == nil {
|
||||
store = newHybridStoreFromIngester(ingester)
|
||||
store = newHybridStoreFromIngester(ingester, opts.cachedMediaTypes)
|
||||
}
|
||||
handlers := []images.Handler{
|
||||
filterHandler(opts, opts.allowedMediaTypes...),
|
||||
|
|
|
|||
|
|
@ -2,10 +2,14 @@ package oras
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
orascontent "github.com/deislabs/oras/pkg/content"
|
||||
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/opencontainers/go-digest"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"golang.org/x/sync/semaphore"
|
||||
)
|
||||
|
|
@ -17,6 +21,7 @@ type pullOpts struct {
|
|||
callbackHandlers []images.Handler
|
||||
contentProvideIngester orascontent.ProvideIngester
|
||||
filterName func(ocispec.Descriptor) bool
|
||||
cachedMediaTypes []string
|
||||
}
|
||||
|
||||
// PullOpt allows callers to set options on the oras pull
|
||||
|
|
@ -24,8 +29,26 @@ type PullOpt func(o *pullOpts) error
|
|||
|
||||
func pullOptsDefaults() *pullOpts {
|
||||
return &pullOpts{
|
||||
dispatch: images.Dispatch,
|
||||
filterName: filterName,
|
||||
dispatch: images.Dispatch,
|
||||
filterName: filterName,
|
||||
cachedMediaTypes: []string{ocispec.MediaTypeImageManifest, ocispec.MediaTypeImageIndex},
|
||||
}
|
||||
}
|
||||
|
||||
// WithCachedMediaTypes sets the media types normally cached in memory when pulling.
|
||||
func WithCachedMediaTypes(cachedMediaTypes ...string) PullOpt {
|
||||
return func(o *pullOpts) error {
|
||||
o.cachedMediaTypes = cachedMediaTypes
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithAdditionalCachedMediaTypes adds media types normally cached in memory when pulling.
|
||||
// This does not replace the default media types, but appends to them
|
||||
func WithAdditionalCachedMediaTypes(cachedMediaTypes ...string) PullOpt {
|
||||
return func(o *pullOpts) error {
|
||||
o.cachedMediaTypes = append(o.cachedMediaTypes, cachedMediaTypes...)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,3 +110,26 @@ func WithPullEmptyNameAllowed() PullOpt {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithPullStatusTrack report results to stdout
|
||||
func WithPullStatusTrack(writer io.Writer) PullOpt {
|
||||
return WithPullCallbackHandler(pullStatusTrack(writer))
|
||||
}
|
||||
|
||||
func pullStatusTrack(writer io.Writer) images.Handler {
|
||||
var printLock sync.Mutex
|
||||
return images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
||||
if name, ok := orascontent.ResolveName(desc); ok {
|
||||
digestString := desc.Digest.String()
|
||||
if err := desc.Digest.Validate(); err == nil {
|
||||
if algo := desc.Digest.Algorithm(); algo == digest.SHA256 {
|
||||
digestString = desc.Digest.Encoded()[:12]
|
||||
}
|
||||
}
|
||||
printLock.Lock()
|
||||
defer printLock.Unlock()
|
||||
fmt.Fprintln(writer, "Downloaded", digestString, name)
|
||||
}
|
||||
return nil, nil
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,6 @@ func Push(ctx context.Context, resolver remotes.Resolver, ref string, provider c
|
|||
if resolver == nil {
|
||||
return ocispec.Descriptor{}, ErrResolverUndefined
|
||||
}
|
||||
if len(descriptors) == 0 {
|
||||
return ocispec.Descriptor{}, ErrEmptyDescriptors
|
||||
}
|
||||
opt := pushOptsDefaults()
|
||||
for _, o := range opts {
|
||||
if err := o(opt); err != nil {
|
||||
|
|
@ -60,7 +57,7 @@ func Push(ctx context.Context, resolver remotes.Resolver, ref string, provider c
|
|||
|
||||
//func pack(store *hybridStore, descriptors []ocispec.Descriptor, opts *pushOpts) (ocispec.Descriptor, error) {
|
||||
func pack(provider content.Provider, descriptors []ocispec.Descriptor, opts *pushOpts) (ocispec.Descriptor, content.Store, error) {
|
||||
store := newHybridStoreFromProvider(provider)
|
||||
store := newHybridStoreFromProvider(provider, nil)
|
||||
|
||||
// Config
|
||||
var config ocispec.Descriptor
|
||||
|
|
@ -87,6 +84,9 @@ func pack(provider content.Provider, descriptors []ocispec.Descriptor, opts *pus
|
|||
return *opts.manifest, store, nil
|
||||
}
|
||||
|
||||
if descriptors == nil {
|
||||
descriptors = []ocispec.Descriptor{} // make it an empty array to prevent potential server-side bugs
|
||||
}
|
||||
manifest := ocispec.Manifest{
|
||||
Versioned: specs.Versioned{
|
||||
SchemaVersion: 2, // historical value. does not pertain to OCI or docker version
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
package oras
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/containerd/images"
|
||||
orascontent "github.com/deislabs/oras/pkg/content"
|
||||
|
|
@ -127,3 +131,20 @@ func WithPushBaseHandler(handlers ...images.Handler) PushOpt {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithPushStatusTrack report results to a provided writer
|
||||
func WithPushStatusTrack(writer io.Writer) PushOpt {
|
||||
return WithPushBaseHandler(pushStatusTrack(writer))
|
||||
}
|
||||
|
||||
func pushStatusTrack(writer io.Writer) images.Handler {
|
||||
var printLock sync.Mutex
|
||||
return images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
||||
if name, ok := orascontent.ResolveName(desc); ok {
|
||||
printLock.Lock()
|
||||
defer printLock.Unlock()
|
||||
fmt.Fprintln(writer, "Uploading", desc.Digest.Encoded()[:12], name)
|
||||
}
|
||||
return nil, nil
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,15 @@ package oras
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
orascontent "github.com/deislabs/oras/pkg/content"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/opencontainers/go-digest"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
// ensure interface
|
||||
|
|
@ -17,22 +20,25 @@ var (
|
|||
)
|
||||
|
||||
type hybridStore struct {
|
||||
cache *orascontent.Memorystore
|
||||
provider content.Provider
|
||||
ingester content.Ingester
|
||||
cache *orascontent.Memorystore
|
||||
cachedMediaTypes []string
|
||||
provider content.Provider
|
||||
ingester content.Ingester
|
||||
}
|
||||
|
||||
func newHybridStoreFromProvider(provider content.Provider) *hybridStore {
|
||||
func newHybridStoreFromProvider(provider content.Provider, cachedMediaTypes []string) *hybridStore {
|
||||
return &hybridStore{
|
||||
cache: orascontent.NewMemoryStore(),
|
||||
provider: provider,
|
||||
cache: orascontent.NewMemoryStore(),
|
||||
cachedMediaTypes: cachedMediaTypes,
|
||||
provider: provider,
|
||||
}
|
||||
}
|
||||
|
||||
func newHybridStoreFromIngester(ingester content.Ingester) *hybridStore {
|
||||
func newHybridStoreFromIngester(ingester content.Ingester, cachedMediaTypes []string) *hybridStore {
|
||||
return &hybridStore{
|
||||
cache: orascontent.NewMemoryStore(),
|
||||
ingester: ingester,
|
||||
cache: orascontent.NewMemoryStore(),
|
||||
cachedMediaTypes: cachedMediaTypes,
|
||||
ingester: ingester,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -61,8 +67,16 @@ func (s *hybridStore) Writer(ctx context.Context, opts ...content.WriterOpt) (co
|
|||
}
|
||||
}
|
||||
|
||||
if isAllowedMediaType(wOpts.Desc.MediaType, ocispec.MediaTypeImageManifest, ocispec.MediaTypeImageIndex) || s.ingester == nil {
|
||||
return s.cache.Writer(ctx, opts...)
|
||||
if isAllowedMediaType(wOpts.Desc.MediaType, s.cachedMediaTypes...) || s.ingester == nil {
|
||||
cacheWriter, err := s.cache.Writer(ctx, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ingesterWriter, err := s.ingester.Writer(ctx, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newTeeWriter(wOpts.Desc, cacheWriter, ingesterWriter), nil
|
||||
}
|
||||
return s.ingester.Writer(ctx, opts...)
|
||||
}
|
||||
|
|
@ -117,3 +131,94 @@ func (s *hybridStore) ListStatuses(ctx context.Context, filters ...string) ([]co
|
|||
func (s *hybridStore) Abort(ctx context.Context, ref string) error {
|
||||
return errors.New("not yet implemented: Abort (content.Store interface)")
|
||||
}
|
||||
|
||||
// teeWriter tees the content to one or more content.Writer
|
||||
type teeWriter struct {
|
||||
writers []content.Writer
|
||||
digester digest.Digester
|
||||
status content.Status
|
||||
}
|
||||
|
||||
func newTeeWriter(desc ocispec.Descriptor, writers ...content.Writer) *teeWriter {
|
||||
now := time.Now()
|
||||
return &teeWriter{
|
||||
writers: writers,
|
||||
digester: digest.Canonical.Digester(),
|
||||
status: content.Status{
|
||||
Total: desc.Size,
|
||||
StartedAt: now,
|
||||
UpdatedAt: now,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (t *teeWriter) Close() error {
|
||||
g := new(errgroup.Group)
|
||||
for _, w := range t.writers {
|
||||
w := w // closure issues, see https://golang.org/doc/faq#closures_and_goroutines
|
||||
g.Go(func() error {
|
||||
return w.Close()
|
||||
})
|
||||
}
|
||||
return g.Wait()
|
||||
}
|
||||
|
||||
func (t *teeWriter) Write(p []byte) (n int, err error) {
|
||||
g := new(errgroup.Group)
|
||||
for _, w := range t.writers {
|
||||
w := w // closure issues, see https://golang.org/doc/faq#closures_and_goroutines
|
||||
g.Go(func() error {
|
||||
n, err := w.Write(p[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n != len(p) {
|
||||
return io.ErrShortWrite
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
err = g.Wait()
|
||||
n = len(p)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
_, _ = t.digester.Hash().Write(p[:n])
|
||||
t.status.Offset += int64(len(p))
|
||||
t.status.UpdatedAt = time.Now()
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Digest may return empty digest or panics until committed.
|
||||
func (t *teeWriter) Digest() digest.Digest {
|
||||
return t.digester.Digest()
|
||||
}
|
||||
|
||||
func (t *teeWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
|
||||
g := new(errgroup.Group)
|
||||
for _, w := range t.writers {
|
||||
w := w // closure issues, see https://golang.org/doc/faq#closures_and_goroutines
|
||||
g.Go(func() error {
|
||||
return w.Commit(ctx, size, expected, opts...)
|
||||
})
|
||||
}
|
||||
return g.Wait()
|
||||
}
|
||||
|
||||
// Status returns the current state of write
|
||||
func (t *teeWriter) Status() (content.Status, error) {
|
||||
return t.status, nil
|
||||
}
|
||||
|
||||
// Truncate updates the size of the target blob
|
||||
func (t *teeWriter) Truncate(size int64) error {
|
||||
g := new(errgroup.Group)
|
||||
for _, w := range t.writers {
|
||||
w := w // closure issues, see https://golang.org/doc/faq#closures_and_goroutines
|
||||
g.Go(func() error {
|
||||
return w.Truncate(size)
|
||||
})
|
||||
}
|
||||
return g.Wait()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ Aaron.L.Xu <likexu@harmonycloud.cn>
|
|||
Abdur Rehman <abdur_rehman@mentor.com>
|
||||
Abhinandan Prativadi <abhi@docker.com>
|
||||
Abin Shahab <ashahab@altiscale.com>
|
||||
Abreto FU <public@abreto.email>
|
||||
Ace Tang <aceapril@126.com>
|
||||
Addam Hardy <addam.hardy@gmail.com>
|
||||
Adolfo Ochagavía <aochagavia92@gmail.com>
|
||||
|
|
@ -17,12 +18,15 @@ Adrien Folie <folie.adrien@gmail.com>
|
|||
Ahmet Alp Balkan <ahmetb@microsoft.com>
|
||||
Aidan Feldman <aidan.feldman@gmail.com>
|
||||
Aidan Hobson Sayers <aidanhs@cantab.net>
|
||||
AJ Bowen <aj@gandi.net>
|
||||
Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
|
||||
AJ Bowen <aj@soulshake.net>
|
||||
Akhil Mohan <akhil.mohan@mayadata.io>
|
||||
Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
|
||||
Akim Demaille <akim.demaille@docker.com>
|
||||
Alan Thompson <cloojure@gmail.com>
|
||||
Albert Callarisa <shark234@gmail.com>
|
||||
Albin Kerouanton <albin@akerouanton.name>
|
||||
Aleksa Sarai <asarai@suse.de>
|
||||
Aleksander Piotrowski <apiotrowski312@gmail.com>
|
||||
Alessandro Boch <aboch@tetrationanalytics.com>
|
||||
Alex Mavrogiannis <alex.mavrogiannis@docker.com>
|
||||
Alex Mayer <amayer5125@gmail.com>
|
||||
|
|
@ -40,6 +44,7 @@ Amir Goldstein <amir73il@aquasec.com>
|
|||
Amit Krishnan <amit.krishnan@oracle.com>
|
||||
Amit Shukla <amit.shukla@docker.com>
|
||||
Amy Lindburg <amy.lindburg@docker.com>
|
||||
Anca Iordache <anca.iordache@docker.com>
|
||||
Anda Xu <anda.xu@docker.com>
|
||||
Andrea Luzzardi <aluzzardi@gmail.com>
|
||||
Andreas Köhler <andi5.py@gmx.net>
|
||||
|
|
@ -49,6 +54,7 @@ Andrew Macpherson <hopscotch23@gmail.com>
|
|||
Andrew McDonnell <bugs@andrewmcdonnell.net>
|
||||
Andrew Po <absourd.noise@gmail.com>
|
||||
Andrey Petrov <andrey.petrov@shazow.net>
|
||||
Andrii Berehuliak <berkusandrew@gmail.com>
|
||||
André Martins <aanm90@gmail.com>
|
||||
Andy Goldstein <agoldste@redhat.com>
|
||||
Andy Rothfusz <github@developersupport.net>
|
||||
|
|
@ -61,7 +67,9 @@ Antonis Kalipetis <akalipetis@gmail.com>
|
|||
Anusha Ragunathan <anusha.ragunathan@docker.com>
|
||||
Ao Li <la9249@163.com>
|
||||
Arash Deshmeh <adeshmeh@ca.ibm.com>
|
||||
Arko Dasgupta <arko.dasgupta@docker.com>
|
||||
Arnaud Porterie <arnaud.porterie@docker.com>
|
||||
Arthur Peka <arthur.peka@outlook.com>
|
||||
Ashwini Oruganti <ashwini.oruganti@gmail.com>
|
||||
Azat Khuyiyakhmetov <shadow_uz@mail.ru>
|
||||
Bardia Keyoumarsi <bkeyouma@ucsc.edu>
|
||||
|
|
@ -87,6 +95,7 @@ Brent Salisbury <brent.salisbury@docker.com>
|
|||
Bret Fisher <bret@bretfisher.com>
|
||||
Brian (bex) Exelbierd <bexelbie@redhat.com>
|
||||
Brian Goff <cpuguy83@gmail.com>
|
||||
Brian Wieder <brian@4wieders.com>
|
||||
Bryan Bess <squarejaw@bsbess.com>
|
||||
Bryan Boreham <bjboreham@gmail.com>
|
||||
Bryan Murphy <bmurphy1976@gmail.com>
|
||||
|
|
@ -95,6 +104,7 @@ Cameron Spear <cameronspear@gmail.com>
|
|||
Cao Weiwei <cao.weiwei30@zte.com.cn>
|
||||
Carlo Mion <mion00@gmail.com>
|
||||
Carlos Alexandro Becker <caarlos0@gmail.com>
|
||||
Carlos de Paula <me@carlosedp.com>
|
||||
Ce Gao <ce.gao@outlook.com>
|
||||
Cedric Davies <cedricda@microsoft.com>
|
||||
Cezar Sa Espinola <cezarsa@gmail.com>
|
||||
|
|
@ -128,26 +138,31 @@ Coenraad Loubser <coenraad@wish.org.za>
|
|||
Colin Hebert <hebert.colin@gmail.com>
|
||||
Collin Guarino <collin.guarino@gmail.com>
|
||||
Colm Hally <colmhally@gmail.com>
|
||||
Comical Derskeal <27731088+derskeal@users.noreply.github.com>
|
||||
Corey Farrell <git@cfware.com>
|
||||
Corey Quon <corey.quon@docker.com>
|
||||
Craig Wilhite <crwilhit@microsoft.com>
|
||||
Cristian Staretu <cristian.staretu@gmail.com>
|
||||
Daehyeok Mun <daehyeok@gmail.com>
|
||||
Dafydd Crosby <dtcrsby@gmail.com>
|
||||
Daisuke Ito <itodaisuke00@gmail.com>
|
||||
dalanlan <dalanlan925@gmail.com>
|
||||
Damien Nadé <github@livna.org>
|
||||
Dan Cotora <dan@bluevision.ro>
|
||||
Daniel Artine <daniel.artine@ufrj.br>
|
||||
Daniel Cassidy <mail@danielcassidy.me.uk>
|
||||
Daniel Dao <dqminh@cloudflare.com>
|
||||
Daniel Farrell <dfarrell@redhat.com>
|
||||
Daniel Gasienica <daniel@gasienica.ch>
|
||||
Daniel Goosen <daniel.goosen@surveysampling.com>
|
||||
Daniel Helfand <dhelfand@redhat.com>
|
||||
Daniel Hiltgen <daniel.hiltgen@docker.com>
|
||||
Daniel J Walsh <dwalsh@redhat.com>
|
||||
Daniel Nephin <dnephin@docker.com>
|
||||
Daniel Norberg <dano@spotify.com>
|
||||
Daniel Watkins <daniel@daniel-watkins.co.uk>
|
||||
Daniel Zhang <jmzwcn@gmail.com>
|
||||
Daniil Nikolenko <qoo2p5@gmail.com>
|
||||
Danny Berger <dpb587@gmail.com>
|
||||
Darren Shepherd <darren.s.shepherd@gmail.com>
|
||||
Darren Stahl <darst@microsoft.com>
|
||||
|
|
@ -180,13 +195,15 @@ Dima Stopel <dima@twistlock.com>
|
|||
Dimitry Andric <d.andric@activevideo.com>
|
||||
Ding Fei <dingfei@stars.org.cn>
|
||||
Diogo Monica <diogo@docker.com>
|
||||
Djordje Lukic <djordje.lukic@docker.com>
|
||||
Dmitry Gusev <dmitry.gusev@gmail.com>
|
||||
Dmitry Smirnov <onlyjob@member.fsf.org>
|
||||
Dmitry V. Krivenok <krivenok.dmitry@gmail.com>
|
||||
Dominik Braun <dominik.braun@nbsp.de>
|
||||
Don Kjer <don.kjer@gmail.com>
|
||||
Dong Chen <dongluo.chen@docker.com>
|
||||
Doug Davis <dug@us.ibm.com>
|
||||
Drew Erny <drew.erny@docker.com>
|
||||
Drew Erny <derny@mirantis.com>
|
||||
Ed Costello <epc@epcostello.com>
|
||||
Elango Sivanandam <elango.siva@docker.com>
|
||||
Eli Uriegas <eli.uriegas@docker.com>
|
||||
|
|
@ -249,6 +266,7 @@ Harald Albers <github@albersweb.de>
|
|||
Harold Cooper <hrldcpr@gmail.com>
|
||||
Harry Zhang <harryz@hyper.sh>
|
||||
He Simei <hesimei@zju.edu.cn>
|
||||
Hector S <hfsam88@gmail.com>
|
||||
Helen Xie <chenjg@harmonycloud.cn>
|
||||
Henning Sprang <henning.sprang@gmail.com>
|
||||
Henry N <henrynmail-github@yahoo.de>
|
||||
|
|
@ -256,6 +274,7 @@ Hernan Garcia <hernandanielg@gmail.com>
|
|||
Hongbin Lu <hongbin034@gmail.com>
|
||||
Hu Keping <hukeping@huawei.com>
|
||||
Huayi Zhang <irachex@gmail.com>
|
||||
Hugo Gabriel Eyherabide <hugogabriel.eyherabide@gmail.com>
|
||||
huqun <huqun@zju.edu.cn>
|
||||
Huu Nguyen <huu@prismskylabs.com>
|
||||
Hyzhou Zhy <hyzhou.zhy@alibaba-inc.com>
|
||||
|
|
@ -297,7 +316,7 @@ Jeremy Unruh <jeremybunruh@gmail.com>
|
|||
Jeremy Yallop <yallop@docker.com>
|
||||
Jeroen Franse <jeroenfranse@gmail.com>
|
||||
Jesse Adametz <jesseadametz@gmail.com>
|
||||
Jessica Frazelle <jessfraz@google.com>
|
||||
Jessica Frazelle <jess@oxide.computer>
|
||||
Jezeniel Zapanta <jpzapanta22@gmail.com>
|
||||
Jian Zhang <zhangjian.fnst@cn.fujitsu.com>
|
||||
Jie Luo <luo612@zju.edu.cn>
|
||||
|
|
@ -308,6 +327,7 @@ Jimmy Song <rootsongjc@gmail.com>
|
|||
jimmyxian <jimmyxian2004@yahoo.com.cn>
|
||||
Jintao Zhang <zhangjintao9020@gmail.com>
|
||||
Joao Fernandes <joao.fernandes@docker.com>
|
||||
Joe Abbey <joe.abbey@gmail.com>
|
||||
Joe Doliner <jdoliner@pachyderm.io>
|
||||
Joe Gordon <joe.gordon0@gmail.com>
|
||||
Joel Handwell <joelhandwell@gmail.com>
|
||||
|
|
@ -317,7 +337,7 @@ Johan Euphrosine <proppy@google.com>
|
|||
Johannes 'fish' Ziemke <github@freigeist.org>
|
||||
John Feminella <jxf@jxf.me>
|
||||
John Harris <john@johnharris.io>
|
||||
John Howard (VM) <John.Howard@microsoft.com>
|
||||
John Howard <github@lowenna.com>
|
||||
John Laswell <john.n.laswell@gmail.com>
|
||||
John Maguire <jmaguire@duosecurity.com>
|
||||
John Mulhausen <john@docker.com>
|
||||
|
|
@ -326,12 +346,15 @@ John Stephens <johnstep@docker.com>
|
|||
John Tims <john.k.tims@gmail.com>
|
||||
John V. Martinez <jvmatl@gmail.com>
|
||||
John Willis <john.willis@docker.com>
|
||||
Jon Johnson <jonjohnson@google.com>
|
||||
Jonatas Baldin <jonatas.baldin@gmail.com>
|
||||
Jonathan Boulle <jonathanboulle@gmail.com>
|
||||
Jonathan Lee <jonjohn1232009@gmail.com>
|
||||
Jonathan Lomas <jonathan@floatinglomas.ca>
|
||||
Jonathan McCrohan <jmccrohan@gmail.com>
|
||||
Jonh Wendell <jonh.wendell@redhat.com>
|
||||
Jordan Jennings <jjn2009@gmail.com>
|
||||
Jose J. Escobar <53836904+jescobar-docker@users.noreply.github.com>
|
||||
Joseph Kern <jkern@semafour.net>
|
||||
Josh Bodah <jb3689@yahoo.com>
|
||||
Josh Chorlton <jchorlton@gmail.com>
|
||||
|
|
@ -369,6 +392,7 @@ Kevin Kern <kaiwentan@harmonycloud.cn>
|
|||
Kevin Kirsche <Kev.Kirsche+GitHub@gmail.com>
|
||||
Kevin Meredith <kevin.m.meredith@gmail.com>
|
||||
Kevin Richardson <kevin@kevinrichardson.co>
|
||||
Kevin Woblick <mail@kovah.de>
|
||||
khaled souf <khaled.souf@gmail.com>
|
||||
Kim Eik <kim@heldig.org>
|
||||
Kir Kolyshkin <kolyshkin@gmail.com>
|
||||
|
|
@ -406,13 +430,16 @@ Luca Favatella <luca.favatella@erlang-solutions.com>
|
|||
Luca Marturana <lucamarturana@gmail.com>
|
||||
Lucas Chan <lucas-github@lucaschan.com>
|
||||
Luka Hartwig <mail@lukahartwig.de>
|
||||
Lukas Heeren <lukas-heeren@hotmail.com>
|
||||
Lukasz Zajaczkowski <Lukasz.Zajaczkowski@ts.fujitsu.com>
|
||||
Lydell Manganti <LydellManganti@users.noreply.github.com>
|
||||
Lénaïc Huard <lhuard@amadeus.com>
|
||||
Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
|
||||
Mabin <bin.ma@huawei.com>
|
||||
Maciej Kalisz <maciej.d.kalisz@gmail.com>
|
||||
Madhav Puri <madhav.puri@gmail.com>
|
||||
Madhu Venugopal <madhu@socketplane.io>
|
||||
Madhur Batra <madhurbatra097@gmail.com>
|
||||
Malte Janduda <mail@janduda.net>
|
||||
Manjunath A Kumatagi <mkumatag@in.ibm.com>
|
||||
Mansi Nahar <mmn4185@rit.edu>
|
||||
|
|
@ -422,6 +449,7 @@ Marco Mariani <marco.mariani@alterway.fr>
|
|||
Marco Vedovati <mvedovati@suse.com>
|
||||
Marcus Martins <marcus@docker.com>
|
||||
Marianna Tessel <mtesselh@gmail.com>
|
||||
Marius Ileana <marius.ileana@gmail.com>
|
||||
Marius Sturm <marius@graylog.com>
|
||||
Mark Oates <fl0yd@me.com>
|
||||
Marsh Macy <marsma@microsoft.com>
|
||||
|
|
@ -467,12 +495,14 @@ mikelinjie <294893458@qq.com>
|
|||
Mikhail Vasin <vasin@cloud-tv.ru>
|
||||
Milind Chawre <milindchawre@gmail.com>
|
||||
Mindaugas Rukas <momomg@gmail.com>
|
||||
Miroslav Gula <miroslav.gula@naytrolabs.com>
|
||||
Misty Stanley-Jones <misty@docker.com>
|
||||
Mohammad Banikazemi <mb@us.ibm.com>
|
||||
Mohammed Aaqib Ansari <maaquib@gmail.com>
|
||||
Mohini Anne Dsouza <mohini3917@gmail.com>
|
||||
Moorthy RS <rsmoorthy@gmail.com>
|
||||
Morgan Bauer <mbauer@us.ibm.com>
|
||||
Morten Hekkvang <morten.hekkvang@sbab.se>
|
||||
Moysés Borges <moysesb@gmail.com>
|
||||
Mrunal Patel <mrunalp@gmail.com>
|
||||
muicoder <muicoder@gmail.com>
|
||||
|
|
@ -503,9 +533,11 @@ Nishant Totla <nishanttotla@gmail.com>
|
|||
NIWA Hideyuki <niwa.niwa@nifty.ne.jp>
|
||||
Noah Treuhaft <noah.treuhaft@docker.com>
|
||||
O.S. Tezer <ostezer@gmail.com>
|
||||
Odin Ugedal <odin@ugedal.com>
|
||||
ohmystack <jun.jiang02@ele.me>
|
||||
Olle Jonsson <olle.jonsson@gmail.com>
|
||||
Olli Janatuinen <olli.janatuinen@gmail.com>
|
||||
Oscar Wieman <oscrx@icloud.com>
|
||||
Otto Kekäläinen <otto@seravo.fi>
|
||||
Ovidio Mallo <ovidio.mallo@gmail.com>
|
||||
Pascal Borreli <pascal@borreli.com>
|
||||
|
|
@ -515,6 +547,7 @@ Patrick Lang <plang@microsoft.com>
|
|||
Paul <paul9869@gmail.com>
|
||||
Paul Kehrer <paul.l.kehrer@gmail.com>
|
||||
Paul Lietar <paul@lietar.net>
|
||||
Paul Mulders <justinkb@gmail.com>
|
||||
Paul Weaver <pauweave@cisco.com>
|
||||
Pavel Pospisil <pospispa@gmail.com>
|
||||
Paweł Szczekutowicz <pszczekutowicz@gmail.com>
|
||||
|
|
@ -541,6 +574,7 @@ Qiang Huang <h.huangqiang@huawei.com>
|
|||
Qinglan Peng <qinglanpeng@zju.edu.cn>
|
||||
qudongfang <qudongfang@gmail.com>
|
||||
Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com>
|
||||
Rahul Zoldyck <rahulzoldyck@gmail.com>
|
||||
Ravi Shekhar Jethani <rsjethani@gmail.com>
|
||||
Ray Tsang <rayt@google.com>
|
||||
Reficul <xuzhenglun@gmail.com>
|
||||
|
|
@ -553,6 +587,7 @@ Richard Scothern <richard.scothern@gmail.com>
|
|||
Rick Wieman <git@rickw.nl>
|
||||
Ritesh H Shukla <sritesh@vmware.com>
|
||||
Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
|
||||
Rob Gulewich <rgulewich@netflix.com>
|
||||
Robert Wallis <smilingrob@gmail.com>
|
||||
Robin Naundorf <r.naundorf@fh-muenster.de>
|
||||
Robin Speekenbrink <robin@kingsquare.nl>
|
||||
|
|
@ -574,10 +609,14 @@ Sainath Grandhi <sainath.grandhi@intel.com>
|
|||
Sakeven Jiang <jc5930@sina.cn>
|
||||
Sally O'Malley <somalley@redhat.com>
|
||||
Sam Neirinck <sam@samneirinck.com>
|
||||
Samarth Shah <samashah@microsoft.com>
|
||||
Sambuddha Basu <sambuddhabasu1@gmail.com>
|
||||
Sami Tabet <salph.tabet@gmail.com>
|
||||
Samuel Cochran <sj26@sj26.com>
|
||||
Samuel Karp <skarp@amazon.com>
|
||||
Santhosh Manohar <santhosh@docker.com>
|
||||
Sargun Dhillon <sargun@netflix.com>
|
||||
Saswat Bhattacharya <sas.saswat@gmail.com>
|
||||
Scott Brenner <scott@scottbrenner.me>
|
||||
Scott Collier <emailscottcollier@gmail.com>
|
||||
Sean Christopherson <sean.j.christopherson@intel.com>
|
||||
|
|
@ -598,6 +637,7 @@ sidharthamani <sid@rancher.com>
|
|||
Silvin Lubecki <silvin.lubecki@docker.com>
|
||||
Simei He <hesimei@zju.edu.cn>
|
||||
Simon Ferquel <simon.ferquel@docker.com>
|
||||
Simon Heimberg <simon.heimberg@heimberg-ea.ch>
|
||||
Sindhu S <sindhus@live.in>
|
||||
Slava Semushin <semushin@redhat.com>
|
||||
Solomon Hykes <solomon@docker.com>
|
||||
|
|
@ -627,7 +667,10 @@ TAGOMORI Satoshi <tagomoris@gmail.com>
|
|||
taiji-tech <csuhqg@foxmail.com>
|
||||
Taylor Jones <monitorjbl@gmail.com>
|
||||
Tejaswini Duggaraju <naduggar@microsoft.com>
|
||||
Tengfei Wang <tfwang@alauda.io>
|
||||
Teppei Fukuda <knqyf263@gmail.com>
|
||||
Thatcher Peskens <thatcher@docker.com>
|
||||
Thibault Coupin <thibault.coupin@gmail.com>
|
||||
Thomas Gazagnaire <thomas@gazagnaire.org>
|
||||
Thomas Krzero <thomas.kovatchitch@gmail.com>
|
||||
Thomas Leonard <thomas.leonard@docker.com>
|
||||
|
|
@ -639,6 +682,7 @@ Tianyi Wang <capkurmagati@gmail.com>
|
|||
Tibor Vass <teabee89@gmail.com>
|
||||
Tim Dettrick <t.dettrick@uq.edu.au>
|
||||
Tim Hockin <thockin@google.com>
|
||||
Tim Sampson <tim@sampson.fi>
|
||||
Tim Smith <timbot@google.com>
|
||||
Tim Waugh <twaugh@redhat.com>
|
||||
Tim Wraight <tim.wraight@tangentlabs.co.uk>
|
||||
|
|
@ -663,9 +707,11 @@ Tristan Carel <tristan@cogniteev.com>
|
|||
Tycho Andersen <tycho@docker.com>
|
||||
Tycho Andersen <tycho@tycho.ws>
|
||||
uhayate <uhayate.gong@daocloud.io>
|
||||
Ulrich Bareth <ulrich.bareth@gmail.com>
|
||||
Ulysses Souza <ulysses.souza@docker.com>
|
||||
Umesh Yadav <umesh4257@gmail.com>
|
||||
Valentin Lorentz <progval+git@progval.net>
|
||||
Venkateswara Reddy Bukkasamudram <bukkasamudram@outlook.com>
|
||||
Veres Lajos <vlajos@gmail.com>
|
||||
Victor Vieux <victor.vieux@docker.com>
|
||||
Victoria Bialas <victoria.bialas@docker.com>
|
||||
|
|
@ -683,6 +729,7 @@ Wang Long <long.wanglong@huawei.com>
|
|||
Wang Ping <present.wp@icloud.com>
|
||||
Wang Xing <hzwangxing@corp.netease.com>
|
||||
Wang Yuexiao <wang.yuexiao@zte.com.cn>
|
||||
Wang Yumu <37442693@qq.com>
|
||||
Wataru Ishida <ishida.wataru@lab.ntt.co.jp>
|
||||
Wayne Song <wsong@docker.com>
|
||||
Wen Cheng Ma <wenchma@cn.ibm.com>
|
||||
|
|
@ -691,6 +738,7 @@ Wes Morgan <cap10morgan@gmail.com>
|
|||
Wewang Xiaorenfine <wang.xiaoren@zte.com.cn>
|
||||
William Henry <whenry@redhat.com>
|
||||
Xianglin Gao <xlgao@zju.edu.cn>
|
||||
Xiaodong Liu <liuxiaodong@loongson.cn>
|
||||
Xiaodong Zhang <a4012017@sina.com>
|
||||
Xiaoxi He <xxhe@alauda.io>
|
||||
Xinbo Weng <xihuanbo_0521@zju.edu.cn>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/cli/cli/config/credentials"
|
||||
|
|
@ -23,17 +24,37 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
configDir = os.Getenv("DOCKER_CONFIG")
|
||||
initConfigDir sync.Once
|
||||
configDir string
|
||||
homeDir string
|
||||
)
|
||||
|
||||
func init() {
|
||||
// resetHomeDir is used in testing to resets the "homeDir" package variable to
|
||||
// force re-lookup of the home directory between tests.
|
||||
func resetHomeDir() {
|
||||
homeDir = ""
|
||||
}
|
||||
|
||||
func getHomeDir() string {
|
||||
if homeDir == "" {
|
||||
homeDir = homedir.Get()
|
||||
}
|
||||
return homeDir
|
||||
}
|
||||
|
||||
func setConfigDir() {
|
||||
if configDir != "" {
|
||||
return
|
||||
}
|
||||
configDir = os.Getenv("DOCKER_CONFIG")
|
||||
if configDir == "" {
|
||||
configDir = filepath.Join(homedir.Get(), configFileDir)
|
||||
configDir = filepath.Join(getHomeDir(), configFileDir)
|
||||
}
|
||||
}
|
||||
|
||||
// Dir returns the directory the configuration file is stored in
|
||||
func Dir() string {
|
||||
initConfigDir.Do(setConfigDir)
|
||||
return configDir
|
||||
}
|
||||
|
||||
|
|
@ -88,11 +109,7 @@ func Load(configDir string) (*configfile.ConfigFile, error) {
|
|||
configFile := configfile.New(filename)
|
||||
|
||||
// Try happy path first - latest config file
|
||||
if _, err := os.Stat(filename); err == nil {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return configFile, errors.Wrap(err, filename)
|
||||
}
|
||||
if file, err := os.Open(filename); err == nil {
|
||||
defer file.Close()
|
||||
err = configFile.LoadFromReader(file)
|
||||
if err != nil {
|
||||
|
|
@ -106,22 +123,12 @@ func Load(configDir string) (*configfile.ConfigFile, error) {
|
|||
}
|
||||
|
||||
// Can't find latest config file so check for the old one
|
||||
homedir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return configFile, errors.Wrap(err, oldConfigfile)
|
||||
}
|
||||
confFile := filepath.Join(homedir, oldConfigfile)
|
||||
if _, err := os.Stat(confFile); err != nil {
|
||||
return configFile, nil // missing file is not an error
|
||||
}
|
||||
file, err := os.Open(confFile)
|
||||
if err != nil {
|
||||
return configFile, errors.Wrap(err, filename)
|
||||
}
|
||||
defer file.Close()
|
||||
err = configFile.LegacyLoadFromReader(file)
|
||||
if err != nil {
|
||||
return configFile, errors.Wrap(err, filename)
|
||||
filename = filepath.Join(getHomeDir(), oldConfigfile)
|
||||
if file, err := os.Open(filename); err == nil {
|
||||
defer file.Close()
|
||||
if err := configFile.LegacyLoadFromReader(file); err != nil {
|
||||
return configFile, errors.Wrap(err, filename)
|
||||
}
|
||||
}
|
||||
return configFile, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,5 +14,6 @@ go_library(
|
|||
"//vendor/github.com/docker/cli/cli/config/credentials:go_default_library",
|
||||
"//vendor/github.com/docker/cli/cli/config/types:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
"//vendor/github.com/sirupsen/logrus:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/docker/cli/cli/config/credentials"
|
||||
"github.com/docker/cli/cli/config/types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -118,7 +119,7 @@ func (configFile *ConfigFile) LegacyLoadFromReader(configData io.Reader) error {
|
|||
// LoadFromReader reads the configuration data given and sets up the auth config
|
||||
// information with given directory and populates the receiver object
|
||||
func (configFile *ConfigFile) LoadFromReader(configData io.Reader) error {
|
||||
if err := json.NewDecoder(configData).Decode(&configFile); err != nil {
|
||||
if err := json.NewDecoder(configData).Decode(&configFile); err != nil && !errors.Is(err, io.EOF) {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
|
|
@ -168,6 +169,13 @@ func (configFile *ConfigFile) SaveToWriter(writer io.Writer) error {
|
|||
configFile.AuthConfigs = tmpAuthConfigs
|
||||
defer func() { configFile.AuthConfigs = saveAuthConfigs }()
|
||||
|
||||
// User-Agent header is automatically set, and should not be stored in the configuration
|
||||
for v := range configFile.HTTPHeaders {
|
||||
if strings.EqualFold(v, "User-Agent") {
|
||||
delete(configFile.HTTPHeaders, v)
|
||||
}
|
||||
}
|
||||
|
||||
data, err := json.MarshalIndent(configFile, "", "\t")
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -177,7 +185,7 @@ func (configFile *ConfigFile) SaveToWriter(writer io.Writer) error {
|
|||
}
|
||||
|
||||
// Save encodes and writes out all the authorization information
|
||||
func (configFile *ConfigFile) Save() error {
|
||||
func (configFile *ConfigFile) Save() (retErr error) {
|
||||
if configFile.Filename == "" {
|
||||
return errors.Errorf("Can't save config with empty filename")
|
||||
}
|
||||
|
|
@ -190,16 +198,33 @@ func (configFile *ConfigFile) Save() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
temp.Close()
|
||||
if retErr != nil {
|
||||
if err := os.Remove(temp.Name()); err != nil {
|
||||
logrus.WithError(err).WithField("file", temp.Name()).Debug("Error cleaning up temp file")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
err = configFile.SaveToWriter(temp)
|
||||
temp.Close()
|
||||
if err != nil {
|
||||
os.Remove(temp.Name())
|
||||
return err
|
||||
}
|
||||
// Try copying the current config file (if any) ownership and permissions
|
||||
copyFilePermissions(configFile.Filename, temp.Name())
|
||||
|
||||
return os.Rename(temp.Name(), configFile.Filename)
|
||||
if err := temp.Close(); err != nil {
|
||||
return errors.Wrap(err, "error closing temp file")
|
||||
}
|
||||
|
||||
// Handle situation where the configfile is a symlink
|
||||
cfgFile := configFile.Filename
|
||||
if f, err := os.Readlink(cfgFile); err == nil {
|
||||
cfgFile = f
|
||||
}
|
||||
|
||||
// Try copying the current config file (if any) ownership and permissions
|
||||
copyFilePermissions(cfgFile, temp.Name())
|
||||
return os.Rename(temp.Name(), cfgFile)
|
||||
}
|
||||
|
||||
// ParseProxyConfig computes proxy configuration by retrieving the config for the provided host and
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue