Pause initiates docker-compose stop
()
| 2950 | |
| 2951 | // Pause initiates docker-compose stop |
| 2952 | func (app *DdevApp) Pause() error { |
| 2953 | _ = app.DockerEnv() |
| 2954 | |
| 2955 | status, _ := app.SiteStatus() |
| 2956 | if status == SiteStopped { |
| 2957 | return nil |
| 2958 | } |
| 2959 | |
| 2960 | err := app.ProcessHooks("pre-pause") |
| 2961 | if err != nil { |
| 2962 | return err |
| 2963 | } |
| 2964 | |
| 2965 | _ = SyncAndPauseMutagenSession(app) |
| 2966 | |
| 2967 | if _, _, err := dockerutil.ComposeCmd(&dockerutil.ComposeCmdOpts{ |
| 2968 | ComposeFiles: []string{app.DockerComposeFullRenderedYAMLPath()}, |
| 2969 | Profiles: []string{`*`}, |
| 2970 | Action: []string{"stop"}, |
| 2971 | }); err != nil { |
| 2972 | return err |
| 2973 | } |
| 2974 | |
| 2975 | // Wait for containers to fully transition to exited state |
| 2976 | // This prevents race conditions where SiteStatus() might return "unhealthy" |
| 2977 | // instead of "paused" when checked immediately after Pause() returns |
| 2978 | // Poll for up to 5 seconds with 100ms intervals |
| 2979 | maxAttempts := 50 |
| 2980 | for range maxAttempts { |
| 2981 | containers, err := dockerutil.GetAppContainers(app.Name) |
| 2982 | if err != nil { |
| 2983 | // If we can't get containers, assume they're stopped |
| 2984 | break |
| 2985 | } |
| 2986 | |
| 2987 | allExited := true |
| 2988 | for _, c := range containers { |
| 2989 | if c.State != container.StateExited { |
| 2990 | allExited = false |
| 2991 | break |
| 2992 | } |
| 2993 | } |
| 2994 | if allExited { |
| 2995 | break |
| 2996 | } |
| 2997 | time.Sleep(100 * time.Millisecond) |
| 2998 | } |
| 2999 | |
| 3000 | err = app.ProcessHooks("post-pause") |
| 3001 | if err != nil { |
| 3002 | return err |
| 3003 | } |
| 3004 | |
| 3005 | return nil |
| 3006 | } |
| 3007 | |
| 3008 | // WaitForServices waits for all the services in docker-compose to come up |
| 3009 | func (app *DdevApp) WaitForServices() error { |