opennebula-3.3.80-nichotplug.patch

Simon Boulet, 04/15/2012 02:20 AM

Download (22.7 KB)

View differences:

opennebula-3.3.80-nichotplug/include/RequestManagerVirtualMachine.h 2012-04-13 14:58:14.000000000 -0400
140 140
            RequestAttributes& att);
141 141
};
142 142

  
143
/* ------------------------------------------------------------------------- */
144
/* ------------------------------------------------------------------------- */
145

  
146
class VirtualMachineAddNic : public RequestManagerVirtualMachine
147
{
148
public:
149
    VirtualMachineAddNic():
150
        RequestManagerVirtualMachine("VirtualMachineAddNic",
151
                           "Add NIC to running virtual machine",
152
                           "A:sis"){};
153

  
154
    ~VirtualMachineAddNic(){};
155

  
156
    void request_execute(xmlrpc_c::paramList const& _paramList,
157
            RequestAttributes& att);
158
};
159

  
160
/* -------------------------------------------------------------------------- */
161
/* -------------------------------------------------------------------------- */
162

  
163
class VirtualMachineRemoveNic : public RequestManagerVirtualMachine
164
{
165
public:
166
    VirtualMachineRemoveNic():
167
        RequestManagerVirtualMachine("VirtualMachineRemoveNic",
168
                           "Remove NIC from running virtual machine",
169
                           "A:sis"){};
170

  
171
    ~VirtualMachineRemoveNic(){};
172

  
173
    void request_execute(xmlrpc_c::paramList const& _paramList,
174
            RequestAttributes& att);
175
};
176

  
143 177
/* -------------------------------------------------------------------------- */
144 178
/* -------------------------------------------------------------------------- */
145 179
/* -------------------------------------------------------------------------- */
opennebula-3.3.80-nichotplug/include/VirtualMachineManagerDriver.h 2012-04-14 11:26:37.000000000 -0400
164 164
        const string& drv_msg) const;
165 165

  
166 166
    /**
167
     *  Sends a save request to the MAD: "RESTORE ID XML_DRV_MSG"
167
     *  Sends a restore request to the MAD: "RESTORE ID XML_DRV_MSG"
168 168
     *    @param oid the virtual machine id.
169 169
     *    @param drv_msg xml data for the mad operation
170 170
     */
......
189 189
    void poll (
190 190
        const int     oid,
191 191
        const string& drv_msg) const;
192

  
193
    /**
194
     *  Sends a addnic request to the MAD: "ADDNIC ID XML_DRV_MSG"
195
     *    @param oid the virtual machine id.
196
     *    @param drv_msg xml data for the mad operation
197
     */
198
    void addnic (
199
        const int     oid,
200
        const string& drv_msg) const;
201

  
202
    /**
203
     *  Sends a rmnic request to the MAD: "RMNIC ID XML_DRV_MSG"
204
     *    @param oid the virtual machine id.
205
     *    @param drv_msg xml data for the mad operation
206
     */
207
    void rmnic (
208
        const int     oid,
209
        const string& drv_msg) const;
210

  
192 211
};
193 212

  
194 213
/* -------------------------------------------------------------------------- */
opennebula-3.3.80-nichotplug/include/VirtualMachineManager.h 2012-04-14 11:23:28.000000000 -0400
53 53
        RESTORE,
54 54
        REBOOT,
55 55
        POLL,
56
	ADDNIC,
57
	RMNIC,
56 58
        TIMER,
57 59
        DRIVER_CANCEL,
58 60
        FINALIZE
......
278 280
        int vid);
279 281
    
280 282
    /**
283
     *  Add NIC to a running VM. 
284
     *    @param vid the id of the VM.
285
     */
286
    void addnic_action(
287
        int vid);
288

  
289
    /**
290
     *  Remove NIC from a running VM.
291
     *    @param vid the id of the VM.
292
     */
293
    void rmnic_action(
294
        int vid);
295

  
296
    /**
281 297
     *  This function is executed periodically to poll the running VMs
282 298
     */
283 299
    void timer_action();
opennebula-3.3.80-nichotplug/src/mad/ruby/VirtualMachineDriver.rb 2012-04-14 11:07:58.000000000 -0400
42 42
        :restore    => "RESTORE",
