]> review.fuel-infra Code Review - packages/trusty/cirros-testvm.git/blob - cirros-testvm/src-cirros/src/lib/cirros/ds/configdrive
Fix for file injection is broken on centos computes with Cirros images LP #1587960
[packages/trusty/cirros-testvm.git] / cirros-testvm / src-cirros / src / lib / cirros / ds / configdrive
1 #!/bin/sh
2
3 VERBOSITY=0
4 CONFIG=/etc/cirros-init/configdrive
5 NAME="${0##*/}"
6 LABEL="config-2"
7 LABEL_ALT="CONFIG-2"
8 SEED_PRE_D="/var/lib/cloud/seed/configdrive-pre"
9 SEED_POST_D="/var/lib/cloud/seed/configdrive"
10
11 . ${CIRROS_SHLIB:=/lib/cirros/shlib} ||
12         { echo "failed to read ${CIRROS_SHLIB}" 1>&2; exit 1; }
13
14 Usage() {
15         cat <<EOF
16 Usage: ${0##*/} mode output_d
17
18    Datasource for openstack config drive
19 EOF
20 }
21
22 search_local() {
23         local out_d="$1"
24         local devlist="" num="" found="" fstree_d=""
25         local raw_d="" dev="" rdir="" mdjson="" ud="" found=""
26         find_devs_with "LABEL=$LABEL" && [ -n "${_RET}" ] ||
27                 find_devs_with "LABEL=$LABEL_ALT" ||
28                 { error "failed to find devs"; return 1; }
29
30         devlist=${_RET}
31         [ -n "$devlist" ] || { debug 1 "no devices labeled $LABEL"; exit 0; }
32
33         if [ -d "${SEED_PRE_D}" ]; then
34                 devlist="$SEED_PRE_D $devlist"
35         fi
36         if [ -d "${SEED_POST_D}" ]; then
37                 devlist="$devlist $SEED_POST_D"
38         fi
39
40         num=0
41         for dev in ${devlist}; do num=$(($num+1)); done
42         [ $num -eq 1 ] || debug 1 "multiple devices matching $LABEL: $devlist"
43
44         [ -d "$out_d" ] || mkdir -p "$out_d" ||
45                 fail "failed to create outputdir: ${out_d}"
46
47         found=""
48         rdir=""
49         fstree_d="${out_d}/processed"
50         raw_d="${out_d}/raw"
51         for dev in ${devlist}; do
52                 rdir="${raw_d}.tmp"
53                 rm -Rf "$rdir"
54                 if [ -b "$dev" ]; then
55                         mount_callback_umount "$dev" -o,ro cp -a "${rdir}" ||
56                                 { debug 1 "mount callback umount $dev failed"; continue; }
57                 else
58                         cp -a "$dev" "${rdir}" ||
59                                 { debug 1 "failed to copy from $dev"; continue; }
60                 fi
61
62                 mdjson="$rdir/openstack/latest/meta_data.json"
63                 if [ -f "$mdjson" ]; then
64                         json2fstree "$fstree_d" "$mdjson" ||
65                                 fail "json2fstree failed on $mdjson for $dev"
66                         ud="$rdir/openstack/latest/user_data"
67                         [ -f "$ud" ] && cp "$ud" "$fstree_d/user-data"
68                         found="$dev"
69                         mv "$rdir" "$raw_d" ||
70                                 fail "rename failed!"
71                         break
72                 fi
73         done
74
75         [ -z "$found" ] && return 0
76
77         # now we have filesystem rendering at $fstree_d
78         # and raw data (copy of config drive data) at $raw_d
79         mkdir -p "${out_d}/data" ||
80                 fail "failed to make data dir"
81
82         start_d="$PWD"
83         cd "${out_d}/data"
84         local f="" t="" fix=""
85         set +f
86         for f in ../processed/*; do
87                 [ -f "$f" ] || continue
88                 ln -s "$f" .
89         done
90         set -f
91
92         if [ -d ../processed/public_keys ]; then
93                 set +f
94                 cat ../processed/public_keys/* > public-keys || rm public-keys
95                 set -f
96         fi
97
98         for fix in uuid:instance-id hostname:local-hostname user_data:user-data \
99                 availability_zone:availability-zone launch_index:launch-index; do
100                 f="${fix%:*}"
101                 t="${fix#*:}"
102                 [ -f "$f" -a ! -f "$t" ] || continue
103                 ln -sf "$f" "$t" || fail "failed to link $f to $t"
104         done
105
106         # now create files/ tree
107         cd "${start_d}"
108         cd "${out_d}"
109         local d path content_path omask
110         omask=$(umask)
111         umask 0226
112         if [ -f processed/files/0 ]; then
113                 # processed/files/0 is the length
114                 set +f
115                 for d in processed/files/*; do
116                         [ "${d##*/}" = "0" ] && continue
117                         set -f
118                         [ -f "$d/path" -a -f "$d/content_path" ] ||
119                                 { debug 1 "$d unexpected file dir"; continue; }
120                         { read path < "$d/path" || [ -n "$path" ] ; } &&
121                                 { read content_path < "$d/content_path" ||
122                                   [ -n "$content_path" ]; } ||
123                                 { debug 1 "skipping $d, failed reads"; continue; }
124                         mkdir -p "files/${path%/*}" &&
125                                 cp "raw/openstack/${content_path}" "files/${path}" ||
126                                 { fail "failed to create ${path} in files"; return 1; }
127                 done
128                 set -f
129         fi
130
131         umask $omask
132
133         cd "$start_d"
134         echo 0 > "$out_d/result"
135 }
136
137 apply() {
138         local mode="$1" data_d="$2"
139         if [ -d "$data_d/files" ]; then
140                 local omask="" f="" path="" tpath=""
141                 omask=$(umask)
142                 umask 0226
143                 for f in $(find "$data_d/files/" -type f); do
144                         path="${f#${data_d}/files/}"
145                         tpath="${TARGET_ROOT}/${path}"
146                         mkdir -p "${tpath%/*}" && cp "${f}" "${tpath}" ||
147                                 { error "failed to create ${tpath}"; return 1; }
148                 done
149                 umask "$omask"
150         fi
151 }
152
153 short_opts="hv"
154 long_opts="help,verbose"
155 getopt_out=$(getopt --name "${0##*/}" \
156         --options "${short_opts}" --long "${long_opts}" -- "$@") &&
157         eval set -- "${getopt_out}" ||
158         bad_Usage
159
160 while [ $# -ne 0 ]; do
161         cur=${1}; next=${2};
162         case "$cur" in
163                 -h|--help) Usage ; exit 0;;
164                 -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
165                 --) shift; break;;
166         esac
167         shift;
168 done
169
170 [ $# -eq 2 ] || bad_Usage "must provide mode and output dir"
171 mode="$1"
172 out_d="$2"
173
174 [ "$mode" = "local" -o "$mode" = "apply-local" ] ||
175         { debug 2 "only supported in mode 'local'"; exit 0; }
176
177 [ ! -e "$CONFIG" ] || . "$CONFIG" ||
178         fail "failed to read $CONFIG"
179
180 if [ "$mode" = "local" ]; then
181         search_local "$out_d"
182 elif [ "$mode" = "apply-local" ]; then
183         apply "$mode" "$out_d"
184 else
185         fail "error, unexpected input"
186 fi
187
188 exit
189 # vi: ts=4 noexpandtab