XML-RPC: Extend by new functionality
authorMichal Novotny <minovotn@redhat.com>
Thu, 4 Oct 2012 13:44:10 +0000 (15:44 +0200)
committerMichal Novotny <minovotn@redhat.com>
Thu, 4 Oct 2012 13:44:10 +0000 (15:44 +0200)
Signed-off-by: Michal Novotny <minovotn@redhat.com>

classes/XmlRPC.php
classes/libvirt-domain.php
classes/libvirt-network.php
classes/libvirt.php
xmlrpc-test.py

index 98e7c24..1b99b4c 100644 (file)
                        if ((empty($data)) || ($data == false)) {
                                $errmsg = false;
                                $log = ($this->log_override) ? $this->log_override : $this->get_log();
-                               for ($i = sizeof($log) - 1; $i > 0; $i--) {
+                               for ($i = sizeof($log) - 1; $i >= 0; $i--) {
                                        if ($log[$i]['type'] == TYPE_ERROR) {
                                                $errmsg = $log[$i]['msg'];
                                                break;
index a856425..25854a9 100644 (file)
                        return ($lv->domain_reboot($name)) ? 'Domain reboot triggered successfully' : 'Cannot trigger reboot command';
                }
 
+               function rpc_dump($idUser, $lv, $ret) {
+                       if ((!array_key_exists('data', $ret)) || (!array_key_exists('data', $ret['data'])) || (!array_key_exists('name', $ret['data']['data'])))
+                               return $this->log(TYPE_ERROR, __CLASS__.'::'.__FUNCTION__, 'Name is missing', 'Domain name is missing');
+
+                       $name = $ret['data']['data']['name'];
+                       return $lv->domain_get_xml($name, ($lv->domain_is_running($name) ? false : true));
+               }
+
+               function rpc_migrate($idUser, $lv, $ret) {
+                       if ((!array_key_exists('data', $ret)) || (!array_key_exists('data', $ret['data'])) || (!array_key_exists('name', $ret['data']['data'])))
+                               return $this->log(TYPE_ERROR, __CLASS__.'::'.__FUNCTION__, 'Name is missing', 'Domain name is missing');
+
+                       if ((!array_key_exists('destination', $ret['data']['data'])) || (!array_key_exists('uri', $ret['data']['data']['destination'])))
+                               return $this->log(TYPE_ERROR, __CLASS__.'::'.__FUNCTION__, 'Destination is missing', 'Destination connection information are missing');
+
+                       $name = $ret['data']['data']['name'];
+                       $uri  = $ret['data']['data']['destination']['uri'];
+                       $user = array_key_exists('username', $ret['data']['data']['destination']) ? $ret['data']['data']['destination']['username'] : null;
+                       $pass = array_key_exists('password', $ret['data']['data']['destination']) ? $ret['data']['data']['destination']['password'] : null;
+
+                       if ($lv->get_uri() == $uri)
+                               return $this->log(TYPE_ERROR, __CLASS__.'::'.__FUNCTION__, 'Local migration not supported', 'Local migration requested but not supported');
+
+                       $dest_lv = new Libvirt($uri, $user, $pass, false, 'en');
+                       if (!$dest_lv->is_connected()) {
+                               unset($dest_lv);
+                               return 'Cannot connect to destination';
+                       }
+
+                       $ret = $lv->migrate($name, $dest_lv->get_connection(), array_key_exists('live', $ret['data']['data']) ? $ret['data']['data']['live'] : false,
+                                       array_key_exists('bandwidth', $ret['data']['data']) ? $ret['data']['data']['bandwidth'] :  1000);
+                       unset($dest_lv);
+
+                       return $ret ? 'Success' : 'Error on migrate';
+               }
+
+               function rpc_get_screenshot($idUser, $lv, $ret) {
+                       if ((!array_key_exists('data', $ret)) || (!array_key_exists('data', $ret['data'])) || (!array_key_exists('name', $ret['data']['data'])))
+                               return $this->log(TYPE_ERROR, __CLASS__.'::'.__FUNCTION__, 'Name is missing', 'Domain name is missing');
+
+                       $name = $ret['data']['data']['name'];
+
+                       if (!$lv->domain_is_running($name))
+                               return $this->log(TYPE_ERROR, __CLASS__.'::'.__FUNCTION__, 'Domain not active', 'Cannot get screenshot for inactive domain');
+
+                       /* TODO: Implement. Just a placeholder for now */
+
+                       return 'Not supported yet';
+               }
+
                function rpc_info($idUser, $lv, $ret) {
                        if ((!array_key_exists('data', $ret)) || (!array_key_exists('data', $ret['data'])) || (!array_key_exists('name', $ret['data']['data'])))
                                return $this->log(TYPE_ERROR, __CLASS__.'::'.__FUNCTION__, 'Name is missing', 'Domain name is missing');
index e342ed9..3052792 100644 (file)
                                        'msg' => $msg
                                        );
                }
+
+               function rpc_list($idUser, $lv, $ret) {
+                       return $lv->get_networks();
+               }
+
+               function rpc_info($idUser, $lv, $ret) {
+                       if ((!array_key_exists('data', $ret)) || (!array_key_exists('data', $ret['data'])) || (!array_key_exists('name', $ret['data']['data'])))
+                               return $this->log(TYPE_ERROR, __CLASS__.'::'.__FUNCTION__, 'Name is missing', 'Network name is missing');
+
+                       $name = $ret['data']['data']['name'];
+                       return $lv->get_network_information($name);
+               }
        }
 ?>
index ad8335d..8ea33d9 100644 (file)
                        return true;
                }
 