43 43
        :migrate    => "MIGRATE",
44 44
        :poll       => "POLL",
45
        :log        => "LOG"
45
        :log        => "LOG",
46
        :addnic     => "ADDNIC",
47
        :rmnic      => "RMNIC"
46 48
    }
47 49

  
48 50
    POLL_ATTRIBUTE = {
......
87 89
        register_action(ACTION[:restore].to_sym,    method("restore"))
88 90
        register_action(ACTION[:migrate].to_sym,    method("migrate"))
89 91
        register_action(ACTION[:poll].to_sym,       method("poll"))
92
        register_action(ACTION[:addnic].to_sym,     method("addnic"))
93
        register_action(ACTION[:rmnic].to_sym,     method("rmnic"))
90 94
    end
91 95

  
92 96
    # Decodes the encoded XML driver message received from the core
......
151 155
        send_message(ACTION[:poll],RESULT[:failure],id,error)
152 156
    end
153 157

  
158
    def addnic(id, drv_message)
159
        error = "Action not implemented by driver #{self.class}"
160
        send_message(ACTION[:addnic],RESULT[:failure],id,error)
161
    end
162

  
163
    def rmnic(id, drv_message)
164
        error = "Action not implemented by driver #{self.class}"
165
        send_message(ACTION[:rmnic],RESULT[:failure],id,error)
166
    end
167

  
154 168
private
155 169
    # Interface to handle the pending events from the ActionManager Interface
156 170
    def delete_running_action(action_id)
opennebula-3.3.80-nichotplug/src/rm/RequestManager.cc 2012-04-13 14:51:57.000000000 -0400
242 242
    xmlrpc_c::methodPtr vm_migrate(new VirtualMachineMigrate());
243 243
    xmlrpc_c::methodPtr vm_action(new VirtualMachineAction()); 
244 244
    xmlrpc_c::methodPtr vm_savedisk(new VirtualMachineSaveDisk());
245
    xmlrpc_c::methodPtr vm_addnic(new VirtualMachineAddNic());
246
    xmlrpc_c::methodPtr vm_rmnic(new VirtualMachineRemoveNic());
245 247

  
246 248
    // VirtualNetwork Methods
247 249
    xmlrpc_c::methodPtr vn_addleases(new VirtualNetworkAddLeases());
......
345 347
    RequestManagerRegistry.addMethod("one.vm.info", vm_info);
346 348
    RequestManagerRegistry.addMethod("one.vm.chown", vm_chown);
347 349
    RequestManagerRegistry.addMethod("one.vm.chmod", vm_chmod);
350
    RequestManagerRegistry.addMethod("one.vm.addnic", vm_addnic);
351
    RequestManagerRegistry.addMethod("one.vm.rmnic", vm_rmnic);
348 352

  
349 353
    RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info);
350 354

  
opennebula-3.3.80-nichotplug/src/rm/RequestManagerVirtualMachine.cc 2012-04-14 20:57:49.000000000 -0400
553 553

  
554 554
/* -------------------------------------------------------------------------- */
555 555
/* -------------------------------------------------------------------------- */
556

  
557
void VirtualMachineAddNic::request_execute(xmlrpc_c::paramList const& paramList,
558
                                       RequestAttributes& att)
