Revision 3c3bccab snf-deploy/snfdeploy/utils.py

b/snf-deploy/snfdeploy/utils.py
1
# Copyright (C) 2010, 2011, 2012, 2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A. OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

  
1 34
from __future__ import with_statement
2 35
from fabric.api import hide, env, settings, local, roles
3 36
from fabric.operations import run, put, get
......
9 42
import ast
10 43
from snfdeploy.lib import debug, Conf, Env, disable_color
11 44
from snfdeploy import massedit
45
from snfdeploy.components import *
46
from snfdeploy.roles import ROLES, CONFLICTS
12 47

  
13 48

  
14 49
def abort(action):
......
17 52
            return action(*args, **kwargs)
18 53
        except BaseException as e:
19 54
            abort = kwargs.get("abort", True)
20
            if not abort:
55
            force = env.force
56
            if not abort or force:
21 57
                 debug(env.host, "WARNING: command failed. Continuing anyway...")
22 58
            else:
23 59
                 fabric.utils.abort(e)
......
26 62

  
27 63
@abort
28 64
def try_get(remote_path, local_path=None, **kwargs):
65
    if env.dry_run:
66
        debug(env.host, " * Fetching file localy... ", remote_path)
67
        return
29 68
    get(remote_path, local_path=local_path, **kwargs)
30 69

  
31 70

  
32 71
@abort
33
def try_put(local_path=None, remote_path=None, **kwargs):
34
    put(local_path=local_path, remote_path=remote_path, **kwargs)
35

  
72
def try_put(local_path=None, remote_path=None, mode=0644, **kwargs):
73
    if env.dry_run:
74
        debug(env.host, " * Upload file... ", remote_path)
75
        return
76
    put(local_path=local_path, remote_path=remote_path, mode=mode)
36 77

  
37 78

  
38 79
@abort
39 80
def try_run(cmd, **kwargs):
40
    if env.local:
41
        return local(cmd, capture=True)
81
    if env.dry_run:
82
        debug(env.host, cmd)
83
        return ""
84
    elif env.local:
85
        return local(cmd, capture=True, shell="/bin/bash")
42 86
    else:
43 87
        return run(cmd)
44 88

  
45 89

  
46 90
def install_package(package):
47
    debug(env.host, " * Installing package %s..." % package)
91
    debug(env.host, " * Installing package... ", package)
48 92
    apt_get = "export DEBIAN_FRONTEND=noninteractive ;" + \
49 93
              "apt-get install -y --force-yes "
50 94

  
......
92 136
    return custom
93 137

  
94 138

  
139
def get_node_info(ident):
140
    if ident in env.env.ips_info:
141
        return env.env.ips_info[ident]
142
    elif ident in env.env.hosts_info:
143
        return env.env.hosts_info[ident]
144
    elif ident in env.env.nodes_info:
145
        return env.env.nodes_info[ident]
146

  
147

  
148
def GetFromComponent(component, remote, local):
149
    c = GetSynnefoComponent(component)
150
    c.debug(" * Downloading: ", remote)
151
    with settings(host_string=c.node_info.ip):
152
        try_get(remote, local)
153

  
154

  
155
def PutToComponent(component, local, remote):
156
    c = GetSynnefoComponent(component)
157
    c.debug(" * Uploading: ", remote)
158
    with settings(host_string=c.node_info.ip):
159
        try_put(local, remote)
160

  
161

  
162
def RunComponentMethod(component, method, *args, **kwargs):
163
    c = GetSynnefoComponent(component)
164
    c.debug(" * Running method: ", method)
165
    with settings(host_string=c.node_info.ip):
166
        fn = getattr(c, method)
167
        ret = ""
168
        for cmd in fn(*args, **kwargs):
169
            ret += try_run(cmd)
170
        return ret
171

  
172

  
173
def GetSynnefoComponent(component):
174
    node_info = get_node_info(env.host)
175
    env.password = node_info.passwd
176
    return component(node_info, env)
177

  
178

  
179
def conflicting_exists(component):
180
    conflict = CONFLICTS.get(component, [])
181
    for c in conflict:
182
        cs = env.env.status.check_status(env.host, c)
183
        if cs:
184
            debug(env.host, "Conflicting component already exists", c.__name__)
185
            return True
186

  
187
    return False
188

  
189

  
190
def SetupSynnefoRole(role):
191
    debug("Setting up base configuration for: ", role)
192
    try:
193
        components = ROLES.get(role)
194
    except KeyError:
195
        debug(env.host, "Please give a valid role")
196
        return
197
    for c in components:
198
        if conflicting_exists(c):
199
            continue
200
        status = env.env.status.check_status(env.host, c)
201
        if status:
202
            debug(env.host, "Base configuration already exists", c.__name__)
203
        else:
204
            AddSynnefoComponent(c)
205
            env.env.status.update_status(env.host, c, "ok")
206
            env.env.status.write_status()
207

  
208

  
209
class AddSynnefoComponent(object):
210

  
211
    def _run(self, commands):
212
        for c in commands:
213
            try_run(c)
214

  
215
    def _install(self, packages):
216
        for p in packages:
217
            install_package(p)
218

  
219
    def _configure(self, templates):
220
        for tmpl, replace, opts in templates:
221
            mode = opts.get("mode", 0644)
222
            remote = opts.get("remote", tmpl)
223
            custom = customize_settings_from_tmpl(tmpl, replace)
224
            try_put(custom, remote, mode)
225
            os.remove(custom)
226

  
227
    def __init__(self, component):
228
        self.c = GetSynnefoComponent(component)
229
        self.c.debug("Adding component..")
230

  
231
        self.c.debug(" * Checking prerequisites..")
232
        self._run(self.c.check())
233

  
234
        self.c.debug(" * Installing packages..")
235
        self._install(self.c.install())
236

  
237
        self.c.debug(" * Preparing configuration..")
238
        self._run(self.c.prepare())
239

  
240
        self.c.debug(" * Setting up configuration files..")
241
        self._configure(self.c.configure())
242

  
243
        self.c.debug(" * Restarting services..")
244
        self._run(self.c.restart())
245

  
246
        self.c.debug(" * Initializing setup..")
247
        self._run(self.c.initialize())
248

  
249
        self.c.debug(" * Testing setup..")
250
        self._run(self.c.test())

Also available in: Unified diff