dependabot[bot] 394ab0d149
build(deps): bump the golang group with 5 updates
Bumps the golang group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/Microsoft/hcsshim](https://github.com/Microsoft/hcsshim) | `0.11.4` | `0.12.0` |
| [github.com/alexflint/go-filemutex](https://github.com/alexflint/go-filemutex) | `1.2.0` | `1.3.0` |
| [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) | `2.13.2` | `2.16.0` |
| [github.com/onsi/gomega](https://github.com/onsi/gomega) | `1.30.0` | `1.31.1` |
| [golang.org/x/sys](https://github.com/golang/sys) | `0.15.0` | `0.17.0` |


Updates `github.com/Microsoft/hcsshim` from 0.11.4 to 0.12.0
- [Release notes](https://github.com/Microsoft/hcsshim/releases)
- [Commits](https://github.com/Microsoft/hcsshim/compare/v0.11.4...v0.12.0)

Updates `github.com/alexflint/go-filemutex` from 1.2.0 to 1.3.0
- [Release notes](https://github.com/alexflint/go-filemutex/releases)
- [Commits](https://github.com/alexflint/go-filemutex/compare/v1.2.0...v1.3.0)

Updates `github.com/onsi/ginkgo/v2` from 2.13.2 to 2.16.0
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.13.2...v2.16.0)

Updates `github.com/onsi/gomega` from 1.30.0 to 1.31.1
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.30.0...v1.31.1)

Updates `golang.org/x/sys` from 0.15.0 to 0.17.0
- [Commits](https://github.com/golang/sys/compare/v0.15.0...v0.17.0)

---
updated-dependencies:
- dependency-name: github.com/Microsoft/hcsshim
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: golang
- dependency-name: github.com/alexflint/go-filemutex
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: golang
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: golang
- dependency-name: github.com/onsi/gomega
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: golang
- dependency-name: golang.org/x/sys
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: golang
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 15:54:46 +00:00

160 lines
4.2 KiB
Go

//go:build windows
package wclayer
import (
"context"
"fmt"
"os"
"path/filepath"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/longpath"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/safefile"
"github.com/Microsoft/hcsshim/internal/winapi"
"github.com/pkg/errors"
"go.opencensus.io/trace"
"golang.org/x/sys/windows"
)
var hiveNames = []string{"DEFAULT", "SAM", "SECURITY", "SOFTWARE", "SYSTEM"}
// Ensure the given file exists as an ordinary file, and create a minimal hive file if not.
func ensureHive(path string, root *os.File) (err error) {
_, err = safefile.LstatRelative(path, root)
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("accessing %s: %w", path, err)
}
version := windows.RtlGetVersion()
if version == nil {
return fmt.Errorf("failed to get OS version")
}
var fullPath string
fullPath, err = longpath.LongAbs(filepath.Join(root.Name(), path))
if err != nil {
return fmt.Errorf("getting path: %w", err)
}
var key winapi.ORHKey
err = winapi.ORCreateHive(&key)
if err != nil {
return fmt.Errorf("creating hive: %w", err)
}
defer func() {
closeErr := winapi.ORCloseHive(key)
if closeErr != nil && err == nil {
err = fmt.Errorf("closing hive key: %w", closeErr)
}
}()
err = winapi.ORSaveHive(key, fullPath, version.MajorVersion, version.MinorVersion)
if err != nil {
return fmt.Errorf("saving hive: %w", err)
}
return nil
}
func ensureBaseLayer(root *os.File) (hasUtilityVM bool, err error) {
// The base layer registry hives will be copied from here
const hiveSourcePath = "Files\\Windows\\System32\\config"
if err = safefile.MkdirAllRelative(hiveSourcePath, root); err != nil {
return
}
for _, hiveName := range hiveNames {
hivePath := filepath.Join(hiveSourcePath, hiveName)
if err = ensureHive(hivePath, root); err != nil {
return
}
}
stat, err := safefile.LstatRelative(UtilityVMFilesPath, root)
if os.IsNotExist(err) {
return false, nil
}
if err != nil {
return
}
if !stat.Mode().IsDir() {
fullPath := filepath.Join(root.Name(), UtilityVMFilesPath)
return false, errors.Errorf("%s has unexpected file mode %s", fullPath, stat.Mode().String())
}
const bcdRelativePath = "EFI\\Microsoft\\Boot\\BCD"
// Just check that this exists as a regular file. If it exists but is not a valid registry hive,
// ProcessUtilityVMImage will complain:
// "The registry could not read in, or write out, or flush, one of the files that contain the system's image of the registry."
bcdPath := filepath.Join(UtilityVMFilesPath, bcdRelativePath)
stat, err = safefile.LstatRelative(bcdPath, root)
if err != nil {
return false, errors.Wrapf(err, "UtilityVM must contain '%s'", bcdRelativePath)
}
if !stat.Mode().IsRegular() {
fullPath := filepath.Join(root.Name(), bcdPath)
return false, errors.Errorf("%s has unexpected file mode %s", fullPath, stat.Mode().String())
}
return true, nil
}
func convertToBaseLayer(ctx context.Context, root *os.File) error {
hasUtilityVM, err := ensureBaseLayer(root)
if err != nil {
return err
}
if err := ProcessBaseLayer(ctx, root.Name()); err != nil {
return err
}
if !hasUtilityVM {
return nil
}
err = safefile.EnsureNotReparsePointRelative(UtilityVMPath, root)
if err != nil {
return err
}
utilityVMPath := filepath.Join(root.Name(), UtilityVMPath)
return ProcessUtilityVMImage(ctx, utilityVMPath)
}
// ConvertToBaseLayer processes a candidate base layer, i.e. a directory
// containing the desired file content under Files/, and optionally the
// desired file content for a UtilityVM under UtilityVM/Files/
func ConvertToBaseLayer(ctx context.Context, path string) (err error) {
title := "hcsshim::ConvertToBaseLayer"
ctx, span := trace.StartSpan(ctx, title)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("path", path))
root, err := safefile.OpenRoot(path)
if err != nil {
return hcserror.New(err, title+" - failed", "")
}
defer func() {
if err2 := root.Close(); err == nil && err2 != nil {
err = hcserror.New(err2, title+" - failed", "")
}
}()
if err = convertToBaseLayer(ctx, root); err != nil {
return hcserror.New(err, title+" - failed", "")
}
return nil
}