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