-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·214 lines (177 loc) · 6.85 KB
/
Copy pathinstall.sh
File metadata and controls
executable file
·214 lines (177 loc) · 6.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#!/usr/bin/env bash
# Ensure script stops on error
set -euo pipefail
# Function to add colors
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 3)
BLUE=$(tput setaf 4)
BOLD=$(tput bold)
RESET=$(tput sgr0)
# Constants
INSTALL_PATH="./charts"
SUCCESS=false
# Validate dependencies
command -v git >/dev/null 2>&1 || { echo >&2 "git is required but not installed. Aborting."; exit 1; }
command -v yq >/dev/null 2>&1 || { echo >&2 "yq is required but not installed. Aborting."; exit 1; }
# Function to validate project name
validate_project_name() {
local project_name="$1"
# Optional: Add more validation if needed (e.g., must start with a letter)
if [[ ! "$project_name" =~ ^[a-zA-Z][a-zA-Z0-9-]*$ ]]; then
echo "❌ Error: Project name must start with a letter and can only contain letters, numbers, and hyphens." >&2
return 1
fi
return 0
}
# Function to get user input
get_input() {
local prompt="$1"
local default="${2:-}"
local input
while true; do
if [ -n "$default" ]; then
read -p "🔹 $prompt [$default]: " input < /dev/tty
input=${input:-$default}
else
read -p "🔹 $prompt: " input < /dev/tty
fi
if [ -n "$input" ]; then
echo "$input"
break
else
echo "Input cannot be empty. Please try again." >&2
fi
done
}
# Function to confirm overwrite
confirm_overwrite() {
if [ -d "$INSTALL_PATH" ] && [ -n "$(ls -A "$INSTALL_PATH" 2>/dev/null)" ]; then
echo "${YELLOW}Warning: The directory '$INSTALL_PATH' already exists and is not empty.${RESET}"
read -p "Continuing may overwrite shared configuration files. Do you want to proceed? [y/N]: " -n 1 -r REPLY < /dev/tty
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Operation cancelled."
exit 1
fi
fi
}
# Function to check if project already exists
check_project_exists() {
local project_name="$1"
# Assume no project exists if charts directory is empty or doesn't exist
if [ ! -d "$INSTALL_PATH" ] || [ -z "$(ls -A $INSTALL_PATH 2>/dev/null)" ]; then
return 1
fi
# Check if the project directory exists
if [ -d "$INSTALL_PATH/$project_name" ]; then
echo "❌ Error: A project with the name '$project_name' already exists." >&2
return 0
fi
# Check if the project name is already in helmfile.yaml
if [ -f "$INSTALL_PATH/helmfile.yaml" ]; then
local existing_project=$(yq ".releases[].name" $INSTALL_PATH/helmfile.yaml 2>/dev/null | grep "^$project_name$")
if [ -n "$existing_project" ]; then
echo "❌ Error: A project with the name '$project_name' is already configured in helmfile.yaml." >&2
return 0
fi
fi
return 1
}
# Ensure releases section exists in helmfile.yaml
ensure_releases_section() {
local helmfile_path="$1"
# Check if releases section exists
if ! yq '.releases' "$helmfile_path" > /dev/null 2>&1; then
# Add releases section if it doesn't exist
yq -i '. += {"releases": []}' "$helmfile_path"
fi
}
# Create a temporary directory for the setup
TEMP_DIR=$(mktemp -d)
# Function to handle script cleanup
cleanup_on_exit() {
# Always remove the temp directory
rm -rf "$TEMP_DIR"
if [ "$SUCCESS" = "true" ]; then
echo -e "\n ${GREEN}🎉 Project setup complete for ${BOLD}$project_name${RESET}\n"
echo " Next steps:"
echo -e " ${YELLOW}📝 Update Chart Values${RESET} --> $INSTALL_PATH/$project_name/values.yaml"
echo -e " ${BLUE}🚀 Deploy The Helm Chart${RESET} --> helmfile -f $INSTALL_PATH/helmfile.yaml apply"
echo -e " ${BLUE}🤖 Deploy With ArgoCD${RESET} --> kubectl apply -f $INSTALL_PATH/argocd/application.yaml\n"
else
echo "An error occurred or script was interrupted"
echo "Cleanup finished."
fi
}
trap cleanup_on_exit EXIT
# Prompt for overwrite if necessary
confirm_overwrite
# Get project details with validation
while true; do
project_name=$(get_input "Enter the project name")
# Validate project name
if ! validate_project_name "$project_name"; then
continue
fi
# Check if project exists
if check_project_exists "$project_name"; then
continue
fi
break
done
# Get project namespace with validation
while true; do
project_namespace=$(get_input "Enter the project namespace" "openad-models")
# Validate project name
if ! validate_project_name "$project_namespace"; then
continue
fi
break
done
# Get git repo URL
repo_url=$(get_input "Enter the Git repository URL" "$(git config --get remote.origin.url 2>/dev/null || echo '')")
# --- All operations will happen in the temp dir ---
CLONE_DIR="$TEMP_DIR/openad-model-helm-template"
TARGET_PROJECT_DIR="$TEMP_DIR/$project_name"
TARGET_ARGOCD_DIR="$TEMP_DIR/argocd"
TARGET_HELMFILE="$TEMP_DIR/helmfile.yaml"
# Clone repository into temp dir
git clone --depth 1 https://github.com/acceleratedscience/openad-model-helm-template.git "$CLONE_DIR" > /dev/null 2>&1
# Prepare directories in temp
mkdir -p "$TARGET_PROJECT_DIR"
cp -r "$CLONE_DIR/helm/"* "$TARGET_PROJECT_DIR"
cp -r "$CLONE_DIR/argocd" "$TARGET_ARGOCD_DIR"
# Handle helmfile.yaml in temp
if [ -f "$INSTALL_PATH/helmfile.yaml" ]; then
cp "$INSTALL_PATH/helmfile.yaml" "$TARGET_HELMFILE"
else
cp "$CLONE_DIR/helmfile.yaml" "$TARGET_HELMFILE"
ensure_releases_section "$TARGET_HELMFILE"
fi
# Modify files in temp
yq -i ".name = \"$project_name\"" "$TARGET_PROJECT_DIR/Chart.yaml"
yq -i ".releases += [{\"name\": \"$project_name\", \"namespace\": \"$project_namespace\", \"chart\": \"./$project_name\"}]" "$TARGET_HELMFILE"
yq -i "
.metadata.name = \"$project_name\" |
.spec.destination.namespace = \"$project_namespace\" |
.spec.source.repoURL = \"$repo_url\" |
.spec.source.path = \"charts/$project_name\" |
.spec.ignoreDifferences[0].name = \"$project_name\" |
.spec.ignoreDifferences[0].jqPathExpressions[0] = \".spec.template.spec.containers[] | select(.name == \\\"$project_name\\\") | .image\"
" "$TARGET_ARGOCD_DIR/application.yaml"
# --- Commit phase: Move files to final destination ---
mkdir -p "$INSTALL_PATH"
# Use cp to handle overwriting existing directories gracefully
cp -R "$TARGET_PROJECT_DIR" "$INSTALL_PATH/"
# Handle argocd application file by appending
mkdir -p "$INSTALL_PATH/argocd"
if [ -f "$INSTALL_PATH/argocd/application.yaml" ] && [ -s "$INSTALL_PATH/argocd/application.yaml" ]; then
# Append to existing non-empty file
echo "---" >> "$INSTALL_PATH/argocd/application.yaml"
cat "$TARGET_ARGOCD_DIR/application.yaml" >> "$INSTALL_PATH/argocd/application.yaml"
else
# Move the new file if destination is empty or doesn't exist
mv "$TARGET_ARGOCD_DIR/application.yaml" "$INSTALL_PATH/argocd/"
fi
cp -R "$TARGET_HELMFILE" "$INSTALL_PATH/"
SUCCESS=true