Beispiel #1
0
class Controller(object):

    def __init__(self, unit=None, group_rules=None):
        state_path = os.path.join(os.environ.get("CHARM_DIR", ""), "rds.state")
        self._state = KVFile(state_path)
        self.unit = unit or Unit()
        self._group_rules = group_rules or ()

    def get_region(self):
        return self.unit.ec2metadata['availability-zone'][:-1]

    def get_rds(self, config):
        return rds.connect_to_region(self.get_region())

    def get_ec2(self, config):
        return rds.connect_to_region(self.get_region())

    def get_db(self, config, instance):
        if 'mysql' in config['engine'].lower():
            db = MySQL(config)
            if not self._state.get('mysql.client'):
                db.install_driver()
                self._state.set('mysql.client', True)
            return db

    def get_svc_dbname(self):
        return self.get_db_identifier()[:16].replace('-', '_')

    def get_db_identifier(self):
        service = os.environ["JUJU_REMOTE_UNIT"].split("/")[0]
        rel_id = os.environ["JUJU_RELATION_ID"].split(":")[-1]
        return "-".join([
            service,
            rel_id,
            os.environ["JUJU_ENV_UUID"]])

    def wait_for_db_instance(self, rds, instance_id):
        # Don't wait more than 10m
        print "test: waiting for db instance", instance_id,
        t = time.time()
        seen = set()
        while True:
            time.sleep(3)
            sys.stdout.write(".")
            try:
                dbs = rds.get_all_dbinstances(instance_id)
            except boto.exception.EC2ResponseError, e:
                if e.error_code == "InvalidInstanceId.NotFound":
                    continue
            db = dbs.pop()
            if db.status == "available":
                print "\ntest: db %s available in %s" % (
                    instance_id, time.time() - t)
                return db
            elif db.status not in seen:
                print "\n  db status", db.status, (time.time() - t),
                seen.add(db.status)
            if time.time() - t > 15 * 60:
                raise RuntimeError(
                    "Database not provisioned within threshold %s" % (
                        instance_id))
Beispiel #2
0
class Controller(BaseController):

    def __init__(self, unit=None):
        self.unit = unit or Unit()
        self._elb = None
        self._ec2 = None
        self._config = None
        state_path = os.path.join(os.environ.get("CHARM_DIR", ""), "elb.state")
        self._state = KVFile(state_path)

    def get_zones(self):
        """
        Get all the zones currently in use by backend instances
        """
        zones = []
        for k, v in self._state.get_all().items():
            zones.append(v['zone'])
        return zones

    def get_elb(self):
        """
        Get the charm elb abstraction.
        """
        if self._elb:
            return self._elb

        data = self.get_config()
        self._elb = ELB(
            data['access-key-id'],
            data['secret-access-key'],
            self.get_region(),
            self.unit.get_service_identifier())

        return self._elb

    def get_instance(self):
        """
        Get the remote instance id and zone the hook is currently
        executing for.

        Also saves the information for future use.
        """
        data = self.unit.relation_get()
        port = data.get('port')
        address = data.get('hostname')

        if not port or not address:
            self.unit.log('Peer address not set, waiting for handshake')
            raise RetryLater()

        ec2 = self.get_ec2()
        instance = self.unit.get_instance(ec2)
        return instance.id, instance.placement

    def on_changed(self):
        """Called when a unit changes it settings or comes online.
        """
        lb = self.get_elb()
        instance_id, zone = self.get_instance()
        if instance_id is None:
            return

        if lb.exists():
            print "added %s to elb %s" % (instance_id, lb.elb_name)
            lb.add(instance_id, zone)
        else:
            print "creating elb %s" % (lb.elb_name)
            lb.create([zone])
            lb.add(instance_id, zone)

    def on_depart(self):
        """Called when a unit is no longer available.
        """
        data = self._state.get(self.unit.remote_unit)
        if data is None:
            print "could not find remote unit %s" % self.unit.remote_unit
            return
        instance_id = data['instance-id']
        lb = self.get_elb()
        if lb.exists():
            print "removed %s from elb %s" % (instance_id, lb.elb_name)
            lb.remove(instance_id)
            self._state.remove(self.unit.remote_unit)
            lb.sync(self.get_zones())

    def on_broken(self):
        """Called when the relationship is broken.
        """
        lb = self.get_elb()
        if lb.exists():
            print "removed elb %s" % (lb.elb_name)
            lb.destroy()

    def on_config_changed(self):
        lb = self.get_elb()
        print lb