Skip to content

Commit 00ca088

Browse files
committed
Refactor layer mount functions
This commit uses the newly added WCOW layer parsers and the new type for representing mounted WCOW layers. LCOW functions are also moved around (and renamed) to follow similar style as that of WCOW functions. Signed-off-by: Amit Barve <[email protected]>
1 parent 49ada2e commit 00ca088

25 files changed

Lines changed: 449 additions & 647 deletions

File tree

cmd/containerd-shim-runhcs-v1/delete.go

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ package main
44

55
import (
66
"context"
7-
"encoding/json"
87
"fmt"
98
"os"
109
"path/filepath"
@@ -18,10 +17,8 @@ import (
1817
"google.golang.org/protobuf/types/known/timestamppb"
1918

2019
"github.com/Microsoft/hcsshim/internal/hcs"
21-
"github.com/Microsoft/hcsshim/internal/layers"
2220
"github.com/Microsoft/hcsshim/internal/memory"
2321
"github.com/Microsoft/hcsshim/internal/oc"
24-
cimlayer "github.com/Microsoft/hcsshim/internal/wclayer/cim"
2522
"github.com/Microsoft/hcsshim/internal/winapi"
2623
)
2724

@@ -126,28 +123,8 @@ The delete command will be executed in the container's bundle as its cwd.
126123
fmt.Fprintf(os.Stderr, "failed to delete user %q: %v", username, err)
127124
}
128125

129-
// cleanup the layers mounted for the container. We currently only handle cleanup of CimFS
130-
// layers here. First n-1 values should be the image layerFolders (topmost layer being at
131-
// index 0) and the last entry should be the scratch layer
132-
var layerFolders []string
133-
f, err := os.Open(filepath.Join(bundleFlag, layersFile))
134-
if err != nil {
135-
if !errors.Is(err, os.ErrNotExist) {
136-
fmt.Fprintf(os.Stderr, "open layers file: %s", err)
137-
}
138-
} else {
139-
defer f.Close()
140-
if err = json.NewDecoder(f).Decode(&layerFolders); err != nil {
141-
fmt.Fprintf(os.Stderr, "decode layers json: %s", err)
142-
}
143-
}
144-
if err == nil && cimlayer.IsCimLayer(layerFolders[0]) {
145-
scratchLayerFolderPath := layerFolders[len(layerFolders)-1]
146-
err = layers.ReleaseCimFSHostLayers(ctx, scratchLayerFolderPath, idFlag)
147-
if err != nil {
148-
fmt.Fprintf(os.Stderr, "cleanup container %q mounts: %s", idFlag, err)
149-
}
150-
}
126+
// TODO(ambarve):
127+
// correctly handle cleanup of cimfs layers in case of shim process crash here.
151128

