Skip to content

Commit e349bc3

Browse files
authored
Merge pull request #465 from uselagoon/build-hook-execution
feat: support for build hook entrypoints
2 parents 122bcfc + 2b1360d commit e349bc3

File tree

6 files changed

+156
-3
lines changed

6 files changed

+156
-3
lines changed

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ RUN architecture=$(case $(uname -m) in x86_64 | amd64) echo "amd64" ;; aarch64 |
9494

9595
RUN mkdir -p /kubectl-build-deploy/git
9696
RUN mkdir -p /kubectl-build-deploy/lagoon
97+
RUN mkdir -p /kubectl-build-deploy/hooks
9798

9899
WORKDIR /kubectl-build-deploy/git
99100

cmd/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ func init() {
107107
rootCmd.AddCommand(identifyCmd)
108108
rootCmd.AddCommand(validateCmd)
109109
rootCmd.AddCommand(collectCmd)
110+
rootCmd.AddCommand(runCmd)
110111

111112
rootCmd.PersistentFlags().StringP("lagoon-yml", "l", ".lagoon.yml",
112113
"The .lagoon.yml file to read")

cmd/run_hooks.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/spf13/cobra"
8+
"github.com/uselagoon/build-deploy-tool/internal/hooks"
9+
)
10+
11+
var runCmd = &cobra.Command{
12+
Use: "run",
13+
Aliases: []string{"r"},
14+
Short: "Run commands",
15+
}
16+
17+
var runHookCmd = &cobra.Command{
18+
Use: "hooks",
19+
Aliases: []string{"hook", "h"},
20+
Short: "Run build hooks",
21+
Long: "Run build hooks of specific types at entrypoints in a build",
22+
Run: func(cmd *cobra.Command, args []string) {
23+
hookName, err := cmd.Flags().GetString("hook-name")
24+
if err != nil {
25+
fmt.Printf("error reading hook-name flag: %v\n", err)
26+
os.Exit(1)
27+
}
28+
hookDir, err := cmd.Flags().GetString("hook-directory")
29+
if err != nil {
30+
fmt.Printf("error reading hook-directory flag: %v\n", err)
31+
os.Exit(1)
32+
}
33+
dir := fmt.Sprintf("/kubectl-build-deploy/hooks/%s", hookDir)
34+
err = hooks.RunHooks(hookName, dir)
35+
if err != nil {
36+
os.Exit(1)
37+
}
38+
},
39+
}
40+
41+
func init() {
42+
runCmd.AddCommand(runHookCmd)
43+
runHookCmd.Flags().StringP("hook-name", "N", "", "The name of the hooks run")
44+
runHookCmd.Flags().StringP("hook-directory", "D", "", "The name of the hook directory to run")
45+
}

