summaryrefslogtreecommitdiffstats
path: root/core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/docker-init
blob: f98e6688d71c276a2d6d7bff6fb3c5484d38f350 (plain) (blame)
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
215
216
217
218
219
220
221
222
223
224
#!/bin/bash

USER_CONTAINER_CONFIG="$HOME/.local/docker/.bwlp-user-conf"

echo "+ source user_config $USER_CONTAINER_CONFIG"
source $USER_CONTAINER_CONFIG

load_image () {

	IMAGE_SIZE=$(stat --printf="%s" $VM_DISKFILE_RO)
	# check file size of VM_DISKFILE_RO is equals to 4096 = 4kB (because of padding)

	if [[ $CONTAINER_IMAGE_CONTEXT == "DOCKER_ARCHIVE" ]]; then
		# In this case a pre build container image (tar archive from "docker save ...") 
		# will be loaded into the local docker daemon. 
		echo "+ load container image... (please be patient)"
		# create TMP_FILE for docker load output
		local TMP_FILE=$(mktemp)

		# TODO no progress output for docker load
		# load image from tar file
		pv -cN "Image Transfer" < $VM_DISKFILE_RO | docker load -q > $TMP_FILE
		echo "+ $(cat $TMP_FILE)"

		# repotags in docker-archive optional, so the load output can be
		# "Loaded image ID: sha256:<DIGES>" OR "Loaded image: <RepoTag>"
		local repotag=$(head -n 1 $TMP_FILE | awk -F ': ' '{print $2}')
		# rename image and remove old tag
		writelog "docker tag $repotag $CONTAINER_IMAGE_NAME"
		docker tag "$repotag" "$CONTAINER_IMAGE_NAME"
		rm -f -- "$TMP_FILE"
	
	elif [[ "$CONTAINER_IMAGE_CONTEXT" == "DOCKERFILE" || "$CONTAINER_IMAGE_CONTEXT" == "GIT_REPO" ]]; then
		echo "+ build container image with build_context"
		echo "+ docker build --tag $CONTAINER_IMAGE_NAME $CONTAINER_BUILD_CONTEXT"
		docker build --tag $CONTAINER_IMAGE_NAME $CONTAINER_BUILD_CONTEXT
	fi
	retval=$?
	return $retval
}

function build_container_image() 
{
	echo "+ build container image with build_context"
	echo "+ docker build --tag $CONTAINER_IMAGE_TAG $CONTAINER_IMAGE_BUILD_CONTEXT"
	docker build --tag $CONTAINER_IMAGE_TAG $CONTAINER_IMAGE_BUILD_CONTEXT
}

function load_container_image()
{
	# load a pre build container image (tar archive from "docker save ...") 
	# into the local docker daemon. 
	echo "+ load container image... (please be patient)"
	# create TMP_FILE for docker load output
	local TMP_FILE=$(mktemp)

	# TODO no progress output for docker load
	# load image from tar file
	pv -cN "Image Transfer" < $DATA_CONTAINER_DNBD3_IMAGE | docker load -q > $TMP_FILE
	retval=$?
	echo "+ $(cat $TMP_FILE)"

	# repotags in docker-archive optional, so the load output can be
	# "Loaded image ID: sha256:<DIGES>" OR "Loaded image: <RepoTag>"
	local repotag=$(head -n 1 $TMP_FILE | awk -F ': ' '{print $2}')
	# rename image and remove old tag
	writelog "docker tag $repotag $CONTAINER_IMAGE_TAG"
	docker tag "$repotag" "$CONTAINER_IMAGE_TAG"
	rm -f -- "$TMP_FILE"
	return $retval
}

function prepare_dnbd3_mount()
{
	# prepare dnbd3 mount
	DATA_CONTAINER_DNBD3_MOUNT="${DATA_CONTAINER_DIR}/dnbd3.fuse"
	DATA_CONTAINER_DNBD3_LOG="${DATA_CONTAINER_DIR}/dnbd3.log"
	DATA_CONTAINER_DNBD3_IMAGE="${DATA_CONTAINER_DNBD3_MOUNT}/img"

	mkdir -p $DATA_CONTAINER_DNBD3_MOUNT
	# check DNBD3_MOUNT dir exists and is not used

	if [[ -d $DATA_CONTAINER_DNBD3_MOUNT ]]; then
		if [[ -n "$(ls -A $DATA_CONTAINER_DNBD3_MOUNT)" ]]; then
			writelog "+ mount directory not empty"
			umount "$DATA_CONTAINER_DNBD3_MOUNT"
			find "$DATA_CONTAINER_DNBD3_MOUNT" -mindepth 1 -delete
		fi
	fi

	source /opt/openslx/config
	writelog "dnbd3-fuse --host $SLX_DNBD3_SERVERS --image $BWLP_IMAGE_PATH $DATA_CONTAINER_DNBD3_MOUNT"
	dnbd3-fuse --log $DATA_CONTAINER_DNBD3_LOG  --host "${SLX_DNBD3_SERVERS}" --image $BWLP_IMAGE_PATH $DATA_CONTAINER_DNBD3_MOUNT > /dev/null 2>&1
	echo "RETVAL $?"
	if [[ ! -f $DATA_CONTAINER_DNBD3_IMAGE ]]; then
		writelog "+ -FAIL- dnbd3-fuse failed to mount image"
		return 1
	fi

	return 0
}