559
{
560
    Nebula& nd = Nebula::instance();
561

  
562
    int id = xmlrpc_c::value_int(paramList.getInt(1));
563
    string str_tmpl = xmlrpc_c::value_string(paramList.getString(2));
564

  
565
    VirtualMachinePool * vmpool = nd.get_vmpool();
566
    VirtualNetworkPool * vnpool = nd.get_vnpool();
567
    VirtualMachineManager * vmm = nd.get_vmm();
568

  
569
    VirtualMachine * vm;
570

  
571
    VirtualNetworkTemplate tmpl;
572
    string error_str;
573
    int rc;
574

  
575
    // -------------------------------------------------------------------------
576
    // Authorize the operation
577
    // -------------------------------------------------------------------------
578

  
579
    if ( vm_authorization(id, 0, att, 0, 0) == false )
580
    {
581
        return;
582
    }
583

  
584
    if ( (vm = get_vm(id, att)) == 0 )
585
    {
586
        return;
587
    }
588

  
589
    if (vm->get_state() != VirtualMachine::ACTIVE) {
590
                 failure_response(ACTION, request_error("Wrong state to perform action",""), att);
591
        vm->unlock();
592
        return;
593
    }
594

  
595
    // -------------------------------------------------------------------------
596
    // Parse passed template into a NIC description
597
    // -------------------------------------------------------------------------
598

  
599
    rc = tmpl.parse_str_or_xml(str_tmpl, error_str);
600

  
601
    if ( rc != 0 )
602
    {
603
        failure_response(INTERNAL, request_error(error_str, ""), att);
604
        vm->unlock();
605
        return;
606
    }
607

  
608
    vector<Attribute*> vector_nic;
609
    tmpl.get(string("NIC"), vector_nic);
610
    VectorAttribute * single_attr_nic = 0;
611

  
612
    if ( vector_nic.size() > 0 )
613
    {
614
        single_attr_nic = dynamic_cast<VectorAttribute *>(vector_nic[0]);
615
    }
616

  
617
    if( single_attr_nic == 0 )
618
    {
619
        failure_response(INTERNAL, request_error("Empty NIC description.", ""), att);
620
        vm->unlock();
621
        return;
622
    }
623

  
624
    // -------------------------------------------------------------------------
625
    // Obtain auth for the requested Virtual network
626
    // -------------------------------------------------------------------------
627

  
628
    AuthRequest ar(att.uid, att.gid);
629
    vnpool->authorize_nic(single_attr_nic,att.uid,&ar);
630

  
631
    if (UserPool::authorize(ar) == -1)
632
    {
633
        failure_response(AUTHORIZATION, authorization_error(ar.message, att), att);
634
        vm->unlock();
635
        return;
636
    }
637

  
638
    // -------------------------------------------------------------------------
639
    // Assign new NIC to VM
640
    // -------------------------------------------------------------------------
641

  
642
    rc = vnpool->nic_attribute(single_attr_nic, att.uid, id, error_str);
643

  
644
    if (rc != 0) {
645
        if (error_str.empty()) {
646
            error_str = "Invalid network or no leases available.";
647
        }
648
        failure_response(INTERNAL,request_error(error_str,""), att);
649
        vm->unlock();
650
        return;
651
    }
652
    
653
    // -------------------------------------------------------------------------
654
    // Append new NIC to VM template
655
    // -------------------------------------------------------------------------
656

  
657
    string vm_xml;
658
    vm->to_xml(vm_xml);
659
    vm_xml = vm_xml.substr(vm_xml.find("<TEMPLATE>"));
660
    vm_xml = vm_xml.substr(0, vm_xml.rfind("</TEMPLATE>"));
661
    string * nic_xml = single_attr_nic->to_xml();
662
    vm_xml.append(*nic_xml).append("</TEMPLATE>");
663
    delete nic_xml;
664

  
665
    // -------------------------------------------------------------------------
666
    // Update the VM template
667
    // -------------------------------------------------------------------------
668

  
669
    rc = vm->replace_template(vm_xml, error_str);
670
    vmpool->update(vm);
671

  
672
    if (rc != 0) {
673
        failure_response(INTERNAL,request_error(error_str,""), att);
674
        vm->unlock();
675
        return;
676
    }
677
    
678
    // -------------------------------------------------------------------------
679
    // Trigger the ADDNIC action
680
    // -------------------------------------------------------------------------
681

  
682
    vmm->trigger(VirtualMachineManager::ADDNIC, id);
683

  
684
    vm->unlock();
685
    success_response(true, att);
686
}
687

  
688
/* ------------------------------------------------------------------------- */
689
/* ------------------------------------------------------------------------- */
690

  
691
void VirtualMachineRemoveNic::request_execute(xmlrpc_c::paramList const& paramList,
692
                                       RequestAttributes& att)