+               function is_connected() {
+                       return $this->conn ? true : false;
+               }
+
                function get_capabilities() {
                        $tmp = libvirt_connect_get_capabilities($this->conn);
                        return ($tmp) ? $tmp : $this->_set_last_error();
index 2e70281..00731fa 100755 (executable)
@@ -5,18 +5,21 @@ import xmlrpc.client
 
 apikey = "8YBjNqa8zFyTs3lZqqqNnkC8KT3KQsxOfWWQaUNAq9jI2vxgJLRUWkSu1M2H2ok5a6MbQpB4oICe1YjAz0lj83E0DwvwKFrJz1Ige7asFBvxnEVKs6UrYmfpGyLf41Mr"
 address = "http://localhost/php-virt-control/xmlrpc.php"
-selections = ['Information', 'Domain', 'Network']
+selections = ['Information', 'Domain', 'Get network information']
 info_types = ['connection', 'node', 'cpustats', 'eachcpustats', 'memstats', 'system']
 domactions = ['Start', 'Stop', 'Reboot', 'Dump', 'Migrate', 'Get screenshot']
 request = {'apikey': apikey,
            'connection': {'uri': 'qemu:///system'}
          }
 
+# Should bail on this
+connection_uri2 = 'qemu:///system';
+
 request_info = request
 request_info['data'] = {'type': 'unknown'}
 
-request_domain = request
-request_domain['data'] = {'name': 'x'}
+request_name = request
+request_name['data'] = {'name': 'x'}
 
 def choose(prompt, chooser, types):
     print("\n%s types:\n" % chooser)
@@ -56,11 +59,11 @@ try:
         except:
             sys.exit(1)
 
-        # Assign the name to request_domain dictionary
+        # Assign the name to request_name dictionary
         name = l[str(idx)]
-        request_domain['data']['name'] = name
+        request_name['data']['name'] = name
 
-        l = proxy.Domain.info(request_domain)
+        l = proxy.Domain.info(request_name)
         print("\nDomain information:\n\nName: %s\nvCPUs: %s\nState: %s\nMemory: %s MiB (max %s MiB)\nCPUUsed: %s" %
             (name, l['nrVirtCpu'], l['state'], l['memory'] / 1024, l['maxMem'] / 1024, l['cpuUsed']))
         print("\nFeatures: %s\nMultimedia:\n\tInput: %s\n\tVideo: %s\n\tConsole: %s\n\tGraphics: %s\nHost devices: %s\nBoot devices: %s\n" %
@@ -73,19 +76,43 @@ try:
         # Process actions
         if num == 0:
             print("Starting up domain %s" % name)
-            print("Method returned: %s" % proxy.Domain.start(request_domain))
+            print("Method returned: %s" % proxy.Domain.start(request_name)['msg'])
         elif num == 1:
             print("Stopping domain %s" % name)
-            print("Method returned: %s" % proxy.Domain.stop(request_domain))
+            print("Method returned: %s" % proxy.Domain.stop(request_name)['msg'])
         elif num == 2:
             print("Rebooting %s" % name)
-            print("Method returned: %s" % proxy.Domain.reboot(request_domain))
+            print("Method returned: %s" % proxy.Domain.reboot(request_name)['msg'])
         elif num == 3:
             print("Dumping %s" % name)
+            print("Method returned:\n%s" % proxy.Domain.dump(request_name)['msg'])
         elif num == 4:
             print("Migrating %s" % name)
+            request_domain_migrate = request_name
+            request_domain_migrate['data']['destination'] = {'uri': connection_uri2}
+
+            print("Method returned: %s" % proxy.Domain.migrate(request_domain_migrate)['msg'])
         elif num == 5:
             print("Getting screenshot of %s" % name)
+            print("Method returned: %s" % proxy.Domain.get_screenshot(request_name)['msg'])
+    elif num == 2:
+        l = proxy.Network.list(request)
+        print("Network:\n")
+        for d in l:
+            print("%s) %s" % (int(d) + 1, l[d]))
+        print("\n")
+        line = input("Choose network index: ")
+        try:
+            idx = int(line) - 1
+        except:
+            sys.exit(1)
+
+        # Assign the name to request_name dictionary
+        name = l[str(idx)]
+        request_name['data']['name'] = name
+
+        print("Getting information about %s" % name)
+        print("Method returned: %s" % proxy.Network.info(request_name))
 
 except xmlrpc.client.ProtocolError as err:
     print("A protocol error occurred")