internal/hooks/hooks.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package hooks
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"io"
7+
"os"
8+
"os/exec"
9+
"path/filepath"
10+
"time"
11+
)
12+
13+
func RunHooks(hookName, hookDir string) error {
14+
if _, err := os.Stat(hookDir); os.IsNotExist(err) {
15+
// there are no hooks to run, so just bail
16+
return nil
17+
}
18+
files, err := os.ReadDir(hookDir)
19+
if err != nil {
20+
// there was an error getting the list of files in the hookdirectory
21+
// just bail to prevent issues
22+
fmt.Printf("failed to read hook directory: %s", err)
23+
return nil
24+
}
25+
26+
hookCount := 0
27+
for _, file := range files {
28+
if file.IsDir() || !isExecutable(fmt.Sprintf("%s/%s", hookDir, file.Name())) {
29+
// skip if directory or not executable
30+
continue
31+
}
32+
hookCount++
33+
34+
// print the step header for build log parser
35+
fmt.Printf("##############################################\nBEGIN %s - %d\n##############################################\n", hookName, hookCount)
36+
st := time.Now()
37+
binaryPath := filepath.Join(hookDir, file.Name())
38+
39+
// execute the binary and capture its error
40+
// stream stdout and stderr
41+
var stdBuffer bytes.Buffer
42+
mw := io.MultiWriter(os.Stdout, &stdBuffer)
43+
cmd := exec.Command(binaryPath)
44+
cmd.Stdout = mw
45+
cmd.Stderr = mw
46+
err := cmd.Run()
47+
exitCode := cmd.ProcessState.ExitCode()
48+
49+
var warning string
50+
if exitCode == 1 {
51+
// for 1 return the error and fail the build
52+
return fmt.Errorf("hook %s %d failed with exit code %d: %v", hookName, hookCount, exitCode, err)
53+
} else if exitCode > 1 {
54+
// if the exit code is greater than 1, we will consider as a warning
55+
// set the warning flag for the step footer
56+
warning = " WithWarnings"
57+
// add to the warnings counter to add to the end of the build to flag build as warning
58+
f, err := os.OpenFile("/tmp/warnings", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
59+
if err != nil {
60+
panic(err)
61+
}
62+
defer f.Close()
63+
if _, err = f.WriteString(fmt.Sprintf("%s:%d\n", hookName, hookCount)); err != nil {
64+
panic(err)
65+
}
66+
}
67+
68+
et := time.Now()
69+
diff := time.Time{}.Add(et.Sub(st))
70+
tz, _ := et.Zone()
71+
// print the step footer for build log parser
72+
fmt.Printf("##############################################\nSTEP %s - %d: Completed at %s (%s) Duration %s Elapsed %s%s\n##############################################\n", hookName, hookCount, et.Format("2006-01-02 15:04:05"), tz, diff.Format("15:04:05"), diff.Format("15:04:05"), warning)
73+
}
74+
75+
return nil
76+
}
77+
78+
func isExecutable(filename string) bool {
79+
info, err := os.Stat(filename)
80+
if err != nil {
81+
return false
82+
}
83+
return (info.Mode() & 0111) != 0
84+
}

legacy/build-deploy-docker-compose.sh

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ function cleanupCertificates() {
215215
done
216216
}
217217

218+
touch /tmp/warnings
219+
218220
##############################################
219221
### PREPARATION
220222
##############################################
@@ -262,11 +264,12 @@ if [ ! -z "$(featureFlag IMAGECACHE_REGISTRY)" ]; then
262264
[[ $last_char != "/" ]] && IMAGECACHE_REGISTRY="$IMAGECACHE_REGISTRY/"; :
263265
fi
264266

265-
set +e
266267
currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")"
267268
finalizeBuildStep "${buildStartTime}" "${previousStepEnd}" "${currentStepEnd}" "${NAMESPACE}" "initialSetup" "Initial Environment Setup" "false"
269+
build-deploy-tool run hooks --hook-name "Pre .lagoon.yml Validation" --hook-directory "pre-lagoon-yaml-validation"
268270
previousStepEnd=${currentStepEnd}
269271

272+
set +e
270273
# Validate `lagoon.yml` first to try detect any errors here first
271274
beginBuildStep ".lagoon.yml Validation" "lagoonYmlValidation"
272275
##############################################
@@ -324,6 +327,9 @@ fi
324327

325328
currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")"
326329
finalizeBuildStep "${buildStartTime}" "${previousStepEnd}" "${currentStepEnd}" "${NAMESPACE}" "lagoonYmlValidation" ".lagoon.yml Validation" "false"
330+
set -e
331+
build-deploy-tool run hooks --hook-name "Pre Docker Compose Validation" --hook-directory "pre-docker-compose-validation"
332+
set +e
327333
previousStepEnd=${currentStepEnd}
328334

329335
# The attempt to valid the `docker-compose.yaml` file
@@ -452,11 +458,9 @@ if [[ "$DOCKER_COMPOSE_WARNING_COUNT" -gt 0 ]]; then
452458
echo "##############################################"
453459
currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")"
454460
finalizeBuildStep "${buildStartTime}" "${previousStepEnd}" "${currentStepEnd}" "${NAMESPACE}" "dockerComposeValidationWarning" "Docker Compose Validation" "true"
455-
previousStepEnd=${currentStepEnd}
456461
else
457462
currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")"
458463
finalizeBuildStep "${buildStartTime}" "${previousStepEnd}" "${currentStepEnd}" "${NAMESPACE}" "dockerComposeValidation" "Docker Compose Validation" "false"
459-
previousStepEnd=${currentStepEnd}
460464
fi
461465
set -e
462466

@@ -480,6 +484,8 @@ else
480484
fi
481485
##################
482486

487+
build-deploy-tool run hooks --hook-name "Pre Configure Variables" --hook-directory "pre-configure-variables"
488+
previousStepEnd=${currentStepEnd}
483489
beginBuildStep "Configure Variables" "configuringVariables"
484490

485491
##############################################
@@ -641,6 +647,7 @@ LAGOON_POSTROLLOUT_DISABLED=$(apiEnvVarCheck LAGOON_POSTROLLOUT_DISABLED "false"
641647

642648
currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")"
643649
finalizeBuildStep "${buildStartTime}" "${buildStartTime}" "${currentStepEnd}" "${NAMESPACE}" "configureVars" "Configure Variables" "false"
650+
build-deploy-tool run hooks --hook-name "Pre Container Registry Login" --hook-directory "pre-registry-login"
644651
previousStepEnd=${currentStepEnd}
645652
beginBuildStep "Container Registry Login" "registryLogin"
646653

@@ -1006,6 +1013,7 @@ fi
10061013
# set that the image build and push phase has ended
10071014
IMAGE_BUILD_PUSH_COMPLETE="true"
10081015

1016+
build-deploy-tool run hooks --hook-name "Pre Service Configuration Phase" --hook-directory "pre-service-configuration-phase"
10091017
previousStepEnd=${currentStepEnd}
10101018
beginBuildStep "Service Configuration Phase" "serviceConfigurationPhase"
10111019

@@ -1097,6 +1105,7 @@ fi
10971105

10981106
currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")"
10991107
finalizeBuildStep "${buildStartTime}" "${previousStepEnd}" "${currentStepEnd}" "${NAMESPACE}" "serviceConfigurationComplete" "Service Configuration Phase" "false"
1108+
build-deploy-tool run hooks --hook-name "Pre Route Configuration" --hook-directory "pre-route-configuration"
11001109
previousStepEnd=${currentStepEnd}
11011110
beginBuildStep "Route/Ingress Configuration" "configuringRoutes"
11021111

@@ -1124,6 +1133,7 @@ fi
11241133

11251134
currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")"
11261135
finalizeBuildStep "${buildStartTime}" "${previousStepEnd}" "${currentStepEnd}" "${NAMESPACE}" "configuringRoutesComplete" "Route/Ingress Configuration" "false"
1136+
build-deploy-tool run hooks --hook-name "Pre Route Cleanup" --hook-directory "pre-route-cleanup"
11271137
previousStepEnd=${currentStepEnd}
11281138
beginBuildStep "Route/Ingress Cleanup" "cleanupRoutes"
11291139

@@ -1231,6 +1241,7 @@ if [ "${CURRENT_CHALLENGE_ROUTES[@]}" != "" ]; then
12311241
currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")"
12321242
finalizeBuildStep "${buildStartTime}" "${previousStepEnd}" "${currentStepEnd}" "${NAMESPACE}" "staleChallengesComplete" "Route/Ingress Certificate Challenges" "true"
12331243
fi
1244+
build-deploy-tool run hooks --hook-name "Pre Update Secrets" --hook-directory "pre-update-secrets"
12341245
previousStepEnd=${currentStepEnd}
12351246
beginBuildStep "Update Environment Secrets" "updateEnvSecrets"
12361247

@@ -1508,6 +1519,7 @@ LAGOONPLATFORMENV_SHA=$(kubectl --insecure-skip-tls-verify -n ${NAMESPACE} get s
15081519
CONFIG_MAP_SHA=$(echo $LAGOONENV_SHA$LAGOONPLATFORMENV_SHA | sha256sum | awk '{print $1}')
15091520
export CONFIG_MAP_SHA
15101521

1522+
build-deploy-tool run hooks --hook-name "Pre Backup Configuration" --hook-directory "pre-backup-configuration"
15111523
previousStepEnd=${currentStepEnd}
15121524
beginBuildStep "Backup Configuration" "configuringBackups"
15131525

@@ -1562,6 +1574,7 @@ fi
15621574

15631575
currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")"
15641576
finalizeBuildStep "${buildStartTime}" "${previousStepEnd}" "${currentStepEnd}" "${NAMESPACE}" "backupConfigurationComplete" "Backup Configuration" "false"
1577+
build-deploy-tool run hooks --hook-name "Pre Pre-Rollout Tasks" --hook-directory "pre-pre-rollout"
15651578
previousStepEnd=${currentStepEnd}
15661579
beginBuildStep "Pre-Rollout Tasks" "runningPreRolloutTasks"
15671580

@@ -1578,6 +1591,7 @@ else
15781591
fi
15791592

15801593
currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")"
1594+
build-deploy-tool run hooks --hook-name "Pre Deployment Templating" --hook-directory "pre-deployment-templating"
15811595
previousStepEnd=${currentStepEnd}
15821596
beginBuildStep "Deployment Templating" "templatingDeployments"
15831597

@@ -1617,6 +1631,7 @@ build-deploy-tool template lagoon-services --saved-templates-path ${LAGOON_SERVI
16171631

16181632
currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")"
16191633
finalizeBuildStep "${buildStartTime}" "${previousStepEnd}" "${currentStepEnd}" "${NAMESPACE}" "deploymentTemplatingComplete" "Deployment Templating" "false"
1634+
build-deploy-tool run hooks --hook-name "Pre Applying Deployments" --hook-directory "pre-applying-deployments"
16201635
previousStepEnd=${currentStepEnd}
16211636
beginBuildStep "Applying Deployments" "applyingDeployments"
16221637

@@ -1683,6 +1698,7 @@ fi
16831698

16841699
currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")"
16851700
finalizeBuildStep "${buildStartTime}" "${previousStepEnd}" "${currentStepEnd}" "${NAMESPACE}" "deploymentApplyComplete" "Applying Deployments" "false"
1701+
build-deploy-tool run hooks --hook-name "Pre Cronjob Cleanup" --hook-directory "pre-cronjob-cleanup"
16861702
previousStepEnd=${currentStepEnd}
16871703
beginBuildStep "Cronjob Cleanup" "cleaningUpCronjobs"
16881704

@@ -1716,6 +1732,7 @@ done
17161732

17171733
currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")"
17181734
finalizeBuildStep "${buildStartTime}" "${previousStepEnd}" "${currentStepEnd}" "${NAMESPACE}" "cronjobCleanupComplete" "Cronjob Cleanup" "false"
1735+
build-deploy-tool run hooks --hook-name "Pre Post-Rollout Tasks" --hook-directory "pre-post-rollout"
17191736
previousStepEnd=${currentStepEnd}
17201737
beginBuildStep "Post-Rollout Tasks" "runningPostRolloutTasks"
17211738

@@ -1733,6 +1750,7 @@ else
17331750
fi
17341751

17351752
currentStepEnd="$(date +"%Y-%m-%d %H:%M:%S")"
1753+
build-deploy-tool run hooks --hook-name "Pre Finalizing Build" --hook-directory "pre-finalizing-build"
17361754
previousStepEnd=${currentStepEnd}
17371755
beginBuildStep "Build and Deploy" "finalizingBuild"
17381756

@@ -1803,6 +1821,8 @@ if [ "$(featureFlag INSIGHTS)" = enabled ]; then
18031821

18041822
fi
18051823

1824+
EXTRA_WARNINGS=$(cat /tmp/warnings | wc -l)
1825+
BUILD_WARNING_COUNT=$((BUILD_WARNING_COUNT + EXTRA_WARNINGS))
18061826
if [[ "$BUILD_WARNING_COUNT" -gt 0 ]]; then
18071827
beginBuildStep "Completed With Warnings" "deployCompletedWithWarnings"
18081828
echo "This build completed with ${BUILD_WARNING_COUNT} warnings, you should scan the build for warnings and correct them as necessary"

legacy/build-deploy.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ echo "##############################################"
99

1010
NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
1111
LAGOON_VERSION=$(cat /lagoon/version)
12+
export NAMESPACE
13+
export LAGOON_VERSION
1214

1315
echo -e "##############################################\nBEGIN Checkout Repository\n##############################################"
1416
if [ "$BUILD_TYPE" == "pullrequest" ]; then

0 commit comments

Comments
 (0)