From 69bdca6331eaeba40f17290cb7d4f80671df08b1 Mon Sep 17 00:00:00 2001 From: Andy Cooper Date: Tue, 20 Feb 2018 17:45:56 -0500 Subject: [PATCH] add astro airflow pause --- airflow/docker.go | 82 ++++++++++++++++++++++++++++++++++++++--------- cmd/airflow.go | 21 ++++++++++-- 2 files changed, 85 insertions(+), 18 deletions(-) diff --git a/airflow/docker.go b/airflow/docker.go index 3ea0d0da4..dba0bfb04 100644 --- a/airflow/docker.go +++ b/airflow/docker.go @@ -21,8 +21,10 @@ import ( ) const ( - componentName = "airflow" - deployTagPrefix = "cli-" + componentName = "airflow" + deployTagPrefix = "cli-" + dockerStateUp = "Up" + dockerStateExited = "Exited" ) // ComposeConfig is input data to docker compose yaml template @@ -85,8 +87,18 @@ func generateConfig(projectName, airflowHome string) string { return buff.String() } -// createProjectFromContext creates project with yaml config as context -func createProjectFromContext(projectName, airflowHome string) (project.APIProject, error) { +func checkServiceState(serviceState, expectedState string) bool { + scrubbedState := strings.Split(serviceState, " ")[0] + + if scrubbedState == expectedState { + return true + } + + return false +} + +// createProject creates project with yaml config as context +func createProject(projectName, airflowHome string) (project.APIProject, error) { // Generate the docker-compose yaml yaml := generateConfig(projectName, airflowHome) @@ -107,30 +119,50 @@ func Start(airflowHome string) error { projectName := config.GetString(config.CFGProjectName) // Create a libcompose project - project, err := createProjectFromContext(projectName, airflowHome) + project, err := createProject(projectName, airflowHome) if err != nil { return errors.Wrap(err, "Error creating docker-compose project") } - // Build this project image - imageBuild(airflowHome, imageName(projectName, "latest")) - - // Start up our project - err = project.Up(context.Background(), options.Up{}) + // Fetch project containers + psInfo, err := project.Ps(context.Background()) if err != nil { - return errors.Wrap(err, "Error building, (re)creating or starting project containers") + return errors.Wrap(err, "Error checking docker-compose status") + } + + if len(psInfo) > 0 { + // Ensure project is not already running + for _, info := range psInfo { + if checkServiceState(info["State"], dockerStateUp) { + return errors.New("Project is already running, cannot start") + } + } + + err = project.Start(context.Background()) + if err != nil { + return errors.Wrap(err, "Error building, (re)creating or starting project containers") + } + } else { + // Build this project image + imageBuild(airflowHome, imageName(projectName, "latest")) + + // Start up our project + err = project.Up(context.Background(), options.Up{}) + if err != nil { + return errors.Wrap(err, "Error building, (re)creating or starting project containers") + } } return nil } -// Stop stops a local airflow development cluster -func Stop(airflowHome string) error { +// Kill stops a local airflow development cluster +func Kill(airflowHome string) error { // Get project name from config projectName := config.GetString(config.CFGProjectName) // Create a libcompose project - project, err := createProjectFromContext(projectName, airflowHome) + project, err := createProject(projectName, airflowHome) if err != nil { return errors.Wrap(err, "Error creating docker-compose project") } @@ -144,13 +176,33 @@ func Stop(airflowHome string) error { return nil } +// Stop a running docker project +func Stop(airflowHome string) error { + // Get project name from config + projectName := config.GetString(config.CFGProjectName) + + // Create a libcompose project + project, err := createProject(projectName, airflowHome) + if err != nil { + return errors.Wrap(err, "Error creating docker-compose project") + } + + // Pause our project + err = project.Stop(context.Background(), 30) + if err != nil { + return errors.Wrap(err, "Error pausing project containers") + } + + return nil +} + // PS prints the running airflow containers func PS(airflowHome string) error { // Get project name from config projectName := config.GetString(config.CFGProjectName) // Create a libcompose project - project, err := createProjectFromContext(projectName, airflowHome) + project, err := createProject(projectName, airflowHome) if err != nil { return errors.Wrap(err, "Error creating docker-compose project") } diff --git a/cmd/airflow.go b/cmd/airflow.go index 2dbe384c5..c38a8449f 100644 --- a/cmd/airflow.go +++ b/cmd/airflow.go @@ -53,6 +53,13 @@ var ( RunE: checkForProject(airflowStart), } + airflowKillCmd = &cobra.Command{ + Use: "kill", + Short: "Kill a development airflow cluster", + Long: "Kill a development airflow cluster", + RunE: checkForProject(airflowKill), + } + airflowStopCmd = &cobra.Command{ Use: "stop", Short: "Stop a development airflow cluster", @@ -88,6 +95,9 @@ func init() { // Airflow start airflowRootCmd.AddCommand(airflowStartCmd) + // Airflow kill + airflowRootCmd.AddCommand(airflowKillCmd) + // Airflow stop airflowRootCmd.AddCommand(airflowStopCmd) @@ -149,17 +159,22 @@ func airflowDeploy(cmd *cobra.Command, args []string) error { return airflow.Deploy(projectRoot, args[0]) } -// Start airflow +// Start an airflow cluster func airflowStart(cmd *cobra.Command, args []string) error { return airflow.Start(projectRoot) } -// Stop airflow +// Kill an airflow cluster +func airflowKill(cmd *cobra.Command, args []string) error { + return airflow.Kill(projectRoot) +} + +// Stop an airflow cluster func airflowStop(cmd *cobra.Command, args []string) error { return airflow.Stop(projectRoot) } -// Airflow PS +// List containers of an airflow cluster func airflowPS(cmd *cobra.Command, args []string) error { return airflow.PS(projectRoot) }