Skip to content

Commit

Permalink
[Alternative to 148] go.mod: github.com/containerd/containerd/v2 v2.0…
Browse files Browse the repository at this point in the history
….0-rc.0

Similar to PR 148, but does not bump up urfave/cli.

- `cmd/ctr` is kept to use urfave/cli v1, but its containerd library is
  bumped up from v1.6 to v1.7 due to dependencies.
  typeurl is bumped up from v1 to v2 as a part of them.

- `cmd/ctr/v2v1glue` and `cmd/ctr/v1v2glue` are added for using
  containerd v2-based encryption library from containerd v1-based CLI.

- `cmd/ctr/commands/tasks` was copied from <https://github.com/containerd/containerd/tree/v1.7.14/cmd/ctr/commands/tasks>,
  but `metrics.go` was removed due to a dependency issue:
  containerd v1 depends on hcsshim v0.11, while containerd v2 depends on hcsshim v0.12.

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
  • Loading branch information
AkihiroSuda committed Mar 28, 2024
1 parent 2db95f3 commit fa20237
Show file tree
Hide file tree
Showing 31 changed files with 1,892 additions and 3,583 deletions.
2 changes: 1 addition & 1 deletion cmd/ctr/app/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ import (
"github.com/containerd/containerd/cmd/ctr/commands/plugins"
"github.com/containerd/containerd/cmd/ctr/commands/pprof"
"github.com/containerd/containerd/cmd/ctr/commands/snapshots"
"github.com/containerd/containerd/cmd/ctr/commands/tasks"
versionCmd "github.com/containerd/containerd/cmd/ctr/commands/version"
"github.com/containerd/containerd/defaults"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/version"
"github.com/containerd/imgcrypt/cmd/ctr/commands/containers"
"github.com/containerd/imgcrypt/cmd/ctr/commands/images"
"github.com/containerd/imgcrypt/cmd/ctr/commands/run"
"github.com/containerd/imgcrypt/cmd/ctr/commands/tasks"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"google.golang.org/grpc/grpclog"
Expand Down
4 changes: 2 additions & 2 deletions cmd/ctr/commands/containers/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
"github.com/containerd/containerd/log"
"github.com/containerd/imgcrypt/cmd/ctr/commands/flags"
"github.com/containerd/imgcrypt/cmd/ctr/commands/run"
"github.com/containerd/typeurl"
"github.com/containerd/typeurl/v2"
"github.com/urfave/cli"
)

Expand Down Expand Up @@ -281,7 +281,7 @@ var infoCommand = cli.Command{
return nil
}

