summaryrefslogtreecommitdiffstats
path: root/cobbler/action_enchant.py
blob: a911c94d27ca33789de26bab70c31b69966eeb47 (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
"""
Enables the "cobbler enchant" command to apply profiles
to remote systems, whether or not they are running koan.

Copyright 2006, Red Hat, Inc
Michael DeHaan <mdehaan@redhat.com>

This software may be freely redistributed under the terms of the GNU
general public license.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
"""

import cexceptions
import os
import os.path
import sub_process
import traceback

class Enchant:

   def __init__(self,config,address,profile,system,is_virt):
       """
       Constructor.
       config:  a configuration reference (see api module)
       sysname:  address of system to enchant (not necc. defined in cobbler)
       profile:  profile to make the system become
       """
       self.config = config
       self.settings = self.config.settings()
       self.address = address
       self.profile = profile
       self.system = system
       self.is_virt = is_virt
       if address is None:
           raise cexceptions.CobblerException("enchant_failed","no address specified")
       if system is None and profile is None:
           raise cexceptions.CobblerException("enchant_failed","no profile specified")
       if system is not None and self.config.systems().find(system) is None:
           raise cexceptions.CobblerException("enchant_failed","system name not found")
       if profile is not None and self.config.profiles().find(profile) is None:
           raise cexceptions.CobblerException("enchant_failed","profile name not found")


   def ssh_exec(self,cmd,catch_fail=True):
       """
       Invoke an SSH command.
 -o 'HostKeyAlias NoHostKeyStorage'
       """
       cmd2 = "ssh -o 'StrictHostKeyChecking=no' -o 'HostKeyAlias nocobblerhostkey' root@%s %s" % (self.address,cmd)
       print "running: %s" % cmd2
       rc = sub_process.call(cmd2,shell=True)
       print "returns: %d" % rc
       if catch_fail and rc != 0:
           raise cexceptions.CobblerException("enchant_failed","ssh failure")

   def run(self):
       """
       Replace the OS of a remote system.
       """

       # clean out known hosts file to eliminate conflicts
       known_hosts = open("/root/.ssh/known_hosts","r")
       data = known_hosts.read()
       known_hosts.close()
       known_hosts = open("/root/.ssh/known_hosts","w+")
       for line in data.split("\n"):
           if not line.startswith("nocobblerhostkey"):
               known_hosts.write(line)
               known_hosts.write("\n")
       known_hosts.close()

       # make sure the koan rpm is present, if it's not there, user didn't run sync first
       # or it's not configured in /var/lib/cobbler/settings
       koan = os.path.basename(self.settings.koan_path)
       where_is_koan = os.path.join(self.settings.webdir,os.path.basename(koan))
       if not os.path.exists(where_is_koan) or os.path.isdir(where_is_koan):
           raise cexceptions.CobblerException("enchant_failed","koan is missing")

       try:
           self.ssh_exec("wget http://%s/cobbler/%s" % (self.settings.server, koan))
           # koan doesn't require libvirt-python, but uses it for koan --virt options if available
           # so, if --virt is requested, we have to make sure it's installed.  It's probably
           # reasonable to just assume it /IS/ installed though as Xen kernel usage is required.
           extra_virt_packages = ""
           if self.is_virt:
              extra_virt_packages = " libvirt-python libvirt"
           # package installation without knowing whether the target is yum-based or not
           self.ssh_exec("up2date install syslinux%s" % (extra_virt_packages), catch_fail=False)
           self.ssh_exec("yum -y install syslinux%s" % (extra_virt_packages), catch_fail=False)
           self.ssh_exec("rpm -Uvh %s --force --nodeps" % koan)
           # choose SSH command line based on whether this command was given --virt or not
           operation = "--replace-self"
           if self.is_virt:
               operation = "--virt"
           if self.system:
               self.ssh_exec("koan %s --system=%s --server=%s" % (operation, self.system, self.settings.server))
           else:
               self.ssh_exec("koan %s --profile=%s --server=%s" % (operation, self.profile, self.settings.server))
           # don't have to reboot for virt installs
           if not self.is_virt:
               self.ssh_exec("/sbin/reboot")
           return True
       except:
           traceback.print_exc()
           raise cexceptions.CobblerException("enchant_failed","exception")
       return False # shouldn't be here