From 1633b049218b2f9be447fe42871e0ed3e0823767 Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Tue, 13 Jun 2023 18:25:14 +0530 Subject: [PATCH 01/14] windows impl for multiapp run Signed-off-by: Pravin Pushkar --- cmd/run.go | 4 ---- cmd/stop.go | 5 ----- pkg/standalone/stop_windows.go | 34 +++++++++++++++++++++++----------- pkg/syscall/syscall_windows.go | 4 ++-- 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/cmd/run.go b/cmd/run.go index f664a7eef..268e05dec 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -112,10 +112,6 @@ dapr run --run-file /path/to/directory }, Run: func(cmd *cobra.Command, args []string) { if len(runFilePath) > 0 { - if runtime.GOOS == string(windowsOsType) { - print.FailureStatusEvent(os.Stderr, "The run command with run file is not supported on Windows") - os.Exit(1) - } runConfigFilePath, err := getRunFilePath(runFilePath) if err != nil { print.FailureStatusEvent(os.Stderr, "Failed to get run file path: %v", err) diff --git a/cmd/stop.go b/cmd/stop.go index bdfe8be48..3540bac90 100644 --- a/cmd/stop.go +++ b/cmd/stop.go @@ -17,7 +17,6 @@ import ( "fmt" "os" "path/filepath" - "runtime" "github.com/spf13/cobra" @@ -43,10 +42,6 @@ dapr stop --run-file /path/to/directory Run: func(cmd *cobra.Command, args []string) { var err error if len(runFilePath) > 0 { - if runtime.GOOS == string(windowsOsType) { - print.FailureStatusEvent(os.Stderr, "Stop command with run file is not supported on Windows") - os.Exit(1) - } runFilePath, err = getRunFilePath(runFilePath) if err != nil { print.FailureStatusEvent(os.Stderr, "Failed to get run file path: %v", err) diff --git a/pkg/standalone/stop_windows.go b/pkg/standalone/stop_windows.go index b12bc5c58..6e6942d40 100644 --- a/pkg/standalone/stop_windows.go +++ b/pkg/standalone/stop_windows.go @@ -14,7 +14,6 @@ limitations under the License. package standalone import ( - "errors" "fmt" "syscall" @@ -25,20 +24,33 @@ import ( func Stop(appID string, cliPIDToNoOfApps map[int]int, apps []ListOutput) error { for _, a := range apps { if a.AppID == appID { - eventName, _ := syscall.UTF16FromString(fmt.Sprintf("dapr_cli_%v", a.CliPID)) - eventHandle, err := windows.OpenEvent(windows.EVENT_MODIFY_STATE, false, &eventName[0]) - if err != nil { - return err - } - - err = windows.SetEvent(eventHandle) - return err + return handleEvent(a.CliPID) } } return fmt.Errorf("couldn't find app id %s", appID) } // StopAppsWithRunFile terminates the daprd and application processes with the given run file. -func StopAppsWithRunFile(runFilePath string) error { - return errors.New("stopping apps with run template file is not supported on windows") +func StopAppsWithRunFile(runTemplatePath string) error { + apps, err := List() + if err != nil { + return err + } + for _, a := range apps { + if a.RunTemplatePath == runTemplatePath { + return handleEvent(a.CliPID) + } + } + return fmt.Errorf("couldn't find apps with run file %q", runTemplatePath) +} + +func handleEvent(cliPID int) error { + eventName, _ := syscall.UTF16FromString(fmt.Sprintf("dapr_cli_%v", cliPID)) + eventHandle, err := windows.OpenEvent(windows.EVENT_MODIFY_STATE, false, &eventName[0]) + if err != nil { + return err + } + + err = windows.SetEvent(eventHandle) + return err } diff --git a/pkg/syscall/syscall_windows.go b/pkg/syscall/syscall_windows.go index 89c3c7d88..bd9a07579 100644 --- a/pkg/syscall/syscall_windows.go +++ b/pkg/syscall/syscall_windows.go @@ -43,6 +43,6 @@ func SetupShutdownNotify(sigCh chan os.Signal) { // CreateProcessGroupID creates a process group ID for the current process. func CreateProcessGroupID() { - // No-op on Windows - print.WarningStatusEvent(os.Stdout, "Creating process group id is not implemented on Windows") + // Process group ID is not required on windows, since all the child processes can be killed by killing the parent process. + //no-op } From 3750a476ea231dc7d9e9b0c131565509b73d63ac Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Tue, 13 Jun 2023 18:45:44 +0530 Subject: [PATCH 02/14] Uncommenting run on windows Signed-off-by: Pravin Pushkar --- tests/e2e/standalone/run_template_test.go | 3 --- tests/e2e/standalone/stop_with_run_template_test.go | 3 --- 2 files changed, 6 deletions(-) diff --git a/tests/e2e/standalone/run_template_test.go b/tests/e2e/standalone/run_template_test.go index a831527db..acc6e5de4 100644 --- a/tests/e2e/standalone/run_template_test.go +++ b/tests/e2e/standalone/run_template_test.go @@ -43,9 +43,6 @@ type AppTestOutput struct { } func TestRunWithTemplateFile(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("Skipping test on Windows") - } ensureDaprInstallation(t) t.Cleanup(func() { // remove dapr installation after all tests in this function. diff --git a/tests/e2e/standalone/stop_with_run_template_test.go b/tests/e2e/standalone/stop_with_run_template_test.go index 920d916d5..ca809de4c 100644 --- a/tests/e2e/standalone/stop_with_run_template_test.go +++ b/tests/e2e/standalone/stop_with_run_template_test.go @@ -31,9 +31,6 @@ import ( ) func TestStopAppsStartedWithRunTemplate(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("Skipping test on windows") - } ensureDaprInstallation(t) t.Cleanup(func() { // remove dapr installation after all tests in this function. From 994b3dc82e2f0dc66c74aa183c16cc4e2ad1033d Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Tue, 13 Jun 2023 21:01:29 +0530 Subject: [PATCH 03/14] fix static checks Signed-off-by: Pravin Pushkar --- tests/e2e/standalone/run_template_test.go | 4 ---- tests/e2e/standalone/stop_with_run_template_test.go | 1 - 2 files changed, 5 deletions(-) diff --git a/tests/e2e/standalone/run_template_test.go b/tests/e2e/standalone/run_template_test.go index acc6e5de4..7291504a5 100644 --- a/tests/e2e/standalone/run_template_test.go +++ b/tests/e2e/standalone/run_template_test.go @@ -24,7 +24,6 @@ import ( "io/ioutil" "os" "path/filepath" - "runtime" "strings" "testing" "time" @@ -370,9 +369,6 @@ func TestRunWithTemplateFile(t *testing.T) { } func TestRunTemplateFileWithoutDaprInit(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("Skipping test on Windows") - } // remove any dapr installation before this test. must(t, cmdUninstall, "failed to uninstall Dapr") t.Run("valid template file without dapr init", func(t *testing.T) { diff --git a/tests/e2e/standalone/stop_with_run_template_test.go b/tests/e2e/standalone/stop_with_run_template_test.go index ca809de4c..9544ab716 100644 --- a/tests/e2e/standalone/stop_with_run_template_test.go +++ b/tests/e2e/standalone/stop_with_run_template_test.go @@ -22,7 +22,6 @@ import ( "encoding/json" "fmt" "os" - "runtime" "testing" "time" From 87eee74860ca2007feecc7a6cba78fb84ae4d453 Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Mon, 26 Jun 2023 16:45:15 +0530 Subject: [PATCH 04/14] Kill children and grand children forcefully Signed-off-by: Pravin Pushkar --- pkg/standalone/stop_windows.go | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/pkg/standalone/stop_windows.go b/pkg/standalone/stop_windows.go index 6e6942d40..ad482cef4 100644 --- a/pkg/standalone/stop_windows.go +++ b/pkg/standalone/stop_windows.go @@ -15,8 +15,11 @@ package standalone import ( "fmt" + "os/exec" "syscall" + ps "github.com/mitchellh/go-ps" + process "github.com/shirou/gopsutil/process" "golang.org/x/sys/windows" ) @@ -38,12 +41,39 @@ func StopAppsWithRunFile(runTemplatePath string) error { } for _, a := range apps { if a.RunTemplatePath == runTemplatePath { - return handleEvent(a.CliPID) + return killProcessAndChildren(a.CliPID) } } return fmt.Errorf("couldn't find apps with run file %q", runTemplatePath) } +func killProcessAndChildren(cliPID int) error { + processes, err := ps.Processes() + if err != nil { + return err + } + + for _, p := range processes { + if p.Pid() == cliPID { + proc, err := process.NewProcess(int32(p.Pid())) + if err != nil { + return err + } + processName, err := proc.Name() + if err != nil { + return err + } + killCMD := exec.Command("taskkill", "/im", processName, "/T", "/F") + err = killCMD.Run() + if err != nil { + return err + } + return nil + } + } + return fmt.Errorf("process not found") +} + func handleEvent(cliPID int) error { eventName, _ := syscall.UTF16FromString(fmt.Sprintf("dapr_cli_%v", cliPID)) eventHandle, err := windows.OpenEvent(windows.EVENT_MODIFY_STATE, false, &eventName[0]) From 7d9e55a61253049e53bf50ac49e4a416518d0b9f Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Mon, 26 Jun 2023 21:28:49 +0530 Subject: [PATCH 05/14] ommiting tests for wiondows Signed-off-by: Pravin Pushkar --- tests/e2e/standalone/run_template_test.go | 3 ++- tests/e2e/standalone/stop_with_run_template_test.go | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/e2e/standalone/run_template_test.go b/tests/e2e/standalone/run_template_test.go index 7291504a5..2e77c63aa 100644 --- a/tests/e2e/standalone/run_template_test.go +++ b/tests/e2e/standalone/run_template_test.go @@ -1,4 +1,5 @@ -//go:build e2e || template +//go:build !windows && (e2e || template) +// +build !windows // +build e2e template /* diff --git a/tests/e2e/standalone/stop_with_run_template_test.go b/tests/e2e/standalone/stop_with_run_template_test.go index 9544ab716..0401c4352 100644 --- a/tests/e2e/standalone/stop_with_run_template_test.go +++ b/tests/e2e/standalone/stop_with_run_template_test.go @@ -1,4 +1,5 @@ -//go:build e2e || template +//go:build !windows && (e2e || template) +// +build !windows // +build e2e template /* From 9046d52ad95c63ae29fa24f50173ff20e892f5f1 Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Tue, 27 Jun 2023 17:14:25 +0530 Subject: [PATCH 06/14] rename method Signed-off-by: Pravin Pushkar --- pkg/standalone/stop_windows.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/standalone/stop_windows.go b/pkg/standalone/stop_windows.go index ad482cef4..1b868d72f 100644 --- a/pkg/standalone/stop_windows.go +++ b/pkg/standalone/stop_windows.go @@ -41,13 +41,13 @@ func StopAppsWithRunFile(runTemplatePath string) error { } for _, a := range apps { if a.RunTemplatePath == runTemplatePath { - return killProcessAndChildren(a.CliPID) + return killDaprRunProcessTree(a.CliPID) } } return fmt.Errorf("couldn't find apps with run file %q", runTemplatePath) } -func killProcessAndChildren(cliPID int) error { +func killDaprRunProcessTree(cliPID int) error { processes, err := ps.Processes() if err != nil { return err From c9f2ac561746cade97e4f95ccb79b1430519ade1 Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Tue, 4 Jul 2023 19:01:43 +0530 Subject: [PATCH 07/14] shut down all processes Signed-off-by: Pravin Pushkar --- cmd/run.go | 3 ++- pkg/standalone/stop_windows.go | 38 +++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/cmd/run.go b/cmd/run.go index 268e05dec..749502404 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -937,8 +937,9 @@ func killAppProcess(runE *runExec.RunExec) error { if runE.AppCMD.Command == nil { return nil } - err := runE.AppCMD.Command.Process.Kill() + _, err := runE.AppCMD.Command.Process.Wait() if err != nil { + fmt.Println("line no 943") print.StatusEvent(runE.DaprCMD.ErrorWriter, print.LogFailure, "Error exiting App: %s", err) return err } diff --git a/pkg/standalone/stop_windows.go b/pkg/standalone/stop_windows.go index 1b868d72f..35c2219ed 100644 --- a/pkg/standalone/stop_windows.go +++ b/pkg/standalone/stop_windows.go @@ -15,7 +15,6 @@ package standalone import ( "fmt" - "os/exec" "syscall" ps "github.com/mitchellh/go-ps" @@ -59,16 +58,39 @@ func killDaprRunProcessTree(cliPID int) error { if err != nil { return err } - processName, err := proc.Name() + child, err := proc.Children() if err != nil { - return err + return fmt.Errorf("error getting children of process %d: %s", proc.Pid, err) } - killCMD := exec.Command("taskkill", "/im", processName, "/T", "/F") - err = killCMD.Run() - if err != nil { - return err + for _, c := range child { + grand, err := c.Children() + if err != nil { + return fmt.Errorf("error getting grand children of process %d: %s", c.Pid, err) + } + var gc int = 0 + for _, g := range grand { + gc = 1 + err := g.Terminate() + for { + if ok, _ := g.IsRunning(); !ok { + fmt.Println("grand child process terminated") + break + } + } + if err != nil { + return fmt.Errorf("error killing grand process %d: %s", g.Pid, err) + } + } + if gc == 1 { + for { + if ok, _ := c.IsRunning(); !ok { + fmt.Println("grand child process has terminated the parent process") + break + } + } + } } - return nil + return handleEvent(cliPID) } } return fmt.Errorf("process not found") From 4924f0cee3a18e7e7327e8ee24e2a4b6e1e52d6d Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Fri, 7 Jul 2023 00:10:41 +0530 Subject: [PATCH 08/14] Use job handle and named evens together to kill the processes Signed-off-by: Pravin Pushkar --- cmd/run.go | 3 +- go.mod | 1 + go.sum | 8 +++++ pkg/standalone/stop_windows.go | 61 ++++++++-------------------------- pkg/syscall/syscall.go | 6 ++++ pkg/syscall/syscall_windows.go | 45 +++++++++++++++++++++++-- utils/utils.go | 5 +++ 7 files changed, 78 insertions(+), 51 deletions(-) diff --git a/cmd/run.go b/cmd/run.go index 749502404..e193a6c60 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -548,6 +548,8 @@ func executeRun(runTemplateName, runFilePath string, apps []runfileconfig.App) ( if runState.AppCMD.Command.Process != nil { putAppProcessIDInMeta(runState) + // Attach a job object to the app process. + daprsyscall.AttachJobObjectToProcess(strconv.Itoa(os.Getpid())+"-"+utils.WindowsDaprdAppProcJobName, runState.AppCMD.Command.Process) } } @@ -939,7 +941,6 @@ func killAppProcess(runE *runExec.RunExec) error { } _, err := runE.AppCMD.Command.Process.Wait() if err != nil { - fmt.Println("line no 943") print.StatusEvent(runE.DaprCMD.ErrorWriter, print.LogFailure, "Error exiting App: %s", err) return err } diff --git a/go.mod b/go.mod index a903106b9..97548b5f0 100644 --- a/go.mod +++ b/go.mod @@ -130,6 +130,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.16.3 // indirect + github.com/kolesnikovae/go-winjob v1.0.0 github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/lestrrat-go/blackmagic v1.0.1 // indirect diff --git a/go.sum b/go.sum index bf91ca344..86a97a55e 100644 --- a/go.sum +++ b/go.sum @@ -119,6 +119,7 @@ github.com/Microsoft/hcsshim v0.9.6/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfy github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Pallinder/sillyname-go v0.0.0-20130730142914-97aeae9e6ba1 h1:ReSY7H5Nf08bSzShfWAUTCthIsK08iNitWGX5YFQGXE= github.com/Pallinder/sillyname-go v0.0.0-20130730142914-97aeae9e6ba1/go.mod h1:cTmXjiBQMtbZnpc/yLode6SPqKmzeL7xJlD+9R9zxoc= @@ -417,6 +418,7 @@ github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= +github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -715,6 +717,7 @@ github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -739,6 +742,8 @@ github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/kolesnikovae/go-winjob v1.0.0 h1:OKEtCHB3sYNAiqNwGDhf08Y6luM7C8mP+42rp1N6SeE= +github.com/kolesnikovae/go-winjob v1.0.0/go.mod h1:k0joOLP3/NBrRmDQjPV2+oN1TPmEWt6arTNtFjVeQuM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -1049,6 +1054,7 @@ github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= @@ -1069,6 +1075,7 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg= github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -1139,6 +1146,7 @@ github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq// github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= diff --git a/pkg/standalone/stop_windows.go b/pkg/standalone/stop_windows.go index 35c2219ed..36ccdcaa1 100644 --- a/pkg/standalone/stop_windows.go +++ b/pkg/standalone/stop_windows.go @@ -15,10 +15,12 @@ package standalone import ( "fmt" + "strconv" "syscall" + "time" - ps "github.com/mitchellh/go-ps" - process "github.com/shirou/gopsutil/process" + "github.com/dapr/cli/utils" + "github.com/kolesnikovae/go-winjob" "golang.org/x/sys/windows" ) @@ -40,60 +42,23 @@ func StopAppsWithRunFile(runTemplatePath string) error { } for _, a := range apps { if a.RunTemplatePath == runTemplatePath { - return killDaprRunProcessTree(a.CliPID) + return disposeJobHandle(a.CliPID) } } return fmt.Errorf("couldn't find apps with run file %q", runTemplatePath) } -func killDaprRunProcessTree(cliPID int) error { - processes, err := ps.Processes() +func disposeJobHandle(cliPID int) error { + jbobj, err := winjob.Open(strconv.Itoa(cliPID) + "-" + utils.WindowsDaprdAppProcJobName) if err != nil { - return err + return fmt.Errorf("error opening job object: %s", err) } - - for _, p := range processes { - if p.Pid() == cliPID { - proc, err := process.NewProcess(int32(p.Pid())) - if err != nil { - return err - } - child, err := proc.Children() - if err != nil { - return fmt.Errorf("error getting children of process %d: %s", proc.Pid, err) - } - for _, c := range child { - grand, err := c.Children() - if err != nil { - return fmt.Errorf("error getting grand children of process %d: %s", c.Pid, err) - } - var gc int = 0 - for _, g := range grand { - gc = 1 - err := g.Terminate() - for { - if ok, _ := g.IsRunning(); !ok { - fmt.Println("grand child process terminated") - break - } - } - if err != nil { - return fmt.Errorf("error killing grand process %d: %s", g.Pid, err) - } - } - if gc == 1 { - for { - if ok, _ := c.IsRunning(); !ok { - fmt.Println("grand child process has terminated the parent process") - break - } - } - } - } - return handleEvent(cliPID) - } + err = jbobj.TerminateWithExitCode(0) + if err != nil { + return fmt.Errorf("error terminating job object: %s", err) } - return fmt.Errorf("process not found") + time.Sleep(5 * time.Second) + return handleEvent(cliPID) } func handleEvent(cliPID int) error { diff --git a/pkg/syscall/syscall.go b/pkg/syscall/syscall.go index bde03be4e..197d6dd33 100644 --- a/pkg/syscall/syscall.go +++ b/pkg/syscall/syscall.go @@ -40,3 +40,9 @@ func CreateProcessGroupID() { print.WarningStatusEvent(os.Stdout, "Failed to create process group id: %s", err.Error()) } } + +// AttachJobObjectToProcess attaches the process to a job object. +func AttachJobObjectToProcess(jobName string, proc *os.Process) { + // This is a no-op on Linux/Mac. + // Instead, we use process group ID to kill all the processes. +} diff --git a/pkg/syscall/syscall_windows.go b/pkg/syscall/syscall_windows.go index bd9a07579..a4fa2911b 100644 --- a/pkg/syscall/syscall_windows.go +++ b/pkg/syscall/syscall_windows.go @@ -1,3 +1,6 @@ +//go:build windows +// +build windows + /* Copyright 2021 The Dapr Authors Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,12 +21,17 @@ import ( "os" "os/signal" "syscall" + "unsafe" "golang.org/x/sys/windows" "github.com/dapr/cli/pkg/print" + "github.com/kolesnikovae/go-winjob" + "github.com/kolesnikovae/go-winjob/jobapi" ) +var jbObj *winjob.JobObject + func SetupShutdownNotify(sigCh chan os.Signal) { signal.Notify(sigCh, syscall.SIGTERM, syscall.SIGINT) @@ -43,6 +51,39 @@ func SetupShutdownNotify(sigCh chan os.Signal) { // CreateProcessGroupID creates a process group ID for the current process. func CreateProcessGroupID() { - // Process group ID is not required on windows, since all the child processes can be killed by killing the parent process. - //no-op + // This is a no-op on windows. + // Process group ID is not used for killing all the processes on windows. + // Instead, we use combination of named event and job object to kill all the processes. +} + +// AttachJobObjectToProcess attaches the process to a job object. +// It creates the job object if it doesn't exist. +func AttachJobObjectToProcess(jobName string, proc *os.Process) { + if jbObj != nil { + err := jbObj.Assign(proc) + if err != nil { + print.WarningStatusEvent(os.Stdout, "failed to assign process to job object: %s", err.Error()) + } + return + } + jbObj, err := winjob.Create(jobName) + if err != nil { + print.WarningStatusEvent(os.Stdout, "failed to create job object: %s", err.Error()) + return + } + info := windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION{ + BasicLimitInformation: windows.JOBOBJECT_BASIC_LIMIT_INFORMATION{ + LimitFlags: windows.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, + }, + } + err = jobapi.SetInformationJobObject(jbObj.Handle, jobapi.JobObjectExtendedLimitInformation, unsafe.Pointer(&info), uint32(unsafe.Sizeof(info))) + if err != nil { + print.WarningStatusEvent(os.Stdout, "failed to set job object info: %s", err.Error()) + return + } + err = jbObj.Assign(proc) + if err != nil { + print.WarningStatusEvent(os.Stdout, "failed to assign process to job object: %s", err.Error()) + } + return } diff --git a/utils/utils.go b/utils/utils.go index 6a4d3aa3b..7a72effbc 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -51,6 +51,11 @@ const ( // DefaultAppChannelAddress is the default local network address that user application listen on. DefaultAppChannelAddress = "127.0.0.1" + + // WindowsDaprdAppProcJobName is the name of the Windows job object that is used to manage the Dapr processes on windows. + WindowsDaprdAppProcJobName = "daprd-app-process-job" + // WindowsCLIProcessJobName is the name of the Windows job object that is used to manage the Dapr CLI processes on windows. + WindowsCLIProcessJobName = "dapr-cli-process-job" ) // IsValidContainerRuntime checks if the input is a valid container runtime. From 2e717c065c8c6562dc56274b8cc2819379378de7 Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Fri, 7 Jul 2023 00:15:45 +0530 Subject: [PATCH 09/14] lint fix Signed-off-by: Pravin Pushkar --- pkg/standalone/stop_windows.go | 4 ++-- pkg/syscall/syscall_windows.go | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pkg/standalone/stop_windows.go b/pkg/standalone/stop_windows.go index 36ccdcaa1..b4d2337c7 100644 --- a/pkg/standalone/stop_windows.go +++ b/pkg/standalone/stop_windows.go @@ -51,11 +51,11 @@ func StopAppsWithRunFile(runTemplatePath string) error { func disposeJobHandle(cliPID int) error { jbobj, err := winjob.Open(strconv.Itoa(cliPID) + "-" + utils.WindowsDaprdAppProcJobName) if err != nil { - return fmt.Errorf("error opening job object: %s", err) + return fmt.Errorf("error opening job object: %w", err) } err = jbobj.TerminateWithExitCode(0) if err != nil { - return fmt.Errorf("error terminating job object: %s", err) + return fmt.Errorf("error terminating job object: %w", err) } time.Sleep(5 * time.Second) return handleEvent(cliPID) diff --git a/pkg/syscall/syscall_windows.go b/pkg/syscall/syscall_windows.go index a4fa2911b..3c2161945 100644 --- a/pkg/syscall/syscall_windows.go +++ b/pkg/syscall/syscall_windows.go @@ -85,5 +85,4 @@ func AttachJobObjectToProcess(jobName string, proc *os.Process) { if err != nil { print.WarningStatusEvent(os.Stdout, "failed to assign process to job object: %s", err.Error()) } - return } From b742b9cf8fb4df602f9bfab737936590e41e8478 Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Fri, 7 Jul 2023 12:40:02 +0530 Subject: [PATCH 10/14] revert wait to kill Signed-off-by: Pravin Pushkar --- cmd/run.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/run.go b/cmd/run.go index e193a6c60..bb6aa59c5 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -939,7 +939,7 @@ func killAppProcess(runE *runExec.RunExec) error { if runE.AppCMD.Command == nil { return nil } - _, err := runE.AppCMD.Command.Process.Wait() + err := runE.AppCMD.Command.Process.Kill() if err != nil { print.StatusEvent(runE.DaprCMD.ErrorWriter, print.LogFailure, "Error exiting App: %s", err) return err From 65afe66bb92bf8ef2bc294999a80e9f71beda42e Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Fri, 7 Jul 2023 18:53:31 +0530 Subject: [PATCH 11/14] Adding E2E for windows template file run Signed-off-by: Pravin Pushkar --- .../standalone/windows_run_template_test.go | 144 ++++++++++++++++++ .../app_output_to_only_console.yaml | 14 ++ 2 files changed, 158 insertions(+) create mode 100644 tests/e2e/standalone/windows_run_template_test.go create mode 100644 tests/e2e/testdata/run-template-files/app_output_to_only_console.yaml diff --git a/tests/e2e/standalone/windows_run_template_test.go b/tests/e2e/standalone/windows_run_template_test.go new file mode 100644 index 000000000..44c71bc03 --- /dev/null +++ b/tests/e2e/standalone/windows_run_template_test.go @@ -0,0 +1,144 @@ +//go:build windows && (e2e || template) +// +build windows +// +build e2e template + +/* +Copyright 2023 The Dapr 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 standalone_test + +import ( + "strings" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +type AppTestOutput struct { + appID string + appLogContents []string + daprdLogContent []string + baseLogDirPath string + appLogDoesNotExist bool + daprdLogFileDoesNotExist bool +} + +func TestRunWithTemplateFile(t *testing.T) { + ensureDaprInstallation(t) + t.Cleanup(func() { + // remove dapr installation after all tests in this function. + must(t, cmdUninstall, "failed to uninstall Dapr") + }) + // These tests are dependent on run template files in ../testdata/run-template-files folder. + t.Run("valid template file", func(t *testing.T) { + runFilePath := "../testdata/run-template-files/dapr.yaml" + go startAppsWithValidRunTemplate(t, runFilePath) + time.Sleep(10 * time.Second) + output, err := cmdStopWithRunTemplate(runFilePath) + assert.NoError(t, err, "failed to stop apps started with run template") + assert.Contains(t, output, "Dapr and app processes stopped successfully") + time.Sleep(5 * time.Second) + }) + + t.Run("valid template file with App output written to only file", func(t *testing.T) { + runFilePath := "../testdata/run-template-files/app_output_to_file_and_console.yaml" + go startAppsWithAppLogDestFile(t, runFilePath) + time.Sleep(10 * time.Second) + output, err := cmdStopWithRunTemplate(runFilePath) + assert.NoError(t, err, "failed to stop apps started with run template") + assert.Contains(t, output, "Dapr and app processes stopped successfully") + time.Sleep(5 * time.Second) + }) + + t.Run("valid template file with App output written to only console", func(t *testing.T) { + runFilePath := "../testdata/run-template-files/app_output_to_only_console.yaml" + go startAppsWithAppLogDestConsole(t, runFilePath) + time.Sleep(10 * time.Second) + output, err := cmdStopWithRunTemplate(runFilePath) + assert.NoError(t, err, "failed to stop apps started with run template") + assert.Contains(t, output, "Dapr and app processes stopped successfully") + time.Sleep(5 * time.Second) + }) +} + +func startAppsWithValidRunTemplate(t *testing.T, file string) { + args := []string{ + "-f", file, + } + output, err := cmdRun("", args...) + t.Logf(output) + require.NoError(t, err, "run failed") + lines := strings.Split(output, "\n") + assert.GreaterOrEqual(t, len(lines), 7, "expected at least 7 lines in output of starting two apps") + assert.Contains(t, lines[0], "This is a preview feature and subject to change in future releases.") + assert.Contains(t, lines[1], "Validating config and starting app \"processor\"") + assert.Contains(t, lines[2], "Started Dapr with app id \"processor\". HTTP Port: 3510.") + assert.Contains(t, lines[3], "Writing log files to directory") + assert.Contains(t, lines[3], "tests\\apps\\processor\\.dapr\\logs") + assert.Contains(t, lines[4], "Validating config and starting app \"emit-metrics\"") + assert.Contains(t, lines[5], "Started Dapr with app id \"emit-metrics\". HTTP Port: 3511.") + assert.Contains(t, lines[6], "Writing log files to directory") + assert.Contains(t, lines[6], "tests\\apps\\emit-metrics\\.dapr\\logs") +} + +func startAppsWithAppLogDestFile(t *testing.T, file string) { + args := []string{ + "-f", file, + } + output, err := cmdRun("", args...) + t.Logf(output) + require.NoError(t, err, "run failed") + + // App logs for processor app should not be printed to console and only written to file. + assert.NotContains(t, output, "== APP - processor") + + // Daprd logs for processor app should only be printed to console and not written to file. + assert.Contains(t, output, "msg=\"All outstanding components processed\" app_id=processor") + + // App logs for emit-metrics app should be printed to console and written to file. + assert.Contains(t, output, "== APP - emit-metrics") + + // Daprd logs for emit-metrics app should only be written to file. + assert.NotContains(t, output, "msg=\"All outstanding components processed\" app_id=emit-metrics") + + assert.Contains(t, output, "Received signal to stop Dapr and app processes. Shutting down Dapr and app processes.") + +} + +func startAppsWithAppLogDestConsole(t *testing.T, file string) { + args := []string{ + "-f", file, + } + output, err := cmdRun("", args...) + t.Logf(output) + require.NoError(t, err, "run failed") + + // App logs for processor app should be printed to console. + assert.Contains(t, output, "== APP - processor") + + // Daprd logs for processor app should only be written to file. + assert.NotContains(t, output, "msg=\"All outstanding components processed\" app_id=processor") + + // App logs for emit-metrics app should be printed to console. + assert.Contains(t, output, "== APP - emit-metrics") + + // Daprd logs for emit-metrics app should only be written to file. + assert.NotContains(t, output, "msg=\"All outstanding components processed\" app_id=emit-metrics") + + assert.Contains(t, output, "Received signal to stop Dapr and app processes. Shutting down Dapr and app processes.") + +} diff --git a/tests/e2e/testdata/run-template-files/app_output_to_only_console.yaml b/tests/e2e/testdata/run-template-files/app_output_to_only_console.yaml new file mode 100644 index 000000000..17ddc86a2 --- /dev/null +++ b/tests/e2e/testdata/run-template-files/app_output_to_only_console.yaml @@ -0,0 +1,14 @@ +version: 1 +apps: + - appDirPath: ../../../apps/processor/ + appPort: 9081 + daprHTTPPort: 3510 + command: ["go","run", "app.go"] + appLogDestination: console + - appID: emit-metrics + appDirPath: ../../../apps/emit-metrics/ + daprHTTPPort: 3511 + env: + DAPR_HOST_ADD: localhost + command: ["go","run", "app.go"] + appLogDestination: console From 0cce83cadedb5b4d243367b4a99ff4c07eec5f4f Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Wed, 9 Aug 2023 11:27:13 +0530 Subject: [PATCH 12/14] rename job name Signed-off-by: Pravin Pushkar --- cmd/run.go | 2 +- pkg/standalone/stop_windows.go | 2 +- utils/utils.go | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/cmd/run.go b/cmd/run.go index 80ff5d023..c58ade3f0 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -559,7 +559,7 @@ func executeRun(runTemplateName, runFilePath string, apps []runfileconfig.App) ( if runState.AppCMD.Command.Process != nil { putAppProcessIDInMeta(runState) // Attach a job object to the app process. - daprsyscall.AttachJobObjectToProcess(strconv.Itoa(os.Getpid())+"-"+utils.WindowsDaprdAppProcJobName, runState.AppCMD.Command.Process) + daprsyscall.AttachJobObjectToProcess(strconv.Itoa(os.Getpid())+"-"+utils.WindowsDaprAppProcJobName, runState.AppCMD.Command.Process) } } diff --git a/pkg/standalone/stop_windows.go b/pkg/standalone/stop_windows.go index b4d2337c7..6b3a0ef2d 100644 --- a/pkg/standalone/stop_windows.go +++ b/pkg/standalone/stop_windows.go @@ -49,7 +49,7 @@ func StopAppsWithRunFile(runTemplatePath string) error { } func disposeJobHandle(cliPID int) error { - jbobj, err := winjob.Open(strconv.Itoa(cliPID) + "-" + utils.WindowsDaprdAppProcJobName) + jbobj, err := winjob.Open(strconv.Itoa(cliPID) + "-" + utils.WindowsDaprAppProcJobName) if err != nil { return fmt.Errorf("error opening job object: %w", err) } diff --git a/utils/utils.go b/utils/utils.go index 9fc77dfd2..f7f383e82 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -52,10 +52,8 @@ const ( // DefaultAppChannelAddress is the default local network address that user application listen on. DefaultAppChannelAddress = "127.0.0.1" - // WindowsDaprdAppProcJobName is the name of the Windows job object that is used to manage the Dapr processes on windows. - WindowsDaprdAppProcJobName = "daprd-app-process-job" - // WindowsCLIProcessJobName is the name of the Windows job object that is used to manage the Dapr CLI processes on windows. - WindowsCLIProcessJobName = "dapr-cli-process-job" + // WindowsDaprAppProcJobName is the name of the Windows job object that is used to manage the Daprized app's processes on windows. + WindowsDaprAppProcJobName = "dapr-app-process-job" ) // IsValidContainerRuntime checks if the input is a valid container runtime. From 25a9b629a4bdc78d1c70aef1ae7fff6299bcbd1a Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Wed, 23 Aug 2023 12:48:31 +0530 Subject: [PATCH 13/14] review comments Signed-off-by: Pravin Pushkar --- cmd/run.go | 4 ++-- pkg/standalone/stop_windows.go | 6 +++--- pkg/syscall/syscall_windows.go | 3 +++ utils/utils.go | 11 +++++++++-- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/cmd/run.go b/cmd/run.go index c58ade3f0..bf89f68a2 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -558,8 +558,8 @@ func executeRun(runTemplateName, runFilePath string, apps []runfileconfig.App) ( if runState.AppCMD.Command.Process != nil { putAppProcessIDInMeta(runState) - // Attach a job object to the app process. - daprsyscall.AttachJobObjectToProcess(strconv.Itoa(os.Getpid())+"-"+utils.WindowsDaprAppProcJobName, runState.AppCMD.Command.Process) + // Attach a windows job object to the app process. + utils.AttachJobObjectToProcess(strconv.Itoa(os.Getpid()), runState.AppCMD.Command.Process) } } diff --git a/pkg/standalone/stop_windows.go b/pkg/standalone/stop_windows.go index 6b3a0ef2d..08bfabdcd 100644 --- a/pkg/standalone/stop_windows.go +++ b/pkg/standalone/stop_windows.go @@ -28,7 +28,7 @@ import ( func Stop(appID string, cliPIDToNoOfApps map[int]int, apps []ListOutput) error { for _, a := range apps { if a.AppID == appID { - return handleEvent(a.CliPID) + return setStopEvent(a.CliPID) } } return fmt.Errorf("couldn't find app id %s", appID) @@ -58,10 +58,10 @@ func disposeJobHandle(cliPID int) error { return fmt.Errorf("error terminating job object: %w", err) } time.Sleep(5 * time.Second) - return handleEvent(cliPID) + return setStopEvent(cliPID) } -func handleEvent(cliPID int) error { +func setStopEvent(cliPID int) error { eventName, _ := syscall.UTF16FromString(fmt.Sprintf("dapr_cli_%v", cliPID)) eventHandle, err := windows.OpenEvent(windows.EVENT_MODIFY_STATE, false, &eventName[0]) if err != nil { diff --git a/pkg/syscall/syscall_windows.go b/pkg/syscall/syscall_windows.go index 3c2161945..90d93ae71 100644 --- a/pkg/syscall/syscall_windows.go +++ b/pkg/syscall/syscall_windows.go @@ -71,6 +71,9 @@ func AttachJobObjectToProcess(jobName string, proc *os.Process) { print.WarningStatusEvent(os.Stdout, "failed to create job object: %s", err.Error()) return } + // Below lines control the relation between Job object and processes attached to it. + // By passing JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE flag, it will make sure that when + // job object is closed all the processed must also be exited. info := windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION{ BasicLimitInformation: windows.JOBOBJECT_BASIC_LIMIT_INFORMATION{ LimitFlags: windows.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, diff --git a/utils/utils.go b/utils/utils.go index f7f383e82..bba9c6acc 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -29,6 +29,7 @@ import ( "time" "github.com/dapr/cli/pkg/print" + daprsyscall "github.com/dapr/cli/pkg/syscall" "github.com/docker/docker/client" "github.com/gocarina/gocsv" @@ -52,8 +53,8 @@ const ( // DefaultAppChannelAddress is the default local network address that user application listen on. DefaultAppChannelAddress = "127.0.0.1" - // WindowsDaprAppProcJobName is the name of the Windows job object that is used to manage the Daprized app's processes on windows. - WindowsDaprAppProcJobName = "dapr-app-process-job" + // windowsDaprAppProcJobName is the name of the Windows job object that is used to manage the Daprized app's processes on windows. + windowsDaprAppProcJobName = "dapr-app-process-job" ) // IsValidContainerRuntime checks if the input is a valid container runtime. @@ -411,3 +412,9 @@ func FindFileInDir(dirPath, fileName string) (string, error) { func SanitizeDir(destDir string) string { return strings.ReplaceAll(destDir, "'", "''") } + +// Attach Job object to App Process +func AttachJobObjectToProcess(pid string, proc *os.Process) { + // Attach a job object to the app process. + daprsyscall.AttachJobObjectToProcess(pid+"-"+windowsDaprAppProcJobName, proc) +} From 20c34af652c843fb475f9f15ea5f5cf470ec2f7f Mon Sep 17 00:00:00 2001 From: Pravin Pushkar Date: Thu, 24 Aug 2023 00:33:40 +0530 Subject: [PATCH 14/14] build failure Signed-off-by: Pravin Pushkar --- pkg/standalone/stop_windows.go | 3 ++- utils/utils.go | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pkg/standalone/stop_windows.go b/pkg/standalone/stop_windows.go index 08bfabdcd..b5d40ce36 100644 --- a/pkg/standalone/stop_windows.go +++ b/pkg/standalone/stop_windows.go @@ -49,7 +49,8 @@ func StopAppsWithRunFile(runTemplatePath string) error { } func disposeJobHandle(cliPID int) error { - jbobj, err := winjob.Open(strconv.Itoa(cliPID) + "-" + utils.WindowsDaprAppProcJobName) + jobObjectName := utils.GetJobObjectNameFromPID(strconv.Itoa(cliPID)) + jbobj, err := winjob.Open(jobObjectName) if err != nil { return fmt.Errorf("error opening job object: %w", err) } diff --git a/utils/utils.go b/utils/utils.go index bba9c6acc..977e57866 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -413,8 +413,13 @@ func SanitizeDir(destDir string) string { return strings.ReplaceAll(destDir, "'", "''") } -// Attach Job object to App Process +// Attach Job object to App Process. func AttachJobObjectToProcess(pid string, proc *os.Process) { // Attach a job object to the app process. - daprsyscall.AttachJobObjectToProcess(pid+"-"+windowsDaprAppProcJobName, proc) + daprsyscall.AttachJobObjectToProcess(GetJobObjectNameFromPID(pid), proc) +} + +// GetJobObjectNameFromPID returns the name of the Windows job object that is used to manage the Daprized app's processes on windows. +func GetJobObjectNameFromPID(pid string) string { + return pid + "-" + windowsDaprAppProcJobName }