if info.Spec != nil && info.Spec.Value != nil {
if info.Spec != nil && info.Spec.GetValue() != nil {
v, err := typeurl.UnmarshalAny(info.Spec)
if err != nil {
return err
Expand Down
7 changes: 5 additions & 2 deletions cmd/ctr/commands/images/crypt_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/platforms"
"github.com/containerd/imgcrypt/cmd/ctr/commands/img"
"github.com/containerd/imgcrypt/cmd/ctr/v1v2glue"
imgenc "github.com/containerd/imgcrypt/images/encryption"
"github.com/containerd/imgcrypt/images/encryption/parsehelpers"
encconfig "github.com/containers/ocicrypt/config"
Expand Down Expand Up @@ -126,10 +127,12 @@ func cryptImage(client *containerd.Client, ctx gocontext.Context, name, newName
}
defer done(ctx)

contentStore := &v1v2glue.ContentStore{Store: client.ContentStore()}

if encrypt {
newSpec, modified, err = imgenc.EncryptImage(ctx, client.ContentStore(), image.Target, cc, lf)
newSpec, modified, err = imgenc.EncryptImage(ctx, contentStore, image.Target, cc, lf)
} else {
newSpec, modified, err = imgenc.DecryptImage(ctx, client.ContentStore(), image.Target, cc, lf)
newSpec, modified, err = imgenc.DecryptImage(ctx, contentStore, image.Target, cc, lf)
}
if err != nil {
return image, err
Expand Down
5 changes: 3 additions & 2 deletions cmd/ctr/commands/images/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/containerd/containerd/platforms"
"github.com/containerd/imgcrypt"
"github.com/containerd/imgcrypt/cmd/ctr/commands/flags"
"github.com/containerd/imgcrypt/cmd/ctr/v2v1glue"
"github.com/containerd/imgcrypt/images/encryption"
"github.com/containerd/imgcrypt/images/encryption/parsehelpers"
"github.com/urfave/cli"
Expand Down Expand Up @@ -173,7 +174,7 @@ decrypting the image later on.
ltdd := imgcrypt.Payload{
DecryptConfig: *cc.DecryptConfig,
}
opts := encryption.WithUnpackConfigApplyOpts(encryption.WithDecryptedUnpack(&ltdd))
opts := v2v1glue.UnpackOpts(encryption.WithUnpackConfigApplyOpts(encryption.WithDecryptedUnpack(&ltdd)))
log.G(ctx).Debugf("unpacking %d images", len(imgs))

for _, img := range imgs {
Expand All @@ -184,7 +185,7 @@ decrypting the image later on.

// TODO: Show unpack status
fmt.Printf("unpacking %s (%s)...", img.Name, img.Target.Digest)
err = image.Unpack(ctx, context.String("snapshotter"), opts)
err = image.Unpack(ctx, context.String("snapshotter"), opts...)
if err != nil {
return err
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/ctr/commands/images/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/containerd/containerd/platforms"
"github.com/containerd/imgcrypt"
"github.com/containerd/imgcrypt/cmd/ctr/commands/flags"
"github.com/containerd/imgcrypt/cmd/ctr/v2v1glue"
"github.com/containerd/imgcrypt/images/encryption"
"github.com/containerd/imgcrypt/images/encryption/parsehelpers"

Expand Down Expand Up @@ -133,13 +134,13 @@ command. As part of this process, we do the following:
ltdd := imgcrypt.Payload{
DecryptConfig: *cc.DecryptConfig,
}
opts := encryption.WithUnpackConfigApplyOpts(encryption.WithDecryptedUnpack(&ltdd))
opts := v2v1glue.UnpackOpts(encryption.WithUnpackConfigApplyOpts(encryption.WithDecryptedUnpack(&ltdd)))

start := time.Now()
for _, platform := range p {
fmt.Printf("unpacking %s %s...\n", platforms.Format(platform), img.Target.Digest)
i := containerd.NewImageWithPlatform(client, img, platforms.Only(platform))
err = i.Unpack(ctx, context.String("snapshotter"), opts)
err = i.Unpack(ctx, context.String("snapshotter"), opts...)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/ctr/commands/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ import (
"github.com/containerd/containerd"
"github.com/containerd/containerd/cio"
"github.com/containerd/containerd/cmd/ctr/commands"
"github.com/containerd/containerd/cmd/ctr/commands/tasks"
"github.com/containerd/containerd/containers"
clabels "github.com/containerd/containerd/labels"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/oci"
gocni "github.com/containerd/go-cni"
"github.com/containerd/imgcrypt/cmd/ctr/commands/flags"
"github.com/containerd/imgcrypt/cmd/ctr/commands/tasks"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
Expand Down
25 changes: 22 additions & 3 deletions cmd/ctr/commands/run/run_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package run

import (
"context"
gocontext "context"
"errors"
"fmt"
Expand All @@ -38,11 +39,15 @@ import (
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/runtime/v2/runc/options"
"github.com/containerd/containerd/snapshots"
"github.com/containerd/errdefs"
"github.com/containerd/imgcrypt"
"github.com/containerd/imgcrypt/cmd/ctr/commands"
"github.com/containerd/imgcrypt/cmd/ctr/commands/images"
"github.com/containerd/imgcrypt/cmd/ctr/v1v2glue"
"github.com/containerd/imgcrypt/cmd/ctr/v2v1glue"
"github.com/containerd/imgcrypt/images/encryption"
"github.com/containerd/imgcrypt/images/encryption/parsehelpers"
encconfig "github.com/containers/ocicrypt/config"

"github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -157,8 +162,8 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
ltdd := imgcrypt.Payload{
DecryptConfig: *cc.DecryptConfig,
}
opts := encryption.WithUnpackConfigApplyOpts(encryption.WithDecryptedUnpack(&ltdd))
if err := image.Unpack(ctx, snapshotter, opts); err != nil {
opts := v2v1glue.UnpackOpts(encryption.WithUnpackConfigApplyOpts(encryption.WithDecryptedUnpack(&ltdd)))
if err := image.Unpack(ctx, snapshotter, opts...); err != nil {
return nil, err
}
}
Expand Down Expand Up @@ -369,14 +374,28 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
}

if !context.IsSet("skip-decrypt-auth") {
cOpts = append(cOpts, encryption.WithAuthorizationCheck(cc.DecryptConfig))
cOpts = append(cOpts, withAuthorizationCheck(cc.DecryptConfig))
}

// oci.WithImageConfig (WithUsername, WithUserID) depends on access to rootfs for resolving via
// the /etc/{passwd,group} files. So cOpts needs to have precedence over opts.
return client.NewContainer(ctx, id, cOpts...)
}

func withAuthorizationCheck(dc *encconfig.DecryptConfig) containerd.NewContainerOpts {
return func(ctx context.Context, client *containerd.Client, c *containers.Container) error {
image, err := client.ImageService().Get(ctx, c.Image)
if errdefs.IsNotFound(err) {
// allow creation of container without a existing image
return nil
} else if err != nil {
return err
}

return encryption.CheckAuthorization(ctx, &v1v2glue.ContentStore{Store: client.ContentStore()}, image.Target, dc)
}
}

func getRuncOptions(context *cli.Context) (*options.Options, error) {
runtimeOpts := &options.Options{}
if runcBinary := context.String("runc-binary"); runcBinary != "" {
Expand Down
86 changes: 86 additions & 0 deletions cmd/ctr/commands/tasks/attach.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package tasks

import (
"github.com/containerd/console"
"github.com/containerd/containerd/cio"
"github.com/containerd/containerd/cmd/ctr/commands"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
)

var attachCommand = cli.Command{
Name: "attach",
Usage: "Attach to the IO of a running container",
ArgsUsage: "CONTAINER",
Action: func(context *cli.Context) error {
client, ctx, cancel, err := commands.NewClient(context)
if err != nil {
return err
}
defer cancel()
container, err := client.LoadContainer(ctx, context.Args().First())
if err != nil {
return err
}
spec, err := container.Spec(ctx)
if err != nil {
return err
}
var (
con console.Console
tty = spec.Process.Terminal
)
if tty {
con = console.Current()
defer con.Reset()
if err := con.SetRaw(); err != nil {
return err
}
}
task, err := container.Task(ctx, cio.NewAttach(cio.WithStdio))
if err != nil {
return err
}
defer task.Delete(ctx)

statusC, err := task.Wait(ctx)
if err != nil {
return err
}

if tty {
if err := HandleConsoleResize(ctx, task, con); err != nil {
logrus.WithError(err).Error("console resize")
}
} else {
sigc := commands.ForwardAllSignals(ctx, task)
defer commands.StopCatch(sigc)
}

ec := <-statusC
code, _, err := ec.Result()
if err != nil {
return err
}
if code != 0 {
return cli.NewExitError("", int(code))
}
return nil
},
}
123 changes: 123 additions & 0 deletions cmd/ctr/commands/tasks/checkpoint.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package tasks

import (
"errors"
"fmt"

"github.com/containerd/containerd"
"github.com/containerd/containerd/cmd/ctr/commands"
"github.com/containerd/containerd/plugin"
"github.com/containerd/containerd/runtime/linux/runctypes"
"github.com/containerd/containerd/runtime/v2/runc/options"
"github.com/urfave/cli"
)

var checkpointCommand = cli.Command{
Name: "checkpoint",
Usage: "Checkpoint a container",
ArgsUsage: "[flags] CONTAINER",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "exit",
Usage: "Stop the container after the checkpoint",
},
cli.StringFlag{
Name: "image-path",
Usage: "Path to criu image files",
},
cli.StringFlag{
Name: "work-path",
Usage: "Path to criu work files and logs",
},
},
Action: func(context *cli.Context) error {
id := context.Args().First()
if id == "" {
return errors.New("container id must be provided")
}
client, ctx, cancel, err := commands.NewClient(context, containerd.WithDefaultRuntime(context.String("runtime")))
if err != nil {
return err
}
defer cancel()
container, err := client.LoadContainer(ctx, id)
if err != nil {
return err
}
task, err := container.Task(ctx, nil)
if err != nil {
return err
}
info, err := container.Info(ctx)
if err != nil {
return err
}
opts := []containerd.CheckpointTaskOpts{withCheckpointOpts(info.Runtime.Name, context)}
checkpoint, err := task.Checkpoint(ctx, opts...)
if err != nil {
return err
}
if context.String("image-path") == "" {
fmt.Println(checkpoint.Name())
}
return nil
},
}

// withCheckpointOpts only suitable for runc runtime now
func withCheckpointOpts(rt string, context *cli.Context) containerd.CheckpointTaskOpts {
return func(r *containerd.CheckpointTaskInfo) error {
imagePath := context.String("image-path")
workPath := context.String("work-path")

switch rt {
case plugin.RuntimeRuncV1, plugin.RuntimeRuncV2:
if r.Options == nil {
r.Options = &options.CheckpointOptions{}
}
opts, _ := r.Options.(*options.CheckpointOptions)

if context.Bool("exit") {
opts.Exit = true
}
if imagePath != "" {
opts.ImagePath = imagePath
}
if workPath != "" {
opts.WorkPath = workPath
}
case plugin.RuntimeLinuxV1:
if r.Options == nil {
r.Options = &runctypes.CheckpointOptions{}
}
opts, _ := r.Options.(*runctypes.CheckpointOptions)

if context.Bool("exit") {
opts.Exit = true
}
if imagePath != "" {
opts.ImagePath = imagePath
}
if workPath != "" {
opts.WorkPath = workPath
}
}
return nil
}
}
Loading

0 comments on commit fa20237

Please sign in to comment.