Advertisement
Guest User

Untitled

a guest
Aug 1st, 2016
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 63.05 KB | None | 0 0
  1. /* -------------------------------------------------------------------------- */
  2. /* Copyright 2002-2015, OpenNebula Project (OpenNebula.org), C12G Labs        */
  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 "RequestManagerVirtualMachine.h"
  18. #include "PoolObjectAuth.h"
  19. #include "Nebula.h"
  20. #include "Quotas.h"
  21.  
  22. /* -------------------------------------------------------------------------- */
  23. /* -------------------------------------------------------------------------- */
  24.  
  25. bool RequestManagerVirtualMachine::vm_authorization(
  26.         int                     oid,
  27.         ImageTemplate *         tmpl,
  28.         VirtualMachineTemplate* vtmpl,
  29.         RequestAttributes&      att,
  30.         PoolObjectAuth *        host_perm,
  31.         PoolObjectAuth *        ds_perm,
  32.         AuthRequest::Operation  op)
  33. {
  34.     PoolObjectSQL * object;
  35.     PoolObjectAuth vm_perms;
  36.  
  37.     object = pool->get(oid,true);
  38.  
  39.     if ( object == 0 )
  40.     {
  41.         failure_response(NO_EXISTS,
  42.                 get_error(object_name(auth_object),oid),
  43.                 att);
  44.  
  45.         return false;
  46.     }
  47.  
  48.     if ( att.uid == 0 )
  49.     {
  50.         object->unlock();
  51.         return true;
  52.     }
  53.  
  54.     object->get_permissions(vm_perms);
  55.  
  56.     object->unlock();
  57.  
  58.     AuthRequest ar(att.uid, att.group_ids);
  59.  
  60.     ar.add_auth(op, vm_perms);
  61.  
  62.     if (host_perm != 0)
  63.     {
  64.         ar.add_auth(AuthRequest::MANAGE, *host_perm);
  65.     }
  66.  
  67.     if (tmpl != 0)
  68.     {
  69.         string t_xml;
  70.  
  71.         ar.add_create_auth(att.uid, att.gid, PoolObjectSQL::IMAGE, tmpl->to_xml(t_xml));
  72.     }
  73.  
  74.     if ( vtmpl != 0 )
  75.     {
  76.         VirtualMachine::set_auth_request(att.uid, ar, vtmpl);
  77.     }
  78.  
  79.     if ( ds_perm != 0 )
  80.     {
  81.         ar.add_auth(AuthRequest::USE, *ds_perm);
  82.     }
  83.  
  84.     if (UserPool::authorize(ar) == -1)
  85.     {
  86.         failure_response(AUTHORIZATION,
  87.                 authorization_error(ar.message, att),
  88.                 att);
  89.  
  90.         return false;
  91.     }
  92.  
  93.     return true;
  94. }
  95.  
  96. /* -------------------------------------------------------------------------- */
  97. /* -------------------------------------------------------------------------- */
  98.  
  99. bool RequestManagerVirtualMachine::quota_resize_authorization(
  100.         int                 oid,
  101.         Template *          deltas,
  102.         RequestAttributes&  att)
  103. {
  104.     PoolObjectAuth      vm_perms;
  105.     VirtualMachine *    vm = Nebula::instance().get_vmpool()->get(oid, true);
  106.  
  107.     if (vm == 0)
  108.     {
  109.         failure_response(NO_EXISTS,
  110.                 get_error(object_name(PoolObjectSQL::VM),oid),
  111.                 att);
  112.  
  113.         return false;
  114.     }
  115.  
  116.     vm->get_permissions(vm_perms);
  117.  
  118.     vm->unlock();
  119.  
  120.     return quota_resize_authorization(deltas, att, vm_perms);
  121. }
  122.  
  123. /* -------------------------------------------------------------------------- */
  124. /* -------------------------------------------------------------------------- */
  125.  
  126. bool RequestManagerVirtualMachine::quota_resize_authorization(
  127.         Template *          deltas,
  128.         RequestAttributes&  att,
  129.         PoolObjectAuth&     vm_perms)
  130. {
  131.     int rc;
  132.  
  133.     string   error_str;
  134.  
  135.     Nebula&    nd    = Nebula::instance();
  136.     UserPool*  upool = nd.get_upool();
  137.     GroupPool* gpool = nd.get_gpool();
  138.  
  139.     DefaultQuotas user_dquotas  = nd.get_default_user_quota();
  140.     DefaultQuotas group_dquotas = nd.get_default_group_quota();
  141.  
  142.     if (vm_perms.uid != UserPool::ONEADMIN_ID)
  143.     {
  144.         User * user  = upool->get(vm_perms.uid, true);
  145.  
  146.         if ( user != 0 )
  147.         {
  148.             rc = user->quota.quota_update(Quotas::VM, deltas, user_dquotas, error_str);
  149.  
  150.             if (rc == false)
  151.             {
  152.                 ostringstream oss;
  153.  
  154.                 oss << object_name(PoolObjectSQL::USER)
  155.                     << " [" << vm_perms.uid << "] "
  156.                     << error_str;
  157.  
  158.                 failure_response(AUTHORIZATION,
  159.                         request_error(oss.str(), ""),
  160.                         att);
  161.  
  162.                 user->unlock();
  163.  
  164.                 return false;
  165.             }
  166.  
  167.             upool->update_quotas(user);
  168.  
  169.             user->unlock();
  170.         }
  171.     }
  172.  
  173.     if (vm_perms.gid != GroupPool::ONEADMIN_ID)
  174.     {
  175.         Group * group  = gpool->get(vm_perms.gid, true);
  176.  
  177.         if ( group != 0 )
  178.         {
  179.             rc = group->quota.quota_update(Quotas::VM, deltas, group_dquotas, error_str);
  180.  
  181.             if (rc == false)
  182.             {
  183.                 ostringstream oss;
  184.                 RequestAttributes att_tmp(vm_perms.uid, -1, att);
  185.  
  186.                 oss << object_name(PoolObjectSQL::GROUP)
  187.                     << " [" << vm_perms.gid << "] "
  188.                     << error_str;
  189.  
  190.                 failure_response(AUTHORIZATION,
  191.                                  request_error(oss.str(), ""),
  192.                                  att);
  193.  
  194.                 group->unlock();
  195.  
  196.                 quota_rollback(deltas, Quotas::VM, att_tmp);
  197.  
  198.                 return false;
  199.             }
  200.  
  201.             gpool->update_quotas(group);
  202.  
  203.             group->unlock();
  204.         }
  205.     }
  206.  
  207.     return true;
  208. }
  209.  
  210. /* -------------------------------------------------------------------------- */
  211. /* -------------------------------------------------------------------------- */
  212.  
  213. int RequestManagerVirtualMachine::get_default_ds_information(
  214.     int cluster_id,
  215.     int& ds_id,
  216.     string& tm_mad,
  217.     RequestAttributes& att)
  218. {
  219.     Nebula& nd = Nebula::instance();
  220.  
  221.     ClusterPool*    clpool = nd.get_clpool();
  222.     Cluster*        cluster;
  223.  
  224.     ds_id = -1;
  225.  
  226.     if (cluster_id == ClusterPool::NONE_CLUSTER_ID)
  227.     {
  228.         ds_id = DatastorePool::SYSTEM_DS_ID;
  229.     }
  230.     else
  231.     {
  232.         cluster = clpool->get(cluster_id, true);
  233.  
  234.         if (cluster == 0)
  235.         {
  236.             failure_response(NO_EXISTS,
  237.                 get_error(object_name(PoolObjectSQL::CLUSTER), cluster_id),
  238.                 att);
  239.  
  240.             return -1;
  241.         }
  242.  
  243.         set<int> ds_ids = cluster->get_datastores();
  244.  
  245.         cluster->unlock();
  246.  
  247.         ds_id = Cluster::get_default_sysetm_ds(ds_ids);
  248.  
  249.         if (ds_id == -1)
  250.         {
  251.             ostringstream oss;
  252.  
  253.             oss << object_name(PoolObjectSQL::CLUSTER)
  254.                 << " [" << cluster_id << "] does not have any "
  255.                 << object_name(PoolObjectSQL::DATASTORE) << " of type "
  256.                 << Datastore::type_to_str(Datastore::SYSTEM_DS) << ".";
  257.  
  258.             failure_response(ACTION, request_error(oss.str(),""), att);
  259.  
  260.             return -1;
  261.         }
  262.     }
  263.  
  264.     return get_ds_information(ds_id, cluster_id, tm_mad, att);
  265. }
  266.  
  267. /* -------------------------------------------------------------------------- */
  268. /* -------------------------------------------------------------------------- */
  269.  
  270. int RequestManagerVirtualMachine::get_ds_information(int ds_id,
  271.     int& ds_cluster_id,
  272.     string& tm_mad,
  273.     RequestAttributes& att)
  274. {
  275.     Nebula& nd = Nebula::instance();
  276.  
  277.     Datastore * ds = nd.get_dspool()->get(ds_id, true);
  278.  
  279.     ds_cluster_id = -1;
  280.  
  281.     if ( ds == 0 )
  282.     {
  283.         failure_response(NO_EXISTS,
  284.             get_error(object_name(PoolObjectSQL::DATASTORE), ds_id),
  285.             att);
  286.  
  287.         return -1;
  288.     }
  289.  
  290.     if ( ds->get_type() != Datastore::SYSTEM_DS )
  291.     {
  292.         ostringstream oss;
  293.  
  294.         oss << "Trying to use " << object_name(PoolObjectSQL::DATASTORE)
  295.             << " [" << ds_id << "] to deploy the VM, but it is not of type"
  296.             << " system datastore.";
  297.  
  298.         failure_response(INTERNAL, request_error(oss.str(),""), att);
  299.  
  300.         ds->unlock();
  301.  
  302.         return -1;
  303.     }
  304.  
  305.     ds_cluster_id = ds->get_cluster_id();
  306.  
  307.     tm_mad = ds->get_tm_mad();
  308.  
  309.     ds->unlock();
  310.  
  311.     return 0;
  312. }
  313.  
  314.  
  315. /* -------------------------------------------------------------------------- */
  316. /* -------------------------------------------------------------------------- */
  317.  
  318. int RequestManagerVirtualMachine::get_host_information(
  319.     int     hid,
  320.     string& name,
  321.     string& vmm,
  322.     string& vnm,
  323.     int&    cluster_id,
  324.     string& ds_location,
  325.     bool&   is_public_cloud,
  326.     PoolObjectAuth&    host_perms,
  327.     RequestAttributes& att)
  328.  
  329.  
  330. {
  331.     Nebula&    nd    = Nebula::instance();
  332.     HostPool * hpool = nd.get_hpool();
  333.  
  334.     Host *     host  = hpool->get(hid,true);
  335.  
  336.     if ( host == 0 )
  337.     {
  338.         failure_response(NO_EXISTS,
  339.                 get_error(object_name(PoolObjectSQL::HOST),hid),
  340.                 att);
  341.  
  342.         return -1;
  343.     }
  344.  
  345.     name = host->get_name();
  346.     vmm  = host->get_vmm_mad();
  347.     vnm  = host->get_vnm_mad();
  348.  
  349.     cluster_id = host->get_cluster_id();
  350.  
  351.     is_public_cloud = host->is_public_cloud();
  352.  
  353.     host->get_permissions(host_perms);
  354.  
  355.     host->unlock();
  356.  
  357.     if (nd.get_ds_location(cluster_id, ds_location) == -1)
  358.     {
  359.         failure_response(NO_EXISTS,
  360.             get_error(object_name(PoolObjectSQL::CLUSTER),cluster_id),
  361.             att);
  362.  
  363.         return -1;
  364.     }
  365.  
  366.     return 0;
  367. }
  368.  
  369. /* -------------------------------------------------------------------------- */
  370. /* -------------------------------------------------------------------------- */
  371.  
  372. bool RequestManagerVirtualMachine::check_host(int     hid,
  373.                                               int     cpu,
  374.                                               int     mem,
  375.                                               int     disk,
  376.                                               string& error)
  377. {
  378.     Nebula&    nd    = Nebula::instance();
  379.     HostPool * hpool = nd.get_hpool();
  380.  
  381.     Host * host;
  382.     bool   test;
  383.  
  384.     host = hpool->get(hid, true);
  385.  
  386.     if (host == 0)
  387.     {
  388.         error = "Host no longer exists";
  389.         return false;
  390.     }
  391.  
  392.     test = host->test_capacity(cpu, mem, disk);
  393.  
  394.     if (!test)
  395.     {
  396.         ostringstream oss;
  397.  
  398.         oss << object_name(PoolObjectSQL::HOST)
  399.             << " " << hid << " does not have enough capacity.";
  400.  
  401.         error = oss.str();
  402.     }
  403.  
  404.     host->unlock();
  405.  
  406.     return test;
  407. }
  408.  
  409. /* -------------------------------------------------------------------------- */
  410. /* -------------------------------------------------------------------------- */
  411.  
  412. VirtualMachine * RequestManagerVirtualMachine::get_vm(int id,
  413.                                                       RequestAttributes& att)
  414. {
  415.     VirtualMachine * vm;
  416.  
  417.     vm = static_cast<VirtualMachine *>(pool->get(id,true));
  418.  
  419.     if ( vm == 0 )
  420.     {
  421.         failure_response(NO_EXISTS,get_error(object_name(auth_object),id), att);
  422.         return 0;
  423.     }
  424.  
  425.     return vm;
  426. }
  427.  
  428. /* -------------------------------------------------------------------------- */
  429. /* -------------------------------------------------------------------------- */
  430.  
  431. int RequestManagerVirtualMachine::add_history(VirtualMachine * vm,
  432.                                        int              hid,
  433.                                        int              cid,
  434.                                        const string&    hostname,
  435.                                        const string&    vmm_mad,
  436.                                        const string&    vnm_mad,
  437.                                        const string&    tm_mad,
  438.                                        const string&    ds_location,
  439.                                        int              ds_id,
  440.                                        RequestAttributes& att)
  441. {
  442.     string  vmdir;
  443.     int     rc;
  444.  
  445.     VirtualMachinePool * vmpool = static_cast<VirtualMachinePool *>(pool);
  446.  
  447.     vm->add_history(hid, cid, hostname, vmm_mad, vnm_mad, tm_mad, ds_location, ds_id);
  448.  
  449.     rc = vmpool->update_history(vm);
  450.  
  451.     if ( rc != 0 )
  452.     {
  453.         failure_response(INTERNAL,
  454.                 request_error("Cannot update virtual machine history",""),
  455.                 att);
  456.  
  457.         return -1;
  458.     }
  459.  
  460.     vmpool->update(vm);
  461.  
  462.     return 0;
  463. }
  464.  
  465. /* -------------------------------------------------------------------------- */
  466. /* -------------------------------------------------------------------------- */
  467.  
  468. void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList,
  469.                                            RequestAttributes& att)
  470. {
  471.     string action_st = xmlrpc_c::value_string(paramList.getString(1));
  472.     int    id        = xmlrpc_c::value_int(paramList.getInt(2));
  473.  
  474.     int    rc;
  475.  
  476.     Nebula& nd = Nebula::instance();
  477.     DispatchManager * dm = nd.get_dm();
  478.  
  479.     ostringstream oss;
  480.  
  481.     AuthRequest::Operation op = auth_op;
  482.     History::VMAction action;
  483.  
  484.     VirtualMachine * vm;
  485.  
  486.     // Compatibility with 3.8
  487.     if (action_st == "cancel")
  488.     {
  489.         action_st = "shutdown-hard";
  490.     }
  491.     else if (action_st == "restart")
  492.     {
  493.         action_st = "boot";
  494.     }
  495.     else if (action_st == "finalize")
  496.     {
  497.         action_st = "delete";
  498.     }
  499.     else if (action_st == "resubmit")
  500.     {
  501.         action_st = "delete-recreate";
  502.     }
  503.     else if (action_st == "reset")
  504.     {
  505.         action_st = "reboot-hard";
  506.     }
  507.  
  508.     History::action_from_str(action_st, action);
  509.  
  510.     if (action == History::RESCHED_ACTION || action == History::UNRESCHED_ACTION)
  511.     {
  512.         op = AuthRequest::ADMIN;
  513.     }
  514.  
  515.     if ( vm_authorization(id, 0, 0, att, 0, 0, op) == false )
  516.     {
  517.         return;
  518.     }
  519.  
  520.     if ((vm = get_vm(id, att)) == 0)
  521.     {
  522.         return;
  523.     }
  524.  
  525.     if (vm->isImported() && (
  526.         action == History::DELETE_RECREATE_ACTION ||
  527.         action == History::UNDEPLOY_ACTION ||
  528.         action == History::UNDEPLOY_HARD_ACTION ||
  529.         action == History::STOP_ACTION))
  530.     {
  531.         oss << "Action \"" << action_st << "\" is not supported for imported VMs";
  532.  
  533.         failure_response(ACTION,
  534.                 request_error(oss.str(),""),
  535.                 att);
  536.  
  537.         vm->unlock();
  538.         return;
  539.     }
  540.  
  541.     vm->unlock();
  542.  
  543.     switch (action)
  544.     {
  545.         case History::SHUTDOWN_ACTION:
  546.             rc = dm->shutdown(id);
  547.             break;
  548.         case History::HOLD_ACTION:
  549.             rc = dm->hold(id);
  550.             break;
  551.         case History::RELEASE_ACTION:
  552.             rc = dm->release(id);
  553.             break;
  554.         case History::STOP_ACTION:
  555.             rc = dm->stop(id);
  556.             break;
  557.         case History::SHUTDOWN_HARD_ACTION:
  558.             rc = dm->cancel(id);
  559.             break;
  560.         case History::SUSPEND_ACTION:
  561.             rc = dm->suspend(id);
  562.             break;
  563.         case History::RESUME_ACTION:
  564.             rc = dm->resume(id);
  565.             break;
  566.         case History::BOOT_ACTION:
  567.             rc = dm->restart(id);
  568.             break;
  569.         case History::DELETE_ACTION:
  570.             rc = dm->finalize(id);
  571.             break;
  572.         case History::DELETE_RECREATE_ACTION:
  573.             rc = dm->resubmit(id);
  574.             break;
  575.         case History::REBOOT_ACTION:
  576.             rc = dm->reboot(id);
  577.             break;
  578.         case History::RESCHED_ACTION:
  579.             rc = dm->resched(id, true);
  580.             break;
  581.         case History::UNRESCHED_ACTION:
  582.             rc = dm->resched(id, false);
  583.             break;
  584.         case History::REBOOT_HARD_ACTION:
  585.             rc = dm->reset(id);
  586.             break;
  587.         case History::POWEROFF_ACTION:
  588.             rc = dm->poweroff(id, false);
  589.             break;
  590.         case History::POWEROFF_HARD_ACTION:
  591.             rc = dm->poweroff(id, true);
  592.             break;
  593.         case History::UNDEPLOY_ACTION:
  594.             rc = dm->undeploy(id, false);
  595.             break;
  596.         case History::UNDEPLOY_HARD_ACTION:
  597.             rc = dm->undeploy(id, true);
  598.             break;
  599.         default:
  600.             rc = -3;
  601.             break;
  602.     }
  603.  
  604.     switch (rc)
  605.     {
  606.         case 0:
  607.             success_response(id, att);
  608.             break;
  609.         case -1:
  610.             failure_response(NO_EXISTS,
  611.                     get_error(object_name(auth_object),id),
  612.                     att);
  613.             break;
  614.         case -2:
  615.             oss << "Wrong state to perform action \"" << action_st << "\"";
  616.  
  617.             failure_response(ACTION,
  618.                     request_error(oss.str(),""),
  619.                     att);
  620.              break;
  621.         case -3:
  622.             oss << "Virtual machine action \"" << action_st
  623.                 << "\" is not supported";
  624.  
  625.             failure_response(ACTION,
  626.                     request_error(oss.str(),""),
  627.                     att);
  628.             break;
  629.         default:
  630.             failure_response(INTERNAL,
  631.                     request_error("Internal error","Action result not defined"),
  632.                     att);
  633.     }
  634.  
  635.     return;
  636. }
  637.  
  638. /* -------------------------------------------------------------------------- */
  639. /* -------------------------------------------------------------------------- */
  640.  
  641. void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
  642.                                            RequestAttributes& att)
  643. {
  644.     Nebula&             nd = Nebula::instance();
  645.     DispatchManager *   dm = nd.get_dm();
  646.     DatastorePool * dspool = nd.get_dspool();
  647.  
  648.     VirtualMachine * vm;
  649.  
  650.     string hostname;
  651.     string vmm_mad;
  652.     string vnm_mad;
  653.     int    cluster_id;
  654.     string ds_location;
  655.     bool   is_public_cloud;
  656.  
  657.     PoolObjectAuth host_perms, ds_perms;
  658.     PoolObjectAuth * auth_ds_perms;
  659.  
  660.     string tm_mad;
  661.  
  662.     bool auth = false;
  663.  
  664.     // ------------------------------------------------------------------------
  665.     // Get request parameters and information about the target host
  666.     // ------------------------------------------------------------------------
  667.  
  668.     int  id      = xmlrpc_c::value_int(paramList.getInt(1));
  669.     int  hid     = xmlrpc_c::value_int(paramList.getInt(2));
  670.     bool enforce = false;
  671.     int  ds_id   = -1;
  672.  
  673.     if ( paramList.size() > 3 )
  674.     {
  675.         enforce = xmlrpc_c::value_boolean(paramList.getBoolean(3));
  676.     }
  677.  
  678.     if ( paramList.size() > 4 )
  679.     {
  680.         ds_id = xmlrpc_c::value_int(paramList.getInt(4));
  681.     }
  682.  
  683.     if (get_host_information(hid,
  684.                              hostname,
  685.                              vmm_mad,
  686.                              vnm_mad,
  687.                              cluster_id,
  688.                              ds_location,
  689.                              is_public_cloud,
  690.                              host_perms,
  691.                              att) != 0)
  692.     {
  693.         return;
  694.     }
  695.  
  696.     // ------------------------------------------------------------------------
  697.     // Get information about the system DS to use (tm_mad & permissions)
  698.     // ------------------------------------------------------------------------
  699.  
  700.     if ((vm = get_vm(id, att)) == 0)
  701.     {
  702.         return;
  703.     }
  704.  
  705.     if (vm->hasHistory() &&
  706.         (vm->get_action() == History::STOP_ACTION ||
  707.          vm->get_action() == History::UNDEPLOY_ACTION ||
  708.          vm->get_action() == History::UNDEPLOY_HARD_ACTION))
  709.     {
  710.         ds_id = vm->get_ds_id();
  711.     }
  712.  
  713.     vm->unlock();
  714.  
  715.     if (is_public_cloud) // Set ds_id to -1 and tm_mad empty(). This is used by
  716.     {                    // by VirtualMachine::get_host_is_cloud()
  717.         ds_id  = -1;
  718.         tm_mad = "";
  719.     }
  720.     else
  721.     {
  722.         if ( ds_id == -1 ) //Use default system DS for cluster
  723.         {
  724.             if (get_default_ds_information(cluster_id, ds_id, tm_mad, att) != 0)
  725.             {
  726.                 return;
  727.             }
  728.         }
  729.         else //Get information from user selected system DS
  730.         {
  731.             int ds_cluster_id;
  732.  
  733.             if (get_ds_information(ds_id, ds_cluster_id, tm_mad, att) != 0)
  734.             {
  735.                 return;
  736.             }
  737.  
  738.             if (ds_cluster_id != cluster_id)
  739.             {
  740.                 ostringstream oss;
  741.  
  742.                 oss << object_name(PoolObjectSQL::DATASTORE)
  743.                     << " [" << ds_id << "] and " << object_name(PoolObjectSQL::HOST)
  744.                     << " [" << hid <<"] are not in the same cluster.";
  745.  
  746.                 failure_response(ACTION, request_error(oss.str(),""), att);
  747.  
  748.                 return;
  749.             }
  750.         }
  751.     }
  752.  
  753.     if (ds_id == -1)
  754.     {
  755.        auth_ds_perms = 0;
  756.     }
  757.     else
  758.     {
  759.         Datastore * ds = dspool->get(ds_id, true);
  760.  
  761.         if (ds == 0 )
  762.         {
  763.             failure_response(NO_EXISTS,
  764.                 get_error(object_name(PoolObjectSQL::DATASTORE), ds_id),
  765.                 att);
  766.  
  767.             return;
  768.         }
  769.  
  770.         ds->get_permissions(ds_perms);
  771.  
  772.         ds->unlock();
  773.  
  774.         auth_ds_perms = &ds_perms;
  775.     }
  776.  
  777.     // ------------------------------------------------------------------------
  778.     // Authorize request
  779.     // ------------------------------------------------------------------------
  780.  
  781.     auth = vm_authorization(id, 0, 0, att, &host_perms, auth_ds_perms, auth_op);
  782.  
  783.     if (auth == false)
  784.     {
  785.         return;
  786.     }
  787.  
  788.     // ------------------------------------------------------------------------
  789.     // Check request consistency:
  790.     // - VM States are right
  791.     // - Host capacity if required
  792.     // ------------------------------------------------------------------------
  793.  
  794.     if ((vm = get_vm(id, att)) == 0)
  795.     {
  796.         return;
  797.     }
  798.  
  799.     if (vm->get_state() != VirtualMachine::PENDING &&
  800.         vm->get_state() != VirtualMachine::HOLD)
  801.     {
  802.         failure_response(ACTION,
  803.                 request_error("Wrong state to perform action",""),
  804.                 att);
  805.  
  806.         vm->unlock();
  807.         return;
  808.     }
  809.  
  810.     if (enforce)
  811.     {
  812.         int    cpu, mem, disk;
  813.         string error;
  814.  
  815.         vm->get_requirements(cpu, mem, disk);
  816.  
  817.         vm->unlock();
  818.  
  819.         if (check_host(hid, cpu, mem, disk, error) == false)
  820.         {
  821.             failure_response(ACTION, request_error(error,""), att);
  822.             return;
  823.         }
  824.  
  825.         if ((vm = get_vm(id, att)) == 0)
  826.         {
  827.             return;
  828.         }
  829.     }
  830.  
  831.     // ------------------------------------------------------------------------
  832.     // Add a new history record and deploy the VM
  833.     // ------------------------------------------------------------------------
  834.  
  835.     if (add_history(vm,
  836.                     hid,
  837.                     cluster_id,
  838.                     hostname,
  839.                     vmm_mad,
  840.                     vnm_mad,
  841.                     tm_mad,
  842.                     ds_location,
  843.                     ds_id,
  844.                     att) != 0)
  845.     {
  846.         vm->unlock();
  847.         return;
  848.     }
  849.  
  850.     if (vm->isImported())
  851.     {
  852.         dm->import(vm);
  853.     }
  854.     else
  855.     {
  856.         dm->deploy(vm);
  857.     }
  858.  
  859.     vm->unlock();
  860.  
  861.     success_response(id, att);
  862. }
  863.  
  864. /* -------------------------------------------------------------------------- */
  865. /* -------------------------------------------------------------------------- */
  866.  
  867. void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList,
  868.                                             RequestAttributes& att)
  869. {
  870.     Nebula&             nd = Nebula::instance();
  871.     DispatchManager *   dm = nd.get_dm();
  872.  
  873.     VirtualMachine * vm;
  874.  
  875.     string hostname;
  876.     string vmm_mad;
  877.     string vnm_mad;
  878.     int    cluster_id;
  879.     string ds_location;
  880.     bool   is_public_cloud;
  881.     PoolObjectAuth host_perms;
  882.  
  883.     int    c_hid;
  884.     int    c_cluster_id;
  885.     int    c_ds_id;
  886.     string c_tm_mad;
  887.     bool   c_is_public_cloud;
  888.  
  889.     bool auth = false;
  890.  
  891.     // ------------------------------------------------------------------------
  892.     // Get request parameters and information about the target host
  893.     // ------------------------------------------------------------------------
  894.  
  895.     int  id      = xmlrpc_c::value_int(paramList.getInt(1));
  896.     int  hid     = xmlrpc_c::value_int(paramList.getInt(2));
  897.     bool live    = xmlrpc_c::value_boolean(paramList.getBoolean(3));
  898.     bool enforce = false;
  899.  
  900.     if ( paramList.size() > 4 )
  901.     {
  902.         enforce = xmlrpc_c::value_boolean(paramList.getBoolean(4));
  903.     }
  904.  
  905.     if (get_host_information(hid,
  906.                              hostname,
  907.                              vmm_mad,
  908.                              vnm_mad,
  909.                              cluster_id,
  910.                              ds_location,
  911.                              is_public_cloud,
  912.                              host_perms,
  913.                              att) != 0)
  914.     {
  915.         return;
  916.     }
  917.  
  918.     // ------------------------------------------------------------------------
  919.     // Authorize request
  920.     // ------------------------------------------------------------------------
  921.  
  922.     auth = vm_authorization(id, 0, 0, att, &host_perms, 0, auth_op);
  923.  
  924.     if (auth == false)
  925.     {
  926.         return;
  927.     }
  928.  
  929.     // ------------------------------------------------------------------------
  930.     // Check request consistency:
  931.     // - VM States are right and there is at least a history record
  932.     // - New host is not the current one
  933.     // - Host capacity if required
  934.     // - New host and current one are in the same cluster
  935.     // - New or old host are not public cloud
  936.     // ------------------------------------------------------------------------
  937.  
  938.     if ((vm = get_vm(id, att)) == 0)
  939.     {
  940.         return;
  941.     }
  942.  
  943.     if((vm->get_state()     != VirtualMachine::ACTIVE)  ||
  944.        (vm->get_lcm_state() != VirtualMachine::RUNNING &&
  945.         vm->get_lcm_state() != VirtualMachine::UNKNOWN) ||
  946.        (vm->hasPreviousHistory() && vm->get_previous_reason() == History::NONE))
  947.     {
  948.         failure_response(ACTION,
  949.                 request_error("Wrong state to perform action",""),
  950.                 att);
  951.  
  952.         vm->unlock();
  953.         return;
  954.     }
  955.  
  956.     if (vm->isImported())
  957.     {
  958.         failure_response(ACTION,
  959.                 request_error("Migration is not supported for imported VMs",""),
  960.                 att);
  961.  
  962.         vm->unlock();
  963.         return;
  964.     }
  965.  
  966.     // Check we are not migrating to the same host
  967.  
  968.     c_hid = vm->get_hid();
  969.  
  970.     if (c_hid == hid)
  971.     {
  972.         ostringstream oss;
  973.  
  974.         oss << "VM is already running on "
  975.             << object_name(PoolObjectSQL::HOST) << " [" << c_hid << "]";
  976.  
  977.         failure_response(ACTION,
  978.                 request_error(oss.str(),""),
  979.                 att);
  980.  
  981.         vm->unlock();
  982.         return;
  983.     }
  984.  
  985.     // Get System DS information from current History record
  986.     c_ds_id  = vm->get_ds_id();
  987.     c_tm_mad = vm->get_tm_mad();
  988.  
  989.     if (enforce)
  990.     {
  991.         int    cpu, mem, disk;
  992.         string error;
  993.  
  994.         vm->get_requirements(cpu, mem, disk);
  995.  
  996.         vm->unlock();
  997.  
  998.         if (check_host(hid, cpu, mem, disk, error) == false)
  999.         {
  1000.             failure_response(ACTION, request_error(error,""), att);
  1001.             return;
  1002.         }
  1003.     }
  1004.     else
  1005.     {
  1006.         vm->unlock();
  1007.     }
  1008.  
  1009.     // Check we are in the same cluster
  1010.  
  1011.     Host * host = nd.get_hpool()->get(c_hid, true);
  1012.  
  1013.     if (host == 0)
  1014.     {
  1015.         failure_response(NO_EXISTS,
  1016.                 get_error(object_name(PoolObjectSQL::HOST), c_hid),
  1017.                 att);
  1018.     }
  1019.  
  1020.     c_cluster_id = host->get_cluster_id();
  1021.  
  1022.     c_is_public_cloud = host->is_public_cloud();
  1023.  
  1024.     host->unlock();
  1025.  
  1026.     if ( c_cluster_id != cluster_id )
  1027.     {
  1028.         ostringstream oss;
  1029.  
  1030.         oss << "Cannot migrate to a different cluster. VM running in a host"
  1031.             << " in " << object_name(PoolObjectSQL::CLUSTER) << " ["
  1032.             << c_cluster_id << "] , and new host is in "
  1033.             << object_name(PoolObjectSQL::CLUSTER) << " [" << cluster_id << "]";
  1034.  
  1035.         failure_response(ACTION,
  1036.                 request_error(oss.str(),""),
  1037.                 att);
  1038.  
  1039.         return;
  1040.     }
  1041.  
  1042.     if ( is_public_cloud || c_is_public_cloud )
  1043.     {
  1044.         failure_response(ACTION,
  1045.                 request_error("Cannot migrate to or from a Public Cloud Host",""),
  1046.                 att);
  1047.  
  1048.         return;
  1049.     }
  1050.  
  1051.     // ------------------------------------------------------------------------
  1052.     // Add a new history record and migrate the VM
  1053.     // ------------------------------------------------------------------------
  1054.  
  1055.     if ( (vm = get_vm(id, att)) == 0 )
  1056.     {
  1057.         return;
  1058.     }
  1059.  
  1060.     if (add_history(vm,
  1061.                     hid,
  1062.                     cluster_id,
  1063.                     hostname,
  1064.                     vmm_mad,
  1065.                     vnm_mad,
  1066.                     c_tm_mad,
  1067.                     ds_location,
  1068.                     c_ds_id,
  1069.                     att) != 0)
  1070.     {
  1071.         vm->unlock();
  1072.         return;
  1073.     }
  1074.  
  1075.     if (live == true && vm->get_lcm_state() == VirtualMachine::RUNNING )
  1076.     {
  1077.         dm->live_migrate(vm);
  1078.     }
  1079.     else
  1080.     {
  1081.         dm->migrate(vm);
  1082.     }
  1083.  
  1084.     vm->unlock();
  1085.  
  1086.     success_response(id, att);
  1087. }
  1088.  
  1089. /* -------------------------------------------------------------------------- */
  1090. /* -------------------------------------------------------------------------- */
  1091.  
  1092. void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramList,
  1093.                                              RequestAttributes& att)
  1094. {
  1095.     Nebula& nd  = Nebula::instance();
  1096.  
  1097.     ImagePool *     ipool  = nd.get_ipool();
  1098.     DatastorePool * dspool = nd.get_dspool();
  1099.     VMTemplatePool* tpool  = nd.get_tpool();
  1100.  
  1101.     int    id          = xmlrpc_c::value_int(paramList.getInt(1));
  1102.     int    disk_id     = xmlrpc_c::value_int(paramList.getInt(2));
  1103.     string img_name    = xmlrpc_c::value_string(paramList.getString(3));
  1104.     string img_type    = xmlrpc_c::value_string(paramList.getString(4));
  1105.     bool   is_hot      = false; //Optional XML-RPC argument
  1106.     bool   do_template = false; //Optional XML-RPC argument
  1107.  
  1108.     if ( paramList.size() > 5 )
  1109.     {
  1110.         is_hot = xmlrpc_c::value_boolean(paramList.getBoolean(5));
  1111.     }
  1112.  
  1113.     if ( paramList.size() > 6 )
  1114.     {
  1115.         do_template = xmlrpc_c::value_boolean(paramList.getBoolean(6));
  1116.     }
  1117.  
  1118.     VirtualMachinePool * vmpool = static_cast<VirtualMachinePool *>(pool);
  1119.     VirtualMachine * vm;
  1120.     Datastore      * ds;
  1121.     int              iid;
  1122.     int              tid;
  1123.  
  1124.     string error_str;
  1125.  
  1126.     string driver;
  1127.     string target;
  1128.     string dev_prefix;
  1129.  
  1130.     // -------------------------------------------------------------------------
  1131.     // Prepare and check the VM/DISK to be saved_as
  1132.     // -------------------------------------------------------------------------
  1133.     if ((vm = get_vm(id, att)) == 0)
  1134.     {
  1135.         return;
  1136.     }
  1137.  
  1138.     if ( vm->set_saveas_state(disk_id, is_hot) != 0 )
  1139.     {
  1140.         vm->unlock();
  1141.  
  1142.         failure_response(INTERNAL,
  1143.                          request_error("VM has to be RUNNING, POWEROFF or"
  1144.                          " SUSPENDED to snapshot disks.",""), att);
  1145.         return;
  1146.     }
  1147.  
  1148.     int iid_orig = vm->get_image_from_disk(disk_id, is_hot, error_str);
  1149.  
  1150.     if ( iid_orig == -1 )
  1151.     {
  1152.         vm->clear_saveas_state(disk_id, is_hot);
  1153.  
  1154.         vm->unlock();
  1155.  
  1156.         failure_response(INTERNAL,
  1157.                          request_error("Cannot use selected DISK", error_str),
  1158.                          att);
  1159.         return;
  1160.     }
  1161.  
  1162.     if (do_template && !vm->get_template_attribute("TEMPLATE_ID",tid))
  1163.     {
  1164.         vm->clear_saveas_state(disk_id, is_hot);
  1165.  
  1166.         vm->unlock();
  1167.  
  1168.         failure_response(ACTION,
  1169.                          request_error("VM has no template to be saved",""),
  1170.                          att);
  1171.         return;
  1172.     }
  1173.  
  1174.     vmpool->update(vm);
  1175.  
  1176.     vm->unlock();
  1177.  
  1178.     // -------------------------------------------------------------------------
  1179.     // Get the data of the Image to be saved
  1180.     // -------------------------------------------------------------------------
  1181.     Image * img = ipool->get(iid_orig, true);
  1182.  
  1183.     if ( img == 0 )
  1184.     {
  1185.         failure_response(NO_EXISTS,
  1186.                          get_error(object_name(PoolObjectSQL::IMAGE), iid_orig),
  1187.                          att);
  1188.  
  1189.         if ((vm = vmpool->get(id, true)) != 0)
  1190.         {
  1191.             vm->clear_saveas_state(disk_id, is_hot);
  1192.  
  1193.             vmpool->update(vm);
  1194.             vm->unlock();
  1195.         }
  1196.  
  1197.         return;
  1198.     }
  1199.  
  1200.     int       ds_id   = img->get_ds_id();
  1201.     string    ds_name = img->get_ds_name();
  1202.     long long size    = img->get_size();
  1203.  
  1204.     string iname_orig  = img->get_name();
  1205.     string iuname_orig = img->get_uname();
  1206.     Image::ImageType type = img->get_type();
  1207.  
  1208.     img->get_template_attribute("DRIVER", driver);
  1209.     img->get_template_attribute("TARGET", target);
  1210.     img->get_template_attribute("DEV_PREFIX", dev_prefix);
  1211.  
  1212.     img->unlock();
  1213.  
  1214.     switch (type)
  1215.     {
  1216.         case Image::OS:
  1217.         case Image::DATABLOCK:
  1218.         case Image::CDROM:
  1219.         break;
  1220.  
  1221.         case Image::KERNEL:
  1222.         case Image::RAMDISK:
  1223.         case Image::CONTEXT:
  1224.             failure_response(INTERNAL,
  1225.                     request_error("Cannot save_as image of type " +
  1226.                     Image::type_to_str(type), ""), att);
  1227.         return;
  1228.     }
  1229.  
  1230.     // -------------------------------------------------------------------------
  1231.     // Get the data of the DataStore for the new image
  1232.     // -------------------------------------------------------------------------
  1233.     if ((ds = dspool->get(ds_id, true)) == 0 )
  1234.     {
  1235.         failure_response(NO_EXISTS,
  1236.                 get_error(object_name(PoolObjectSQL::DATASTORE), ds_id),
  1237.                 att);
  1238.  
  1239.         if ((vm = vmpool->get(id, true)) != 0)
  1240.         {
  1241.             vm->clear_saveas_state(disk_id, is_hot);
  1242.  
  1243.             vmpool->update(vm);
  1244.             vm->unlock();
  1245.         }
  1246.  
  1247.         return;
  1248.     }
  1249.  
  1250.     string         ds_data;
  1251.     PoolObjectAuth ds_perms;
  1252.     long long      avail;
  1253.     bool           ds_check;
  1254.  
  1255.     ds->get_permissions(ds_perms);
  1256.     ds->to_xml(ds_data);
  1257.  
  1258.     ds_check = ds->get_avail_mb(avail);
  1259.  
  1260.     Image::DiskType ds_disk_type = ds->get_disk_type();
  1261.  
  1262.     ds->unlock();
  1263.  
  1264.     // -------------------------------------------------------------------------
  1265.     // Check Datastore Capacity
  1266.     // -------------------------------------------------------------------------
  1267.     if (ds_check && (size > avail))
  1268.     {
  1269.         failure_response(ACTION, "Not enough space in datastore", att);
  1270.  
  1271.         if ((vm = vmpool->get(id, true)) != 0)
  1272.         {
  1273.             vm->clear_saveas_state(disk_id, is_hot);
  1274.  
  1275.             vmpool->update(vm);
  1276.             vm->unlock();
  1277.         }
  1278.  
  1279.         return;
  1280.     }
  1281.  
  1282.     // -------------------------------------------------------------------------
  1283.     // Create a template for the new Image
  1284.     // -------------------------------------------------------------------------
  1285.     ImageTemplate * itemplate = new ImageTemplate;
  1286.     Template        img_usage;
  1287.  
  1288.     itemplate->add("NAME", img_name);
  1289.     itemplate->add("SIZE", size);
  1290.  
  1291.     itemplate->add("SAVED_IMAGE_ID",iid_orig);
  1292.     itemplate->add("SAVED_DISK_ID",disk_id);
  1293.     itemplate->add("SAVED_VM_ID", id);
  1294.  
  1295.     itemplate->set_saving();
  1296.  
  1297.     if ( is_hot )
  1298.     {
  1299.         itemplate->set_saving_hot();
  1300.     }
  1301.  
  1302.     if ( img_type.empty() )
  1303.     {
  1304.         itemplate->add("TYPE", Image::type_to_str(type));
  1305.     }
  1306.     else
  1307.     {
  1308.         itemplate->add("TYPE", img_type);
  1309.     }
  1310.  
  1311.     if ( driver.empty() == false )
  1312.     {
  1313.         itemplate->add("DRIVER", driver);
  1314.     }
  1315.  
  1316.     if ( target.empty() == false )
  1317.     {
  1318.         itemplate->add("TARGET", target);
  1319.     }
  1320.  
  1321.     if ( dev_prefix.empty() == false )
  1322.     {
  1323.         itemplate->add("DEV_PREFIX", dev_prefix);
  1324.     }
  1325.  
  1326.     img_usage.add("SIZE",      size);
  1327.     img_usage.add("DATASTORE", ds_id);
  1328.  
  1329.     // -------------------------------------------------------------------------
  1330.     // Authorize the operation & check quotas
  1331.     // -------------------------------------------------------------------------
  1332.     bool rc_auth = vm_authorization(id, itemplate, 0, att, 0,&ds_perms,auth_op);
  1333.  
  1334.     if ( rc_auth == true )
  1335.     {
  1336.         rc_auth = quota_authorization(&img_usage, Quotas::DATASTORE, att);
  1337.     }
  1338.  
  1339.     if ( rc_auth == false)
  1340.     {
  1341.         delete itemplate;
  1342.  
  1343.         if ((vm = vmpool->get(id, true)) != 0)
  1344.         {
  1345.             vm->clear_saveas_state(disk_id, is_hot);
  1346.  
  1347.             vmpool->update(vm);
  1348.             vm->unlock();
  1349.         }
  1350.  
  1351.         return;
  1352.     }
  1353.  
  1354.     // -------------------------------------------------------------------------
  1355.     // Create the image
  1356.     // -------------------------------------------------------------------------
  1357.     int rc = ipool->allocate(att.uid,
  1358.                              att.gid,
  1359.                              att.uname,
  1360.                              att.gname,
  1361.                              att.umask,
  1362.                              itemplate,
  1363.                              ds_id,
  1364.                              ds_name,
  1365.                              ds_disk_type,
  1366.                              ds_data,
  1367.                              Datastore::IMAGE_DS,
  1368.                              -1,
  1369.                              &iid,
  1370.                              error_str);
  1371.     if (rc < 0)
  1372.     {
  1373.         quota_rollback(&img_usage, Quotas::DATASTORE, att);
  1374.  
  1375.         if ((vm = vmpool->get(id, true)) != 0)
  1376.         {
  1377.             vm->clear_saveas_state(disk_id, is_hot);
  1378.  
  1379.             vmpool->update(vm);
  1380.             vm->unlock();
  1381.         }
  1382.  
  1383.         failure_response(INTERNAL,
  1384.                 allocate_error(PoolObjectSQL::IMAGE, error_str), att);
  1385.         return;
  1386.     }
  1387.  
  1388.     ds = dspool->get(ds_id, true);
  1389.  
  1390.     if ( ds != 0 )  // TODO: error otherwise or leave image in ERROR?
  1391.     {
  1392.         ds->add_image(iid);
  1393.  
  1394.         dspool->update(ds);
  1395.  
  1396.         ds->unlock();
  1397.     }
  1398.  
  1399.     // Return the new allocated Image ID
  1400.     if (!do_template)
  1401.     {
  1402.         success_response(iid, att);
  1403.         return;
  1404.     }
  1405.  
  1406.     // -------------------------------------------------------------------------
  1407.     // Clone original template and replace disk with saved one
  1408.     // -------------------------------------------------------------------------
  1409.     int ntid;
  1410.  
  1411.     PoolObjectAuth perms;
  1412.     VMTemplate *   vm_tmpl = tpool->get(tid,true);
  1413.  
  1414.     if ( vm_tmpl == 0 ) //Failed to get original template return saved image id
  1415.     {
  1416.         ostringstream error;
  1417.  
  1418.         error << get_error(object_name(PoolObjectSQL::TEMPLATE), tid)
  1419.               << "Image successfully saved with id: " << iid;
  1420.  
  1421.         failure_response(NO_EXISTS, error.str(), att);
  1422.         return;
  1423.     }
  1424.  
  1425.     VirtualMachineTemplate * tmpl = vm_tmpl->clone_template();
  1426.  
  1427.     vm_tmpl->get_permissions(perms);
  1428.  
  1429.     vm_tmpl->unlock();
  1430.  
  1431.     //Setup the new template: name and replace disk
  1432.  
  1433.     ostringstream tmpl_name;
  1434.  
  1435.     tmpl_name << img_name << "-" << iid;
  1436.  
  1437.     tmpl->replace("NAME", tmpl_name.str());
  1438.     tmpl->replace("SAVED_TEMPLATE_ID", tid);
  1439.     tmpl->replace("SAVED_TO_IMAGE_ID", iid);
  1440.  
  1441.     tmpl->replace_disk_image(iid_orig, iname_orig, iuname_orig, img_name, att.uname);
  1442.  
  1443.     //Authorize the template creation operation
  1444.  
  1445.     if ( att.uid != 0 )
  1446.     {
  1447.         string tmpl_str = "";
  1448.  
  1449.         AuthRequest ar(att.uid, att.group_ids);
  1450.  
  1451.         ar.add_auth(AuthRequest::USE, perms);
  1452.  
  1453.         tmpl->to_xml(tmpl_str);
  1454.  
  1455.         ar.add_create_auth(att.uid, att.gid, PoolObjectSQL::TEMPLATE, tmpl_str);
  1456.  
  1457.         if (UserPool::authorize(ar) == -1)
  1458.         {
  1459.             delete tmpl;
  1460.  
  1461.             ostringstream error;
  1462.  
  1463.             error << authorization_error(ar.message, att)
  1464.                   << "Image successfully saved with id: " << iid;
  1465.  
  1466.             failure_response(AUTHORIZATION, error.str(), att);
  1467.  
  1468.             return;
  1469.         }
  1470.     }
  1471.  
  1472.     //Allocate the template
  1473.  
  1474.     rc = tpool->allocate(att.uid, att.gid, att.uname, att.gname, att.umask,
  1475.                 tmpl, &ntid, error_str);
  1476.  
  1477.     if (rc < 0)
  1478.     {
  1479.         ostringstream error;
  1480.  
  1481.         error << allocate_error(PoolObjectSQL::TEMPLATE, error_str)
  1482.               << "Image successfully saved with id: " << iid;
  1483.  
  1484.         failure_response(INTERNAL, error.str(), att);
  1485.  
  1486.         return;
  1487.     }
  1488.  
  1489.     success_response(iid, att);
  1490. }
  1491.  
  1492. /* -------------------------------------------------------------------------- */
  1493. /* -------------------------------------------------------------------------- */
  1494.  
  1495. void VirtualMachineMonitoring::request_execute(
  1496.         xmlrpc_c::paramList const&  paramList,
  1497.         RequestAttributes&          att)
  1498. {
  1499.     int  id = xmlrpc_c::value_int(paramList.getInt(1));
  1500.     int  rc;
  1501.  
  1502.     ostringstream oss;
  1503.  
  1504.     bool auth = vm_authorization(id, 0, 0, att, 0, 0, auth_op);
  1505.  
  1506.     if ( auth == false )
  1507.     {
  1508.         return;
  1509.     }
  1510.  
  1511.     rc = (static_cast<VirtualMachinePool *>(pool))->dump_monitoring(oss, id);
  1512.  
  1513.     if ( rc != 0 )
  1514.     {
  1515.         failure_response(INTERNAL,request_error("Internal Error",""), att);
  1516.         return;
  1517.     }
  1518.  
  1519.     success_response(oss.str(), att);
  1520.  
  1521.     return;
  1522. }
  1523.  
  1524. /* -------------------------------------------------------------------------- */
  1525. /* -------------------------------------------------------------------------- */
  1526.  
  1527. void VirtualMachineAttach::request_execute(xmlrpc_c::paramList const& paramList,
  1528.                                             RequestAttributes& att)
  1529. {
  1530.     Nebula&           nd = Nebula::instance();
  1531.     DispatchManager * dm = nd.get_dm();
  1532.  
  1533.     VirtualMachineTemplate * tmpl = new VirtualMachineTemplate();
  1534.     VirtualMachineTemplate * deltas = 0;
  1535.     PoolObjectAuth           vm_perms;
  1536.  
  1537.     VirtualMachinePool * vmpool = static_cast<VirtualMachinePool *>(pool);
  1538.     VirtualMachine *     vm;
  1539.  
  1540.     int    rc;
  1541.     string error_str;
  1542.     bool   volatile_disk;
  1543.  
  1544.     int     id       = xmlrpc_c::value_int(paramList.getInt(1));
  1545.     string  str_tmpl = xmlrpc_c::value_string(paramList.getString(2));
  1546.  
  1547.     // -------------------------------------------------------------------------
  1548.     // Parse Disk template
  1549.     // -------------------------------------------------------------------------
  1550.  
  1551.     rc = tmpl->parse_str_or_xml(str_tmpl, error_str);
  1552.  
  1553.     if ( rc != 0 )
  1554.     {
  1555.         failure_response(INTERNAL, error_str, att);
  1556.         delete tmpl;
  1557.  
  1558.         return;
  1559.     }
  1560.  
  1561.     // -------------------------------------------------------------------------
  1562.     // Authorize the operation & check quotas
  1563.     // -------------------------------------------------------------------------
  1564.  
  1565.     if ( vm_authorization(id, 0, tmpl, att, 0, 0, auth_op) == false )
  1566.     {
  1567.         delete tmpl;
  1568.         return;
  1569.     }
  1570.  
  1571.     vm = vmpool->get(id, true);
  1572.  
  1573.     if (vm == 0)
  1574.     {
  1575.         failure_response(NO_EXISTS,
  1576.                 get_error(object_name(PoolObjectSQL::VM),id),
  1577.                 att);
  1578.         return;
  1579.     }
  1580.  
  1581.     vm->get_permissions(vm_perms);
  1582.  
  1583.     vm->unlock();
  1584.  
  1585.     RequestAttributes att_quota(vm_perms.uid, vm_perms.gid, att);
  1586.  
  1587.     volatile_disk = VirtualMachine::isVolatile(tmpl);
  1588.  
  1589.     if ( volatile_disk )
  1590.     {
  1591.         deltas = new VirtualMachineTemplate(*tmpl);
  1592.  
  1593.         deltas->add("VMS", 0);
  1594.  
  1595.         if (quota_resize_authorization(id, deltas, att_quota) == false)
  1596.         {
  1597.             delete tmpl;
  1598.             delete deltas;
  1599.  
  1600.             return;
  1601.         }
  1602.     }
  1603.     else
  1604.     {
  1605.         if ( quota_authorization(tmpl, Quotas::IMAGE, att_quota) == false )
  1606.         {
  1607.             delete tmpl;
  1608.             return;
  1609.         }
  1610.     }
  1611.  
  1612.     rc = dm->attach(id, tmpl, error_str);
  1613.  
  1614.     if ( rc != 0 )
  1615.     {
  1616.         if ( volatile_disk )
  1617.         {
  1618.             quota_rollback(deltas, Quotas::VM, att_quota);
  1619.         }
  1620.         else
  1621.         {
  1622.             quota_rollback(tmpl, Quotas::IMAGE, att_quota);
  1623.         }
  1624.  
  1625.         failure_response(ACTION,
  1626.                 request_error(error_str, ""),
  1627.                 att);
  1628.     }
  1629.     else
  1630.     {
  1631.         success_response(id, att);
  1632.     }
  1633.  
  1634.     delete tmpl;
  1635.     delete deltas;
  1636.  
  1637.     return;
  1638. }
  1639.  
  1640. /* -------------------------------------------------------------------------- */
  1641. /* -------------------------------------------------------------------------- */
  1642.  
  1643. void VirtualMachineDetach::request_execute(xmlrpc_c::paramList const& paramList,
  1644.                                             RequestAttributes& att)
  1645. {
  1646.     Nebula&             nd = Nebula::instance();
  1647.     DispatchManager *   dm = nd.get_dm();
  1648.  
  1649.     int rc;
  1650.     string error_str;
  1651.  
  1652.     int     id      = xmlrpc_c::value_int(paramList.getInt(1));
  1653.     int     disk_id = xmlrpc_c::value_int(paramList.getInt(2));
  1654.  
  1655.     // -------------------------------------------------------------------------
  1656.     // Authorize the operation
  1657.     // -------------------------------------------------------------------------
  1658.  
  1659.     if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
  1660.     {
  1661.         return;
  1662.     }
  1663.  
  1664.     rc = dm->detach(id, disk_id, error_str);
  1665.  
  1666.     if ( rc != 0 )
  1667.     {
  1668.         failure_response(ACTION,
  1669.                 request_error(error_str, ""),
  1670.                 att);
  1671.     }
  1672.     else
  1673.     {
  1674.         success_response(id, att);
  1675.     }
  1676.  
  1677.     return;
  1678. }
  1679.  
  1680. /* -------------------------------------------------------------------------- */
  1681. /* -------------------------------------------------------------------------- */
  1682.  
  1683. void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList,
  1684.                                            RequestAttributes& att)
  1685. {
  1686.     int     id              = xmlrpc_c::value_int(paramList.getInt(1));
  1687.     string  str_tmpl        = xmlrpc_c::value_string(paramList.getString(2));
  1688.     bool    enforce_param   = xmlrpc_c::value_boolean(paramList.getBoolean(3));
  1689.  
  1690.     float ncpu, ocpu, dcpu;
  1691.     int   nmemory, omemory, dmemory;
  1692.     int   nvcpu, ovcpu;
  1693.  
  1694.     Nebula&    nd    = Nebula::instance();
  1695.     HostPool * hpool = nd.get_hpool();
  1696.     Host *     host;
  1697.  
  1698.     Template deltas;
  1699.     string   error_str;
  1700.     bool     rc;
  1701.     int      ret;
  1702.     int      hid = -1;
  1703.  
  1704.     PoolObjectAuth vm_perms;
  1705.  
  1706.     VirtualMachinePool * vmpool = static_cast<VirtualMachinePool *>(pool);
  1707.     VirtualMachine * vm;
  1708.     VirtualMachineTemplate tmpl;
  1709.  
  1710.     bool enforce = true;
  1711.  
  1712.     if (att.uid == UserPool::ONEADMIN_ID || att.gid == GroupPool::ONEADMIN_ID)
  1713.     {
  1714.         enforce = enforce_param;
  1715.     }
  1716.  
  1717.     // -------------------------------------------------------------------------
  1718.     // Parse template
  1719.     // -------------------------------------------------------------------------
  1720.  
  1721.     rc = tmpl.parse_str_or_xml(str_tmpl, error_str);
  1722.  
  1723.     if ( rc != 0 )
  1724.     {
  1725.         failure_response(INTERNAL, error_str, att);
  1726.         return;
  1727.     }
  1728.  
  1729.     /* ---------------------------------------------------------------------- */
  1730.     /*  Authorize the operation & restricted attributes                       */
  1731.     /* ---------------------------------------------------------------------- */
  1732.  
  1733.     if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
  1734.     {
  1735.         return;
  1736.     }
  1737.  
  1738.     if (att.uid != UserPool::ONEADMIN_ID && att.gid!=GroupPool::ONEADMIN_ID)
  1739.     {
  1740.         string aname;
  1741.  
  1742.         if (tmpl.check(aname))
  1743.         {
  1744.             ostringstream oss;
  1745.  
  1746.             oss << "Template includes a restricted attribute " << aname;
  1747.  
  1748.             failure_response(AUTHORIZATION,
  1749.                     authorization_error(oss.str(), att),
  1750.                     att);
  1751.             return;
  1752.         }
  1753.     }
  1754.  
  1755.     /* ---------------------------------------------------------------------- */
  1756.     /*  Get the resize values                                                 */
  1757.     /* ---------------------------------------------------------------------- */
  1758.  
  1759.     tmpl.get("CPU", ncpu);
  1760.     tmpl.get("VCPU", nvcpu);
  1761.     tmpl.get("MEMORY", nmemory);
  1762.  
  1763.     vm = vmpool->get(id, true);
  1764.  
  1765.     if (vm == 0)
  1766.     {
  1767.         failure_response(NO_EXISTS,
  1768.                 get_error(object_name(PoolObjectSQL::VM),id),
  1769.                 att);
  1770.         return;
  1771.     }
  1772.  
  1773.     vm->get_permissions(vm_perms);
  1774.  
  1775.     vm->get_template_attribute("MEMORY", omemory);
  1776.     vm->get_template_attribute("CPU", ocpu);
  1777.     vm->get_template_attribute("VCPU", ovcpu);
  1778.  
  1779.     if (nmemory == 0)
  1780.     {
  1781.         nmemory = omemory;
  1782.     }
  1783.  
  1784.     if (ncpu == 0)
  1785.     {
  1786.         ncpu = ocpu;
  1787.     }
  1788.  
  1789.     if (nvcpu == 0)
  1790.     {
  1791.         nvcpu = ovcpu;
  1792.     }
  1793.  
  1794.     dcpu    = ncpu - ocpu;
  1795.     dmemory = nmemory - omemory;
  1796.  
  1797.     deltas.add("MEMORY", dmemory);
  1798.     deltas.add("CPU", dcpu);
  1799.     deltas.add("VMS", 0);
  1800.  
  1801.     switch (vm->get_state())
  1802.     {
  1803.         case VirtualMachine::POWEROFF: //Only check host capacity in POWEROFF
  1804.             if (vm->hasHistory() == true)
  1805.             {
  1806.                 hid = vm->get_hid();
  1807.             }
  1808.         break;
  1809.  
  1810.         case VirtualMachine::INIT:
  1811.         case VirtualMachine::PENDING:
  1812.         case VirtualMachine::HOLD:
  1813.         case VirtualMachine::FAILED:
  1814.         case VirtualMachine::UNDEPLOYED:
  1815.         break;
  1816.  
  1817.         case VirtualMachine::STOPPED:
  1818.         case VirtualMachine::DONE:
  1819.         case VirtualMachine::SUSPENDED:
  1820.         case VirtualMachine::ACTIVE:
  1821.             failure_response(ACTION,
  1822.                      request_error("Wrong state to perform action",""),
  1823.                      att);
  1824.  
  1825.             vm->unlock();
  1826.             return;
  1827.     }
  1828.  
  1829.     ret = vm->check_resize(ncpu, nmemory, nvcpu, error_str);
  1830.  
  1831.     vm->unlock();
  1832.  
  1833.     if (ret != 0)
  1834.     {
  1835.         failure_response(INTERNAL,
  1836.                 request_error("Could resize the VM", error_str),
  1837.                 att);
  1838.         return;
  1839.     }
  1840.  
  1841.     /* ---------------------------------------------------------------------- */
  1842.     /*  Check quotas                                                          */
  1843.     /* ---------------------------------------------------------------------- */
  1844.  
  1845.     if (quota_resize_authorization(&deltas, att, vm_perms) == false)
  1846.     {
  1847.         return;
  1848.     }
  1849.  
  1850.     RequestAttributes att_rollback(vm_perms.uid, vm_perms.gid, att);
  1851.  
  1852.     /* ---------------------------------------------------------------------- */
  1853.     /*  Check & update host capacity                                          */
  1854.     /* ---------------------------------------------------------------------- */
  1855.  
  1856.     if (hid != -1)
  1857.     {
  1858.         int dcpu_host = (int) (dcpu * 100);//now in 100%
  1859.         int dmem_host = dmemory * 1024;    //now in Kilobytes
  1860.  
  1861.         host = hpool->get(hid, true);
  1862.  
  1863.         if (host == 0)
  1864.         {
  1865.             failure_response(NO_EXISTS,
  1866.                 get_error(object_name(PoolObjectSQL::HOST),hid),
  1867.                 att);
  1868.  
  1869.             quota_rollback(&deltas, Quotas::VM, att_rollback);
  1870.  
  1871.             return;
  1872.         }
  1873.  
  1874.         if ( enforce && host->test_capacity(dcpu_host, dmem_host, 0) == false)
  1875.         {
  1876.             ostringstream oss;
  1877.  
  1878.             oss << object_name(PoolObjectSQL::HOST)
  1879.                 << " " << hid << " does not have enough capacity.";
  1880.  
  1881.             failure_response(ACTION, request_error(oss.str(),""), att);
  1882.  
  1883.             host->unlock();
  1884.  
  1885.             quota_rollback(&deltas, Quotas::VM, att_rollback);
  1886.  
  1887.             return;
  1888.         }
  1889.  
  1890.         host->update_capacity(dcpu_host, dmem_host, 0);
  1891.  
  1892.         hpool->update(host);
  1893.  
  1894.         host->unlock();
  1895.     }
  1896.  
  1897.     /* ---------------------------------------------------------------------- */
  1898.     /*  Resize the VM                                                         */
  1899.     /* ---------------------------------------------------------------------- */
  1900.  
  1901.     vm = vmpool->get(id, true);
  1902.  
  1903.     if (vm == 0)
  1904.     {
  1905.         failure_response(NO_EXISTS,
  1906.                 get_error(object_name(PoolObjectSQL::VM),id),
  1907.                 att);
  1908.  
  1909.         quota_rollback(&deltas, Quotas::VM, att_rollback);
  1910.  
  1911.         if (hid != -1)
  1912.         {
  1913.             host = hpool->get(hid, true);
  1914.  
  1915.             if (host != 0)
  1916.             {
  1917.                 host->update_capacity(-dcpu, -dmemory, 0);
  1918.                 hpool->update(host);
  1919.  
  1920.                 host->unlock();
  1921.             }
  1922.         }
  1923.         return;
  1924.     }
  1925.  
  1926.     //Check again state as the VM may transit to active (e.g. scheduled)
  1927.     switch (vm->get_state())
  1928.     {
  1929.         case VirtualMachine::INIT:
  1930.         case VirtualMachine::PENDING:
  1931.         case VirtualMachine::HOLD:
  1932.         case VirtualMachine::FAILED:
  1933.         case VirtualMachine::POWEROFF:
  1934.         case VirtualMachine::UNDEPLOYED:
  1935.             ret = vm->resize(ncpu, nmemory, nvcpu, error_str);
  1936.  
  1937.             if (ret != 0)
  1938.             {
  1939.                 vm->unlock();
  1940.  
  1941.                 failure_response(INTERNAL,
  1942.                         request_error("Could not resize the VM", error_str),
  1943.                         att);
  1944.                 return;
  1945.             }
  1946.  
  1947.             vmpool->update(vm);
  1948.         break;
  1949.  
  1950.         case VirtualMachine::STOPPED:
  1951.         case VirtualMachine::DONE:
  1952.         case VirtualMachine::SUSPENDED:
  1953.         case VirtualMachine::ACTIVE:
  1954.             failure_response(ACTION,
  1955.                      request_error("Wrong state to perform action",""),
  1956.                      att);
  1957.  
  1958.             vm->unlock();
  1959.  
  1960.             quota_rollback(&deltas, Quotas::VM, att_rollback);
  1961.  
  1962.             if (hid != -1)
  1963.             {
  1964.                 host = hpool->get(hid, true);
  1965.  
  1966.                 if (host != 0)
  1967.                 {
  1968.                     host->update_capacity(ocpu - ncpu, omemory - nmemory, 0);
  1969.                     hpool->update(host);
  1970.  
  1971.                     host->unlock();
  1972.                 }
  1973.             }
  1974.             return;
  1975.     }
  1976.  
  1977.     vm->unlock();
  1978.  
  1979.     success_response(id, att);
  1980. }
  1981.  
  1982. /* -------------------------------------------------------------------------- */
  1983. /* -------------------------------------------------------------------------- */
  1984.  
  1985. void VirtualMachineSnapshotCreate::request_execute(
  1986.         xmlrpc_c::paramList const&  paramList,
  1987.         RequestAttributes&          att)
  1988. {
  1989.     Nebula&           nd = Nebula::instance();
  1990.     DispatchManager * dm = nd.get_dm();
  1991.  
  1992.     int     rc;
  1993.     int     snap_id;
  1994.     string  error_str;
  1995.  
  1996.     int     id   = xmlrpc_c::value_int(paramList.getInt(1));
  1997.     string  name = xmlrpc_c::value_string(paramList.getString(2));
  1998.  
  1999.     // -------------------------------------------------------------------------
  2000.     // Authorize the operation
  2001.     // -------------------------------------------------------------------------
  2002.  
  2003.     if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
  2004.     {
  2005.         return;
  2006.     }
  2007.  
  2008.     rc = dm->snapshot_create(id, name, snap_id, error_str);
  2009.  
  2010.     if ( rc != 0 )
  2011.     {
  2012.         failure_response(ACTION,
  2013.                 request_error(error_str, ""),
  2014.                 att);
  2015.     }
  2016.     else
  2017.     {
  2018.         success_response(snap_id, att);
  2019.     }
  2020.  
  2021.     return;
  2022. }
  2023.  
  2024. /* -------------------------------------------------------------------------- */
  2025. /* -------------------------------------------------------------------------- */
  2026.  
  2027. void VirtualMachineSnapshotRevert::request_execute(
  2028.         xmlrpc_c::paramList const&  paramList,
  2029.         RequestAttributes&          att)
  2030. {
  2031.     Nebula&           nd = Nebula::instance();
  2032.     DispatchManager * dm = nd.get_dm();
  2033.  
  2034.     int    rc;
  2035.     string error_str;
  2036.  
  2037.     int id      = xmlrpc_c::value_int(paramList.getInt(1));
  2038.     int snap_id = xmlrpc_c::value_int(paramList.getInt(2));
  2039.  
  2040.     // -------------------------------------------------------------------------
  2041.     // Authorize the operation
  2042.     // -------------------------------------------------------------------------
  2043.  
  2044.     if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
  2045.     {
  2046.         return;
  2047.     }
  2048.  
  2049.     rc = dm->snapshot_revert(id, snap_id, error_str);
  2050.  
  2051.     if ( rc != 0 )
  2052.     {
  2053.         failure_response(ACTION,
  2054.                 request_error(error_str, ""),
  2055.                 att);
  2056.     }
  2057.     else
  2058.     {
  2059.         success_response(id, att);
  2060.     }
  2061.  
  2062.     return;
  2063. }
  2064.  
  2065. /* -------------------------------------------------------------------------- */
  2066. /* -------------------------------------------------------------------------- */
  2067.  
  2068. void VirtualMachineSnapshotDelete::request_execute(
  2069.         xmlrpc_c::paramList const&  paramList,
  2070.         RequestAttributes&          att)
  2071. {
  2072.     Nebula&           nd = Nebula::instance();
  2073.     DispatchManager * dm = nd.get_dm();
  2074.  
  2075.     int    rc;
  2076.     string error_str;
  2077.  
  2078.     int id      = xmlrpc_c::value_int(paramList.getInt(1));
  2079.     int snap_id = xmlrpc_c::value_int(paramList.getInt(2));
  2080.  
  2081.     // -------------------------------------------------------------------------
  2082.     // Authorize the operation
  2083.     // -------------------------------------------------------------------------
  2084.  
  2085.     if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
  2086.     {
  2087.         return;
  2088.     }
  2089.  
  2090.     rc = dm->snapshot_delete(id, snap_id, error_str);
  2091.  
  2092.     if ( rc != 0 )
  2093.     {
  2094.         failure_response(ACTION,
  2095.                 request_error(error_str, ""),
  2096.                 att);
  2097.     }
  2098.     else
  2099.     {
  2100.         success_response(id, att);
  2101.     }
  2102.  
  2103.     return;
  2104. }
  2105.  
  2106. /* -------------------------------------------------------------------------- */
  2107. /* -------------------------------------------------------------------------- */
  2108.  
  2109. void VirtualMachineAttachNic::request_execute(
  2110.         xmlrpc_c::paramList const&  paramList,
  2111.         RequestAttributes&          att)
  2112. {
  2113.     Nebula&           nd = Nebula::instance();
  2114.     DispatchManager * dm = nd.get_dm();
  2115.  
  2116.     VirtualMachineTemplate tmpl;
  2117.  
  2118.     PoolObjectAuth       vm_perms;
  2119.     VirtualMachinePool * vmpool = static_cast<VirtualMachinePool *>(pool);
  2120.     VirtualMachine *     vm;
  2121.  
  2122.     int    rc;
  2123.     string error_str;
  2124.  
  2125.     int     id       = xmlrpc_c::value_int(paramList.getInt(1));
  2126.     string  str_tmpl = xmlrpc_c::value_string(paramList.getString(2));
  2127.  
  2128.     // -------------------------------------------------------------------------
  2129.     // Parse NIC template
  2130.     // -------------------------------------------------------------------------
  2131.  
  2132.     rc = tmpl.parse_str_or_xml(str_tmpl, error_str);
  2133.  
  2134.     if ( rc != 0 )
  2135.     {
  2136.         failure_response(INTERNAL, error_str, att);
  2137.         return;
  2138.     }
  2139.  
  2140.     // -------------------------------------------------------------------------
  2141.     // Authorize the operation, restricted attributes & check quotas
  2142.     // -------------------------------------------------------------------------
  2143.  
  2144.     if ( vm_authorization(id, 0, &tmpl, att, 0, 0, auth_op) == false )
  2145.     {
  2146.         return;
  2147.     }
  2148.  
  2149.     vm = vmpool->get(id, true);
  2150.  
  2151.     if (vm == 0)
  2152.     {
  2153.         failure_response(NO_EXISTS,
  2154.                 get_error(object_name(PoolObjectSQL::VM),id),
  2155.                 att);
  2156.         return;
  2157.     }
  2158.  
  2159.     vm->get_permissions(vm_perms);
  2160.  
  2161.     vm->unlock();
  2162.  
  2163.     RequestAttributes att_quota(vm_perms.uid, vm_perms.gid, att);
  2164.  
  2165.     if (att.uid != UserPool::ONEADMIN_ID && att.gid!=GroupPool::ONEADMIN_ID)
  2166.     {
  2167.         string aname;
  2168.  
  2169.         if (tmpl.check(aname))
  2170.         {
  2171.             ostringstream oss;
  2172.  
  2173.             oss << "NIC includes a restricted attribute " << aname;
  2174.  
  2175.             failure_response(AUTHORIZATION,
  2176.                     authorization_error(oss.str(), att),
  2177.                     att);
  2178.             return;
  2179.         }
  2180.     }
  2181.  
  2182.     if ( quota_authorization(&tmpl, Quotas::NETWORK, att_quota) == false )
  2183.     {
  2184.         return;
  2185.     }
  2186.  
  2187.     rc = dm->attach_nic(id, &tmpl, error_str);
  2188.  
  2189.     if ( rc != 0 )
  2190.     {
  2191.         quota_rollback(&tmpl, Quotas::NETWORK, att_quota);
  2192.  
  2193.         failure_response(ACTION,
  2194.                 request_error(error_str, ""),
  2195.                 att);
  2196.     }
  2197.     else
  2198.     {
  2199.         success_response(id, att);
  2200.     }
  2201.  
  2202.     return;
  2203. }
  2204.  
  2205. /* -------------------------------------------------------------------------- */
  2206. /* -------------------------------------------------------------------------- */
  2207.  
  2208. void VirtualMachineDetachNic::request_execute(
  2209.         xmlrpc_c::paramList const&  paramList,
  2210.         RequestAttributes&          att)
  2211. {
  2212.     Nebula&             nd = Nebula::instance();
  2213.     DispatchManager *   dm = nd.get_dm();
  2214.  
  2215.     int rc;
  2216.     string error_str;
  2217.  
  2218.     int id      = xmlrpc_c::value_int(paramList.getInt(1));
  2219.     int nic_id  = xmlrpc_c::value_int(paramList.getInt(2));
  2220.  
  2221.     // -------------------------------------------------------------------------
  2222.     // Authorize the operation
  2223.     // -------------------------------------------------------------------------
  2224.  
  2225.     if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
  2226.     {
  2227.         return;
  2228.     }
  2229.  
  2230.     rc = dm->detach_nic(id, nic_id, error_str);
  2231.  
  2232.     if ( rc != 0 )
  2233.     {
  2234.         failure_response(ACTION,
  2235.                 request_error(error_str, ""),
  2236.                 att);
  2237.     }
  2238.     else
  2239.     {
  2240.         success_response(id, att);
  2241.     }
  2242.  
  2243.     return;
  2244. }
  2245.  
  2246. /* -------------------------------------------------------------------------- */
  2247. /* -------------------------------------------------------------------------- */
  2248.  
  2249. void VirtualMachineRecover::request_execute(
  2250.         xmlrpc_c::paramList const& paramList, RequestAttributes& att)
  2251. {
  2252.     int  id      = xmlrpc_c::value_int(paramList.getInt(1));
  2253.     bool success = xmlrpc_c::value_boolean(paramList.getBoolean(2));
  2254.  
  2255.     VirtualMachine * vm;
  2256.  
  2257.     Nebula& nd             = Nebula::instance();
  2258.     LifeCycleManager*  lcm = nd.get_lcm();
  2259.  
  2260.     if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
  2261.     {
  2262.         return;
  2263.     }
  2264.  
  2265.     if ((vm = get_vm(id, att)) == 0)
  2266.     {
  2267.         return;
  2268.     }
  2269.  
  2270.     if(vm->get_state() != VirtualMachine::ACTIVE)
  2271.     {
  2272.         failure_response(ACTION,
  2273.                 request_error("Wrong state to perform action",""),
  2274.                 att);
  2275.  
  2276.         vm->unlock();
  2277.         return;
  2278.     }
  2279.  
  2280.     lcm->recover(vm, success);
  2281.  
  2282.     success_response(id, att);
  2283.  
  2284.     vm->unlock();
  2285.  
  2286.     return;
  2287. }
  2288.  
  2289. /* -------------------------------------------------------------------------- */
  2290. /* -------------------------------------------------------------------------- */
  2291.  
  2292. void VirtualMachinePoolCalculateShowback::request_execute(
  2293.         xmlrpc_c::paramList const& paramList,
  2294.         RequestAttributes& att)
  2295. {
  2296.     int start_month = xmlrpc_c::value_int(paramList.getInt(1));
  2297.     int start_year  = xmlrpc_c::value_int(paramList.getInt(2));
  2298.     int end_month   = xmlrpc_c::value_int(paramList.getInt(3));
  2299.     int end_year    = xmlrpc_c::value_int(paramList.getInt(4));
  2300.  
  2301.     ostringstream oss;
  2302.     string        where;
  2303.     int           rc;
  2304.     string        error_str;
  2305.  
  2306.     if ( att.gid != 0 )
  2307.     {
  2308.         failure_response(AUTHORIZATION,
  2309.                          authorization_error("Action reserved for group 0 only", att),
  2310.                          att);
  2311.         return;
  2312.     }
  2313.  
  2314.     rc = (static_cast<VirtualMachinePool *>(pool))->calculate_showback(
  2315.                     start_month, start_year, end_month, end_year, error_str);
  2316.  
  2317.     if (rc != 0)
  2318.     {
  2319.         failure_response(AUTHORIZATION,
  2320.                          request_error(error_str, ""),
  2321.                          att);
  2322.         return;
  2323.     }
  2324.  
  2325.     success_response("", att);
  2326.  
  2327.     return;
  2328. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement