Skip to content

Commit eaf39c2

Browse files
committed
support nerdctl+containerd runtime (dapr#1232)
Signed-off-by: tianya <[email protected]>
1 parent a6f8c76 commit eaf39c2

File tree

5 files changed

+76
-33
lines changed

5 files changed

+76
-33
lines changed

cmd/init.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ var (
4848
var InitCmd = &cobra.Command{
4949
Use: "init",
5050
Short: "Install Dapr on supported hosting platforms. Supported platforms: Kubernetes and self-hosted",
51-
PreRun: func(cmd *cobra.Command, args []string) {
51+
PreRun: func(cmd *cobra.Command, _ []string) {
5252
viper.BindPFlag("network", cmd.Flags().Lookup("network"))
5353
viper.BindPFlag("image-registry", cmd.Flags().Lookup("image-registry"))
5454
},
@@ -87,7 +87,7 @@ dapr init --runtime-path <path-to-install-directory>
8787
8888
# See more at: https://docs.dapr.io/getting-started/
8989
`,
90-
Run: func(cmd *cobra.Command, args []string) {
90+
Run: func(*cobra.Command, []string) {
9191
print.PendingStatusEvent(os.Stdout, "Making the jump to hyperspace...")
9292
imageRegistryFlag := strings.TrimSpace(viper.GetString("image-registry"))
9393

@@ -148,7 +148,7 @@ dapr init --runtime-path <path-to-install-directory>
148148
}
149149

150150
if !utils.IsValidContainerRuntime(containerRuntime) {
151-
print.FailureStatusEvent(os.Stdout, "Invalid container runtime. Supported values are docker and podman.")
151+
print.FailureStatusEvent(os.Stdout, "Invalid container runtime. Supported values are docker and podman and containerd.")
152152
os.Exit(1)
153153
}
154154
err := standalone.Init(runtimeVersion, dashboardVersion, dockerNetwork, slimMode, imageRegistryURI, fromDir, containerRuntime, imageVariant, daprRuntimePath)
@@ -194,7 +194,7 @@ func init() {
194194
InitCmd.Flags().BoolP("help", "h", false, "Print this help message")
195195
InitCmd.Flags().StringArrayVar(&values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
196196
InitCmd.Flags().String("image-registry", "", "Custom/private docker image repository URL")
197-
InitCmd.Flags().StringVarP(&containerRuntime, "container-runtime", "", "docker", "The container runtime to use. Supported values are docker (default) and podman")
197+
InitCmd.Flags().StringVarP(&containerRuntime, "container-runtime", "", "docker", "The container runtime to use. Supported values are docker (default) and podman and containerd")
198198

199199
RootCmd.AddCommand(InitCmd)
200200
}

cmd/uninstall.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ dapr uninstall -k
5252
# This will remove the .dapr directory present in the path <path-to-install-directory>
5353
dapr uninstall --runtime-path <path-to-install-directory>
5454
`,
55-
PreRun: func(cmd *cobra.Command, args []string) {
55+
PreRun: func(cmd *cobra.Command, _ []string) {
5656
viper.BindPFlag("network", cmd.Flags().Lookup("network"))
5757
viper.BindPFlag("install-path", cmd.Flags().Lookup("install-path"))
5858
},
59-
Run: func(cmd *cobra.Command, args []string) {
59+
Run: func(*cobra.Command, []string) {
6060
var err error
6161

6262
if uninstallKubernetes {
@@ -69,7 +69,7 @@ dapr uninstall --runtime-path <path-to-install-directory>
6969
err = kubernetes.Uninstall(uninstallNamespace, uninstallAll, timeout)
7070
} else {
7171
if !utils.IsValidContainerRuntime(uninstallContainerRuntime) {
72-
print.FailureStatusEvent(os.Stdout, "Invalid container runtime. Supported values are docker and podman.")
72+
print.FailureStatusEvent(os.Stdout, "Invalid container runtime. Supported values are docker and podman and containerd.")
7373
os.Exit(1)
7474
}
7575
print.InfoStatusEvent(os.Stdout, "Removing Dapr from your machine...")
@@ -92,6 +92,6 @@ func init() {
9292
UninstallCmd.Flags().String("network", "", "The Docker network from which to remove the Dapr runtime")
9393
UninstallCmd.Flags().StringVarP(&uninstallNamespace, "namespace", "n", "dapr-system", "The Kubernetes namespace to uninstall Dapr from")
9494
UninstallCmd.Flags().BoolP("help", "h", false, "Print this help message")
95-
UninstallCmd.Flags().StringVarP(&uninstallContainerRuntime, "container-runtime", "", "docker", "The container runtime to use. Supported values are docker (default) and podman")
95+
UninstallCmd.Flags().StringVarP(&uninstallContainerRuntime, "container-runtime", "", "docker", "The container runtime to use. Supported values are docker (default) and podman and containerd")
9696
RootCmd.AddCommand(UninstallCmd)
9797
}

pkg/standalone/standalone.go

+22-15
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,9 @@ func Init(runtimeVersion, dashboardVersion string, dockerNetwork string, slimMod
161161
fromDir = strings.TrimSpace(fromDir)
162162
setAirGapInit(fromDir)
163163
if !slimMode {
164-
// If --slim installation is not requested, check if docker is installed.
165-
conatinerRuntimeAvailable := utils.IsDockerInstalled() || utils.IsPodmanInstalled()
166-
if !conatinerRuntimeAvailable {
167-
return errors.New("could not connect to Docker. Docker may not be installed or running")
164+
// If --slim installation is not requested, check if docker or podman or containerd is installed.
165+
if !utils.ContainerRuntimeAvailable() {
166+
return errors.New("could not connect to conatiner. Docker or podman or containerd may not be installed or running")
168167
}
169168

170169
// Initialize default registry only if any of --slim or --image-registry or --from-dir are not given.
@@ -363,10 +362,8 @@ func runZipkin(wg *sync.WaitGroup, errorChan chan<- error, info initInfo) {
363362
)
364363

365364
if info.dockerNetwork != "" {
366-
args = append(
367-
args,
368-
"--network", info.dockerNetwork,
369-
"--network-alias", DaprZipkinContainerName)
365+
networks := withContainerNetwork(info.containerRuntime, info.dockerNetwork, DaprZipkinContainerName)
366+
args = append(args, networks...)
370367
} else {
371368
args = append(
372369
args,
@@ -430,10 +427,8 @@ func runRedis(wg *sync.WaitGroup, errorChan chan<- error, info initInfo) {
430427
)
431428

432429
if info.dockerNetwork != "" {
433-
args = append(
434-
args,
435-
"--network", info.dockerNetwork,
436-
"--network-alias", DaprRedisContainerName)
430+
networks := withContainerNetwork(info.containerRuntime, info.dockerNetwork, DaprRedisContainerName)
431+
args = append(args, networks...)
437432
} else {
438433
args = append(
439434
args,
@@ -510,9 +505,8 @@ func runPlacementService(wg *sync.WaitGroup, errorChan chan<- error, info initIn
510505
}
511506

512507
if info.dockerNetwork != "" {
513-
args = append(args,
514-
"--network", info.dockerNetwork,
515-
"--network-alias", DaprPlacementContainerName)
508+
networks := withContainerNetwork(info.containerRuntime, info.dockerNetwork, DaprPlacementContainerName)
509+
args = append(args, networks...)
516510
} else {
517511
osPort := 50005
518512
if runtime.GOOS == daprWindowsOS {
@@ -1011,6 +1005,19 @@ func createDefaultConfiguration(zipkinHost, filePath string) error {
10111005
return err
10121006
}
10131007

1008+
// withContainerNetwork connect a container to a network.
1009+
// Network alias is now only parsed by docker,
1010+
// `podman` is only compatible with docker commands
1011+
// and does not really implement this feature.
1012+
// `containerd` does not support network alias.
1013+
func withContainerNetwork(containerCmd, network, containerName string) []string {
1014+
networks := []string{"--network", network}
1015+
if utils.GetContainerRuntimeCmd(containerCmd) == string(utils.DOCKER) {
1016+
networks = append(networks, "--network-alias", containerName)
1017+
}
1018+
return networks
1019+
}
1020+
10141021
func checkAndOverWriteFile(filePath string, b []byte) error {
10151022
_, err := os.Stat(filePath)
10161023
if os.IsNotExist(err) {

pkg/standalone/uninstall.go

+3-5
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,9 @@ func Uninstall(uninstallAll bool, dockerNetwork string, containerRuntime string,
9090
print.WarningStatusEvent(os.Stdout, "WARNING: could not delete dapr bin dir: %s", daprBinDir)
9191
}
9292

93-
containerRuntime = strings.TrimSpace(containerRuntime)
94-
runtimeCmd := utils.GetContainerRuntimeCmd(containerRuntime)
95-
conatinerRuntimeAvailable := false
96-
conatinerRuntimeAvailable = utils.IsDockerInstalled() || utils.IsPodmanInstalled()
97-
if conatinerRuntimeAvailable {
93+
if utils.ContainerRuntimeAvailable() {
94+
containerRuntime = strings.TrimSpace(containerRuntime)
95+
runtimeCmd := utils.GetContainerRuntimeCmd(containerRuntime)
9896
containerErrs = removeContainers(uninstallPlacementContainer, uninstallAll, dockerNetwork, runtimeCmd)
9997
}
10098

utils/utils.go

+43-5
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ import (
2424
"os"
2525
"os/exec"
2626
"path/filepath"
27+
"runtime"
2728
"strings"
29+
"sync"
2830
"time"
2931

3032
"github.com/dapr/cli/pkg/print"
@@ -38,25 +40,44 @@ import (
3840
type ContainerRuntime string
3941

4042
const (
41-
DOCKER ContainerRuntime = "docker"
42-
PODMAN ContainerRuntime = "podman"
43+
DOCKER ContainerRuntime = "docker"
44+
PODMAN ContainerRuntime = "podman"
45+
CONTAINERD ContainerRuntime = "containerd"
46+
47+
MACOS = runtime.GOOS == "darwin"
4348

4449
marinerImageVariantName = "mariner"
4550

4651
socketFormat = "%s/dapr-%s-%s.socket"
4752
)
4853

54+
var (
55+
cacheOnce sync.Once
56+
supportMacos bool
57+
)
58+
59+
var supportRuntime = func(containerRuntime string) bool {
60+
cacheOnce.Do(func() {
61+
supportMacos = containerRuntime == string(CONTAINERD) && !MACOS
62+
})
63+
return supportMacos
64+
}
65+
4966
// IsValidContainerRuntime checks if the input is a valid container runtime.
50-
// Valid container runtimes are docker and podman.
67+
// Valid container runtimes are docker and podman and containerd.
5168
func IsValidContainerRuntime(containerRuntime string) bool {
5269
containerRuntime = strings.TrimSpace(containerRuntime)
53-
return containerRuntime == string(DOCKER) || containerRuntime == string(PODMAN)
70+
return containerRuntime == string(DOCKER) || containerRuntime == string(PODMAN) || supportRuntime(containerRuntime)
5471
}
5572

5673
// GetContainerRuntimeCmd returns a valid container runtime to be used by CLI operations.
57-
// If the input is a valid container runtime, it is returned as is.
74+
// If the input is a valid container runtime, it is returned client tool.
5875
// Otherwise the default container runtime, docker, is returned.
5976
func GetContainerRuntimeCmd(containerRuntime string) string {
77+
// containerd runtime use nerdctl tool.
78+
if supportRuntime(containerRuntime) {
79+
return "nerdctl"
80+
}
6081
if IsValidContainerRuntime(containerRuntime) {
6182
return strings.TrimSpace(containerRuntime)
6283
}
@@ -188,6 +209,23 @@ func IsPodmanInstalled() bool {
188209
return true
189210
}
190211

212+
// IsContainerdInstalled checks whether nerdctl and containerd is installed/running.
213+
func IsContainerdInstalled() bool {
214+
if MACOS {
215+
print.FailureStatusEvent(os.Stderr, "containerd is not supported on macos")
216+
return false
217+
}
218+
if _, err := RunCmdAndWait("nerdctl", "info"); err != nil {
219+
print.FailureStatusEvent(os.Stderr, err.Error())
220+
return false
221+
}
222+
return true
223+
}
224+
225+
func ContainerRuntimeAvailable() bool {
226+
return IsDockerInstalled() || IsPodmanInstalled() || IsContainerdInstalled()
227+
}
228+
191229
// IsDaprListeningOnPort checks if Dapr is litening to a given port.
192230
func IsDaprListeningOnPort(port int, timeout time.Duration) error {
193231
start := time.Now()

0 commit comments

Comments
 (0)