152129
if data, err := proto.Marshal(&task.DeleteResponse{
153130
ExitedAt: timestamppb.New(time.Now()),

cmd/containerd-shim-runhcs-v1/main.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import (
2929

3030
const usage = ``
3131
const ttrpcAddressEnv = "TTRPC_ADDRESS"
32-
const layersFile = "layers.json"
3332

3433
// Add a manifest to get proper Windows version detection.
3534
//go:generate go run github.com/josephspurrier/goversioninfo/cmd/goversioninfo -platform-specific

cmd/containerd-shim-runhcs-v1/pod.go

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"strings"
1111
"sync"
1212

13+
"github.com/Microsoft/hcsshim/internal/layers"
1314
"github.com/Microsoft/hcsshim/internal/log"
1415
"github.com/Microsoft/hcsshim/internal/oci"
1516
"github.com/Microsoft/hcsshim/internal/uvm"
@@ -122,22 +123,15 @@ func createPod(ctx context.Context, events publisher, req *task.CreateTaskReques
122123
return nil, err
123124
}
124125
case *uvm.OptionsWCOW:
126+
var layerFolders []string
127+
if s.Windows != nil {
128+
layerFolders = s.Windows.LayerFolders
129+
}
125130
wopts := (opts).(*uvm.OptionsWCOW)
126-
127-
// In order for the UVM sandbox.vhdx not to collide with the actual
128-
// nested Argon sandbox.vhdx we append the \vm folder to the last
129-
// entry in the list.
130-
layersLen := len(s.Windows.LayerFolders)
131-
layers := make([]string, layersLen)
132-
copy(layers, s.Windows.LayerFolders)
133-
134-
vmPath := filepath.Join(layers[layersLen-1], "vm")
135-
err := os.MkdirAll(vmPath, 0)
131+
wopts.BootFiles, err = layers.GetWCOWUVMBootFilesFromLayers(ctx, req.Rootfs, layerFolders)
136132
if err != nil {
137133
return nil, err
138134
}
139-
layers[layersLen-1] = vmPath
140-
wopts.LayerFolders = layers
141135

142136
parent, err = uvm.CreateWCOW(ctx, wopts)
143137
if err != nil {

cmd/containerd-shim-runhcs-v1/rootfs.go

Lines changed: 0 additions & 144 deletions
This file was deleted.

cmd/containerd-shim-runhcs-v1/service_internal.go

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,6 @@ import (
2727

2828
var empty = &emptypb.Empty{}
2929

30-
// TODO(ambarve): Once we can vendor containerd 2.0 in hcsshim, we should directly reference these types from
31-
// containerd module
32-
const (
33-
LegacyMountType string = "windows-layer"
34-
CimFSMountType string = "CimFS"
35-
)
36-
3730
// getPod returns the pod this shim is tracking or else returns `nil`. It is the
3831
// callers responsibility to verify that `s.isSandbox == true` before calling
3932
// this method.
@@ -123,53 +116,6 @@ func (s *service) createInternal(ctx context.Context, req *task.CreateTaskReques
123116
}
124117
}
125118

126-
var layerFolders []string
127-
if spec.Windows != nil {
128-
layerFolders = spec.Windows.LayerFolders
129-
}
130-
if err := validateRootfsAndLayers(req.Rootfs, layerFolders); err != nil {
131-
return nil, err
132-
}
133-
134-
// Only work with Windows here.
135-
// Parsing of the rootfs mount for Linux containers occurs later.
136-
if spec.Linux == nil && len(req.Rootfs) > 0 {
137-
// For Windows containers, we work with LayerFolders throughout
138-
// much of the creation logic in the shim. If we were given a
139-
// rootfs mount, convert it to LayerFolders here.
140-
m := req.Rootfs[0]
141-
if m.Type != LegacyMountType && m.Type != CimFSMountType {
142-
return nil, fmt.Errorf("unsupported Windows mount type: %s", m.Type)
143-
} else if m.Type == CimFSMountType && (shimOpts.SandboxIsolation == runhcsopts.Options_HYPERVISOR) {
144-
// For CIMFS layers only process isolation is supported right now.
145-
return nil, fmt.Errorf("cimfs doesn't support hyperv isolation")
146-
}
147-
148-
source, parentLayerPaths, err := parseLegacyRootfsMount(m)
149-
if err != nil {
150-
return nil, err
151-
}
152-
153-
// Append the parents
154-
spec.Windows.LayerFolders = append(spec.Windows.LayerFolders, parentLayerPaths...)
155-
// Append the scratch
156-
spec.Windows.LayerFolders = append(spec.Windows.LayerFolders, source)
157-
158-
if m.Type == CimFSMountType {
159-
// write the layers to a file so that it can be used for proper cleanup during shim
160-
// delete. We can't write to the config.json as it is read-only for shim.
161-
f, err = os.Create(filepath.Join(req.Bundle, layersFile))
162-
if err != nil {
163-
return nil, err
164-
}
165-
if err := json.NewEncoder(f).Encode(spec.Windows.LayerFolders); err != nil {
166-
f.Close()
167-
return nil, err
168-
}
169-
f.Close()
170-
}
171-
}
172-
173119
// This is a Windows Argon make sure that we have a Root filled in.
174120
if spec.Windows.HyperV == nil {
175121
if spec.Root == nil {

cmd/containerd-shim-runhcs-v1/task_hcs.go

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
3636
"github.com/Microsoft/hcsshim/internal/hcsoci"
3737
"github.com/Microsoft/hcsshim/internal/jobcontainers"
38+
"github.com/Microsoft/hcsshim/internal/layers"
3839
"github.com/Microsoft/hcsshim/internal/log"
3940
"github.com/Microsoft/hcsshim/internal/memory"
4041
"github.com/Microsoft/hcsshim/internal/oc"
@@ -82,23 +83,15 @@ func newHcsStandaloneTask(ctx context.Context, events publisher, req *task.Creat
8283
return nil, err
8384
}
8485
case *uvm.OptionsWCOW:
86+
var layerFolders []string
87+
if s.Windows != nil {
88+
layerFolders = s.Windows.LayerFolders
89+
}
8590
wopts := (opts).(*uvm.OptionsWCOW)
86-
87-
// In order for the UVM sandbox.vhdx not to collide with the actual
88-
// nested Argon sandbox.vhdx we append the \vm folder to the last
89-
// entry in the list.
90-
layersLen := len(s.Windows.LayerFolders)
91-
layers := make([]string, layersLen)
92-
copy(layers, s.Windows.LayerFolders)
93-
94-
vmPath := filepath.Join(layers[layersLen-1], "vm")
95-
err := os.MkdirAll(vmPath, 0)
91+
wopts.BootFiles, err = layers.GetWCOWUVMBootFilesFromLayers(ctx, req.Rootfs, layerFolders)
9692
if err != nil {
9793
return nil, err
9894
}
99-
layers[layersLen-1] = vmPath
100-
wopts.LayerFolders = layers
101-
10295
parent, err = uvm.CreateWCOW(ctx, wopts)
10396
if err != nil {
10497
return nil, err
@@ -140,8 +133,24 @@ func createContainer(
140133
resources *resources.Resources
141134
)
142135

136+
var wcowLayers layers.WCOWLayers
137+
var lcowLayers *layers.LCOWLayers
138+
var layerFolders []string
139+
if s.Windows != nil {
140+
layerFolders = s.Windows.LayerFolders
141+
}
142+
if s.Linux != nil {
143+
lcowLayers, err = layers.ParseLCOWLayers(rootfs, layerFolders)
144+
} else {
145+
wcowLayers, err = layers.ParseWCOWLayers(rootfs, layerFolders)
146+
}
147+
if err != nil {
148+
return nil, nil, err
149+
}
150+
143151
if oci.IsJobContainer(s) {
144-
container, resources, err = jobcontainers.Create(ctx, id, s)
152+
opts := jobcontainers.CreateOptions{WCOWLayers: wcowLayers}
153+
container, resources, err = jobcontainers.Create(ctx, id, s, opts)
145154
if err != nil {
146155
return nil, nil, err
147156
}
@@ -152,18 +161,10 @@ func createContainer(
152161
Spec: s,
153162
HostingSystem: parent,
154163
NetworkNamespace: netNS,
164+
LCOWLayers: lcowLayers,
165+
WCOWLayers: wcowLayers,
155166
}
156-
if s.Linux != nil {
157-
var layerFolders []string
158-
if s.Windows != nil {
159-
layerFolders = s.Windows.LayerFolders
160-
}
161-
lcowLayers, err := getLCOWLayers(rootfs, layerFolders)
162-
if err != nil {
163-
return nil, nil, err
164-
}
165-
opts.LCOWLayers = lcowLayers
166-
}
167+
167168
if shimOpts != nil {
168169
opts.ScaleCPULimitsToSandbox = shimOpts.ScaleCpuLimitsToSandbox
169170
}

0 commit comments

Comments
 (0)