summaryrefslogtreecommitdiff
path: root/ec2init/DataSourceEc2.py
blob: 123ede67be1c72a5bb47248782d8e192b1dd1f61 (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 socket
import urllib2
import time
import cPickle
import boto_utils

class DataSourceEc2(DataSource.DataSource):
    api_ver  = '2009-04-04'
    cachedir = ec2init.cachedir + '/ec2'

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

    def __init__(self):
        pass

    def get_data(self):
        try:
            udf = open(self.cachedir + "/user-data.raw")
            self.userdata_raw = udf.read()
            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.userdata_raw = boto_utils.get_instance_userdata(self.api_ver)
            self.metadata = boto_utils.get_instance_metadata(self.api_ver)
            return True
        except Exception as e:
            print e
            return False

    def get_instance_id(self):
        return(self.metadata['instance-id'])

    def get_availability_zone(self):
        return(self.metadata['placement']['availability-zone'])

    def get_local_mirror(self):
        return(self.get_mirror_from_availability_zone())

    def get_locale(self):
        az = self.metadata['placement']['availability-zone']
        if self.location_locale_map.has_key(az[0:2]):
            return(self.location_locale_map[az[0:2]])
        else:
            return(self.location_locale_map["default"])

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

    def get_mirror_from_availability_zone(self, availability_zone = None):
        # availability is like 'us-west-1b' or 'eu-west-1a'
        if availability_zone == None:
            availability_zone = self.get_availability_zone()

        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_public_ssh_keys(self):
        keys = []
        if not self.metadata.has_key('public-keys'): return([])
        for keyname, klist in self.metadata['public-keys'].items():
            # lp:506332 uec metadata service responds with
            # data that makes boto populate a string for 'klist' rather
            # than a list.
            if isinstance(klist,str):
                klist = [ klist ]
            for pkey in klist:
                # there is an empty string at the end of the keylist, trim it
                if pkey:
                    keys.append(pkey)

        return(keys)

    def getswap_devs(self):
        if not self.metadata.has_key('block-device-mapping'):
            raise Exception("no block-device-mapping")
        list = []
        for use_t, device in self.metadata['block-device-mapping'].items():
            if not device.startswith("/dev"):
                device="/dev/%s" % device
            if use_t == "swap":
                list.append(device)
        return(list)