~ahasenack/charms/precise/swift-storage/use-charm-dir

« back to all changes in this revision

Viewing changes to hooks/lib/openstack-common

  • Committer: Adam Gandelman
  • Date: 2013-01-07 23:25:53 UTC
  • mfrom: (15.1.13 swift-storage)
  • Revision ID: adamg@canonical.com-20130107232553-i0k0u397vhe6ke1d
Merge swift-storage rewrite work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/bin/bash -e
 
2
 
 
3
# Common utility functions used across all OpenStack charms.
 
4
 
 
5
error_out() {
 
6
  juju-log "$CHARM ERROR: $@"
 
7
  exit 1
 
8
}
 
9
 
 
10
function service_ctl_status {
 
11
  # Return 0 if a service is running, 1 otherwise.
 
12
  local svc="$1"
 
13
  local status=$(service $svc status | cut -d/ -f1 | awk '{ print $2 }')
 
14
  case $status in
 
15
    "start") return 0 ;;
 
16
    "stop") return 1 ;;
 
17
    *) error_out "Unexpected status of service $svc: $status" ;;
 
18
  esac
 
19
}
 
20
 
 
21
function service_ctl {
 
22
  # control a specific service, or all (as defined by $SERVICES)
 
23
  if [[ $1 == "all" ]] ; then
 
24
    ctl="$SERVICES"
 
25
  else
 
26
    ctl="$1"
 
27
  fi
 
28
  action="$2"
 
29
  if [[ -z "$ctl" ]] || [[ -z "$action" ]] ; then
 
30
    error_out "ERROR service_ctl: Not enough arguments"
 
31
  fi
 
32
 
 
33
  for i in $ctl ; do
 
34
    case $action in
 
35
      "start")
 
36
        service_ctl_status $i || service $i start ;;
 
37
      "stop")
 
38
        service_ctl_status $i && service $i stop || return 0 ;;
 
39
      "restart")
 
40
        service_ctl_status $i && service $i restart || service $i start ;;
 
41
    esac
 
42
    if [[ $? != 0 ]] ; then
 
43
      juju-log "$CHARM: service_ctl ERROR - Service $i failed to $action"
 
44
    fi
 
45
  done
 
46
}
 
47
 
 
48
function configure_install_source {
 
49
  # Setup and configure installation source based on a config flag.
 
50
  local src="$1"
 
51
 
 
52
  # Default to installing from the main Ubuntu archive.
 
53
  [[ $src == "distro" ]] || [[ -z "$src" ]] && return 0
 
54
 
 
55
  . /etc/lsb-release
 
56
 
 
57
  # standard 'ppa:someppa/name' format.
 
58
   if [[ "${src:0:4}" == "ppa:" ]] ; then
 
59
    juju-log "$CHARM: Configuring installation from custom src ($src)"
 
60
    add-apt-repository -y "$src" || error_out "Could not configure PPA access."
 
61
    return 0
 
62
  fi
 
63
 
 
64
  # standard 'deb http://url/ubuntu main' entries. gpg key ids must
 
65
  # be appended to the end of url after a |, ie:
 
66
  # 'deb http://url/ubuntu main|$GPGKEYID'
 
67
  if [[ "${src:0:3}" == "deb" ]] ; then
 
68
    juju-log "$CHARM: Configuring installation from custom src URL ($src)"
 
69
    if echo "$src" | grep -q "|" ; then
 
70
      # gpg key id tagged to end of url folloed by a |
 
71
      url=$(echo $src | cut -d'|' -f1)
 
72
      key=$(echo $src | cut -d'|' -f2)
 
73
      juju-log "$CHARM: Importing repository key: $key"
 
74
      apt-key adv --keyserver keyserver.ubuntu.com --recv-keys "$key" || \
 
75
        juju-log "$CHARM WARN: Could not import key from keyserver: $key"
 
76
    else
 
77
      juju-log "$CHARM No repository key specified."
 
78
      url="$src"
 
79
    fi
 
80
    echo "$url" > /etc/apt/sources.list.d/juju_deb.list
 
81
    return 0
 
82
  fi
 
83
 
 
84
  # Cloud Archive
 
85
  if [[ "${src:0:6}" == "cloud:" ]] ; then
 
86
    local archive_key="5EDB1B62EC4926EA"
 
87
    local rel=$(echo $src | cut -d: -f2)
 
88
    local u_rel=$(echo $rel | cut -d- -f1)
 
89
    local ca_rel=$(echo $rel | cut -d- -f2)
 
90
 
 
91
    [[ "$u_rel" != "$DISTRIB_CODENAME" ]] &&
 
92
      error_out "Cannot install from Cloud Archive pocket $src " \
 
93
                "on this Ubuntu version ($DISTRIB_CODENAME)!"
 
94
 
 
95
    # CA staging repos are standard PPAs.
 
96
    if echo $ca_rel | grep -q "staging" ; then
 
97
      ca_rel=$(echo $ca_rel | sed -e 's,/,-,g')
 
98
      add-apt-repository -y ppa:ubuntu-cloud-archive/$ca_rel
 
99
      return 0
 
100
    fi
 
101
 
 
102
    # the others are LP-external deb repos.
 
103
    case "$ca_rel" in
 
104
      "folsom"|"folsom/updates") pocket="precise-updates/folsom" ;;
 
