Charm: precise/nova-compute   Revision: 81   Hook: image-service-relation-joined
#!/bin/bash -e
CHARM_DIR=$(dirname $0)
ARG0=${0##*/}

if [[ -e $CHARM_DIR/nova-compute-common ]] ; then
  . $CHARM_DIR/nova-compute-common
else
  juju-log "ERROR: Could not load nova-compute-common from $CHARM_DIR"
fi

function install_hook {
  [ -d exec.d ] && ( for f in exec.d/*/charm-pre-install; do [ -x $f ] && /bin/sh -c "$f";done )
  local virt_type=$(config-get virt-type)
  local compute_pkg=$(determine_compute_package "$virt_type")
  apt-get -y install python-software-properties || exit 1
  configure_install_source "$(config-get openstack-origin)"
  apt-get update || exit 1
  apt-get -y install $compute_pkg $PACKAGES || exit 1
  service_ctl all stop
  set_or_update "auth_strategy" "keystone"
  configure_libvirt
}

function upgrade_hook {
  [ -d exec.d ] && ( for f in exec.d/*/charm-pre-install; do [ -x $f ] && /bin/sh -c "$f";done )
}

function config_changed() {

  # Determine whether or not we should do an upgrade, based on whether or not
  # the version offered in openstack-origin is greater than what is installed.

  local install_src=$(config-get openstack-origin)
  local cur=$(get_os_codename_package "nova-common")
  local available=$(get_os_codename_install_source "$install_src")

  if dpkg --compare-versions $(get_os_version_codename "$cur") lt \
                             $(get_os_version_codename "$available") ; then
    juju-log "$CHARM: Upgrading OpenStack release: $cur -> $available."
    do_openstack_upgrade "$install_src" $PACKAGES
  fi

  set_config_flags
  service_ctl all restart
}

function amqp_joined {
  # we request a username on the rabbit queue
  # and store it in nova.conf. our response is its IP + PASSWD
  # but we configure that in _changed
  local rabbit_user=$(config-get rabbit-user)
  local rabbit_vhost=$(config-get rabbit-vhost)
  juju-log "$CHARM - amqp_joined: requesting credentials for $rabbit_user"
  relation-set username=$rabbit_user
  relation-set vhost=$rabbit_vhost
}

function amqp_changed {
  # server creates our credentials and tells us where
  # to connect.  for now, using default vhost '/'
  local rabbit_host=$(relation-get private-address)
  local rabbit_password=$(relation-get password)

  if [[ -z $rabbit_host ]] || \
     [[ -z $rabbit_password ]] ; then
      juju-log "$CHARM - amqp_changed: rabbit_host||rabbit_password not set."
      exit 0
  fi

  local rabbit_user=$(config-get rabbit-user)
  local rabbit_vhost=$(config-get rabbit-vhost)
  juju-log "$CHARM - amqp_changed: Setting rabbit config in nova.conf: " \
           "$rabbit_user@$rabbit_host/$rabbit_vhost"
  set_or_update rabbit_host $rabbit_host
  set_or_update rabbit_userid $rabbit_user
  set_or_update rabbit_password $rabbit_password
  set_or_update rabbit_virtual_host $rabbit_vhost

  if [ "$NET_MANAGER" == "Quantum" ]; then
    set_or_update rabbit_host "$rabbit_host" "$QUANTUM_CONF"
    set_or_update rabbit_userid "$rabbit_user" "$QUANTUM_CONF"
    set_or_update rabbit_password "$rabbit_password" "$QUANTUM_CONF"
    set_or_update rabbit_virtual_host "$rabbit_vhost" "$QUANTUM_CONF"
  fi

  service_ctl all restart
}

function db_joined {
  # tell mysql provider which database we want. it will create it and give us
  # credentials
  local nova_db=$(config-get nova-db)
  local db_user=$(config-get db-user)
  local hostname=$(unit-get private-address)
  juju-log "$CHARM - db_joined: requesting database access to $nova_db for "\
           "$db_user@$hostname"
  relation-set nova_database=$nova_db nova_username=$db_user nova_hostname=$hostname
  if [ "$NET_MANAGER" == "Quantum" ]; then
    relation-set quantum_database=quantum quantum_username=quantum quantum_hostname=$hostname
  fi
}

function db_changed {
  local db_host=`relation-get private-address`
  local db_password=`relation-get nova_password`

  if [[ -z $db_host ]] || [[ -z $db_password ]] ; then
    juju-log "$CHARM - db_changed: db_host||db_password set, will retry."
    exit 0
  fi

  local nova_db=$(config-get nova-db)
  local db_user=$(config-get db-user)
  juju-log "$CHARM - db_changed: Configuring nova.conf for access to $nova_db"

  set_or_update sql_connection "mysql://$db_user:$db_password@$db_host/$nova_db"

  if [ "$NET_MANAGER" == "Quantum" ]; then
    local quantum_db_password=`relation-get quantum_password`
    set_or_update sql_connection "mysql://quantum:$quantum_db_password@$db_host/quantum?charset=utf8" \
      $QUANTUM_PLUGIN_CONF "DATABASE"
  fi

  service_ctl all restart
}

function image-service_changed {
  GLANCE_API_SERVER=`relation-get glance-api-server`
  if [[ -z $GLANCE_API_SERVER ]] ; then
    echo "image-service_changed: GLANCE_API_SERVER not yet set. Exit 0 and retry"
    exit 0
  fi
  set_or_update glance_api_servers $GLANCE_API_SERVER
  service_ctl all restart
}

function compute_changed {
  # nova-c-c will inform us of the configured network manager.  nova-compute
  # needs to configure itself accordingly.
  network_manager=`relation-get network_manager`
  if [[ -n "$network_manager" ]] ; then
    if [ "$network_manager" == "Quantum" ]; then
      configure_network_manager "$network_manager" "$(relation-get quantum_plugin)"
      configure_quantum_bridge
      # Quantum also needs access to the quantum database
      # depending on add-relation order, this relation
      # may already be present so ask it for credentials if so
      r_ids="$(relation-ids shared-db)"
      for id in $r_ids ; do
        relation-set -r $id \
          quantum_database=quantum \
          quantum_username=quantum \
          quantum_hostname=$(unit-get private-address)
      done
      # Rabbit MQ relation may also already be in place
      # shared vhost with nova so just grab settings and
      # configure
      r_ids="$(relation-ids amqp)"
      for id in $r_ids ; do
        for unit in $(relation-list -r $id) ; do
          local rabbit_host=$(relation-get -r $id private-address $unit)
          local rabbit_password=$(relation-get -r $id password $unit)
          if [[ -n $rabbit_host ]] && \
             [[ -n $rabbit_password ]]; then
            set_or_update rabbit_host "$rabbit_host" "$QUANTUM_CONF"
            set_or_update rabbit_userid "$(config-get rabbit-user)" "$QUANTUM_CONF"
            set_or_update rabbit_password "$rabbit_password" "$QUANTUM_CONF"
            set_or_update rabbit_virtual_host "$(config-get rabbit-vhost)" "$QUANTUM_CONF"
          fi
        done
      done
    else
      configure_network_manager "$network_manager"
    fi
  fi

  # nova-c-c informs us of what volume service has been deployed.
  volume_service=`relation-get volume_service`
  [[ -n "$volume_service" ]] && configure_volume_service "$volume_service"

  # restart on all changed events. nova-c-c may send out a uuid to trigger
  # remote restarts of services here (after db migrations, for instance)
  service_ctl all restart
}

function ceph_joined {
  mkdir -p /etc/ceph
  apt-get -y install ceph-common || exit 1
}

function ceph_changed {
  SERVICE_NAME=`echo $JUJU_UNIT_NAME | cut -d / -f 1`
  KEYRING=/etc/ceph/ceph.client.$SERVICE_NAME.keyring
  KEY=`relation-get key`
  if [ -n "$KEY" ]; then
    # But only once
    if [ ! -f $KEYRING ]; then
      ceph-authtool $KEYRING \
        --create-keyring --name=client.$SERVICE_NAME \
        --add-key="$KEY"
      chmod +r $KEYRING
    fi
  else
    # No key - bail for the time being
    exit 0
  fi

  MONS=`relation-list`
  mon_hosts=""
  for mon in $MONS; do
    mon_hosts="$mon_hosts $(get_ip $(relation-get private-address $mon)):6789"
  done
  cat > /etc/ceph/ceph.conf << EOF
[global]
 auth supported = $(relation-get auth)
 keyring = /etc/ceph/\$cluster.\$name.keyring
 mon host = $mon_hosts
EOF

  if [ ! -f /etc/ceph/secret.xml ]; then
    cat > /etc/ceph/secret.xml << EOF
<secret ephemeral='no' private='no'>
   <usage type='ceph'>
     <name>client.$SERVICE_NAME secret</name>
   </usage>
</secret>
EOF
    # Create secret for libvirt usage
    # note that this does limit ceph usage to 
    # KVM only at this point in time.
    uuid=$(virsh secret-define --file /etc/ceph/secret.xml | cut -d " " -f 2)
    virsh secret-set-value --secret $uuid --base64 $KEY
    set_or_update rbd_user $SERVICE_NAME
    set_or_update rbd_secret_uuid $uuid
    set_or_update rbd_pool nova
    service_ctl all restart
  fi
}

case $ARG0 in
  "install") install_hook ;;
  "upgrade-charm") upgrade_hook ;;
  "start"|"stop") exit 0 ;;
  "config-changed") config_changed ;;
  "amqp-relation-joined") amqp_joined ;;
  "amqp-relation-changed") amqp_changed ;;
  "shared-db-relation-joined") db_joined ;;
  "shared-db-relation-changed") db_changed ;;
  "image-service-relation-joined") exit 0 ;;
  "image-service-relation-changed") image-service_changed ;;
  "identity-service-relation-joined") keystone_joined ;;
  "identity-service-relation-changed") exit 0 ;;
  "ceph-relation-joined") ceph_joined;;
  "ceph-relation-changed") ceph_changed;;
  "cloud-compute-relation-joined" ) exit 0 ;;
  "cloud-compute-relation-changed") compute_changed ;;
esac