~ubuntu-branches/ubuntu/natty/cobbler/natty

« back to all changes in this revision

Viewing changes to .pc/32_fix_koan_import_yum.patch/koan/configurator.py

  • Committer: Bazaar Package Importer
  • Author(s): Andres Rodriguez
  • Date: 2011-03-11 16:02:48 UTC
  • Revision ID: james.westby@ubuntu.com-20110311160248-o881mf0wys4j8rk1
Tags: 2.1.0~bzr2005-0ubuntu2
* debian/patches/31_add_ubuntu_koan_utils_support.patch: Add support for
  ubuntu distro in koan utils.py.
* debian/patches/32_fix_koan_import_yum.patch: Fix import error of yum
  python module; adds flexibility for other package managers. (LP: #731620)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
Configuration class.
 
3
 
 
4
Copyright 2010 Kelsey Hightower
 
5
Kelsey Hightower <kelsey.hightower@gmail.com>
 
6
 
 
7
This program is free software; you can redistribute it and/or modify
 
8
it under the terms of the GNU General Public License as published by
 
9
the Free Software Foundation; either version 2 of the License, or
 
10
(at your option) any later version.
 
11
 
 
12
This program is distributed in the hope that it will be useful,
 
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
GNU General Public License for more details.
 
16
 
 
17
You should have received a copy of the GNU General Public License
 
18
along with this program; if not, write to the Free Software
 
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
20
02110-1301  USA
 
21
 
 
22
module for configuring repos, ldap, packages, files, and monit
 
23
"""
 
24
 
 
25
import filecmp
 
26
import shutil
 
27
import utils
 
28
import subprocess
 
29
import tempfile
 
30
import stat
 
31
import os.path
 
32
import sys
 
33
import time
 
34
import yum
 
35
import pwd
 
36
import grp
 
37
import simplejson as json
 
38
sys.path.append('/usr/share/yum-cli')
 
39
import cli
 
40
 
 
41
 
 
42
class KoanConfigure:
 
43
    """
 
44
    Used for all configuration methods, used by koan
 
45
    to configure repos, ldap, files, packages, and monit. 
 
46
    """
 
47
    
 
48
    def __init__(self, config):
 
49
        """Constructor. Requires json config object."""
 
50
        self.config = json.JSONDecoder().decode(config)
 
51
        self.stats = {}
 
52
        
 
53
    #----------------------------------------------------------------------
 
54
 
 
55
    def configure_repos(self):
 
56
        """Configure YUM repositories."""
 
57
        print "- Configuring Repos"  
 
58
        old_repo = '/etc/yum.repos.d/config.repo'
 
59
        
 
60
        # Stage a tempfile to hold new file contents
 
61
        _tempfile = tempfile.NamedTemporaryFile()
 
62
        _tempfile.write(self.config['repo_data'])
 
63
        _tempfile.flush()
 
64
        new_repo = _tempfile.name
 
65
        
 
66
        # Check if repo resource exist, create if missing
 
67
        if os.path.isfile(old_repo):
 
68
            if not filecmp.cmp(old_repo, new_repo):
 
69
                utils.sync_file(old_repo, new_repo, 0, 0, 644)
 
70
                self.stats['repos_status'] = "Success: Repos in sync"
 
71
            else:
 
72
                self.stats['repos_status'] = "Success: Repos in sync"
 
73
        else:
 
74
            print "  %s not found, creating..." % (old_repo)
 
75
            open(old_repo,'w').close()
 
76
            utils.sync_file(old_repo, new_repo, 0, 0, 644)
 
77
            self.stats['repos_status'] = "Success: Repos in sync"
 
78
        _tempfile.close()
 
79
        
 
80
    #----------------------------------------------------------------------
 
81
 
 
82
    def configure_ldap(self):
 
83
        """Configure LDAP by running the specified LDAP command."""
 
84
        print "- Configuring LDAP"
 
85
        rc = subprocess.call(self.config['ldap_data'],shell="True")
 
86
        if rc == 0:
 
87
            self.stats['ldap_status'] = "Success: LDAP has been configured"
 
88
        else:
 
89
            self.stats['ldap_status'] = "ERROR: configuring LDAP failed"
 
90
    
 
91
    #----------------------------------------------------------------------
 
92
        
 
93
    def configure_monit(self):
 
94
        """Start or reload Monit"""
 
95
        print "- Configuring Monit"
 
96
        ret = subprocess.call(['/sbin/service', 'monit', 'status'])
 
97
        if ret == 0:
 
98
            _ret = subprocess.call(['/usr/bin/monit', 'reload'])
 
99
            if _ret == 0:
 
100
                self.stats['monit_status'] = "Running: Monit has been reloaded"
 
101
        else:
 
102
            _ret = subprocess.call(['/sbin/service', 'monit', 'start'])
 
103
            if _ret == 0:
 
104
                self.stats['monit_status'] = "Running: Monit has been started"
 
105
            else:
 
106
                self.stats['monit_status'] = "Stopped: Failed to start monit"
 
107
            
 
108
    #----------------------------------------------------------------------
 
109
    
 
110
    def configure_packages(self):
 
111
        """Configure package resources."""
 
112
        print "- Configuring Packages"
 
113
        runtime_start = time.time()
 
114
        nsync = 0
 
115
        osync = 0
 
116
        fail  = 0
 
117
        packages = self.config['packages']
 
118
 
 
119
        yb = yum.YumBase()
 
120
        yb.preconf.debuglevel = 0
 
121
        yb.preconf.errorlevel = 0
 
122
        yb.doTsSetup()
 
123
        yb.doRpmDBSetup()
 
124
        
 
125
        ybc = cli.YumBaseCli()
 
126
        ybc.preconf.debuglevel = 0
 
127
        ybc.preconf.errorlevel = 0
 
128
        ybc.conf.assumeyes = True
 
129
        ybc.doTsSetup()
 
130
        ybc.doRpmDBSetup()
 
131
        
 
132
        create_pkg_list = []
 
133
        remove_pkg_list = []   
 
134
        for package in packages:
 
135
            action = packages[package]['action']
 
136
            # In the near future, will use install_name vs package
 
137
            # as it includes a more specific package name: "package-version"
 
138
            install_name = packages[package]['install_name']  
 
139
                    
 
140
            if yb.isPackageInstalled(package):
 
141
                if action == 'create':
 
142
                    nsync += 1
 
143
                if action == 'remove':
 
144
                    remove_pkg_list.append(package)
 
145
            if not yb.isPackageInstalled(package):
 
146
                if action == 'create':
 
147
                    create_pkg_list.append(package)
 
148
                if action == 'remove':
 
149
                    nsync += 1
 
150
        
 
151
        # Don't waste time with YUM if there is nothing to do.
 
152
        doTransaction = False
 
153
        
 
154
        if create_pkg_list:
 
155
            print "  Packages out of sync: %s" % create_pkg_list
 
156
            ybc.installPkgs(create_pkg_list)
 
157
            osync += len(create_pkg_list)
 
158
            doTransaction = True
 
159
        if remove_pkg_list:
 
160
            print "  Packages out of sync: %s" % remove_pkg_list
 
161
            ybc.erasePkgs(remove_pkg_list)
 
162
            osync += len(remove_pkg_list)
 
163
            doTransaction = True
 
164
        if doTransaction:
 
165
            ybc.buildTransaction()
 
166
            ybc.doTransaction()
 
167
            
 
168
        runtime_end = time.time()
 
169
        runtime = (runtime_end - runtime_start)
 
170
        self.stats['pkg'] = {'runtime': runtime,'nsync': nsync,'osync': osync,'fail' : fail}
 
171
    
 
172
    #----------------------------------------------------------------------
 
173
   
 
174
    def configure_directories(self):
 
175
        """ Configure directory resources."""
 
176
        print "- Configuring Directories"
 
177
        runtime_start = time.time()
 
178
        nsync = 0
 
179
        osync = 0
 
180
        fail  = 0
 
181
        files = self.config['files']
 
182
        # Split out directories
 
183
        _dirs  = [d for d in files if files[d]['is_dir']]
 
184
        
 
185
        # Configure directories first
 
186
        for dir in _dirs:
 
187
            action  = files[dir]['action']
 
188
            odir = files[dir]['path']
 
189
            
 
190
            protected_dirs = ['/','/bin','/boot','/dev','/etc','/lib','/lib64','/proc','/sbin','/sys','/usr','/var']
 
191
            if os.path.isdir(odir):
 
192
                if os.path.realpath(odir) in protected_dirs:
 
193
                    print " %s is a protected directory, skipping..." % os.path.realpath(odir)
 
194
                    fail += 1
 
195
                    continue          
 
196
          
 
197
            if action == 'create':
 
198
                nmode = int(files[dir]['mode'],8)
 
199
                nuid  = pwd.getpwnam(files[dir]['owner'])[2]
 
200
                ngid  = grp.getgrnam(files[dir]['group'])[2]  
 
201
                
 
202
                # Compare old and new directories, sync if permissions mismatch       
 
203
                if os.path.isdir(odir):
 
204
                    dstat = os.stat(odir)
 
205
                    omode = stat.S_IMODE(dstat.st_mode)
 
206
                    ouid  = pwd.getpwuid(dstat.st_uid)[2]
 
207
                    ogid  = grp.getgrgid(dstat.st_gid)[2]
 
208
                    if omode != nmode or ouid != nuid or ogid != ngid:
 
209
                        os.chmod(odir,nmode)
 
210
                        os.chown(odir,nuid,ngid)
 
211
                        osync += 1
 
212
                    else:
 
213
                        nsync += 1
 
214
                else:
 
215
                    print "  Directory out of sync, creating %s" % odir
 
216
                    os.makedirs(odir,nmode)
 
217
                    os.chown(odir,nuid,ngid)
 
218
                    osync += 1
 
219
            elif action == 'remove':
 
220
                if os.path.isdir(odir):
 
221
                    print "  Directory out of sync, removing %s" % odir
 
222
                    shutil.rmtree(odir)
 
223
                    osync += 1
 
224
                else:
 
225
                    nsync += 1
 
226
            else:
 
227
                pass
 
228
        runtime_end = time.time()
 
229
        runtime = (runtime_end - runtime_start)
 
230
        self.stats['dir'] = {'runtime': runtime,'nsync': nsync,'osync': osync,'fail': fail}
 
231
            
 
232
    #----------------------------------------------------------------------
 
233
    
 
234
    def configure_files(self):
 
235
        """ Configure file resources."""
 
236
        print "- Configuring Files"
 
237
        runtime_start = time.time()
 
238
        nsync = 0
 
239
        osync = 0
 
240
        fail  = 0
 
241
        files = self.config['files']
 
242
        # Split out files
 
243
        _files = [f for f in files if files[f]['is_dir'] is False]
 
244
        
 
245
        for file in _files:
 
246
            action   = files[file]['action']
 
247
            ofile = files[file]['path']         
 
248
            
 
249
            if action == 'create':
 
250
                nmode = int(files[file]['mode'],8)
 
251
                nuid  = pwd.getpwnam(files[file]['owner'])[2]
 
252
                ngid  = grp.getgrnam(files[file]['group'])[2]
 
253
                
 
254
                # Stage a tempfile to hold new file contents
 
255
                _tempfile = tempfile.NamedTemporaryFile()
 
256
                _tempfile.write(files[file]['content'])
 
257
                _tempfile.flush()
 
258
                nfile = _tempfile.name    
 
259
                
 
260
                # Compare new and old files, sync if permissions or contents mismatch
 
261
                if os.path.isfile(ofile):
 
262
                    fstat = os.stat(ofile)
 
263
                    omode = stat.S_IMODE(fstat.st_mode)
 
264
                    ouid  = pwd.getpwuid(fstat.st_uid)[2]
 
265
                    ogid  = grp.getgrgid(fstat.st_gid)[2]             
 
266
                    if not filecmp.cmp(ofile, nfile) or omode != nmode or ogid != ngid or ouid != nuid:
 
267
                        utils.sync_file(ofile, nfile, nuid, ngid, nmode)
 
268
                        osync += 1      
 
269
                    else:
 
270
                        nsync += 1
 
271
                elif os.path.dirname(ofile):
 
272
                    # Create the file only if the base directory exists
 
273
                    open(ofile,'w').close()
 
274
                    utils.sync_file(ofile, nfile, nuid, ngid, nmode)
 
275
                    osync += 1
 
276
                else:
 
277
                    print "  Base directory not found, %s required." % (os.path.dirname(ofile))
 
278
                    fail += 1
 
279
                _tempfile.close()
 
280
            elif action == 'remove':
 
281
                if os.path.isfile(file):
 
282
                    os.remove(ofile)
 
283
                    osync += 1
 
284
                else:
 
285
                    nsync += 1
 
286
            else:
 
287
                pass
 
288
        
 
289
        runtime_end = time.time()
 
290
        runtime = (runtime_end - runtime_start)
 
291
        self.stats['files'] = {'runtime': runtime,'nsync': nsync,'osync': osync,'fail': fail}
 
292
    
 
293
    #----------------------------------------------------------------------
 
294
    
 
295
    def run(self):
 
296
        # Configure resources in a specific order: repos, ldap, packages, directories, files, monit    
 
297
        if self.config['repos_enabled']:
 
298
            self.configure_repos()    
 
299
        if self.config['ldap_enabled']:
 
300
            self.configure_ldap()
 
301
        self.configure_packages()
 
302
        self.configure_directories()
 
303
        self.configure_files()
 
304
        if self.config['monit_enabled']:
 
305
            self.configure_monit()
 
306
            
 
307
        return self.stats
 
 
b'\\ No newline at end of file'