Statistics
| Branch: | Tag: | Revision:

one / src / nebula / Nebula.cc @ 87b5e5cb

History | View | Annotate | Download (33.5 KB)

1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2017, OpenNebula Project, OpenNebula Systems                */
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
#include "Client.h"
23

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

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

    
35
using namespace std;
36

    
37
/* -------------------------------------------------------------------------- */
38
/* -------------------------------------------------------------------------- */
39

    
40
void Nebula::start(bool bootstrap_only)
41
{
42
    int      rc;
43
    int      fd;
44
    sigset_t mask;
45
    int      signal;
46
    char     hn[80];
47
    string   scripts_remote_dir;
48
    SqlDB *  db_backend;
49
    bool     solo;
50

    
51
    SqlDB *  db_ptr;
52

    
53
    if ( gethostname(hn,79) != 0 )
54
    {
55
        throw runtime_error("Error getting hostname");
56
    }
57

    
58
    hostname = hn;
59

    
60
    // -----------------------------------------------------------
61
    // Configuration
62
    // -----------------------------------------------------------
63

    
64
    nebula_configuration = new OpenNebulaTemplate(etc_location, var_location);
65

    
66
    rc = nebula_configuration->load_configuration();
67

    
68
    if ( rc != 0 )
69
    {
70
        throw runtime_error("Could not load nebula configuration file.");
71
    }
72

    
73
    string   config_fname = var_location + "config";
74
    ofstream config_file(config_fname.c_str(), ios_base::trunc & ios_base::out);
75

    
76
    if (config_file.fail() == false)
77
    {
78
        config_file << *nebula_configuration << endl;
79
        config_file.close();
80
    }
81

    
82
    nebula_configuration->get("SCRIPTS_REMOTE_DIR", scripts_remote_dir);
83
    hook_location = scripts_remote_dir + "/hooks/";
84

    
85
    // -----------------------------------------------------------
86
    // Log system
87
    // -----------------------------------------------------------
88

    
89
    ostringstream os;
90

    
91
    try
92
    {
93
        Log::MessageType   clevel;
94
        NebulaLog::LogType log_system;
95

    
96
        log_system = get_log_system();
97
        clevel     = get_debug_level();
98

    
99
        // Initializing ONE Daemon log system
100
        if ( log_system != NebulaLog::UNDEFINED )
101
        {
102
            string log_fname;
103
            log_fname = log_location + "oned.log";
104

    
105
            NebulaLog::init_log_system(log_system,
106
                                       clevel,
107
                                       log_fname.c_str(),
108
                                       ios_base::trunc,
109
                                       "oned");
110
        }
111
        else
112
        {
113
            throw runtime_error("Unknown LOG_SYSTEM.");
114
        }
115

    
116
        os << "Starting " << version() << endl;
117
        os << "----------------------------------------\n";
118
        os << "     OpenNebula Configuration File      \n";
119
        os << "----------------------------------------\n";
120
        os << *nebula_configuration;
121
        os << "----------------------------------------";
122

    
123
        NebulaLog::log("ONE",Log::INFO,os);
124

    
125
        os.str("");
126
        os << "Log level:" << clevel << " [0=ERROR,1=WARNING,2=INFO,3=DEBUG]";
127

    
128
        NebulaLog::log("ONE",Log::INFO,os);
129

    
130
        os.str("");
131
        os << "Support for xmlrpc-c > 1.31: ";
132

    
133
#ifdef OLD_XMLRPC
134
        os << "no. MAX_CONN and MAX_CONN_BACKLOG configuration will not be used";
135
#else
136
        os << "yes";
137
#endif
138

    
139
        NebulaLog::log("ONE",Log::INFO,os);
140
    }
141
    catch(runtime_error&)
142
    {
143
        throw;
144
    }
145

    
146
    // -----------------------------------------------------------
147
    // Load the OpenNebula master key and keep it in memory
148
    // -----------------------------------------------------------
149

    
150
    rc = nebula_configuration->load_key();
151

    
152
    if ( rc != 0 )
153
    {
154
        throw runtime_error("Could not load nebula master key file.");
155
    }
156

    
157
    // -----------------------------------------------------------
158
    // Initialize the XML library
159
    // -----------------------------------------------------------
160
    xmlInitParser();
161

    
162
    // -----------------------------------------------------------
163
    // Init federation configuration
164
    // -----------------------------------------------------------
165
    federation_enabled = false;
166
    federation_master  = false;
167
    zone_id            = 0;
168
    server_id          = -1;
169
    master_oned        = "";
170

    
171
    const VectorAttribute * vatt = nebula_configuration->get("FEDERATION");
172

    
173
    if (vatt != 0)
174
    {
175
        string mode = vatt->vector_value("MODE");
176
        one_util::toupper(mode);
177

    
178
        if (mode == "STANDALONE")
179
        {
180
            federation_enabled = false;
181
            federation_master = false;
182
            zone_id = 0;
183
        }
184
        else if (mode == "MASTER")
185
        {
186
            federation_enabled = true;
187
            federation_master = true;
188
        }
189
        else if (mode == "SLAVE")
190
        {
191
            federation_enabled = true;
192
            federation_master = false;
193
        }
194
        else
195
        {
196
            throw runtime_error(
197
                "FEDERATION MODE must be one of STANDALONE, MASTER, SLAVE.");
198
        }
199

    
200
        if (federation_enabled)
201
        {
202
            rc = vatt->vector_value("ZONE_ID", zone_id);
203

    
204
            if (rc != 0)
205
            {
206
                throw runtime_error("FEDERATION ZONE_ID must be set for "
207
                    "federated instances.");
208
            }
209

    
210
            master_oned = vatt->vector_value("MASTER_ONED");
211

    
212
            if (master_oned.empty() && !federation_master)
213
            {
214
                throw runtime_error(
215
                    "FEDERATION MASTER_ONED endpoint is missing.");
216
            }
217
        }
218

    
219
        if ( vatt->vector_value("SERVER_ID", server_id) != 0 )
220
        {
221
            server_id = -1;
222
        }
223

    
224
    }
225

    
226
    vatt = nebula_configuration->get("RAFT");
227

    
228
    long long election_ms;
229
    long long bcast_ms;
230

    
231
    time_t xmlrpc_ms;
232
    time_t log_purge;
233

    
234
    unsigned int log_retention;
235

    
236
    vatt->vector_value("LOG_PURGE_TIMEOUT", log_purge);
237
    vatt->vector_value("ELECTION_TIMEOUT_MS", election_ms);
238
    vatt->vector_value("BROADCAST_TIMEOUT_MS", bcast_ms);
239
    vatt->vector_value("XMLRPC_TIMEOUT_MS", xmlrpc_ms);
240
    vatt->vector_value("LOG_RETENTION", log_retention);
241

    
242
    Log::set_zone_id(zone_id);
243

    
244
    // -----------------------------------------------------------
245
    // Database
246
    // -----------------------------------------------------------
247
    try
248
    {
249
        bool db_is_sqlite = true;
250

    
251
        string server  = "localhost";
252
        string port_str;
253
        int    port    = 0;
254
        string user    = "oneadmin";
255
        string passwd  = "oneadmin";
256
        string db_name = "opennebula";
257

    
258
        const VectorAttribute * _db = nebula_configuration->get("DB");
259

    
260
        if ( _db != 0 )
261
        {
262
            string value = _db->vector_value("BACKEND");
263

    
264
            if (value == "mysql")
265
            {
266
                db_is_sqlite = false;
267

    
268
                value = _db->vector_value("SERVER");
269
                if (!value.empty())
270
                {
271
                    server = value;
272
                }
273

    
274
                istringstream   is;
275

    
276
                port_str = _db->vector_value("PORT");
277

    
278
                is.str(port_str);
279
                is >> port;
280

    
281
                if( is.fail() )
282
                {
283
                    port = 0;
284
                }
285

    
286
                value = _db->vector_value("USER");
287
                if (!value.empty())
288
                {
289
                    user = value;
290
                }
291

    
292
                value = _db->vector_value("PASSWD");
293
                if (!value.empty())
294
                {
295
                    passwd = value;
296
                }
297

    
298
                value = _db->vector_value("DB_NAME");
299
                if (!value.empty())
300
                {
301
                    db_name = value;
302
                }
303
            }
304
        }
305

    
306
        if ( db_is_sqlite )
307
        {
308
            db_backend = new SqliteDB(var_location + "one.db");
309
        }
310
        else
311
        {
312
            db_backend = new MySqlDB(server, port, user, passwd, db_name);
313
        }
314

    
315
        // ---------------------------------------------------------------------
316
        // Check Database Versions
317
        // ---------------------------------------------------------------------
318
        bool local_bootstrap;
319
        bool shared_bootstrap;
320

    
321
        NebulaLog::log("ONE",Log::INFO,"Checking database version.");
322

    
323
        SystemDB sysdb(db_backend);
324

    
325
        rc = sysdb.check_db_version(is_federation_slave(), local_bootstrap,
326
                shared_bootstrap);
327

    
328
        if( rc == -1 )
329
        {
330
            throw runtime_error("Database version mismatch. Check oned.log.");
331
        }
332

    
333
        // ---------------------------------------------------------------------
334
        // Initialize logging and federation database facilities and SystemDB
335
        // ---------------------------------------------------------------------
336
        solo = server_id == -1;
337

    
338
        if ( (solo && local_bootstrap) || bootstrap_only)
339
        {
340
            if ( logdb->bootstrap(db_backend) != 0 )
341
            {
342
                throw runtime_error("Error bootstrapping database.");
343
            }
344
        }
345

    
346
        logdb = new LogDB(db_backend, solo, log_retention);
347

    
348
        if ( federation_master )
349
        {
350
            fed_logdb = new FedLogDB(logdb);
351
            db_ptr    = fed_logdb;
352
        }
353
        else
354
        {
355
            db_ptr = logdb;
356
        }
357

    
358
        system_db = new SystemDB(logdb);
359

    
360
        // ---------------------------------------------------------------------
361
        // DB Bootstraping
362
        // ---------------------------------------------------------------------
363
        rc = 0;
364

    
365
        if ( (local_bootstrap || shared_bootstrap) && !solo )
366
        {
367
            throw runtime_error("Database has to be bootstraped to start"
368
                    " oned in HA");
369
        }
370

    
371
        if (local_bootstrap)
372
        {
373
            NebulaLog::log("ONE",Log::INFO,
374
                    "Bootstrapping OpenNebula database, stage 1.");
375

    
376
            rc += VirtualMachinePool::bootstrap(logdb);
377
            rc += HostPool::bootstrap(logdb);
378
            rc += VirtualNetworkPool::bootstrap(logdb);
379
            rc += ImagePool::bootstrap(logdb);
380
            rc += VMTemplatePool::bootstrap(logdb);
381
            rc += DatastorePool::bootstrap(logdb);
382
            rc += ClusterPool::bootstrap(logdb);
383
            rc += DocumentPool::bootstrap(logdb);
384
            rc += UserQuotas::bootstrap(logdb);
385
            rc += GroupQuotas::bootstrap(logdb);
386
            rc += SecurityGroupPool::bootstrap(logdb);
387
            rc += VirtualRouterPool::bootstrap(logdb);
388
            rc += VMGroupPool::bootstrap(logdb);
389

    
390
            // Create the system tables only if bootstrap went well
391
            if (rc == 0)
392
            {
393
                rc += system_db->local_bootstrap();
394
            }
395

    
396
            // Insert default system attributes
397
            rc += default_user_quota.insert();
398
            rc += default_group_quota.insert();
399
        }
400

    
401
        if (shared_bootstrap)
402
        {
403
            NebulaLog::log("ONE",Log::INFO,
404
                    "Bootstrapping OpenNebula database, stage 2.");
405

    
406
            rc += GroupPool::bootstrap(logdb);
407
            rc += UserPool::bootstrap(logdb);
408
            rc += AclManager::bootstrap(logdb);
409
            rc += ZonePool::bootstrap(logdb);
410
            rc += VdcPool::bootstrap(logdb);
411
            rc += MarketPlacePool::bootstrap(logdb);
412
            rc += MarketPlaceAppPool::bootstrap(logdb);
413

    
414
            // Create the system tables only if bootstrap went well
415
            if ( rc == 0 )
416
            {
417
                rc += system_db->shared_bootstrap();
418
            }
419
        }
420

    
421
        if ( rc != 0 )
422
        {
423
            throw runtime_error("Error bootstrapping database.");
424
        }
425
    }
426
    catch (exception&)
427
    {
428
        throw;
429
    }
430

    
431
    if (bootstrap_only)
432
    {
433
        //XML Library
434
        xmlCleanupParser();
435

    
436
        NebulaLog::log("ONE", Log::INFO,
437
                "Database bootstrap finalized, exiting.\n");
438
        return;
439
    }
440

    
441
    // -----------------------------------------------------------
442
    // Close stds, we no longer need them
443
    // -----------------------------------------------------------
444
    if (NebulaLog::log_type() != NebulaLog::STD )
445
    {
446
        fd = open("/dev/null", O_RDWR);
447

    
448
        dup2(fd,0);
449
        dup2(fd,1);
450
        dup2(fd,2);
451

    
452
        close(fd);
453

    
454
        fcntl(0, F_SETFD, 0); // Keep them open across exec funcs
455
        fcntl(1, F_SETFD, 0);
456
        fcntl(2, F_SETFD, 0);
457
    }
458
    else
459
    {
460
        fcntl(0, F_SETFD, FD_CLOEXEC);
461
        fcntl(1, F_SETFD, FD_CLOEXEC);
462
        fcntl(2, F_SETFD, FD_CLOEXEC);
463
    }
464

    
465
    // -----------------------------------------------------------
466
    // Block all signals before creating any Nebula thread
467
    // -----------------------------------------------------------
468

    
469
    sigfillset(&mask);
470

    
471
    pthread_sigmask(SIG_BLOCK, &mask, NULL);
472

    
473
    one_util::SSLMutex::initialize();
474

    
475
    // -----------------------------------------------------------
476
    //Managers
477
    // -----------------------------------------------------------
478

    
479
    MadManager::mad_manager_system_init();
480

    
481
    time_t timer_period;
482
    time_t monitor_period;
483

    
484
    nebula_configuration->get("MANAGER_TIMER", timer_period);
485
    nebula_configuration->get("MONITORING_INTERVAL", monitor_period);
486

    
487
    // ---- ACL Manager ----
488
    try
489
    {
490
        aclm = new AclManager(db_ptr, zone_id, is_federation_slave(),
491
                timer_period);
492
    }
493
    catch (bad_alloc&)
494
    {
495
        throw;
496
    }
497

    
498
    rc = aclm->start();
499

    
500
    if ( rc != 0 )
501
    {
502
       throw runtime_error("Could not start the ACL Manager");
503
    }
504

    
505
    // -------------------------------------------------------------------------
506
    // Pools
507
    // -------------------------------------------------------------------------
508
    try
509
    {
510
        /* -------------------------- Cluster Pool -------------------------- */
511
        const VectorAttribute * vnc_conf;
512

    
513
        vnc_conf = nebula_configuration->get("VNC_PORTS");
514

    
515
        clpool = new ClusterPool(logdb, vnc_conf);
516

    
517
        /* --------------------- VirtualMachine Pool ------------------------ */
518
        vector<const VectorAttribute *> vm_hooks;
519
        vector<const SingleAttribute *> vm_restricted_attrs;
520

    
521
        time_t vm_expiration;
522
        bool   vm_submit_on_hold;
523

    
524
        float cpu_cost;
525
        float mem_cost;
526
        float disk_cost;
527

    
528
        const VectorAttribute * default_cost;
529

    
530
        nebula_configuration->get("VM_HOOK", vm_hooks);
531

    
532
        nebula_configuration->get("VM_RESTRICTED_ATTR", vm_restricted_attrs);
533

    
534
        nebula_configuration->get("VM_MONITORING_EXPIRATION_TIME",vm_expiration);
535

    
536
        nebula_configuration->get("VM_SUBMIT_ON_HOLD",vm_submit_on_hold);
537

    
538
        default_cost = nebula_configuration->get("DEFAULT_COST");
539

    
540
        if (default_cost->vector_value("CPU_COST", cpu_cost) != 0)
541
        {
542
            cpu_cost = 0;
543
        }
544

    
545
        if (default_cost->vector_value("MEMORY_COST", mem_cost) != 0)
546
        {
547
            mem_cost = 0;
548
        }
549

    
550
        if (default_cost->vector_value("DISK_COST", disk_cost) != 0)
551
        {
552
            disk_cost = 0;
553
        }
554

    
555
        vmpool = new VirtualMachinePool(logdb, vm_hooks, hook_location,
556
            remotes_location, vm_restricted_attrs, vm_expiration,
557
            vm_submit_on_hold, cpu_cost, mem_cost, disk_cost);
558

    
559
        /* ---------------------------- Host Pool --------------------------- */
560
        vector<const VectorAttribute *> host_hooks;
561

    
562
        time_t host_expiration;
563

    
564
        nebula_configuration->get("HOST_HOOK", host_hooks);
565

    
566
        nebula_configuration->get("HOST_MONITORING_EXPIRATION_TIME",
567
                host_expiration);
568

    
569
        hpool  = new HostPool(logdb, host_hooks, hook_location, remotes_location,
570
            host_expiration);
571

    
572
        /* --------------------- VirtualRouter Pool ------------------------- */
573
        vector<const VectorAttribute *> vrouter_hooks;
574

    
575
        nebula_configuration->get("VROUTER_HOOK", vrouter_hooks);
576

    
577
        vrouterpool = new VirtualRouterPool(logdb, vrouter_hooks,
578
                remotes_location);
579

    
580
        /* -------------------- VirtualNetwork Pool ------------------------- */
581
        int     size;
582
        string  mac_prefix;
583

    
584
        vector<const SingleAttribute *> inherit_vnet_attrs;
585
        vector<const SingleAttribute *> vnet_restricted_attrs;
586
        vector<const VectorAttribute *> vnet_hooks;
587

    
588
        const VectorAttribute * vlan_id;
589
        const VectorAttribute * vxlan_id;
590

    
591
        nebula_configuration->get("MAC_PREFIX", mac_prefix);
592

    
593
        nebula_configuration->get("NETWORK_SIZE", size);
594

    
595
        nebula_configuration->get("VNET_RESTRICTED_ATTR", vnet_restricted_attrs);
596

    
597
        nebula_configuration->get("VNET_HOOK", vnet_hooks);
598

    
599
        nebula_configuration->get("INHERIT_VNET_ATTR", inherit_vnet_attrs);
600

    
601
        vlan_id  = nebula_configuration->get("VLAN_IDS");
602

    
603
        vxlan_id = nebula_configuration->get("VXLAN_IDS");
604

    
605
        vnpool = new VirtualNetworkPool(logdb, mac_prefix, size,
606
                vnet_restricted_attrs, vnet_hooks, remotes_location,
607
                inherit_vnet_attrs, vlan_id, vxlan_id);
608

    
609
        /* ----------------------- Group/User Pool -------------------------- */
610
        vector<const VectorAttribute *> user_hooks;
611
        vector<const VectorAttribute *> group_hooks;
612

    
613
        time_t  expiration_time;
614

    
615
        nebula_configuration->get("GROUP_HOOK", group_hooks);
616

    
617
        gpool = new GroupPool(db_ptr, group_hooks, remotes_location,
618
                is_federation_slave());
619

    
620
        nebula_configuration->get("SESSION_EXPIRATION_TIME", expiration_time);
621

    
622
        nebula_configuration->get("USER_HOOK", user_hooks);
623

    
624
        upool = new UserPool(db_ptr, expiration_time, user_hooks,
625
                remotes_location, is_federation_slave());
626

    
627
        /* -------------------- Image/Datastore Pool ------------------------ */
628
        string  image_type;
629
        string  device_prefix;
630
        string  cd_dev_prefix;
631

    
632
        vector<const VectorAttribute *> image_hooks;
633
        vector<const SingleAttribute *> img_restricted_attrs;
634
        vector<const SingleAttribute *> inherit_image_attrs;
635
        vector<const SingleAttribute *> inherit_ds_attrs;
636

    
637
        nebula_configuration->get("DEFAULT_IMAGE_TYPE", image_type);
638
        nebula_configuration->get("DEFAULT_DEVICE_PREFIX", device_prefix);
639
        nebula_configuration->get("DEFAULT_CDROM_DEVICE_PREFIX", cd_dev_prefix);
640

    
641
        nebula_configuration->get("IMAGE_HOOK", image_hooks);
642

    
643
        nebula_configuration->get("IMAGE_RESTRICTED_ATTR", img_restricted_attrs);
644

    
645
        nebula_configuration->get("INHERIT_IMAGE_ATTR", inherit_image_attrs);
646

    
647
        ipool = new ImagePool(logdb, image_type, device_prefix, cd_dev_prefix,
648
            img_restricted_attrs, image_hooks, remotes_location,
649
            inherit_image_attrs);
650

    
651
        nebula_configuration->get("INHERIT_DATASTORE_ATTR", inherit_ds_attrs);
652

    
653
        dspool = new DatastorePool(logdb, inherit_ds_attrs);
654

    
655
        /* ----- Document, Zone, VDC, VMTemplate, SG and Makerket Pools ----- */
656
        docpool  = new DocumentPool(logdb);
657
        zonepool = new ZonePool(db_ptr, is_federation_slave());
658
        vdcpool  = new VdcPool(db_ptr, is_federation_slave());
659

    
660
        tpool = new VMTemplatePool(logdb);
661

    
662
        secgrouppool = new SecurityGroupPool(logdb);
663

    
664
        marketpool = new MarketPlacePool(db_ptr, is_federation_slave());
665
        apppool    = new MarketPlaceAppPool(db_ptr);
666

    
667
        vmgrouppool = new VMGroupPool(logdb);
668

    
669
        default_user_quota.select();
670
        default_group_quota.select();
671
    }
672
    catch (exception&)
673
    {
674
        throw runtime_error("Error Initializing OpenNebula pools");
675
    }
676

    
677
    // ---- XMLRPC Client for federation slaves ----
678
    if (is_federation_slave())
679
    {
680
        long long msg_size;
681

    
682
        unsigned int timeout;
683

    
684
        get_configuration_attribute("MESSAGE_SIZE", msg_size);
685

    
686
        get_configuration_attribute("TIMEOUT", timeout);
687

    
688
        Client::initialize("", get_master_oned(), msg_size, timeout);
689
    }
690

    
691
    // ---- Hook Manager ----
692
    try
693
    {
694
        vector<const VectorAttribute *> hm_mads;
695

    
696
        nebula_configuration->get("HM_MAD", hm_mads);
697

    
698
        hm = new HookManager(hm_mads,vmpool);
699
    }
700
    catch (bad_alloc&)
701
    {
702
        throw;
703
    }
704

    
705
    rc = hm->start();
706

    
707
    if ( rc != 0 )
708
    {
709
       throw runtime_error("Could not start the Hook Manager");
710
    }
711

    
712
    if (hm->load_mads(0) != 0)
713
    {
714
        goto error_mad;
715
    }
716

    
717

    
718
    // ---- Raft Manager ----
719
    const VectorAttribute * raft_leader_hook;
720
    const VectorAttribute * raft_follower_hook;
721

    
722
    raft_leader_hook   = nebula_configuration->get("RAFT_LEADER_HOOK");
723
    raft_follower_hook = nebula_configuration->get("RAFT_FOLLOWER_HOOK");
724

    
725
    try
726
    {
727
        raftm = new RaftManager(server_id, raft_leader_hook, raft_follower_hook,
728
                log_purge, bcast_ms, election_ms, xmlrpc_ms, remotes_location);
729
    }
730
    catch (bad_alloc&)
731
    {
732
        throw;
733
    }
734

    
735
    rc = raftm->start();
736

    
737
    if ( rc != 0 )
738
    {
739
       throw runtime_error("Could not start the Raft Consensus Manager");
740
    }
741

    
742
    // ---- FedReplica Manager ----
743
    try
744
    {
745
        frm = new FedReplicaManager(logdb);
746
    }
747
    catch (bad_alloc&)
748
    {
749
        throw;
750
    }
751

    
752
    rc = frm->start();
753

    
754
    if ( is_federation_master() && solo )
755
    {
756
        // Replica threads are started on master in solo mode.
757
        // HA start/stop the replica threads on leader/follower states 
758
        frm->start_replica_threads();
759
    }
760

    
761
    if ( rc != 0 )
762
    {
763
       throw runtime_error("Could not start the Federation Replica Manager");
764
    }
765

    
766
    // ---- Virtual Machine Manager ----
767
    try
768
    {
769
        vector<const VectorAttribute *> vmm_mads;
770
        int    vm_limit;
771

    
772
        bool   do_poll;
773
        time_t poll_period = 0;
774

    
775
        nebula_configuration->get("VM_PER_INTERVAL", vm_limit);
776

    
777
        nebula_configuration->get("VM_MAD", vmm_mads);
778

    
779
        nebula_configuration->get("VM_INDIVIDUAL_MONITORING", do_poll);
780

    
781
        poll_period = monitor_period * 2.5;
782

    
783
        vmm = new VirtualMachineManager(
784
            timer_period,
785
            poll_period,
786
            do_poll,
787
            vm_limit,
788
            vmm_mads);
789
    }
790
    catch (bad_alloc&)
791
    {
792
        throw;
793
    }
794

    
795
    rc = vmm->start();
796

    
797
    if ( rc != 0 )
798
    {
799
        throw runtime_error("Could not start the Virtual Machine Manager");
800
    }
801

    
802
    // ---- Life-cycle Manager ----
803
    try
804
    {
805
        lcm = new LifeCycleManager();
806
    }
807
    catch (bad_alloc&)
808
    {
809
        throw;
810
    }
811

    
812
    rc = lcm->start();
813

    
814
    if ( rc != 0 )
815
    {
816
        throw runtime_error("Could not start the Life-cycle Manager");
817
    }
818

    
819
    // ---- Information Manager ----
820
    try
821
    {
822
        vector<const VectorAttribute *> im_mads;
823

    
824
        int host_limit;
825
        int monitor_threads;
826

    
827
        nebula_configuration->get("HOST_PER_INTERVAL", host_limit);
828

    
829
        nebula_configuration->get("MONITORING_THREADS", monitor_threads);
830

    
831
        nebula_configuration->get("IM_MAD", im_mads);
832

    
833
        im = new InformationManager(hpool,
834
                                    clpool,
835
                                    timer_period,
836
                                    monitor_period,
837
                                    host_limit,
838
                                    monitor_threads,
839
                                    remotes_location,
840
                                    im_mads);
841
    }
842
    catch (bad_alloc&)
843
    {
844
        throw;
845
    }
846

    
847
    rc = im->start();
848

    
849
    if ( rc != 0 )
850
    {
851
        throw runtime_error("Could not start the Information Manager");
852
    }
853

    
854
    // ---- Transfer Manager ----
855
    try
856
    {
857
        vector<const VectorAttribute *> tm_mads;
858

    
859
        nebula_configuration->get("TM_MAD", tm_mads);
860

    
861
        tm = new TransferManager(vmpool, hpool, tm_mads);
862
    }
863
    catch (bad_alloc&)
864
    {
865
        throw;
866
    }
867

    
868
    rc = tm->start();
869

    
870
    if ( rc != 0 )
871
    {
872
        throw runtime_error("Could not start the Transfer Manager");
873
    }
874

    
875
    // ---- Dispatch Manager ----
876
    try
877
    {
878
        dm = new DispatchManager();
879
    }
880
    catch (bad_alloc&)
881
    {
882
        throw;
883
    }
884

    
885
    rc = dm->start();
886

    
887
    if ( rc != 0 )
888
    {
889
       throw runtime_error("Could not start the Dispatch Manager");
890
    }
891

    
892
    // ---- Auth Manager ----
893
    try
894
    {
895
        vector<const VectorAttribute *> auth_mads;
896

    
897
        nebula_configuration->get("AUTH_MAD", auth_mads);
898

    
899
        if (!auth_mads.empty())
900
        {
901
            authm = new AuthManager(timer_period, auth_mads);
902
        }
903
        else
904
        {
905
            authm = 0; //Built-in authm/authz
906
        }
907
    }
908
    catch (bad_alloc&)
909
    {
910
        throw;
911
    }
912

    
913
    if (authm != 0)
914
    {
915
        rc = authm->start();
916

    
917
        if ( rc != 0 )
918
        {
919
          throw runtime_error("Could not start the Auth Manager");
920
        }
921
    }
922

    
923
    // ---- Image Manager ----
924
    try
925
    {
926
        vector<const VectorAttribute *> image_mads;
927

    
928
        nebula_configuration->get("DATASTORE_MAD", image_mads);
929

    
930
        imagem = new ImageManager(timer_period,
931
                                  monitor_period,
932
                                  ipool,
933
                                  dspool,
934
                                  image_mads);
935
    }
936
    catch (bad_alloc&)
937
    {
938
        throw;
939
    }
940

    
941
    rc = imagem->start();
942

    
943
    if ( rc != 0 )
944
    {
945
       throw runtime_error("Could not start the Image Manager");
946
    }
947

    
948
    // ---- Marketplace Manager ----
949
    try
950
    {
951
        vector<const VectorAttribute *> mmads ;
952

    
953
        nebula_configuration->get("MARKET_MAD", mmads);
954

    
955
        marketm = new MarketPlaceManager(timer_period, monitor_period, mmads);
956
    }
957
    catch (bad_alloc&)
958
    {
959
        throw;
960
    }
961

    
962
    rc = marketm->start();
963

    
964
    if ( rc != 0 )
965
    {
966
       throw runtime_error("Could not start the Marketplace Manager");
967
    }
968

    
969
    // ---- IPAM Manager ----
970
    try
971
    {
972
        vector<const VectorAttribute *> ipam_mads ;
973

    
974
        nebula_configuration->get("IPAM_MAD", ipam_mads);
975

    
976
        ipamm = new IPAMManager(timer_period, ipam_mads);
977
    }
978
    catch (bad_alloc&)
979
    {
980
        throw;
981
    }
982

    
983
    rc = ipamm->start();
984

    
985
    if ( rc != 0 )
986
    {
987
       throw runtime_error("Could not start the IPAM Manager");
988
    }
989

    
990
    // -----------------------------------------------------------
991
    // Load mads
992
    // -----------------------------------------------------------
993

    
994
    usleep(2500000);
995

    
996
    rc = 0;
997

    
998
    if (vmm->load_mads(0) != 0)
999
    {
1000
        goto error_mad;
1001
    }
1002

    
1003
    if (im->load_mads(0) != 0)
1004
    {
1005
        goto error_mad;
1006
    }
1007

    
1008
    if (tm->load_mads(0) != 0)
1009
    {
1010
        goto error_mad;
1011
    }
1012

    
1013
    if (imagem->load_mads(0) != 0)
1014
    {
1015
        goto error_mad;
1016
    }
1017

    
1018
    if (marketm->load_mads(0) != 0)
1019
    {
1020
        goto error_mad;
1021
    }
1022

    
1023
    if (ipamm->load_mads(0) != 0)
1024
    {
1025
        goto error_mad;
1026
    }
1027

    
1028
    if ( authm != 0 )
1029
    {
1030
        if (authm->load_mads(0) != 0)
1031
        {
1032
            goto error_mad;
1033
        }
1034
    }
1035

    
1036
    // ---- Request Manager ----
1037
    try
1038
    {
1039
        string rm_port;
1040
        int  max_conn;
1041
        int  max_conn_backlog;
1042
        int  keepalive_timeout;
1043
        int  keepalive_max_conn;
1044
        int  timeout;
1045
        bool rpc_log;
1046
        string log_call_format;
1047
        string rpc_filename = "";
1048
        int  message_size;
1049
        string rm_listen_address = "0.0.0.0";
1050

    
1051
        nebula_configuration->get("PORT", rm_port);
1052
        nebula_configuration->get("LISTEN_ADDRESS", rm_listen_address);
1053
        nebula_configuration->get("MAX_CONN", max_conn);
1054
        nebula_configuration->get("MAX_CONN_BACKLOG", max_conn_backlog);
1055
        nebula_configuration->get("KEEPALIVE_TIMEOUT", keepalive_timeout);
1056
        nebula_configuration->get("KEEPALIVE_MAX_CONN", keepalive_max_conn);
1057
        nebula_configuration->get("TIMEOUT", timeout);
1058
        nebula_configuration->get("RPC_LOG", rpc_log);
1059
        nebula_configuration->get("LOG_CALL_FORMAT", log_call_format);
1060
        nebula_configuration->get("MESSAGE_SIZE", message_size);
1061

    
1062
        if (rpc_log)
1063
        {
1064
            rpc_filename = log_location + "one_xmlrpc.log";
1065
        }
1066

    
1067
        rm = new RequestManager(rm_port, max_conn, max_conn_backlog,
1068
            keepalive_timeout, keepalive_max_conn, timeout, rpc_filename,
1069
            log_call_format, rm_listen_address, message_size);
1070
    }
1071
    catch (bad_alloc&)
1072
    {
1073
        NebulaLog::log("ONE", Log::ERROR, "Error starting RM");
1074
        throw;
1075
    }
1076

    
1077
    // ---- Initialize Manager cross-reference pointers and pool references ----
1078

    
1079
    dm->init_managers();
1080

    
1081
    lcm->init_managers();
1082

    
1083
    marketm->init_managers();
1084

    
1085
    // ---- Start the Request Manager ----
1086

    
1087
    rc = rm->start();
1088

    
1089
    if ( rc != 0 )
1090
    {
1091
       throw runtime_error("Could not start the Request Manager");
1092
    }
1093

    
1094
    // -----------------------------------------------------------
1095
    // Wait for a SIGTERM or SIGINT signal
1096
    // -----------------------------------------------------------
1097

    
1098
    sigemptyset(&mask);
1099

    
1100
    sigaddset(&mask, SIGINT);
1101
    sigaddset(&mask, SIGTERM);
1102

    
1103
    sigwait(&mask, &signal);
1104

    
1105
    // -----------------------------------------------------------
1106
    // Stop the managers & free resources
1107
    // -----------------------------------------------------------
1108

    
1109
    vmm->finalize();
1110
    lcm->finalize();
1111

    
1112
    tm->finalize();
1113
    dm->finalize();
1114

    
1115
    im->finalize();
1116
    rm->finalize();
1117
    hm->finalize();
1118
    imagem->finalize();
1119
    marketm->finalize();
1120
        ipamm->finalize();
1121
    aclm->finalize();
1122
    raftm->finalize();
1123
    frm->finalize();
1124

    
1125
    //sleep to wait drivers???
1126

    
1127
    pthread_join(vmm->get_thread_id(),0);
1128
    pthread_join(lcm->get_thread_id(),0);
1129
    pthread_join(tm->get_thread_id(),0);
1130
    pthread_join(dm->get_thread_id(),0);
1131

    
1132
    pthread_join(im->get_thread_id(),0);
1133
    pthread_join(rm->get_thread_id(),0);
1134
    pthread_join(hm->get_thread_id(),0);
1135
    pthread_join(imagem->get_thread_id(),0);
1136
    pthread_join(marketm->get_thread_id(),0);
1137
    pthread_join(ipamm->get_thread_id(),0);
1138
    pthread_join(raftm->get_thread_id(),0);
1139
    pthread_join(frm->get_thread_id(),0);
1140

    
1141
    if(is_federation_slave())
1142
    {
1143
        pthread_join(aclm->get_thread_id(),0);
1144
    }
1145

    
1146
    //XML Library
1147
    xmlCleanupParser();
1148

    
1149
    one_util::SSLMutex::finalize();
1150

    
1151
    NebulaLog::log("ONE", Log::INFO, "All modules finalized, exiting.\n");
1152

    
1153
    return;
1154

    
1155
error_mad:
1156
    NebulaLog::log("ONE", Log::ERROR, "Could not load driver");
1157
    throw runtime_error("Could not load an OpenNebula driver");
1158
}
1159

    
1160

    
1161
/* -------------------------------------------------------------------------- */
1162
/* -------------------------------------------------------------------------- */
1163

    
1164
Log::MessageType Nebula::get_debug_level() const
1165
{
1166
    Log::MessageType clevel = Log::ERROR;
1167
    int              log_level_int;
1168

    
1169
    const VectorAttribute * log = nebula_configuration->get("LOG");
1170

    
1171
    if ( log != 0 )
1172
    {
1173
        string value = log->vector_value("DEBUG_LEVEL");
1174

    
1175
        log_level_int = atoi(value.c_str());
1176

    
1177
        if ( Log::ERROR <= log_level_int && log_level_int <= Log::DDDEBUG )
1178
        {
1179
            clevel = static_cast<Log::MessageType>(log_level_int);
1180
        }
1181
    }
1182

    
1183
    return clevel;
1184
}
1185

    
1186
/* -------------------------------------------------------------------------- */
1187
/* -------------------------------------------------------------------------- */
1188

    
1189
NebulaLog::LogType Nebula::get_log_system() const
1190
{
1191
    NebulaLog::LogType log_system = NebulaLog::UNDEFINED;
1192

    
1193
    const VectorAttribute * log = nebula_configuration->get("LOG");
1194

    
1195
    if ( log != 0 )
1196
    {
1197
        string value = log->vector_value("SYSTEM");
1198
        log_system   = NebulaLog::str_to_type(value);
1199
    }
1200

    
1201
    return log_system;
1202
};
1203

    
1204
/* -------------------------------------------------------------------------- */
1205
/* -------------------------------------------------------------------------- */
1206

    
1207
void Nebula::get_ds_location(string& dsloc)
1208
{
1209
    get_configuration_attribute("DATASTORE_LOCATION", dsloc);
1210
}
1211

    
1212
/* -------------------------------------------------------------------------- */
1213
/* -------------------------------------------------------------------------- */
1214

    
1215
string Nebula::get_vm_log_filename(int oid)
1216
{
1217
    ostringstream oss;
1218

    
1219
    if (nebula_location == "/")
1220
    {
1221
        oss << log_location << oid << ".log";
1222
    }
1223
    else
1224
    {
1225
        oss << vms_location << oid << "/vm.log";
1226
    }
1227

    
1228
    return oss.str();
1229
};
1230

    
1231
/* -------------------------------------------------------------------------- */
1232
/* -------------------------------------------------------------------------- */
1233

    
1234
int Nebula::get_conf_attribute(
1235
    const std::string& key,
1236
    const std::string& name,
1237
    const VectorAttribute* &value) const
1238
{
1239
    std::vector<const VectorAttribute*>::const_iterator it;
1240
    std::vector<const VectorAttribute*> values;
1241
    std::string template_name;
1242
    std::string name_upper = name;
1243

    
1244
    one_util::toupper(name_upper);
1245

    
1246
    nebula_configuration->get(key, values);
1247

    
1248
    for (it = values.begin(); it != values.end(); it ++)
1249
    {
1250
        value         = *it;
1251
        template_name = (*it)->vector_value("NAME");
1252

    
1253
        one_util::toupper(template_name);
1254

    
1255
        if ( template_name == name_upper )
1256
        {
1257
            return 0;
1258
        }
1259
    }
1260

    
1261
    value = 0;
1262
    return -1;
1263
};
1264