105
      "folsom/proposed") pocket="precise-proposed/folsom" ;;
 
106
      *) error_out "Invalid Cloud Archive repo specified: $src"
 
107
    esac
 
108
 
 
109
    entry="deb http://ubuntu-cloud.archive.canonical.com/ubuntu $pocket main"
 
110
    echo "$entry" \
 
111
      >/etc/apt/sources.list.d/ubuntu-cloud-archive-$DISTRIB_CODENAME.list
 
112
    apt-key  adv --keyserver keyserver.ubuntu.com --recv-keys $archive_key
 
113
    return 0
 
114
  fi
 
115
 
 
116
  error_out "Invalid installation source specified in config: $src"
 
117
 
 
118
}
 
119
 
 
120
get_os_codename_install_source() {
 
121
  # derive the openstack release provided by a supported installation source.
 
122
  local rel="$1"
 
123
  local codename="unknown"
 
124
  . /etc/lsb-release
 
125
 
 
126
  # map ubuntu releases to the openstack version shipped with it.
 
127
  if [[ "$rel" == "distro" ]] ; then
 
128
    case "$DISTRIB_CODENAME" in
 
129
      "oneiric") codename="diablo" ;;
 
130
      "precise") codename="essex" ;;
 
131
      "quantal") codename="folsom" ;;
 
132
      "raring")  codename="grizzly" ;;
 
133
    esac
 
134
  fi
 
135
 
 
136
  # derive version from cloud archive strings.
 
137
  if [[ "${rel:0:6}" == "cloud:" ]] ; then
 
138
    rel=$(echo $rel | cut -d: -f2)
 
139
    local u_rel=$(echo $rel | cut -d- -f1)
 
140
    local ca_rel=$(echo $rel | cut -d- -f2)
 
141
    if [[ "$u_rel" == "$DISTRIB_CODENAME" ]] ; then
 
142
      case "$ca_rel" in
 
143
        "folsom"|"folsom/updates"|"folsom/proposed"|"folsom/staging")
 
144
          codename="folsom" ;;
 
145
        "grizzly"|"grizzly/updates"|"grizzly/proposed"|"grizzly/staging")
 
146
          codename="grizzly" ;;
 
147
      esac
 
148
    fi
 
149
  fi
 
150
 
 
151
  # have a guess based on the deb string provided
 
152
  if [[ "${rel:0:3}" == "deb" ]]; then
 
153
    CODENAMES="diablo essex folsom grizzly"
 
154
    for cname in $CODENAMES; do
 
155
      if echo $rel | grep -q $cname; then
 
156
        codename=$cname
 
157
      fi
 
158
    done
 
159
  fi
 
160
  echo $codename
 
161
}
 
162
 
 
163
get_os_codename_package() {
 
164
  local pkg_vers=$(dpkg -l | grep "$1" | awk '{ print $3 }') || echo "none"
 
165
  case "${pkg_vers:0:6}" in
 
166
    "2011.2") echo "diablo" ;;
 
167
    "2012.1") echo "essex" ;;
 
168
    "2012.2") echo "folsom" ;;
 
169
    "2013.1") echo "grizzly" ;;
 
170
  esac
 
171
}
 
172
 
 
173
get_os_version_codename() {
 
174
  case "$1" in
 
175
    "diablo") echo "2011.2" ;;
 
176
    "essex") echo "2012.1" ;;
 
177
    "folsom") echo "2012.2" ;;
 
178
    "grizzly") echo "2012.3" ;;
 
179
  esac
 
180
}
 
181
 
 
182
get_ip() {
 
183
  dpkg -l | grep -q python-dnspython || {
 
184
    apt-get -y install python-dnspython 2>&1 > /dev/null
 
185
  }
 
186
  hostname=$1
 
187
  python -c "
 
188
import dns.resolver
 
189
import socket
 
190
try:
 
191
  # Test to see if already an IPv4 address
 
192
  socket.inet_aton('$hostname')
 
193
  print '$hostname'
 
194
except socket.error:
 
195
  try:
 
196
    answers = dns.resolver.query('$hostname', 'A')
 
197
    if answers:
 
198
      print answers[0].address
 
199
  except dns.resolver.NXDOMAIN:
 
200
    pass
 
201
"
 
202
}
 
