Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<description>containerd-shim-lcow-v2</description>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10+, Windows 11, Server 2016/2019/2022/2025 and future -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- Long Path Enablement -->
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<ws2:longPathAware>true</ws2:longPathAware>
</windowsSettings>
</application>
</assembly>

93 changes: 93 additions & 0 deletions cmd/containerd-shim-lcow-v2/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//go:build windows

// containerd-shim-lcow-v2 is a containerd shim implementation for Linux Containers on Windows (LCOW).
package main

import (
"context"
"errors"
"fmt"
"io"
"os"

"github.com/Microsoft/hcsshim/cmd/containerd-shim-lcow-v2/service"
_ "github.com/Microsoft/hcsshim/cmd/containerd-shim-lcow-v2/service/plugin"
runhcsopts "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/shim"

"github.com/containerd/errdefs"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)

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

func main() {
logrus.AddHook(log.NewHook())

// Register our OpenCensus logrus exporter so that trace spans are emitted via logrus.
trace.ApplyConfig(trace.Config{DefaultSampler: oc.DefaultSampler})
trace.RegisterExporter(&oc.LogrusExporter{})

logrus.SetFormatter(log.NopFormatter{})
logrus.SetOutput(io.Discard)

// Set the log configuration.
// If we encounter an error, we exit with non-zero code.
if err := setLogConfiguration(); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "%s: %s", service.ShimName, err)
os.Exit(1)
}

// Start the shim manager event loop. The manager is responsible for
// handling containerd start/stop lifecycle calls for the shim process.
shim.Run(context.Background(), newShimManager(service.ShimName), func(c *shim.Config) {
// We don't want the shim package to set up logging options.
c.NoSetupLogger = true
})
}

// setLogConfiguration reads the runtime options from stdin and sets the log configuration.
// We only set up the log configuration for serve action.
func setLogConfiguration() error {
// We set up the log configuration in the serve action only.
// This is because we want to avoid reading the stdin in start action,
// so that we can pass it along to the invocation for serve action.
if len(os.Args) > 1 && os.Args[len(os.Args)-1] == "serve" {
// The serve process is started with stderr pointing to panic.log file.
// We want to keep that file only for pure Go panics. Any explicit writes
// to os.Stderr should go to stdout instead, which is connected to the parent's
// stderr for regular logging.
// We can safely redirect os.Stderr to os.Stdout because in case of panics,
// the Go runtime will write the panic stack trace directly to the file descriptor,
// bypassing os.Stderr, so it will still go to panic.log.
os.Stderr = os.Stdout

opts, err := shim.ReadRuntimeOptions[*runhcsopts.Options](os.Stdin)
if err != nil {
if !errors.Is(err, errdefs.ErrNotFound) {
return fmt.Errorf("failed to read runtime options from stdin: %w", err)
}
}

if opts != nil {
if opts.LogLevel != "" {
// If log level is specified, set the corresponding logrus logging level.
lvl, err := logrus.ParseLevel(opts.LogLevel)
if err != nil {
return fmt.Errorf("failed to parse shim log level %q: %w", opts.LogLevel, err)
}
logrus.SetLevel(lvl)
}

if opts.ScrubLogs {
log.SetScrubbing(true)
}
}
_ = os.Stdin.Close()
}
return nil
}
Loading
Loading