utils.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. //go:build windows
  2. package hcs
  3. import (
  4. "context"
  5. "io"
  6. "syscall"
  7. "github.com/Microsoft/go-winio"
  8. diskutil "github.com/Microsoft/go-winio/vhd"
  9. "github.com/Microsoft/hcsshim/computestorage"
  10. "github.com/pkg/errors"
  11. "golang.org/x/sys/windows"
  12. )
  13. // makeOpenFiles calls winio.MakeOpenFile for each handle in a slice but closes all the handles
  14. // if there is an error.
  15. func makeOpenFiles(hs []syscall.Handle) (_ []io.ReadWriteCloser, err error) {
  16. fs := make([]io.ReadWriteCloser, len(hs))
  17. for i, h := range hs {
  18. if h != syscall.Handle(0) {
  19. if err == nil {
  20. fs[i], err = winio.MakeOpenFile(h)
  21. }
  22. if err != nil {
  23. syscall.Close(h)
  24. }
  25. }
  26. }
  27. if err != nil {
  28. for _, f := range fs {
  29. if f != nil {
  30. f.Close()
  31. }
  32. }
  33. return nil, err
  34. }
  35. return fs, nil
  36. }
  37. // CreateNTFSVHD creates a VHD formatted with NTFS of size `sizeGB` at the given `vhdPath`.
  38. func CreateNTFSVHD(ctx context.Context, vhdPath string, sizeGB uint32) (err error) {
  39. if err := diskutil.CreateVhdx(vhdPath, sizeGB, 1); err != nil {
  40. return errors.Wrap(err, "failed to create VHD")
  41. }
  42. vhd, err := diskutil.OpenVirtualDisk(vhdPath, diskutil.VirtualDiskAccessNone, diskutil.OpenVirtualDiskFlagNone)
  43. if err != nil {
  44. return errors.Wrap(err, "failed to open VHD")
  45. }
  46. defer func() {
  47. err2 := windows.CloseHandle(windows.Handle(vhd))
  48. if err == nil {
  49. err = errors.Wrap(err2, "failed to close VHD")
  50. }
  51. }()
  52. if err := computestorage.FormatWritableLayerVhd(ctx, windows.Handle(vhd)); err != nil {
  53. return errors.Wrap(err, "failed to format VHD")
  54. }
  55. return nil
  56. }