693
{
694
    Nebula& nd = Nebula::instance();
695

  
696
    int id = xmlrpc_c::value_int(paramList.getInt(1));
697
    string str_tmpl = xmlrpc_c::value_string(paramList.getString(2));
698

  
699
    VirtualMachinePool * vmpool = nd.get_vmpool();
700
    VirtualNetworkPool * vnpool = nd.get_vnpool();
701
    VirtualMachineManager * vmm = nd.get_vmm();
702

  
703
    VirtualMachine * vm;
704

  
705
    VirtualNetworkTemplate tmpl;
706
    string error_str;
707
    int rc;
708
    string ip;
709
    string vnid;
710

  
711
    // -------------------------------------------------------------------------
712
    // Authorize the operation
713
    // -------------------------------------------------------------------------
714

  
715
    if ( vm_authorization(id, 0, att, 0, 0) == false )
716
    {
717
        return;
718
    }
719

  
720
    if ( (vm = get_vm(id, att)) == 0 )
721
    {
722
        return;
723
    }
724

  
725
    if (vm->get_state() != VirtualMachine::ACTIVE) {
726
        failure_response(ACTION, request_error("Wrong state to perform action",""), att);
727
        vm->unlock();
728
        return;
729
    }
730

  
731
    // -------------------------------------------------------------------------
732
    // Parse passed template into a NIC description
733
    // -------------------------------------------------------------------------
734

  
735
    rc = tmpl.parse_str_or_xml(str_tmpl, error_str);
736

  
737
    if ( rc != 0 )
738
    {
739
        failure_response(INTERNAL, request_error(error_str, ""), att);
740
        vm->unlock();
741
        return;
742
    }
743

  
744
    vector<Attribute*> vector_nic;
745
    tmpl.get(string("NIC"), vector_nic);
746
    VectorAttribute * single_attr_nic = 0;
747

  
748
    if ( vector_nic.size() > 0 )
749
    {
750
        single_attr_nic = dynamic_cast<VectorAttribute *>(vector_nic[0]);
751
    }
752

  
753
    if( single_attr_nic == 0 )
754
    {
755
        failure_response(INTERNAL, request_error("Empty NIC description.", ""), att);
756
        vm->unlock();
757
        return;
758
    }
759

  
760
    ip  = single_attr_nic->vector_value("IP");
761
    vnid = single_attr_nic->vector_value("NETWORK_ID");
762

  
763
    if( ip.empty() || vnid.empty() )
764
    {
765
        failure_response(INTERNAL, request_error("Missing IP and/or NETWORK_ID from NIC description.", ""), att);
766
        vm->unlock();
767
        return;
768
    }
769

  
770
    // -------------------------------------------------------------------------
771
    // Search VM template for requested NIC to be removed
772
    // -------------------------------------------------------------------------
773

  
774
    vector<Attribute const  * > nics;
775
    int num_nics  = vm->get_template_attribute("NIC",nics);
776

  
777
    const VectorAttribute * nic;
778
    bool found = false;
779

  
780
    for(int i=0; i<num_nics; i++)
781
    {
782
        nic = dynamic_cast<VectorAttribute const * >(nics[i]);
783

  
784
        if (nic->vector_value("IP") == ip && nic->vector_value("NETWORK_ID") == vnid) {
785
            found = true;
786
            break;
787
        }
788
    }
789

  
790
    if ( found == false ) {
791
        failure_response(INTERNAL, request_error("No leases matched the requested network.",""), att);
792
        vm->unlock();
793
        return;
794
    }
795

  
796
    // -------------------------------------------------------------------------
797
    // Release IP address back into the pool
798
    // -------------------------------------------------------------------------
799

  
800
    VirtualNetwork * vn = vnpool->get(atoi(vnid.c_str()),true);
801
    vn->release_lease(ip);
802
    vnpool->update(vn);
803
    vn->unlock();
804

  
805
    // -------------------------------------------------------------------------
806
    // Remove NIC from VM template
807
    // -------------------------------------------------------------------------
808

  
809
    string vm_xml;
810
    vm->to_xml(vm_xml);
811
    vm_xml = vm_xml.substr(vm_xml.find("<TEMPLATE>"));
812
    vm_xml = vm_xml.substr(0, vm_xml.rfind("</TEMPLATE>") + 11);
813
    string * nic_xml = nic->to_xml();
814
    vm_xml.replace(vm_xml.find(*nic_xml), nic_xml->length(), "");
815
    delete nic_xml;
816

  
817
    // -------------------------------------------------------------------------
818
    // Update the VM template
819
    // -------------------------------------------------------------------------
820

  
821
    rc = vm->replace_template(vm_xml, error_str);
822
    vmpool->update(vm);
823

  
824
    if (rc != 0) {
825
        failure_response(INTERNAL,request_error(error_str,""), att);
826
        vm->unlock();
827
        return;
828
    }
829

  
830
    // -------------------------------------------------------------------------
831
    // Trigger the RMNIC action
832
    // -------------------------------------------------------------------------
833

  
834
    vmm->trigger(VirtualMachineManager::RMNIC,id);
835

  
836
    vm->unlock();
837
    success_response(true, att);
838
}
839

  
840
/* -------------------------------------------------------------------------- */
841
/* -------------------------------------------------------------------------- */
842
/* -------------------------------------------------------------------------- */
opennebula-3.3.80-nichotplug/src/vmm/VirtualMachineManager.cc 2012-04-14 11:17:38.000000000 -0400
130 130
        aname = "REBOOT";
