diff --no-dereference -uNr opennebula-5.2.1.orig/src/lcm/LifeCycleActions.cc opennebula-5.2.1-vncautoport/src/lcm/LifeCycleActions.cc
--- opennebula-5.2.1.orig/src/lcm/LifeCycleActions.cc	2017-01-04 10:40:37.000000000 -0600
+++ opennebula-5.2.1-vncautoport/src/lcm/LifeCycleActions.cc	2017-04-20 12:04:16.417496645 -0500
@@ -907,7 +907,7 @@
 
     const VectorAttribute * graphics = vm->get_template_attribute("GRAPHICS");
 
-    if ( graphics != 0 && (graphics->vector_value("PORT", port) == 0))
+    if ( graphics != 0 && (graphics->vector_value("PORT") != "auto" && graphics->vector_value("PORT", port) == 0))
     {
         clpool->release_vnc_port(vm->get_cid(), port);
     }
diff --no-dereference -uNr opennebula-5.2.1.orig/src/lcm/LifeCycleStates.cc opennebula-5.2.1-vncautoport/src/lcm/LifeCycleStates.cc
--- opennebula-5.2.1.orig/src/lcm/LifeCycleStates.cc	2017-01-04 10:40:37.000000000 -0600
+++ opennebula-5.2.1-vncautoport/src/lcm/LifeCycleStates.cc	2017-04-20 12:04:25.748497333 -0500
@@ -965,7 +965,7 @@
 
     const VectorAttribute * graphics = vm->get_template_attribute("GRAPHICS");
 
-    if ( graphics != 0 && (graphics->vector_value("PORT", port) == 0))
+    if ( graphics != 0 && (graphics->vector_value("PORT") != "auto" && graphics->vector_value("PORT", port) == 0))
     {
         clpool->release_vnc_port(vm->get_cid(), port);
     }
diff --no-dereference -uNr opennebula-5.2.1.orig/src/onedb/fsck.rb opennebula-5.2.1-vncautoport/src/onedb/fsck.rb
--- opennebula-5.2.1.orig/src/onedb/fsck.rb	2017-01-04 10:40:37.000000000 -0600
+++ opennebula-5.2.1-vncautoport/src/onedb/fsck.rb	2017-04-20 12:21:54.810574684 -0500
@@ -812,7 +812,17 @@
 
             # VNC ports per cluster
             cid = vm_doc.root.at_xpath("HISTORY_RECORDS/HISTORY[last()]/CID").text.to_i rescue nil
-            port = vm_doc.root.at_xpath('TEMPLATE/GRAPHICS[translate(TYPE,"vnc","VNC")="VNC"]/PORT').text.to_i rescue nil
+
+            port = vm_doc.root.at_xpath('TEMPLATE/GRAPHICS[translate(TYPE,"vnc","VNC")="VNC"]/PORT').text rescue nil
+            if port == "auto"
+                port = nil
+            else
+                port = port.to_i rescue nil
+
+                if port == 0
+                    port = nil
+                end
+            end
 
             if cid && port
                 cluster_vnc[cid] ||= Set.new
diff --no-dereference -uNr opennebula-5.2.1.orig/src/onedb/local/4.13.85_to_4.90.0.rb opennebula-5.2.1-vncautoport/src/onedb/local/4.13.85_to_4.90.0.rb
--- opennebula-5.2.1.orig/src/onedb/local/4.13.85_to_4.90.0.rb	2017-01-04 10:40:37.000000000 -0600
+++ opennebula-5.2.1-vncautoport/src/onedb/local/4.13.85_to_4.90.0.rb	2017-04-20 12:22:05.782575493 -0500
@@ -854,7 +854,16 @@
       @db.fetch("SELECT * FROM vm_pool WHERE state != 6") do |row|
         doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks}
 
-        port = doc.root.at_xpath('TEMPLATE/GRAPHICS[translate(TYPE,"vnc","VNC")="VNC"]/PORT').text.to_i rescue nil
+        port = doc.root.at_xpath('TEMPLATE/GRAPHICS[translate(TYPE,"vnc","VNC")="VNC"]/PORT').text rescue nil
+        if port == "auto"
+            port = nil
+        else
+            port = port.to_i rescue nil
+
+            if port == 0
+                port = nil
+            end
+        end
         cluster_id = doc.root.at_xpath('HISTORY_RECORDS/HISTORY[last()]/CID').text.to_i rescue nil
 
         # skip if no port is defined or if it's not assigned to a cluster (not deployed yet!)