function prepare_data_volume() 
{
	local display_name=$( jq -r '.displayname' ${DATA_CONTAINER_METADATA} )

	echo "+ prepare data container $display_name"
	local build_context_method=$( jq -r '.build_context_method' ${DATA_CONTAINER_METADATA} )
	local image_file_size=$( jq -r '.filesize' ${DATA_CONTAINER_METADATA} )
	if [[ "$build_context_method" == "0" ]]; then
		writelog "+ container_build_context: dockerfile"
		CONTAINER_IMAGE_BUILD_CONTEXT="$DATA_CONTAINER_DIR"
		CONTAINER_IMAGE_TAG="$(echo ${display_name} | tr -dc '[:alnum:]' | tr '[:upper:]' '[:lower:]')"
		DATA_CONTAINER_IMAGE_NAME=$CONTAINER_IMAGE_TAG
		build_container_image
		retval=$?
	elif [[ "$build_context_method" == "1" ]]; then
		writelog "+ container_build_context: git url"
		CONTAINER_IMAGE_BUILD_CONTEXT=$( jq -r '.build_context_url' ${DATA_CONTAINER_METADATA} )
		CONTAINER_IMAGE_TAG="$(echo ${display_name} | tr -dc '[:alnum:]' | tr '[:upper:]' '[:lower:]')"
		DATA_CONTAINER_IMAGE_NAME=$CONTAINER_IMAGE_TAG
		build_container_image
		retval=$?	
	elif [[ "$build_context_method" == "2" ]]; then
		writelog "+ pull data container"
		DATA_CONTAINER_REPO=$( jq -r '.image_repo' ${DATA_CONTAINER_METADATA} )
		DATA_CONTAINER_IMAGE_NAME="$DATA_CONTAINER_REPO"
		docker pull "$DATA_CONTAINER_REPO"
		retval=$?
	elif  [[ "$build_context_method" == "3" ]]; then
		CONTAINER_IMAGE_TAG="$(echo ${display_name} | tr -dc '[:alnum:]' | tr '[:upper:]' '[:lower:]')"
		DATA_CONTAINER_IMAGE_NAME=$CONTAINER_IMAGE_TAG
		BWLP_IMAGE_PATH=$( jq -r '.imagepath' ${DATA_CONTAINER_METADATA})
		prepare_dnbd3_mount && load_container_image
		retval=$?
	else
		writelog "+ no proper build_context_method (=$build_context_method)"
		return 1
	fi

	## create the volume
	if [[ $retval == 0 ]]; then
		VOLUME_NAME="volume_$(echo ${display_name} | tr -dc '[:alnum:]' | tr '[:upper:]' '[:lower:]')"
		echo "+ create volume VOLUME_NAME=$VOLUME_NAME"
		docker volume create $VOLUME_NAME
		
		# TODO assumption: every data container stores data at /data/
		writelog "+ populate volume with container data"
		writelog "+ docker run -it --rm -v $VOLUME_NAME:/data/ $DATA_CONTAINER_IMAGE_NAME"
		docker run -itd --rm -v $VOLUME_NAME:/data/ $DATA_CONTAINER_IMAGE_NAME
		
		source $DATA_CONTAINER_MOUNT_INFO
		CONTAINER_BIND_MOUNT_STRING+=" --mount type=volume,source=${VOLUME_NAME},target=$MOUNT_TARGET"
	fi
}

function process_volume_mount_info()
{
	for DATA_CONTAINER_DIR in $VOLUME_MOUNT_INFO; do
		echo $DATA_CONTAINER_DIR
		DATA_CONTAINER_METADATA="${DATA_CONTAINER_DIR}/metadata"
		DATA_CONTAINER_MOUNT_INFO="${DATA_CONTAINER_DIR}/mount_info"

		prepare_data_volume
	done
}


main () 
{

	if [[ -n "$VOLUME_MOUNT_INFO" ]]; then
		echo "+ prepare volumes from data container"
		process_volume_mount_info
	fi

	if [[ "$CONTAINER_IMAGE_CONTEXT" == "CONTAINER_REPO" ]]; then
		echo "pull container $CONTAINER_REPO_NAME"
		docker pull $CONTAINER_REPO_NAME

		[ "$?" != 0 ] && echo ".. docker pull not successful ...giving up..." && exit -1

		CONTAINER_IMAGE_NAME="$CONTAINER_REPO_NAME"
	fi

	# TODO only check by image name could be bad, images whith a same name could exist
	
	# check if the container_image_name already loaded in docker daemon
	if [[ -z $(docker images $CONTAINER_IMAGE_NAME -q) ]]; then
		echo "+ Image unknown by docker daemon ..."
		load_image

		if [[ "$retval" != "0" ]]; then
			echo "...could not build/load container image!...giving up..."
			return -1
		fi
	fi

	if [[ -n "$(docker ps -aq)" ]]; then
		echo "+ cleanup running container"
		docker rm --force $(docker ps -aq) > /dev/null
	fi

	echo "+ start container..."
	echo "+ docker run $CONTAINER_RUN_OPTIONS $CONTAINER_BIND_MOUNT_STRING $CONTAINER_IMAGE_NAME $CONTAINER_RUN_COMMAND"
	docker run $CONTAINER_RUN_OPTIONS $CONTAINER_BIND_MOUNT_STRING $CONTAINER_IMAGE_NAME $CONTAINER_RUN_COMMAND

	if [[ "$?" != "0" ]]; then
		echo "...container start failed!...giving up..."
		return -1
	fi
	
	if [[ -n $RUNSCRIPT ]]; then
		echo "+ execute user runscript"
		NOHUP_TMP=$(mktemp)
		nohup /bin/bash $RUNSCRIPT > "$NOHUP_TMP" & tail -f "$NOHUP_TMP"
	fi 
}

main 

# keeping terminal open
bash