Statistics
| Branch: | Tag: | Revision:

one / src / nebula / Nebula.cc @ ae53d437

History | View | Annotate | Download (14.9 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
#include "Nebula.h"
18
#include "NebulaLog.h"
19
#include "VirtualMachine.h"
20
#include "SqliteDB.h"
21
#include "MySqlDB.h"
22

    
23
#include <stdlib.h>
24
#include <stdexcept>
25
#include <libxml/parser.h>
26

    
27
#include <signal.h>
28
#include <unistd.h>
29
#include <fcntl.h>
30
#include <sys/types.h>
31
#include <sys/stat.h>
32
#include <pthread.h>
33

    
34
using namespace std;
35

    
36
/* -------------------------------------------------------------------------- */
37
/* -------------------------------------------------------------------------- */
38

    
39
void Nebula::start()
40
{
41
    int             rc;
42
    int             fd;
43
    sigset_t        mask;
44
    int             signal;
45
    char            hn[80];
46

    
47
    if ( gethostname(hn,79) != 0 )
48
    {
49
        throw runtime_error("Error getting hostname");
50
    }
51

    
52
    hostname = hn;
53

    
54
    // -----------------------------------------------------------
55
    // Configuration
56
    // -----------------------------------------------------------
57

    
58
    nebula_configuration = new NebulaTemplate(etc_location, var_location);
59

    
60
    rc = nebula_configuration->load_configuration();
61

    
62
    if ( rc != 0 )
63
    {
64
        throw runtime_error("Could not load nebula configuration file.");
65
    }
66

    
67
    string   config_fname = var_location + "config";
68
    ofstream config_file(config_fname.c_str(), ios_base::trunc & ios_base::out);
69

    
70
    if (config_file.fail() == false)
71
    {
72
        config_file << *nebula_configuration << endl;
73
        config_file.close();
74
    }
75

    
76
    // -----------------------------------------------------------
77
    // Log system
78
    // -----------------------------------------------------------
79

    
80
    ostringstream os;
81

    
82
    try
83
    {
84
        string              log_fname;
85
        int                 log_level_int;
86
        Log::MessageType    clevel = Log::ERROR;
87

    
88
        log_fname = log_location + "oned.log";
89

    
90
        nebula_configuration->get("DEBUG_LEVEL", log_level_int);
91

    
92
        if (0 <= log_level_int && log_level_int <= 3 )
93
        {
94
            clevel = static_cast<Log::MessageType>(log_level_int);
95
        }
96

    
97
        // Initializing ONE Daemon log system
98

    
99
        NebulaLog::init_log_system(NebulaLog::FILE_TS,
100
                                   clevel,
101
                                   log_fname.c_str(),
102
                                   ios_base::trunc);
103

    
104
        NebulaLog::log("ONE",Log::INFO,"Init OpenNebula Log system");
105

    
106
        os << "Log Level: " << clevel << " [0=ERROR,1=WARNING,2=INFO,3=DEBUG]";
107

    
108
        NebulaLog::log("ONE",Log::INFO,os);
109
    }
110
    catch(runtime_error&)
111
    {
112
        throw;
113
    }
114

    
115

    
116
    NebulaLog::log("ONE",Log::INFO,"----------------------------------------");
117
    NebulaLog::log("ONE",Log::INFO,"     OpenNebula Configuration File      ");
118
    NebulaLog::log("ONE",Log::INFO,"----------------------------------------");
119

    
120
    os.str("");
121
    os << "\n----------------------------------\n";
122
    os << *nebula_configuration;
123
    os << "----------------------------------";
124

    
125
    NebulaLog::log("ONE",Log::INFO,os);
126

    
127
    // -----------------------------------------------------------
128
    // Initialize the XML library
129
    // -----------------------------------------------------------
130
    xmlInitParser();
131

    
132
    // -----------------------------------------------------------
133
    // Pools
134
    // -----------------------------------------------------------
135

    
136
    try
137
    {
138
        vector<const Attribute *> dbs;
139
        int  rc;
140

    
141
        bool   db_is_sqlite = true;
142

    
143
        string server  = "localhost";
144
        string port_str;
145
        int    port    = 0;
146
        string user    = "oneadmin";
147
        string passwd  = "oneadmin";
148
        string db_name = "opennebula";
149

    
150
        rc = nebula_configuration->get("DB", dbs);
151

    
152
        if ( rc != 0 )
153
        {
154
            string value;
155
            const  VectorAttribute * db = static_cast<const VectorAttribute *>
156
                                              (dbs[0]);
157
            value = db->vector_value("BACKEND");
158

    
159
            if (value == "mysql")
160
            {
161
                db_is_sqlite = false;
162

    
163
                value = db->vector_value("SERVER");
164
                if (!value.empty())
165
                {
166
                    server = value;
167
                }
168

    
169
                istringstream   is;
170

    
171
                port_str = db->vector_value("PORT");
172

    
173
                is.str(port_str);
174
                is >> port;
175

    
176
                if( is.fail() )
177
                {
178
                    port = 0;
179
                }
180

    
181
                value = db->vector_value("USER");
182
                if (!value.empty())
183
                {
184
                    user = value;
185
                }
186

    
187
                value = db->vector_value("PASSWD");
188
                if (!value.empty())
189
                {
190
                    passwd = value;
191
                }
192

    
193
                value = db->vector_value("DB_NAME");
194
                if (!value.empty())
195
                {
196
                    db_name = value;
197
                }
198
            }
199
        }
200

    
201
        if ( db_is_sqlite )
202
        {
203
            string  db_name = var_location + "one.db";
204

    
205
            db = new SqliteDB(db_name);
206
        }
207
        else
208
        {
209
            ostringstream   oss;
210

    
211
            db = new MySqlDB(server,port,user,passwd,db_name);
212

    
213
            oss << "CREATE DATABASE IF NOT EXISTS " << db_name;
214
            rc = db->exec(oss);
215

    
216
            if ( rc != 0 )
217
            {
218
                throw runtime_error("Could not create database.");
219
            }
220

    
221
            oss.str("");
222
            oss << "USE " << db_name;
223
            rc = db->exec(oss);
224
            if ( rc != 0 )
225
            {
226
                throw runtime_error("Could not open database.");
227
            }
228
        }
229

    
230
        NebulaLog::log("ONE",Log::INFO,"Bootstraping OpenNebula database.");
231

    
232
        VirtualMachinePool::bootstrap(db);
233
        HostPool::bootstrap(db);
234
        VirtualNetworkPool::bootstrap(db);
235
        UserPool::bootstrap(db);
236
        ImagePool::bootstrap(db);
237
        ClusterPool::bootstrap(db);
238
        GroupPool::bootstrap(db);
239
        VMTemplatePool::bootstrap(db);
240
    }
241
    catch (exception&)
242
    {
243
        throw;
244
    }
245

    
246
    try
247
    {
248
        string  mac_prefix;
249
        int     size;
250
        string  default_image_type;
251
        string  default_device_prefix;
252

    
253
        vector<const Attribute *> vm_hooks;
254
        vector<const Attribute *> host_hooks;
255

    
256
        nebula_configuration->get("VM_HOOK", vm_hooks);
257
        nebula_configuration->get("HOST_HOOK", host_hooks);
258

    
259
        vmpool = new VirtualMachinePool(db, vm_hooks, hook_location);
260
        hpool  = new HostPool(db, host_hooks, hook_location);
261

    
262
        nebula_configuration->get("MAC_PREFIX", mac_prefix);
263
        nebula_configuration->get("NETWORK_SIZE", size);
264

    
265
        vnpool = new VirtualNetworkPool(db,mac_prefix,size);
266

    
267
        upool  = new UserPool(db);
268

    
269
        nebula_configuration->get("DEFAULT_IMAGE_TYPE", default_image_type);
270
        nebula_configuration->get("DEFAULT_DEVICE_PREFIX",
271
                                  default_device_prefix);
272

    
273
        ipool  = new ImagePool(db,
274
                               default_image_type,
275
                               default_device_prefix);
276

    
277
        cpool = new ClusterPool(db);
278

    
279
        gpool = new GroupPool(db);
280

    
281
        tpool = new VMTemplatePool(db);
282
    }
283
    catch (exception&)
284
    {
285
        throw;
286
    }
287

    
288
    // -----------------------------------------------------------
289
    // Close stds, we no longer need them
290
    // -----------------------------------------------------------
291

    
292
    fd = open("/dev/null", O_RDWR);
293

    
294
    dup2(fd,0);
295
    dup2(fd,1);
296
    dup2(fd,2);
297

    
298
    close(fd);
299

    
300
    fcntl(0,F_SETFD,0); // Keep them open across exec funcs
301
    fcntl(1,F_SETFD,0);
302
    fcntl(2,F_SETFD,0);
303

    
304
    // -----------------------------------------------------------
305
    // Block all signals before creating any Nebula thread
306
    // -----------------------------------------------------------
307

    
308
    sigfillset(&mask);
309

    
310
    pthread_sigmask(SIG_BLOCK, &mask, NULL);
311

    
312
    // -----------------------------------------------------------
313
    //Managers
314
    // -----------------------------------------------------------
315

    
316
    MadManager::mad_manager_system_init();
317

    
318
    time_t timer_period;
319

    
320
    nebula_configuration->get("MANAGER_TIMER", timer_period);
321

    
322
    // ---- Virtual Machine Manager ----
323
    try
324
    {
325
        time_t                    poll_period;
326
        vector<const Attribute *> vmm_mads;
327

    
328
        nebula_configuration->get("VM_POLLING_INTERVAL", poll_period);
329

    
330
        nebula_configuration->get("VM_MAD", vmm_mads);
331

    
332
        vmm = new VirtualMachineManager(
333
            vmpool,
334
            hpool,
335
            timer_period,
336
            poll_period,
337
            vmm_mads);
338
    }
339
    catch (bad_alloc&)
340
    {
341
        throw;
342
    }
343

    
344
    rc = vmm->start();
345

    
346
    if ( rc != 0 )
347
    {
348
        throw runtime_error("Could not start the Virtual Machine Manager");
349
    }
350

    
351
    // ---- Life-cycle Manager ----
352
    try
353
    {
354
        lcm = new LifeCycleManager(vmpool,hpool);
355
    }
356
    catch (bad_alloc&)
357
    {
358
        throw;
359
    }
360

    
361
    rc = lcm->start();
362

    
363
    if ( rc != 0 )
364
    {
365
        throw runtime_error("Could not start the Life-cycle Manager");
366
    }
367

    
368
    // ---- Information Manager ----
369
    try
370
    {
371
        vector<const Attribute *>   im_mads;
372
        time_t                      monitor_period;
373

    
374
        nebula_configuration->get("HOST_MONITORING_INTERVAL", monitor_period);
375

    
376
        nebula_configuration->get("IM_MAD", im_mads);
377

    
378
        im = new InformationManager(hpool,
379
                                    timer_period,
380
                                    monitor_period,
381
                                    remotes_location,
382
                                    im_mads);
383
    }
384
    catch (bad_alloc&)
385
    {
386
        throw;
387
    }
388

    
389
    rc = im->start();
390

    
391
    if ( rc != 0 )
392
    {
393
        throw runtime_error("Could not start the Information Manager");
394
    }
395

    
396
    // ---- Transfer Manager ----
397
    try
398
    {
399
        vector<const Attribute *> tm_mads;
400

    
401
        nebula_configuration->get("TM_MAD", tm_mads);
402

    
403
        tm = new TransferManager(vmpool, hpool, tm_mads);
404
    }
405
    catch (bad_alloc&)
406
    {
407
        throw;
408
    }
409

    
410
    rc = tm->start();
411

    
412
    if ( rc != 0 )
413
    {
414
        throw runtime_error("Could not start the Transfer Manager");
415
    }
416

    
417
    // ---- Dispatch Manager ----
418
    try
419
    {
420
        dm = new DispatchManager(vmpool,hpool);
421
    }
422
    catch (bad_alloc&)
423
    {
424
        throw;
425
    }
426

    
427
    rc = dm->start();
428

    
429
    if ( rc != 0 )
430
    {
431
       throw runtime_error("Could not start the Dispatch Manager");
432
    }
433

    
434
    // ---- Request Manager ----
435
    try
436
    {
437
        int             rm_port = 0;
438

    
439
        nebula_configuration->get("PORT", rm_port);
440

    
441
        rm = new RequestManager(
442
            vmpool,
443
            hpool,
444
            vnpool,
445
            upool,
446
            ipool,
447
            cpool,
448
            tpool,
449
            gpool,
450
            rm_port,
451
            log_location + "one_xmlrpc.log");
452
    }
453
    catch (bad_alloc&)
454
    {
455
        NebulaLog::log("ONE", Log::ERROR, "Error starting RM");
456
        throw;
457
    }
458

    
459
    rc = rm->start();
460

    
461
    if ( rc != 0 )
462
    {
463
       throw runtime_error("Could not start the Request Manager");
464
    }
465

    
466
    // ---- Hook Manager ----
467
    try
468
    {
469
        vector<const Attribute *> hm_mads;
470

    
471
        nebula_configuration->get("HM_MAD", hm_mads);
472

    
473
        hm = new HookManager(hm_mads,vmpool);
474
    }
475
    catch (bad_alloc&)
476
    {
477
        throw;
478
    }
479

    
480
    rc = hm->start();
481

    
482
    if ( rc != 0 )
483
    {
484
       throw runtime_error("Could not start the Hook Manager");
485
    }
486

    
487
    // ---- Auth Manager ----
488
    try
489
    {
490
        vector<const Attribute *> auth_mads;
491

    
492
        nebula_configuration->get("AUTH_MAD", auth_mads);
493

    
494
        if (!auth_mads.empty())
495
        {
496
            //Defaults 60s to timeout auth requests
497
            authm = new AuthManager(timer_period,60,auth_mads);
498
        }
499
        else
500
        {
501
            authm = 0; //Built-in authm/authz
502
        }
503
    }
504
    catch (bad_alloc&)
505
    {
506
        throw;
507
    }
508

    
509
    if (authm != 0)
510
    {
511
        rc = authm->start();
512

    
513
        if ( rc != 0 )
514
        {
515
          throw runtime_error("Could not start the Auth Manager");
516
        }
517
    }
518

    
519
    // ---- Image Manager ----
520
    try
521
    {
522
        vector<const Attribute *> image_mads;
523

    
524
        nebula_configuration->get("IMAGE_MAD", image_mads);
525

    
526
        imagem = new ImageManager(ipool,image_mads);
527
    }
528
    catch (bad_alloc&)
529
    {
530
        throw;
531
    }
532

    
533
    rc = imagem->start();
534

    
535
    if ( rc != 0 )
536
    {
537
       throw runtime_error("Could not start the Image Manager");
538
    }
539

    
540
    // -----------------------------------------------------------
541
    // Load mads
542
    // -----------------------------------------------------------
543

    
544
    sleep(2);
545

    
546
    vmm->load_mads(0);
547

    
548
    im->load_mads(0);
549
    tm->load_mads(0);
550
    hm->load_mads(0);
551
    imagem->load_mads(0);
552

    
553
    if ( authm != 0 )
554
    {
555
        authm->load_mads(0);
556
    }
557

    
558
    // -----------------------------------------------------------
559
    // Wait for a SIGTERM or SIGINT signal
560
    // -----------------------------------------------------------
561

    
562
    sigemptyset(&mask);
563

    
564
    sigaddset(&mask, SIGINT);
565
    sigaddset(&mask, SIGTERM);
566

    
567
    sigwait(&mask, &signal);
568

    
569
    // -----------------------------------------------------------
570
    // Stop the managers & free resources
571
    // -----------------------------------------------------------
572

    
573
    vmm->trigger(VirtualMachineManager::FINALIZE,0);
574
    lcm->trigger(LifeCycleManager::FINALIZE,0);
575

    
576
    tm->trigger(TransferManager::FINALIZE,0);
577
    dm->trigger(DispatchManager::FINALIZE,0);
578

    
579
    im->finalize();
580
    rm->finalize();
581
    hm->finalize();
582
    imagem->finalize();
583

    
584
    //sleep to wait drivers???
585

    
586
    pthread_join(vmm->get_thread_id(),0);
587
    pthread_join(lcm->get_thread_id(),0);
588
    pthread_join(tm->get_thread_id(),0);
589
    pthread_join(dm->get_thread_id(),0);
590

    
591
    pthread_join(im->get_thread_id(),0);
592
    pthread_join(rm->get_thread_id(),0);
593
    pthread_join(hm->get_thread_id(),0);
594
    pthread_join(imagem->get_thread_id(),0);
595

    
596
    //XML Library
597
    xmlCleanupParser();
598

    
599
    NebulaLog::log("ONE", Log::INFO, "All modules finalized, exiting.\n");
600
}