Merge pull request #89710 from dims/update-hcsshim-to-latest

Update hcsshim to latest - v0.8.9
This commit is contained in:
Kubernetes Prow Robot 2020-05-28 16:37:29 -07:00 committed by GitHub
commit e9f560d720
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
164 changed files with 10806 additions and 1867 deletions

205
LICENSES/vendor/github.com/containerd/cgroups/LICENSE generated vendored Normal file
View File

@ -0,0 +1,205 @@
= vendor/github.com/containerd/cgroups licensed under: =
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
= vendor/github.com/containerd/cgroups/LICENSE 86d3f3a95c324c9479bd8986968f4327

8
go.mod
View File

@ -15,7 +15,7 @@ require (
github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20200415212048-7901bc822317 github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20200415212048-7901bc822317
github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5
github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d github.com/Microsoft/hcsshim v0.8.9
github.com/PuerkitoBio/purell v1.1.1 github.com/PuerkitoBio/purell v1.1.1
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e
github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7 // indirect github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7 // indirect
@ -166,7 +166,7 @@ replace (
github.com/JeffAshton/win_pdh => github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab github.com/JeffAshton/win_pdh => github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab
github.com/MakeNowJust/heredoc => github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd github.com/MakeNowJust/heredoc => github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd
github.com/Microsoft/go-winio => github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 github.com/Microsoft/go-winio => github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5
github.com/Microsoft/hcsshim => github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d github.com/Microsoft/hcsshim => github.com/Microsoft/hcsshim v0.8.9
github.com/NYTimes/gziphandler => github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 github.com/NYTimes/gziphandler => github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46
github.com/PuerkitoBio/purell => github.com/PuerkitoBio/purell v1.1.1 github.com/PuerkitoBio/purell => github.com/PuerkitoBio/purell v1.1.1
github.com/PuerkitoBio/urlesc => github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 github.com/PuerkitoBio/urlesc => github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578
@ -200,8 +200,12 @@ replace (
github.com/cockroachdb/datadriven => github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa github.com/cockroachdb/datadriven => github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa
github.com/codegangsta/negroni => github.com/codegangsta/negroni v1.0.0 github.com/codegangsta/negroni => github.com/codegangsta/negroni v1.0.0
github.com/container-storage-interface/spec => github.com/container-storage-interface/spec v1.2.0 github.com/container-storage-interface/spec => github.com/container-storage-interface/spec v1.2.0
github.com/containerd/cgroups => github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f
github.com/containerd/console => github.com/containerd/console v1.0.0 github.com/containerd/console => github.com/containerd/console v1.0.0
github.com/containerd/containerd => github.com/containerd/containerd v1.3.3 github.com/containerd/containerd => github.com/containerd/containerd v1.3.3
github.com/containerd/continuity => github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc
github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448
github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3
github.com/containerd/ttrpc => github.com/containerd/ttrpc v1.0.0 github.com/containerd/ttrpc => github.com/containerd/ttrpc v1.0.0
github.com/containerd/typeurl => github.com/containerd/typeurl v1.0.0 github.com/containerd/typeurl => github.com/containerd/typeurl v1.0.0
github.com/containernetworking/cni => github.com/containernetworking/cni v0.7.1 github.com/containernetworking/cni => github.com/containernetworking/cni v0.7.1

9
go.sum
View File

@ -38,8 +38,8 @@ 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 v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= 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.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d h1:u64+IetywsPQ0gJ/4cXBJ/KiXV9xTKRMoaCOzW9PI3g= github.com/Microsoft/hcsshim v0.8.9 h1:VrfodqvztU8YSOvygU+DN1BGaSGxmrNfqOv5oOuX2Bk=
github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
@ -93,10 +93,15 @@ github.com/codegangsta/negroni v1.0.0 h1:+aYywywx4bnKXWvoWtRfJ91vC59NbEhEY03sZjQ
github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0= github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0=
github.com/container-storage-interface/spec v1.2.0 h1:bD9KIVgaVKKkQ/UbVUY9kCaH/CJbhNxe0eeB4JeJV2s= github.com/container-storage-interface/spec v1.2.0 h1:bD9KIVgaVKKkQ/UbVUY9kCaH/CJbhNxe0eeB4JeJV2s=
github.com/container-storage-interface/spec v1.2.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4= github.com/container-storage-interface/spec v1.2.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
github.com/containerd/console v1.0.0 h1:fU3UuQapBs+zLJu82NhR11Rif1ny2zfMMAyPJzSN5tQ= github.com/containerd/console v1.0.0 h1:fU3UuQapBs+zLJu82NhR11Rif1ny2zfMMAyPJzSN5tQ=
github.com/containerd/console v1.0.0/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= github.com/containerd/console v1.0.0/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
github.com/containerd/containerd v1.3.3 h1:LoIzb5y9x5l8VKAlyrbusNPXqBY0+kviRloxFUMFwKc= github.com/containerd/containerd v1.3.3 h1:LoIzb5y9x5l8VKAlyrbusNPXqBY0+kviRloxFUMFwKc=
github.com/containerd/containerd v1.3.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
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/ttrpc v1.0.0 h1:NY8Zk2i7TpkLxrkOASo+KTFq9iNCEmMH2/ZG9OuOw6k= github.com/containerd/ttrpc v1.0.0 h1:NY8Zk2i7TpkLxrkOASo+KTFq9iNCEmMH2/ZG9OuOw6k=
github.com/containerd/ttrpc v1.0.0/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v1.0.0/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/typeurl v1.0.0 h1:7LMH7LfEmpWeCkGcIputvd4P0Rnd0LrIv1Jk2s5oobs= github.com/containerd/typeurl v1.0.0 h1:7LMH7LfEmpWeCkGcIputvd4P0Rnd0LrIv1Jk2s5oobs=

1
vendor/BUILD vendored
View File

@ -56,6 +56,7 @@ filegroup(
"//vendor/github.com/cilium/ebpf:all-srcs", "//vendor/github.com/cilium/ebpf:all-srcs",
"//vendor/github.com/clusterhq/flocker-go:all-srcs", "//vendor/github.com/clusterhq/flocker-go:all-srcs",
"//vendor/github.com/container-storage-interface/spec/lib/go/csi:all-srcs", "//vendor/github.com/container-storage-interface/spec/lib/go/csi:all-srcs",
"//vendor/github.com/containerd/cgroups/stats/v1:all-srcs",
"//vendor/github.com/containerd/console:all-srcs", "//vendor/github.com/containerd/console:all-srcs",
"//vendor/github.com/containerd/containerd/api/services/containers/v1:all-srcs", "//vendor/github.com/containerd/containerd/api/services/containers/v1:all-srcs",
"//vendor/github.com/containerd/containerd/api/services/tasks/v1:all-srcs", "//vendor/github.com/containerd/containerd/api/services/tasks/v1:all-srcs",

View File

@ -40,6 +40,7 @@ filegroup(
srcs = [ srcs = [
":package-srcs", ":package-srcs",
"//vendor/github.com/Microsoft/go-winio/pkg/guid:all-srcs", "//vendor/github.com/Microsoft/go-winio/pkg/guid:all-srcs",
"//vendor/github.com/Microsoft/go-winio/vhd:all-srcs",
], ],
tags = ["automanaged"], tags = ["automanaged"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],

27
vendor/github.com/Microsoft/go-winio/vhd/BUILD generated vendored Normal file
View File

@ -0,0 +1,27 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"vhd.go",
"zvhd.go",
],
importmap = "k8s.io/kubernetes/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"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

151
vendor/github.com/Microsoft/go-winio/vhd/vhd.go generated vendored Normal file
View File

@ -0,0 +1,151 @@
// +build windows
package vhd
import "syscall"
//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
}
type (
createVirtualDiskFlag uint32
VirtualDiskAccessMask uint32
VirtualDiskFlag uint32
)
const (
// Flags for creating a VHD (not exported)
createVirtualDiskFlagNone createVirtualDiskFlag = 0
createVirtualDiskFlagFullPhysicalAllocation createVirtualDiskFlag = 1
createVirtualDiskFlagPreventWritesToSourceDisk createVirtualDiskFlag = 2
createVirtualDiskFlagDoNotCopyMetadataFromParent createVirtualDiskFlag = 4
// 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
MaximumSize uint64
BlockSizeInBytes uint32
SectorSizeInBytes uint32
ParentPath *uint16 // string
SourcePath *uint16 // string
OpenFlags uint32
ParentVirtualStorageType virtualStorageType
SourceVirtualStorageType virtualStorageType
ResiliencyGUID [16]byte // GUID
}
type createVirtualDiskParameters struct {
Version uint32 // Must always be set to 2
Version2 createVersion2
}
type openVersion2 struct {
GetInfoOnly int32 // bool but 4-byte aligned
ReadOnly int32 // bool but 4-byte aligned
ResiliencyGUID [16]byte // GUID
}
type openVirtualDiskParameters struct {
Version uint32 // Must always be set to 2
Version2 openVersion2
}
// CreateVhdx will 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{
Version: 2,
Version2: createVersion2{
MaximumSize: uint64(maxSizeInGb) * 1024 * 1024 * 1024,
BlockSizeInBytes: blockSizeInMb * 1024 * 1024,
},
}
if err := createVirtualDisk(
&defaultType,
path,
uint32(VirtualDiskAccessNone),
nil,
uint32(createVirtualDiskFlagNone),
0,
&parameters,
nil,
&handle); 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`.
func DetachVhd(path string) error {
handle, err := OpenVirtualDisk(
path,
VirtualDiskAccessNone,
OpenVirtualDiskFlagCachedIO|OpenVirtualDiskFlagIgnoreRelativeParentLocator)
if err != nil {
return err
}
defer syscall.CloseHandle(handle)
return detachVirtualDisk(handle, 0, 0)
}
// 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),
&parameters,
&handle); err != nil {
return 0, err
}
return handle, nil
}

99
vendor/github.com/Microsoft/go-winio/vhd/zvhd.go generated vendored Normal file
View File

@ -0,0 +1,99 @@
// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
package vhd
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 (
modVirtDisk = windows.NewLazySystemDLL("VirtDisk.dll")
procCreateVirtualDisk = modVirtDisk.NewProc("CreateVirtualDisk")
procOpenVirtualDisk = modVirtDisk.NewProc("OpenVirtualDisk")
procDetachVirtualDisk = modVirtDisk.NewProc("DetachVirtualDisk")
)
func createVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *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)
}
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)))
if r1 != 0 {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func openVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, flags 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)
}
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)))
if r1 != 0 {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
}
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))
if r1 != 0 {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
}
return
}

View File

@ -21,7 +21,7 @@ go_library(
importpath = "github.com/Microsoft/hcsshim", importpath = "github.com/Microsoft/hcsshim",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//vendor/github.com/Microsoft/hcsshim/internal/guid:go_default_library", "//vendor/github.com/Microsoft/go-winio/pkg/guid:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/hcs:go_default_library", "//vendor/github.com/Microsoft/hcsshim/internal/hcs:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/hcserror:go_default_library", "//vendor/github.com/Microsoft/hcsshim/internal/hcserror:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/hns:go_default_library", "//vendor/github.com/Microsoft/hcsshim/internal/hns:go_default_library",
@ -49,21 +49,25 @@ filegroup(
":package-srcs", ":package-srcs",
"//vendor/github.com/Microsoft/hcsshim/hcn:all-srcs", "//vendor/github.com/Microsoft/hcsshim/hcn:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/cni:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/cni:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/guid:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/cow:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/hcs:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/hcs:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/hcserror:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/hcserror:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/hns:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/hns:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/interop:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/interop:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/log:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/logfields:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/logfields:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/longpath:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/longpath:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/mergemaps:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/mergemaps:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/oc:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/regstate:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/regstate:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/runhcs:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/runhcs:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/safefile:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/safefile:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/schema1:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/schema1:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/schema2:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/schema2:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/timeout:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/timeout:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/vmcompute:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/internal/wclayer:all-srcs", "//vendor/github.com/Microsoft/hcsshim/internal/wclayer:all-srcs",
"//vendor/github.com/Microsoft/hcsshim/osversion:all-srcs",
], ],
tags = ["automanaged"], tags = ["automanaged"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],

3
vendor/github.com/Microsoft/hcsshim/CODEOWNERS generated vendored Normal file
View File

@ -0,0 +1,3 @@
* @microsoft/containerplat
/hcn/* @nagiesek

View File

@ -29,6 +29,11 @@ plugins = ["grpc", "fieldpath"]
"google/protobuf/field_mask.proto" = "github.com/gogo/protobuf/types" "google/protobuf/field_mask.proto" = "github.com/gogo/protobuf/types"
"google/protobuf/timestamp.proto" = "github.com/gogo/protobuf/types" "google/protobuf/timestamp.proto" = "github.com/gogo/protobuf/types"
"google/protobuf/duration.proto" = "github.com/gogo/protobuf/types" "google/protobuf/duration.proto" = "github.com/gogo/protobuf/types"
"github/containerd/cgroups/stats/v1/metrics.proto" = "github.com/containerd/cgroups/stats/v1"
[[overrides]]
prefixes = ["github.com/Microsoft/hcsshim/internal/shimdiag"]
plugins = ["ttrpc"]
# Lock down runhcs config # Lock down runhcs config
@ -39,3 +44,11 @@ ignore_files = [
"google/protobuf/descriptor.proto", "google/protobuf/descriptor.proto",
"gogoproto/gogo.proto" "gogoproto/gogo.proto"
] ]
[[descriptors]]
prefix = "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats"
target = "cmd/containerd-shim-runhcs-v1/stats/next.pb.txt"
ignore_files = [
"google/protobuf/descriptor.proto",
"gogoproto/gogo.proto"
]

View File

@ -2,7 +2,7 @@
[![Build status](https://ci.appveyor.com/api/projects/status/nbcw28mnkqml0loa/branch/master?svg=true)](https://ci.appveyor.com/project/WindowsVirtualization/hcsshim/branch/master) [![Build status](https://ci.appveyor.com/api/projects/status/nbcw28mnkqml0loa/branch/master?svg=true)](https://ci.appveyor.com/project/WindowsVirtualization/hcsshim/branch/master)
This package contains the Golang interface for using the Windows [Host Compute Service](https://blogs.technet.microsoft.com/virtualization/2017/01/27/introducing-the-host-compute-service-hcs/) (HCS) to launch and manage [Windows Containers](https://docs.microsoft.com/en-us/virtualization/windowscontainers/about/). It also contains other helpers and functions for managing Windows Containers such as the Golang interface for the Host Network Service (HNS). This package contains the Golang interface for using the Windows [Host Compute Service](https://techcommunity.microsoft.com/t5/containers/introducing-the-host-compute-service-hcs/ba-p/382332) (HCS) to launch and manage [Windows Containers](https://docs.microsoft.com/en-us/virtualization/windowscontainers/about/). It also contains other helpers and functions for managing Windows Containers such as the Golang interface for the Host Network Service (HNS).
It is primarily used in the [Moby Project](https://github.com/moby/moby), but it can be freely used by other projects as well. It is primarily used in the [Moby Project](https://github.com/moby/moby), but it can be freely used by other projects as well.
@ -16,6 +16,11 @@ When you submit a pull request, a CLA-bot will automatically determine whether y
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA. provided by the bot. You will only need to do this once across all repos using our CLA.
We also ask that contributors [sign their commits](https://git-scm.com/docs/git-commit) using `git commit -s` or `git commit --signoff` to certify they either authored the work themselves or otherwise have permission to use it in this project.
## Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

View File

@ -6,9 +6,9 @@ clone_folder: c:\gopath\src\github.com\Microsoft\hcsshim
environment: environment:
GOPATH: c:\gopath GOPATH: c:\gopath
PATH: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;%GOPATH%\bin;C:\gometalinter-2.0.12-windows-amd64;%PATH% PATH: "%GOPATH%\\bin;C:\\gometalinter-2.0.12-windows-amd64;%PATH%"
stack: go 1.12.2 stack: go 1.13.4
build_script: build_script:
- appveyor DownloadFile https://github.com/alecthomas/gometalinter/releases/download/v2.0.12/gometalinter-2.0.12-windows-amd64.zip - appveyor DownloadFile https://github.com/alecthomas/gometalinter/releases/download/v2.0.12/gometalinter-2.0.12-windows-amd64.zip
@ -22,10 +22,12 @@ build_script:
- go build ./internal/tools/uvmboot - go build ./internal/tools/uvmboot
- go build ./internal/tools/zapdir - go build ./internal/tools/zapdir
- go test -v ./... -tags admin - go test -v ./... -tags admin
- go test -c ./test/containerd-shim-runhcs-v1/ -tags functional - cd test
- go test -c ./test/cri-containerd/ -tags functional - go test -v ./internal -tags admin
- go test -c ./test/functional/ -tags functional - go test -c ./containerd-shim-runhcs-v1/ -tags functional
- go test -c ./test/runhcs/ -tags functional - go test -c ./cri-containerd/ -tags functional
- go test -c ./functional/ -tags functional
- go test -c ./runhcs/ -tags functional
artifacts: artifacts:
- path: 'containerd-shim-runhcs-v1.exe' - path: 'containerd-shim-runhcs-v1.exe'
@ -35,7 +37,7 @@ artifacts:
- path: 'grantvmgroupaccess.exe' - path: 'grantvmgroupaccess.exe'
- path: 'uvmboot.exe' - path: 'uvmboot.exe'
- path: 'zapdir.exe' - path: 'zapdir.exe'
- path: 'containerd-shim-runhcs-v1.test.exe' - path: './test/containerd-shim-runhcs-v1.test.exe'
- path: 'cri-containerd.test.exe' - path: './test/cri-containerd.test.exe'
- path: 'functional.test.exe' - path: './test/functional.test.exe'
- path: 'runhcs.test.exe' - path: './test/runhcs.test.exe'

View File

@ -1,8 +1,10 @@
package hcsshim package hcsshim
import ( import (
"context"
"fmt" "fmt"
"os" "os"
"sync"
"time" "time"
"github.com/Microsoft/hcsshim/internal/hcs" "github.com/Microsoft/hcsshim/internal/hcs"
@ -53,6 +55,9 @@ type ResourceModificationRequestResponse = schema1.ResourceModificationRequestRe
type container struct { type container struct {
system *hcs.System system *hcs.System
waitOnce sync.Once
waitErr error
waitCh chan struct{}
} }
// createComputeSystemAdditionalJSON is read from the environment at initialisation // createComputeSystemAdditionalJSON is read from the environment at initialisation
@ -71,61 +76,87 @@ func CreateContainer(id string, c *ContainerConfig) (Container, error) {
return nil, fmt.Errorf("failed to merge additional JSON '%s': %s", createContainerAdditionalJSON, err) return nil, fmt.Errorf("failed to merge additional JSON '%s': %s", createContainerAdditionalJSON, err)
} }
system, err := hcs.CreateComputeSystem(id, fullConfig) system, err := hcs.CreateComputeSystem(context.Background(), id, fullConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &container{system}, err return &container{system: system}, err
} }
// OpenContainer opens an existing container by ID. // OpenContainer opens an existing container by ID.
func OpenContainer(id string) (Container, error) { func OpenContainer(id string) (Container, error) {
system, err := hcs.OpenComputeSystem(id) system, err := hcs.OpenComputeSystem(context.Background(), id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &container{system}, err return &container{system: system}, err
} }
// GetContainers gets a list of the containers on the system that match the query // GetContainers gets a list of the containers on the system that match the query
func GetContainers(q ComputeSystemQuery) ([]ContainerProperties, error) { func GetContainers(q ComputeSystemQuery) ([]ContainerProperties, error) {
return hcs.GetComputeSystems(q) return hcs.GetComputeSystems(context.Background(), q)
} }
// Start synchronously starts the container. // Start synchronously starts the container.
func (container *container) Start() error { func (container *container) Start() error {
return convertSystemError(container.system.Start(), container) return convertSystemError(container.system.Start(context.Background()), container)
} }
// Shutdown requests a container shutdown, but it may not actually be shutdown until Wait() succeeds. // Shutdown requests a container shutdown, but it may not actually be shutdown until Wait() succeeds.
func (container *container) Shutdown() error { func (container *container) Shutdown() error {
return convertSystemError(container.system.Shutdown(), container) err := container.system.Shutdown(context.Background())
if err != nil {
return convertSystemError(err, container)
}
return &ContainerError{Container: container, Err: ErrVmcomputeOperationPending, Operation: "hcsshim::ComputeSystem::Shutdown"}
} }
// Terminate requests a container terminate, but it may not actually be terminated until Wait() succeeds. // Terminate requests a container terminate, but it may not actually be terminated until Wait() succeeds.
func (container *container) Terminate() error { func (container *container) Terminate() error {
return convertSystemError(container.system.Terminate(), container) err := container.system.Terminate(context.Background())
if err != nil {
return convertSystemError(err, container)
}
return &ContainerError{Container: container, Err: ErrVmcomputeOperationPending, Operation: "hcsshim::ComputeSystem::Terminate"}
} }
// Waits synchronously waits for the container to shutdown or terminate. // Waits synchronously waits for the container to shutdown or terminate.
func (container *container) Wait() error { func (container *container) Wait() error {
return convertSystemError(container.system.Wait(), container) err := container.system.Wait()
if err == nil {
err = container.system.ExitError()
}
return convertSystemError(err, container)
} }
// WaitTimeout synchronously waits for the container to terminate or the duration to elapse. It // WaitTimeout synchronously waits for the container to terminate or the duration to elapse. It
// returns false if timeout occurs. // returns false if timeout occurs.
func (container *container) WaitTimeout(t time.Duration) error { func (container *container) WaitTimeout(timeout time.Duration) error {
return convertSystemError(container.system.WaitTimeout(t), container) container.waitOnce.Do(func() {
container.waitCh = make(chan struct{})
go func() {
container.waitErr = container.Wait()
close(container.waitCh)
}()
})
t := time.NewTimer(timeout)
defer t.Stop()
select {
case <-t.C:
return &ContainerError{Container: container, Err: ErrTimeout, Operation: "hcsshim::ComputeSystem::Wait"}
case <-container.waitCh:
return container.waitErr
}
} }
// Pause pauses the execution of a container. // Pause pauses the execution of a container.
func (container *container) Pause() error { func (container *container) Pause() error {
return convertSystemError(container.system.Pause(), container) return convertSystemError(container.system.Pause(context.Background()), container)
} }
// Resume resumes the execution of a container. // Resume resumes the execution of a container.
func (container *container) Resume() error { func (container *container) Resume() error {
return convertSystemError(container.system.Resume(), container) return convertSystemError(container.system.Resume(context.Background()), container)
} }
// HasPendingUpdates returns true if the container has updates pending to install // HasPendingUpdates returns true if the container has updates pending to install
@ -135,7 +166,7 @@ func (container *container) HasPendingUpdates() (bool, error) {
// Statistics returns statistics for the container. This is a legacy v1 call // Statistics returns statistics for the container. This is a legacy v1 call
func (container *container) Statistics() (Statistics, error) { func (container *container) Statistics() (Statistics, error) {
properties, err := container.system.Properties(schema1.PropertyTypeStatistics) properties, err := container.system.Properties(context.Background(), schema1.PropertyTypeStatistics)
if err != nil { if err != nil {
return Statistics{}, convertSystemError(err, container) return Statistics{}, convertSystemError(err, container)
} }
@ -145,7 +176,7 @@ func (container *container) Statistics() (Statistics, error) {
// ProcessList returns an array of ProcessListItems for the container. This is a legacy v1 call // ProcessList returns an array of ProcessListItems for the container. This is a legacy v1 call
func (container *container) ProcessList() ([]ProcessListItem, error) { func (container *container) ProcessList() ([]ProcessListItem, error) {
properties, err := container.system.Properties(schema1.PropertyTypeProcessList) properties, err := container.system.Properties(context.Background(), schema1.PropertyTypeProcessList)
if err != nil { if err != nil {
return nil, convertSystemError(err, container) return nil, convertSystemError(err, container)
} }
@ -155,7 +186,7 @@ func (container *container) ProcessList() ([]ProcessListItem, error) {
// This is a legacy v1 call // This is a legacy v1 call
func (container *container) MappedVirtualDisks() (map[int]MappedVirtualDiskController, error) { func (container *container) MappedVirtualDisks() (map[int]MappedVirtualDiskController, error) {
properties, err := container.system.Properties(schema1.PropertyTypeMappedVirtualDisk) properties, err := container.system.Properties(context.Background(), schema1.PropertyTypeMappedVirtualDisk)
if err != nil { if err != nil {
return nil, convertSystemError(err, container) return nil, convertSystemError(err, container)
} }
@ -165,20 +196,20 @@ func (container *container) MappedVirtualDisks() (map[int]MappedVirtualDiskContr
// CreateProcess launches a new process within the container. // CreateProcess launches a new process within the container.
func (container *container) CreateProcess(c *ProcessConfig) (Process, error) { func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
p, err := container.system.CreateProcess(c) p, err := container.system.CreateProcess(context.Background(), c)
if err != nil { if err != nil {
return nil, convertSystemError(err, container) return nil, convertSystemError(err, container)
} }
return &process{p}, nil return &process{p: p.(*hcs.Process)}, nil
} }
// OpenProcess gets an interface to an existing process within the container. // OpenProcess gets an interface to an existing process within the container.
func (container *container) OpenProcess(pid int) (Process, error) { func (container *container) OpenProcess(pid int) (Process, error) {
p, err := container.system.OpenProcess(pid) p, err := container.system.OpenProcess(context.Background(), pid)
if err != nil { if err != nil {
return nil, convertSystemError(err, container) return nil, convertSystemError(err, container)
} }
return &process{p}, nil return &process{p: p}, nil
} }
// Close cleans up any state associated with the container but does not terminate or wait for it. // Close cleans up any state associated with the container but does not terminate or wait for it.
@ -188,5 +219,5 @@ func (container *container) Close() error {
// Modify the System // Modify the System
func (container *container) Modify(config *ResourceModificationRequestResponse) error { func (container *container) Modify(config *ResourceModificationRequestResponse) error {
return convertSystemError(container.system.Modify(config), container) return convertSystemError(container.system.Modify(context.Background(), config), container)
} }

35
vendor/github.com/Microsoft/hcsshim/go.mod generated vendored Normal file
View File

@ -0,0 +1,35 @@
module github.com/Microsoft/hcsshim
go 1.13
require (
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1
github.com/containerd/containerd v1.3.2
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 // indirect
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd
github.com/gogo/protobuf v1.3.1
github.com/golang/protobuf v1.3.2 // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2 // indirect
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f // indirect
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700
github.com/pkg/errors v0.8.1
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7 // indirect
github.com/sirupsen/logrus v1.4.2
github.com/stretchr/testify v1.4.0 // indirect
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5
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-20190916202348-b4ddaad3f8a3
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
gopkg.in/yaml.v2 v2.2.8 // indirect
gotest.tools v2.2.0+incompatible // indirect
)

149
vendor/github.com/Microsoft/hcsshim/go.sum generated vendored Normal file
View File

@ -0,0 +1,149 @@
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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 h1:uict5mhHFTzKLUCufdSLym7z/J0CbBJT59lYbP9wtbg=
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
github.com/containerd/containerd v1.3.2 h1:ForxmXkA6tPIvffbrDAcPUIB32QgXkt2XFj+F0UxetA=
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc h1:TP+534wVlf61smEIq1nwLLAjQVEK2EADoW3CX9AuT+8=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 h1:PUD50EuOMkXVcpBIA/R95d56duJR9VxhwncsFbNnxW4=
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3 h1:esQOJREg8nw8aXj6uCN5dfW5cKUBiEJ/+nni1Q/D/sw=
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de h1:dlfGmNcE3jDAecLqwKPMNX6nk2qh1c1Vg1/YTzpOOF4=
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd h1:JNn81o/xG+8NEo3bC/vx9pbi/g2WI8mtP2/nXzu297Y=
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
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/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2 h1:QhPf3A2AZW3tTGvHPg0TA+CR3oHbVLlXUhlghqISp1I=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f h1:a969LJ4IQFwRHYqonHtUDMSh9i54WcKggeEkQ3fZMl4=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700 h1:eNUVfm/RFLIi1G7flU5/ZRTHvd4kcVuzfRnL6OFlzCI=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7 h1:hhvfGDVThBnd4kYisSFmYuHYeUhglxcwag7FhVPH9zM=
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5 h1:MCfT24H3f//U5+UCrZp1/riVO3B50BovxtDiNn0XKkk=
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09 h1:KaQtG+aDELoNmXYas3TVkGNYRuq8JQ1aa7LJt8EXVyo=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/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=
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=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb h1:i1Ppqkc3WQXikh8bXiwHqAN5Rv3/qDCcRk0/Otx73BY=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -11,6 +11,7 @@ go_library(
"hcnnamespace.go", "hcnnamespace.go",
"hcnnetwork.go", "hcnnetwork.go",
"hcnpolicy.go", "hcnpolicy.go",
"hcnroute.go",
"hcnsupport.go", "hcnsupport.go",
"zsyscall_windows.go", "zsyscall_windows.go",
], ],
@ -18,8 +19,9 @@ go_library(
importpath = "github.com/Microsoft/hcsshim/hcn", importpath = "github.com/Microsoft/hcsshim/hcn",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//vendor/github.com/Microsoft/go-winio/pkg/guid:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/cni:go_default_library", "//vendor/github.com/Microsoft/hcsshim/internal/cni:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/guid:go_default_library", "//vendor/github.com/Microsoft/hcsshim/internal/hcs:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/hcserror:go_default_library", "//vendor/github.com/Microsoft/hcsshim/internal/hcserror:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/interop:go_default_library", "//vendor/github.com/Microsoft/hcsshim/internal/interop:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/regstate:go_default_library", "//vendor/github.com/Microsoft/hcsshim/internal/regstate:go_default_library",

View File

@ -7,7 +7,7 @@ import (
"fmt" "fmt"
"syscall" "syscall"
"github.com/Microsoft/hcsshim/internal/guid" "github.com/Microsoft/go-winio/pkg/guid"
) )
//go:generate go run ../mksyscall_windows.go -output zsyscall_windows.go hcn.go //go:generate go run ../mksyscall_windows.go -output zsyscall_windows.go hcn.go
@ -55,6 +55,15 @@ import (
//sys hcnDeleteLoadBalancer(id *_guid, result **uint16) (hr error) = computenetwork.HcnDeleteLoadBalancer? //sys hcnDeleteLoadBalancer(id *_guid, result **uint16) (hr error) = computenetwork.HcnDeleteLoadBalancer?
//sys hcnCloseLoadBalancer(loadBalancer hcnLoadBalancer) (hr error) = computenetwork.HcnCloseLoadBalancer? //sys hcnCloseLoadBalancer(loadBalancer hcnLoadBalancer) (hr error) = computenetwork.HcnCloseLoadBalancer?
// SDN Routes
//sys hcnEnumerateRoutes(query string, routes **uint16, result **uint16) (hr error) = computenetwork.HcnEnumerateSdnRoutes?
//sys hcnCreateRoute(id *_guid, settings string, route *hcnRoute, result **uint16) (hr error) = computenetwork.HcnCreateSdnRoute?
//sys hcnOpenRoute(id *_guid, route *hcnRoute, result **uint16) (hr error) = computenetwork.HcnOpenSdnRoute?
//sys hcnModifyRoute(route hcnRoute, settings string, result **uint16) (hr error) = computenetwork.HcnModifySdnRoute?
//sys hcnQueryRouteProperties(route hcnRoute, query string, properties **uint16, result **uint16) (hr error) = computenetwork.HcnQuerySdnRouteProperties?
//sys hcnDeleteRoute(id *_guid, result **uint16) (hr error) = computenetwork.HcnDeleteSdnRoute?
//sys hcnCloseRoute(route hcnRoute) (hr error) = computenetwork.HcnCloseSdnRoute?
// Service // Service
//sys hcnOpenService(service *hcnService, result **uint16) (hr error) = computenetwork.HcnOpenService? //sys hcnOpenService(service *hcnService, result **uint16) (hr error) = computenetwork.HcnOpenService?
//sys hcnRegisterServiceCallback(service hcnService, callback int32, context int32, callbackHandle *hcnCallbackHandle) (hr error) = computenetwork.HcnRegisterServiceCallback? //sys hcnRegisterServiceCallback(service hcnService, callback int32, context int32, callbackHandle *hcnCallbackHandle) (hr error) = computenetwork.HcnRegisterServiceCallback?
@ -67,6 +76,7 @@ type hcnNetwork syscall.Handle
type hcnEndpoint syscall.Handle type hcnEndpoint syscall.Handle
type hcnNamespace syscall.Handle type hcnNamespace syscall.Handle
type hcnLoadBalancer syscall.Handle type hcnLoadBalancer syscall.Handle
type hcnRoute syscall.Handle
type hcnService syscall.Handle type hcnService syscall.Handle
type hcnCallbackHandle syscall.Handle type hcnCallbackHandle syscall.Handle
@ -161,6 +171,42 @@ func DSRSupported() error {
return platformDoesNotSupportError("Direct Server Return (DSR)") return platformDoesNotSupportError("Direct Server Return (DSR)")
} }
// Slash32EndpointPrefixesSupported returns an error if the HCN version does not support configuring endpoints with /32 prefixes.
func Slash32EndpointPrefixesSupported() error {
supported := GetSupportedFeatures()
if supported.Slash32EndpointPrefixes {
return nil
}
return platformDoesNotSupportError("Slash 32 Endpoint prefixes")
}
// AclSupportForProtocol252Supported returns an error if the HCN version does not support HNS ACL Policies to support protocol 252 for VXLAN.
func AclSupportForProtocol252Supported() error {
supported := GetSupportedFeatures()
if supported.AclSupportForProtocol252 {
return nil
}
return platformDoesNotSupportError("HNS ACL Policies to support protocol 252 for VXLAN")
}
// SessionAffinitySupported returns an error if the HCN version does not support Session Affinity.
func SessionAffinitySupported() error {
supported := GetSupportedFeatures()
if supported.SessionAffinity {
return nil
}
return platformDoesNotSupportError("Session Affinity")
}
// IPv6DualStackSupported returns an error if the HCN version does not support IPv6DualStack.
func IPv6DualStackSupported() error {
supported := GetSupportedFeatures()
if supported.IPv6DualStack {
return nil
}
return platformDoesNotSupportError("IPv6 DualStack")
}
// RequestType are the different operations performed to settings. // RequestType are the different operations performed to settings.
// Used to update the settings of Endpoint/Namespace objects. // Used to update the settings of Endpoint/Namespace objects.
type RequestType string type RequestType string

View File

@ -3,7 +3,8 @@ package hcn
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"github.com/Microsoft/hcsshim/internal/guid"
"github.com/Microsoft/go-winio/pkg/guid"
"github.com/Microsoft/hcsshim/internal/interop" "github.com/Microsoft/hcsshim/internal/interop"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -121,7 +122,10 @@ func enumerateEndpoints(query string) ([]HostComputeEndpoint, error) {
} }
func createEndpoint(networkId string, endpointSettings string) (*HostComputeEndpoint, error) { func createEndpoint(networkId string, endpointSettings string) (*HostComputeEndpoint, error) {
networkGuid := guid.FromString(networkId) networkGuid, err := guid.FromString(networkId)
if err != nil {
return nil, errInvalidNetworkID
}
// Open network. // Open network.
var networkHandle hcnNetwork var networkHandle hcnNetwork
var resultBuffer *uint16 var resultBuffer *uint16
@ -167,7 +171,10 @@ func createEndpoint(networkId string, endpointSettings string) (*HostComputeEndp
} }
func modifyEndpoint(endpointId string, settings string) (*HostComputeEndpoint, error) { func modifyEndpoint(endpointId string, settings string) (*HostComputeEndpoint, error) {
endpointGuid := guid.FromString(endpointId) endpointGuid, err := guid.FromString(endpointId)
if err != nil {
return nil, errInvalidEndpointID
}
// Open endpoint // Open endpoint
var ( var (
endpointHandle hcnEndpoint endpointHandle hcnEndpoint
@ -208,7 +215,10 @@ func modifyEndpoint(endpointId string, settings string) (*HostComputeEndpoint, e
} }
func deleteEndpoint(endpointId string) error { func deleteEndpoint(endpointId string) error {
endpointGuid := guid.FromString(endpointId) endpointGuid, err := guid.FromString(endpointId)
if err != nil {
return errInvalidEndpointID
}
var resultBuffer *uint16 var resultBuffer *uint16
hr := hcnDeleteEndpoint(&endpointGuid, &resultBuffer) hr := hcnDeleteEndpoint(&endpointGuid, &resultBuffer)
if err := checkForErrors("hcnDeleteEndpoint", hr, resultBuffer); err != nil { if err := checkForErrors("hcnDeleteEndpoint", hr, resultBuffer); err != nil {
@ -343,7 +353,7 @@ func ModifyEndpointSettings(endpointId string, request *ModifyEndpointSettingReq
} }
// ApplyPolicy applies a Policy (ex: ACL) on the Endpoint. // ApplyPolicy applies a Policy (ex: ACL) on the Endpoint.
func (endpoint *HostComputeEndpoint) ApplyPolicy(endpointPolicy PolicyEndpointRequest) error { func (endpoint *HostComputeEndpoint) ApplyPolicy(requestType RequestType, endpointPolicy PolicyEndpointRequest) error {
logrus.Debugf("hcn::HostComputeEndpoint::ApplyPolicy id=%s", endpoint.Id) logrus.Debugf("hcn::HostComputeEndpoint::ApplyPolicy id=%s", endpoint.Id)
settingsJson, err := json.Marshal(endpointPolicy) settingsJson, err := json.Marshal(endpointPolicy)
@ -352,7 +362,7 @@ func (endpoint *HostComputeEndpoint) ApplyPolicy(endpointPolicy PolicyEndpointRe
} }
requestMessage := &ModifyEndpointSettingRequest{ requestMessage := &ModifyEndpointSettingRequest{
ResourceType: EndpointResourceTypePolicy, ResourceType: EndpointResourceTypePolicy,
RequestType: RequestTypeUpdate, RequestType: requestType,
Settings: settingsJson, Settings: settingsJson,
} }

View File

@ -3,13 +3,23 @@
package hcn package hcn
import ( import (
"errors"
"fmt" "fmt"
"github.com/Microsoft/hcsshim/internal/hcs"
"github.com/Microsoft/hcsshim/internal/hcserror" "github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/interop" "github.com/Microsoft/hcsshim/internal/interop"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
var (
errInvalidNetworkID = errors.New("invalid network ID")
errInvalidEndpointID = errors.New("invalid endpoint ID")
errInvalidNamespaceID = errors.New("invalid namespace ID")
errInvalidLoadBalancerID = errors.New("invalid load balancer ID")
errInvalidRouteID = errors.New("invalid route ID")
)
func checkForErrors(methodName string, hr error, resultBuffer *uint16) error { func checkForErrors(methodName string, hr error, resultBuffer *uint16) error {
errorFound := false errorFound := false
@ -26,7 +36,7 @@ func checkForErrors(methodName string, hr error, resultBuffer *uint16) error {
} }
if errorFound { if errorFound {
returnError := hcserror.New(hr, methodName, result) returnError := new(hr, methodName, result)
logrus.Debugf(returnError.Error()) // HCN errors logged for debugging. logrus.Debugf(returnError.Error()) // HCN errors logged for debugging.
return returnError return returnError
} }
@ -34,6 +44,52 @@ func checkForErrors(methodName string, hr error, resultBuffer *uint16) error {
return nil return nil
} }
type ErrorCode uint32
// For common errors, define the error as it is in windows, so we can quickly determine it later
const (
ERROR_NOT_FOUND = 0x490
HCN_E_PORT_ALREADY_EXISTS ErrorCode = 0x803b0013
)
type HcnError struct {
*hcserror.HcsError
code ErrorCode
}
func (e *HcnError) Error() string {
return e.HcsError.Error()
}
func CheckErrorWithCode(err error, code ErrorCode) bool {
hcnError, ok := err.(*HcnError)
if ok {
return hcnError.code == code
}
return false
}
func IsElementNotFoundError(err error) bool {
return CheckErrorWithCode(err, ERROR_NOT_FOUND)
}
func IsPortAlreadyExistsError(err error) bool {
return CheckErrorWithCode(err, HCN_E_PORT_ALREADY_EXISTS)
}
func new(hr error, title string, rest string) error {
err := &HcnError{}
hcsError := hcserror.New(hr, title, rest)
err.HcsError = hcsError.(*hcserror.HcsError)
err.code = ErrorCode(hcserror.Win32FromError(hr))
return err
}
//
// Note that the below errors are not errors returned by hcn itself
// we wish to seperate them as they are shim usage error
//
// NetworkNotFoundError results from a failed seach for a network by Id or Name // NetworkNotFoundError results from a failed seach for a network by Id or Name
type NetworkNotFoundError struct { type NetworkNotFoundError struct {
NetworkName string NetworkName string
@ -41,10 +97,10 @@ type NetworkNotFoundError struct {
} }
func (e NetworkNotFoundError) Error() string { func (e NetworkNotFoundError) Error() string {
if e.NetworkName == "" { if e.NetworkName != "" {
return fmt.Sprintf("Network Name %s not found", e.NetworkName) return fmt.Sprintf("Network name %q not found", e.NetworkName)
} }
return fmt.Sprintf("Network Id %s not found", e.NetworkID) return fmt.Sprintf("Network ID %q not found", e.NetworkID)
} }
// EndpointNotFoundError results from a failed seach for an endpoint by Id or Name // EndpointNotFoundError results from a failed seach for an endpoint by Id or Name
@ -54,10 +110,10 @@ type EndpointNotFoundError struct {
} }
func (e EndpointNotFoundError) Error() string { func (e EndpointNotFoundError) Error() string {
if e.EndpointName == "" { if e.EndpointName != "" {
return fmt.Sprintf("Endpoint Name %s not found", e.EndpointName) return fmt.Sprintf("Endpoint name %q not found", e.EndpointName)
} }
return fmt.Sprintf("Endpoint Id %s not found", e.EndpointID) return fmt.Sprintf("Endpoint ID %q not found", e.EndpointID)
} }
// NamespaceNotFoundError results from a failed seach for a namsepace by Id // NamespaceNotFoundError results from a failed seach for a namsepace by Id
@ -66,7 +122,7 @@ type NamespaceNotFoundError struct {
} }
func (e NamespaceNotFoundError) Error() string { func (e NamespaceNotFoundError) Error() string {
return fmt.Sprintf("Namespace %s not found", e.NamespaceID) return fmt.Sprintf("Namespace ID %q not found", e.NamespaceID)
} }
// LoadBalancerNotFoundError results from a failed seach for a loadbalancer by Id // LoadBalancerNotFoundError results from a failed seach for a loadbalancer by Id
@ -75,13 +131,22 @@ type LoadBalancerNotFoundError struct {
} }
func (e LoadBalancerNotFoundError) Error() string { func (e LoadBalancerNotFoundError) Error() string {
return fmt.Sprintf("LoadBalancer %s not found", e.LoadBalancerId) return fmt.Sprintf("LoadBalancer %q not found", e.LoadBalancerId)
}
// RouteNotFoundError results from a failed seach for a route by Id
type RouteNotFoundError struct {
RouteId string
}
func (e RouteNotFoundError) Error() string {
return fmt.Sprintf("SDN Route %q not found", e.RouteId)
} }
// IsNotFoundError returns a boolean indicating whether the error was caused by // IsNotFoundError returns a boolean indicating whether the error was caused by
// a resource not being found. // a resource not being found.
func IsNotFoundError(err error) bool { func IsNotFoundError(err error) bool {
switch err.(type) { switch pe := err.(type) {
case NetworkNotFoundError: case NetworkNotFoundError:
return true return true
case EndpointNotFoundError: case EndpointNotFoundError:
@ -90,6 +155,10 @@ func IsNotFoundError(err error) bool {
return true return true
case LoadBalancerNotFoundError: case LoadBalancerNotFoundError:
return true return true
case RouteNotFoundError:
return true
case *hcserror.HcsError:
return pe.Err == hcs.ErrElementNotFound
} }
return false return false
} }

View File

@ -3,6 +3,7 @@ package hcn
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"math"
"github.com/Microsoft/hcsshim/internal/hcserror" "github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/interop" "github.com/Microsoft/hcsshim/internal/interop"
@ -20,17 +21,41 @@ type Version struct {
Minor int `json:"Minor"` Minor int `json:"Minor"`
} }
type VersionRange struct {
MinVersion Version
MaxVersion Version
}
type VersionRanges []VersionRange
var ( var (
// HNSVersion1803 added ACL functionality. // HNSVersion1803 added ACL functionality.
HNSVersion1803 = Version{Major: 7, Minor: 2} HNSVersion1803 = VersionRanges{VersionRange{MinVersion: Version{Major: 7, Minor: 2}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
// V2ApiSupport allows the use of V2 Api calls and V2 Schema. // V2ApiSupport allows the use of V2 Api calls and V2 Schema.
V2ApiSupport = Version{Major: 9, Minor: 2} V2ApiSupport = VersionRanges{VersionRange{MinVersion: Version{Major: 9, Minor: 2}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
// Remote Subnet allows for Remote Subnet policies on Overlay networks // Remote Subnet allows for Remote Subnet policies on Overlay networks
RemoteSubnetVersion = Version{Major: 9, Minor: 2} RemoteSubnetVersion = VersionRanges{VersionRange{MinVersion: Version{Major: 9, Minor: 2}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
// A Host Route policy allows for local container to local host communication Overlay networks // A Host Route policy allows for local container to local host communication Overlay networks
HostRouteVersion = Version{Major: 9, Minor: 2} HostRouteVersion = VersionRanges{VersionRange{MinVersion: Version{Major: 9, Minor: 2}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
// HNS 10.2 allows for Direct Server Return for loadbalancing // HNS 10.2 allows for Direct Server Return for loadbalancing
DSRVersion = Version{Major: 10, Minor: 2} DSRVersion = VersionRanges{VersionRange{MinVersion: Version{Major: 10, Minor: 2}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
// HNS 9.3 through 10.0 (not included) and, 10.4+ provide support for configuring endpoints with /32 prefixes
Slash32EndpointPrefixesVersion = VersionRanges{
VersionRange{MinVersion: Version{Major: 9, Minor: 3}, MaxVersion: Version{Major: 9, Minor: math.MaxInt32}},
VersionRange{MinVersion: Version{Major: 10, Minor: 4}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}},
}
// HNS 9.3 through 10.0 (not included) and, 10.4+ allow for HNS ACL Policies to support protocol 252 for VXLAN
AclSupportForProtocol252Version = VersionRanges{
VersionRange{MinVersion: Version{Major: 9, Minor: 3}, MaxVersion: Version{Major: 9, Minor: math.MaxInt32}},
VersionRange{MinVersion: Version{Major: 10, Minor: 4}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}},
}
// HNS 12.0 allows for session affinity for loadbalancing
SessionAffinityVersion = VersionRanges{VersionRange{MinVersion: Version{Major: 12, Minor: 0}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
// HNS 10.5 through 11 (not included) and 12.0+ supports Ipv6 dual stack.
IPv6DualStackVersion = VersionRanges{
VersionRange{MinVersion: Version{Major: 10, Minor: 5}, MaxVersion: Version{Major: 10, Minor: math.MaxInt32}},
VersionRange{MinVersion: Version{Major: 12, Minor: 0}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}},
}
) )
// GetGlobals returns the global properties of the HCN Service. // GetGlobals returns the global properties of the HCN Service.

View File

@ -3,7 +3,7 @@ package hcn
import ( import (
"encoding/json" "encoding/json"
"github.com/Microsoft/hcsshim/internal/guid" "github.com/Microsoft/go-winio/pkg/guid"
"github.com/Microsoft/hcsshim/internal/interop" "github.com/Microsoft/hcsshim/internal/interop"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -13,6 +13,7 @@ type LoadBalancerPortMapping struct {
Protocol uint32 `json:",omitempty"` // EX: TCP = 6, UDP = 17 Protocol uint32 `json:",omitempty"` // EX: TCP = 6, UDP = 17
InternalPort uint16 `json:",omitempty"` InternalPort uint16 `json:",omitempty"`
ExternalPort uint16 `json:",omitempty"` ExternalPort uint16 `json:",omitempty"`
DistributionType LoadBalancerDistribution `json:",omitempty"` // EX: Distribute per connection = 0, distribute traffic of the same protocol per client IP = 1, distribute per client IP = 2
Flags LoadBalancerPortMappingFlags `json:",omitempty"` Flags LoadBalancerPortMappingFlags `json:",omitempty"`
} }
@ -53,6 +54,18 @@ var (
LoadBalancerPortMappingFlagsPreserveDIP LoadBalancerPortMappingFlags = 8 LoadBalancerPortMappingFlagsPreserveDIP LoadBalancerPortMappingFlags = 8
) )
// LoadBalancerDistribution specifies how the loadbalancer distributes traffic.
type LoadBalancerDistribution uint32
var (
// LoadBalancerDistributionNone is the default and loadbalances each connection to the same pod.
LoadBalancerDistributionNone LoadBalancerDistribution
// LoadBalancerDistributionSourceIPProtocol loadbalances all traffic of the same protocol from a client IP to the same pod.
LoadBalancerDistributionSourceIPProtocol LoadBalancerDistribution = 1
// LoadBalancerDistributionSourceIP loadbalances all traffic from a client IP to the same pod.
LoadBalancerDistributionSourceIP LoadBalancerDistribution = 2
)
func getLoadBalancer(loadBalancerGuid guid.GUID, query string) (*HostComputeLoadBalancer, error) { func getLoadBalancer(loadBalancerGuid guid.GUID, query string) (*HostComputeLoadBalancer, error) {
// Open loadBalancer. // Open loadBalancer.
var ( var (
@ -148,7 +161,10 @@ func createLoadBalancer(settings string) (*HostComputeLoadBalancer, error) {
} }
func modifyLoadBalancer(loadBalancerId string, settings string) (*HostComputeLoadBalancer, error) { func modifyLoadBalancer(loadBalancerId string, settings string) (*HostComputeLoadBalancer, error) {
loadBalancerGuid := guid.FromString(loadBalancerId) loadBalancerGuid, err := guid.FromString(loadBalancerId)
if err != nil {
return nil, errInvalidLoadBalancerID
}
// Open loadBalancer. // Open loadBalancer.
var ( var (
loadBalancerHandle hcnLoadBalancer loadBalancerHandle hcnLoadBalancer
@ -189,7 +205,10 @@ func modifyLoadBalancer(loadBalancerId string, settings string) (*HostComputeLoa
} }
func deleteLoadBalancer(loadBalancerId string) error { func deleteLoadBalancer(loadBalancerId string) error {
loadBalancerGuid := guid.FromString(loadBalancerId) loadBalancerGuid, err := guid.FromString(loadBalancerId)
if err != nil {
return errInvalidLoadBalancerID
}
var resultBuffer *uint16 var resultBuffer *uint16
hr := hcnDeleteLoadBalancer(&loadBalancerGuid, &resultBuffer) hr := hcnDeleteLoadBalancer(&loadBalancerGuid, &resultBuffer)
if err := checkForErrors("hcnDeleteLoadBalancer", hr, resultBuffer); err != nil { if err := checkForErrors("hcnDeleteLoadBalancer", hr, resultBuffer); err != nil {

View File

@ -5,8 +5,8 @@ import (
"os" "os"
"syscall" "syscall"
"github.com/Microsoft/go-winio/pkg/guid"
icni "github.com/Microsoft/hcsshim/internal/cni" icni "github.com/Microsoft/hcsshim/internal/cni"
"github.com/Microsoft/hcsshim/internal/guid"
"github.com/Microsoft/hcsshim/internal/interop" "github.com/Microsoft/hcsshim/internal/interop"
"github.com/Microsoft/hcsshim/internal/regstate" "github.com/Microsoft/hcsshim/internal/regstate"
"github.com/Microsoft/hcsshim/internal/runhcs" "github.com/Microsoft/hcsshim/internal/runhcs"
@ -165,7 +165,10 @@ func createNamespace(settings string) (*HostComputeNamespace, error) {
} }
func modifyNamespace(namespaceId string, settings string) (*HostComputeNamespace, error) { func modifyNamespace(namespaceId string, settings string) (*HostComputeNamespace, error) {
namespaceGuid := guid.FromString(namespaceId) namespaceGuid, err := guid.FromString(namespaceId)
if err != nil {
return nil, errInvalidNamespaceID
}
// Open namespace. // Open namespace.
var ( var (
namespaceHandle hcnNamespace namespaceHandle hcnNamespace
@ -206,7 +209,10 @@ func modifyNamespace(namespaceId string, settings string) (*HostComputeNamespace
} }
func deleteNamespace(namespaceId string) error { func deleteNamespace(namespaceId string) error {
namespaceGuid := guid.FromString(namespaceId) namespaceGuid, err := guid.FromString(namespaceId)
if err != nil {
return errInvalidNamespaceID
}
var resultBuffer *uint16 var resultBuffer *uint16
hr := hcnDeleteNamespace(&namespaceGuid, &resultBuffer) hr := hcnDeleteNamespace(&namespaceGuid, &resultBuffer)
if err := checkForErrors("hcnDeleteNamespace", hr, resultBuffer); err != nil { if err := checkForErrors("hcnDeleteNamespace", hr, resultBuffer); err != nil {
@ -241,7 +247,23 @@ func ListNamespacesQuery(query HostComputeQuery) ([]HostComputeNamespace, error)
// GetNamespaceByID returns the Namespace specified by Id. // GetNamespaceByID returns the Namespace specified by Id.
func GetNamespaceByID(namespaceId string) (*HostComputeNamespace, error) { func GetNamespaceByID(namespaceId string) (*HostComputeNamespace, error) {
return getNamespace(guid.FromString(namespaceId), defaultQueryJson()) hcnQuery := defaultQuery()
mapA := map[string]string{"ID": namespaceId}
filter, err := json.Marshal(mapA)
if err != nil {
return nil, err
}
hcnQuery.Filter = string(filter)
namespaces, err := ListNamespacesQuery(hcnQuery)
if err != nil {
return nil, err
}
if len(namespaces) == 0 {
return nil, NamespaceNotFoundError{NamespaceID: namespaceId}
}
return &namespaces[0], err
} }
// GetNamespaceEndpointIds returns the endpoints of the Namespace specified by Id. // GetNamespaceEndpointIds returns the endpoints of the Namespace specified by Id.

View File

@ -3,7 +3,8 @@ package hcn
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"github.com/Microsoft/hcsshim/internal/guid"
"github.com/Microsoft/go-winio/pkg/guid"
"github.com/Microsoft/hcsshim/internal/interop" "github.com/Microsoft/hcsshim/internal/interop"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -132,6 +133,12 @@ func getNetwork(networkGuid guid.GUID, query string) (*HostComputeNetwork, error
} }
// Convert output to HostComputeNetwork // Convert output to HostComputeNetwork
var outputNetwork HostComputeNetwork var outputNetwork HostComputeNetwork
// If HNS sets the network type to NAT (i.e. '0' in HNS.Schema.Network.NetworkMode),
// the value will be omitted from the JSON blob. We therefore need to initialize NAT here before
// unmarshaling the JSON blob.
outputNetwork.Type = NAT
if err := json.Unmarshal([]byte(properties), &outputNetwork); err != nil { if err := json.Unmarshal([]byte(properties), &outputNetwork); err != nil {
return nil, err return nil, err
} }
@ -196,6 +203,12 @@ func createNetwork(settings string) (*HostComputeNetwork, error) {
} }
// Convert output to HostComputeNetwork // Convert output to HostComputeNetwork
var outputNetwork HostComputeNetwork var outputNetwork HostComputeNetwork
// If HNS sets the network type to NAT (i.e. '0' in HNS.Schema.Network.NetworkMode),
// the value will be omitted from the JSON blob. We therefore need to initialize NAT here before
// unmarshaling the JSON blob.
outputNetwork.Type = NAT
if err := json.Unmarshal([]byte(properties), &outputNetwork); err != nil { if err := json.Unmarshal([]byte(properties), &outputNetwork); err != nil {
return nil, err return nil, err
} }
@ -203,7 +216,10 @@ func createNetwork(settings string) (*HostComputeNetwork, error) {
} }
func modifyNetwork(networkId string, settings string) (*HostComputeNetwork, error) { func modifyNetwork(networkId string, settings string) (*HostComputeNetwork, error) {
networkGuid := guid.FromString(networkId) networkGuid, err := guid.FromString(networkId)
if err != nil {
return nil, errInvalidNetworkID
}
// Open Network // Open Network
var ( var (
networkHandle hcnNetwork networkHandle hcnNetwork
@ -237,6 +253,12 @@ func modifyNetwork(networkId string, settings string) (*HostComputeNetwork, erro
} }
// Convert output to HostComputeNetwork // Convert output to HostComputeNetwork
var outputNetwork HostComputeNetwork var outputNetwork HostComputeNetwork
// If HNS sets the network type to NAT (i.e. '0' in HNS.Schema.Network.NetworkMode),
// the value will be omitted from the JSON blob. We therefore need to initialize NAT here before
// unmarshaling the JSON blob.
outputNetwork.Type = NAT
if err := json.Unmarshal([]byte(properties), &outputNetwork); err != nil { if err := json.Unmarshal([]byte(properties), &outputNetwork); err != nil {
return nil, err return nil, err
} }
@ -244,7 +266,10 @@ func modifyNetwork(networkId string, settings string) (*HostComputeNetwork, erro
} }
func deleteNetwork(networkId string) error { func deleteNetwork(networkId string) error {
networkGuid := guid.FromString(networkId) networkGuid, err := guid.FromString(networkId)
if err != nil {
return errInvalidNetworkID
}
var resultBuffer *uint16 var resultBuffer *uint16
hr := hcnDeleteNetwork(&networkGuid, &resultBuffer) hr := hcnDeleteNetwork(&networkGuid, &resultBuffer)
if err := checkForErrors("hcnDeleteNetwork", hr, resultBuffer); err != nil { if err := checkForErrors("hcnDeleteNetwork", hr, resultBuffer); err != nil {

View File

@ -1,6 +1,8 @@
package hcn package hcn
import "encoding/json" import (
"encoding/json"
)
// EndpointPolicyType are the potential Policies that apply to Endpoints. // EndpointPolicyType are the potential Policies that apply to Endpoints.
type EndpointPolicyType string type EndpointPolicyType string
@ -14,6 +16,7 @@ const (
OutBoundNAT EndpointPolicyType = "OutBoundNAT" OutBoundNAT EndpointPolicyType = "OutBoundNAT"
SDNRoute EndpointPolicyType = "SDNRoute" SDNRoute EndpointPolicyType = "SDNRoute"
L4Proxy EndpointPolicyType = "L4Proxy" L4Proxy EndpointPolicyType = "L4Proxy"
L4WFPPROXY EndpointPolicyType = "L4WFPPROXY"
PortName EndpointPolicyType = "PortName" PortName EndpointPolicyType = "PortName"
EncapOverhead EndpointPolicyType = "EncapOverhead" EncapOverhead EndpointPolicyType = "EncapOverhead"
// Endpoint and Network have InterfaceConstraint and ProviderAddress // Endpoint and Network have InterfaceConstraint and ProviderAddress
@ -64,6 +67,9 @@ type SubnetPolicy struct {
Settings json.RawMessage `json:",omitempty"` Settings json.RawMessage `json:",omitempty"`
} }
// NatFlags are flags for portmappings.
type NatFlags uint32
/// Endpoint Policy objects /// Endpoint Policy objects
// PortMappingPolicySetting defines Port Mapping (NAT) // PortMappingPolicySetting defines Port Mapping (NAT)
@ -72,6 +78,7 @@ type PortMappingPolicySetting struct {
InternalPort uint16 `json:",omitempty"` InternalPort uint16 `json:",omitempty"`
ExternalPort uint16 `json:",omitempty"` ExternalPort uint16 `json:",omitempty"`
VIP string `json:",omitempty"` VIP string `json:",omitempty"`
Flags NatFlags `json:",omitempty"`
} }
// ActionType associated with ACLs. Value is either Allow or Block. // ActionType associated with ACLs. Value is either Allow or Block.
@ -122,6 +129,7 @@ type QosPolicySetting struct {
type OutboundNatPolicySetting struct { type OutboundNatPolicySetting struct {
VirtualIP string `json:",omitempty"` VirtualIP string `json:",omitempty"`
Exceptions []string `json:",omitempty"` Exceptions []string `json:",omitempty"`
Destinations []string `json:",omitempty"`
} }
// SDNRoutePolicySetting sets SDN Route on an Endpoint. // SDNRoutePolicySetting sets SDN Route on an Endpoint.
@ -131,14 +139,21 @@ type SDNRoutePolicySetting struct {
NeedEncap bool `json:",omitempty"` NeedEncap bool `json:",omitempty"`
} }
// L4ProxyPolicySetting sets Layer-4 Proxy on an endpoint. // FiveTuple is nested in L4ProxyPolicySetting for WFP support.
type L4ProxyPolicySetting struct { type FiveTuple struct {
IP string `json:",omitempty"` Protocols string `json:",omitempty"`
LocalAddresses string `json:",omitempty"`
RemoteAddresses string `json:",omitempty"`
LocalPorts string `json:",omitempty"`
RemotePorts string `json:",omitempty"`
Priority uint16 `json:",omitempty"`
}
// L4WfpProxyPolicySetting sets Layer-4 Proxy on an endpoint.
type L4WfpProxyPolicySetting struct {
Port string `json:",omitempty"` Port string `json:",omitempty"`
Protocol uint32 `json:",omitempty"` // EX: TCP = 6, UDP = 17 FilterTuple FiveTuple `json:",omitempty"`
ExceptionList []string `json:",omitempty"` UserSID string `json:",omitempty"`
Destination string `json:","`
OutboundNat bool `json:",omitempty"`
} }
// PortnameEndpointPolicySetting sets the port name for an endpoint. // PortnameEndpointPolicySetting sets the port name for an endpoint.

266
vendor/github.com/Microsoft/hcsshim/hcn/hcnroute.go generated vendored Normal file
View File

@ -0,0 +1,266 @@
package hcn
import (
"encoding/json"
"errors"
"github.com/Microsoft/go-winio/pkg/guid"
"github.com/Microsoft/hcsshim/internal/interop"
"github.com/sirupsen/logrus"
)
// HostComputeRoute represents SDN routes.
type HostComputeRoute struct {
ID string `json:"ID,omitempty"`
HostComputeEndpoints []string `json:",omitempty"`
Setting []SDNRoutePolicySetting `json:",omitempty"`
SchemaVersion SchemaVersion `json:",omitempty"`
}
// ListRoutes makes a call to list all available routes.
func ListRoutes() ([]HostComputeRoute, error) {
hcnQuery := defaultQuery()
routes, err := ListRoutesQuery(hcnQuery)
if err != nil {
return nil, err
}
return routes, nil
}
// ListRoutesQuery makes a call to query the list of available routes.
func ListRoutesQuery(query HostComputeQuery) ([]HostComputeRoute, error) {
queryJSON, err := json.Marshal(query)
if err != nil {
return nil, err
}
routes, err := enumerateRoutes(string(queryJSON))
if err != nil {
return nil, err
}
return routes, nil
}
// GetRouteByID returns the route specified by Id.
func GetRouteByID(routeID string) (*HostComputeRoute, error) {
hcnQuery := defaultQuery()
mapA := map[string]string{"ID": routeID}
filter, err := json.Marshal(mapA)
if err != nil {
return nil, err
}
hcnQuery.Filter = string(filter)
routes, err := ListRoutesQuery(hcnQuery)
if err != nil {
return nil, err
}
if len(routes) == 0 {
return nil, RouteNotFoundError{RouteId: routeID}
}
return &routes[0], err
}
// Create Route.
func (route *HostComputeRoute) Create() (*HostComputeRoute, error) {
logrus.Debugf("hcn::HostComputeRoute::Create id=%s", route.ID)
jsonString, err := json.Marshal(route)
if err != nil {
return nil, err
}
logrus.Debugf("hcn::HostComputeRoute::Create JSON: %s", jsonString)
route, hcnErr := createRoute(string(jsonString))
if hcnErr != nil {
return nil, hcnErr
}
return route, nil
}
// Delete Route.
func (route *HostComputeRoute) Delete() error {
logrus.Debugf("hcn::HostComputeRoute::Delete id=%s", route.ID)
existingRoute, _ := GetRouteByID(route.ID)
if existingRoute != nil {
if err := deleteRoute(route.ID); err != nil {
return err
}
}
return nil
}
// AddEndpoint add an endpoint to a route
// Since HCNRoute doesn't implement modify functionality, add operation is essentially delete and add
func (route *HostComputeRoute) AddEndpoint(endpoint *HostComputeEndpoint) (*HostComputeRoute, error) {
logrus.Debugf("hcn::HostComputeRoute::AddEndpoint route=%s endpoint=%s", route.ID, endpoint.Id)
err := route.Delete()
if err != nil {
return nil, err
}
// Add Endpoint to the Existing List
route.HostComputeEndpoints = append(route.HostComputeEndpoints, endpoint.Id)
return route.Create()
}
// RemoveEndpoint removes an endpoint from a route
// Since HCNRoute doesn't implement modify functionality, remove operation is essentially delete and add
func (route *HostComputeRoute) RemoveEndpoint(endpoint *HostComputeEndpoint) (*HostComputeRoute, error) {
logrus.Debugf("hcn::HostComputeRoute::RemoveEndpoint route=%s endpoint=%s", route.ID, endpoint.Id)
err := route.Delete()
if err != nil {
return nil, err
}
// Create a list of all the endpoints besides the one being removed
i := 0
for index, endpointReference := range route.HostComputeEndpoints {
if endpointReference == endpoint.Id {
i = index
break
}
}
route.HostComputeEndpoints = append(route.HostComputeEndpoints[0:i], route.HostComputeEndpoints[i+1:]...)
return route.Create()
}
// AddRoute for the specified endpoints and SDN Route setting
func AddRoute(endpoints []HostComputeEndpoint, destinationPrefix string, nextHop string, needEncapsulation bool) (*HostComputeRoute, error) {
logrus.Debugf("hcn::HostComputeRoute::AddRoute endpointId=%v, destinationPrefix=%v, nextHop=%v, needEncapsulation=%v", endpoints, destinationPrefix, nextHop, needEncapsulation)
if len(endpoints) <= 0 {
return nil, errors.New("Missing endpoints")
}
route := &HostComputeRoute{
SchemaVersion: V2SchemaVersion(),
Setting: []SDNRoutePolicySetting{
{
DestinationPrefix: destinationPrefix,
NextHop: nextHop,
NeedEncap: needEncapsulation,
},
},
}
for _, endpoint := range endpoints {
route.HostComputeEndpoints = append(route.HostComputeEndpoints, endpoint.Id)
}
return route.Create()
}
func enumerateRoutes(query string) ([]HostComputeRoute, error) {
// Enumerate all routes Guids
var (
resultBuffer *uint16
routeBuffer *uint16
)
hr := hcnEnumerateRoutes(query, &routeBuffer, &resultBuffer)
if err := checkForErrors("hcnEnumerateRoutes", hr, resultBuffer); err != nil {
return nil, err
}
routes := interop.ConvertAndFreeCoTaskMemString(routeBuffer)
var routeIds []guid.GUID
if err := json.Unmarshal([]byte(routes), &routeIds); err != nil {
return nil, err
}
var outputRoutes []HostComputeRoute
for _, routeGUID := range routeIds {
route, err := getRoute(routeGUID, query)
if err != nil {
return nil, err
}
outputRoutes = append(outputRoutes, *route)
}
return outputRoutes, nil
}
func getRoute(routeGUID guid.GUID, query string) (*HostComputeRoute, error) {
// Open routes.
var (
routeHandle hcnRoute
resultBuffer *uint16
propertiesBuffer *uint16
)
hr := hcnOpenRoute(&routeGUID, &routeHandle, &resultBuffer)
if err := checkForErrors("hcnOpenRoute", hr, resultBuffer); err != nil {
return nil, err
}
// Query routes.
hr = hcnQueryRouteProperties(routeHandle, query, &propertiesBuffer, &resultBuffer)
if err := checkForErrors("hcnQueryRouteProperties", hr, resultBuffer); err != nil {
return nil, err
}
properties := interop.ConvertAndFreeCoTaskMemString(propertiesBuffer)
// Close routes.
hr = hcnCloseRoute(routeHandle)
if err := checkForErrors("hcnCloseRoute", hr, nil); err != nil {
return nil, err
}
// Convert output to HostComputeRoute
var outputRoute HostComputeRoute
if err := json.Unmarshal([]byte(properties), &outputRoute); err != nil {
return nil, err
}
return &outputRoute, nil
}
func createRoute(settings string) (*HostComputeRoute, error) {
// Create new route.
var (
routeHandle hcnRoute
resultBuffer *uint16
propertiesBuffer *uint16
)
routeGUID := guid.GUID{}
hr := hcnCreateRoute(&routeGUID, settings, &routeHandle, &resultBuffer)
if err := checkForErrors("hcnCreateRoute", hr, resultBuffer); err != nil {
return nil, err
}
// Query route.
hcnQuery := defaultQuery()
query, err := json.Marshal(hcnQuery)
if err != nil {
return nil, err
}
hr = hcnQueryRouteProperties(routeHandle, string(query), &propertiesBuffer, &resultBuffer)
if err := checkForErrors("hcnQueryRouteProperties", hr, resultBuffer); err != nil {
return nil, err
}
properties := interop.ConvertAndFreeCoTaskMemString(propertiesBuffer)
// Close Route.
hr = hcnCloseRoute(routeHandle)
if err := checkForErrors("hcnCloseRoute", hr, nil); err != nil {
return nil, err
}
// Convert output to HostComputeRoute
var outputRoute HostComputeRoute
if err := json.Unmarshal([]byte(properties), &outputRoute); err != nil {
return nil, err
}
return &outputRoute, nil
}
func deleteRoute(routeID string) error {
routeGUID, err := guid.FromString(routeID)
if err != nil {
return errInvalidRouteID
}
var resultBuffer *uint16
hr := hcnDeleteRoute(&routeGUID, &resultBuffer)
if err := checkForErrors("hcnDeleteRoute", hr, resultBuffer); err != nil {
return err
}
return nil
}

View File

@ -11,6 +11,10 @@ type SupportedFeatures struct {
RemoteSubnet bool `json:"RemoteSubnet"` RemoteSubnet bool `json:"RemoteSubnet"`
HostRoute bool `json:"HostRoute"` HostRoute bool `json:"HostRoute"`
DSR bool `json:"DSR"` DSR bool `json:"DSR"`
Slash32EndpointPrefixes bool `json:"Slash32EndpointPrefixes"`
AclSupportForProtocol252 bool `json:"AclSupportForProtocol252"`
SessionAffinity bool `json:"SessionAffinity"`
IPv6DualStack bool `json:"IPv6DualStack"`
} }
// AclFeatures are the supported ACL possibilities. // AclFeatures are the supported ACL possibilities.
@ -53,18 +57,39 @@ func GetSupportedFeatures() SupportedFeatures {
features.RemoteSubnet = isFeatureSupported(globals.Version, RemoteSubnetVersion) features.RemoteSubnet = isFeatureSupported(globals.Version, RemoteSubnetVersion)
features.HostRoute = isFeatureSupported(globals.Version, HostRouteVersion) features.HostRoute = isFeatureSupported(globals.Version, HostRouteVersion)
features.DSR = isFeatureSupported(globals.Version, DSRVersion) features.DSR = isFeatureSupported(globals.Version, DSRVersion)
features.Slash32EndpointPrefixes = isFeatureSupported(globals.Version, Slash32EndpointPrefixesVersion)
features.AclSupportForProtocol252 = isFeatureSupported(globals.Version, AclSupportForProtocol252Version)
features.SessionAffinity = isFeatureSupported(globals.Version, SessionAffinityVersion)
features.IPv6DualStack = isFeatureSupported(globals.Version, IPv6DualStackVersion)
return features return features
} }
func isFeatureSupported(currentVersion Version, minVersionSupported Version) bool { func isFeatureSupported(currentVersion Version, versionsSupported VersionRanges) bool {
if currentVersion.Major < minVersionSupported.Major { isFeatureSupported := false
for _, versionRange := range versionsSupported {
isFeatureSupported = isFeatureSupported || isFeatureInRange(currentVersion, versionRange)
}
return isFeatureSupported
}
func isFeatureInRange(currentVersion Version, versionRange VersionRange) bool {
if currentVersion.Major < versionRange.MinVersion.Major {
logrus.Infof("currentVersion.Major < versionRange.MinVersion.Major: %v, %v", currentVersion.Major, versionRange.MinVersion.Major)
return false return false
} }
if currentVersion.Major > minVersionSupported.Major { if currentVersion.Major > versionRange.MaxVersion.Major {
return true logrus.Infof("currentVersion.Major > versionRange.MaxVersion.Major: %v, %v", currentVersion.Major, versionRange.MaxVersion.Major)
return false
} }
if currentVersion.Minor < minVersionSupported.Minor { if currentVersion.Major == versionRange.MinVersion.Major && currentVersion.Minor < versionRange.MinVersion.Minor {
logrus.Infof("currentVersion.Minor < versionRange.MinVersion.Major: %v, %v", currentVersion.Minor, versionRange.MinVersion.Minor)
return false
}
if currentVersion.Major == versionRange.MaxVersion.Major && currentVersion.Minor > versionRange.MaxVersion.Minor {
logrus.Infof("currentVersion.Minor > versionRange.MaxVersion.Major: %v, %v", currentVersion.Minor, versionRange.MaxVersion.Minor)
return false return false
} }
return true return true

View File

@ -71,6 +71,13 @@ var (
procHcnQueryLoadBalancerProperties = modcomputenetwork.NewProc("HcnQueryLoadBalancerProperties") procHcnQueryLoadBalancerProperties = modcomputenetwork.NewProc("HcnQueryLoadBalancerProperties")
procHcnDeleteLoadBalancer = modcomputenetwork.NewProc("HcnDeleteLoadBalancer") procHcnDeleteLoadBalancer = modcomputenetwork.NewProc("HcnDeleteLoadBalancer")
procHcnCloseLoadBalancer = modcomputenetwork.NewProc("HcnCloseLoadBalancer") procHcnCloseLoadBalancer = modcomputenetwork.NewProc("HcnCloseLoadBalancer")
procHcnEnumerateSdnRoutes = modcomputenetwork.NewProc("HcnEnumerateSdnRoutes")
procHcnCreateSdnRoute = modcomputenetwork.NewProc("HcnCreateSdnRoute")
procHcnOpenSdnRoute = modcomputenetwork.NewProc("HcnOpenSdnRoute")
procHcnModifySdnRoute = modcomputenetwork.NewProc("HcnModifySdnRoute")
procHcnQuerySdnRouteProperties = modcomputenetwork.NewProc("HcnQuerySdnRouteProperties")
procHcnDeleteSdnRoute = modcomputenetwork.NewProc("HcnDeleteSdnRoute")
procHcnCloseSdnRoute = modcomputenetwork.NewProc("HcnCloseSdnRoute")
procHcnOpenService = modcomputenetwork.NewProc("HcnOpenService") procHcnOpenService = modcomputenetwork.NewProc("HcnOpenService")
procHcnRegisterServiceCallback = modcomputenetwork.NewProc("HcnRegisterServiceCallback") procHcnRegisterServiceCallback = modcomputenetwork.NewProc("HcnRegisterServiceCallback")
procHcnUnregisterServiceCallback = modcomputenetwork.NewProc("HcnUnregisterServiceCallback") procHcnUnregisterServiceCallback = modcomputenetwork.NewProc("HcnUnregisterServiceCallback")
@ -657,6 +664,140 @@ func hcnCloseLoadBalancer(loadBalancer hcnLoadBalancer) (hr error) {
return return
} }
func hcnEnumerateRoutes(query string, routes **uint16, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(query)
if hr != nil {
return
}
return _hcnEnumerateRoutes(_p0, routes, result)
}
func _hcnEnumerateRoutes(query *uint16, routes **uint16, result **uint16) (hr error) {
if hr = procHcnEnumerateSdnRoutes.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcnEnumerateSdnRoutes.Addr(), 3, uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(routes)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcnCreateRoute(id *_guid, settings string, route *hcnRoute, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(settings)
if hr != nil {
return
}
return _hcnCreateRoute(id, _p0, route, result)
}
func _hcnCreateRoute(id *_guid, settings *uint16, route *hcnRoute, result **uint16) (hr error) {
if hr = procHcnCreateSdnRoute.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall6(procHcnCreateSdnRoute.Addr(), 4, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(route)), uintptr(unsafe.Pointer(result)), 0, 0)
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcnOpenRoute(id *_guid, route *hcnRoute, result **uint16) (hr error) {
if hr = procHcnOpenSdnRoute.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcnOpenSdnRoute.Addr(), 3, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(route)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcnModifyRoute(route hcnRoute, settings string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(settings)
if hr != nil {
return
}
return _hcnModifyRoute(route, _p0, result)
}
func _hcnModifyRoute(route hcnRoute, settings *uint16, result **uint16) (hr error) {
if hr = procHcnModifySdnRoute.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcnModifySdnRoute.Addr(), 3, uintptr(route), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcnQueryRouteProperties(route hcnRoute, query string, properties **uint16, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(query)
if hr != nil {
return
}
return _hcnQueryRouteProperties(route, _p0, properties, result)
}
func _hcnQueryRouteProperties(route hcnRoute, query *uint16, properties **uint16, result **uint16) (hr error) {
if hr = procHcnQuerySdnRouteProperties.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall6(procHcnQuerySdnRouteProperties.Addr(), 4, uintptr(route), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)), 0, 0)
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcnDeleteRoute(id *_guid, result **uint16) (hr error) {
if hr = procHcnDeleteSdnRoute.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcnDeleteSdnRoute.Addr(), 2, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(result)), 0)
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcnCloseRoute(route hcnRoute) (hr error) {
if hr = procHcnCloseSdnRoute.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcnCloseSdnRoute.Addr(), 1, uintptr(route), 0, 0)
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcnOpenService(service *hcnService, result **uint16) (hr error) { func hcnOpenService(service *hcnService, result **uint16) (hr error) {
if hr = procHcnOpenService.Find(); hr != nil { if hr = procHcnOpenService.Find(); hr != nil {
return return

View File

@ -39,11 +39,21 @@ func HNSListEndpointRequest() ([]HNSEndpoint, error) {
// HotAttachEndpoint makes a HCS Call to attach the endpoint to the container // HotAttachEndpoint makes a HCS Call to attach the endpoint to the container
func HotAttachEndpoint(containerID string, endpointID string) error { func HotAttachEndpoint(containerID string, endpointID string) error {
endpoint, err := GetHNSEndpointByID(endpointID)
isAttached, err := endpoint.IsAttached(containerID)
if isAttached {
return err
}
return modifyNetworkEndpoint(containerID, endpointID, Add) return modifyNetworkEndpoint(containerID, endpointID, Add)
} }
// HotDetachEndpoint makes a HCS Call to detach the endpoint from the container // HotDetachEndpoint makes a HCS Call to detach the endpoint from the container
func HotDetachEndpoint(containerID string, endpointID string) error { func HotDetachEndpoint(containerID string, endpointID string) error {
endpoint, err := GetHNSEndpointByID(endpointID)
isAttached, err := endpoint.IsAttached(containerID)
if !isAttached {
return err
}
return modifyNetworkEndpoint(containerID, endpointID, Remove) return modifyNetworkEndpoint(containerID, endpointID, Remove)
} }

View File

@ -21,8 +21,11 @@ const (
OutboundNat = hns.OutboundNat OutboundNat = hns.OutboundNat
ExternalLoadBalancer = hns.ExternalLoadBalancer ExternalLoadBalancer = hns.ExternalLoadBalancer
Route = hns.Route Route = hns.Route
Proxy = hns.Proxy
) )
type ProxyPolicy = hns.ProxyPolicy
type NatPolicy = hns.NatPolicy type NatPolicy = hns.NatPolicy
type QosPolicy = hns.QosPolicy type QosPolicy = hns.QosPolicy

View File

@ -7,7 +7,7 @@ go_library(
importpath = "github.com/Microsoft/hcsshim/internal/cni", importpath = "github.com/Microsoft/hcsshim/internal/cni",
visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"], visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"],
deps = [ deps = [
"//vendor/github.com/Microsoft/hcsshim/internal/guid:go_default_library", "//vendor/github.com/Microsoft/go-winio/pkg/guid:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/regstate:go_default_library", "//vendor/github.com/Microsoft/hcsshim/internal/regstate:go_default_library",
], ],
) )

View File

@ -3,7 +3,7 @@ package cni
import ( import (
"errors" "errors"
"github.com/Microsoft/hcsshim/internal/guid" "github.com/Microsoft/go-winio/pkg/guid"
"github.com/Microsoft/hcsshim/internal/regstate" "github.com/Microsoft/hcsshim/internal/regstate"
) )

27
vendor/github.com/Microsoft/hcsshim/internal/cow/BUILD generated vendored Normal file
View File

@ -0,0 +1,27 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["cow.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/Microsoft/hcsshim/internal/cow",
importpath = "github.com/Microsoft/hcsshim/internal/cow",
visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"],
deps = [
"//vendor/github.com/Microsoft/hcsshim/internal/schema1:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/schema2:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,83 @@
package cow
import (
"context"
"io"
"github.com/Microsoft/hcsshim/internal/schema1"
hcsschema "github.com/Microsoft/hcsshim/internal/schema2"
)
// Process is the interface for an OS process running in a container or utility VM.
type Process interface {
// Close releases resources associated with the process and closes the
// writer and readers returned by Stdio. Depending on the implementation,
// this may also terminate the process.
Close() error
// CloseStdin causes the process's stdin handle to receive EOF/EPIPE/whatever
// is appropriate to indicate that no more data is available.
CloseStdin(ctx context.Context) error
// Pid returns the process ID.
Pid() int
// Stdio returns the stdio streams for a process. These may be nil if a stream
// was not requested during CreateProcess.
Stdio() (_ io.Writer, _ io.Reader, _ io.Reader)
// ResizeConsole resizes the virtual terminal associated with the process.
ResizeConsole(ctx context.Context, width, height uint16) error
// Kill sends a SIGKILL or equivalent signal to the process and returns whether
// the signal was delivered. It does not wait for the process to terminate.
Kill(ctx context.Context) (bool, error)
// Signal sends a signal to the process and returns whether the signal was
// delivered. The input is OS specific (either
// guestrequest.SignalProcessOptionsWCOW or
// guestrequest.SignalProcessOptionsLCOW). It does not wait for the process
// to terminate.
Signal(ctx context.Context, options interface{}) (bool, error)
// Wait waits for the process to complete, or for a connection to the process to be
// terminated by some error condition (including calling Close).
Wait() error
// ExitCode returns the exit code of the process. Returns an error if the process is
// not running.
ExitCode() (int, error)
}
// ProcessHost is the interface for creating processes.
type ProcessHost interface {
// CreateProcess creates a process. The configuration is host specific
// (either hcsschema.ProcessParameters or lcow.ProcessParameters).
CreateProcess(ctx context.Context, config interface{}) (Process, error)
// OS returns the host's operating system, "linux" or "windows".
OS() string
// IsOCI specifies whether this is an OCI-compliant process host. If true,
// then the configuration passed to CreateProcess should have an OCI process
// spec (or nil if this is the initial process in an OCI container).
// Otherwise, it should have the HCS-specific process parameters.
IsOCI() bool
}
// Container is the interface for container objects, either running on the host or
// in a utility VM.
type Container interface {
ProcessHost
// Close releases the resources associated with the container. Depending on
// the implementation, this may also terminate the container.
Close() error
// ID returns the container ID.
ID() string
// Properties returns the requested container properties targeting a V1 schema container.
Properties(ctx context.Context, types ...schema1.PropertyType) (*schema1.ContainerProperties, error)
// PropertiesV2 returns the requested container properties targeting a V2 schema container.
PropertiesV2(ctx context.Context, types ...hcsschema.PropertyType) (*hcsschema.Properties, error)
// Start starts a container.
Start(ctx context.Context) error
// Shutdown sends a shutdown request to the container (but does not wait for
// the shutdown to complete).
Shutdown(ctx context.Context) error
// Terminate sends a terminate request to the container (but does not wait
// for the terminate to complete).
Terminate(ctx context.Context) error
// Wait waits for the container to terminate, or for the connection to the
// container to be terminated by some error condition (including calling
// Close).
Wait() error
}

View File

@ -1,69 +0,0 @@
package guid
import (
"crypto/rand"
"encoding/json"
"fmt"
"io"
"strconv"
"strings"
)
var _ = (json.Marshaler)(&GUID{})
var _ = (json.Unmarshaler)(&GUID{})
type GUID [16]byte
func New() GUID {
g := GUID{}
_, err := io.ReadFull(rand.Reader, g[:])
if err != nil {
panic(err)
}
return g
}
func (g GUID) String() string {
return fmt.Sprintf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x-%02x", g[3], g[2], g[1], g[0], g[5], g[4], g[7], g[6], g[8:10], g[10:])
}
func FromString(s string) GUID {
if len(s) != 36 {
panic(fmt.Sprintf("invalid GUID length: %d", len(s)))
}
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
panic("invalid GUID format")
}
indexOrder := [16]int{
0, 2, 4, 6,
9, 11,
14, 16,
19, 21,
24, 26, 28, 30, 32, 34,
}
byteOrder := [16]int{
3, 2, 1, 0,
5, 4,
7, 6,
8, 9,
10, 11, 12, 13, 14, 15,
}
var g GUID
for i, x := range indexOrder {
b, err := strconv.ParseInt(s[x:x+2], 16, 16)
if err != nil {
panic(err)
}
g[byteOrder[i]] = byte(b)
}
return g
}
func (g GUID) MarshalJSON() ([]byte, error) {
return json.Marshal(g.String())
}
func (g *GUID) UnmarshalJSON(data []byte) error {
*g = FromString(strings.Trim(string(data), "\""))
return nil
}

View File

@ -4,34 +4,34 @@ go_library(
name = "go_default_library", name = "go_default_library",
srcs = [ srcs = [
"callback.go", "callback.go",
"cgo.go",
"errors.go", "errors.go",
"hcs.go",
"log.go",
"process.go", "process.go",
"syscall.go",
"system.go", "system.go",
"utils.go", "utils.go",
"waithelper.go", "waithelper.go",
"watcher.go",
"zsyscall_windows.go", "zsyscall_windows.go",
], ],
cgo = True,
importmap = "k8s.io/kubernetes/vendor/github.com/Microsoft/hcsshim/internal/hcs", importmap = "k8s.io/kubernetes/vendor/github.com/Microsoft/hcsshim/internal/hcs",
importpath = "github.com/Microsoft/hcsshim/internal/hcs", importpath = "github.com/Microsoft/hcsshim/internal/hcs",
visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"], visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"],
deps = [ deps = [
"//vendor/github.com/Microsoft/go-winio:go_default_library", "//vendor/github.com/Microsoft/go-winio:go_default_library",
"//vendor/github.com/Microsoft/go-winio/vhd: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/interop:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/log:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/logfields:go_default_library", "//vendor/github.com/Microsoft/hcsshim/internal/logfields:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/oc:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/schema1:go_default_library", "//vendor/github.com/Microsoft/hcsshim/internal/schema1:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/schema2:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/timeout:go_default_library", "//vendor/github.com/Microsoft/hcsshim/internal/timeout:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/vmcompute:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/sirupsen/logrus:go_default_library", "//vendor/github.com/sirupsen/logrus:go_default_library",
] + select({ "//vendor/go.opencensus.io/trace:go_default_library",
"@io_bazel_rules_go//go/platform:windows": [
"//vendor/golang.org/x/sys/windows:go_default_library", "//vendor/golang.org/x/sys/windows:go_default_library",
], ],
"//conditions:default": [],
}),
) )
filegroup( filegroup(

View File

@ -7,6 +7,7 @@ import (
"github.com/Microsoft/hcsshim/internal/interop" "github.com/Microsoft/hcsshim/internal/interop"
"github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/logfields"
"github.com/Microsoft/hcsshim/internal/vmcompute"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -88,7 +89,7 @@ type notificationChannel chan error
type notifcationWatcherContext struct { type notifcationWatcherContext struct {
channels notificationChannels channels notificationChannels
handle hcsCallback handle vmcompute.HcsCallback
systemID string systemID string
processID int processID int
@ -98,21 +99,27 @@ type notificationChannels map[hcsNotification]notificationChannel
func newSystemChannels() notificationChannels { func newSystemChannels() notificationChannels {
channels := make(notificationChannels) channels := make(notificationChannels)
for _, notif := range []hcsNotification{
channels[hcsNotificationSystemExited] = make(notificationChannel, 1) hcsNotificationServiceDisconnect,
channels[hcsNotificationSystemCreateCompleted] = make(notificationChannel, 1) hcsNotificationSystemExited,
channels[hcsNotificationSystemStartCompleted] = make(notificationChannel, 1) hcsNotificationSystemCreateCompleted,
channels[hcsNotificationSystemPauseCompleted] = make(notificationChannel, 1) hcsNotificationSystemStartCompleted,
channels[hcsNotificationSystemResumeCompleted] = make(notificationChannel, 1) hcsNotificationSystemPauseCompleted,
hcsNotificationSystemResumeCompleted,
} {
channels[notif] = make(notificationChannel, 1)
}
return channels return channels
} }
func newProcessChannels() notificationChannels { func newProcessChannels() notificationChannels {
channels := make(notificationChannels) channels := make(notificationChannels)
for _, notif := range []hcsNotification{
channels[hcsNotificationProcessExited] = make(notificationChannel, 1) hcsNotificationServiceDisconnect,
hcsNotificationProcessExited,
} {
channels[notif] = make(notificationChannel, 1)
}
return channels return channels
} }
@ -143,18 +150,7 @@ func notificationWatcher(notificationType hcsNotification, callbackNumber uintpt
if context.processID != 0 { if context.processID != 0 {
log.Data[logfields.ProcessID] = context.processID log.Data[logfields.ProcessID] = context.processID
} }
log.Debug("") log.Debug("HCS notification")
// The HCS notification system can grow overtime. We explicitly opt-in to
// the notifications we would like to handle, all others we simply return.
// This means that as it grows we don't have issues associated with new
// notification types the code didn't know about.
switch notificationType {
case hcsNotificationSystemExited, hcsNotificationSystemCreateCompleted, hcsNotificationSystemStartCompleted, hcsNotificationSystemPauseCompleted, hcsNotificationSystemResumeCompleted:
case hcsNotificationProcessExited:
default:
return 0
}
if channel, ok := context.channels[notificationType]; ok { if channel, ok := context.channels[notificationType]; ok {
channel <- result channel <- result

View File

@ -1,7 +0,0 @@
package hcs
import "C"
// This import is needed to make the library compile as CGO because HCSSHIM
// only works with CGO due to callbacks from HCS comming back from a C thread
// which is not supported without CGO. See https://github.com/golang/go/issues/10973

View File

@ -1,14 +1,14 @@
package hcs package hcs
import ( import (
"context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"net"
"syscall" "syscall"
"github.com/Microsoft/hcsshim/internal/interop" "github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/logfields"
"github.com/sirupsen/logrus"
) )
var ( var (
@ -117,17 +117,11 @@ func (ev *ErrorEvent) String() string {
return evs return evs
} }
func processHcsResult(resultp *uint16) []ErrorEvent { func processHcsResult(ctx context.Context, resultJSON string) []ErrorEvent {
if resultp != nil { if resultJSON != "" {
resultj := interop.ConvertAndFreeCoTaskMemString(resultp)
logrus.WithField(logfields.JSON, resultj).
Debug("HCS Result")
result := &hcsResult{} result := &hcsResult{}
if err := json.Unmarshal([]byte(resultj), result); err != nil { if err := json.Unmarshal([]byte(resultJSON), result); err != nil {
logrus.WithFields(logrus.Fields{ log.G(ctx).WithError(err).Warning("Could not unmarshal HCS result")
logfields.JSON: resultj,
logrus.ErrorKey: err,
}).Warning("Could not unmarshal HCS result")
return nil return nil
} }
return result.ErrorEvents return result.ErrorEvents
@ -141,6 +135,8 @@ type HcsError struct {
Events []ErrorEvent Events []ErrorEvent
} }
var _ net.Error = &HcsError{}
func (e *HcsError) Error() string { func (e *HcsError) Error() string {
s := e.Op + ": " + e.Err.Error() s := e.Op + ": " + e.Err.Error()
for _, ev := range e.Events { for _, ev := range e.Events {
@ -149,6 +145,16 @@ func (e *HcsError) Error() string {
return s return s
} }
func (e *HcsError) Temporary() bool {
err, ok := e.Err.(net.Error)
return ok && err.Temporary()
}
func (e *HcsError) Timeout() bool {
err, ok := e.Err.(net.Error)
return ok && err.Timeout()
}
// ProcessError is an error encountered in HCS during an operation on a Process object // ProcessError is an error encountered in HCS during an operation on a Process object
type ProcessError struct { type ProcessError struct {
SystemID string SystemID string
@ -158,6 +164,8 @@ type ProcessError struct {
Events []ErrorEvent Events []ErrorEvent
} }
var _ net.Error = &ProcessError{}
// SystemError is an error encountered in HCS during an operation on a Container object // SystemError is an error encountered in HCS during an operation on a Container object
type SystemError struct { type SystemError struct {
ID string ID string
@ -167,6 +175,8 @@ type SystemError struct {
Events []ErrorEvent Events []ErrorEvent
} }
var _ net.Error = &SystemError{}
func (e *SystemError) Error() string { func (e *SystemError) Error() string {
s := e.Op + " " + e.ID + ": " + e.Err.Error() s := e.Op + " " + e.ID + ": " + e.Err.Error()
for _, ev := range e.Events { for _, ev := range e.Events {
@ -178,6 +188,16 @@ func (e *SystemError) Error() string {
return s return s
} }
func (e *SystemError) Temporary() bool {
err, ok := e.Err.(net.Error)
return ok && err.Temporary()
}
func (e *SystemError) Timeout() bool {
err, ok := e.Err.(net.Error)
return ok && err.Timeout()
}
func makeSystemError(system *System, op string, extra string, err error, events []ErrorEvent) error { func makeSystemError(system *System, op string, extra string, err error, events []ErrorEvent) error {
// Don't double wrap errors // Don't double wrap errors
if _, ok := err.(*SystemError); ok { if _, ok := err.(*SystemError); ok {
@ -200,6 +220,16 @@ func (e *ProcessError) Error() string {
return s return s
} }
func (e *ProcessError) Temporary() bool {
err, ok := e.Err.(net.Error)
return ok && err.Temporary()
}
func (e *ProcessError) Timeout() bool {
err, ok := e.Err.(net.Error)
return ok && err.Timeout()
}
func makeProcessError(process *Process, op string, err error, events []ErrorEvent) error { func makeProcessError(process *Process, op string, err error, events []ErrorEvent) error {
// Don't double wrap errors // Don't double wrap errors
if _, ok := err.(*ProcessError); ok { if _, ok := err.(*ProcessError); ok {
@ -242,6 +272,9 @@ func IsPending(err error) bool {
// IsTimeout returns a boolean indicating whether the error is caused by // IsTimeout returns a boolean indicating whether the error is caused by
// a timeout waiting for the operation to complete. // a timeout waiting for the operation to complete.
func IsTimeout(err error) bool { func IsTimeout(err error) bool {
if err, ok := err.(net.Error); ok && err.Timeout() {
return true
}
err = getInnerError(err) err = getInnerError(err)
return err == ErrTimeout return err == ErrTimeout
} }
@ -292,3 +325,12 @@ func getInnerError(err error) error {
} }
return err return err
} }
func getOperationLogResult(err error) (string, error) {
switch err {
case nil:
return "Success", nil
default:
return "Error", err
}
}

View File

@ -1,48 +0,0 @@
// Shim for the Host Compute Service (HCS) to manage Windows Server
// containers and Hyper-V containers.
package hcs
import (
"syscall"
)
//go:generate go run ../../mksyscall_windows.go -output zsyscall_windows.go hcs.go
//sys hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) = vmcompute.HcsEnumerateComputeSystems?
//sys hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsCreateComputeSystem?
//sys hcsOpenComputeSystem(id string, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsOpenComputeSystem?
//sys hcsCloseComputeSystem(computeSystem hcsSystem) (hr error) = vmcompute.HcsCloseComputeSystem?
//sys hcsStartComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsStartComputeSystem?
//sys hcsShutdownComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsShutdownComputeSystem?
//sys hcsTerminateComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsTerminateComputeSystem?
//sys hcsPauseComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsPauseComputeSystem?
//sys hcsResumeComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsResumeComputeSystem?
//sys hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetComputeSystemProperties?
//sys hcsModifyComputeSystem(computeSystem hcsSystem, configuration string, result **uint16) (hr error) = vmcompute.HcsModifyComputeSystem?
//sys hcsRegisterComputeSystemCallback(computeSystem hcsSystem, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) = vmcompute.HcsRegisterComputeSystemCallback?
//sys hcsUnregisterComputeSystemCallback(callbackHandle hcsCallback) (hr error) = vmcompute.HcsUnregisterComputeSystemCallback?
//sys hcsCreateProcess(computeSystem hcsSystem, processParameters string, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsCreateProcess?
//sys hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsOpenProcess?
//sys hcsCloseProcess(process hcsProcess) (hr error) = vmcompute.HcsCloseProcess?
//sys hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) = vmcompute.HcsTerminateProcess?
//sys hcsSignalProcess(process hcsProcess, options string, result **uint16) (hr error) = vmcompute.HcsSignalProcess?
//sys hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInformation, result **uint16) (hr error) = vmcompute.HcsGetProcessInfo?
//sys hcsGetProcessProperties(process hcsProcess, processProperties **uint16, result **uint16) (hr error) = vmcompute.HcsGetProcessProperties?
//sys hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr error) = vmcompute.HcsModifyProcess?
//sys hcsGetServiceProperties(propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetServiceProperties?
//sys hcsRegisterProcessCallback(process hcsProcess, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) = vmcompute.HcsRegisterProcessCallback?
//sys hcsUnregisterProcessCallback(callbackHandle hcsCallback) (hr error) = vmcompute.HcsUnregisterProcessCallback?
type hcsSystem syscall.Handle
type hcsProcess syscall.Handle
type hcsCallback syscall.Handle
type hcsProcessInformation struct {
ProcessId uint32
Reserved uint32
StdInput syscall.Handle
StdOutput syscall.Handle
StdError syscall.Handle
}

View File

@ -1,20 +0,0 @@
package hcs
import "github.com/sirupsen/logrus"
func logOperationBegin(ctx logrus.Fields, msg string) {
logrus.WithFields(ctx).Debug(msg)
}
func logOperationEnd(ctx logrus.Fields, msg string, err error) {
// Copy the log and fields first.
log := logrus.WithFields(ctx)
if err == nil {
log.Debug(msg)
} else {
// Edit only the copied field data to avoid race conditions on the
// write.
log.Data[logrus.ErrorKey] = err
log.Error(msg)
}
}

View File

@ -1,52 +1,47 @@
package hcs package hcs
import ( import (
"context"
"encoding/json" "encoding/json"
"io" "io"
"sync" "sync"
"syscall" "syscall"
"time" "time"
"github.com/Microsoft/hcsshim/internal/interop" "github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/oc"
"github.com/sirupsen/logrus" "github.com/Microsoft/hcsshim/internal/vmcompute"
"go.opencensus.io/trace"
) )
// ContainerError is an error encountered in HCS // ContainerError is an error encountered in HCS
type Process struct { type Process struct {
handleLock sync.RWMutex handleLock sync.RWMutex
handle hcsProcess handle vmcompute.HcsProcess
processID int processID int
system *System system *System
cachedPipes *cachedPipes hasCachedStdio bool
stdioLock sync.Mutex
stdin io.WriteCloser
stdout io.ReadCloser
stderr io.ReadCloser
callbackNumber uintptr callbackNumber uintptr
logctx logrus.Fields
closedWaitOnce sync.Once closedWaitOnce sync.Once
waitBlock chan struct{} waitBlock chan struct{}
exitCode int
waitError error waitError error
} }
func newProcess(process hcsProcess, processID int, computeSystem *System) *Process { func newProcess(process vmcompute.HcsProcess, processID int, computeSystem *System) *Process {
return &Process{ return &Process{
handle: process, handle: process,
processID: processID, processID: processID,
system: computeSystem, system: computeSystem,
logctx: logrus.Fields{
logfields.ContainerID: computeSystem.ID(),
logfields.ProcessID: processID,
},
waitBlock: make(chan struct{}), waitBlock: make(chan struct{}),
} }
} }
type cachedPipes struct {
stdIn syscall.Handle
stdOut syscall.Handle
stdErr syscall.Handle
}
type processModifyRequest struct { type processModifyRequest struct {
Operation string Operation string
ConsoleSize *consoleSize `json:",omitempty"` ConsoleSize *consoleSize `json:",omitempty"`
@ -62,7 +57,7 @@ type closeHandle struct {
Handle string Handle string
} }
type ProcessStatus struct { type processStatus struct {
ProcessID uint32 ProcessID uint32
Exited bool Exited bool
ExitCode uint32 ExitCode uint32
@ -90,24 +85,32 @@ func (process *Process) SystemID() string {
return process.system.ID() return process.system.ID()
} }
func (process *Process) logOperationBegin(operation string) { func (process *Process) processSignalResult(ctx context.Context, err error) (bool, error) {
logOperationBegin( switch err {
process.logctx, case nil:
operation+" - Begin Operation") return true, nil
case ErrVmcomputeOperationInvalidState, ErrComputeSystemDoesNotExist, ErrElementNotFound:
select {
case <-process.waitBlock:
// The process exit notification has already arrived.
default:
// The process should be gone, but we have not received the notification.
// After a second, force unblock the process wait to work around a possible
// deadlock in the HCS.
go func() {
time.Sleep(time.Second)
process.closedWaitOnce.Do(func() {
log.G(ctx).WithError(err).Warn("force unblocking process waits")
process.exitCode = -1
process.waitError = err
close(process.waitBlock)
})
}()
} }
return false, nil
func (process *Process) logOperationEnd(operation string, err error) { default:
var result string return false, err
if err == nil {
result = "Success"
} else {
result = "Error"
} }
logOperationEnd(
process.logctx,
operation+" - End Operation - "+result,
err)
} }
// Signal signals the process with `options`. // Signal signals the process with `options`.
@ -115,115 +118,120 @@ func (process *Process) logOperationEnd(operation string, err error) {
// For LCOW `guestrequest.SignalProcessOptionsLCOW`. // For LCOW `guestrequest.SignalProcessOptionsLCOW`.
// //
// For WCOW `guestrequest.SignalProcessOptionsWCOW`. // For WCOW `guestrequest.SignalProcessOptionsWCOW`.
func (process *Process) Signal(options interface{}) (err error) { func (process *Process) Signal(ctx context.Context, options interface{}) (bool, error) {
process.handleLock.RLock() process.handleLock.RLock()
defer process.handleLock.RUnlock() defer process.handleLock.RUnlock()
operation := "hcsshim::Process::Signal" operation := "hcsshim::Process::Signal"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
if process.handle == 0 { if process.handle == 0 {
return makeProcessError(process, operation, ErrAlreadyClosed, nil) return false, makeProcessError(process, operation, ErrAlreadyClosed, nil)
} }
optionsb, err := json.Marshal(options) optionsb, err := json.Marshal(options)
if err != nil { if err != nil {
return err return false, err
} }
optionsStr := string(optionsb) resultJSON, err := vmcompute.HcsSignalProcess(ctx, process.handle, string(optionsb))
events := processHcsResult(ctx, resultJSON)
var resultp *uint16 delivered, err := process.processSignalResult(ctx, err)
syscallWatcher(process.logctx, func() {
err = hcsSignalProcess(process.handle, optionsStr, &resultp)
})
events := processHcsResult(resultp)
if err != nil { if err != nil {
return makeProcessError(process, operation, err, events) err = makeProcessError(process, operation, err, events)
} }
return delivered, err
return nil
} }
// Kill signals the process to terminate but does not wait for it to finish terminating. // Kill signals the process to terminate but does not wait for it to finish terminating.
func (process *Process) Kill() (err error) { func (process *Process) Kill(ctx context.Context) (bool, error) {
process.handleLock.RLock() process.handleLock.RLock()
defer process.handleLock.RUnlock() defer process.handleLock.RUnlock()
operation := "hcsshim::Process::Kill" operation := "hcsshim::Process::Kill"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
if process.handle == 0 { if process.handle == 0 {
return makeProcessError(process, operation, ErrAlreadyClosed, nil) return false, makeProcessError(process, operation, ErrAlreadyClosed, nil)
} }
var resultp *uint16 resultJSON, err := vmcompute.HcsTerminateProcess(ctx, process.handle)
syscallWatcher(process.logctx, func() { events := processHcsResult(ctx, resultJSON)
err = hcsTerminateProcess(process.handle, &resultp) delivered, err := process.processSignalResult(ctx, err)
})
events := processHcsResult(resultp)
if err != nil { if err != nil {
return makeProcessError(process, operation, err, events) err = makeProcessError(process, operation, err, events)
} }
return delivered, err
return nil
} }
// waitBackground waits for the process exit notification. Once received sets // waitBackground waits for the process exit notification. Once received sets
// `process.waitError` (if any) and unblocks all `Wait` and `WaitTimeout` calls. // `process.waitError` (if any) and unblocks all `Wait` calls.
// //
// This MUST be called exactly once per `process.handle` but `Wait` and // This MUST be called exactly once per `process.handle` but `Wait` is safe to
// `WaitTimeout` are safe to call multiple times. // call multiple times.
func (process *Process) waitBackground() { func (process *Process) waitBackground() {
process.waitError = waitForNotification(process.callbackNumber, hcsNotificationProcessExited, nil) operation := "hcsshim::Process::waitBackground"
ctx, span := trace.StartSpan(context.Background(), operation)
defer span.End()
span.AddAttributes(
trace.StringAttribute("cid", process.SystemID()),
trace.Int64Attribute("pid", int64(process.processID)))
var (
err error
exitCode = -1
)
err = waitForNotification(ctx, process.callbackNumber, hcsNotificationProcessExited, nil)
if err != nil {
err = makeProcessError(process, operation, err, nil)
log.G(ctx).WithError(err).Error("failed wait")
} else {
process.handleLock.RLock()
defer process.handleLock.RUnlock()
// Make sure we didnt race with Close() here
if process.handle != 0 {
propertiesJSON, resultJSON, err := vmcompute.HcsGetProcessProperties(ctx, process.handle)
events := processHcsResult(ctx, resultJSON)
if err != nil {
err = makeProcessError(process, operation, err, events)
} else {
properties := &processStatus{}
err = json.Unmarshal([]byte(propertiesJSON), properties)
if err != nil {
err = makeProcessError(process, operation, err, nil)
} else {
if properties.LastWaitResult != 0 {
log.G(ctx).WithField("wait-result", properties.LastWaitResult).Warning("non-zero last wait result")
} else {
exitCode = int(properties.ExitCode)
}
}
}
}
}
log.G(ctx).WithField("exitCode", exitCode).Debug("process exited")
process.closedWaitOnce.Do(func() { process.closedWaitOnce.Do(func() {
process.exitCode = exitCode
process.waitError = err
close(process.waitBlock) close(process.waitBlock)
}) })
oc.SetSpanStatus(span, err)
} }
// Wait waits for the process to exit. If the process has already exited returns // Wait waits for the process to exit. If the process has already exited returns
// the pervious error (if any). // the pervious error (if any).
func (process *Process) Wait() (err error) { func (process *Process) Wait() error {
operation := "hcsshim::Process::Wait"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
<-process.waitBlock <-process.waitBlock
if process.waitError != nil { return process.waitError
return makeProcessError(process, operation, process.waitError, nil)
}
return nil
}
// WaitTimeout waits for the process to exit or the duration to elapse. If the
// process has already exited returns the pervious error (if any). If a timeout
// occurs returns `ErrTimeout`.
func (process *Process) WaitTimeout(timeout time.Duration) (err error) {
operation := "hcssshim::Process::WaitTimeout"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
select {
case <-process.waitBlock:
if process.waitError != nil {
return makeProcessError(process, operation, process.waitError, nil)
}
return nil
case <-time.After(timeout):
return makeProcessError(process, operation, ErrTimeout, nil)
}
} }
// ResizeConsole resizes the console of the process. // ResizeConsole resizes the console of the process.
func (process *Process) ResizeConsole(width, height uint16) (err error) { func (process *Process) ResizeConsole(ctx context.Context, width, height uint16) error {
process.handleLock.RLock() process.handleLock.RLock()
defer process.handleLock.RUnlock() defer process.handleLock.RUnlock()
operation := "hcsshim::Process::ResizeConsole" operation := "hcsshim::Process::ResizeConsole"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
if process.handle == 0 { if process.handle == 0 {
return makeProcessError(process, operation, ErrAlreadyClosed, nil) return makeProcessError(process, operation, ErrAlreadyClosed, nil)
@ -242,11 +250,8 @@ func (process *Process) ResizeConsole(width, height uint16) (err error) {
return err return err
} }
modifyRequestStr := string(modifyRequestb) resultJSON, err := vmcompute.HcsModifyProcess(ctx, process.handle, string(modifyRequestb))
events := processHcsResult(ctx, resultJSON)
var resultp *uint16
err = hcsModifyProcess(process.handle, modifyRequestStr, &resultp)
events := processHcsResult(resultp)
if err != nil { if err != nil {
return makeProcessError(process, operation, err, events) return makeProcessError(process, operation, err, events)
} }
@ -254,109 +259,55 @@ func (process *Process) ResizeConsole(width, height uint16) (err error) {
return nil return nil
} }
func (process *Process) Properties() (_ *ProcessStatus, err error) {
process.handleLock.RLock()
defer process.handleLock.RUnlock()
operation := "hcsshim::Process::Properties"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
if process.handle == 0 {
return nil, makeProcessError(process, operation, ErrAlreadyClosed, nil)
}
var (
resultp *uint16
propertiesp *uint16
)
syscallWatcher(process.logctx, func() {
err = hcsGetProcessProperties(process.handle, &propertiesp, &resultp)
})
events := processHcsResult(resultp)
if err != nil {
return nil, makeProcessError(process, operation, err, events)
}
if propertiesp == nil {
return nil, ErrUnexpectedValue
}
propertiesRaw := interop.ConvertAndFreeCoTaskMemBytes(propertiesp)
properties := &ProcessStatus{}
if err := json.Unmarshal(propertiesRaw, properties); err != nil {
return nil, makeProcessError(process, operation, err, nil)
}
return properties, nil
}
// ExitCode returns the exit code of the process. The process must have // ExitCode returns the exit code of the process. The process must have
// already terminated. // already terminated.
func (process *Process) ExitCode() (_ int, err error) { func (process *Process) ExitCode() (int, error) {
operation := "hcsshim::Process::ExitCode" select {
process.logOperationBegin(operation) case <-process.waitBlock:
defer func() { process.logOperationEnd(operation, err) }() if process.waitError != nil {
return -1, process.waitError
properties, err := process.Properties() }
if err != nil { return process.exitCode, nil
return -1, makeProcessError(process, operation, err, nil) default:
return -1, makeProcessError(process, "hcsshim::Process::ExitCode", ErrInvalidProcessState, nil)
}
} }
if properties.Exited == false { // StdioLegacy returns the stdin, stdout, and stderr pipes, respectively. Closing
return -1, makeProcessError(process, operation, ErrInvalidProcessState, nil) // these pipes does not close the underlying pipes. Once returned, these pipes
} // are the responsibility of the caller to close.
func (process *Process) StdioLegacy() (_ io.WriteCloser, _ io.ReadCloser, _ io.ReadCloser, err error) {
operation := "hcsshim::Process::StdioLegacy"
ctx, span := trace.StartSpan(context.Background(), operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("cid", process.SystemID()),
trace.Int64Attribute("pid", int64(process.processID)))
if properties.LastWaitResult != 0 {
logrus.WithFields(logrus.Fields{
logfields.ContainerID: process.SystemID(),
logfields.ProcessID: process.processID,
"wait-result": properties.LastWaitResult,
}).Warn("hcsshim::Process::ExitCode - Non-zero last wait result")
return -1, nil
}
return int(properties.ExitCode), nil
}
// Stdio returns the stdin, stdout, and stderr pipes, respectively. Closing
// these pipes does not close the underlying pipes; it should be possible to
// call this multiple times to get multiple interfaces.
func (process *Process) Stdio() (_ io.WriteCloser, _ io.ReadCloser, _ io.ReadCloser, err error) {
process.handleLock.RLock() process.handleLock.RLock()
defer process.handleLock.RUnlock() defer process.handleLock.RUnlock()
operation := "hcsshim::Process::Stdio"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
if process.handle == 0 { if process.handle == 0 {
return nil, nil, nil, makeProcessError(process, operation, ErrAlreadyClosed, nil) return nil, nil, nil, makeProcessError(process, operation, ErrAlreadyClosed, nil)
} }
var stdIn, stdOut, stdErr syscall.Handle process.stdioLock.Lock()
defer process.stdioLock.Unlock()
if process.hasCachedStdio {
stdin, stdout, stderr := process.stdin, process.stdout, process.stderr
process.stdin, process.stdout, process.stderr = nil, nil, nil
process.hasCachedStdio = false
return stdin, stdout, stderr, nil
}
if process.cachedPipes == nil { processInfo, resultJSON, err := vmcompute.HcsGetProcessInfo(ctx, process.handle)
var ( events := processHcsResult(ctx, resultJSON)
processInfo hcsProcessInformation
resultp *uint16
)
err = hcsGetProcessInfo(process.handle, &processInfo, &resultp)
events := processHcsResult(resultp)
if err != nil { if err != nil {
return nil, nil, nil, makeProcessError(process, operation, err, events) return nil, nil, nil, makeProcessError(process, operation, err, events)
} }
stdIn, stdOut, stdErr = processInfo.StdInput, processInfo.StdOutput, processInfo.StdError pipes, err := makeOpenFiles([]syscall.Handle{processInfo.StdInput, processInfo.StdOutput, processInfo.StdError})
} else {
// Use cached pipes
stdIn, stdOut, stdErr = process.cachedPipes.stdIn, process.cachedPipes.stdOut, process.cachedPipes.stdErr
// Invalidate the cache
process.cachedPipes = nil
}
pipes, err := makeOpenFiles([]syscall.Handle{stdIn, stdOut, stdErr})
if err != nil { if err != nil {
return nil, nil, nil, makeProcessError(process, operation, err, nil) return nil, nil, nil, makeProcessError(process, operation, err, nil)
} }
@ -364,15 +315,21 @@ func (process *Process) Stdio() (_ io.WriteCloser, _ io.ReadCloser, _ io.ReadClo
return pipes[0], pipes[1], pipes[2], nil return pipes[0], pipes[1], pipes[2], nil
} }
// Stdio returns the stdin, stdout, and stderr pipes, respectively.
// To close them, close the process handle.
func (process *Process) Stdio() (stdin io.Writer, stdout, stderr io.Reader) {
process.stdioLock.Lock()
defer process.stdioLock.Unlock()
return process.stdin, process.stdout, process.stderr
}
// CloseStdin closes the write side of the stdin pipe so that the process is // CloseStdin closes the write side of the stdin pipe so that the process is
// notified on the read side that there is no more data in stdin. // notified on the read side that there is no more data in stdin.
func (process *Process) CloseStdin() (err error) { func (process *Process) CloseStdin(ctx context.Context) error {
process.handleLock.RLock() process.handleLock.RLock()
defer process.handleLock.RUnlock() defer process.handleLock.RUnlock()
operation := "hcsshim::Process::CloseStdin" operation := "hcsshim::Process::CloseStdin"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
if process.handle == 0 { if process.handle == 0 {
return makeProcessError(process, operation, ErrAlreadyClosed, nil) return makeProcessError(process, operation, ErrAlreadyClosed, nil)
@ -390,51 +347,76 @@ func (process *Process) CloseStdin() (err error) {
return err return err
} }
modifyRequestStr := string(modifyRequestb) resultJSON, err := vmcompute.HcsModifyProcess(ctx, process.handle, string(modifyRequestb))
events := processHcsResult(ctx, resultJSON)
var resultp *uint16
err = hcsModifyProcess(process.handle, modifyRequestStr, &resultp)
events := processHcsResult(resultp)
if err != nil { if err != nil {
return makeProcessError(process, operation, err, events) return makeProcessError(process, operation, err, events)
} }
process.stdioLock.Lock()
if process.stdin != nil {
process.stdin.Close()
process.stdin = nil
}
process.stdioLock.Unlock()
return nil return nil
} }
// Close cleans up any state associated with the process but does not kill // Close cleans up any state associated with the process but does not kill
// or wait on it. // or wait on it.
func (process *Process) Close() (err error) { func (process *Process) Close() (err error) {
operation := "hcsshim::Process::Close"
ctx, span := trace.StartSpan(context.Background(), operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("cid", process.SystemID()),
trace.Int64Attribute("pid", int64(process.processID)))
process.handleLock.Lock() process.handleLock.Lock()
defer process.handleLock.Unlock() defer process.handleLock.Unlock()
operation := "hcsshim::Process::Close"
process.logOperationBegin(operation)
defer func() { process.logOperationEnd(operation, err) }()
// Don't double free this // Don't double free this
if process.handle == 0 { if process.handle == 0 {
return nil return nil
} }
if err = process.unregisterCallback(); err != nil { process.stdioLock.Lock()
if process.stdin != nil {
process.stdin.Close()
process.stdin = nil
}
if process.stdout != nil {
process.stdout.Close()
process.stdout = nil
}
if process.stderr != nil {
process.stderr.Close()
process.stderr = nil
}
process.stdioLock.Unlock()
if err = process.unregisterCallback(ctx); err != nil {
return makeProcessError(process, operation, err, nil) return makeProcessError(process, operation, err, nil)
} }
if err = hcsCloseProcess(process.handle); err != nil { if err = vmcompute.HcsCloseProcess(ctx, process.handle); err != nil {
return makeProcessError(process, operation, err, nil) return makeProcessError(process, operation, err, nil)
} }
process.handle = 0 process.handle = 0
process.closedWaitOnce.Do(func() { process.closedWaitOnce.Do(func() {
process.exitCode = -1
process.waitError = ErrAlreadyClosed
close(process.waitBlock) close(process.waitBlock)
}) })
return nil return nil
} }
func (process *Process) registerCallback() error { func (process *Process) registerCallback(ctx context.Context) error {
context := &notifcationWatcherContext{ callbackContext := &notifcationWatcherContext{
channels: newProcessChannels(), channels: newProcessChannels(),
systemID: process.SystemID(), systemID: process.SystemID(),
processID: process.processID, processID: process.processID,
@ -443,45 +425,44 @@ func (process *Process) registerCallback() error {
callbackMapLock.Lock() callbackMapLock.Lock()
callbackNumber := nextCallback callbackNumber := nextCallback
nextCallback++ nextCallback++
callbackMap[callbackNumber] = context callbackMap[callbackNumber] = callbackContext
callbackMapLock.Unlock() callbackMapLock.Unlock()
var callbackHandle hcsCallback callbackHandle, err := vmcompute.HcsRegisterProcessCallback(ctx, process.handle, notificationWatcherCallback, callbackNumber)
err := hcsRegisterProcessCallback(process.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
if err != nil { if err != nil {
return err return err
} }
context.handle = callbackHandle callbackContext.handle = callbackHandle
process.callbackNumber = callbackNumber process.callbackNumber = callbackNumber
return nil return nil
} }
func (process *Process) unregisterCallback() error { func (process *Process) unregisterCallback(ctx context.Context) error {
callbackNumber := process.callbackNumber callbackNumber := process.callbackNumber
callbackMapLock.RLock() callbackMapLock.RLock()
context := callbackMap[callbackNumber] callbackContext := callbackMap[callbackNumber]
callbackMapLock.RUnlock() callbackMapLock.RUnlock()
if context == nil { if callbackContext == nil {
return nil return nil
} }
handle := context.handle handle := callbackContext.handle
if handle == 0 { if handle == 0 {
return nil return nil
} }
// hcsUnregisterProcessCallback has its own syncronization // vmcompute.HcsUnregisterProcessCallback has its own synchronization to
// to wait for all callbacks to complete. We must NOT hold the callbackMapLock. // wait for all callbacks to complete. We must NOT hold the callbackMapLock.
err := hcsUnregisterProcessCallback(handle) err := vmcompute.HcsUnregisterProcessCallback(ctx, handle)
if err != nil { if err != nil {
return err return err
} }
closeChannels(context.channels) closeChannels(callbackContext.channels)
callbackMapLock.Lock() callbackMapLock.Lock()
delete(callbackMap, callbackNumber) delete(callbackMap, callbackNumber)

View File

@ -0,0 +1,5 @@
package hcs
//go:generate go run ../../mksyscall_windows.go -output zsyscall_windows.go syscall.go
//sys hcsFormatWritableLayerVhd(handle uintptr) (hr error) = computestorage.HcsFormatWritableLayerVhd

View File

@ -1,91 +1,56 @@
package hcs package hcs
import ( import (
"context"
"encoding/json" "encoding/json"
"os" "errors"
"strconv" "strings"
"sync" "sync"
"syscall" "syscall"
"time"
"github.com/Microsoft/hcsshim/internal/interop" "github.com/Microsoft/hcsshim/internal/cow"
"github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/schema1" "github.com/Microsoft/hcsshim/internal/schema1"
hcsschema "github.com/Microsoft/hcsshim/internal/schema2"
"github.com/Microsoft/hcsshim/internal/timeout" "github.com/Microsoft/hcsshim/internal/timeout"
"github.com/sirupsen/logrus" "github.com/Microsoft/hcsshim/internal/vmcompute"
"go.opencensus.io/trace"
) )
// currentContainerStarts is used to limit the number of concurrent container
// starts.
var currentContainerStarts containerStarts
type containerStarts struct {
maxParallel int
inProgress int
sync.Mutex
}
func init() {
mpsS := os.Getenv("HCSSHIM_MAX_PARALLEL_START")
if len(mpsS) > 0 {
mpsI, err := strconv.Atoi(mpsS)
if err != nil || mpsI < 0 {
return
}
currentContainerStarts.maxParallel = mpsI
}
}
type System struct { type System struct {
handleLock sync.RWMutex handleLock sync.RWMutex
handle hcsSystem handle vmcompute.HcsSystem
id string id string
callbackNumber uintptr callbackNumber uintptr
logctx logrus.Fields
closedWaitOnce sync.Once closedWaitOnce sync.Once
waitBlock chan struct{} waitBlock chan struct{}
waitError error waitError error
exitError error
os, typ string
} }
func newSystem(id string) *System { func newSystem(id string) *System {
return &System{ return &System{
id: id, id: id,
logctx: logrus.Fields{
logfields.ContainerID: id,
},
waitBlock: make(chan struct{}), waitBlock: make(chan struct{}),
} }
} }
func (computeSystem *System) logOperationBegin(operation string) {
logOperationBegin(
computeSystem.logctx,
operation+" - Begin Operation")
}
func (computeSystem *System) logOperationEnd(operation string, err error) {
var result string
if err == nil {
result = "Success"
} else {
result = "Error"
}
logOperationEnd(
computeSystem.logctx,
operation+" - End Operation - "+result,
err)
}
// CreateComputeSystem creates a new compute system with the given configuration but does not start it. // CreateComputeSystem creates a new compute system with the given configuration but does not start it.
func CreateComputeSystem(id string, hcsDocumentInterface interface{}) (_ *System, err error) { func CreateComputeSystem(ctx context.Context, id string, hcsDocumentInterface interface{}) (_ *System, err error) {
operation := "hcsshim::CreateComputeSystem" operation := "hcsshim::CreateComputeSystem"
// hcsCreateComputeSystemContext is an async operation. Start the outer span
// here to measure the full create time.
ctx, span := trace.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", id))
computeSystem := newSystem(id) computeSystem := newSystem(id)
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
hcsDocumentB, err := json.Marshal(hcsDocumentInterface) hcsDocumentB, err := json.Marshal(hcsDocumentInterface)
if err != nil { if err != nil {
@ -94,129 +59,114 @@ func CreateComputeSystem(id string, hcsDocumentInterface interface{}) (_ *System
hcsDocument := string(hcsDocumentB) hcsDocument := string(hcsDocumentB)
logrus.WithFields(computeSystem.logctx).
WithField(logfields.JSON, hcsDocument).
Debug("HCS ComputeSystem Document")
var ( var (
resultp *uint16
identity syscall.Handle identity syscall.Handle
resultJSON string
createError error createError error
) )
syscallWatcher(computeSystem.logctx, func() { computeSystem.handle, resultJSON, createError = vmcompute.HcsCreateComputeSystem(ctx, id, hcsDocument, identity)
createError = hcsCreateComputeSystem(id, hcsDocument, identity, &computeSystem.handle, &resultp)
})
if createError == nil || IsPending(createError) { if createError == nil || IsPending(createError) {
if err = computeSystem.registerCallback(); err != nil { defer func() {
if err != nil {
computeSystem.Close()
}
}()
if err = computeSystem.registerCallback(ctx); err != nil {
// Terminate the compute system if it still exists. We're okay to // Terminate the compute system if it still exists. We're okay to
// ignore a failure here. // ignore a failure here.
computeSystem.Terminate() computeSystem.Terminate(ctx)
return nil, makeSystemError(computeSystem, operation, "", err, nil) return nil, makeSystemError(computeSystem, operation, "", err, nil)
} }
} }
events, err := processAsyncHcsResult(createError, resultp, computeSystem.callbackNumber, hcsNotificationSystemCreateCompleted, &timeout.SystemCreate) events, err := processAsyncHcsResult(ctx, createError, resultJSON, computeSystem.callbackNumber, hcsNotificationSystemCreateCompleted, &timeout.SystemCreate)
if err != nil { if err != nil {
if err == ErrTimeout { if err == ErrTimeout {
// Terminate the compute system if it still exists. We're okay to // Terminate the compute system if it still exists. We're okay to
// ignore a failure here. // ignore a failure here.
computeSystem.Terminate() computeSystem.Terminate(ctx)
} }
return nil, makeSystemError(computeSystem, operation, hcsDocument, err, events) return nil, makeSystemError(computeSystem, operation, hcsDocument, err, events)
} }
go computeSystem.waitBackground() go computeSystem.waitBackground()
if err = computeSystem.getCachedProperties(ctx); err != nil {
return nil, err
}
return computeSystem, nil return computeSystem, nil
} }
// OpenComputeSystem opens an existing compute system by ID. // OpenComputeSystem opens an existing compute system by ID.
func OpenComputeSystem(id string) (_ *System, err error) { func OpenComputeSystem(ctx context.Context, id string) (*System, error) {
operation := "hcsshim::OpenComputeSystem" operation := "hcsshim::OpenComputeSystem"
computeSystem := newSystem(id) computeSystem := newSystem(id)
computeSystem.logOperationBegin(operation) handle, resultJSON, err := vmcompute.HcsOpenComputeSystem(ctx, id)
defer func() { events := processHcsResult(ctx, resultJSON)
if IsNotExist(err) {
computeSystem.logOperationEnd(operation, nil)
} else {
computeSystem.logOperationEnd(operation, err)
}
}()
var (
handle hcsSystem
resultp *uint16
)
err = hcsOpenComputeSystem(id, &handle, &resultp)
events := processHcsResult(resultp)
if err != nil { if err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, events) return nil, makeSystemError(computeSystem, operation, "", err, events)
} }
computeSystem.handle = handle computeSystem.handle = handle
defer func() {
if err = computeSystem.registerCallback(); err != nil { if err != nil {
computeSystem.Close()
}
}()
if err = computeSystem.registerCallback(ctx); err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, nil) return nil, makeSystemError(computeSystem, operation, "", err, nil)
} }
go computeSystem.waitBackground() go computeSystem.waitBackground()
if err = computeSystem.getCachedProperties(ctx); err != nil {
return nil, err
}
return computeSystem, nil return computeSystem, nil
} }
// GetComputeSystems gets a list of the compute systems on the system that match the query func (computeSystem *System) getCachedProperties(ctx context.Context) error {
func GetComputeSystems(q schema1.ComputeSystemQuery) (_ []schema1.ContainerProperties, err error) { props, err := computeSystem.Properties(ctx)
operation := "hcsshim::GetComputeSystems" if err != nil {
fields := logrus.Fields{} return err
logOperationBegin( }
fields, computeSystem.typ = strings.ToLower(props.SystemType)
operation+" - Begin Operation") computeSystem.os = strings.ToLower(props.RuntimeOSType)
if computeSystem.os == "" && computeSystem.typ == "container" {
defer func() { // Pre-RS5 HCS did not return the OS, but it only supported containers
var result string // that ran Windows.
if err == nil { computeSystem.os = "windows"
result = "Success" }
} else { return nil
result = "Error"
} }
logOperationEnd( // OS returns the operating system of the compute system, "linux" or "windows".
fields, func (computeSystem *System) OS() string {
operation+" - End Operation - "+result, return computeSystem.os
err) }
}()
// IsOCI returns whether processes in the compute system should be created via
// OCI.
func (computeSystem *System) IsOCI() bool {
return computeSystem.os == "linux" && computeSystem.typ == "container"
}
// GetComputeSystems gets a list of the compute systems on the system that match the query
func GetComputeSystems(ctx context.Context, q schema1.ComputeSystemQuery) ([]schema1.ContainerProperties, error) {
operation := "hcsshim::GetComputeSystems"
queryb, err := json.Marshal(q) queryb, err := json.Marshal(q)
if err != nil { if err != nil {
return nil, err return nil, err
} }
query := string(queryb) computeSystemsJSON, resultJSON, err := vmcompute.HcsEnumerateComputeSystems(ctx, string(queryb))
events := processHcsResult(ctx, resultJSON)
logrus.WithFields(fields).
WithField(logfields.JSON, query).
Debug("HCS ComputeSystem Query")
var (
resultp *uint16
computeSystemsp *uint16
)
syscallWatcher(fields, func() {
err = hcsEnumerateComputeSystems(query, &computeSystemsp, &resultp)
})
events := processHcsResult(resultp)
if err != nil { if err != nil {
return nil, &HcsError{Op: operation, Err: err, Events: events} return nil, &HcsError{Op: operation, Err: err, Events: events}
} }
if computeSystemsp == nil { if computeSystemsJSON == "" {
return nil, ErrUnexpectedValue return nil, ErrUnexpectedValue
} }
computeSystemsRaw := interop.ConvertAndFreeCoTaskMemBytes(computeSystemsp)
computeSystems := []schema1.ContainerProperties{} computeSystems := []schema1.ContainerProperties{}
if err = json.Unmarshal(computeSystemsRaw, &computeSystems); err != nil { if err = json.Unmarshal([]byte(computeSystemsJSON), &computeSystems); err != nil {
return nil, err return nil, err
} }
@ -224,51 +174,27 @@ func GetComputeSystems(q schema1.ComputeSystemQuery) (_ []schema1.ContainerPrope
} }
// Start synchronously starts the computeSystem. // Start synchronously starts the computeSystem.
func (computeSystem *System) Start() (err error) { func (computeSystem *System) Start(ctx context.Context) (err error) {
operation := "hcsshim::System::Start"
// hcsStartComputeSystemContext is an async operation. Start the outer span
// here to measure the full start time.
ctx, span := trace.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
computeSystem.handleLock.RLock() computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock() defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::Start"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
if computeSystem.handle == 0 { if computeSystem.handle == 0 {
return makeSystemError(computeSystem, "Start", "", ErrAlreadyClosed, nil) return makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil)
} }
// This is a very simple backoff-retry loop to limit the number resultJSON, err := vmcompute.HcsStartComputeSystem(ctx, computeSystem.handle, "")
// of parallel container starts if environment variable events, err := processAsyncHcsResult(ctx, err, resultJSON, computeSystem.callbackNumber, hcsNotificationSystemStartCompleted, &timeout.SystemStart)
// HCSSHIM_MAX_PARALLEL_START is set to a positive integer.
// It should generally only be used as a workaround to various
// platform issues that exist between RS1 and RS4 as of Aug 2018
if currentContainerStarts.maxParallel > 0 {
for {
currentContainerStarts.Lock()
if currentContainerStarts.inProgress < currentContainerStarts.maxParallel {
currentContainerStarts.inProgress++
currentContainerStarts.Unlock()
break
}
if currentContainerStarts.inProgress == currentContainerStarts.maxParallel {
currentContainerStarts.Unlock()
time.Sleep(100 * time.Millisecond)
}
}
// Make sure we decrement the count when we are done.
defer func() {
currentContainerStarts.Lock()
currentContainerStarts.inProgress--
currentContainerStarts.Unlock()
}()
}
var resultp *uint16
syscallWatcher(computeSystem.logctx, func() {
err = hcsStartComputeSystem(computeSystem.handle, "", &resultp)
})
events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemStartCompleted, &timeout.SystemStart)
if err != nil { if err != nil {
return makeSystemError(computeSystem, "Start", "", err, events) return makeSystemError(computeSystem, operation, "", err, events)
} }
return nil return nil
@ -279,273 +205,257 @@ func (computeSystem *System) ID() string {
return computeSystem.id return computeSystem.id
} }
// Shutdown requests a compute system shutdown, if IsPending() on the error returned is true, // Shutdown requests a compute system shutdown.
// it may not actually be shut down until Wait() succeeds. func (computeSystem *System) Shutdown(ctx context.Context) error {
func (computeSystem *System) Shutdown() (err error) {
computeSystem.handleLock.RLock() computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock() defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::Shutdown" operation := "hcsshim::System::Shutdown"
computeSystem.logOperationBegin(operation)
defer func() {
if IsAlreadyClosed(err) || IsAlreadyStopped(err) || IsPending(err) {
computeSystem.logOperationEnd(operation, nil)
} else {
computeSystem.logOperationEnd(operation, err)
}
}()
if computeSystem.handle == 0 { if computeSystem.handle == 0 {
return makeSystemError(computeSystem, "Shutdown", "", ErrAlreadyClosed, nil)
}
var resultp *uint16
syscallWatcher(computeSystem.logctx, func() {
err = hcsShutdownComputeSystem(computeSystem.handle, "", &resultp)
})
events := processHcsResult(resultp)
if err != nil {
return makeSystemError(computeSystem, "Shutdown", "", err, events)
}
return nil return nil
} }
// Terminate requests a compute system terminate, if IsPending() on the error returned is true, resultJSON, err := vmcompute.HcsShutdownComputeSystem(ctx, computeSystem.handle, "")
// it may not actually be shut down until Wait() succeeds. events := processHcsResult(ctx, resultJSON)
func (computeSystem *System) Terminate() (err error) { switch err {
case nil, ErrVmcomputeAlreadyStopped, ErrComputeSystemDoesNotExist, ErrVmcomputeOperationPending:
default:
return makeSystemError(computeSystem, operation, "", err, events)
}
return nil
}
// Terminate requests a compute system terminate.
func (computeSystem *System) Terminate(ctx context.Context) error {
computeSystem.handleLock.RLock() computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock() defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::Terminate" operation := "hcsshim::System::Terminate"
computeSystem.logOperationBegin(operation)
defer func() {
if IsAlreadyClosed(err) || IsAlreadyStopped(err) || IsPending(err) {
computeSystem.logOperationEnd(operation, nil)
} else {
computeSystem.logOperationEnd(operation, err)
}
}()
if computeSystem.handle == 0 { if computeSystem.handle == 0 {
return makeSystemError(computeSystem, "Terminate", "", ErrAlreadyClosed, nil) return nil
} }
var resultp *uint16 resultJSON, err := vmcompute.HcsTerminateComputeSystem(ctx, computeSystem.handle, "")
syscallWatcher(computeSystem.logctx, func() { events := processHcsResult(ctx, resultJSON)
err = hcsTerminateComputeSystem(computeSystem.handle, "", &resultp) switch err {
}) case nil, ErrVmcomputeAlreadyStopped, ErrComputeSystemDoesNotExist, ErrVmcomputeOperationPending:
events := processHcsResult(resultp) default:
if err != nil && err != ErrVmcomputeAlreadyStopped { return makeSystemError(computeSystem, operation, "", err, events)
return makeSystemError(computeSystem, "Terminate", "", err, events)
} }
return nil return nil
} }
// waitBackground waits for the compute system exit notification. Once received // waitBackground waits for the compute system exit notification. Once received
// sets `computeSystem.waitError` (if any) and unblocks all `Wait`, // sets `computeSystem.waitError` (if any) and unblocks all `Wait` calls.
// `WaitExpectedError`, and `WaitTimeout` calls.
// //
// This MUST be called exactly once per `computeSystem.handle` but `Wait`, // This MUST be called exactly once per `computeSystem.handle` but `Wait` is
// `WaitExpectedError`, and `WaitTimeout` are safe to call multiple times. // safe to call multiple times.
func (computeSystem *System) waitBackground() { func (computeSystem *System) waitBackground() {
computeSystem.waitError = waitForNotification(computeSystem.callbackNumber, hcsNotificationSystemExited, nil) operation := "hcsshim::System::waitBackground"
ctx, span := trace.StartSpan(context.Background(), operation)
defer span.End()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
err := waitForNotification(ctx, computeSystem.callbackNumber, hcsNotificationSystemExited, nil)
switch err {
case nil:
log.G(ctx).Debug("system exited")
case ErrVmcomputeUnexpectedExit:
log.G(ctx).Debug("unexpected system exit")
computeSystem.exitError = makeSystemError(computeSystem, operation, "", err, nil)
err = nil
default:
err = makeSystemError(computeSystem, operation, "", err, nil)
}
computeSystem.closedWaitOnce.Do(func() { computeSystem.closedWaitOnce.Do(func() {
computeSystem.waitError = err
close(computeSystem.waitBlock) close(computeSystem.waitBlock)
}) })
oc.SetSpanStatus(span, err)
} }
// Wait synchronously waits for the compute system to shutdown or terminate. If // Wait synchronously waits for the compute system to shutdown or terminate. If
// the compute system has already exited returns the previous error (if any). // the compute system has already exited returns the previous error (if any).
func (computeSystem *System) Wait() (err error) { func (computeSystem *System) Wait() error {
operation := "hcsshim::ComputeSystem::Wait"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
<-computeSystem.waitBlock <-computeSystem.waitBlock
if computeSystem.waitError != nil { return computeSystem.waitError
return makeSystemError(computeSystem, "Wait", "", computeSystem.waitError, nil)
} }
return nil // ExitError returns an error describing the reason the compute system terminated.
} func (computeSystem *System) ExitError() error {
// WaitExpectedError synchronously waits for the compute system to shutdown or
// terminate and returns the error (if any) as long as it does not match
// `expected`. If the compute system has already exited returns the previous
// error (if any) as long as it does not match `expected`.
func (computeSystem *System) WaitExpectedError(expected error) (err error) {
operation := "hcsshim::ComputeSystem::WaitExpectedError"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
<-computeSystem.waitBlock
if computeSystem.waitError != nil && getInnerError(computeSystem.waitError) != expected {
return makeSystemError(computeSystem, "WaitExpectedError", "", computeSystem.waitError, nil)
}
return nil
}
// WaitTimeout synchronously waits for the compute system to terminate or the
// duration to elapse. If the timeout expires, `IsTimeout(err) == true`. If
// the compute system has already exited returns the previous error (if any).
func (computeSystem *System) WaitTimeout(timeout time.Duration) (err error) {
operation := "hcsshim::ComputeSystem::WaitTimeout"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
select { select {
case <-computeSystem.waitBlock: case <-computeSystem.waitBlock:
if computeSystem.waitError != nil { if computeSystem.waitError != nil {
return makeSystemError(computeSystem, "WaitTimeout", "", computeSystem.waitError, nil) return computeSystem.waitError
} }
return nil return computeSystem.exitError
case <-time.After(timeout): default:
return makeSystemError(computeSystem, "WaitTimeout", "", ErrTimeout, nil) return errors.New("container not exited")
} }
} }
func (computeSystem *System) Properties(types ...schema1.PropertyType) (_ *schema1.ContainerProperties, err error) { // Properties returns the requested container properties targeting a V1 schema container.
func (computeSystem *System) Properties(ctx context.Context, types ...schema1.PropertyType) (*schema1.ContainerProperties, error) {
computeSystem.handleLock.RLock() computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock() defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::Properties" operation := "hcsshim::System::Properties"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
queryBytes, err := json.Marshal(schema1.PropertyQuery{PropertyTypes: types}) queryBytes, err := json.Marshal(schema1.PropertyQuery{PropertyTypes: types})
if err != nil { if err != nil {
return nil, makeSystemError(computeSystem, "Properties", "", err, nil) return nil, makeSystemError(computeSystem, operation, "", err, nil)
} }
queryString := string(queryBytes) propertiesJSON, resultJSON, err := vmcompute.HcsGetComputeSystemProperties(ctx, computeSystem.handle, string(queryBytes))
logrus.WithFields(computeSystem.logctx). events := processHcsResult(ctx, resultJSON)
WithField(logfields.JSON, queryString).
Debug("HCS ComputeSystem Properties Query")
var resultp, propertiesp *uint16
syscallWatcher(computeSystem.logctx, func() {
err = hcsGetComputeSystemProperties(computeSystem.handle, string(queryString), &propertiesp, &resultp)
})
events := processHcsResult(resultp)
if err != nil { if err != nil {
return nil, makeSystemError(computeSystem, "Properties", "", err, events) return nil, makeSystemError(computeSystem, operation, "", err, events)
} }
if propertiesp == nil { if propertiesJSON == "" {
return nil, ErrUnexpectedValue return nil, ErrUnexpectedValue
} }
propertiesRaw := interop.ConvertAndFreeCoTaskMemBytes(propertiesp)
properties := &schema1.ContainerProperties{} properties := &schema1.ContainerProperties{}
if err := json.Unmarshal(propertiesRaw, properties); err != nil { if err := json.Unmarshal([]byte(propertiesJSON), properties); err != nil {
return nil, makeSystemError(computeSystem, "Properties", "", err, nil) return nil, makeSystemError(computeSystem, operation, "", err, nil)
}
return properties, nil
}
// PropertiesV2 returns the requested container properties targeting a V2 schema container.
func (computeSystem *System) PropertiesV2(ctx context.Context, types ...hcsschema.PropertyType) (*hcsschema.Properties, error) {
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::System::PropertiesV2"
queryBytes, err := json.Marshal(hcsschema.PropertyQuery{PropertyTypes: types})
if err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, nil)
}
propertiesJSON, resultJSON, err := vmcompute.HcsGetComputeSystemProperties(ctx, computeSystem.handle, string(queryBytes))
events := processHcsResult(ctx, resultJSON)
if err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, events)
}
if propertiesJSON == "" {
return nil, ErrUnexpectedValue
}
properties := &hcsschema.Properties{}
if err := json.Unmarshal([]byte(propertiesJSON), properties); err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, nil)
} }
return properties, nil return properties, nil
} }
// Pause pauses the execution of the computeSystem. This feature is not enabled in TP5. // Pause pauses the execution of the computeSystem. This feature is not enabled in TP5.
func (computeSystem *System) Pause() (err error) { func (computeSystem *System) Pause(ctx context.Context) (err error) {
operation := "hcsshim::System::Pause"
// hcsPauseComputeSystemContext is an async peration. Start the outer span
// here to measure the full pause time.
ctx, span := trace.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
computeSystem.handleLock.RLock() computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock() defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::Pause"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
if computeSystem.handle == 0 { if computeSystem.handle == 0 {
return makeSystemError(computeSystem, "Pause", "", ErrAlreadyClosed, nil) return makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil)
} }
var resultp *uint16 resultJSON, err := vmcompute.HcsPauseComputeSystem(ctx, computeSystem.handle, "")
syscallWatcher(computeSystem.logctx, func() { events, err := processAsyncHcsResult(ctx, err, resultJSON, computeSystem.callbackNumber, hcsNotificationSystemPauseCompleted, &timeout.SystemPause)
err = hcsPauseComputeSystem(computeSystem.handle, "", &resultp)
})
events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemPauseCompleted, &timeout.SystemPause)
if err != nil { if err != nil {
return makeSystemError(computeSystem, "Pause", "", err, events) return makeSystemError(computeSystem, operation, "", err, events)
} }
return nil return nil
} }
// Resume resumes the execution of the computeSystem. This feature is not enabled in TP5. // Resume resumes the execution of the computeSystem. This feature is not enabled in TP5.
func (computeSystem *System) Resume() (err error) { func (computeSystem *System) Resume(ctx context.Context) (err error) {
operation := "hcsshim::System::Resume"
// hcsResumeComputeSystemContext is an async operation. Start the outer span
// here to measure the full restore time.
ctx, span := trace.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
computeSystem.handleLock.RLock() computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock() defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::Resume"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
if computeSystem.handle == 0 { if computeSystem.handle == 0 {
return makeSystemError(computeSystem, "Resume", "", ErrAlreadyClosed, nil) return makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil)
} }
var resultp *uint16 resultJSON, err := vmcompute.HcsResumeComputeSystem(ctx, computeSystem.handle, "")
syscallWatcher(computeSystem.logctx, func() { events, err := processAsyncHcsResult(ctx, err, resultJSON, computeSystem.callbackNumber, hcsNotificationSystemResumeCompleted, &timeout.SystemResume)
err = hcsResumeComputeSystem(computeSystem.handle, "", &resultp)
})
events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemResumeCompleted, &timeout.SystemResume)
if err != nil { if err != nil {
return makeSystemError(computeSystem, "Resume", "", err, events) return makeSystemError(computeSystem, operation, "", err, events)
} }
return nil return nil
} }
// CreateProcess launches a new process within the computeSystem. func (computeSystem *System) createProcess(ctx context.Context, operation string, c interface{}) (*Process, *vmcompute.HcsProcessInformation, error) {
func (computeSystem *System) CreateProcess(c interface{}) (_ *Process, err error) {
computeSystem.handleLock.RLock() computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock() defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::CreateProcess"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
var (
processInfo hcsProcessInformation
processHandle hcsProcess
resultp *uint16
)
if computeSystem.handle == 0 { if computeSystem.handle == 0 {
return nil, makeSystemError(computeSystem, "CreateProcess", "", ErrAlreadyClosed, nil) return nil, nil, makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil)
} }
configurationb, err := json.Marshal(c) configurationb, err := json.Marshal(c)
if err != nil { if err != nil {
return nil, makeSystemError(computeSystem, "CreateProcess", "", err, nil) return nil, nil, makeSystemError(computeSystem, operation, "", err, nil)
} }
configuration := string(configurationb) configuration := string(configurationb)
processInfo, processHandle, resultJSON, err := vmcompute.HcsCreateProcess(ctx, computeSystem.handle, configuration)
logrus.WithFields(computeSystem.logctx). events := processHcsResult(ctx, resultJSON)
WithField(logfields.JSON, configuration).
Debug("HCS ComputeSystem Process Document")
syscallWatcher(computeSystem.logctx, func() {
err = hcsCreateProcess(computeSystem.handle, configuration, &processInfo, &processHandle, &resultp)
})
events := processHcsResult(resultp)
if err != nil { if err != nil {
return nil, makeSystemError(computeSystem, "CreateProcess", configuration, err, events) return nil, nil, makeSystemError(computeSystem, operation, configuration, err, events)
} }
logrus.WithFields(computeSystem.logctx). log.G(ctx).WithField("pid", processInfo.ProcessId).Debug("created process pid")
WithField(logfields.ProcessID, processInfo.ProcessId). return newProcess(processHandle, int(processInfo.ProcessId), computeSystem), &processInfo, nil
Debug("HCS ComputeSystem CreateProcess PID")
process := newProcess(processHandle, int(processInfo.ProcessId), computeSystem)
process.cachedPipes = &cachedPipes{
stdIn: processInfo.StdInput,
stdOut: processInfo.StdOutput,
stdErr: processInfo.StdError,
} }
if err = process.registerCallback(); err != nil { // CreateProcess launches a new process within the computeSystem.
return nil, makeSystemError(computeSystem, "CreateProcess", "", err, nil) func (computeSystem *System) CreateProcess(ctx context.Context, c interface{}) (cow.Process, error) {
operation := "hcsshim::System::CreateProcess"
process, processInfo, err := computeSystem.createProcess(ctx, operation, c)
if err != nil {
return nil, err
}
defer func() {
if err != nil {
process.Close()
}
}()
pipes, err := makeOpenFiles([]syscall.Handle{processInfo.StdInput, processInfo.StdOutput, processInfo.StdError})
if err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, nil)
}
process.stdin = pipes[0]
process.stdout = pipes[1]
process.stderr = pipes[2]
process.hasCachedStdio = true
if err = process.registerCallback(ctx); err != nil {
return nil, makeSystemError(computeSystem, operation, "", err, nil)
} }
go process.waitBackground() go process.waitBackground()
@ -553,38 +463,25 @@ func (computeSystem *System) CreateProcess(c interface{}) (_ *Process, err error
} }
// OpenProcess gets an interface to an existing process within the computeSystem. // OpenProcess gets an interface to an existing process within the computeSystem.
func (computeSystem *System) OpenProcess(pid int) (_ *Process, err error) { func (computeSystem *System) OpenProcess(ctx context.Context, pid int) (*Process, error) {
computeSystem.handleLock.RLock() computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock() defer computeSystem.handleLock.RUnlock()
// Add PID for the context of this operation operation := "hcsshim::System::OpenProcess"
computeSystem.logctx[logfields.ProcessID] = pid
defer delete(computeSystem.logctx, logfields.ProcessID)
operation := "hcsshim::ComputeSystem::OpenProcess"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
var (
processHandle hcsProcess
resultp *uint16
)
if computeSystem.handle == 0 { if computeSystem.handle == 0 {
return nil, makeSystemError(computeSystem, "OpenProcess", "", ErrAlreadyClosed, nil) return nil, makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil)
} }
syscallWatcher(computeSystem.logctx, func() { processHandle, resultJSON, err := vmcompute.HcsOpenProcess(ctx, computeSystem.handle, uint32(pid))
err = hcsOpenProcess(computeSystem.handle, uint32(pid), &processHandle, &resultp) events := processHcsResult(ctx, resultJSON)
})
events := processHcsResult(resultp)
if err != nil { if err != nil {
return nil, makeSystemError(computeSystem, "OpenProcess", "", err, events) return nil, makeSystemError(computeSystem, operation, "", err, events)
} }
process := newProcess(processHandle, pid, computeSystem) process := newProcess(processHandle, pid, computeSystem)
if err = process.registerCallback(); err != nil { if err = process.registerCallback(ctx); err != nil {
return nil, makeSystemError(computeSystem, "OpenProcess", "", err, nil) return nil, makeSystemError(computeSystem, operation, "", err, nil)
} }
go process.waitBackground() go process.waitBackground()
@ -593,39 +490,40 @@ func (computeSystem *System) OpenProcess(pid int) (_ *Process, err error) {
// Close cleans up any state associated with the compute system but does not terminate or wait for it. // Close cleans up any state associated with the compute system but does not terminate or wait for it.
func (computeSystem *System) Close() (err error) { func (computeSystem *System) Close() (err error) {
operation := "hcsshim::System::Close"
ctx, span := trace.StartSpan(context.Background(), operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
computeSystem.handleLock.Lock() computeSystem.handleLock.Lock()
defer computeSystem.handleLock.Unlock() defer computeSystem.handleLock.Unlock()
operation := "hcsshim::ComputeSystem::Close"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
// Don't double free this // Don't double free this
if computeSystem.handle == 0 { if computeSystem.handle == 0 {
return nil return nil
} }
if err = computeSystem.unregisterCallback(); err != nil { if err = computeSystem.unregisterCallback(ctx); err != nil {
return makeSystemError(computeSystem, "Close", "", err, nil) return makeSystemError(computeSystem, operation, "", err, nil)
} }
syscallWatcher(computeSystem.logctx, func() { err = vmcompute.HcsCloseComputeSystem(ctx, computeSystem.handle)
err = hcsCloseComputeSystem(computeSystem.handle)
})
if err != nil { if err != nil {
return makeSystemError(computeSystem, "Close", "", err, nil) return makeSystemError(computeSystem, operation, "", err, nil)
} }
computeSystem.handle = 0 computeSystem.handle = 0
computeSystem.closedWaitOnce.Do(func() { computeSystem.closedWaitOnce.Do(func() {
computeSystem.waitError = ErrAlreadyClosed
close(computeSystem.waitBlock) close(computeSystem.waitBlock)
}) })
return nil return nil
} }
func (computeSystem *System) registerCallback() error { func (computeSystem *System) registerCallback(ctx context.Context) error {
context := &notifcationWatcherContext{ callbackContext := &notifcationWatcherContext{
channels: newSystemChannels(), channels: newSystemChannels(),
systemID: computeSystem.id, systemID: computeSystem.id,
} }
@ -633,32 +531,31 @@ func (computeSystem *System) registerCallback() error {
callbackMapLock.Lock() callbackMapLock.Lock()
callbackNumber := nextCallback callbackNumber := nextCallback
nextCallback++ nextCallback++
callbackMap[callbackNumber] = context callbackMap[callbackNumber] = callbackContext
callbackMapLock.Unlock() callbackMapLock.Unlock()
var callbackHandle hcsCallback callbackHandle, err := vmcompute.HcsRegisterComputeSystemCallback(ctx, computeSystem.handle, notificationWatcherCallback, callbackNumber)
err := hcsRegisterComputeSystemCallback(computeSystem.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
if err != nil { if err != nil {
return err return err
} }
context.handle = callbackHandle callbackContext.handle = callbackHandle
computeSystem.callbackNumber = callbackNumber computeSystem.callbackNumber = callbackNumber
return nil return nil
} }
func (computeSystem *System) unregisterCallback() error { func (computeSystem *System) unregisterCallback(ctx context.Context) error {
callbackNumber := computeSystem.callbackNumber callbackNumber := computeSystem.callbackNumber
callbackMapLock.RLock() callbackMapLock.RLock()
context := callbackMap[callbackNumber] callbackContext := callbackMap[callbackNumber]
callbackMapLock.RUnlock() callbackMapLock.RUnlock()
if context == nil { if callbackContext == nil {
return nil return nil
} }
handle := context.handle handle := callbackContext.handle
if handle == 0 { if handle == 0 {
return nil return nil
@ -666,12 +563,12 @@ func (computeSystem *System) unregisterCallback() error {
// hcsUnregisterComputeSystemCallback has its own syncronization // hcsUnregisterComputeSystemCallback has its own syncronization
// to wait for all callbacks to complete. We must NOT hold the callbackMapLock. // to wait for all callbacks to complete. We must NOT hold the callbackMapLock.
err := hcsUnregisterComputeSystemCallback(handle) err := vmcompute.HcsUnregisterComputeSystemCallback(ctx, handle)
if err != nil { if err != nil {
return err return err
} }
closeChannels(context.channels) closeChannels(callbackContext.channels)
callbackMapLock.Lock() callbackMapLock.Lock()
delete(callbackMap, callbackNumber) delete(callbackMap, callbackNumber)
@ -683,36 +580,26 @@ func (computeSystem *System) unregisterCallback() error {
} }
// Modify the System by sending a request to HCS // Modify the System by sending a request to HCS
func (computeSystem *System) Modify(config interface{}) (err error) { func (computeSystem *System) Modify(ctx context.Context, config interface{}) error {
computeSystem.handleLock.RLock() computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock() defer computeSystem.handleLock.RUnlock()
operation := "hcsshim::ComputeSystem::Modify" operation := "hcsshim::System::Modify"
computeSystem.logOperationBegin(operation)
defer func() { computeSystem.logOperationEnd(operation, err) }()
if computeSystem.handle == 0 { if computeSystem.handle == 0 {
return makeSystemError(computeSystem, "Modify", "", ErrAlreadyClosed, nil) return makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil)
} }
requestJSON, err := json.Marshal(config) requestBytes, err := json.Marshal(config)
if err != nil { if err != nil {
return err return err
} }
requestString := string(requestJSON) requestJSON := string(requestBytes)
resultJSON, err := vmcompute.HcsModifyComputeSystem(ctx, computeSystem.handle, requestJSON)
logrus.WithFields(computeSystem.logctx). events := processHcsResult(ctx, resultJSON)
WithField(logfields.JSON, requestString).
Debug("HCS ComputeSystem Modify Document")
var resultp *uint16
syscallWatcher(computeSystem.logctx, func() {
err = hcsModifyComputeSystem(computeSystem.handle, requestString, &resultp)
})
events := processHcsResult(resultp)
if err != nil { if err != nil {
return makeSystemError(computeSystem, "Modify", requestString, err, events) return makeSystemError(computeSystem, operation, requestJSON, err, events)
} }
return nil return nil

View File

@ -1,10 +1,14 @@
package hcs package hcs
import ( import (
"context"
"io" "io"
"syscall" "syscall"
"github.com/Microsoft/go-winio" "github.com/Microsoft/go-winio"
diskutil "github.com/Microsoft/go-winio/vhd"
"github.com/pkg/errors"
"golang.org/x/sys/windows"
) )
// makeOpenFiles calls winio.MakeOpenFile for each handle in a slice but closes all the handles // makeOpenFiles calls winio.MakeOpenFile for each handle in a slice but closes all the handles
@ -31,3 +35,27 @@ func makeOpenFiles(hs []syscall.Handle) (_ []io.ReadWriteCloser, err error) {
} }
return fs, nil return fs, nil
} }
// 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")
}
vhd, err := diskutil.OpenVirtualDisk(vhdPath, diskutil.VirtualDiskAccessNone, diskutil.OpenVirtualDiskFlagNone)
if err != nil {
return errors.Wrap(err, "failed to open VHD")
}
defer func() {
err2 := windows.CloseHandle(windows.Handle(vhd))
if err == nil {
err = errors.Wrap(err2, "failed to close VHD")
}
}()
if err := hcsFormatWritableLayerVhd(uintptr(vhd)); err != nil {
return errors.Wrap(err, "failed to format VHD")
}
return nil
}

View File

@ -1,25 +1,26 @@
package hcs package hcs
import ( import (
"context"
"time" "time"
"github.com/sirupsen/logrus" "github.com/Microsoft/hcsshim/internal/log"
) )
func processAsyncHcsResult(err error, resultp *uint16, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) ([]ErrorEvent, error) { func processAsyncHcsResult(ctx context.Context, err error, resultJSON string, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) ([]ErrorEvent, error) {
events := processHcsResult(resultp) events := processHcsResult(ctx, resultJSON)
if IsPending(err) { if IsPending(err) {
return nil, waitForNotification(callbackNumber, expectedNotification, timeout) return nil, waitForNotification(ctx, callbackNumber, expectedNotification, timeout)
} }
return events, err return events, err
} }
func waitForNotification(callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error { func waitForNotification(ctx context.Context, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
callbackMapLock.RLock() callbackMapLock.RLock()
if _, ok := callbackMap[callbackNumber]; !ok { if _, ok := callbackMap[callbackNumber]; !ok {
callbackMapLock.RUnlock() callbackMapLock.RUnlock()
logrus.Errorf("failed to waitForNotification: callbackNumber %d does not exist in callbackMap", callbackNumber) log.G(ctx).WithField("callbackNumber", callbackNumber).Error("failed to waitForNotification: callbackNumber does not exist in callbackMap")
return ErrHandleClose return ErrHandleClose
} }
channels := callbackMap[callbackNumber].channels channels := callbackMap[callbackNumber].channels
@ -27,7 +28,7 @@ func waitForNotification(callbackNumber uintptr, expectedNotification hcsNotific
expectedChannel := channels[expectedNotification] expectedChannel := channels[expectedNotification]
if expectedChannel == nil { if expectedChannel == nil {
logrus.Errorf("unknown notification type in waitForNotification %x", expectedNotification) log.G(ctx).WithField("type", expectedNotification).Error("unknown notification type in waitForNotification")
return ErrInvalidNotificationType return ErrInvalidNotificationType
} }

View File

@ -1,41 +0,0 @@
package hcs
import (
"context"
"github.com/Microsoft/hcsshim/internal/logfields"
"github.com/Microsoft/hcsshim/internal/timeout"
"github.com/sirupsen/logrus"
)
// syscallWatcher is used as a very simple goroutine around calls into
// the platform. In some cases, we have seen HCS APIs not returning due to
// various bugs, and the goroutine making the syscall ends up not returning,
// prior to its async callback. By spinning up a syscallWatcher, it allows
// us to at least log a warning if a syscall doesn't complete in a reasonable
// amount of time.
//
// Usage is:
//
// syscallWatcher(logContext, func() {
// err = <syscall>(args...)
// })
//
func syscallWatcher(logContext logrus.Fields, syscallLambda func()) {
ctx, cancel := context.WithTimeout(context.Background(), timeout.SyscallWatcher)
defer cancel()
go watchFunc(ctx, logContext)
syscallLambda()
}
func watchFunc(ctx context.Context, logContext logrus.Fields) {
select {
case <-ctx.Done():
if ctx.Err() != context.Canceled {
logrus.WithFields(logContext).
WithField(logfields.Timeout, timeout.SyscallWatcher).
Warning("Syscall did not complete within operation timeout. This may indicate a platform issue. If it appears to be making no forward progress, obtain the stacks and see if there is a syscall stuck in the platform API for a significant length of time.")
}
}
}

View File

@ -37,492 +37,13 @@ func errnoErr(e syscall.Errno) error {
} }
var ( var (
modvmcompute = windows.NewLazySystemDLL("vmcompute.dll") modcomputestorage = windows.NewLazySystemDLL("computestorage.dll")
procHcsEnumerateComputeSystems = modvmcompute.NewProc("HcsEnumerateComputeSystems") procHcsFormatWritableLayerVhd = modcomputestorage.NewProc("HcsFormatWritableLayerVhd")
procHcsCreateComputeSystem = modvmcompute.NewProc("HcsCreateComputeSystem")
procHcsOpenComputeSystem = modvmcompute.NewProc("HcsOpenComputeSystem")
procHcsCloseComputeSystem = modvmcompute.NewProc("HcsCloseComputeSystem")
procHcsStartComputeSystem = modvmcompute.NewProc("HcsStartComputeSystem")
procHcsShutdownComputeSystem = modvmcompute.NewProc("HcsShutdownComputeSystem")
procHcsTerminateComputeSystem = modvmcompute.NewProc("HcsTerminateComputeSystem")
procHcsPauseComputeSystem = modvmcompute.NewProc("HcsPauseComputeSystem")
procHcsResumeComputeSystem = modvmcompute.NewProc("HcsResumeComputeSystem")
procHcsGetComputeSystemProperties = modvmcompute.NewProc("HcsGetComputeSystemProperties")
procHcsModifyComputeSystem = modvmcompute.NewProc("HcsModifyComputeSystem")
procHcsRegisterComputeSystemCallback = modvmcompute.NewProc("HcsRegisterComputeSystemCallback")
procHcsUnregisterComputeSystemCallback = modvmcompute.NewProc("HcsUnregisterComputeSystemCallback")
procHcsCreateProcess = modvmcompute.NewProc("HcsCreateProcess")
procHcsOpenProcess = modvmcompute.NewProc("HcsOpenProcess")
procHcsCloseProcess = modvmcompute.NewProc("HcsCloseProcess")
procHcsTerminateProcess = modvmcompute.NewProc("HcsTerminateProcess")
procHcsSignalProcess = modvmcompute.NewProc("HcsSignalProcess")
procHcsGetProcessInfo = modvmcompute.NewProc("HcsGetProcessInfo")
procHcsGetProcessProperties = modvmcompute.NewProc("HcsGetProcessProperties")
procHcsModifyProcess = modvmcompute.NewProc("HcsModifyProcess")
procHcsGetServiceProperties = modvmcompute.NewProc("HcsGetServiceProperties")
procHcsRegisterProcessCallback = modvmcompute.NewProc("HcsRegisterProcessCallback")
procHcsUnregisterProcessCallback = modvmcompute.NewProc("HcsUnregisterProcessCallback")
) )
func hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) { func hcsFormatWritableLayerVhd(handle uintptr) (hr error) {
var _p0 *uint16 r0, _, _ := syscall.Syscall(procHcsFormatWritableLayerVhd.Addr(), 1, uintptr(handle), 0, 0)
_p0, hr = syscall.UTF16PtrFromString(query)
if hr != nil {
return
}
return _hcsEnumerateComputeSystems(_p0, computeSystems, result)
}
func _hcsEnumerateComputeSystems(query *uint16, computeSystems **uint16, result **uint16) (hr error) {
if hr = procHcsEnumerateComputeSystems.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsEnumerateComputeSystems.Addr(), 3, uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(computeSystems)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(id)
if hr != nil {
return
}
var _p1 *uint16
_p1, hr = syscall.UTF16PtrFromString(configuration)
if hr != nil {
return
}
return _hcsCreateComputeSystem(_p0, _p1, identity, computeSystem, result)
}
func _hcsCreateComputeSystem(id *uint16, configuration *uint16, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) {
if hr = procHcsCreateComputeSystem.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall6(procHcsCreateComputeSystem.Addr(), 5, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(configuration)), uintptr(identity), uintptr(unsafe.Pointer(computeSystem)), uintptr(unsafe.Pointer(result)), 0)
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsOpenComputeSystem(id string, computeSystem *hcsSystem, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(id)
if hr != nil {
return
}
return _hcsOpenComputeSystem(_p0, computeSystem, result)
}
func _hcsOpenComputeSystem(id *uint16, computeSystem *hcsSystem, result **uint16) (hr error) {
if hr = procHcsOpenComputeSystem.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsOpenComputeSystem.Addr(), 3, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(computeSystem)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsCloseComputeSystem(computeSystem hcsSystem) (hr error) {
if hr = procHcsCloseComputeSystem.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsCloseComputeSystem.Addr(), 1, uintptr(computeSystem), 0, 0)
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsStartComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(options)
if hr != nil {
return
}
return _hcsStartComputeSystem(computeSystem, _p0, result)
}
func _hcsStartComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
if hr = procHcsStartComputeSystem.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsStartComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsShutdownComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(options)
if hr != nil {
return
}
return _hcsShutdownComputeSystem(computeSystem, _p0, result)
}
func _hcsShutdownComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
if hr = procHcsShutdownComputeSystem.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsShutdownComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsTerminateComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(options)
if hr != nil {
return
}
return _hcsTerminateComputeSystem(computeSystem, _p0, result)
}
func _hcsTerminateComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
if hr = procHcsTerminateComputeSystem.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsTerminateComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsPauseComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(options)
if hr != nil {
return
}
return _hcsPauseComputeSystem(computeSystem, _p0, result)
}
func _hcsPauseComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
if hr = procHcsPauseComputeSystem.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsPauseComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsResumeComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(options)
if hr != nil {
return
}
return _hcsResumeComputeSystem(computeSystem, _p0, result)
}
func _hcsResumeComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
if hr = procHcsResumeComputeSystem.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsResumeComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(propertyQuery)
if hr != nil {
return
}
return _hcsGetComputeSystemProperties(computeSystem, _p0, properties, result)
}
func _hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery *uint16, properties **uint16, result **uint16) (hr error) {
if hr = procHcsGetComputeSystemProperties.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall6(procHcsGetComputeSystemProperties.Addr(), 4, uintptr(computeSystem), uintptr(unsafe.Pointer(propertyQuery)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)), 0, 0)
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsModifyComputeSystem(computeSystem hcsSystem, configuration string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(configuration)
if hr != nil {
return
}
return _hcsModifyComputeSystem(computeSystem, _p0, result)
}
func _hcsModifyComputeSystem(computeSystem hcsSystem, configuration *uint16, result **uint16) (hr error) {
if hr = procHcsModifyComputeSystem.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsModifyComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(configuration)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsRegisterComputeSystemCallback(computeSystem hcsSystem, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) {
if hr = procHcsRegisterComputeSystemCallback.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall6(procHcsRegisterComputeSystemCallback.Addr(), 4, uintptr(computeSystem), uintptr(callback), uintptr(context), uintptr(unsafe.Pointer(callbackHandle)), 0, 0)
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsUnregisterComputeSystemCallback(callbackHandle hcsCallback) (hr error) {
if hr = procHcsUnregisterComputeSystemCallback.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsUnregisterComputeSystemCallback.Addr(), 1, uintptr(callbackHandle), 0, 0)
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsCreateProcess(computeSystem hcsSystem, processParameters string, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(processParameters)
if hr != nil {
return
}
return _hcsCreateProcess(computeSystem, _p0, processInformation, process, result)
}
func _hcsCreateProcess(computeSystem hcsSystem, processParameters *uint16, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) {
if hr = procHcsCreateProcess.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall6(procHcsCreateProcess.Addr(), 5, uintptr(computeSystem), uintptr(unsafe.Pointer(processParameters)), uintptr(unsafe.Pointer(processInformation)), uintptr(unsafe.Pointer(process)), uintptr(unsafe.Pointer(result)), 0)
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, result **uint16) (hr error) {
if hr = procHcsOpenProcess.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall6(procHcsOpenProcess.Addr(), 4, uintptr(computeSystem), uintptr(pid), uintptr(unsafe.Pointer(process)), uintptr(unsafe.Pointer(result)), 0, 0)
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsCloseProcess(process hcsProcess) (hr error) {
if hr = procHcsCloseProcess.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsCloseProcess.Addr(), 1, uintptr(process), 0, 0)
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) {
if hr = procHcsTerminateProcess.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsTerminateProcess.Addr(), 2, uintptr(process), uintptr(unsafe.Pointer(result)), 0)
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsSignalProcess(process hcsProcess, options string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(options)
if hr != nil {
return
}
return _hcsSignalProcess(process, _p0, result)
}
func _hcsSignalProcess(process hcsProcess, options *uint16, result **uint16) (hr error) {
if hr = procHcsSignalProcess.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsSignalProcess.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInformation, result **uint16) (hr error) {
if hr = procHcsGetProcessInfo.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsGetProcessInfo.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(processInformation)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsGetProcessProperties(process hcsProcess, processProperties **uint16, result **uint16) (hr error) {
if hr = procHcsGetProcessProperties.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsGetProcessProperties.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(processProperties)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(settings)
if hr != nil {
return
}
return _hcsModifyProcess(process, _p0, result)
}
func _hcsModifyProcess(process hcsProcess, settings *uint16, result **uint16) (hr error) {
if hr = procHcsModifyProcess.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsModifyProcess.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsGetServiceProperties(propertyQuery string, properties **uint16, result **uint16) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(propertyQuery)
if hr != nil {
return
}
return _hcsGetServiceProperties(_p0, properties, result)
}
func _hcsGetServiceProperties(propertyQuery *uint16, properties **uint16, result **uint16) (hr error) {
if hr = procHcsGetServiceProperties.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsGetServiceProperties.Addr(), 3, uintptr(unsafe.Pointer(propertyQuery)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)))
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsRegisterProcessCallback(process hcsProcess, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) {
if hr = procHcsRegisterProcessCallback.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall6(procHcsRegisterProcessCallback.Addr(), 4, uintptr(process), uintptr(callback), uintptr(context), uintptr(unsafe.Pointer(callbackHandle)), 0, 0)
if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff
}
hr = syscall.Errno(r0)
}
return
}
func hcsUnregisterProcessCallback(callbackHandle hcsCallback) (hr error) {
if hr = procHcsUnregisterProcessCallback.Find(); hr != nil {
return
}
r0, _, _ := syscall.Syscall(procHcsUnregisterProcessCallback.Addr(), 1, uintptr(callbackHandle), 0, 0)
if int32(r0) < 0 { if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 { if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff r0 &= 0xffff

View File

@ -3,6 +3,7 @@ package hns
import ( import (
"encoding/json" "encoding/json"
"net" "net"
"strings"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -94,6 +95,27 @@ func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
return nil, EndpointNotFoundError{EndpointName: endpointName} return nil, EndpointNotFoundError{EndpointName: endpointName}
} }
type endpointAttachInfo struct {
SharedContainers json.RawMessage `json:",omitempty"`
}
func (endpoint *HNSEndpoint) IsAttached(vID string) (bool, error) {
attachInfo := endpointAttachInfo{}
err := hnsCall("GET", "/endpoints/"+endpoint.Id, "", &attachInfo)
// Return false allows us to just return the err
if err != nil {
return false, err
}
if strings.Contains(strings.ToLower(string(attachInfo.SharedContainers)), strings.ToLower(vID)) {
return true, nil
}
return false, nil
}
// Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods // Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) { func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {
operation := "Create" operation := "Create"
@ -151,6 +173,27 @@ func (endpoint *HNSEndpoint) ApplyACLPolicy(policies ...*ACLPolicy) error {
return err return err
} }
// ApplyProxyPolicy applies a set of Proxy Policies on the Endpoint
func (endpoint *HNSEndpoint) ApplyProxyPolicy(policies ...*ProxyPolicy) error {
operation := "ApplyProxyPolicy"
title := "hcsshim::HNSEndpoint::" + operation
logrus.Debugf(title+" id=%s", endpoint.Id)
for _, policy := range policies {
if policy == nil {
continue
}
jsonString, err := json.Marshal(policy)
if err != nil {
return err
}
endpoint.Policies = append(endpoint.Policies, jsonString)
}
_, err := endpoint.Update()
return err
}
// ContainerAttach attaches an endpoint to container // ContainerAttach attaches an endpoint to container
func (endpoint *HNSEndpoint) ContainerAttach(containerID string, compartmentID uint16) error { func (endpoint *HNSEndpoint) ContainerAttach(containerID string, compartmentID uint16) error {
operation := "ContainerAttach" operation := "ContainerAttach"

View File

@ -9,23 +9,30 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
func hnsCall(method, path, request string, returnResponse interface{}) error { func hnsCallRawResponse(method, path, request string) (*hnsResponse, error) {
var responseBuffer *uint16 var responseBuffer *uint16
logrus.Debugf("[%s]=>[%s] Request : %s", method, path, request) logrus.Debugf("[%s]=>[%s] Request : %s", method, path, request)
err := _hnsCall(method, path, request, &responseBuffer) err := _hnsCall(method, path, request, &responseBuffer)
if err != nil { if err != nil {
return hcserror.New(err, "hnsCall ", "") return nil, hcserror.New(err, "hnsCall ", "")
} }
response := interop.ConvertAndFreeCoTaskMemString(responseBuffer) response := interop.ConvertAndFreeCoTaskMemString(responseBuffer)
hnsresponse := &hnsResponse{} hnsresponse := &hnsResponse{}
if err = json.Unmarshal([]byte(response), &hnsresponse); err != nil { if err = json.Unmarshal([]byte(response), &hnsresponse); err != nil {
return err return nil, err
}
return hnsresponse, nil
} }
func hnsCall(method, path, request string, returnResponse interface{}) error {
hnsresponse, err := hnsCallRawResponse(method, path, request)
if err != nil {
return fmt.Errorf("failed during hnsCallRawResponse: %v", err)
}
if !hnsresponse.Success { if !hnsresponse.Success {
return fmt.Errorf("HNS failed with error : %s", hnsresponse.Error) return fmt.Errorf("hns failed with error : %s", hnsresponse.Error)
} }
if len(hnsresponse.Output) == 0 { if len(hnsresponse.Output) == 0 {

View File

@ -17,6 +17,7 @@ const (
OutboundNat PolicyType = "OutBoundNAT" OutboundNat PolicyType = "OutBoundNAT"
ExternalLoadBalancer PolicyType = "ELB" ExternalLoadBalancer PolicyType = "ELB"
Route PolicyType = "ROUTE" Route PolicyType = "ROUTE"
Proxy PolicyType = "PROXY"
) )
type NatPolicy struct { type NatPolicy struct {
@ -57,6 +58,16 @@ type OutboundNatPolicy struct {
Policy Policy
VIP string `json:"VIP,omitempty"` VIP string `json:"VIP,omitempty"`
Exceptions []string `json:"ExceptionList,omitempty"` Exceptions []string `json:"ExceptionList,omitempty"`
Destinations []string `json:",omitempty"`
}
type ProxyPolicy struct {
Type PolicyType `json:"Type"`
IP string `json:",omitempty"`
Port string `json:",omitempty"`
ExceptionList []string `json:",omitempty"`
Destination string `json:",omitempty"`
OutboundNat bool `json:",omitempty"`
} }
type ActionType string type ActionType string

View File

@ -15,10 +15,6 @@ func ConvertAndFreeCoTaskMemString(buffer *uint16) string {
return str return str
} }
func ConvertAndFreeCoTaskMemBytes(buffer *uint16) []byte {
return []byte(ConvertAndFreeCoTaskMemString(buffer))
}
func Win32FromHresult(hr uintptr) syscall.Errno { func Win32FromHresult(hr uintptr) syscall.Errno {
if hr&0x1fff0000 == 0x00070000 { if hr&0x1fff0000 == 0x00070000 {
return syscall.Errno(hr & 0xffff) return syscall.Errno(hr & 0xffff)

View File

@ -2,10 +2,14 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = ["guid.go"], srcs = ["g.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/Microsoft/hcsshim/internal/guid", importmap = "k8s.io/kubernetes/vendor/github.com/Microsoft/hcsshim/internal/log",
importpath = "github.com/Microsoft/hcsshim/internal/guid", importpath = "github.com/Microsoft/hcsshim/internal/log",
visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"], visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"],
deps = [
"//vendor/github.com/sirupsen/logrus:go_default_library",
"//vendor/go.opencensus.io/trace:go_default_library",
],
) )
filegroup( filegroup(

23
vendor/github.com/Microsoft/hcsshim/internal/log/g.go generated vendored Normal file
View File

@ -0,0 +1,23 @@
package log
import (
"context"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
// G returns a `logrus.Entry` with the `TraceID, SpanID` from `ctx` if `ctx`
// contains an OpenCensus `trace.Span`.
func G(ctx context.Context) *logrus.Entry {
span := trace.FromContext(ctx)
if span != nil {
sctx := span.SpanContext()
return logrus.WithFields(logrus.Fields{
"traceID": sctx.TraceID.String(),
"spanID": sctx.SpanID.String(),
// "parentSpanID": TODO: JTERRY75 - Try to convince OC to export this?
})
}
return logrus.NewEntry(logrus.StandardLogger())
}

30
vendor/github.com/Microsoft/hcsshim/internal/oc/BUILD generated vendored Normal file
View File

@ -0,0 +1,30 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"exporter.go",
"span.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/Microsoft/hcsshim/internal/oc",
importpath = "github.com/Microsoft/hcsshim/internal/oc",
visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"],
deps = [
"//vendor/github.com/sirupsen/logrus:go_default_library",
"//vendor/go.opencensus.io/trace:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,43 @@
package oc
import (
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
var _ = (trace.Exporter)(&LogrusExporter{})
// LogrusExporter is an OpenCensus `trace.Exporter` that exports
// `trace.SpanData` to logrus output.
type LogrusExporter struct {
}
// ExportSpan exports `s` based on the the following rules:
//
// 1. All output will contain `s.Attributes`, `s.TraceID`, `s.SpanID`,
// `s.ParentSpanID` for correlation
//
// 2. Any calls to .Annotate will not be supported.
//
// 3. The span itself will be written at `logrus.InfoLevel` unless
// `s.Status.Code != 0` in which case it will be written at `logrus.ErrorLevel`
// providing `s.Status.Message` as the error value.
func (le *LogrusExporter) ExportSpan(s *trace.SpanData) {
// Combine all span annotations with traceID, spanID, parentSpanID
baseEntry := logrus.WithFields(logrus.Fields(s.Attributes))
baseEntry.Data["traceID"] = s.TraceID.String()
baseEntry.Data["spanID"] = s.SpanID.String()
baseEntry.Data["parentSpanID"] = s.ParentSpanID.String()
baseEntry.Data["startTime"] = s.StartTime
baseEntry.Data["endTime"] = s.EndTime
baseEntry.Data["duration"] = s.EndTime.Sub(s.StartTime).String()
baseEntry.Data["name"] = s.Name
baseEntry.Time = s.StartTime
level := logrus.InfoLevel
if s.Status.Code != 0 {
level = logrus.ErrorLevel
baseEntry.Data[logrus.ErrorKey] = s.Status.Message
}
baseEntry.Log(level, "Span")
}

View File

@ -0,0 +1,17 @@
package oc
import (
"go.opencensus.io/trace"
)
// SetSpanStatus sets `span.SetStatus` to the proper status depending on `err`. If
// `err` is `nil` assumes `trace.StatusCodeOk`.
func SetSpanStatus(span *trace.Span, err error) {
status := trace.Status{}
if err != nil {
// TODO: JTERRY75 - Handle errors in a non-generic way
status.Code = trace.StatusCodeUnknown
status.Message = err.Error()
}
span.SetStatus(status)
}

View File

@ -12,7 +12,7 @@ go_library(
visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"], visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"],
deps = [ deps = [
"//vendor/github.com/Microsoft/go-winio:go_default_library", "//vendor/github.com/Microsoft/go-winio:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/guid:go_default_library", "//vendor/github.com/Microsoft/go-winio/pkg/guid:go_default_library",
], ],
) )

View File

@ -10,7 +10,7 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/Microsoft/hcsshim/internal/guid" "github.com/Microsoft/go-winio/pkg/guid"
) )
// ContainerState represents the platform agnostic pieces relating to a // ContainerState represents the platform agnostic pieces relating to a

View File

@ -6,7 +6,10 @@ go_library(
importmap = "k8s.io/kubernetes/vendor/github.com/Microsoft/hcsshim/internal/schema1", importmap = "k8s.io/kubernetes/vendor/github.com/Microsoft/hcsshim/internal/schema1",
importpath = "github.com/Microsoft/hcsshim/internal/schema1", importpath = "github.com/Microsoft/hcsshim/internal/schema1",
visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"], visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"],
deps = ["//vendor/github.com/Microsoft/hcsshim/internal/schema2:go_default_library"], deps = [
"//vendor/github.com/Microsoft/go-winio/pkg/guid:go_default_library",
"//vendor/github.com/Microsoft/hcsshim/internal/schema2:go_default_library",
],
) )
filegroup( filegroup(

View File

@ -4,7 +4,8 @@ import (
"encoding/json" "encoding/json"
"time" "time"
"github.com/Microsoft/hcsshim/internal/schema2" "github.com/Microsoft/go-winio/pkg/guid"
hcsschema "github.com/Microsoft/hcsshim/internal/schema2"
) )
// ProcessConfig is used as both the input of Container.CreateProcess // ProcessConfig is used as both the input of Container.CreateProcess
@ -62,7 +63,7 @@ type MappedVirtualDisk struct {
CreateInUtilityVM bool `json:",omitempty"` CreateInUtilityVM bool `json:",omitempty"`
ReadOnly bool `json:",omitempty"` ReadOnly bool `json:",omitempty"`
Cache string `json:",omitempty"` // "" (Unspecified); "Disabled"; "Enabled"; "Private"; "PrivateAllowSharing" Cache string `json:",omitempty"` // "" (Unspecified); "Disabled"; "Enabled"; "Private"; "PrivateAllowSharing"
AttachOnly bool `json:",omitempty:` AttachOnly bool `json:",omitempty"`
} }
// AssignedDevice represents a device that has been directly assigned to a container // AssignedDevice represents a device that has been directly assigned to a container
@ -133,9 +134,10 @@ type ContainerProperties struct {
State string State string
Name string Name string
SystemType string SystemType string
RuntimeOSType string `json:"RuntimeOsType,omitempty"`
Owner string Owner string
SiloGUID string `json:"SiloGuid,omitempty"` SiloGUID string `json:"SiloGuid,omitempty"`
RuntimeID string `json:"RuntimeId,omitempty"` RuntimeID guid.GUID `json:"RuntimeId,omitempty"`
IsRuntimeTemplate bool `json:",omitempty"` IsRuntimeTemplate bool `json:",omitempty"`
RuntimeImagePath string `json:",omitempty"` RuntimeImagePath string `json:",omitempty"`
Stopped bool `json:",omitempty"` Stopped bool `json:",omitempty"`
@ -214,6 +216,8 @@ type MappedVirtualDiskController struct {
type GuestDefinedCapabilities struct { type GuestDefinedCapabilities struct {
NamespaceAddRequestSupported bool `json:",omitempty"` NamespaceAddRequestSupported bool `json:",omitempty"`
SignalProcessSupported bool `json:",omitempty"` SignalProcessSupported bool `json:",omitempty"`
DumpStacksSupported bool `json:",omitempty"`
DeleteContainerStateSupported bool `json:",omitempty"`
} }
// GuestConnectionInfo is the structure of an iterm return by a GuestConnection call on a utility VM // GuestConnectionInfo is the structure of an iterm return by a GuestConnection call on a utility VM

View File

@ -55,6 +55,7 @@ go_library(
"processor_stats.go", "processor_stats.go",
"properties.go", "properties.go",
"property_query.go", "property_query.go",
"property_type.go",
"rdp_connection_options.go", "rdp_connection_options.go",
"registry_changes.go", "registry_changes.go",
"registry_key.go", "registry_key.go",
@ -79,6 +80,8 @@ go_library(
"virtual_node_info.go", "virtual_node_info.go",
"virtual_p_mem_controller.go", "virtual_p_mem_controller.go",
"virtual_p_mem_device.go", "virtual_p_mem_device.go",
"virtual_pci_device.go",
"virtual_pci_function.go",
"virtual_smb.go", "virtual_smb.go",
"virtual_smb_share.go", "virtual_smb_share.go",
"virtual_smb_share_options.go", "virtual_smb_share_options.go",
@ -88,6 +91,7 @@ go_library(
importmap = "k8s.io/kubernetes/vendor/github.com/Microsoft/hcsshim/internal/schema2", importmap = "k8s.io/kubernetes/vendor/github.com/Microsoft/hcsshim/internal/schema2",
importpath = "github.com/Microsoft/hcsshim/internal/schema2", importpath = "github.com/Microsoft/hcsshim/internal/schema2",
visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"], visibility = ["//vendor/github.com/Microsoft/hcsshim:__subpackages__"],
deps = ["//vendor/github.com/containerd/cgroups/stats/v1:go_default_library"],
) )
filegroup( filegroup(

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type Attachment struct { type Attachment struct {
Type_ string `json:"Type,omitempty"` Type_ string `json:"Type,omitempty"`
Path string `json:"Path,omitempty"` Path string `json:"Path,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type CacheQueryStatsResponse struct { type CacheQueryStatsResponse struct {
L3OccupancyBytes int32 `json:"L3OccupancyBytes,omitempty"` L3OccupancyBytes int32 `json:"L3OccupancyBytes,omitempty"`
L3TotalBwBytes int32 `json:"L3TotalBwBytes,omitempty"` L3TotalBwBytes int32 `json:"L3TotalBwBytes,omitempty"`

View File

@ -10,6 +10,5 @@
package hcsschema package hcsschema
type CloseHandle struct { type CloseHandle struct {
Handle string `json:"Handle,omitempty"` Handle string `json:"Handle,omitempty"`
} }

View File

@ -11,7 +11,6 @@ package hcsschema
// ComPort specifies the named pipe that will be used for the port, with empty string indicating a disconnected port. // ComPort specifies the named pipe that will be used for the port, with empty string indicating a disconnected port.
type ComPort struct { type ComPort struct {
NamedPipe string `json:"NamedPipe,omitempty"` NamedPipe string `json:"NamedPipe,omitempty"`
OptimizeForDebugger bool `json:"OptimizeForDebugger,omitempty"` OptimizeForDebugger bool `json:"OptimizeForDebugger,omitempty"`

View File

@ -10,14 +10,13 @@
package hcsschema package hcsschema
type ComputeSystem struct { type ComputeSystem struct {
Owner string `json:"Owner,omitempty"` Owner string `json:"Owner,omitempty"`
SchemaVersion *Version `json:"SchemaVersion,omitempty"` SchemaVersion *Version `json:"SchemaVersion,omitempty"`
HostingSystemId string `json:"HostingSystemId,omitempty"` HostingSystemId string `json:"HostingSystemId,omitempty"`
HostedSystem *HostedSystem `json:"HostedSystem,omitempty"` HostedSystem interface{} `json:"HostedSystem,omitempty"`
Container *Container `json:"Container,omitempty"` Container *Container `json:"Container,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type ConsoleSize struct { type ConsoleSize struct {
Height int32 `json:"Height,omitempty"` Height int32 `json:"Height,omitempty"`
Width int32 `json:"Width,omitempty"` Width int32 `json:"Width,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type Container struct { type Container struct {
GuestOs *GuestOs `json:"GuestOs,omitempty"` GuestOs *GuestOs `json:"GuestOs,omitempty"`
Storage *Storage `json:"Storage,omitempty"` Storage *Storage `json:"Storage,omitempty"`

View File

@ -11,7 +11,6 @@ package hcsschema
// memory usage as viewed from within the container // memory usage as viewed from within the container
type ContainerMemoryInformation struct { type ContainerMemoryInformation struct {
TotalPhysicalBytes int32 `json:"TotalPhysicalBytes,omitempty"` TotalPhysicalBytes int32 `json:"TotalPhysicalBytes,omitempty"`
TotalUsage int32 `json:"TotalUsage,omitempty"` TotalUsage int32 `json:"TotalUsage,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type Devices struct { type Devices struct {
ComPorts map[string]ComPort `json:"ComPorts,omitempty"` ComPorts map[string]ComPort `json:"ComPorts,omitempty"`
Scsi map[string]Scsi `json:"Scsi,omitempty"` Scsi map[string]Scsi `json:"Scsi,omitempty"`
@ -40,4 +39,8 @@ type Devices struct {
FlexibleIov map[string]FlexibleIoDevice `json:"FlexibleIov,omitempty"` FlexibleIov map[string]FlexibleIoDevice `json:"FlexibleIov,omitempty"`
SharedMemory *SharedMemoryConfiguration `json:"SharedMemory,omitempty"` SharedMemory *SharedMemoryConfiguration `json:"SharedMemory,omitempty"`
// TODO: This is pre-release support in schema 2.3. Need to add build number
// docs when a public build with this is out.
VirtualPci map[string]VirtualPciDevice `json:",omitempty"`
} }

View File

@ -10,6 +10,5 @@
package hcsschema package hcsschema
type EnhancedModeVideo struct { type EnhancedModeVideo struct {
ConnectionOptions *RdpConnectionOptions `json:"ConnectionOptions,omitempty"` ConnectionOptions *RdpConnectionOptions `json:"ConnectionOptions,omitempty"`
} }

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type FlexibleIoDevice struct { type FlexibleIoDevice struct {
EmulatorId string `json:"EmulatorId,omitempty"` EmulatorId string `json:"EmulatorId,omitempty"`
HostingModel string `json:"HostingModel,omitempty"` HostingModel string `json:"HostingModel,omitempty"`

View File

@ -10,6 +10,5 @@
package hcsschema package hcsschema
type GuestCrashReporting struct { type GuestCrashReporting struct {
WindowsCrashSettings *WindowsCrashReporting `json:"WindowsCrashSettings,omitempty"` WindowsCrashSettings *WindowsCrashReporting `json:"WindowsCrashSettings,omitempty"`
} }

View File

@ -10,6 +10,5 @@
package hcsschema package hcsschema
type GuestOs struct { type GuestOs struct {
HostName string `json:"HostName,omitempty"` HostName string `json:"HostName,omitempty"`
} }

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type HostedSystem struct { type HostedSystem struct {
SchemaVersion *Version `json:"SchemaVersion,omitempty"` SchemaVersion *Version `json:"SchemaVersion,omitempty"`
Container *Container `json:"Container,omitempty"` Container *Container `json:"Container,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type HvSocket struct { type HvSocket struct {
Config *HvSocketSystemConfig `json:"Config,omitempty"` Config *HvSocketSystemConfig `json:"Config,omitempty"`
EnablePowerShellDirect bool `json:"EnablePowerShellDirect,omitempty"` EnablePowerShellDirect bool `json:"EnablePowerShellDirect,omitempty"`

View File

@ -11,6 +11,5 @@ package hcsschema
// HvSocket configuration for a VM // HvSocket configuration for a VM
type HvSocket2 struct { type HvSocket2 struct {
HvSocketConfig *HvSocketSystemConfig `json:"HvSocketConfig,omitempty"` HvSocketConfig *HvSocketSystemConfig `json:"HvSocketConfig,omitempty"`
} }

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type Layer struct { type Layer struct {
Id string `json:"Id,omitempty"` Id string `json:"Id,omitempty"`
Path string `json:"Path,omitempty"` Path string `json:"Path,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type MappedDirectory struct { type MappedDirectory struct {
HostPath string `json:"HostPath,omitempty"` HostPath string `json:"HostPath,omitempty"`
HostPathType string `json:"HostPathType,omitempty"` HostPathType string `json:"HostPathType,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type MappedPipe struct { type MappedPipe struct {
ContainerPipeName string `json:"ContainerPipeName,omitempty"` ContainerPipeName string `json:"ContainerPipeName,omitempty"`
HostPath string `json:"HostPath,omitempty"` HostPath string `json:"HostPath,omitempty"`

View File

@ -10,6 +10,5 @@
package hcsschema package hcsschema
type Memory struct { type Memory struct {
SizeInMB int32 `json:"SizeInMB,omitempty"` SizeInMB int32 `json:"SizeInMB,omitempty"`
} }

View File

@ -22,4 +22,28 @@ type Memory2 struct {
// EnableDeferredCommit is private in the schema. If regenerated need to add back. // EnableDeferredCommit is private in the schema. If regenerated need to add back.
EnableDeferredCommit bool `json:"EnableDeferredCommit,omitempty"` EnableDeferredCommit bool `json:"EnableDeferredCommit,omitempty"`
// EnableColdDiscardHint if enabled, then the memory cold discard hint feature is exposed
// to the VM, allowing it to trim non-zeroed pages from the working set (if supported by
// the guest operating system).
EnableColdDiscardHint bool `json:"EnableColdDiscardHint,omitempty"`
// LowMmioGapInMB is the low MMIO region allocated below 4GB.
//
// TODO: This is pre-release support in schema 2.3. Need to add build number
// docs when a public build with this is out.
LowMMIOGapInMB uint64 `json:"LowMmioGapInMB,omitempty"`
// HighMmioBaseInMB is the high MMIO region allocated above 4GB (base and
// size).
//
// TODO: This is pre-release support in schema 2.3. Need to add build number
// docs when a public build with this is out.
HighMMIOBaseInMB uint64 `json:"HighMmioBaseInMB,omitempty"`
// HighMmioGapInMB is the high MMIO region.
//
// TODO: This is pre-release support in schema 2.3. Need to add build number
// docs when a public build with this is out.
HighMMIOGapInMB uint64 `json:"HighMmioGapInMB,omitempty"`
} }

View File

@ -10,8 +10,7 @@
package hcsschema package hcsschema
type MemoryInformationForVm struct { type MemoryInformationForVm struct {
VirtualNodeCount uint32 `json:"VirtualNodeCount,omitempty"`
VirtualNodeCount int32 `json:"VirtualNodeCount,omitempty"`
VirtualMachineMemory *VmMemory `json:"VirtualMachineMemory,omitempty"` VirtualMachineMemory *VmMemory `json:"VirtualMachineMemory,omitempty"`

View File

@ -11,10 +11,9 @@ package hcsschema
// Memory runtime statistics // Memory runtime statistics
type MemoryStats struct { type MemoryStats struct {
MemoryUsageCommitBytes uint64 `json:"MemoryUsageCommitBytes,omitempty"`
MemoryUsageCommitBytes int32 `json:"MemoryUsageCommitBytes,omitempty"` MemoryUsageCommitPeakBytes uint64 `json:"MemoryUsageCommitPeakBytes,omitempty"`
MemoryUsageCommitPeakBytes int32 `json:"MemoryUsageCommitPeakBytes,omitempty"` MemoryUsagePrivateWorkingSetBytes uint64 `json:"MemoryUsagePrivateWorkingSetBytes,omitempty"`
MemoryUsagePrivateWorkingSetBytes int32 `json:"MemoryUsagePrivateWorkingSetBytes,omitempty"`
} }

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type NetworkAdapter struct { type NetworkAdapter struct {
EndpointId string `json:"EndpointId,omitempty"` EndpointId string `json:"EndpointId,omitempty"`
MacAddress string `json:"MacAddress,omitempty"` MacAddress string `json:"MacAddress,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type Networking struct { type Networking struct {
AllowUnqualifiedDnsQuery bool `json:"AllowUnqualifiedDnsQuery,omitempty"` AllowUnqualifiedDnsQuery bool `json:"AllowUnqualifiedDnsQuery,omitempty"`
DnsSearchList string `json:"DnsSearchList,omitempty"` DnsSearchList string `json:"DnsSearchList,omitempty"`

View File

@ -11,6 +11,5 @@ package hcsschema
// Notification data that is indicated to components running in the Virtual Machine. // Notification data that is indicated to components running in the Virtual Machine.
type PauseNotification struct { type PauseNotification struct {
Reason string `json:"Reason,omitempty"` Reason string `json:"Reason,omitempty"`
} }

View File

@ -11,7 +11,6 @@ package hcsschema
// Options for HcsPauseComputeSystem // Options for HcsPauseComputeSystem
type PauseOptions struct { type PauseOptions struct {
SuspensionLevel string `json:"SuspensionLevel,omitempty"` SuspensionLevel string `json:"SuspensionLevel,omitempty"`
HostedNotification *PauseNotification `json:"HostedNotification,omitempty"` HostedNotification *PauseNotification `json:"HostedNotification,omitempty"`

View File

@ -10,6 +10,5 @@
package hcsschema package hcsschema
type Plan9 struct { type Plan9 struct {
Shares []Plan9Share `json:"Shares,omitempty"` Shares []Plan9Share `json:"Shares,omitempty"`
} }

View File

@ -15,7 +15,6 @@ import (
// Information about a process running in a container // Information about a process running in a container
type ProcessDetails struct { type ProcessDetails struct {
ProcessId int32 `json:"ProcessId,omitempty"` ProcessId int32 `json:"ProcessId,omitempty"`
ImageName string `json:"ImageName,omitempty"` ImageName string `json:"ImageName,omitempty"`

View File

@ -11,7 +11,6 @@ package hcsschema
// Passed to HcsRpc_ModifyProcess // Passed to HcsRpc_ModifyProcess
type ProcessModifyRequest struct { type ProcessModifyRequest struct {
Operation string `json:"Operation,omitempty"` Operation string `json:"Operation,omitempty"`
ConsoleSize *ConsoleSize `json:"ConsoleSize,omitempty"` ConsoleSize *ConsoleSize `json:"ConsoleSize,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type ProcessParameters struct { type ProcessParameters struct {
ApplicationName string `json:"ApplicationName,omitempty"` ApplicationName string `json:"ApplicationName,omitempty"`
CommandLine string `json:"CommandLine,omitempty"` CommandLine string `json:"CommandLine,omitempty"`

View File

@ -11,7 +11,6 @@ package hcsschema
// Status of a process running in a container // Status of a process running in a container
type ProcessStatus struct { type ProcessStatus struct {
ProcessId int32 `json:"ProcessId,omitempty"` ProcessId int32 `json:"ProcessId,omitempty"`
Exited bool `json:"Exited,omitempty"` Exited bool `json:"Exited,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type Processor struct { type Processor struct {
Count int32 `json:"Count,omitempty"` Count int32 `json:"Count,omitempty"`
Maximum int32 `json:"Maximum,omitempty"` Maximum int32 `json:"Maximum,omitempty"`

View File

@ -10,7 +10,6 @@
package hcsschema package hcsschema
type Processor2 struct { type Processor2 struct {
Count int32 `json:"Count,omitempty"` Count int32 `json:"Count,omitempty"`
Limit int32 `json:"Limit,omitempty"` Limit int32 `json:"Limit,omitempty"`

View File

@ -11,10 +11,9 @@ package hcsschema
// CPU runtime statistics // CPU runtime statistics
type ProcessorStats struct { type ProcessorStats struct {
TotalRuntime100ns uint64 `json:"TotalRuntime100ns,omitempty"`
TotalRuntime100ns int32 `json:"TotalRuntime100ns,omitempty"` RuntimeUser100ns uint64 `json:"RuntimeUser100ns,omitempty"`
RuntimeUser100ns int32 `json:"RuntimeUser100ns,omitempty"` RuntimeKernel100ns uint64 `json:"RuntimeKernel100ns,omitempty"`
RuntimeKernel100ns int32 `json:"RuntimeKernel100ns,omitempty"`
} }

View File

@ -9,8 +9,11 @@
package hcsschema package hcsschema
type Properties struct { import (
v1 "github.com/containerd/cgroups/stats/v1"
)
type Properties struct {
Id string `json:"Id,omitempty"` Id string `json:"Id,omitempty"`
SystemType string `json:"SystemType,omitempty"` SystemType string `json:"SystemType,omitempty"`
@ -44,4 +47,8 @@ type Properties struct {
SharedMemoryRegionInfo []SharedMemoryRegionInfo `json:"SharedMemoryRegionInfo,omitempty"` SharedMemoryRegionInfo []SharedMemoryRegionInfo `json:"SharedMemoryRegionInfo,omitempty"`
GuestConnectionInfo *GuestConnectionInfo `json:"GuestConnectionInfo,omitempty"` GuestConnectionInfo *GuestConnectionInfo `json:"GuestConnectionInfo,omitempty"`
// Metrics is not part of the API for HCS but this is used for LCOW v2 to
// return the full cgroup metrics from the guest.
Metrics *v1.Metrics `json:"LCOWMetrics,omitempty"`
} }

View File

@ -11,6 +11,5 @@ package hcsschema
// By default the basic properties will be returned. This query provides a way to request specific properties. // By default the basic properties will be returned. This query provides a way to request specific properties.
type PropertyQuery struct { type PropertyQuery struct {
PropertyTypes []PropertyType `json:"PropertyTypes,omitempty"`
PropertyTypes []string `json:"PropertyTypes,omitempty"`
} }

View File

@ -0,0 +1,23 @@
/*
* HCS API
*
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
*
* API version: 2.1
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package hcsschema
type PropertyType string
const (
PTMemory PropertyType = "Memory"
PTGuestMemory PropertyType = "GuestMemory"
PTStatistics PropertyType = "Statistics"
PTProcessList PropertyType = "ProcessList"
PTTerminateOnLastHandleClosed PropertyType = "TerminateOnLastHandleClosed"
PTSharedMemoryRegion PropertyType = "SharedMemoryRegion"
PTGuestConnection PropertyType = "GuestConnection"
PTICHeartbeatStatus PropertyType = "ICHeartbeatStatus"
)

Some files were not shown because too many files have changed in this diff Show More