summaryrefslogtreecommitdiff
path: root/ec2init/DataSourceEc2.py
blob: 8ee92d29a283803380afac8f49385e52246c2fe3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import DataSource

import ec2init
import boto.utils
import socket
import urllib2
import time
import cPickle

class DataSourceEc2(DataSource.DataSource):
    api_ver  = '2009-04-04'
    conffile = '/etc/ec2-init/ec2-config.cfg'
    cachedir = ec2init.cachedir + '/ec2'

    location_locale_map = { 
        'us' : 'en_US.UTF-8',
        'eu' : 'en_GB.UTF-8'
    }

    location_archive_map = { 
        'us' : 'http://us.ec2.archive.ubuntu.com/ubuntu',
        'eu' : 'http://eu.ec2.archive.ubuntu.com/ubuntu'
    }

    def __init__(self):
        self.meta_data_base_url = 'http://169.254.169.254/%s/meta-data' % self.api_ver
        self.user_data_base_url = 'http://169.254.169.254/%s/user-data' % self.api_ver

    def get_data(self):
        try:
            udf = open(self.cachedir + "/user-data.pkl")
            self.userdata_raw = cPickle.load(udf)
            udf.close()

            mdf = open(self.cachedir + "/meta-data.pkl")
            self.metadata = cPickle.load(mdf)
            mdf.close()

            return True
        except:
            pass

        try:
            if not self.wait_for_metadata_service():
                return False
            self.metadata = boto.utils.get_instance_userdata(api_ver)
            self.userdata_raw = boto.utils.get_instance_metadata(api_ver)
        except Exception as e:
            print e
            return False

    def wait_or_bail(self):
        if self.wait_for_metadata_service():
            return True
        else:
            bailout_command = self.get_cfg_option_str('bailout_command')
            if bailout_command:
                os.system(bailout_command)
            return False

    def get_cfg_option_str(self, key, default=None):
        return self.config.get(key, default)

    def get_ssh_keys(self):
        conn = urllib2.urlopen('%s/public-keys/' % self.meta_data_base_url)
        data = conn.read()
        keyids = [line.split('=')[0] for line in data.split('\n')]
        return [urllib2.urlopen('%s/public-keys/%d/openssh-key' % (self.meta_data_base_url, int(keyid))).read().rstrip() for keyid in keyids]

#    def get_user_data(self):
#        return boto.utils.get_instance_userdata()
#
#    def get_instance_metadata(self):
#        self.instance_metadata = getattr(self, 'instance_metadata', boto.utils.get_instance_metadata())
#        return self.instance_metadata 

    def get_ami_id(self):
        return self.get_instance_metadata()['ami-id']
    
    def get_availability_zone(self):
        conn = urllib2.urlopen('%s/placement/availability-zone' % self.meta_data_base_url)
        return conn.read()

    def get_hostname(self):
        hostname = self.get_instance_metadata()['local-hostname']
        hostname = hostname.split('.')[0]
        return hostname

    def get_mirror_from_availability_zone(self, availability_zone):
        # availability is like 'us-west-1b' or 'eu-west-1a'
        try:
            host="%s.ec2.archive.ubuntu.com" % availability_zone[:-1]
            socket.getaddrinfo(host, None, 0, socket.SOCK_STREAM)
            return 'http://%s/ubuntu/' % host
        except:
            return 'http://archive.ubuntu.com/ubuntu/'

    def wait_for_metadata_service(self, sleeps = 10):
        sleeptime = 1
        for x in range(sleeps):
            s = socket.socket()
            try:
                address = '169.254.169.254'
                port = 80
                s.connect((address,port))
                s.close()
                return True
            except socket.error, e:
                print "sleeping %s" % sleeptime
                time.sleep(sleeptime)
                #timeout = timeout * 2
        return False

    def get_location_from_availability_zone(self, availability_zone):
        if availability_zone.startswith('us-'):
            return 'us'
        elif availability_zone.startswith('eu-'):
            return 'eu'
        raise Exception('Could not determine location')