diff --git a/cmd/create.go b/cmd/create.go index fdff4fd..4fd50c7 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -17,6 +17,7 @@ import ( "github.com/badtuxx/girus-cli/internal/lab" "github.com/badtuxx/girus-cli/internal/repo" "github.com/badtuxx/girus-cli/internal/templates" + "github.com/badtuxx/girus-cli/utils" "github.com/fatih/color" "github.com/spf13/cobra" ) @@ -30,6 +31,8 @@ var ( skipPortForward bool skipBrowser bool repoIndexURL string + frontendTag string + backendTag string ) var createCmd = &cobra.Command{ @@ -40,6 +43,19 @@ var createCmd = &cobra.Command{ }, } +func setDeploymentTag(tag string, deployment utils.DeploymentMap, verboseMode bool) error { + if tag == "latest" { + return nil + } + + image := fmt.Sprintf("%s:%s", deployment.DockerHubImage, tag) + if err := k8s.UpdateContainerImage("girus", deployment.Name, deployment.ContainerName, image, verboseMode); err != nil { + return err + } + + return nil +} + var createClusterCmd = &cobra.Command{ Use: "cluster", Short: "Cria o cluster Girus", @@ -698,6 +714,18 @@ Por padrão, o deployment embutido no binário é utilizado.`, } } + fmt.Println(headerColor("Sobreescrevendo imagem dos deployments...")) + backendDeployment := utils.Deployments["backend"] + if err := setDeploymentTag(backendTag, backendDeployment, verboseMode); err != nil { + fmt.Println(err) + os.Exit(1) + } + + frontendDeployment := utils.Deployments["frontend"] + if err := setDeploymentTag(frontendTag, frontendDeployment, verboseMode); err != nil { + fmt.Println(err) + os.Exit(1) + } // Reiniciar o backend para carregar os templates fmt.Println("\n" + headerColor(common.T("Reiniciando o backend para carregar os templates...", "Reiniciando el backend para cargar las plantillas..."))) restartCmd := exec.Command("kubectl", "rollout", "restart", "deployment/girus-backend", "-n", "girus") @@ -869,8 +897,10 @@ func init() { // Flags para createClusterCmd createClusterCmd.Flags().StringVarP(&deployFile, "file", "f", "", "Arquivo YAML para deployment do Girus (opcional)") createClusterCmd.Flags().BoolVarP(&verboseMode, "verbose", "v", false, "Modo detalhado com output completo em vez da barra de progresso") - createClusterCmd.Flags().BoolVarP(&skipPortForward, "skip-port-forward", "", false, "Não perguntar sobre configurar port-forwarding") - createClusterCmd.Flags().BoolVarP(&skipBrowser, "skip-browser", "", false, "Não abrir o navegador automaticamente") + createClusterCmd.Flags().BoolVar(&skipPortForward, "skip-port-forward", false, "Não perguntar sobre configurar port-forwarding") + createClusterCmd.Flags().BoolVar(&skipBrowser, "skip-browser", false, "Não abrir o navegador automaticamente") + createClusterCmd.Flags().StringVar(&frontendTag, "frontend-tag", "latest", "Define tag do frontend a ser usada na criação do cluster") + createClusterCmd.Flags().StringVar(&backendTag, "backend-tag", "latest", "Define tag do backend a ser usada na criação do cluster") createClusterCmd.Flags().StringVarP(&containerEngine, "container-engine", "e", "docker", "Engine de container (docker ou podman)") diff --git a/internal/k8s/k8s.go b/internal/k8s/k8s.go index 15720e4..9f30177 100644 --- a/internal/k8s/k8s.go +++ b/internal/k8s/k8s.go @@ -26,6 +26,7 @@ import ( var ( green = color.New(color.FgGreen).SprintFunc() bold = color.New(color.Bold).SprintFunc() + k = "kubectl" ) // KubernetesClient wraper do cliente Kubernetes @@ -356,6 +357,23 @@ func (k *KubernetesClient) CreateDeployment(ctx context.Context, namespace, name return nil } +// Atualiza imagem de um container específico dentro de um deployment. +func UpdateContainerImage(namespace, deployment, containerName, image string, verboseMode bool) error { + updateArgs := []string{"set", "image", deployment, fmt.Sprintf("%s=%s", containerName, image), "-n", namespace} + commandString := fmt.Sprint(strings.Join(updateArgs, " ")) + if verboseMode { + fmt.Printf("Executando comando %s %s\n", k, commandString) + } + + kubectlUpdateCmd := exec.Command(k, updateArgs...) + var stderr bytes.Buffer + kubectlUpdateCmd.Stderr = &stderr + if err := kubectlUpdateCmd.Run(); err != nil { + return fmt.Errorf("falha ao atualizar imagem do deployment [%s] no namespace [%s]: %s", deployment, namespace, stderr.String()) + } + return nil +} + // waitForPodsReady espera até que os pods do Girus (backend e frontend) estejam prontos func WaitForPodsReady(namespace string, timeout time.Duration) error { // Criar formatadores de cores diff --git a/utils/deployments.go b/utils/deployments.go new file mode 100644 index 0000000..2444a88 --- /dev/null +++ b/utils/deployments.go @@ -0,0 +1,12 @@ +package utils + +type DeploymentMap struct { + Name string + ContainerName string + DockerHubImage string +} + +var Deployments = map[string]DeploymentMap{ + "frontend": {Name: "deployment/girus-frontend", ContainerName: "frontend", DockerHubImage: "linuxtips/girus-frontend"}, + "backend": {Name: "deployment/girus-backend", ContainerName: "backend", DockerHubImage: "linuxtips/girus-backend"}, +}