summaryrefslogtreecommitdiffstats
path: root/cobbler/action_replicate.py
blob: ae3adc84e5aa85eff1fb4e3f7c5db017a1cfba26 (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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
"""
Replicate from a cobbler master.

Copyright 2007-2008, Red Hat, Inc
Michael DeHaan <mdehaan@redhat.com>
Scott Henson <shenson@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 os
import os.path
import xmlrpclib
import api as cobbler_api
from utils import _

class Replicate:
    def __init__(self,config):
        """
        Constructor
        """
        self.config   = config
        self.settings = config.settings()
        self.api         = config.api
        self.remote = None
        self.uri = None

    # -------------------------------------------------------

    def link_distro(self, distro):
        """
        Create the distro links
        """
        # find the tree location
        dirname = os.path.dirname(distro.kernel)
        tokens = dirname.split("/")
        tokens = tokens[:-2]
        base = "/".join(tokens)
        dest_link = os.path.join(self.settings.webdir, "links", distro.name)

        # create the links directory only if we are mirroring because with
        # SELinux Apache can't symlink to NFS (without some doing)

        if not os.path.exists(dest_link):
            try:
                os.symlink(base, dest_link)
            except:
                # this shouldn't happen but I've seen it ... debug ...
                print _("- symlink creation failed: %(base)s, %(dest)s") % { "base" : base, "dest" : dest_link }
                
    # -------------------------------------------------------

    def add_distro(self, distro):
        """
        Add a distro that has been found
        """
        #Register the distro
        if os.path.exists(distro['kernel']):
            new_distro = self.api.new_distro()
            new_distro.from_datastruct(distro)
            #create the symlinks
            self.link_distro(new_distro)
            #Add the distro permanently
            self.api.distros().add(new_distro, save=True)
            print 'Added distro %s. Creating Links.' % distro['name']
        else:
            print 'Distro %s not here yet.' % distro['name']

    # -------------------------------------------------------

    def add_profile(self, profile):
        """
        Add a profile that has been found
        """
        #Register the new profile
        new_profile = self.api.new_profile()
        new_profile.from_datastruct(profile)
        self.api.profiles().add(new_profile, save=True)
        print 'Added profile %s.' % profile['name']


    # -------------------------------------------------------

    def check_profile(self, profile):
        """
        Check that a profile belongs to a distro
        """
        profiles = self.api.profiles().to_datastruct()
        if profile not in profiles:
            for distro in self.api.distros().to_datastruct():
                if distro['name'] == profile['name']:
                    return True
        return False


    # -------------------------------------------------------

    def sync_distros(self):
        """
        Sync distros from master
        """
        local_distros = self.api.distros()
        remote_distros = self.remote.get_distros()

        needsync = False
        for distro in remote_distros:
            if distro not in local_distros.to_datastruct():
                print 'Found distro %s.' % distro['name']
                self.add_distro(distro)
                needsync = True
                
        self.call_sync(needsync)


    # -------------------------------------------------------

    def sync_profiles(self):
        """
        Sync profiles from master
        """
        local_profiles = self.api.profiles()
        remote_profiles = self.remote.get_profiles()

        needsync = False
        for profile in remote_profiles:
            if self.check_profile(profile):
                print 'Found profile %s.' % profilew['name']
                self.add_profile(profile)
                needsync = True
        self.call_sync(needsync)


    # -------------------------------------------------------

    def call_sync(self, needsync):
        if needsync:
            self.api.sync()
    
    # -------------------------------------------------------

    def run(self, cobbler_master=None):
        """
        Get remote profiles and distros and sync them locally
        """
        if cobbler_master is not None:
            self.uri = 'http://%s/cobbler_api' % cobbler_master
        elif len(self.settings.cobbler_master) > 0:
            self.uri = 'http://%s/cobbler_api' % self.settings.cobbler_master
        else:
            print _('No cobbler master found to replicate from, try --master.')
        if self.uri is not None:
            self.remote =  xmlrpclib.Server(self.uri)
            self.sync_distros()
            self.sync_profiles()