131 131
        break;
132 132

  
133
    case ADDNIC:
134
        aname = "ADDNIC";
135
        break;
136

  
137
    case RMNIC:
138
        aname = "RMNIC";
139
        break;
140

  
133 141
    case SHUTDOWN:
134 142
        aname = "SHUTDOWN";
135 143
        break;
......
226 234
    {
227 235
        poll_action(vid);
228 236
    }
237
    else if (action == "ADDNIC")
238
    {
239
        addnic_action(vid);
240
    }
241
    else if (action == "RMNIC")
242
    {
243
        rmnic_action(vid);
244
    }
229 245
    else if (action == "DRIVER_CANCEL")
230 246
    {
231 247
        driver_cancel_action(vid);
......
1020 1036

  
1021 1037
error_common:
1022 1038
    vm->log("VMM", Log::ERROR, os);
1039
    vm->unlock();
1040
    return;
1041
}
1042

  
1043
/* -------------------------------------------------------------------------- */
1044
/* -------------------------------------------------------------------------- */
1045

  
1046
void VirtualMachineManager::addnic_action(
1047
    int vid)
1048
{
1049
    VirtualMachine *                    vm;
1050
    const VirtualMachineManagerDriver * vmd;
1051

  
1052
    string        vm_tmpl;
1053
    string *      drv_msg; 
1054
    ostringstream os;
1055

  
1056
    // Get the VM from the pool
1057
    vm = vmpool->get(vid,true);
1058

  
1059
    if (vm == 0)
1060
    {
1061
        return;
1062
    }
1063

  
1064
    if (!vm->hasHistory())
1065
    {
1066
        goto error_history;
1067
    }
1068

  
1069
    // Get the driver for this VM
1070
    vmd = get(vm->get_vmm_mad());
1071

  
1072
    if ( vmd == 0 )
1073
    {
1074
        goto error_driver;
1075
    }
1076

  
1077
    // Invoke driver method
1078
    drv_msg = format_message(
1079
        vm->get_hostname(),
1080
        vm->get_vnm_mad(),
1081
        "",
1082
        "",
1083
        vm->get_deploy_id(),
1084
        "",
1085
        "",
1086
        "",
1087
        vm->to_xml(vm_tmpl));
1088

  
1089
    vmd->addnic(vid, *drv_msg);
1090

  
1091
    delete drv_msg;
1092

  
1093
    vm->unlock();
1094

  
1095
    return;
1096

  
1097
error_history:
1098
    os.str("");
1099
    os << "addnic_action, VM has no history";
1100
    goto error_common;
1101

  
1102
error_driver:
1103
    os.str("");
1104
    os << "addnic_action, error getting driver " << vm->get_vmm_mad();
1105

  
1106
error_common:
1107
    vm->log("VMM", Log::ERROR, os);
1108
    vm->unlock();
1109
    return;
1110
}
1111

  
1112
/* -------------------------------------------------------------------------- */
1113
/* -------------------------------------------------------------------------- */
1114

  
1115
void VirtualMachineManager::rmnic_action(
1116
    int vid)
