Skip to content

Commit 694778f

Browse files
author
Slyke
committed
Added YAML merging Python script, with menu script modifications. Added minor changes and bug fixes to backup.
1 parent 7689228 commit 694778f

File tree

6 files changed

+113
-61
lines changed

6 files changed

+113
-61
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@
22
/services/
33
/volumes/
44
/backups/
5+
/.tmp/*
56
docker-compose.yml
6-
.outofdate
7+
.outofdate
8+
9+
!.gitkeep

.tmp/.gitkeep

Whitespace-only changes.

compose-override.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
services:
2+
mosquitto:
3+
ports:
4+
- 1882:1882

menu.sh

Lines changed: 61 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
#get path of menu correct
44
pushd ~/IOTstack
55

6+
# Consts/vars
7+
TMP_DOCKER_COMPOSE_YML=./.tmp/docker-compose.tmp.yml
8+
DOCKER_COMPOSE_YML=./docker-compose.yml
9+
DOCKER_COMPOSE_OVERRIDE_YML=./compose-override.yml
10+
11+
COMPOSE_VERSION="3.6"
12+
DOCKER_VERSION_MAJOR=18
13+
DOCKER_VERSION_MINOR=2
14+
DOCKER_VERSION_BUILD=0
15+
616
declare -A cont_array=(
717
[portainer]="Portainer"
818
[nodered]="Node-RED"
@@ -79,6 +89,7 @@ docker_setfacl() {
7989
[ -d ./services ] || mkdir ./services
8090
[ -d ./volumes ] || mkdir ./volumes
8191
[ -d ./backups ] || mkdir ./backups
92+
[ -d ./tmp ] || mkdir ./tmp
8293

8394
#give current user rwx on the volumes and backups
8495
[ $(getfacl ./volumes | grep -c "default:user:$USER") -eq 0 ] && sudo setfacl -Rdm u:$USER:rwx ./volumes
@@ -108,47 +119,47 @@ function yml_builder() {
108119

109120
[ -d ./services/ ] || mkdir ./services/
110121

111-
if [ -d ./services/$1 ]; then
112-
#directory already exists prompt user to overwrite
113-
sevice_overwrite=$(whiptail --radiolist --title "Overwrite Option" --notags \
114-
"$1 service directory has been detected, use [SPACEBAR] to select you overwrite option" 20 78 12 \
115-
"none" "Do not overwrite" "ON" \
116-
"env" "Preserve Environment and Config files" "OFF" \
117-
"full" "Pull full service from template" "OFF" \
118-
3>&1 1>&2 2>&3)
119-
120-
case $sevice_overwrite in
121-
122-
"full")
123-
echo "...pulled full $1 from template"
124-
rsync -a -q .templates/$1/ services/$1/ --exclude 'build.sh'
125-
;;
126-
"env")
127-
echo "...pulled $1 excluding env file"
128-
rsync -a -q .templates/$1/ services/$1/ --exclude 'build.sh' --exclude '$1.env' --exclude '*.conf'
129-
;;
130-
"none")
131-
echo "...$1 service not overwritten"
132-
;;
133-
134-
esac
122+
if [ -d ./services/$1 ]; then
123+
#directory already exists prompt user to overwrite
124+
sevice_overwrite=$(whiptail --radiolist --title "Overwrite Option" --notags \
125+
"$1 service directory has been detected, use [SPACEBAR] to select you overwrite option" 20 78 12 \
126+
"none" "Do not overwrite" "ON" \
127+
"env" "Preserve Environment and Config files" "OFF" \
128+
"full" "Pull full service from template" "OFF" \
129+
3>&1 1>&2 2>&3)
135130

136-
else
137-
mkdir ./services/$1
131+
case $sevice_overwrite in
132+
133+
"full")
138134
echo "...pulled full $1 from template"
139135
rsync -a -q .templates/$1/ services/$1/ --exclude 'build.sh'
140-
fi
136+
;;
137+
"env")
138+
echo "...pulled $1 excluding env file"
139+
rsync -a -q .templates/$1/ services/$1/ --exclude 'build.sh' --exclude '$1.env' --exclude '*.conf'
140+
;;
141+
"none")
142+
echo "...$1 service not overwritten"
143+
;;
144+
145+
esac
146+
147+
else
148+
mkdir ./services/$1
149+
echo "...pulled full $1 from template"
150+
rsync -a -q .templates/$1/ services/$1/ --exclude 'build.sh'
151+
fi
141152

142153

143154
#if an env file exists check for timezone
144155
[ -f "./services/$1/$1.env" ] && timezones ./services/$1/$1.env
145156

146-
# if a volumes.yml exists, append to overall volumes.yml file
147-
[ -f "./services/$1/volumes.yml" ] && cat "./services/$1/volumes.yml" >> docker-volumes.yml
157+
# if a volumes.yml exists, append to overall volumes.yml file
158+
[ -f "./services/$1/volumes.yml" ] && cat "./services/$1/volumes.yml" >> docker-volumes.yml
148159

149160
#add new line then append service
150-
echo "" >>docker-compose.yml
151-
cat $service >>docker-compose.yml
161+
echo "" >> $TMP_DOCKER_COMPOSE_YML
162+
cat $service >> $TMP_DOCKER_COMPOSE_YML
152163

153164
#test for post build
154165
if [ -f ./.templates/$1/build.sh ]; then
@@ -194,9 +205,9 @@ SERVER_VERSION_MAJOR=$(echo "$SERVER_VERSION"| cut -d'.' -f 1)
194205
SERVER_VERSION_MINOR=$(echo "$SERVER_VERSION"| cut -d'.' -f 2)
195206
SERVER_VERSION_BUILD=$(echo "$SERVER_VERSION"| cut -d'.' -f 3)
196207

197-
if [ "${SERVER_VERSION_MAJOR}" -ge 18 ] && \
198-
[ "${SERVER_VERSION_MINOR}" -ge 2 ] && \
199-
[ "${SERVER_VERSION_BUILD}" -ge 0 ]; then
208+
if [ "${SERVER_VERSION_MAJOR}" -ge $DOCKER_VERSION_MAJOR ] && \
209+
[ "${SERVER_VERSION_MINOR}" -ge $DOCKER_VERSION_MINOR ] && \
210+
[ "${SERVER_VERSION_BUILD}" -ge $DOCKER_VERSION_BUILD ]; then
200211
echo "Docker version >= 18.2.0. You are good to go."
201212
else
202213
echo ""
@@ -279,9 +290,12 @@ case $mainmenu_selection in
279290

280291
#if no container is selected then dont overwrite the docker-compose.yml file
281292
if [ -n "$container_selection" ]; then
282-
touch docker-compose.yml
283-
echo "version: '3.6'" >docker-compose.yml
284-
echo "services:" >>docker-compose.yml
293+
touch $TMP_DOCKER_COMPOSE_YML
294+
echo "services:" > $TMP_DOCKER_COMPOSE_YML
295+
296+
# Uncomment once sort_keys is available in Pyton->yaml
297+
# echo "version: '$COMPOSE_VERSION'" > $TMP_DOCKER_COMPOSE_YML
298+
# echo "services:" >> $TMP_DOCKER_COMPOSE_YML
285299

286300
#set the ACL for the stack
287301
#docker_setfacl
@@ -298,25 +312,17 @@ case $mainmenu_selection in
298312
echo "$container" >>./services/selection.txt
299313
done
300314

301-
# add custom containers
302-
if [ -f ./services/custom.txt ]; then
303-
if (whiptail --title "Custom Container detected" --yesno "custom.txt has been detected do you want to add these containers to the stack?" 20 78); then
304-
mapfile -t containers <<<$(cat ./services/custom.txt)
305-
for container in "${containers[@]}"; do
306-
echo "Adding $container container"
307-
yml_builder "$container"
308-
done
309-
fi
310-
fi
311-
312-
# if a container needs volume, put it at the end of docker-compose
313-
if [ -f docker-volumes.yml ]; then
314-
echo "" >> docker-compose.yml
315-
echo "volumes:" >> docker-compose.yml
316-
cat docker-volumes.yml >> docker-compose.yml
317-
rm docker-volumes.yml
315+
if [ -f "$DOCKER_COMPOSE_OVERRIDE_YML" ]; then
316+
echo "merging docker overrides with docker-compose.yaml"
317+
python ./scripts/yaml_merge.py $TMP_DOCKER_COMPOSE_YML $DOCKER_COMPOSE_OVERRIDE_YML $DOCKER_COMPOSE_YML
318+
else
319+
echo "no override found, using docker-compose.yaml"
320+
cp $TMP_DOCKER_COMPOSE_YML $DOCKER_COMPOSE_YML
318321
fi
319322

323+
# Prepend compose version after merging/copying, so that merging doesn't move it to the bottom (alphabetically ordered).
324+
echo -e "version: '$COMPOSE_VERSION'\n$(cat $DOCKER_COMPOSE_YML)" > $DOCKER_COMPOSE_YML # Remove once sort_keys works in Python->yaml.
325+
320326
echo "docker-compose successfully created"
321327
echo "run 'docker-compose up -d' to start the stack"
322328
else
@@ -496,4 +502,4 @@ case $mainmenu_selection in
496502

497503
esac
498504

499-
popd
505+
popd > /dev/null 2>&1

scripts/docker_backup.sh

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/bin/bash
22

33
pushd ~/IOTstack
4+
USER=$(whoami)
45

56
[ -d ./backups ] || mkdir ./backups
67

@@ -9,6 +10,10 @@ echo "./docker-compose.yml" >list.txt
910
echo "./services/" >>list.txt
1011
echo "./volumes/" >>list.txt
1112

13+
if [ -f "./compose-override.yml" ]; then
14+
echo "./compose-override.yml" >>list.txt
15+
fi
16+
1217
#if influxdb is running
1318
if [ $(docker ps | grep -c influxdb) -gt 0 ]; then
1419
./scripts/backup_influxdb.sh
@@ -30,12 +35,12 @@ sudo tar -czf \
3035
rm list.txt
3136

3237
#set permission for backup files
33-
sudo chown pi:pi ./backups/backup*
38+
sudo chown $USER:$USER ./backups/backup*
3439

3540
#create local logfile and append the latest backup file to it
3641
echo "backup saved to ./backups/$backupfile"
3742
sudo touch $logfile
38-
sudo chown pi:pi $logfile
43+
sudo chown $USER:$USER $logfile
3944
echo $backupfile >>$logfile
4045

4146
#show size of archive file
@@ -67,7 +72,7 @@ if [ -f ./backups/dropbox ]; then
6772

6873
#write files to be deleted to dropbox logfile
6974
sudo touch $dropboxlog
70-
sudo chown pi:pi $dropboxlog
75+
sudo chown $USER:$USER $dropboxlog
7176
echo $files | tr " " "\n" >$dropboxlog
7277

7378
#delete files from dropbox as per logfile
@@ -81,9 +86,7 @@ if [ -f ./backups/dropbox ]; then
8186
$dropboxuploader delete $dropboxfolder/$file
8287
done < "$input"
8388
fi
84-
8589
echo "backups deleted from dropbox" >>$dropboxlog
86-
8790
fi
8891

8992

scripts/yaml_merge.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import sys
2+
import yaml
3+
4+
if len(sys.argv) < 4:
5+
print("Error: Not enough args")
6+
print("Usage:")
7+
print(" yaml_merge.py [inputFile] [mergeFile] [outputFile]")
8+
print("")
9+
print("Example:")
10+
print(" yaml_merge.py ./.tmp/docker-compose.tmp.yml ./compose-override.yml ./docker-compose.yml")
11+
sys.exit(1)
12+
13+
pathTempDockerCompose = sys.argv[1]
14+
pathOverride = sys.argv[2]
15+
pathOutput = sys.argv[3]
16+
17+
def mergeYaml(priorityYaml, extensionYaml):
18+
if isinstance(priorityYaml,dict) and isinstance(extensionYaml,dict):
19+
for k,v in extensionYaml.iteritems():
20+
if k not in priorityYaml:
21+
priorityYaml[k] = v
22+
else:
23+
priorityYaml[k] = mergeYaml(priorityYaml[k],v)
24+
return priorityYaml
25+
26+
with open(r'%s' % pathTempDockerCompose) as fileTempDockerCompose:
27+
yamlTempDockerCompose = yaml.load(fileTempDockerCompose)
28+
29+
with open(r'%s' % pathOverride) as fileOverride:
30+
yamlOverride = yaml.load(fileOverride)
31+
32+
mergedYaml = mergeYaml(yamlOverride, yamlTempDockerCompose)
33+
34+
with open(r'%s' % pathOutput, 'w') as outputFile:
35+
# yaml.dump(mergedYaml, outputFile, default_flow_style=False, sort_keys=False) # TODO: 'sort_keys' not available in this version of Python/yaml
36+
yaml.dump(mergedYaml, outputFile, default_flow_style=False) # Gotta pretty this up for human consumption

0 commit comments

Comments
 (0)