Skip to content
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
49433fe
support nerdctl+containerd runtime (#1232)
tianyax Feb 24, 2023
33e17ee
add containerd runtime validity check and fix test errors
tianyax Feb 25, 2023
cbcb2af
reduce unnecessary container runtime availability checks
tianyax Feb 27, 2023
9200b3d
fixed test failed on macos
tianyax Feb 27, 2023
a3341a6
update help message
tianyax Feb 27, 2023
a3fdee0
use the string nerdctl as a constant
tianyax Feb 27, 2023
003646e
revert containerd support on macos
tianyax Feb 28, 2023
ed91064
update README
tianyax Feb 28, 2023
ebdb471
Merge branch 'master' into containerd-runtime
pravinpushkar Feb 28, 2023
4b9d430
Merge remote-tracking branch 'master' into containerd-runtime
tianyax Mar 2, 2023
70ca0d1
Merge branch 'master' into containerd-runtime
tianyax Mar 2, 2023
968654c
Merge branch 'master' into containerd-runtime
tianyax Mar 2, 2023
6c4c6f8
fixed args missing
tianyax Mar 2, 2023
12a5070
Merge branch 'master' into containerd-runtime
mukundansundar Mar 16, 2023
a76ba30
Merge branch 'master' into containerd-runtime
tianyax Mar 17, 2023
5abfe55
Apply suggestions from code review
tianyax Mar 22, 2023
093dbc5
update runtime installation in README
tianyax Mar 22, 2023
db2a515
add e2e tests with containerd
tianyax Mar 26, 2023
4c8afdf
Merge branch 'master' into containerd-runtime
shubham1172 Mar 26, 2023
3e193c8
Merge branch 'master' into containerd-runtime
pravinpushkar Apr 3, 2023
9525a1c
Merge branch 'master' into containerd-runtime
mukundansundar Apr 5, 2023
8164923
fixed the issue in e2e tests
tianyax Apr 13, 2023
c22aa11
Merge branch 'master' into containerd-runtime
pravinpushkar Apr 20, 2023
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
8 changes: 4 additions & 4 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ var (
var InitCmd = &cobra.Command{
Use: "init",
Short: "Install Dapr on supported hosting platforms. Supported platforms: Kubernetes and self-hosted",
PreRun: func(cmd *cobra.Command, args []string) {
PreRun: func(cmd *cobra.Command, _ []string) {
viper.BindPFlag("network", cmd.Flags().Lookup("network"))
viper.BindPFlag("image-registry", cmd.Flags().Lookup("image-registry"))
},
Expand Down Expand Up @@ -87,7 +87,7 @@ dapr init --runtime-path <path-to-install-directory>

# See more at: https://docs.dapr.io/getting-started/
`,
Run: func(cmd *cobra.Command, args []string) {
Run: func(*cobra.Command, []string) {
print.PendingStatusEvent(os.Stdout, "Making the jump to hyperspace...")
imageRegistryFlag := strings.TrimSpace(viper.GetString("image-registry"))

Expand Down Expand Up @@ -148,7 +148,7 @@ dapr init --runtime-path <path-to-install-directory>
}

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

RootCmd.AddCommand(InitCmd)
}
8 changes: 4 additions & 4 deletions cmd/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ dapr uninstall -k
# This will remove the .dapr directory present in the path <path-to-install-directory>
dapr uninstall --runtime-path <path-to-install-directory>
`,
PreRun: func(cmd *cobra.Command, args []string) {
PreRun: func(cmd *cobra.Command, _ []string) {
viper.BindPFlag("network", cmd.Flags().Lookup("network"))
viper.BindPFlag("install-path", cmd.Flags().Lookup("install-path"))
},
Run: func(cmd *cobra.Command, args []string) {
Run: func(*cobra.Command, []string) {
var err error

if uninstallKubernetes {
Expand All @@ -69,7 +69,7 @@ dapr uninstall --runtime-path <path-to-install-directory>
err = kubernetes.Uninstall(uninstallNamespace, uninstallAll, timeout)
} else {
if !utils.IsValidContainerRuntime(uninstallContainerRuntime) {
print.FailureStatusEvent(os.Stdout, "Invalid container runtime. Supported values are docker and podman.")
print.FailureStatusEvent(os.Stdout, "Invalid container runtime. Supported values are docker, podman and containerd.")
os.Exit(1)
}
print.InfoStatusEvent(os.Stdout, "Removing Dapr from your machine...")
Expand All @@ -92,6 +92,6 @@ func init() {
UninstallCmd.Flags().String("network", "", "The Docker network from which to remove the Dapr runtime")
UninstallCmd.Flags().StringVarP(&uninstallNamespace, "namespace", "n", "dapr-system", "The Kubernetes namespace to uninstall Dapr from")
UninstallCmd.Flags().BoolP("help", "h", false, "Print this help message")
UninstallCmd.Flags().StringVarP(&uninstallContainerRuntime, "container-runtime", "", "docker", "The container runtime to use. Supported values are docker (default) and podman")
UninstallCmd.Flags().StringVarP(&uninstallContainerRuntime, "container-runtime", "", "docker", "The container runtime to use. Supported values are docker (default), podman and containerd")
RootCmd.AddCommand(UninstallCmd)
}
37 changes: 22 additions & 15 deletions pkg/standalone/standalone.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,9 @@ func Init(runtimeVersion, dashboardVersion string, dockerNetwork string, slimMod
fromDir = strings.TrimSpace(fromDir)
setAirGapInit(fromDir)
if !slimMode {
// If --slim installation is not requested, check if docker is installed.
conatinerRuntimeAvailable := utils.IsDockerInstalled() || utils.IsPodmanInstalled()
if !conatinerRuntimeAvailable {
return errors.New("could not connect to Docker. Docker may not be installed or running")
// If --slim installation is not requested, check if docker or podman or containerd is installed.
if !utils.ContainerRuntimeAvailable(containerRuntime) {
return fmt.Errorf("could not connect to container. %v may not be installed or running", containerRuntime)
}

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

if info.dockerNetwork != "" {
args = append(
args,
"--network", info.dockerNetwork,
"--network-alias", DaprZipkinContainerName)
networks := withContainerNetwork(info.containerRuntime, info.dockerNetwork, DaprZipkinContainerName)
args = append(args, networks...)
} else {
args = append(
args,
Expand Down Expand Up @@ -430,10 +427,8 @@ func runRedis(wg *sync.WaitGroup, errorChan chan<- error, info initInfo) {
)

if info.dockerNetwork != "" {
args = append(
args,
"--network", info.dockerNetwork,
"--network-alias", DaprRedisContainerName)
networks := withContainerNetwork(info.containerRuntime, info.dockerNetwork, DaprRedisContainerName)
args = append(args, networks...)
} else {
args = append(
args,
Expand Down Expand Up @@ -510,9 +505,8 @@ func runPlacementService(wg *sync.WaitGroup, errorChan chan<- error, info initIn
}

if info.dockerNetwork != "" {
args = append(args,
"--network", info.dockerNetwork,
"--network-alias", DaprPlacementContainerName)
networks := withContainerNetwork(info.containerRuntime, info.dockerNetwork, DaprPlacementContainerName)
args = append(args, networks...)
} else {
osPort := 50005
if runtime.GOOS == daprWindowsOS {
Expand Down Expand Up @@ -1011,6 +1005,19 @@ func createDefaultConfiguration(zipkinHost, filePath string) error {
return err
}

// withContainerNetwork connect a container to a network.
// Network alias is now only parsed by docker,
// `podman` is only compatible with docker commands
// and does not really implement this feature.
// `containerd` does not support network alias.
func withContainerNetwork(containerCmd, network, containerName string) []string {
networks := []string{"--network", network}
if utils.GetContainerRuntimeCmd(containerCmd) == string(utils.DOCKER) {
networks = append(networks, "--network-alias", containerName)
}
return networks
}

func checkAndOverWriteFile(filePath string, b []byte) error {
_, err := os.Stat(filePath)
if os.IsNotExist(err) {
Expand Down
8 changes: 3 additions & 5 deletions pkg/standalone/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,9 @@ func Uninstall(uninstallAll bool, dockerNetwork string, containerRuntime string,
print.WarningStatusEvent(os.Stdout, "WARNING: could not delete dapr bin dir: %s", daprBinDir)
}

containerRuntime = strings.TrimSpace(containerRuntime)
runtimeCmd := utils.GetContainerRuntimeCmd(containerRuntime)
conatinerRuntimeAvailable := false
conatinerRuntimeAvailable = utils.IsDockerInstalled() || utils.IsPodmanInstalled()
if conatinerRuntimeAvailable {
if utils.ContainerRuntimeAvailable(containerRuntime) {
containerRuntime = strings.TrimSpace(containerRuntime)
runtimeCmd := utils.GetContainerRuntimeCmd(containerRuntime)
containerErrs = removeContainers(uninstallPlacementContainer, uninstallAll, dockerNetwork, runtimeCmd)
}

Expand Down
49 changes: 44 additions & 5 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"time"

Expand All @@ -38,25 +39,38 @@ import (
type ContainerRuntime string

const (
DOCKER ContainerRuntime = "docker"
PODMAN ContainerRuntime = "podman"
DOCKER ContainerRuntime = "docker"
PODMAN ContainerRuntime = "podman"
CONTAINERD ContainerRuntime = "containerd"

NERDCTL = "nerdctl"
MACOS = runtime.GOOS == "darwin"

marinerImageVariantName = "mariner"

socketFormat = "%s/dapr-%s-%s.socket"
)

var IsValidRuntimeOnMacos = func(containerRuntime string) bool {
containerRuntime = strings.TrimSpace(containerRuntime)
return containerRuntime == string(CONTAINERD) && !MACOS
}

// IsValidContainerRuntime checks if the input is a valid container runtime.
// Valid container runtimes are docker and podman.
// Valid container runtimes are docker and podman and containerd.
func IsValidContainerRuntime(containerRuntime string) bool {
containerRuntime = strings.TrimSpace(containerRuntime)
return containerRuntime == string(DOCKER) || containerRuntime == string(PODMAN)
return containerRuntime == string(DOCKER) || containerRuntime == string(PODMAN) || IsValidRuntimeOnMacos(containerRuntime)
}

// GetContainerRuntimeCmd returns a valid container runtime to be used by CLI operations.
// If the input is a valid container runtime, it is returned as is.
// If the input is a valid container runtime, it is returned client tool.
// Otherwise the default container runtime, docker, is returned.
func GetContainerRuntimeCmd(containerRuntime string) string {
// containerd runtime use nerdctl tool.
if IsValidRuntimeOnMacos(containerRuntime) {
return NERDCTL
}
if IsValidContainerRuntime(containerRuntime) {
return strings.TrimSpace(containerRuntime)
}
Expand Down Expand Up @@ -188,6 +202,31 @@ func IsPodmanInstalled() bool {
return true
}

// IsContainerdInstalled checks whether nerdctl and containerd is installed/running.
func IsContainerdInstalled() bool {
if MACOS {
print.FailureStatusEvent(os.Stderr, "containerd is not supported on macos")
return false
}
if _, err := RunCmdAndWait("nerdctl", "info"); err != nil {
print.FailureStatusEvent(os.Stderr, err.Error())
return false
}
return true
}

func ContainerRuntimeAvailable(containerRuntime string) bool {
containerRuntime = strings.TrimSpace(containerRuntime)
switch ContainerRuntime(containerRuntime) {
case PODMAN:
return IsPodmanInstalled()
case CONTAINERD:
return IsContainerdInstalled()
default:
return IsDockerInstalled()
}
}

// IsDaprListeningOnPort checks if Dapr is litening to a given port.
func IsDaprListeningOnPort(port int, timeout time.Duration) error {
start := time.Now()
Expand Down
26 changes: 24 additions & 2 deletions utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,30 @@ import (
)

func TestContainerRuntimeUtils(t *testing.T) {
containerCmd := func() string {
if !MACOS {
return "nerdctl"
}
return "docker"
}()
testcases := []struct {
name string
input string
expected string
valid bool
}{
{
name: "containerd runtime is valid, and nerdctl is returned",
input: "containerd",
expected: containerCmd,
valid: !MACOS,
},
{
name: "containerd runtime with extra spaces is valid, and nerdctl is returned",
input: " containerd ",
expected: containerCmd,
valid: !MACOS,
},
{
name: "podman runtime is valid, and is returned as is",
input: "podman",
Expand Down Expand Up @@ -176,7 +194,9 @@ func TestGetVersionAndImageVariant(t *testing.T) {

func TestValidateFilePaths(t *testing.T) {
dirName := createTempDir(t, "test_validate_paths")
defer cleanupTempDir(t, dirName)
t.Cleanup(func() {
cleanupTempDir(t, dirName)
})
validFile := createTempFile(t, dirName, "valid_test_file.yaml")
testcases := []struct {
name string
Expand Down Expand Up @@ -254,7 +274,9 @@ func TestGetAbsPath(t *testing.T) {

func TestReadFile(t *testing.T) {
fileName := createTempFile(t, "", "test_read_file")
defer cleanupTempDir(t, fileName)
t.Cleanup(func() {
cleanupTempDir(t, fileName)
})
testcases := []struct {
name string
input string
Expand Down