summaryrefslogtreecommitdiff
path: root/ec2init/__init__.py
blob: 77f9676084d793668baf2a4993aef2bb3b541fae (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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#
#    Common code for the EC2 initialisation scripts in Ubuntu
#    Copyright (C) 2008-2009 Canonical Ltd
#
#    Author: Soren Hansen <soren@canonical.com>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License version 3, as
#    published by the Free Software Foundation.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

import os
from   configobj import ConfigObj

import boto.utils
import cPickle
import sys
import os.path
import errno

datadir = '/var/lib/cloud/data'
semdir = '/var/lib/cloud/sem'
cachedir = datadir + '/cache'
user_data = datadir + '/user-data.txt'
user_data_raw = datadir + '/user-data.raw'
user_config = datadir + '/user-config.txt'

import DataSourceEc2

class EC2Init:
    datasource_list = [ DataSourceEc2.DataSourceEc2 ]

    def restore_from_cache(self):
        try:
            f=open(cachedir + "/obj.pkl", "rb")
            data = cPickle.load(f)
            self.datasource = data
            return True
        except:
            return False

    def write_to_cache(self):
        try:
            f=open(cachedir + "/obj.pkl", "wb")
            data = cPickle.dump(self.datasource,f)
            return True
        except:
            return False
        
    def get_data_source(self):
        if self.restore_from_cache():
            return True

        for source in self.datasource_list:
            try:
                s = source()
                if s.get_data():
                    self.datasource = s
                    return
            except Exception as e:
                print e
                pass
        raise Exception("Could not find data source")

    def get_user_data(self):
        return(self.datasource.get_user_data())

    def get_cfg_option_bool(self, key, default=None):
        val = self.config.get(key, default)
        if val.lower() in ['1', 'on', 'yes']:
            return True
        return False

    def initctl_emit(self):
        import subprocess
        subprocess.Popen(['initctl', 'CFG_FILE=%s' % user_config]).communicate()


# if 'str' is compressed return decompressed otherwise return it
def decomp_str(str):
    import StringIO
    import gzip
    try:
        uncomp = gzip.GzipFile(None,"rb",1,StringIO.StringIO(str)).read()
        return(uncomp)
    except:
        return(str)


# preprocess the user data (include / uncompress)
def preprocess_user_data(ud):
    return(decomp_str(ud))

def sem_getpath(name,freq):
    # TODO: freqtok must represent "once-per-instance" somehow
    freqtok = freq
    return("%s/%s.%s" % (semdir,name,freqtok))

def sem_has_run(name,freq):
    semfile = sem_getpath(name,freq)
    if os.path.exists(semfile):
        return True
    return False

def sem_acquire(name,freq):
    from time import time
    semfile = sem_getpath(name,freq)

    try:
        os.makedirs(os.path.dirname(semfile))
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise e

    if os.path.exists(semfile):
        return False

    # race condition
    try:
        f = open(semfile,"w")
        f.write(str(time()))
        f.close()
    except:
        return(False)
    return(True)

def sem_clear(name,freq):
    semfile = sem_getpath(name,freq)
    try:
        os.unlink(semfile)
    except OSError as e:
        if e.errno != errno.ENOENT:
            return False
        
    return True