diff --no-dereference -uNr opennebula-5.2.1.orig/src/rm/RequestManagerVirtualMachine.cc opennebula-5.2.1-vncautoport/src/rm/RequestManagerVirtualMachine.cc
--- opennebula-5.2.1.orig/src/rm/RequestManagerVirtualMachine.cc	2017-01-04 10:40:37.000000000 -0600
+++ opennebula-5.2.1-vncautoport/src/rm/RequestManagerVirtualMachine.cc	2017-04-20 12:02:27.305488600 -0500
@@ -708,6 +708,10 @@
     {
         return 0;
     }
+    else if (graphics->vector_value("PORT") == "auto")
+    {
+        return 0;
+    }
     else if (graphics->vector_value("PORT", port) == 0)
     {
         rc = cpool->set_vnc_port(cluster_id, port);
diff --no-dereference -uNr opennebula-5.2.1.orig/src/vm/VirtualMachine.cc opennebula-5.2.1-vncautoport/src/vm/VirtualMachine.cc
--- opennebula-5.2.1.orig/src/vm/VirtualMachine.cc	2017-01-04 10:40:37.000000000 -0600
+++ opennebula-5.2.1-vncautoport/src/vm/VirtualMachine.cc	2017-04-20 12:15:31.279546405 -0500
@@ -1309,14 +1309,15 @@
 
     if ( !graphics->vector_value("PORT").empty() )
     {
-        unsigned int port;
+        if (graphics->vector_value("PORT") != "auto") {
+            unsigned int port;
+            int rc = graphics->vector_value("PORT", port);
 
-        int rc = graphics->vector_value("PORT", port);
-
-        if (rc == -1 || port > 65535 )
-        {
-            error_str = "Wrong PORT number in GRAPHICS attribute";
-            return -1;
+            if (rc == -1 || port > 65535 )
+            {
+                error_str = "Wrong PORT number in GRAPHICS attribute";
+                return -1;
+            }
         }
     }
 
diff --no-dereference -uNr opennebula-5.2.1.orig/src/vmm/LibVirtDriverKVM.cc opennebula-5.2.1-vncautoport/src/vmm/LibVirtDriverKVM.cc
--- opennebula-5.2.1.orig/src/vmm/LibVirtDriverKVM.cc	2017-01-04 10:40:37.000000000 -0600
+++ opennebula-5.2.1-vncautoport/src/vmm/LibVirtDriverKVM.cc	2017-04-20 12:22:36.293577743 -0500
@@ -1022,7 +1022,11 @@
 
             if ( !port.empty() )
             {
-                file << " port=" << one_util::escape_xml_attr(port);
+                if (port == "auto") {
+                    file << " autoport='yes'";
+                } else {
+                    file << " port=" << one_util::escape_xml_attr(port);
+                }
             }
 
             if ( !passwd.empty() )
diff --no-dereference -uNr opennebula-5.2.1.orig/src/vmm_mad/remotes/kvm/poll opennebula-5.2.1-vncautoport/src/vmm_mad/remotes/kvm/poll
--- opennebula-5.2.1.orig/src/vmm_mad/remotes/kvm/poll	2017-01-04 10:40:37.000000000 -0600
+++ opennebula-5.2.1-vncautoport/src/vmm_mad/remotes/kvm/poll	2017-04-23 09:09:25.867408643 -0500
@@ -418,7 +418,13 @@
 
         spice_txt = ''
         if spice
-            spice_txt = %Q<GRAPHICS = [ TYPE="spice", PORT="#{spice}" ]>
+            spice_autoport = spice.attributes['autoport']
+
+            if vnc_autoport == "yes"
+                spice_txt = %Q<GRAPHICS = [ TYPE="spice", PORT="auto" ]>
+            else
+                spice_txt = %Q<GRAPHICS = [ TYPE="spice", PORT="#{spice}" ]>
+            end
         end
 
         vnc = REXML::XPath.first(doc, "/domain/devices/graphics[@type='vnc']")
@@ -426,7 +432,13 @@
 
         vnc_txt = ''
         if vnc
-            vnc_txt = %Q<GRAPHICS = [ TYPE="vnc", PORT="#{vnc}" ]>
+            vnc_autoport = vnc.attributes['autoport']
+
+            if vnc_autoport == "yes"
+                vnc_txt = %Q<GRAPHICS = [ TYPE="vnc", PORT="auto" ]>
+            else
+                vnc_txt = %Q<GRAPHICS = [ TYPE="vnc", PORT="#{vnc}" ]>
+            end
         end
 
 
