1// +build !windows
2
3/*
4   Copyright The containerd Authors.
5
6   Licensed under the Apache License, Version 2.0 (the "License");
7   you may not use this file except in compliance with the License.
8   You may obtain a copy of the License at
9
10       http://www.apache.org/licenses/LICENSE-2.0
11
12   Unless required by applicable law or agreed to in writing, software
13   distributed under the License is distributed on an "AS IS" BASIS,
14   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   See the License for the specific language governing permissions and
16   limitations under the License.
17*/
18
19package containerd
20
21import (
22	"context"
23
24	"github.com/containerd/containerd/runtime/linux/runctypes"
25	"github.com/containerd/containerd/runtime/v2/runc/options"
26	"github.com/pkg/errors"
27)
28
29// WithNoNewKeyring causes tasks not to be created with a new keyring for secret storage.
30// There is an upper limit on the number of keyrings in a linux system
31func WithNoNewKeyring(ctx context.Context, c *Client, ti *TaskInfo) error {
32	if CheckRuntime(ti.Runtime(), "io.containerd.runc") {
33		if ti.Options == nil {
34			ti.Options = &options.Options{}
35		}
36		opts, ok := ti.Options.(*options.Options)
37		if !ok {
38			return errors.New("invalid v2 shim create options format")
39		}
40		opts.NoNewKeyring = true
41	} else {
42		if ti.Options == nil {
43			ti.Options = &runctypes.CreateOptions{}
44		}
45		opts, ok := ti.Options.(*runctypes.CreateOptions)
46		if !ok {
47			return errors.New("could not cast TaskInfo Options to CreateOptions")
48		}
49		opts.NoNewKeyring = true
50	}
51	return nil
52}
53
54// WithNoPivotRoot instructs the runtime not to you pivot_root
55func WithNoPivotRoot(_ context.Context, _ *Client, ti *TaskInfo) error {
56	if CheckRuntime(ti.Runtime(), "io.containerd.runc") {
57		if ti.Options == nil {
58			ti.Options = &options.Options{}
59		}
60		opts, ok := ti.Options.(*options.Options)
61		if !ok {
62			return errors.New("invalid v2 shim create options format")
63		}
64		opts.NoPivotRoot = true
65	} else {
66		if ti.Options == nil {
67			ti.Options = &runctypes.CreateOptions{
68				NoPivotRoot: true,
69			}
70			return nil
71		}
72		opts, ok := ti.Options.(*runctypes.CreateOptions)
73		if !ok {
74			return errors.New("invalid options type, expected runctypes.CreateOptions")
75		}
76		opts.NoPivotRoot = true
77	}
78	return nil
79}
80
81// WithShimCgroup sets the existing cgroup for the shim
82func WithShimCgroup(path string) NewTaskOpts {
83	return func(ctx context.Context, c *Client, ti *TaskInfo) error {
84		if CheckRuntime(ti.Runtime(), "io.containerd.runc") {
85			if ti.Options == nil {
86				ti.Options = &options.Options{}
87			}
88			opts, ok := ti.Options.(*options.Options)
89			if !ok {
90				return errors.New("invalid v2 shim create options format")
91			}
92			opts.ShimCgroup = path
93		} else {
94			if ti.Options == nil {
95				ti.Options = &runctypes.CreateOptions{}
96			}
97			opts, ok := ti.Options.(*runctypes.CreateOptions)
98			if !ok {
99				return errors.New("could not cast TaskInfo Options to CreateOptions")
100			}
101			opts.ShimCgroup = path
102		}
103		return nil
104	}
105}
106
107// WithUIDOwner allows console I/O to work with the remapped UID in user namespace
108func WithUIDOwner(uid uint32) NewTaskOpts {
109	return func(ctx context.Context, c *Client, ti *TaskInfo) error {
110		if CheckRuntime(ti.Runtime(), "io.containerd.runc") {
111			if ti.Options == nil {
112				ti.Options = &options.Options{}
113			}
114			opts, ok := ti.Options.(*options.Options)
115			if !ok {
116				return errors.New("invalid v2 shim create options format")
117			}
118			opts.IoUid = uid
119		} else {
120			if ti.Options == nil {
121				ti.Options = &runctypes.CreateOptions{}
122			}
123			opts, ok := ti.Options.(*runctypes.CreateOptions)
124			if !ok {
125				return errors.New("could not cast TaskInfo Options to CreateOptions")
126			}
127			opts.IoUid = uid
128		}
129		return nil
130	}
131}
132
133// WithGIDOwner allows console I/O to work with the remapped GID in user namespace
134func WithGIDOwner(gid uint32) NewTaskOpts {
135	return func(ctx context.Context, c *Client, ti *TaskInfo) error {
136		if CheckRuntime(ti.Runtime(), "io.containerd.runc") {
137			if ti.Options == nil {
138				ti.Options = &options.Options{}
139			}
140			opts, ok := ti.Options.(*options.Options)
141			if !ok {
142				return errors.New("invalid v2 shim create options format")
143			}
144			opts.IoGid = gid
145		} else {
146			if ti.Options == nil {
147				ti.Options = &runctypes.CreateOptions{}
148			}
149			opts, ok := ti.Options.(*runctypes.CreateOptions)
150			if !ok {
151				return errors.New("could not cast TaskInfo Options to CreateOptions")
152			}
153			opts.IoGid = gid
154		}
155		return nil
156	}
157}
158