Statistics
| Branch: | Tag: | Revision:

one / src / host / HostPool.cc @ 6329d8b3

History | View | Annotate | Download (6.78 KB)

1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)             */
3
/*                                                                            */
4
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
5
/* not use this file except in compliance with the License. You may obtain    */
6
/* a copy of the License at                                                   */
7
/*                                                                            */
8
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
9
/*                                                                            */
10
/* Unless required by applicable law or agreed to in writing, software        */
11
/* distributed under the License is distributed on an "AS IS" BASIS,          */
12
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
13
/* See the License for the specific language governing permissions and        */
14
/* limitations under the License.                                             */
15
/* -------------------------------------------------------------------------- */
16

    
17
/* ************************************************************************** */
18
/* Host Pool                                                                  */
19
/* ************************************************************************** */
20

    
21
#include <stdexcept>
22

    
23
#include "HostPool.h"
24
#include "HostHook.h"
25
#include "NebulaLog.h"
26
#include "ClusterPool.h"
27

    
28
/* -------------------------------------------------------------------------- */
29
/* -------------------------------------------------------------------------- */
30

    
31
HostPool::HostPool(SqlDB*                    db,
32
                   vector<const Attribute *> hook_mads,
33
                   const string&             hook_location)
34
                        : PoolSQL(db,Host::table)
35
{
36
    // ------------------ Initialize Hooks fot the pool ----------------------
37

    
38
    const VectorAttribute * vattr;
39

    
40
    string name;
41
    string on;
42
    string cmd;
43
    string arg;
44
    string rmt;
45
    bool   remote;
46

    
47
    bool state_hook = false;
48

    
49
    for (unsigned int i = 0 ; i < hook_mads.size() ; i++ )
50
    {
51
        vattr = static_cast<const VectorAttribute *>(hook_mads[i]);
52

    
53
        name = vattr->vector_value("NAME");
54
        on   = vattr->vector_value("ON");
55
        cmd  = vattr->vector_value("COMMAND");
56
        arg  = vattr->vector_value("ARGUMENTS");
57
        rmt  = vattr->vector_value("REMOTE");
58

    
59
        transform (on.begin(),on.end(),on.begin(),(int(*)(int))toupper);
60

    
61
        if ( on.empty() || cmd.empty() )
62
        {
63
            ostringstream oss;
64

    
65
            oss << "Empty ON or COMMAND attribute in HOST_HOOK. Hook "
66
                << "not registered!";
67
            NebulaLog::log("VM",Log::WARNING,oss);
68

    
69
            continue;
70
        }
71

    
72
        if ( name.empty() )
73
        {
74
            name = cmd;
75
        }
76

    
77
        remote = false;
78

    
79
        if ( !rmt.empty() )
80
        {
81
            transform(rmt.begin(),rmt.end(),rmt.begin(),(int(*)(int))toupper);
82

    
83
            if ( rmt == "YES" )
84
            {
85
                remote = true;
86
            }
87
        }
88

    
89
        if (cmd[0] != '/')
90
        {
91
            cmd = hook_location + cmd;
92
        }
93

    
94
        if ( on == "CREATE" )
95
        {
96
            HostAllocateHook * hook;
97

    
98
            hook = new HostAllocateHook(name,cmd,arg,remote);
99

    
100
            add_hook(hook);
101
        }
102
        else if ( on == "DISABLE" )
103
        {
104
            HostStateHook * hook;
105

    
106
            hook = new HostStateHook(name, cmd, arg, remote, Host::DISABLED);
107

    
108
            add_hook(hook);
109

    
110
            state_hook = true;
111
        }
112
        else if ( on == "ERROR" )
113
        {
114
            HostStateHook * hook;
115

    
116
            hook = new HostStateHook(name, cmd, arg, remote, Host::ERROR);
117

    
118
            add_hook(hook);
119

    
120
            state_hook = true;
121
        }
122
    }
123

    
124
    if ( state_hook )
125
    {
126
        HostUpdateStateHook * hook;
127

    
128
        hook = new HostUpdateStateHook();
129

    
130
        add_hook(hook);
131
    }
132
}
133

    
134
/* -------------------------------------------------------------------------- */
135
/* -------------------------------------------------------------------------- */
136

    
137
int HostPool::allocate (
138
    int *  oid,
139
    const string& hostname,
140
    const string& im_mad_name,
141
    const string& vmm_mad_name,
142
    const string& tm_mad_name,
143
    string& error_str)
