Skip to content

Commit

Permalink
feat: Enable initial Windows support (#846)
Browse files Browse the repository at this point in the history
Approved-by: Antoine Cotten <antoine@unikraft.io>
  • Loading branch information
antoineco committed Oct 2, 2023
2 parents b195eae + c146464 commit 947ac80
Show file tree
Hide file tree
Showing 22 changed files with 148 additions and 45 deletions.
4 changes: 2 additions & 2 deletions archive/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ func TarFileWriter(ctx context.Context, src, dst string, tw *tar.Writer, opts ..

if dst == "" {
return fmt.Errorf("cannot tar file with no specified destination")
} else if dst[0] == '/' {
} else if dst[0] == filepath.Separator {
dst = dst[1:]
}
if strings.HasSuffix(dst, "/") {
if strings.HasSuffix(dst, string(filepath.Separator)) {
return fmt.Errorf("attempting to use TarFileWriter with directory")
}

Expand Down
4 changes: 2 additions & 2 deletions archive/unarchive.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ func Untar(src io.Reader, dst string, opts ...UnarchiveOption) error {
if uc.stripComponents > 0 {
// We don't use the context-(host-)specific filepath.SplitList because
// this is a UNIX tarball
parts := strings.Split(header.Name, "/")
path = strings.Join(parts[uc.stripComponents:], "/")
parts := filepath.SplitList(header.Name)
path = strings.Join(parts[uc.stripComponents:], string(filepath.Separator))
path = filepath.Join(dst, path)
} else {
path = filepath.Join(dst, header.Name)
Expand Down
2 changes: 1 addition & 1 deletion config/config_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ func findRegularFile(p string) string {
return p
}
newPath := filepath.Dir(p)
if newPath == p || newPath == "/" || newPath == "." {
if newPath == p || newPath == string(filepath.Separator) || newPath == "." {
break
}
p = newPath
Expand Down
6 changes: 1 addition & 5 deletions exec/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,7 @@ func (e *Process) Start(ctx context.Context) error {
log.G(ctx).Debug(e.Cmdline())

if e.opts.detach {
// the Setpgid flag is used to prevent the child process from exiting when
// the parent is killed
e.cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}
e.cmd.SysProcAttr = hostAttributes()
e.cmd.Stdin = nil
}

Expand Down
17 changes: 17 additions & 0 deletions exec/process_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors.
// Licensed under the BSD-3-Clause License (the "License").
// You may not use this file expect in compliance with the License.
package exec

import (
"syscall"
)

func hostAttributes() *syscall.SysProcAttr {
// the Setpgid flag is used to prevent the child process from exiting when
// the parent is killed
return &syscall.SysProcAttr{
Setpgid: true,
}
}
17 changes: 17 additions & 0 deletions exec/process_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors.
// Licensed under the BSD-3-Clause License (the "License").
// You may not use this file expect in compliance with the License.
package exec

import (
"syscall"
)

func hostAttributes() *syscall.SysProcAttr {
// the Setpgid flag is used to prevent the child process from exiting when
// the parent is killed
return &syscall.SysProcAttr{
Setpgid: true,
}
}
20 changes: 20 additions & 0 deletions exec/process_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// process_windows.go
//go:build windows

// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors.
// Licensed under the BSD-3-Clause License (the "License").
// You may not use this file expect in compliance with the License.
package exec

import (
"syscall"
)

func hostAttributes() *syscall.SysProcAttr {
// the CREATE_NEW_PROCESS_GROUP flag is used to prevent the child process from exiting when
// the parent is killed
return &syscall.SysProcAttr{
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
}
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ require (
sigs.k8s.io/kustomize/kyaml v0.14.3
)

replace github.com/vishvananda/netlink => github.com/craciunoiuc/netlink v1.2.1-beta.2

require (
dario.cat/mergo v1.0.0 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect
Expand Down
10 changes: 2 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/craciunoiuc/netlink v1.2.1-beta.2 h1:77jIchlL4g+LqbmQdxVWg8QthxM/MoG1FMOSPHqZJvc=
github.com/craciunoiuc/netlink v1.2.1-beta.2/go.mod h1:whJevzBpTrid75eZy99s3DqCmy05NfibNaF2Ol5Ox5A=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
Expand Down Expand Up @@ -1010,14 +1012,7 @@ github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck=
github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY=
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs=
github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
Expand Down Expand Up @@ -1224,7 +1219,6 @@ golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
9 changes: 4 additions & 5 deletions initrd/initrd.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,16 @@ func (i *InitrdConfig) NewReader(w io.Reader) (*cpio.Reader, error) {

// NewFromPath accepts a positional argument base which is the directory that
// the provided files should be serialized from. The prefix positional argument
// is used to affix all embedded files to the provided location. Left empty,
// the defeault prefix is "/".
// is used to affix all embedded files to the provided location.
func NewFromPath(base string, prefix string, files ...string) (*InitrdConfig, error) {
initrd := &InitrdConfig{
Format: NEWC,
}

if prefix == "" {
prefix = "/"
prefix = string(filepath.Separator)
}
if !strings.HasPrefix(prefix, "/") {
if !strings.HasPrefix(prefix, string(filepath.Separator)) {
return nil, fmt.Errorf("must use absolute path in prefix: %s", prefix)
}

Expand Down Expand Up @@ -177,7 +176,7 @@ func NewFromMapping(workdir, output string, maps ...string) (*InitrdConfig, erro
return nil
}

internal = "." + strings.ReplaceAll(filepath.Join(initrdPath, internal), "//", "/")
internal = "." + strings.ReplaceAll(filepath.Join(initrdPath, internal), string(filepath.Separator)+string(filepath.Separator), string(filepath.Separator))

info, err := d.Info()
if err != nil {
Expand Down
5 changes: 1 addition & 4 deletions internal/findsh/find_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,11 @@
package findsh

import (
"os"
"path/filepath"

"github.com/cli/safeexec"
)

func Find() (string, error) {
shPath, err := safeexec.LookPath("sh")
shPath, err := safeexec.LookPath("cmd")
if err != nil {
return "", err
}
Expand Down
2 changes: 1 addition & 1 deletion kconfig/kconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ func (kp *kconfigParser) includeSource(file string) {
return
}
kp.newCurrent(nil)
if file[0] != '/' {
if file[0] != filepath.Separator {
file = filepath.Join(kp.baseDir, file)
}
data, err := os.ReadFile(file)
Expand Down
24 changes: 24 additions & 0 deletions machine/network/register_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors.
// Licensed under the BSD-3-Clause License (the "License").
// You may not use this file except in compliance with the License.
package network

import (
"context"
"errors"

networkv1alpha1 "kraftkit.sh/api/network/v1alpha1"
)

// hostSupportedStrategies returns the map of known supported drivers for the
// given host.
func hostSupportedStrategies() map[string]*Strategy {
return map[string]*Strategy{
"bridge": {
NewNetworkV1alpha1: func(ctx context.Context, opts ...any) (networkv1alpha1.NetworkService, error) {
return nil, errors.New("network service is not supported on Windows")
},
},
}
}
3 changes: 3 additions & 0 deletions machine/platform/detect.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//go:build !windows
// +build !windows

// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors.
// Licensed under the BSD-3-Clause License (the "License").
Expand Down
24 changes: 24 additions & 0 deletions machine/platform/detect_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors.
// Licensed under the BSD-3-Clause License (the "License").
// You may not use this file except in compliance with the License.
package platform

import (
"context"
"fmt"
)

type SystemMode string

const (
SystemUnknown = SystemMode("unknown")
SystemGuest = SystemMode("guest")
SystemHost = SystemMode("host")
)

// Detect returns the hypervisor and system mode in the context to the
// determined hypervisor or an error if not detectable.
func Detect(ctx context.Context) (Platform, SystemMode, error) {
return PlatformUnknown, SystemUnknown, fmt.Errorf("Hypervisor detection is not supported on Windows")
}
3 changes: 0 additions & 3 deletions machine/platform/register_darwin.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
//go:build darwin
// +build darwin

// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors.
// Licensed under the BSD-3-Clause License (the "License").
Expand Down
3 changes: 3 additions & 0 deletions machine/platform/register_unix.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//go:build !windows
// +build !windows

// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors.
// Licensed under the BSD-3-Clause License (the "License").
Expand Down
14 changes: 14 additions & 0 deletions machine/platform/register_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2022, Unikraft GmbH and The KraftKit Authors.
// Licensed under the BSD-3-Clause License (the "License").
// You may not use this file except in compliance with the License.
package platform

// hostSupportedStrategies returns the map of known supported drivers for the
// given host.
// No drivers are supported on Windows currently. Future HyperV support is possible.
func hostSupportedStrategies() map[Platform]*Strategy {
s := map[Platform]*Strategy{}

return s
}
2 changes: 1 addition & 1 deletion manifest/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (m *manifestManager) Update(ctx context.Context) error {
filename := manifest.Name + ".yaml"

if manifest.Type != unikraft.ComponentTypeCore {
filename = manifest.Type.Plural() + "/" + filename
filename = manifest.Type.Plural() + string(filepath.Separator) + filename
}

fileloc := filepath.Join(m.LocalManifestsDir(ctx), filename)
Expand Down
10 changes: 5 additions & 5 deletions oci/handler/directory.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ func (handle *DirectoryHandler) FetchImage(ctx context.Context, fullref, platfor
)

// Recursively create the directory
if err = os.MkdirAll(manifestPath[:strings.LastIndex(manifestPath, "/")], 0o775); err != nil {
if err = os.MkdirAll(manifestPath[:strings.LastIndex(manifestPath, string(filepath.Separator))], 0o775); err != nil {
return err
}

Expand Down Expand Up @@ -365,7 +365,7 @@ func (handle *DirectoryHandler) FetchImage(ctx context.Context, fullref, platfor
}

// Recursively create the directory
if err = os.MkdirAll(configPath[:strings.LastIndex(configPath, "/")], 0o775); err != nil {
if err = os.MkdirAll(configPath[:strings.LastIndex(configPath, string(filepath.Separator))], 0o775); err != nil {
return err
}

Expand Down Expand Up @@ -400,7 +400,7 @@ func (handle *DirectoryHandler) FetchImage(ctx context.Context, fullref, platfor
)

// Recursively create the directory
if err = os.MkdirAll(layerPath[:strings.LastIndex(layerPath, "/")], 0o775); err != nil {
if err = os.MkdirAll(layerPath[:strings.LastIndex(layerPath, string(filepath.Separator))], 0o775); err != nil {
return err
}

Expand Down Expand Up @@ -518,8 +518,8 @@ func (handle *DirectoryHandler) UnpackImage(ctx context.Context, ref string, des
}

// If the directory in the path doesn't exist, create it
if _, err := os.Stat(path[:strings.LastIndex(path, "/")]); os.IsNotExist(err) {
if err := os.MkdirAll(path[:strings.LastIndex(path, "/")], 0o775); err != nil {
if _, err := os.Stat(path[:strings.LastIndex(path, string(filepath.Separator))]); os.IsNotExist(err) {
if err := os.MkdirAll(path[:strings.LastIndex(path, string(filepath.Separator))], 0o775); err != nil {
return err
}
}
Expand Down
11 changes: 4 additions & 7 deletions oci/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,14 @@ func (image *Image) AddBlob(ctx context.Context, blob *Blob) (ocispec.Descriptor
return ocispec.Descriptor{}, err
}

defer func() {
closeErr := fp.Close()
if err == nil {
err = closeErr
}
}()

if err := image.handle.SaveDigest(ctx, "", blob.desc, fp, nil); err != nil {
return ocispec.Descriptor{}, err
}

if err := fp.Close(); err != nil {
return ocispec.Descriptor{}, err
}

if blob.removeAfterSave {
if err := os.Remove(blob.tmp); err != nil {
return ocispec.Descriptor{}, err
Expand Down
1 change: 0 additions & 1 deletion oci/layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ func NewLayerFromFile(ctx context.Context, mediaType, src, dst string, opts ...L
if err != nil {
return nil, err
}
defer tmp.Close()

if err := archive.TarFileTo(ctx,
src, dst, tmp.Name(),
Expand Down

0 comments on commit 947ac80

Please sign in to comment.