Skip to content

Commit

Permalink
Merge pull request #1 from artursouza/update_cli_scheduler
Browse files Browse the repository at this point in the history
Fixes install and uninstall of scheduler in standalone mode.
  • Loading branch information
cicoyle authored Jun 8, 2024
2 parents cc5016d + 9b408e2 commit 153619a
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 70 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
*.dylib
cli

# Handy directory to keep local scripts and help files.
.local/

# Mac's metadata folder
.DS_Store

Expand Down Expand Up @@ -37,4 +40,4 @@ go.work
#Wix files
*.wixobj
*.wixpdb
*.msi
*.msi
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ require (
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Masterminds/squirrel v1.5.3 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
Expand Down
12 changes: 2 additions & 10 deletions pkg/standalone/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,10 @@ func isStringNilOrEmpty(val *string) bool {
return val == nil || strings.TrimSpace(*val) == ""
}

func (b *bundleDetails) getPlacementImageName() string {
func (b *bundleDetails) getDaprImageName() string {
return *b.DaprImageName
}

func (b *bundleDetails) getPlacementImageFileName() string {
return *b.DaprImageFileName
}

func (b *bundleDetails) getSchedulerImageName() string {
return *b.DaprImageName
}

func (b *bundleDetails) getSchedulerImageFileName() string {
func (b *bundleDetails) getDaprImageFileName() string {
return *b.DaprImageFileName
}
4 changes: 2 additions & 2 deletions pkg/standalone/bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ func TestParseDetails(t *testing.T) {
assert.Equal(t, "0.10.0", *bd.DashboardVersion, "expected versions to match")
assert.Equal(t, "dist", *bd.BinarySubDir, "expected value to match")
assert.Equal(t, "docker", *bd.ImageSubDir, "expected value to match")
assert.Equal(t, "daprio/dapr:1.7.2", bd.getPlacementImageName(), "expected value to match")
assert.Equal(t, "daprio-dapr-1.7.2.tar.gz", bd.getPlacementImageFileName(), "expected value to match")
assert.Equal(t, "daprio/dapr:1.7.2", bd.getDaprImageName(), "expected value to match")
assert.Equal(t, "daprio-dapr-1.7.2.tar.gz", bd.getDaprImageFileName(), "expected value to match")
}

func TestParseDetailsMissingDetails(t *testing.T) {
Expand Down
17 changes: 15 additions & 2 deletions pkg/standalone/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"os"
path_filepath "path/filepath"
"runtime"
"strconv"
"strings"
)

Expand All @@ -25,8 +26,10 @@ const (
DefaultConfigFileName = "config.yaml"
DefaultResourcesDirName = "resources"

defaultDaprBinDirName = "bin"
defaultComponentsDirName = "components"
defaultDaprBinDirName = "bin"
defaultComponentsDirName = "components"
defaultSchedulerDirName = "scheduler"
defaultSchedulerDataDirName = "data"
)

// GetDaprRuntimePath returns the dapr runtime installation path.
Expand Down Expand Up @@ -58,6 +61,16 @@ func getDaprBinPath(daprDir string) string {
return path_filepath.Join(daprDir, defaultDaprBinDirName)
}

// getSchedulerDataPath returns the data path of a given instance
// Receiving instanceID allows multiple instances of scheduler to run locally in the future.
func getSchedulerDataPath(daprDir string, instanceID int) string {
return path_filepath.Join(
daprDir,
defaultSchedulerDirName,
defaultSchedulerDataDirName,
strconv.Itoa(instanceID))
}

func binaryFilePathWithDir(binaryDir string, binaryFilePrefix string) string {
binaryPath := path_filepath.Join(binaryDir, binaryFilePrefix)
if runtime.GOOS == daprWindowsOS {
Expand Down
4 changes: 4 additions & 0 deletions pkg/standalone/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,10 @@ func (config *RunConfig) Validate() error {
}

err = config.validatePlacementHostAddr()
if err != nil {
return err
}

err = config.validateSchedulerHostAddr()

if err != nil {
Expand Down
120 changes: 65 additions & 55 deletions pkg/standalone/standalone.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"sync"
"time"

"github.com/Masterminds/semver"
"github.com/fatih/color"
"gopkg.in/yaml.v2"

Expand Down Expand Up @@ -85,8 +86,11 @@ const (
healthPort = 58080
metricPort = 59090

schedulerHealthPort = 58181
schedulerMetricPort = 59191
schedulerHealthPort = 58081
schedulerMetricPort = 59091
schedulerEtcdPort = 52379

daprVersionsWithScheduler = ">= 1.13.x"
)

var (
Expand Down Expand Up @@ -160,6 +164,21 @@ func isBinaryInstallationRequired(binaryFilePrefix, binInstallDir string) (bool,
return true, nil
}

// isSchedulerIncluded returns true if scheduler is included a given version for Dapr.
func isSchedulerIncluded(runtimeVersion string) (bool, error) {
c, err := semver.NewConstraint(daprVersionsWithScheduler)
if err != nil {
return false, err
}

v, err := semver.NewVersion(runtimeVersion)
if err != nil {
return false, err
}

return c.Check(v), nil
}

// Init installs Dapr on a local machine using the supplied runtimeVersion.
func Init(runtimeVersion, dashboardVersion string, dockerNetwork string, slimMode bool, imageRegistryURL string, fromDir string, containerRuntime string, imageVariant string, daprInstallPath string) error {
var err error
Expand Down Expand Up @@ -313,10 +332,14 @@ func Init(runtimeVersion, dashboardVersion string, dockerNetwork string, slimMod
print.InfoStatusEvent(os.Stdout, "%s binary has been installed to %s.", schedulerServiceFilePrefix, daprBinDir)
} else {
runtimeCmd := utils.GetContainerRuntimeCmd(info.containerRuntime)
dockerContainerNames := []string{DaprPlacementContainerName, DaprSchedulerContainerName, DaprRedisContainerName, DaprZipkinContainerName}
dockerContainerNames := []string{DaprPlacementContainerName, DaprRedisContainerName, DaprZipkinContainerName}
// Skip redis and zipkin in local installation mode.
if isAirGapInit {
dockerContainerNames = []string{DaprPlacementContainerName, DaprSchedulerContainerName}
dockerContainerNames = []string{DaprPlacementContainerName}
}
hasScheduler, err := isSchedulerIncluded(info.runtimeVersion)
if err == nil && hasScheduler {
dockerContainerNames = append(dockerContainerNames, DaprSchedulerContainerName)
}
for _, container := range dockerContainerNames {
containerName := utils.CreateContainerName(container, dockerNetwork)
Expand Down Expand Up @@ -498,15 +521,15 @@ func runPlacementService(wg *sync.WaitGroup, errorChan chan<- error, info initIn
if isAirGapInit {
// if --from-dir flag is given load the image details from the installer-bundle.
dir := path_filepath.Join(info.fromDir, *info.bundleDet.ImageSubDir)
image = info.bundleDet.getPlacementImageName()
err = loadContainer(dir, info.bundleDet.getPlacementImageFileName(), info.containerRuntime)
image = info.bundleDet.getDaprImageName()
err = loadContainer(dir, info.bundleDet.getDaprImageFileName(), info.containerRuntime)
if err != nil {
errorChan <- err
return
}
} else {
// otherwise load the image from the specified repository.
image, err = getPlacementImageName(imgInfo, info)
image, err = getDaprImageName(imgInfo, info)
if err != nil {
errorChan <- err
return
Expand Down Expand Up @@ -561,6 +584,15 @@ func runSchedulerService(wg *sync.WaitGroup, errorChan chan<- error, info initIn
return
}

hasScheduler, err := isSchedulerIncluded(info.runtimeVersion)
if err != nil {
errorChan <- err
return
}
if !hasScheduler {
return
}

runtimeCmd := utils.GetContainerRuntimeCmd(info.containerRuntime)
schedulerContainerName := utils.CreateContainerName(DaprSchedulerContainerName, info.dockerNetwork)

Expand All @@ -585,27 +617,30 @@ func runSchedulerService(wg *sync.WaitGroup, errorChan chan<- error, info initIn
if isAirGapInit {
// if --from-dir flag is given load the image details from the installer-bundle.
dir := path_filepath.Join(info.fromDir, *info.bundleDet.ImageSubDir)
image = info.bundleDet.getSchedulerImageName()
err = loadContainer(dir, info.bundleDet.getSchedulerImageFileName(), info.containerRuntime)
image = info.bundleDet.getDaprImageName()
err = loadContainer(dir, info.bundleDet.getDaprImageFileName(), info.containerRuntime)
if err != nil {
errorChan <- err
return
}
} else {
// otherwise load the image from the specified repository.
image, err = getSchedulerImageName(imgInfo, info)
image, err = getDaprImageName(imgInfo, info)
if err != nil {
errorChan <- err
return
}
}

// instanceID is 0 because we run one instance only for now.
schedulerDataDir := getSchedulerDataPath(info.installDir, 0)
args := []string{
"run",
"--name", schedulerContainerName,
"--restart", "always",
"-d",
"--entrypoint", "./scheduler",
"--volume", fmt.Sprintf("%v:/data-default-dapr-scheduler-server-0", schedulerDataDir),
}

if info.dockerNetwork != "" {
Expand All @@ -615,13 +650,14 @@ func runSchedulerService(wg *sync.WaitGroup, errorChan chan<- error, info initIn
} else {
osPort := 50006
if runtime.GOOS == daprWindowsOS {
osPort = 6060 //TODO confirm this
osPort = 6060
}

args = append(args,
"-p", fmt.Sprintf("%v:50006", osPort),
"-p", fmt.Sprintf("%v:8081", schedulerHealthPort), //TODO confirm this
"-p", fmt.Sprintf("%v:9091", schedulerMetricPort), //TODO confirm this
"-p", fmt.Sprintf("%v:2379", schedulerEtcdPort),
"-p", fmt.Sprintf("%v:8080", schedulerHealthPort),
"-p", fmt.Sprintf("%v:9090", schedulerMetricPort),
)
}

Expand Down Expand Up @@ -712,7 +748,16 @@ func installScheduler(wg *sync.WaitGroup, errorChan chan<- error, info initInfo)
return
}

err := installBinary(info.runtimeVersion, schedulerServiceFilePrefix, cli_ver.DaprGitHubRepo, info)
hasScheduler, err := isSchedulerIncluded(info.runtimeVersion)
if err != nil {
errorChan <- err
return
}
if !hasScheduler {
return
}

err = installBinary(info.runtimeVersion, schedulerServiceFilePrefix, cli_ver.DaprGitHubRepo, info)
if err != nil {
errorChan <- err
}
Expand Down Expand Up @@ -1298,68 +1343,33 @@ func copyWithTimeout(ctx context.Context, dst io.Writer, src io.Reader) (int64,
}
}

// getPlacementImageName returns the resolved placement image name for online `dapr init`.
// getDaprImageName returns the resolved Dapr image name for online `dapr init`.
// It can either be resolved to the image-registry if given, otherwise GitHub container registry if
// selected or fallback to Docker Hub.
func getPlacementImageName(imageInfo daprImageInfo, info initInfo) (string, error) {
func getDaprImageName(imageInfo daprImageInfo, info initInfo) (string, error) {
image, err := resolveImageURI(imageInfo)
if err != nil {
return "", err
}

image, err = getPlacementImageWithTag(image, info.runtimeVersion, info.imageVariant)
image, err = getDaprImageWithTag(image, info.runtimeVersion, info.imageVariant)
if err != nil {
return "", err
}

// if default registry is GHCR and the image is not available in or cannot be pulled from GHCR
// fallback to using dockerhub.
if useGHCR(imageInfo, info.fromDir) && !tryPullImage(image, info.containerRuntime) {
print.InfoStatusEvent(os.Stdout, "Placement image not found in Github container registry, pulling it from Docker Hub")
image, err = getPlacementImageWithTag(daprDockerImageName, info.runtimeVersion, info.imageVariant)
print.InfoStatusEvent(os.Stdout, "Image not found in Github container registry, pulling it from Docker Hub")
image, err = getDaprImageWithTag(daprDockerImageName, info.runtimeVersion, info.imageVariant)
if err != nil {
return "", err
}
}
return image, nil
}

// getSchedulerImageName returns the resolved scheduler image name for online `dapr init`.
// It can either be resolved to the image-registry if given, otherwise GitHub container registry if
// selected or fallback to Docker Hub.
func getSchedulerImageName(imageInfo daprImageInfo, info initInfo) (string, error) {
image, err := resolveImageURI(imageInfo)
if err != nil {
return "", err
}

image, err = getSchedulerImageWithTag(image, info.runtimeVersion, info.imageVariant)
if err != nil {
return "", err
}

// if default registry is GHCR and the image is not available in or cannot be pulled from GHCR
// fallback to using dockerhub.
if useGHCR(imageInfo, info.fromDir) && !tryPullImage(image, info.containerRuntime) {
print.InfoStatusEvent(os.Stdout, "Scheduler image not found in Github container registry, pulling it from Docker Hub")
image, err = getSchedulerImageWithTag(daprDockerImageName, info.runtimeVersion, info.imageVariant)
if err != nil {
return "", err
}
}
return image, nil
}

func getPlacementImageWithTag(name, version, imageVariant string) (string, error) {
err := utils.ValidateImageVariant(imageVariant)
if err != nil {
return "", err
}
version = utils.GetVariantVersion(version, imageVariant)
return fmt.Sprintf("%s:%s", name, version), nil
}

func getSchedulerImageWithTag(name, version, imageVariant string) (string, error) {
func getDaprImageWithTag(name, version, imageVariant string) (string, error) {
err := utils.ValidateImageVariant(imageVariant)
if err != nil {
return "", err
Expand Down
3 changes: 3 additions & 0 deletions pkg/standalone/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ func Uninstall(uninstallAll bool, dockerNetwork string, containerRuntime string,
if err != nil {
print.WarningStatusEvent(os.Stdout, "WARNING: could not delete dapr bin dir: %s", daprBinDir)
}
// We don't delete .dapr/scheduler by choice since it holds state.
// To delete .dapr/scheduler, user is expected to use the `--all` flag as it deletes the .dapr folder.
// The same happens for .dapr/components folder.

containerRuntime = strings.TrimSpace(containerRuntime)
runtimeCmd := utils.GetContainerRuntimeCmd(containerRuntime)
Expand Down

0 comments on commit 153619a

Please sign in to comment.