github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow@v0.28.1-0.20240311201729-34c6856b157f/pkg/command/run.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 package command 21 22 import ( 23 "fmt" 24 "os" 25 "sync" 26 "time" 27 28 "github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/common" 29 "github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/metadata" 30 "github.com/ory/viper" 31 "github.com/spf13/cobra" 32 ) 33 34 type RunCmdConfig struct { 35 PortMapping string 36 OpenDevUI bool 37 } 38 39 func NewRunCommand() *cobra.Command { 40 cmd := &cobra.Command{ 41 Use: "run", 42 Short: "Run a SonataFlow project in development mode", 43 Long: ` 44 Run a SonataFlow project in development mode. 45 46 By default, it runs over ` + metadata.DevModeImage + ` on Docker. 47 Alternatively, you can run the same image with Podman. 48 49 `, 50 Example: ` 51 # Run the workflow inside the current local directory 52 {{.Name}} run 53 54 # Run the current local directory mapping a different host port to the running container port. 55 {{.Name}} run --port 8081 56 57 # Disable automatic browser launch of SonataFlow Dev UI 58 {{.Name}} run --open-dev-ui=false 59 `, 60 SuggestFor: []string{"rnu", "start"}, //nolint:misspell 61 PreRunE: common.BindEnv("port", "open-dev-ui"), 62 } 63 64 cmd.RunE = func(cmd *cobra.Command, args []string) error { 65 return run() 66 } 67 68 cmd.Flags().StringP("port", "p", "8080", "Maps a different host port to the running container port.") 69 cmd.Flags().Bool("open-dev-ui", true, "Disable automatic browser launch of SonataFlow Dev UI") 70 cmd.SetHelpFunc(common.DefaultTemplatedHelp) 71 72 return cmd 73 } 74 75 func run() error { 76 cfg, err := runDevCmdConfig() 77 if err != nil { 78 return fmt.Errorf("initializing create config: %w", err) 79 } 80 81 if common.IsSonataFlowProject() { 82 if err := runSWFProject(cfg); err != nil { 83 return err 84 } 85 return nil 86 } else if common.IsQuarkusSonataFlowProject() { 87 return fmt.Errorf("looks like you are inside a Quarkus project. If that is the case, you should run it with \"quarkus run\" command") 88 } else { 89 return fmt.Errorf("cannot find SonataFlow project") 90 } 91 } 92 93 func runDevCmdConfig() (cfg RunCmdConfig, err error) { 94 cfg = RunCmdConfig{ 95 PortMapping: viper.GetString("port"), 96 OpenDevUI: viper.GetBool("open-dev-ui"), 97 } 98 return 99 } 100 101 func runSWFProject(cfg RunCmdConfig) error { 102 103 if errPodman := common.CheckPodman(); errPodman == nil { 104 if err := runSWFProjectDevMode(common.Podman, cfg); err != nil { 105 return err 106 } 107 } else if errDocker := common.CheckDocker(); errDocker == nil { 108 if err := runSWFProjectDevMode(common.Docker, cfg); err != nil { 109 return err 110 } 111 } else { 112 return fmt.Errorf("there is no docker or podman available") 113 } 114 return nil 115 } 116 117 func runSWFProjectDevMode(containerTool string, cfg RunCmdConfig) (err error) { 118 fmt.Println("⏳ Starting your SonataFlow project in dev mode...") 119 path, err := os.Getwd() 120 if err != nil { 121 fmt.Errorf("❌ Error running SonataFlow project: %w", err) 122 } 123 124 common.GracefullyStopTheContainerWhenInterrupted(containerTool) 125 126 var wg sync.WaitGroup 127 wg.Add(1) 128 129 go func() { 130 defer wg.Done() 131 if err := common.RunContainerCommand(containerTool, cfg.PortMapping, path); err != nil { 132 fmt.Errorf("❌ Error running SonataFlow project: %w", err) 133 } 134 }() 135 136 readyCheckURL := fmt.Sprintf("http://localhost:%s/q/health/ready", cfg.PortMapping) 137 pollInterval := 5 * time.Second 138 common.ReadyCheck(readyCheckURL, pollInterval, cfg.PortMapping, cfg.OpenDevUI) 139 140 wg.Wait() 141 return err 142 }