Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use current deployment context in SCRIPT_RUN stage #4814

Open
minhquang4334 opened this issue Mar 10, 2024 · 6 comments
Open

Use current deployment context in SCRIPT_RUN stage #4814

minhquang4334 opened this issue Mar 10, 2024 · 6 comments
Assignees
Labels
kind/enhancement New feature or request

Comments

@minhquang4334
Copy link
Contributor

What would you like to be added:
Use current deployment context (like DeploymentTrigger, DeploymentStatus, etc.) in SCRIPT_RUN stage.
refs: https://pipecd.dev/docs-v0.46.x/user-guide/managing-application/customizing-deployment/script-run/

Why is this needed:
Since we don't know about the current deployment, it is difficult to write a script for customization of the deployment process.

This is similar to GitHubAction, where we can access job and step contexts through a defined property.
refs: https://docs.github.com/en/actions/learn-github-actions/contexts#job-context

@minhquang4334 minhquang4334 added the kind/enhancement New feature or request label Mar 10, 2024
@peaceiris
Copy link
Contributor

peaceiris commented Apr 17, 2024

We look forward to this feature!

In our use case, we want to get the Summary including a docker image tag and deployment ID.

@ffjlabo
Copy link
Member

ffjlabo commented May 22, 2024

@minhquang4334 @peaceiris
Sorry for the late response 🙏

We can realize it by adding the default environment variable for SR_XX (like SR_DEPLOYMENT_ID).
How about this?

apiVersion: pipecd.dev/v1beta1
kind: KubernetesApp
spec:
  name: script-run
  labels:
    env: example
    team: product
  pipeline:
    stages:
      - name: K8S_CANARY_ROLLOUT
        with:
          replicas: 10%
      - name: WAIT
        with:
          duration: 10s
      - name: SCRIPT_RUN
        with:
          run: |
            echo $SR_DEPLOYMENT_ID
      - name: K8S_PRIMARY_ROLLOUT
      - name: K8S_CANARY_CLEAN

@peaceiris
Copy link
Contributor

environment variable for SR_XX (like SR_DEPLOYMENT_ID).

LGTM ʕ◔ϖ◔ʔ

@minhquang4334
Copy link
Contributor Author

minhquang4334 commented May 22, 2024

We can realize it by adding the default environment variable for SR_XX (like SR_DEPLOYMENT_ID).

LGTM 🐳 @ffjlabo

@ffjlabo
Copy link
Member

ffjlabo commented May 22, 2024

Thanks, both 👍 I will try it.

Also, I received a comment from @khanhtc1202 about the implementation.
We should check whether the env values are shared by multiple deployments.

So at first, I will investigate it :)

@ffjlabo ffjlabo self-assigned this May 24, 2024
@ffjlabo
Copy link
Member

ffjlabo commented May 25, 2024

After the investigation, I found out the way is possible. 👍 I will implement it later.

Detail
As the official document, os/exec package executes the command as a new process.

Package exec runs external commands. It wraps os.StartProcess to make it easier to remap stdin and stdout, connect I/O with pipes, and do other adjustments.
https://pkg.go.dev/os/exec

Proceses usually have their own environment variable and separate them.

Also, I tested the behavior using the code below, and it works as I expected.

package main

import (
	"bytes"
	"context"
	"fmt"
	"os"
	"os/exec"

	"golang.org/x/sync/errgroup"
)

func main() {
	// This example shows that each exec.Cmd doesn't share the env value.

	// Scenario:
	// 	When executing "echo $DEPLOYMENT_ID" asynchronously with two exec.Cmd,
	// 	The one is executed after 10s with "sleep 10", the other without any waiting time.
	// Result:
	// 	The output of the first command is "one" and the second is "two". Not shared.
	/*
		% go run main.go
		===== D2 ======
		output: two

		err:
		===== D1 (execute after 5s) ======
		output: one

		err:
	*/
	eg, _ := errgroup.WithContext(context.TODO())
	eg.Go(func() error {
		var outBuf, errBuf bytes.Buffer
		cmd := exec.Command("/bin/sh", "-l", "-c", "sleep 5 && echo $DEPLOYMENT_ID")
		cmd.Env = append(os.Environ(), "DEPLOYMENT_ID=one")
		cmd.Stdout = &outBuf
		cmd.Stderr = &errBuf

		if err := cmd.Run(); err != nil {
			return err
		}

		fmt.Println("===== D1 (execute after 5s) ======")
		fmt.Println("output:", outBuf.String())
		fmt.Println("err:", errBuf.String())

		return nil
	})

	eg.Go(func() error {
		var outBuf, errBuf bytes.Buffer
		cmd := exec.Command("/bin/sh", "-l", "-c", "echo $DEPLOYMENT_ID")
		cmd.Env = append(os.Environ(), "DEPLOYMENT_ID=two")
		cmd.Stdout = &outBuf
		cmd.Stderr = &errBuf

		if err := cmd.Run(); err != nil {
			return err
		}

		fmt.Println("===== D2 ======")
		fmt.Println("output:", outBuf.String())
		fmt.Println("err:", errBuf.String())

		return nil
	})

	if err := eg.Wait(); err != nil {
		fmt.Printf("error :%v\n", err)
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement New feature or request
Projects
Status: Todo
Development

No branches or pull requests

3 participants