144
{
145
    Host *        host;
146
    ostringstream oss;
147

    
148
    if ( hostname.empty() )
149
    {
150
        goto error_name;
151
    }
152

    
153
    if ( im_mad_name.empty() )
154
    {
155
        goto error_im;
156
    }
157

    
158
    if ( vmm_mad_name.empty() )
159
    {
160
        goto error_vmm;
161
    }
162

    
163
    if ( tm_mad_name.empty() )
164
    {
165
        goto error_tm;
166
    }
167

    
168
    host = get(hostname,false);
169

    
170
    if ( host !=0)
171
    {
172
        goto error_duplicated;
173
    }
174

    
175
    // Build a new Host object
176

    
177
    host = new Host(-1,
178
        ClusterPool::DEFAULT_CLUSTER_ID,
179
        hostname,
180
        im_mad_name,
181
        vmm_mad_name,
182
        tm_mad_name);
183

    
184
    // Insert the Object in the pool
185

    
186
    *oid = PoolSQL::allocate(host, error_str);
187

    
188
    return *oid;
189

    
190

    
191
error_name:
192
    oss << "NAME cannot be empty.";
193
    goto error_common;
194

    
195
error_im:
196
    oss << "IM_MAD_NAME cannot be empty.";
197
    goto error_common;
198

    
199
error_vmm:
200
    oss << "VMM_MAD_NAME cannot be empty.";
201
    goto error_common;
202

    
203
error_tm:
204
    oss << "TM_MAD_NAME cannot be empty.";
205
    goto error_common;
206

    
207
error_duplicated:
208
    oss << "NAME is already taken by HOST " << host->get_oid() << ".";
209

    
210
error_common:
211
    *oid = -1;
212
    error_str = oss.str();
213

    
214
    return *oid;
215
}
216

    
217
/* -------------------------------------------------------------------------- */
218
/* -------------------------------------------------------------------------- */
219

    
220
int HostPool::discover_cb(void * _map, int num, char **values, char **names)
221
{
222
    map<int, string> *  discovered_hosts;
223
    string              im_mad;
224
    int                 hid;
225
    int                 rc;
226

    
227
    discovered_hosts = static_cast<map<int, string> *>(_map);
228

    
229
    if ( (num<2) || (values[0] == 0) || (values[1] == 0) )
230
    {
231
        return -1;
232
    }
233

    
234
    hid = atoi(values[0]);
235
    rc  = ObjectXML::xpath_value(im_mad,values[1],"/HOST/IM_MAD");
236

    
237
    if( rc != 0)
238
    {
239
        return -1;
240
    }
241

    
242
    discovered_hosts->insert(make_pair(hid,im_mad));
243

    
244
    return 0;
245
}
246

    
247
/* -------------------------------------------------------------------------- */
248

    
249
int HostPool::discover(map<int, string> * discovered_hosts, int host_limit)
250
{
251
    ostringstream   sql;
252
    int             rc;
253

    
254
    set_callback(static_cast<Callbackable::Callback>(&HostPool::discover_cb),
255
                 static_cast<void *>(discovered_hosts));
256

    
257
    sql << "SELECT oid, body FROM "
258
        << Host::table << " WHERE state != "
259
        << Host::DISABLED << " ORDER BY last_mon_time ASC LIMIT " << host_limit;
260

    
261
    rc = db->exec(sql,this);
262

    
263
    unset_callback();
264

    
265
    return rc;
266
}