203
 
 
204
# Common storage routines used by cinder, nova-volume and swift-storage.
 
205
clean_storage() {
 
206
  # if configured to overwrite existing storage, we unmount the block-dev
 
207
  # if mounted and clear any previous pv signatures
 
208
  local block_dev="$1"
 
209
  juju-log "Cleaining storage '$block_dev'"
 
210
  if grep -q "^$block_dev" /proc/mounts ; then
 
211
    mp=$(grep "^$block_dev" /proc/mounts   | awk '{ print $2 }')
 
212
    juju-log "Unmounting $block_dev from $mp"
 
213
    umount "$mp" || error_out "ERROR: Could not unmount storage from $mp"
 
214
  fi
 
215
  if pvdisplay "$block_dev" >/dev/null 2>&1 ; then
 
216
    juju-log "Removing existing LVM PV signatures from $block_dev"
 
217
 
 
218
    # deactivate any volgroups that may be built on this dev
 
219
    vg=$(pvdisplay $block_dev | grep "VG Name" | awk '{ print $3 }')
 
220
    if [[ -n "$vg" ]] ; then
 
221
      juju-log "Deactivating existing volume group: $vg"
 
222
      vgchange -an "$vg" ||
 
223
        error_out "ERROR: Could not deactivate volgroup $vg.  Is it in use?"
 
224
    fi
 
225
    echo "yes" | pvremove -ff "$block_dev" ||
 
226
      error_out "Could not pvremove $block_dev"
 
227
  else
 
228
    juju-log "Zapping disk of all GPT and MBR structures"
 
229
    sgdisk --zap-all $block_dev ||
 
230
      error_out "Unable to zap $block_dev"
 
231
  fi
 
232
}
 
233
 
 
234
function get_block_device() {
 
235
  # given a string, return full path to the block device for that
 
236
  # if input is not a block device, find a loopback device
 
237
  local input="$1"
 
238
 
 
239
  case "$input" in
 
240
    /dev/*) [[ ! -b "$input" ]] && error_out "$input does not exist."
 
241
            echo "$input"; return 0;;
 
242
    /*) :;;
 
243
    *)  [[ ! -b "/dev/$input" ]] && error_out "/dev/$input does not exist."
 
244
        echo "/dev/$input"; return 0;;
 
245
  esac
 
246
 
 
247
  # this represents a file
 
248
  # support "/path/to/file|5G"
 
249
  local fpath size oifs="$IFS"
 
250
  if [ "${input#*|}" != "${input}" ]; then
 
251
    size=${input##*|}
 
252
    fpath=${input%|*}
 
253
  else
 
254
    fpath=${input}
 
255
    size=5G
 
256
  fi
 
257
 
 
258
  ## loop devices are not namespaced.  This is bad for containers.
 
259
  ## it means that the output of 'losetup' may have the given $fpath
 
260
  ## in it, but that may not represent this containers $fpath, but
 
261
  ## another containers.  To address that, we really need to
 
262
  ## allow some uniq container-id to be expanded within path.
 
263
  ## TODO: find a unique container-id that will be consistent for
 
264
  ##       this container throughout its lifetime and expand it
 
265
  ##       in the fpath.
 
266
  # fpath=${fpath//%{id}/$THAT_ID}
 
267
 
 
268
  local found=""
 
269
  # parse through 'losetup -a' output, looking for this file
 
270
  # output is expected to look like:
 
271
  #   /dev/loop0: [0807]:961814 (/tmp/my.img)
 
272
  found=$(losetup -a |
 
273
    awk 'BEGIN { found=0; }
 
274
         $3 == f { sub(/:$/,"",$1); print $1; found=found+1; }
 
275
         END { if( found == 0 || found == 1 ) { exit(0); }; exit(1); }' \
 
276
         f="($fpath)")
 
277
 
 
278
  if [ $? -ne 0 ]; then
 
279
    echo "multiple devices found for $fpath: $found" 1>&2
 
280
    return 1;
 
281
  fi
 
282
 
 
283
  [ -n "$found" -a -b "$found" ] && { echo "$found"; return 1; }
 
284
 
 
285
  if [ -n "$found" ]; then
 
286
    echo "confused, $found is not a block device for $fpath";
 
287
    return 1;
 
288
  fi
 
289
 
 
290
  # no existing device was found, create one
 
291
  mkdir -p "${fpath%/*}"
 
292
  truncate --size "$size" "$fpath" ||
 
293
    { echo "failed to create $fpath of size $size"; return 1; }
 
294
 
 
295
  found=$(losetup --find --show "$fpath") ||
 
296
    { echo "failed to setup loop device for $fpath" 1>&2; return 1; }
 
297
 
 
298
  echo "$found"
 
299
  return 0
 
300
}