1117
{
1118
    VirtualMachine *                    vm;
1119
    const VirtualMachineManagerDriver * vmd;
1120

  
1121
    string        vm_tmpl;
1122
    string *      drv_msg; 
1123
    ostringstream os;
1124

  
1125
    // Get the VM from the pool
1126
    vm = vmpool->get(vid,true);
1127

  
1128
    if (vm == 0)
1129
    {
1130
        return;
1131
    }
1132

  
1133
    if (!vm->hasHistory())
1134
    {
1135
        goto error_history;
1136
    }
1137

  
1138
    // Get the driver for this VM
1139
    vmd = get(vm->get_vmm_mad());
1140

  
1141
    if ( vmd == 0 )
1142
    {
1143
        goto error_driver;
1144
    }
1145

  
1146
    // Invoke driver method
1147
    drv_msg = format_message(
1148
        vm->get_hostname(),
1149
        vm->get_vnm_mad(),
1150
        "",
1151
        "",
1152
        vm->get_deploy_id(),
1153
        "",
1154
        "",
1155
        "",
1156
        vm->to_xml(vm_tmpl));
1157

  
1158
    vmd->rmnic(vid, *drv_msg);
1159

  
1160
    delete drv_msg;
1161

  
1162
    vm->unlock();
1163

  
1164
    return;
1165

  
1166
error_history:
1167
    os.str("");
1168
    os << "rmnic_action, VM has no history";
1169
    goto error_common;
1170

  
1171
error_driver:
1172
    os.str("");
1173
    os << "rmnic_action, error getting driver " << vm->get_vmm_mad();
1174

  
1175
error_common:
1176
    vm->log("VMM", Log::ERROR, os);
1023 1177
    vm->unlock();
1024 1178
    return;
1025 1179
}
opennebula-3.3.80-nichotplug/src/vmm/VirtualMachineManagerDriver.cc 2012-04-14 11:30:57.000000000 -0400
225 225
    write(os);
226 226
};
227 227

  
228
/* -------------------------------------------------------------------------- */
229
/* -------------------------------------------------------------------------- */
230

  
231
void VirtualMachineManagerDriver::addnic (
232
    const int     oid,
233
    const string& drv_msg) const
234
{
235
    ostringstream os;
236

  
237
    os << "ADDNIC " << oid << " " << drv_msg << endl;
238

  
239
    write(os);
240
};
241

  
242
/* -------------------------------------------------------------------------- */
243
/* -------------------------------------------------------------------------- */
244

  
245
void VirtualMachineManagerDriver::rmnic (
246
    const int     oid,
247
    const string& drv_msg) const
248
{
249
    ostringstream os;
250

  
251
    os << "RMNIC " << oid << " " << drv_msg << endl;
252

  
253
    write(os);
254
};
255

  
228 256
/* ************************************************************************** */
229 257
/* MAD Interface                                                              */
230 258
/* ************************************************************************** */
opennebula-3.3.80-nichotplug/src/vmm_mad/exec/one_vmm_exec.rb 2012-04-11 15:09:51.000000000 -0400
470 470

  
471 471
        do_action("#{deploy_id} #{host}", id, host, ACTION[:reboot])
472 472
    end
473

  
474
    #
475
    # ADDNIC action, add NIC to a running VM
476
    #
477
    def addnic(id, drv_message)
478
        action=VmmAction.new(self, id, :addnic, drv_message)
479

  
480
        steps=[
481
            # Execute networking addnic operations
482
            {
483
                :driver      => :vnm,
484
                :action      => :addnic,
485
            },
486
        ]
487

  
488
        action.run(steps)
489
    end
490

  
491
    #
492
    # RMNIC action, remove NIC from a running VM
493
    #
494
    def rmnic(id, drv_message)
495
        action=VmmAction.new(self, id, :rmnic, drv_message)
496

  
497
        steps=[
498
            # Execute networking rmnic operations
499
            {
500
                :driver      => :vnm,
501
                :action      => :rmnic,
502
            },
503
        ]
504

  
505
        action.run(steps)
506
    end
473 507
end
474 508

  
475 509
################################################################################