diff --git a/internal/tools/uvmboot/conf_wcow.go b/internal/tools/uvmboot/conf_wcow.go index ea609b34ac..086f090ae1 100644 --- a/internal/tools/uvmboot/conf_wcow.go +++ b/internal/tools/uvmboot/conf_wcow.go @@ -6,6 +6,7 @@ import ( "context" "fmt" "os" + "path/filepath" "github.com/containerd/console" "github.com/opencontainers/runtime-spec/specs-go" @@ -21,6 +22,7 @@ const ( vmgsFilePathArgName = "vmgs-path" disableSBArgName = "disable-secure-boot" isolationTypeArgName = "isolation-type" + writableEFIArgName = "writable-efi" // default policy (that allows all operations) used when no policy is provided allowAllPolicy = "cGFja2FnZSBwb2xpY3kKCmFwaV92ZXJzaW9uIDo9ICIwLjExLjAiCmZyYW1ld29ya192ZXJzaW9uIDo9ICIwLjQuMCIKCm1vdW50X2NpbXMgOj0geyJhbGxvd2VkIjogdHJ1ZX0KbW91bnRfZGV2aWNlIDo9IHsiYWxsb3dlZCI6IHRydWV9Cm1vdW50X292ZXJsYXkgOj0geyJhbGxvd2VkIjogdHJ1ZX0KY3JlYXRlX2NvbnRhaW5lciA6PSB7ImFsbG93ZWQiOiB0cnVlLCAiZW52X2xpc3QiOiBudWxsLCAiYWxsb3dfc3RkaW9fYWNjZXNzIjogdHJ1ZX0KdW5tb3VudF9kZXZpY2UgOj0geyJhbGxvd2VkIjogdHJ1ZX0KdW5tb3VudF9vdmVybGF5IDo9IHsiYWxsb3dlZCI6IHRydWV9CmV4ZWNfaW5fY29udGFpbmVyIDo9IHsiYWxsb3dlZCI6IHRydWUsICJlbnZfbGlzdCI6IG51bGx9CmV4ZWNfZXh0ZXJuYWwgOj0geyJhbGxvd2VkIjogdHJ1ZSwgImVudl9saXN0IjogbnVsbCwgImFsbG93X3N0ZGlvX2FjY2VzcyI6IHRydWV9CnNodXRkb3duX2NvbnRhaW5lciA6PSB7ImFsbG93ZWQiOiB0cnVlfQpzaWduYWxfY29udGFpbmVyX3Byb2Nlc3MgOj0geyJhbGxvd2VkIjogdHJ1ZX0KcGxhbjlfbW91bnQgOj0geyJhbGxvd2VkIjogdHJ1ZX0KcGxhbjlfdW5tb3VudCA6PSB7ImFsbG93ZWQiOiB0cnVlfQpnZXRfcHJvcGVydGllcyA6PSB7ImFsbG93ZWQiOiB0cnVlfQpkdW1wX3N0YWNrcyA6PSB7ImFsbG93ZWQiOiB0cnVlfQpydW50aW1lX2xvZ2dpbmcgOj0geyJhbGxvd2VkIjogdHJ1ZX0KbG9hZF9mcmFnbWVudCA6PSB7ImFsbG93ZWQiOiB0cnVlfQpzY3JhdGNoX21vdW50IDo9IHsiYWxsb3dlZCI6IHRydWV9CnNjcmF0Y2hfdW5tb3VudCA6PSB7ImFsbG93ZWQiOiB0cnVlfQo=" @@ -34,6 +36,7 @@ var ( cwcowDisableSecureBoot bool cwcowIsolationMode string cwcowSecurityPolicy string + cwcowWritableEFI bool ) var cwcowCommand = cli.Command{ @@ -91,6 +94,11 @@ var cwcowCommand = cli.Command{ Destination: &cwcowSecurityPolicy, Value: allowAllPolicy, }, + cli.BoolFlag{ + Name: writableEFIArgName, + Usage: "Attaches the EFI VHD as read-write instead of read-only. This allows the UVM to modify the contents of the VHD, be careful when using this option!", + Destination: &cwcowWritableEFI, + }, }, Action: func(c *cli.Context) error { runMany(c, func(id string) error { @@ -99,7 +107,6 @@ var cwcowCommand = cli.Command{ options.MemorySizeInMB = 2048 options.AllowOvercommit = false options.EnableDeferredCommit = false - options.DumpDirectoryPath = "C:\\crashdumps" // confidential specific options options.SecurityPolicyEnabled = true @@ -109,6 +116,24 @@ var cwcowCommand = cli.Command{ options.IsolationType = cwcowIsolationMode // always enable graphics console with uvmboot - helps with testing/debugging options.EnableGraphicsConsole = true + options.WritableEFI = cwcowWritableEFI + + var err error + cwcowBootVHD, err = filepath.Abs(cwcowBootVHD) + if err != nil { + return err + } + + cwcowEFIVHD, err = filepath.Abs(cwcowEFIVHD) + if err != nil { + return err + } + + cwcowScratchVHD, err = filepath.Abs(cwcowScratchVHD) + if err != nil { + return err + } + options.BootFiles = &uvm.WCOWBootFiles{ BootType: uvm.BlockCIMBoot, BlockCIMFiles: &uvm.BlockCIMBootFiles{ @@ -118,11 +143,6 @@ var cwcowCommand = cli.Command{ }, } setGlobalOptions(c, options.Options) - tempDir, err := os.MkdirTemp("", "uvmboot") - if err != nil { - return err - } - defer os.RemoveAll(tempDir) vm, err := uvm.CreateWCOW(context.TODO(), options) if err != nil { diff --git a/internal/uvm/create_wcow.go b/internal/uvm/create_wcow.go index aedd960776..0ee9274225 100644 --- a/internal/uvm/create_wcow.go +++ b/internal/uvm/create_wcow.go @@ -74,7 +74,7 @@ func GetDefaultConfidentialBootCIMPath() string { } func GetDefaultConfidentialEFIPath() string { - return filepath.Join(defaultConfidentialWCOWOSBootFilesPath(), "efi.vhd") + return filepath.Join(defaultConfidentialWCOWOSBootFilesPath(), "boot.vhd") } // NewDefaultOptionsWCOW creates the default options for a bootable version of @@ -509,6 +509,7 @@ func CreateWCOW(ctx context.Context, opts *OptionsWCOW) (_ *UtilityVM, err error vsmbNoDirectMap: opts.NoDirectMap, noWritableFileShares: opts.NoWritableFileShares, createOpts: *opts, + blockCIMMounts: make(map[string]*UVMMountedBlockCIMs), } defer func() { diff --git a/internal/uvm/security_policy.go b/internal/uvm/security_policy.go index 950179acc4..2346864afe 100644 --- a/internal/uvm/security_policy.go +++ b/internal/uvm/security_policy.go @@ -124,10 +124,11 @@ func (uvm *UtilityVM) InjectPolicyFragment(ctx context.Context, fragment *ctrdta // returns if this instance of the UtilityVM is created with confidential policy func (uvm *UtilityVM) HasConfidentialPolicy() bool { switch opts := uvm.createOpts.(type) { - case *OptionsWCOW: + case OptionsWCOW: return opts.SecurityPolicyEnabled - case *OptionsLCOW: + case OptionsLCOW: return opts.SecurityPolicyEnabled + default: + panic("unexpected options type") } - return false } diff --git a/internal/wclayer/cim/block_cim_writer.go b/internal/wclayer/cim/block_cim_writer.go index 334e391366..16f7c9552d 100644 --- a/internal/wclayer/cim/block_cim_writer.go +++ b/internal/wclayer/cim/block_cim_writer.go @@ -100,13 +100,16 @@ func (cw *BlockCIMLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo, f if name == wclayer.UtilityVMPath && len(cw.parentLayers) > 0 { // If there are UtilityVM files in non base layers, we will have to merge // those files with the parent layer UtilityVM files - either during image - // pull or at runtime (i.e when starting the UVM). In order to merge at image pull time, we will have - // to read parent layer block CIMs and copy all the UtilityVM files from - // those CIMs into this block CIM one by one i.e effectively merge all - // parent layer UtilityVM files in this layer. Or we will need to be able - // to boot the UtilityVM with merged block CIMs. None of these options are - // implemented yet so error out if we see that. - return fmt.Errorf("UtilityVM files in non base layers is not supported for block CIMs") + // pull or at runtime (i.e when starting the UVM). In order to merge at + // image pull time, we will have to read parent layer block CIMs and copy + // all the UtilityVM files from those CIMs into this block CIM one by one + // i.e effectively merge all parent layer UtilityVM files in this + // layer. Or we will need to be able to boot the UtilityVM with merged + // block CIMs. None of these options are implemented yet so log a + // warning. However, this shouldn't cause issues with most of the standard + // use cases because usually the pod is a nanoserver image and that is + // always a single layer. + log.G(cw.ctx).Warn("UtilityVM files in non base layers is not supported for block CIMs") } return cw.cimLayerWriter.Add(name, fileInfo, fileSize, securityDescriptor, extendedAttributes, reparseData) }