X Tutup
Skip to content

Commit dcff993

Browse files
committed
Update Windows runtime to use snapshotter and differ layers
This changes the Windows runtime to use the snapshotter and differ created layers, and updates the ctr commands to use the snapshotter and differ. Signed-off-by: Darren Stahl <darst@microsoft.com>
1 parent a5a9f91 commit dcff993

File tree

9 files changed

+91
-317
lines changed

9 files changed

+91
-317
lines changed

cmd/ctr/commands/run/run_windows.go

Lines changed: 24 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,12 @@ import (
77
"github.com/containerd/containerd"
88
"github.com/containerd/containerd/cmd/ctr/commands"
99
"github.com/containerd/containerd/containers"
10-
"github.com/containerd/containerd/errdefs"
1110
"github.com/containerd/containerd/oci"
1211
specs "github.com/opencontainers/runtime-spec/specs-go"
13-
"github.com/pkg/errors"
1412
"github.com/sirupsen/logrus"
1513
"github.com/urfave/cli"
1614
)
1715

18-
func init() {
19-
Command.Flags = append(Command.Flags, cli.StringSliceFlag{
20-
Name: "layer",
21-
Usage: "HCSSHIM Layers to be used",
22-
})
23-
}
24-
25-
func withLayers(context *cli.Context) oci.SpecOpts {
26-
return func(ctx gocontext.Context, client oci.Client, c *containers.Container, s *specs.Spec) error {
27-
l := context.StringSlice("layer")
28-
if l == nil {
29-
return errors.Wrap(errdefs.ErrInvalidArgument, "base layers must be specified with `--layer`")
30-
}
31-
s.Windows.LayerFolders = l
32-
return nil
33-
}
34-
}
35-
3616
func withTTY(terminal bool) oci.SpecOpts {
3717
if !terminal {
3818
return func(ctx gocontext.Context, client oci.Client, c *containers.Container, s *specs.Spec) error {
@@ -51,36 +31,39 @@ func withTTY(terminal bool) oci.SpecOpts {
5131

5232
func newContainer(ctx gocontext.Context, client *containerd.Client, context *cli.Context) (containerd.Container, error) {
5333
var (
54-
// ref = context.Args().First()
55-
id = context.Args().Get(1)
56-
args = context.Args()[2:]
57-
tty = context.Bool("tty")
58-
labelStrings = context.StringSlice("label")
34+
ref = context.Args().First()
35+
id = context.Args().Get(1)
36+
args = context.Args()[2:]
5937
)
6038

61-
labels := commands.LabelArgs(labelStrings)
62-
63-
// TODO(mlaventure): get base image once we have a snapshotter
64-
65-
opts := []oci.SpecOpts{
66-
// TODO(mlaventure): use oci.WithImageConfig once we have a snapshotter
67-
withLayers(context),
68-
oci.WithEnv(context.StringSlice("env")),
69-
withMounts(context),
70-
withTTY(tty),
39+
image, err := client.GetImage(ctx, ref)
40+
if err != nil {
41+
return nil, err
7142
}
43+
44+
var (
45+
opts []oci.SpecOpts
46+
cOpts []containerd.NewContainerOpts
47+
)
48+
opts = append(opts, oci.WithImageConfig(image))
49+
opts = append(opts, oci.WithEnv(context.StringSlice("env")))
50+
opts = append(opts, withMounts(context))
7251
if len(args) > 0 {
7352
opts = append(opts, oci.WithProcessArgs(args...))
7453
}
7554
if cwd := context.String("cwd"); cwd != "" {
7655
opts = append(opts, oci.WithProcessCwd(cwd))
7756
}
78-
return client.NewContainer(ctx, id,
79-
containerd.WithNewSpec(opts...),
80-
containerd.WithContainerLabels(labels),
81-
containerd.WithRuntime(context.String("runtime"), nil),
82-
// TODO(mlaventure): containerd.WithImage(image),
83-
)
57+
opts = append(opts, withTTY(context.Bool("tty")))
58+
59+
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
60+
cOpts = append(cOpts, containerd.WithImage(image))
61+
cOpts = append(cOpts, containerd.WithSnapshotter(context.String("snapshotter")))
62+
cOpts = append(cOpts, containerd.WithNewSnapshot(id, image))
63+
cOpts = append(cOpts, containerd.WithRuntime(context.String("runtime"), nil))
64+
65+
cOpts = append([]containerd.NewContainerOpts{containerd.WithNewSpec(opts...)}, cOpts...)
66+
return client.NewContainer(ctx, id, cOpts...)
8467
}
8568

8669
func getNewTaskOpts(_ *cli.Context) []containerd.NewTaskOpts {

diff/windows/windows.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ func (s *windowsDiff) Apply(ctx context.Context, desc ocispec.Descriptor, mounts
140140
// DiffMounts creates a diff between the given mounts and uploads the result
141141
// to the content store.
142142
func (s *windowsDiff) DiffMounts(ctx context.Context, lower, upper []mount.Mount, opts ...diff.Opt) (d ocispec.Descriptor, err error) {
143-
panic("not implemented on Windows")
143+
return emptyDesc, errdefs.ErrNotImplemented
144144
}
145145

146146
type readCounter struct {

mount/mount_windows.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,6 @@ func (m *Mount) Mount(target string) error {
3939
if err = hcsshim.PrepareLayer(di, layerID, parentLayerPaths); err != nil {
4040
return errors.Wrapf(err, "failed to prepare layer %s", m.Source)
4141
}
42-
defer func() {
43-
if err != nil {
44-
hcsshim.UnprepareLayer(di, layerID)
45-
}
46-
}()
4742
return nil
4843
}
4944

@@ -67,10 +62,12 @@ func (m *Mount) GetParentPaths() ([]string, error) {
6762

6863
// Unmount the mount at the provided path
6964
func Unmount(mount string, flags int) error {
70-
home, layerID := filepath.Split(mount)
71-
var di = hcsshim.DriverInfo{
72-
HomeDir: home,
73-
}
65+
var (
66+
home, layerID = filepath.Split(mount)
67+
di = hcsshim.DriverInfo{
68+
HomeDir: home,
69+
}
70+
)
7471

7572
if err := hcsshim.UnprepareLayer(di, layerID); err != nil {
7673
return errors.Wrapf(err, "failed to unprepare layer %s", mount)

snapshots/windows/utilities.go

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

snapshots/windows/windows.go

Lines changed: 19 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ type snapshotter struct {
4141

4242
// NewSnapshotter returns a new windows snapshotter
4343
func NewSnapshotter(root string) (snapshots.Snapshotter, error) {
44-
fsType, err := getFileSystemType(string(root[0]))
44+
fsType, err := getFileSystemType(root)
4545
if err != nil {
4646
return nil, err
4747
}
48-
if strings.ToLower(fsType) == "refs" {
49-
return nil, errors.Wrapf(errdefs.ErrInvalidArgument, "%s is on an ReFS volume - ReFS volumes are not supported", root)
48+
if strings.ToLower(fsType) != "ntfs" {
49+
return nil, errors.Wrapf(errdefs.ErrInvalidArgument, "%s is not on an NTFS volume - only NTFS volumes are supported", root)
5050
}
5151

5252
if err := os.MkdirAll(root, 0700); err != nil {
@@ -83,25 +83,15 @@ func (s *snapshotter) Stat(ctx context.Context, key string) (snapshots.Info, err
8383
defer t.Rollback()
8484

8585
_, info, _, err := storage.GetInfo(ctx, key)
86-
if err != nil {
87-
return snapshots.Info{}, err
88-
}
89-
90-
return info, nil
86+
return info, err
9187
}
9288

9389
func (s *snapshotter) Update(ctx context.Context, info snapshots.Info, fieldpaths ...string) (snapshots.Info, error) {
9490
ctx, t, err := s.ms.TransactionContext(ctx, true)
9591
if err != nil {
9692
return snapshots.Info{}, err
9793
}
98-
99-
var committed bool
100-
defer func() {
101-
if committed == false {
102-
rollbackWithLogging(ctx, t)
103-
}
104-
}()
94+
defer t.Rollback()
10595

10696
info, err = storage.UpdateInfo(ctx, info, fieldpaths...)
10797
if err != nil {
@@ -111,7 +101,6 @@ func (s *snapshotter) Update(ctx context.Context, info snapshots.Info, fieldpath
111101
if err := t.Commit(); err != nil {
112102
return snapshots.Info{}, err
113103
}
114-
committed = true
115104

116105
return info, nil
117106
}
@@ -156,6 +145,7 @@ func (s *snapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount, er
156145
return nil, err
157146
}
158147
defer t.Rollback()
148+
159149
snapshot, err := storage.GetSnapshot(ctx, key)
160150
if err != nil {
161151
return nil, errors.Wrap(err, "failed to get snapshot mount")
@@ -168,13 +158,8 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap
168158
if err != nil {
169159
return err
170160
}
161+
defer t.Rollback()
171162

172-
var committed bool
173-
defer func() {
174-
if committed == false {
175-
rollbackWithLogging(ctx, t)
176-
}
177-
}()
178163
usage := fs.Usage{
179164
Size: 0,
180165
}
@@ -186,7 +171,6 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap
186171
if err := t.Commit(); err != nil {
187172
return err
188173
}
189-
committed = true
190174
return nil
191175
}
192176

@@ -197,13 +181,7 @@ func (s *snapshotter) Remove(ctx context.Context, key string) error {
197181
if err != nil {
198182
return err
199183
}
200-
201-
var committed bool
202-
defer func() {
203-
if committed == false {
204-
rollbackWithLogging(ctx, t)
205-
}
206-
}()
184+
defer t.Rollback()
207185

208186
id, _, err := storage.Remove(ctx, key)
209187
if err != nil {
@@ -217,15 +195,13 @@ func (s *snapshotter) Remove(ctx context.Context, key string) error {
217195
return err
218196
}
219197

220-
err = t.Commit()
221-
if err != nil {
198+
if err := t.Commit(); err != nil {
222199
if err1 := os.Rename(renamed, path); err1 != nil {
223200
// May cause inconsistent data on disk
224201
log.G(ctx).WithError(err1).WithField("path", renamed).Errorf("Failed to rename after failed commit")
225202
}
226203
return errors.Wrap(err, "failed to commit")
227204
}
228-
committed = true
229205

230206
if err := hcsshim.DestroyLayer(s.info, renamedID); err != nil {
231207
// Must be cleaned up, any "rm-*" could be removed if no active transactions
@@ -242,6 +218,7 @@ func (s *snapshotter) Walk(ctx context.Context, fn func(context.Context, snapsho
242218
return err
243219
}
244220
defer t.Rollback()
221+
245222
return storage.WalkInfo(ctx, fn)
246223
}
247224

@@ -251,9 +228,7 @@ func (s *snapshotter) Close() error {
251228
}
252229

253230
func (s *snapshotter) mounts(sn storage.Snapshot) []mount.Mount {
254-
var (
255-
roFlag string
256-
)
231+
var roFlag string
257232

258233
if sn.Kind == snapshots.KindView {
259234
roFlag = "ro"
@@ -288,13 +263,7 @@ func (s *snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, k
288263
if err != nil {
289264
return nil, err
290265
}
291-
292-
var committed bool
293-
defer func() {
294-
if committed == false {
295-
rollbackWithLogging(ctx, t)
296-
}
297-
}()
266+
defer t.Rollback()
298267

299268
newSnapshot, err := storage.CreateSnapshot(ctx, kind, key, parent, opts...)
300269
if err != nil {
@@ -328,7 +297,6 @@ func (s *snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, k
328297
if err := t.Commit(); err != nil {
329298
return nil, errors.Wrap(err, "commit failed")
330299
}
331-
committed = true
332300

333301
return s.mounts(newSnapshot), nil
334302
}
@@ -343,17 +311,19 @@ func (s *snapshotter) parentIDsToParentPaths(parentIDs []string) []string {
343311

344312
// getFileSystemType obtains the type of a file system through GetVolumeInformation
345313
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364993(v=vs.85).aspx
346-
func getFileSystemType(drive string) (fsType string, hr error) {
314+
func getFileSystemType(path string) (fsType string, hr error) {
315+
drive := filepath.VolumeName(path)
316+
if len(drive) != 2 {
317+
return "", errors.New("getFileSystemType path must start with a drive letter")
318+
}
319+
347320
var (
348321
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
349322
procGetVolumeInformation = modkernel32.NewProc("GetVolumeInformationW")
350323
buf = make([]uint16, 255)
351324
size = windows.MAX_PATH + 1
352325
)
353-
if len(drive) != 1 {
354-
return "", errors.New("getFileSystemType must be called with a drive letter")
355-
}
356-
drive += `:\`
326+
drive += `\`
357327
n := uintptr(unsafe.Pointer(nil))
358328
r0, _, _ := syscall.Syscall9(procGetVolumeInformation.Addr(), 8, uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(drive))), n, n, n, n, n, uintptr(unsafe.Pointer(&buf[0])), uintptr(size), 0)
359329
if int32(r0) < 0 {

0 commit comments

Comments
 (0)
X Tutup