From c9ed8a1f688dec19cafc41a06e4167ec82999ab7 Mon Sep 17 00:00:00 2001 From: Callum McIntyre Date: Tue, 30 Aug 2016 17:11:47 +0100 Subject: [PATCH 1/3] CP-17848: XAPI changes to support new update packaging calls/structrures --- XenModel/Actions/SR/SrAction.cs | 2 +- XenModel/XenAPI/FriendlyErrorNames.resx | 3 + XenModel/XenAPI/HTTP.cs | 279 +++++++- XenModel/XenAPI/Host.cs | 37 + XenModel/XenAPI/LVHD.cs | 10 +- XenModel/XenAPI/Pool_update.cs | 655 ++++++++++++++++++ XenModel/XenAPI/Proxy.cs | 167 ++++- XenModel/XenAPI/Relation.cs | 1 + XenModel/XenAPI/VIF.cs | 24 + XenModel/XenAPI/VM.cs | 65 +- .../XenAPI/update_after_apply_guidance.cs | 62 ++ XenModel/XenModel.csproj | 2 + 12 files changed, 1276 insertions(+), 31 deletions(-) create mode 100644 XenModel/XenAPI/Pool_update.cs create mode 100644 XenModel/XenAPI/update_after_apply_guidance.cs diff --git a/XenModel/Actions/SR/SrAction.cs b/XenModel/Actions/SR/SrAction.cs index 3303ef458..042424281 100644 --- a/XenModel/Actions/SR/SrAction.cs +++ b/XenModel/Actions/SR/SrAction.cs @@ -175,7 +175,7 @@ namespace XenAdmin.Actions long.TryParse(parameters["allocation_quantum"], out allocation_quantum); } - LVHD.enable_thin_provisioning(Session, SR.opaque_ref, initial_allocation, allocation_quantum); + LVHD.enable_thin_provisioning(Session, Host.opaque_ref, SR.opaque_ref, initial_allocation, allocation_quantum); Description = string.Format(Messages.ACTION_SR_CONVERTED_TO_THIN, SR.NameWithLocation); break; diff --git a/XenModel/XenAPI/FriendlyErrorNames.resx b/XenModel/XenAPI/FriendlyErrorNames.resx index a1ea7ea32..390c824ba 100644 --- a/XenModel/XenAPI/FriendlyErrorNames.resx +++ b/XenModel/XenAPI/FriendlyErrorNames.resx @@ -1772,6 +1772,9 @@ Authorized Roles: {1} The operation attempted is not valid for templates + + You attempted an operation on a VM which lacks the feature. + You attempted an operation which needs the cooperative shutdown feature on a VM which lacks it. diff --git a/XenModel/XenAPI/HTTP.cs b/XenModel/XenAPI/HTTP.cs index ecd1c1631..f984c4584 100644 --- a/XenModel/XenAPI/HTTP.cs +++ b/XenModel/XenAPI/HTTP.cs @@ -36,6 +36,7 @@ using System.Net.Sockets; using System.Text; using System.Net.Security; using System.Security.Authentication; +using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Runtime.Serialization; @@ -106,6 +107,18 @@ namespace XenAPI protected CancelledException(SerializationInfo info, StreamingContext context) : base(info, context) { } } + [Serializable] + public class ProxyServerAuthenticationException : Exception + { + public ProxyServerAuthenticationException() : base() { } + + public ProxyServerAuthenticationException(string message) : base(message) { } + + public ProxyServerAuthenticationException(string message, Exception exception) : base(message, exception) { } + + protected ProxyServerAuthenticationException(SerializationInfo info, StreamingContext context) : base(info, context) { } + } + public delegate bool FuncBool(); public delegate void UpdateProgressDelegate(int percent); public delegate void DataCopiedDelegate(long bytes); @@ -130,6 +143,10 @@ namespace XenAPI WriteLine("", stream); } + // Stream.ReadByte() is used because using StreamReader in its place causes the reading to become stuck, + // as it seems the Stream object has trouble recognizing the end of the stream. This seems to be a common + // problem, of which a common solution is to read each byte until an EndOfStreamException is thrown, as is + // done here. private static string ReadLine(Stream stream) { System.Text.StringBuilder result = new StringBuilder(); @@ -150,25 +167,81 @@ namespace XenAPI /// /// /// True if a redirect has occurred - headers will need to be resent. - private static bool ReadHttpHeaders(ref Stream stream, IWebProxy proxy, bool nodelay, int timeout_ms) + private static bool ReadHttpHeaders(ref Stream stream, IWebProxy proxy, bool nodelay, int timeout_ms, List headers = null) { - string response = ReadLine(stream); - int code = getResultCode(response); + // read headers/fields + string line = ReadLine(stream), initialLine = line, transferEncodingField = null; + if (string.IsNullOrEmpty(initialLine)) // sanity check + return false; + while (!string.IsNullOrWhiteSpace(line)) // IsNullOrWhiteSpace also checks for empty string + { + if (headers != null) + { + line = line.TrimEnd('\r', '\n'); + headers.Add(line); + if (line == "Transfer-Encoding: Chunked") + transferEncodingField = line; + } + line = ReadLine(stream); + } + // read chunks + string entityBody = ""; + if (!string.IsNullOrEmpty(transferEncodingField)) + { + int lastChunkSize = -1; + do + { + string chunkSizeStr = ReadLine(stream); + chunkSizeStr = chunkSizeStr.TrimEnd('\r', '\n'); + int chunkSize = int.Parse(chunkSizeStr, System.Globalization.NumberStyles.HexNumber); + + byte[] bytes = new byte[chunkSize]; + stream.Read(bytes, 0, chunkSize); + + if (headers != null) + { + string str = System.Text.Encoding.ASCII.GetString(bytes); + string[] split = str.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); + headers.AddRange(split); + + entityBody += str; + } + + line = ReadLine(stream); // empty line in the end of chunk + + lastChunkSize = chunkSize; + } + while (lastChunkSize != 0); + + if (headers != null) + { + entityBody = entityBody.TrimEnd('\r', '\n'); + headers.Add(entityBody); // keep entityBody if it's needed for Digest authentication (when qop="auth-int") + } + } + else + { + // todo: handle other transfer types, in case "Transfer-Encoding: Chunked" isn't used + } + + // handle server response + int code = getResultCode(initialLine); switch (code) { + case 407: // authentication error; caller must handle this case case 200: break; case 302: string url = ""; - while (true) + foreach (string header in headers) { - response = ReadLine(stream); - if (response.StartsWith("Location: ")) - url = response.Substring(10); - if (response.Equals("\r\n") || response.Equals("\n") || response.Equals("")) + if (header.StartsWith("Location: ")) + { + url = header.Substring(10); break; + } } Uri redirect = new Uri(url.Trim()); stream.Close(); @@ -176,19 +249,8 @@ namespace XenAPI return true; // headers need to be sent again default: - if (response.EndsWith("\r\n")) - response = response.Substring(0, response.Length - 2); - else if (response.EndsWith("\n")) - response = response.Substring(0, response.Length - 1); stream.Close(); - throw new BadServerResponseException(string.Format("Received error code {0} from the server", response)); - } - - while (true) - { - string line = ReadLine(stream); - if (System.Text.RegularExpressions.Regex.Match(line, "^\\s*$").Success) - break; + throw new BadServerResponseException(string.Format("Received error code {0} from the server", initialLine)); } return false; @@ -214,6 +276,20 @@ namespace XenAPI return true; } + /// + /// Returns a secure MD5 hash of the given input string. + /// + /// The string to hash. + /// The secure hash as a hex string. + public static string MD5Hash(string str) + { + MD5 hasher = MD5.Create(); + ASCIIEncoding enc = new ASCIIEncoding(); + byte[] bytes = enc.GetBytes(str); + byte[] hash = hasher.ComputeHash(bytes); + return BitConverter.ToString(hash).Replace("-", "").ToLower(); + } + public static long CopyStream(Stream inStream, Stream outStream, DataCopiedDelegate progressDelegate, FuncBool cancellingDelegate) { @@ -299,6 +375,12 @@ namespace XenAPI return uri.Uri; } + private static string GetPartOrNull(string str, int partIndex) + { + string[] parts = str.Split(new char[] { ' ' }, partIndex + 2, StringSplitOptions.RemoveEmptyEntries); + return partIndex < parts.Length - 1 ? parts[partIndex] : null; + } + #endregion private static NetworkStream ConnectSocket(Uri uri, bool nodelay, int timeout_ms) @@ -348,11 +430,13 @@ namespace XenAPI if (useProxy) { string line = String.Format("CONNECT {0}:{1} HTTP/1.0", uri.Host, uri.Port); - WriteLine(line, stream); WriteLine(stream); - ReadHttpHeaders(ref stream, proxy, nodelay, timeout_ms); + List initialResponse = new List(); + ReadHttpHeaders(ref stream, proxy, nodelay, timeout_ms, initialResponse); + + AuthenticateProxy(ref stream, uri, proxy, nodelay, timeout_ms, initialResponse, line); } if (UseSSL(uri)) @@ -373,6 +457,157 @@ namespace XenAPI } } + private static void AuthenticateProxy(ref Stream stream, Uri uri, IWebProxy proxy, bool nodelay, int timeout_ms, List initialResponse, string header) + { + // perform authentication only if proxy requires it + List fields = initialResponse.FindAll(str => str.StartsWith("Proxy-Authenticate:")); + if (fields.Count > 0) + { + // clean up (if initial server response specifies "Proxy-Connection: Close" then stream cannot be re-used) + string field = initialResponse.Find(str => str.StartsWith("Proxy-Connection: Close")); + if (!string.IsNullOrEmpty(field)) + { + stream.Close(); + Uri proxyURI = proxy.GetProxy(uri); + stream = ConnectSocket(proxyURI, nodelay, timeout_ms); + } + + if (proxy.Credentials == null) + throw new BadServerResponseException(string.Format("Received error code {0} from the server", initialResponse[0])); + NetworkCredential credentials = proxy.Credentials.GetCredential(uri, null); + + string basicField = fields.Find(str => str.StartsWith("Proxy-Authenticate: Basic")); + string digestField = fields.Find(str => str.StartsWith("Proxy-Authenticate: Digest")); + if (!string.IsNullOrEmpty(basicField)) + { + string authenticationFieldReply = String.Format("Proxy-Authorization: Basic {0}", + Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials.UserName + ":" + credentials.Password))); + WriteLine(header, stream); + WriteLine(authenticationFieldReply, stream); + WriteLine(stream); + } + else if (!string.IsNullOrEmpty(digestField)) + { + string authenticationFieldReply = string.Format( + "Proxy-Authorization: Digest username=\"{0}\", uri=\"{1}:{2}\"", + credentials.UserName, uri.Host, uri.Port); + + string directiveString = digestField.Substring(27, digestField.Length - 27); + string[] directives = directiveString.Split(new string[] { ", ", "\"" }, StringSplitOptions.RemoveEmptyEntries); + + string algorithm = null; // optional + string opaque = null; // optional + string qop = null; // optional + string realm = null; + string nonce = null; + + for (int i = 0; i < directives.Length; ++i) + { + switch (directives[i]) + { + case "stale=": + if (directives[++i].ToLower() == "true") + throw new ProxyServerAuthenticationException("Stale nonce in Digest authentication attempt."); + break; + case "realm=": + authenticationFieldReply += string.Format(", {0}\"{1}\"", directives[i], directives[++i]); + realm = directives[i]; + break; + case "nonce=": + authenticationFieldReply += string.Format(", {0}\"{1}\"", directives[i], directives[++i]); + nonce = directives[i]; + break; + case "opaque=": + authenticationFieldReply += string.Format(", {0}\"{1}\"", directives[i], directives[++i]); + opaque = directives[i]; + break; + case "algorithm=": + authenticationFieldReply += string.Format(", {0}\"{1}\"", directives[i], directives[++i]); + algorithm = directives[i]; + break; + case "qop=": + List qops = new List(directives[++i].Split(new char[] { ',' })); + if (qops.Count > 0) + { + if (qops.Contains("auth")) + qop = "auth"; + else if (qops.Contains("auth-int")) + qop = "auth-int"; + else + throw new ProxyServerAuthenticationException( + "Digest authentication's quality-of-protection directive of is not supported."); + authenticationFieldReply += string.Format(", qop=\"{0}\"", qop); + } + break; + default: + break; + } + } + + string clientNonce = "X3nC3nt3r"; // todo: generate random string + if (qop != null) + authenticationFieldReply += string.Format(", cnonce=\"{0}\"", clientNonce); + + string nonceCount = "00000001"; // todo: track nonces and their corresponding nonce counts + if (qop != null) + authenticationFieldReply += string.Format(", nc={0}", nonceCount); + + string HA1 = ""; + string scratch = string.Format("{0}:{1}:{2}", credentials.UserName, realm, credentials.Password); + if (algorithm == null || algorithm == "MD5") + HA1 = MD5Hash(scratch); + else + HA1 = MD5Hash(string.Format("{0}:{1}:{2}", MD5Hash(scratch), nonce, clientNonce)); + + string HA2 = ""; + scratch = GetPartOrNull(header, 0); + scratch = string.Format("{0}:{1}:{2}", scratch ?? "CONNECT", uri.Host, uri.Port); + if (qop == null || qop == "auth") + HA2 = MD5Hash(scratch); + else + { + string entityBody = initialResponse[initialResponse.Count - 1]; // entity body should have been stored as last element of initialResponse + string str = string.Format("{0}:{1}", scratch, MD5Hash(entityBody)); + HA2 = MD5Hash(str); + } + + string response = ""; + if (qop == null) + response = MD5Hash(string.Format("{0}:{1}:{2}", HA1, nonce, HA2)); + else + response = MD5Hash(string.Format("{0}:{1}:{2}:{3}:{4}:{5}", HA1, nonce, nonceCount, clientNonce, qop, HA2)); + + authenticationFieldReply += string.Format(", response=\"{0}\"", response); + + WriteLine(header, stream); + WriteLine(authenticationFieldReply, stream); + WriteLine(stream); + } + else + { + string authType = GetPartOrNull(fields[0], 1); + throw new ProxyServerAuthenticationException( + string.Format("Proxy server's {0} authentication method is not supported.", authType ?? "chosen")); + } + + // handle authentication attempt response + List authenticatedResponse = new List(); + ReadHttpHeaders(ref stream, proxy, nodelay, timeout_ms, authenticatedResponse); + if (authenticatedResponse.Count == 0) + throw new BadServerResponseException("No response from the proxy server after authentication attempt."); + switch (getResultCode(authenticatedResponse[0])) + { + case 200: + break; + case 407: + throw new ProxyServerAuthenticationException("Proxy server denied access due to wrong credentials."); + default: + throw new BadServerResponseException(string.Format( + "Received error code {0} from the server", authenticatedResponse[0])); + } + } + } + private static Stream DO_HTTP(Uri uri, IWebProxy proxy, bool nodelay, int timeout_ms, params string[] headers) { Stream stream = ConnectStream(uri, proxy, nodelay, timeout_ms); diff --git a/XenModel/XenAPI/Host.cs b/XenModel/XenAPI/Host.cs index 969f5a987..2537c724a 100644 --- a/XenModel/XenAPI/Host.cs +++ b/XenModel/XenAPI/Host.cs @@ -72,6 +72,7 @@ namespace XenAPI XenRef crash_dump_sr, List> crashdumps, List> patches, + List> updates, List> PBDs, List> host_CPUs, Dictionary cpu_info, @@ -126,6 +127,7 @@ namespace XenAPI this.crash_dump_sr = crash_dump_sr; this.crashdumps = crashdumps; this.patches = patches; + this.updates = updates; this.PBDs = PBDs; this.host_CPUs = host_CPUs; this.cpu_info = cpu_info; @@ -192,6 +194,7 @@ namespace XenAPI crash_dump_sr = update.crash_dump_sr; crashdumps = update.crashdumps; patches = update.patches; + updates = update.updates; PBDs = update.PBDs; host_CPUs = update.host_CPUs; cpu_info = update.cpu_info; @@ -249,6 +252,7 @@ namespace XenAPI crash_dump_sr = proxy.crash_dump_sr == null ? null : XenRef.Create(proxy.crash_dump_sr); crashdumps = proxy.crashdumps == null ? null : XenRef.Create(proxy.crashdumps); patches = proxy.patches == null ? null : XenRef.Create(proxy.patches); + updates = proxy.updates == null ? null : XenRef.Create(proxy.updates); PBDs = proxy.PBDs == null ? null : XenRef.Create(proxy.PBDs); host_CPUs = proxy.host_CPUs == null ? null : XenRef.Create(proxy.host_CPUs); cpu_info = proxy.cpu_info == null ? null : Maps.convert_from_proxy_string_string(proxy.cpu_info); @@ -307,6 +311,7 @@ namespace XenAPI result_.crash_dump_sr = (crash_dump_sr != null) ? crash_dump_sr : ""; result_.crashdumps = (crashdumps != null) ? Helper.RefListToStringArray(crashdumps) : new string[] {}; result_.patches = (patches != null) ? Helper.RefListToStringArray(patches) : new string[] {}; + result_.updates = (updates != null) ? Helper.RefListToStringArray(updates) : new string[] {}; result_.PBDs = (PBDs != null) ? Helper.RefListToStringArray(PBDs) : new string[] {}; result_.host_CPUs = (host_CPUs != null) ? Helper.RefListToStringArray(host_CPUs) : new string[] {}; result_.cpu_info = Maps.convert_to_proxy_string_string(cpu_info); @@ -369,6 +374,7 @@ namespace XenAPI crash_dump_sr = Marshalling.ParseRef(table, "crash_dump_sr"); crashdumps = Marshalling.ParseSetRef(table, "crashdumps"); patches = Marshalling.ParseSetRef(table, "patches"); + updates = Marshalling.ParseSetRef(table, "updates"); PBDs = Marshalling.ParseSetRef(table, "PBDs"); host_CPUs = Marshalling.ParseSetRef(table, "host_CPUs"); cpu_info = Maps.convert_from_proxy_string_string(Marshalling.ParseHashTable(table, "cpu_info")); @@ -433,6 +439,7 @@ namespace XenAPI Helper.AreEqual2(this._crash_dump_sr, other._crash_dump_sr) && Helper.AreEqual2(this._crashdumps, other._crashdumps) && Helper.AreEqual2(this._patches, other._patches) && + Helper.AreEqual2(this._updates, other._updates) && Helper.AreEqual2(this._PBDs, other._PBDs) && Helper.AreEqual2(this._host_CPUs, other._host_CPUs) && Helper.AreEqual2(this._cpu_info, other._cpu_info) && @@ -826,6 +833,17 @@ namespace XenAPI return XenRef.Create(session.proxy.host_get_patches(session.uuid, (_host != null) ? _host : "").parse()); } + /// + /// Get the updates field of the given host. + /// First published in . + /// + /// The session + /// The opaque_ref of the given host + public static List> get_updates(Session session, string _host) + { + return XenRef.Create(session.proxy.host_get_updates(session.uuid, (_host != null) ? _host : "").parse()); + } + /// /// Get the PBDs field of the given host. /// First published in XenServer 4.0. @@ -3008,6 +3026,25 @@ namespace XenAPI } private List> _patches; + /// + /// Set of updates + /// First published in . + /// + public virtual List> updates + { + get { return _updates; } + set + { + if (!Helper.AreEqual(value, _updates)) + { + _updates = value; + Changed = true; + NotifyPropertyChanged("updates"); + } + } + } + private List> _updates; + /// /// physical blockdevices /// diff --git a/XenModel/XenAPI/LVHD.cs b/XenModel/XenAPI/LVHD.cs index bf2a8bb06..4d53ce7a2 100644 --- a/XenModel/XenAPI/LVHD.cs +++ b/XenModel/XenAPI/LVHD.cs @@ -148,12 +148,13 @@ namespace XenAPI /// First published in XenServer Dundee. /// /// The session + /// The LVHD Host to upgrade to being thin-provisioned. /// The LVHD SR to upgrade to being thin-provisioned. /// The initial amount of space to allocate to a newly-created VDI in bytes /// The amount of space to allocate to a VDI when it needs to be enlarged in bytes - public static void enable_thin_provisioning(Session session, string _sr, long _initial_allocation, long _allocation_quantum) + public static string enable_thin_provisioning(Session session, string _host, string _sr, long _initial_allocation, long _allocation_quantum) { - session.proxy.lvhd_enable_thin_provisioning(session.uuid, (_sr != null) ? _sr : "", _initial_allocation.ToString(), _allocation_quantum.ToString()).parse(); + return (string)session.proxy.lvhd_enable_thin_provisioning(session.uuid, (_host != null) ? _host : "", (_sr != null) ? _sr : "", _initial_allocation.ToString(), _allocation_quantum.ToString()).parse(); } /// @@ -161,12 +162,13 @@ namespace XenAPI /// First published in XenServer Dundee. /// /// The session + /// The LVHD Host to upgrade to being thin-provisioned. /// The LVHD SR to upgrade to being thin-provisioned. /// The initial amount of space to allocate to a newly-created VDI in bytes /// The amount of space to allocate to a VDI when it needs to be enlarged in bytes - public static XenRef async_enable_thin_provisioning(Session session, string _sr, long _initial_allocation, long _allocation_quantum) + public static XenRef async_enable_thin_provisioning(Session session, string _host, string _sr, long _initial_allocation, long _allocation_quantum) { - return XenRef.Create(session.proxy.async_lvhd_enable_thin_provisioning(session.uuid, (_sr != null) ? _sr : "", _initial_allocation.ToString(), _allocation_quantum.ToString()).parse()); + return XenRef.Create(session.proxy.async_lvhd_enable_thin_provisioning(session.uuid, (_host != null) ? _host : "", (_sr != null) ? _sr : "", _initial_allocation.ToString(), _allocation_quantum.ToString()).parse()); } /// diff --git a/XenModel/XenAPI/Pool_update.cs b/XenModel/XenAPI/Pool_update.cs new file mode 100644 index 000000000..bcd63485c --- /dev/null +++ b/XenModel/XenAPI/Pool_update.cs @@ -0,0 +1,655 @@ +/* + * Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +using System; +using System.Collections; +using System.Collections.Generic; + +using CookComputing.XmlRpc; + + +namespace XenAPI +{ + /// + /// Pool-wide updates to the host software + /// First published in . + /// + public partial class Pool_update : XenObject + { + public Pool_update() + { + } + + public Pool_update(string uuid, + string name_label, + string name_description, + long installation_size, + string key, + List after_apply_guidance, + XenRef vdi, + List> hosts) + { + this.uuid = uuid; + this.name_label = name_label; + this.name_description = name_description; + this.installation_size = installation_size; + this.key = key; + this.after_apply_guidance = after_apply_guidance; + this.vdi = vdi; + this.hosts = hosts; + } + + /// + /// Creates a new Pool_update from a Proxy_Pool_update. + /// + /// + public Pool_update(Proxy_Pool_update proxy) + { + this.UpdateFromProxy(proxy); + } + + public override void UpdateFrom(Pool_update update) + { + uuid = update.uuid; + name_label = update.name_label; + name_description = update.name_description; + installation_size = update.installation_size; + key = update.key; + after_apply_guidance = update.after_apply_guidance; + vdi = update.vdi; + hosts = update.hosts; + } + + internal void UpdateFromProxy(Proxy_Pool_update proxy) + { + uuid = proxy.uuid == null ? null : (string)proxy.uuid; + name_label = proxy.name_label == null ? null : (string)proxy.name_label; + name_description = proxy.name_description == null ? null : (string)proxy.name_description; + installation_size = proxy.installation_size == null ? 0 : long.Parse((string)proxy.installation_size); + key = proxy.key == null ? null : (string)proxy.key; + after_apply_guidance = proxy.after_apply_guidance == null ? null : Helper.StringArrayToEnumList(proxy.after_apply_guidance); + vdi = proxy.vdi == null ? null : XenRef.Create(proxy.vdi); + hosts = proxy.hosts == null ? null : XenRef.Create(proxy.hosts); + } + + public Proxy_Pool_update ToProxy() + { + Proxy_Pool_update result_ = new Proxy_Pool_update(); + result_.uuid = (uuid != null) ? uuid : ""; + result_.name_label = (name_label != null) ? name_label : ""; + result_.name_description = (name_description != null) ? name_description : ""; + result_.installation_size = installation_size.ToString(); + result_.key = (key != null) ? key : ""; + result_.after_apply_guidance = (after_apply_guidance != null) ? Helper.ObjectListToStringArray(after_apply_guidance) : new string[] {}; + result_.vdi = (vdi != null) ? vdi : ""; + result_.hosts = (hosts != null) ? Helper.RefListToStringArray(hosts) : new string[] {}; + return result_; + } + + /// + /// Creates a new Pool_update from a Hashtable. + /// + /// + public Pool_update(Hashtable table) + { + uuid = Marshalling.ParseString(table, "uuid"); + name_label = Marshalling.ParseString(table, "name_label"); + name_description = Marshalling.ParseString(table, "name_description"); + installation_size = Marshalling.ParseLong(table, "installation_size"); + key = Marshalling.ParseString(table, "key"); + after_apply_guidance = Helper.StringArrayToEnumList(Marshalling.ParseStringArray(table, "after_apply_guidance")); + vdi = Marshalling.ParseRef(table, "vdi"); + hosts = Marshalling.ParseSetRef(table, "hosts"); + } + + public bool DeepEquals(Pool_update other) + { + if (ReferenceEquals(null, other)) + return false; + if (ReferenceEquals(this, other)) + return true; + + return Helper.AreEqual2(this._uuid, other._uuid) && + Helper.AreEqual2(this._name_label, other._name_label) && + Helper.AreEqual2(this._name_description, other._name_description) && + Helper.AreEqual2(this._installation_size, other._installation_size) && + Helper.AreEqual2(this._key, other._key) && + Helper.AreEqual2(this._after_apply_guidance, other._after_apply_guidance) && + Helper.AreEqual2(this._vdi, other._vdi) && + Helper.AreEqual2(this._hosts, other._hosts); + } + + public override string SaveChanges(Session session, string opaqueRef, Pool_update server) + { + if (opaqueRef == null) + { + System.Diagnostics.Debug.Assert(false, "Cannot create instances of this type on the server"); + return ""; + } + else + { + throw new InvalidOperationException("This type has no read/write properties"); + } + } + /// + /// Get a record containing the current state of the given pool_update. + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static Pool_update get_record(Session session, string _pool_update) + { + return new Pool_update((Proxy_Pool_update)session.proxy.pool_update_get_record(session.uuid, (_pool_update != null) ? _pool_update : "").parse()); + } + + /// + /// Get a reference to the pool_update instance with the specified UUID. + /// First published in . + /// + /// The session + /// UUID of object to return + public static XenRef get_by_uuid(Session session, string _uuid) + { + return XenRef.Create(session.proxy.pool_update_get_by_uuid(session.uuid, (_uuid != null) ? _uuid : "").parse()); + } + + /// + /// Get all the pool_update instances with the given label. + /// First published in . + /// + /// The session + /// label of object to return + public static List> get_by_name_label(Session session, string _label) + { + return XenRef.Create(session.proxy.pool_update_get_by_name_label(session.uuid, (_label != null) ? _label : "").parse()); + } + + /// + /// Get the uuid field of the given pool_update. + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static string get_uuid(Session session, string _pool_update) + { + return (string)session.proxy.pool_update_get_uuid(session.uuid, (_pool_update != null) ? _pool_update : "").parse(); + } + + /// + /// Get the name/label field of the given pool_update. + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static string get_name_label(Session session, string _pool_update) + { + return (string)session.proxy.pool_update_get_name_label(session.uuid, (_pool_update != null) ? _pool_update : "").parse(); + } + + /// + /// Get the name/description field of the given pool_update. + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static string get_name_description(Session session, string _pool_update) + { + return (string)session.proxy.pool_update_get_name_description(session.uuid, (_pool_update != null) ? _pool_update : "").parse(); + } + + /// + /// Get the installation_size field of the given pool_update. + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static long get_installation_size(Session session, string _pool_update) + { + return long.Parse((string)session.proxy.pool_update_get_installation_size(session.uuid, (_pool_update != null) ? _pool_update : "").parse()); + } + + /// + /// Get the key field of the given pool_update. + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static string get_key(Session session, string _pool_update) + { + return (string)session.proxy.pool_update_get_key(session.uuid, (_pool_update != null) ? _pool_update : "").parse(); + } + + /// + /// Get the after_apply_guidance field of the given pool_update. + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static List get_after_apply_guidance(Session session, string _pool_update) + { + return Helper.StringArrayToEnumList(session.proxy.pool_update_get_after_apply_guidance(session.uuid, (_pool_update != null) ? _pool_update : "").parse()); + } + + /// + /// Get the vdi field of the given pool_update. + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static XenRef get_vdi(Session session, string _pool_update) + { + return XenRef.Create(session.proxy.pool_update_get_vdi(session.uuid, (_pool_update != null) ? _pool_update : "").parse()); + } + + /// + /// Get the hosts field of the given pool_update. + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static List> get_hosts(Session session, string _pool_update) + { + return XenRef.Create(session.proxy.pool_update_get_hosts(session.uuid, (_pool_update != null) ? _pool_update : "").parse()); + } + + /// + /// Introduce update VDI + /// First published in . + /// + /// The session + /// The VDI which contains a software update. + public static XenRef introduce(Session session, string _vdi) + { + return XenRef.Create(session.proxy.pool_update_introduce(session.uuid, (_vdi != null) ? _vdi : "").parse()); + } + + /// + /// Introduce update VDI + /// First published in . + /// + /// The session + /// The VDI which contains a software update. + public static XenRef async_introduce(Session session, string _vdi) + { + return XenRef.Create(session.proxy.async_pool_update_introduce(session.uuid, (_vdi != null) ? _vdi : "").parse()); + } + + /// + /// Execute the precheck stage of the selected update on a host + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + /// The host to run the prechecks on. + public static void precheck(Session session, string _pool_update, string _host) + { + session.proxy.pool_update_precheck(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse(); + } + + /// + /// Execute the precheck stage of the selected update on a host + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + /// The host to run the prechecks on. + public static XenRef async_precheck(Session session, string _pool_update, string _host) + { + return XenRef.Create(session.proxy.async_pool_update_precheck(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse()); + } + + /// + /// Apply the selected update to a host + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + /// The host to apply the update to. + public static void apply(Session session, string _pool_update, string _host) + { + session.proxy.pool_update_apply(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse(); + } + + /// + /// Apply the selected update to a host + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + /// The host to apply the update to. + public static XenRef async_apply(Session session, string _pool_update, string _host) + { + return XenRef.Create(session.proxy.async_pool_update_apply(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse()); + } + + /// + /// Apply the selected update to all hosts in the pool + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static void pool_apply(Session session, string _pool_update) + { + session.proxy.pool_update_pool_apply(session.uuid, (_pool_update != null) ? _pool_update : "").parse(); + } + + /// + /// Apply the selected update to all hosts in the pool + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static XenRef async_pool_apply(Session session, string _pool_update) + { + return XenRef.Create(session.proxy.async_pool_update_pool_apply(session.uuid, (_pool_update != null) ? _pool_update : "").parse()); + } + + /// + /// Removes the update's files from the host + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + /// The host to clean the update from. + public static void clean(Session session, string _pool_update, string _host) + { + session.proxy.pool_update_clean(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse(); + } + + /// + /// Removes the update's files from the host + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + /// The host to clean the update from. + public static XenRef async_clean(Session session, string _pool_update, string _host) + { + return XenRef.Create(session.proxy.async_pool_update_clean(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse()); + } + + /// + /// Removes the update's files from all hosts in the pool, but does not revert the update + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static void pool_clean(Session session, string _pool_update) + { + session.proxy.pool_update_pool_clean(session.uuid, (_pool_update != null) ? _pool_update : "").parse(); + } + + /// + /// Removes the update's files from all hosts in the pool, but does not revert the update + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static XenRef async_pool_clean(Session session, string _pool_update) + { + return XenRef.Create(session.proxy.async_pool_update_pool_clean(session.uuid, (_pool_update != null) ? _pool_update : "").parse()); + } + + /// + /// Removes the update's files from all hosts in the pool, and removes the database entries. But does not revert the update. + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static void destroy(Session session, string _pool_update) + { + session.proxy.pool_update_destroy(session.uuid, (_pool_update != null) ? _pool_update : "").parse(); + } + + /// + /// Removes the update's files from all hosts in the pool, and removes the database entries. But does not revert the update. + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + public static XenRef async_destroy(Session session, string _pool_update) + { + return XenRef.Create(session.proxy.async_pool_update_destroy(session.uuid, (_pool_update != null) ? _pool_update : "").parse()); + } + + /// + /// Attach the pool update VDI + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + /// The host to attach the update to + public static string attach(Session session, string _pool_update, string _host) + { + return (string)session.proxy.pool_update_attach(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse(); + } + + /// + /// Attach the pool update VDI + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + /// The host to attach the update to + public static XenRef async_attach(Session session, string _pool_update, string _host) + { + return XenRef.Create(session.proxy.async_pool_update_attach(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse()); + } + + /// + /// Detach the pool update VDI + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + /// The host to detach the update from + public static void detach(Session session, string _pool_update, string _host) + { + session.proxy.pool_update_detach(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse(); + } + + /// + /// Detach the pool update VDI + /// First published in . + /// + /// The session + /// The opaque_ref of the given pool_update + /// The host to detach the update from + public static XenRef async_detach(Session session, string _pool_update, string _host) + { + return XenRef.Create(session.proxy.async_pool_update_detach(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse()); + } + + /// + /// Return a list of all the pool_updates known to the system. + /// First published in . + /// + /// The session + public static List> get_all(Session session) + { + return XenRef.Create(session.proxy.pool_update_get_all(session.uuid).parse()); + } + + /// + /// Get all the pool_update Records at once, in a single XML RPC call + /// First published in . + /// + /// The session + public static Dictionary, Pool_update> get_all_records(Session session) + { + return XenRef.Create(session.proxy.pool_update_get_all_records(session.uuid).parse()); + } + + /// + /// Unique identifier/object reference + /// + public virtual string uuid + { + get { return _uuid; } + set + { + if (!Helper.AreEqual(value, _uuid)) + { + _uuid = value; + Changed = true; + NotifyPropertyChanged("uuid"); + } + } + } + private string _uuid; + + /// + /// a human-readable name + /// + public virtual string name_label + { + get { return _name_label; } + set + { + if (!Helper.AreEqual(value, _name_label)) + { + _name_label = value; + Changed = true; + NotifyPropertyChanged("name_label"); + } + } + } + private string _name_label; + + /// + /// a notes field containing human-readable description + /// + public virtual string name_description + { + get { return _name_description; } + set + { + if (!Helper.AreEqual(value, _name_description)) + { + _name_description = value; + Changed = true; + NotifyPropertyChanged("name_description"); + } + } + } + private string _name_description; + + /// + /// Size of the update in bytes + /// + public virtual long installation_size + { + get { return _installation_size; } + set + { + if (!Helper.AreEqual(value, _installation_size)) + { + _installation_size = value; + Changed = true; + NotifyPropertyChanged("installation_size"); + } + } + } + private long _installation_size; + + /// + /// GPG key of the update + /// + public virtual string key + { + get { return _key; } + set + { + if (!Helper.AreEqual(value, _key)) + { + _key = value; + Changed = true; + NotifyPropertyChanged("key"); + } + } + } + private string _key; + + /// + /// What the client should do after this update has been applied. + /// + public virtual List after_apply_guidance + { + get { return _after_apply_guidance; } + set + { + if (!Helper.AreEqual(value, _after_apply_guidance)) + { + _after_apply_guidance = value; + Changed = true; + NotifyPropertyChanged("after_apply_guidance"); + } + } + } + private List _after_apply_guidance; + + /// + /// VDI the update was uploaded to + /// + public virtual XenRef vdi + { + get { return _vdi; } + set + { + if (!Helper.AreEqual(value, _vdi)) + { + _vdi = value; + Changed = true; + NotifyPropertyChanged("vdi"); + } + } + } + private XenRef _vdi; + + /// + /// The hosts that have applied this update. + /// + public virtual List> hosts + { + get { return _hosts; } + set + { + if (!Helper.AreEqual(value, _hosts)) + { + _hosts = value; + Changed = true; + NotifyPropertyChanged("hosts"); + } + } + } + private List> _hosts; + } +} diff --git a/XenModel/XenAPI/Proxy.cs b/XenModel/XenAPI/Proxy.cs index 81b53c1fa..1dc5897ef 100644 --- a/XenModel/XenAPI/Proxy.cs +++ b/XenModel/XenAPI/Proxy.cs @@ -1168,6 +1168,130 @@ namespace XenAPI Response pool_patch_get_all_records(string session); + [XmlRpcMethod("pool_update.get_record")] + Response + pool_update_get_record(string session, string _pool_update); + + [XmlRpcMethod("pool_update.get_by_uuid")] + Response + pool_update_get_by_uuid(string session, string _uuid); + + [XmlRpcMethod("pool_update.get_by_name_label")] + Response + pool_update_get_by_name_label(string session, string _label); + + [XmlRpcMethod("pool_update.get_uuid")] + Response + pool_update_get_uuid(string session, string _pool_update); + + [XmlRpcMethod("pool_update.get_name_label")] + Response + pool_update_get_name_label(string session, string _pool_update); + + [XmlRpcMethod("pool_update.get_name_description")] + Response + pool_update_get_name_description(string session, string _pool_update); + + [XmlRpcMethod("pool_update.get_installation_size")] + Response + pool_update_get_installation_size(string session, string _pool_update); + + [XmlRpcMethod("pool_update.get_key")] + Response + pool_update_get_key(string session, string _pool_update); + + [XmlRpcMethod("pool_update.get_after_apply_guidance")] + Response + pool_update_get_after_apply_guidance(string session, string _pool_update); + + [XmlRpcMethod("pool_update.get_vdi")] + Response + pool_update_get_vdi(string session, string _pool_update); + + [XmlRpcMethod("pool_update.get_hosts")] + Response + pool_update_get_hosts(string session, string _pool_update); + + [XmlRpcMethod("pool_update.introduce")] + Response + pool_update_introduce(string session, string _vdi); + + [XmlRpcMethod("Async.pool_update.introduce")] + Response + async_pool_update_introduce(string session, string _vdi); + + [XmlRpcMethod("pool_update.precheck")] + Response + pool_update_precheck(string session, string _pool_update, string _host); + + [XmlRpcMethod("Async.pool_update.precheck")] + Response + async_pool_update_precheck(string session, string _pool_update, string _host); + + [XmlRpcMethod("pool_update.apply")] + Response + pool_update_apply(string session, string _pool_update, string _host); + + [XmlRpcMethod("Async.pool_update.apply")] + Response + async_pool_update_apply(string session, string _pool_update, string _host); + + [XmlRpcMethod("pool_update.pool_apply")] + Response + pool_update_pool_apply(string session, string _pool_update); + + [XmlRpcMethod("Async.pool_update.pool_apply")] + Response + async_pool_update_pool_apply(string session, string _pool_update); + + [XmlRpcMethod("pool_update.clean")] + Response + pool_update_clean(string session, string _pool_update, string _host); + + [XmlRpcMethod("Async.pool_update.clean")] + Response + async_pool_update_clean(string session, string _pool_update, string _host); + + [XmlRpcMethod("pool_update.pool_clean")] + Response + pool_update_pool_clean(string session, string _pool_update); + + [XmlRpcMethod("Async.pool_update.pool_clean")] + Response + async_pool_update_pool_clean(string session, string _pool_update); + + [XmlRpcMethod("pool_update.destroy")] + Response + pool_update_destroy(string session, string _pool_update); + + [XmlRpcMethod("Async.pool_update.destroy")] + Response + async_pool_update_destroy(string session, string _pool_update); + + [XmlRpcMethod("pool_update.attach")] + Response + pool_update_attach(string session, string _pool_update, string _host); + + [XmlRpcMethod("Async.pool_update.attach")] + Response + async_pool_update_attach(string session, string _pool_update, string _host); + + [XmlRpcMethod("pool_update.detach")] + Response + pool_update_detach(string session, string _pool_update, string _host); + + [XmlRpcMethod("Async.pool_update.detach")] + Response + async_pool_update_detach(string session, string _pool_update, string _host); + + [XmlRpcMethod("pool_update.get_all")] + Response + pool_update_get_all(string session); + + [XmlRpcMethod("pool_update.get_all_records")] + Response + pool_update_get_all_records(string session); + [XmlRpcMethod("VM.get_record")] Response vm_get_record(string session, string _vm); @@ -1504,6 +1628,10 @@ namespace XenAPI Response vm_get_has_vendor_device(string session, string _vm); + [XmlRpcMethod("VM.get_requires_reboot")] + Response + vm_get_requires_reboot(string session, string _vm); + [XmlRpcMethod("VM.set_name_label")] Response vm_set_name_label(string session, string _vm, string _label); @@ -1904,6 +2032,14 @@ namespace XenAPI Response async_vm_set_memory_limits(string session, string _vm, string _static_min, string _static_max, string _dynamic_min, string _dynamic_max); + [XmlRpcMethod("VM.set_memory")] + Response + vm_set_memory(string session, string _vm, string _value); + + [XmlRpcMethod("Async.VM.set_memory")] + Response + async_vm_set_memory(string session, string _vm, string _value); + [XmlRpcMethod("VM.set_memory_target_live")] Response vm_set_memory_target_live(string session, string _vm, string _target); @@ -2856,6 +2992,10 @@ namespace XenAPI Response host_get_patches(string session, string _host); + [XmlRpcMethod("host.get_updates")] + Response + host_get_updates(string session, string _host); + [XmlRpcMethod("host.get_PBDs")] Response host_get_pbds(string session, string _host); @@ -4084,6 +4224,14 @@ namespace XenAPI Response async_vif_unplug_force(string session, string _vif); + [XmlRpcMethod("VIF.move")] + Response + vif_move(string session, string _vif, string _network); + + [XmlRpcMethod("Async.VIF.move")] + Response + async_vif_move(string session, string _vif, string _network); + [XmlRpcMethod("VIF.set_locking_mode")] Response vif_set_locking_mode(string session, string _vif, string _value); @@ -5190,11 +5338,11 @@ namespace XenAPI [XmlRpcMethod("LVHD.enable_thin_provisioning")] Response - lvhd_enable_thin_provisioning(string session, string _sr, string _initial_allocation, string _allocation_quantum); + lvhd_enable_thin_provisioning(string session, string _host, string _sr, string _initial_allocation, string _allocation_quantum); [XmlRpcMethod("Async.LVHD.enable_thin_provisioning")] Response - async_lvhd_enable_thin_provisioning(string session, string _sr, string _initial_allocation, string _allocation_quantum); + async_lvhd_enable_thin_provisioning(string session, string _host, string _sr, string _initial_allocation, string _allocation_quantum); [XmlRpcMethod("LVHD.get_all_records")] Response @@ -7012,6 +7160,19 @@ namespace XenAPI public Object other_config; } + [XmlRpcMissingMapping(MappingAction.Ignore)] + public class Proxy_Pool_update + { + public string uuid; + public string name_label; + public string name_description; + public string installation_size; + public string key; + public string [] after_apply_guidance; + public string vdi; + public string [] hosts; + } + [XmlRpcMissingMapping(MappingAction.Ignore)] public class Proxy_VM { @@ -7092,6 +7253,7 @@ namespace XenAPI public string generation_id; public string hardware_platform_version; public bool has_vendor_device; + public bool requires_reboot; } [XmlRpcMissingMapping(MappingAction.Ignore)] @@ -7200,6 +7362,7 @@ namespace XenAPI public string crash_dump_sr; public string [] crashdumps; public string [] patches; + public string [] updates; public string [] PBDs; public string [] host_CPUs; public Object cpu_info; diff --git a/XenModel/XenAPI/Relation.cs b/XenModel/XenAPI/Relation.cs index 9ccd8622d..685432eb5 100644 --- a/XenModel/XenAPI/Relation.cs +++ b/XenModel/XenAPI/Relation.cs @@ -146,6 +146,7 @@ namespace XenAPI relations.Add(typeof(Proxy_Host), new Relation[] { new Relation("PGPUs", "PGPU", "host"), new Relation("PCIs", "PCI", "host"), + new Relation("updates", "pool_update", "hosts"), new Relation("patches", "host_patch", "host"), new Relation("crashdumps", "host_crashdump", "host"), new Relation("host_CPUs", "host_cpu", "host"), diff --git a/XenModel/XenAPI/VIF.cs b/XenModel/XenAPI/VIF.cs index c84c022d6..88c4a35c0 100644 --- a/XenModel/XenAPI/VIF.cs +++ b/XenModel/XenAPI/VIF.cs @@ -834,6 +834,30 @@ namespace XenAPI return XenRef.Create(session.proxy.async_vif_unplug_force(session.uuid, (_vif != null) ? _vif : "").parse()); } + /// + /// Move the specified VIF to the specified network, even while the VM is running + /// First published in . + /// + /// The session + /// The opaque_ref of the given vif + /// The network to move it to + public static void move(Session session, string _vif, string _network) + { + session.proxy.vif_move(session.uuid, (_vif != null) ? _vif : "", (_network != null) ? _network : "").parse(); + } + + /// + /// Move the specified VIF to the specified network, even while the VM is running + /// First published in . + /// + /// The session + /// The opaque_ref of the given vif + /// The network to move it to + public static XenRef async_move(Session session, string _vif, string _network) + { + return XenRef.Create(session.proxy.async_vif_move(session.uuid, (_vif != null) ? _vif : "", (_network != null) ? _network : "").parse()); + } + /// /// Set the locking mode for this VIF /// First published in XenServer 6.1. diff --git a/XenModel/XenAPI/VM.cs b/XenModel/XenAPI/VM.cs index c1efe6037..b59f71207 100644 --- a/XenModel/XenAPI/VM.cs +++ b/XenModel/XenAPI/VM.cs @@ -124,7 +124,8 @@ namespace XenAPI long version, string generation_id, long hardware_platform_version, - bool has_vendor_device) + bool has_vendor_device, + bool requires_reboot) { this.uuid = uuid; this.allowed_operations = allowed_operations; @@ -203,6 +204,7 @@ namespace XenAPI this.generation_id = generation_id; this.hardware_platform_version = hardware_platform_version; this.has_vendor_device = has_vendor_device; + this.requires_reboot = requires_reboot; } /// @@ -293,6 +295,7 @@ namespace XenAPI generation_id = update.generation_id; hardware_platform_version = update.hardware_platform_version; has_vendor_device = update.has_vendor_device; + requires_reboot = update.requires_reboot; } internal void UpdateFromProxy(Proxy_VM proxy) @@ -374,6 +377,7 @@ namespace XenAPI generation_id = proxy.generation_id == null ? null : (string)proxy.generation_id; hardware_platform_version = proxy.hardware_platform_version == null ? 0 : long.Parse((string)proxy.hardware_platform_version); has_vendor_device = (bool)proxy.has_vendor_device; + requires_reboot = (bool)proxy.requires_reboot; } public Proxy_VM ToProxy() @@ -456,6 +460,7 @@ namespace XenAPI result_.generation_id = (generation_id != null) ? generation_id : ""; result_.hardware_platform_version = hardware_platform_version.ToString(); result_.has_vendor_device = has_vendor_device; + result_.requires_reboot = requires_reboot; return result_; } @@ -542,6 +547,7 @@ namespace XenAPI generation_id = Marshalling.ParseString(table, "generation_id"); hardware_platform_version = Marshalling.ParseLong(table, "hardware_platform_version"); has_vendor_device = Marshalling.ParseBool(table, "has_vendor_device"); + requires_reboot = Marshalling.ParseBool(table, "requires_reboot"); } public bool DeepEquals(VM other, bool ignoreCurrentOperations) @@ -629,7 +635,8 @@ namespace XenAPI Helper.AreEqual2(this._version, other._version) && Helper.AreEqual2(this._generation_id, other._generation_id) && Helper.AreEqual2(this._hardware_platform_version, other._hardware_platform_version) && - Helper.AreEqual2(this._has_vendor_device, other._has_vendor_device); + Helper.AreEqual2(this._has_vendor_device, other._has_vendor_device) && + Helper.AreEqual2(this._requires_reboot, other._requires_reboot); } public override string SaveChanges(Session session, string opaqueRef, VM server) @@ -1743,6 +1750,17 @@ namespace XenAPI return (bool)session.proxy.vm_get_has_vendor_device(session.uuid, (_vm != null) ? _vm : "").parse(); } + /// + /// Get the requires_reboot field of the given VM. + /// First published in . + /// + /// The session + /// The opaque_ref of the given vm + public static bool get_requires_reboot(Session session, string _vm) + { + return (bool)session.proxy.vm_get_requires_reboot(session.uuid, (_vm != null) ? _vm : "").parse(); + } + /// /// Set the name/label field of the given VM. /// First published in XenServer 4.0. @@ -2957,6 +2975,30 @@ namespace XenAPI return XenRef.Create(session.proxy.async_vm_set_memory_limits(session.uuid, (_vm != null) ? _vm : "", _static_min.ToString(), _static_max.ToString(), _dynamic_min.ToString(), _dynamic_max.ToString()).parse()); } + /// + /// Set the memory allocation of this VM. Sets all of memory_static_max, memory_dynamic_min, and memory_dynamic_max to the given value, and leaves memory_static_min untouched. + /// First published in . + /// + /// The session + /// The opaque_ref of the given vm + /// The new memory allocation (bytes). + public static void set_memory(Session session, string _vm, long _value) + { + session.proxy.vm_set_memory(session.uuid, (_vm != null) ? _vm : "", _value.ToString()).parse(); + } + + /// + /// Set the memory allocation of this VM. Sets all of memory_static_max, memory_dynamic_min, and memory_dynamic_max to the given value, and leaves memory_static_min untouched. + /// First published in . + /// + /// The session + /// The opaque_ref of the given vm + /// The new memory allocation (bytes). + public static XenRef async_set_memory(Session session, string _vm, long _value) + { + return XenRef.Create(session.proxy.async_vm_set_memory(session.uuid, (_vm != null) ? _vm : "", _value.ToString()).parse()); + } + /// /// Set the memory target for a running VM /// First published in XenServer 4.0. @@ -5302,5 +5344,24 @@ namespace XenAPI } } private bool _has_vendor_device; + + /// + /// Indicates whether a VM requires a reboot in order to update its configuration, e.g. its memory allocation. + /// First published in . + /// + public virtual bool requires_reboot + { + get { return _requires_reboot; } + set + { + if (!Helper.AreEqual(value, _requires_reboot)) + { + _requires_reboot = value; + Changed = true; + NotifyPropertyChanged("requires_reboot"); + } + } + } + private bool _requires_reboot; } } diff --git a/XenModel/XenAPI/update_after_apply_guidance.cs b/XenModel/XenAPI/update_after_apply_guidance.cs new file mode 100644 index 000000000..ce52d0574 --- /dev/null +++ b/XenModel/XenAPI/update_after_apply_guidance.cs @@ -0,0 +1,62 @@ +/* + * Copyright (c) Citrix Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1) Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +using System; +using System.Collections.Generic; + + +namespace XenAPI +{ + public enum update_after_apply_guidance + { + restartHVM, restartPV, restartHost, restartXAPI, unknown + } + + public static class update_after_apply_guidance_helper + { + public static string ToString(update_after_apply_guidance x) + { + switch (x) + { + case update_after_apply_guidance.restartHVM: + return "restartHVM"; + case update_after_apply_guidance.restartPV: + return "restartPV"; + case update_after_apply_guidance.restartHost: + return "restartHost"; + case update_after_apply_guidance.restartXAPI: + return "restartXAPI"; + default: + return "unknown"; + } + } + } +} diff --git a/XenModel/XenModel.csproj b/XenModel/XenModel.csproj index 076eefa8a..fa0377d51 100644 --- a/XenModel/XenModel.csproj +++ b/XenModel/XenModel.csproj @@ -352,8 +352,10 @@ + + From 49a586430e93b63dc75c398b5782df37e2958751 Mon Sep 17 00:00:00 2001 From: Callum McIntyre Date: Wed, 31 Aug 2016 10:42:09 +0100 Subject: [PATCH 2/3] CP-17848: Rename UpdateType enum NewSuppPack to ISO, since for this ticket we will handle all updates as ISOs --- .../Wizards/PatchingWizard/PatchingWizard_ModePage.cs | 4 ++-- .../PatchingWizard/PatchingWizard_PatchingPage.cs | 10 +++++----- .../PatchingWizard/PatchingWizard_SelectPatchPage.cs | 8 ++++---- .../PatchingWizard/PatchingWizard_SelectServers.cs | 4 ++-- .../PatchingWizard/PatchingWizard_UploadPage.cs | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_ModePage.cs b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_ModePage.cs index f98370489..9d4733898 100644 --- a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_ModePage.cs +++ b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_ModePage.cs @@ -98,14 +98,14 @@ namespace XenAdmin.Wizards.PatchingWizard AutomaticRadioButton.Enabled = true; AutomaticRadioButton.Checked = true; break; - case UpdateType.NewSuppPack: + case UpdateType.ISO: AutomaticRadioButton.Enabled = true; AutomaticRadioButton.Checked = true; textBoxLog.Text = PatchingWizardModeGuidanceBuilder.ModeSuppPack(SelectedServers); break; } - if (SelectedUpdateType == UpdateType.NewSuppPack || SelectedServers.Exists(server => !Helpers.ClearwaterOrGreater(server))) + if (SelectedUpdateType == UpdateType.ISO || SelectedServers.Exists(server => !Helpers.ClearwaterOrGreater(server))) { removeUpdateFileCheckBox.Checked = false; removeUpdateFileCheckBox.Visible = false; diff --git a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_PatchingPage.cs b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_PatchingPage.cs index b884b48dd..0708b3536 100644 --- a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_PatchingPage.cs +++ b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_PatchingPage.cs @@ -135,13 +135,13 @@ namespace XenAdmin.Wizards.PatchingWizard textBoxLog.Text = ManualTextInstructions; List actions = new List(); - if (SelectedUpdateType != UpdateType.NewSuppPack) + if (SelectedUpdateType != UpdateType.ISO) actionManualMode = new ApplyPatchAction(new List { Patch }, SelectedServers); else actionManualMode = new InstallSupplementalPackAction(SuppPackVdis, false); actions.Add(actionManualMode); - if (RemoveUpdateFile && SelectedUpdateType != UpdateType.NewSuppPack) + if (RemoveUpdateFile && SelectedUpdateType != UpdateType.ISO) { foreach (Pool pool in SelectedPools) { @@ -166,7 +166,7 @@ namespace XenAdmin.Wizards.PatchingWizard foreach (Pool pool in SelectedPools) { Pool_patch poolPatch = null; - if (SelectedUpdateType != UpdateType.NewSuppPack) + if (SelectedUpdateType != UpdateType.ISO) { List poolPatches = new List(pool.Connection.Cache.Pool_patches); poolPatch = poolPatches.Find(delegate(Pool_patch otherPatch) @@ -313,7 +313,7 @@ namespace XenAdmin.Wizards.PatchingWizard private List CompileActionList(Host host, Pool_patch patch) { - if (SelectedUpdateType == UpdateType.NewSuppPack) + if (SelectedUpdateType == UpdateType.ISO) return CompileSuppPackActionList(host); List actions = new List(); @@ -405,7 +405,7 @@ namespace XenAdmin.Wizards.PatchingWizard { List actions = new List(); - if (SelectedUpdateType != UpdateType.NewSuppPack || SuppPackVdis == null || !SuppPackVdis.ContainsKey(host)) + if (SelectedUpdateType != UpdateType.ISO || SuppPackVdis == null || !SuppPackVdis.ContainsKey(host)) return actions; List> runningVMs = RunningVMs(host); diff --git a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_SelectPatchPage.cs b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_SelectPatchPage.cs index 942d1492e..b5f70ba50 100644 --- a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_SelectPatchPage.cs +++ b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_SelectPatchPage.cs @@ -184,7 +184,7 @@ namespace XenAdmin.Wizards.PatchingWizard if (fileName.EndsWith(UpdateExtension)) SelectedUpdateType = UpdateType.NewRetail; else if (fileName.EndsWith(".iso")) - SelectedUpdateType = UpdateType.NewSuppPack; + SelectedUpdateType = UpdateType.ISO; else SelectedUpdateType = UpdateType.Existing; } @@ -401,13 +401,13 @@ namespace XenAdmin.Wizards.PatchingWizard { if (downloadUpdateRadioButton.Checked) { - return SelectedUpdateType == UpdateType.NewRetail || SelectedUpdateType == UpdateType.NewSuppPack + return SelectedUpdateType == UpdateType.NewRetail || SelectedUpdateType == UpdateType.ISO ? ((PatchGridViewRow)dataGridViewPatches.SelectedRows[0]).PathPatch : null; } else if (selectFromDiskRadioButton.Checked) { - return SelectedUpdateType == UpdateType.NewRetail || SelectedUpdateType == UpdateType.NewSuppPack + return SelectedUpdateType == UpdateType.NewRetail || SelectedUpdateType == UpdateType.ISO ? fileNameTextBox.Text : null; } @@ -675,5 +675,5 @@ namespace XenAdmin.Wizards.PatchingWizard #endregion } - public enum UpdateType { NewRetail, Existing, NewSuppPack} + public enum UpdateType { NewRetail, Existing, ISO} } diff --git a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_SelectServers.cs b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_SelectServers.cs index 3e4510414..865b7bf5e 100644 --- a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_SelectServers.cs +++ b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_SelectServers.cs @@ -243,7 +243,7 @@ namespace XenAdmin.Wizards.PatchingWizard return; } - if (type != UpdateType.NewSuppPack && !host.CanApplyHotfixes) + if (type != UpdateType.ISO && !host.CanApplyHotfixes) { row.Enabled = false; row.Cells[3].ToolTipText = Messages.PATCHINGWIZARD_SELECTSERVERPAGE_HOST_UNLICENSED; @@ -256,7 +256,7 @@ namespace XenAdmin.Wizards.PatchingWizard case UpdateType.Existing: disableNotApplicableHosts(row, selectedHosts, host); break; - case UpdateType.NewSuppPack: + case UpdateType.ISO: if (!host.CanInstallSuppPack) { row.Enabled = false; diff --git a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_UploadPage.cs b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_UploadPage.cs index af85c34b3..5247b5ab4 100644 --- a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_UploadPage.cs +++ b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_UploadPage.cs @@ -176,7 +176,7 @@ namespace XenAdmin.Wizards.PatchingWizard SelectedExistingPatch); } break; - case UpdateType.NewSuppPack: + case UpdateType.ISO: if (CanUploadUpdateOnHost(SelectedNewPatchPath, selectedServer)) { action = new UploadSupplementalPackAction( From d302815b66f493ec613cd91761ddfb9ccafa19ca Mon Sep 17 00:00:00 2001 From: Callum McIntyre Date: Fri, 9 Sep 2016 12:02:59 +0100 Subject: [PATCH 3/3] CP-17848: Commit to hand over. PatchingWizard_UploadPage.cs contains new code to introduce a Pool_update, PatchingWizard_PatchingPage.cs to apply and clean it. --- .../PatchingWizardModeGuidanceBuilder.cs | 2 +- .../PatchingWizard_PatchingPage.cs | 37 ++++++++++ .../PatchingWizard_UploadPage.cs | 39 ++++++++++ XenModel/Network/Cache.cs | 1 + XenModel/XenAPI/Pool_update.cs | 72 ------------------- XenModel/XenAPI/Proxy.cs | 24 ------- XenModel/XenAPI/Relation.cs | 5 +- 7 files changed, 82 insertions(+), 98 deletions(-) diff --git a/XenAdmin/Wizards/PatchingWizard/PatchingWizardModeGuidanceBuilder.cs b/XenAdmin/Wizards/PatchingWizard/PatchingWizardModeGuidanceBuilder.cs index 346246786..934a28347 100644 --- a/XenAdmin/Wizards/PatchingWizard/PatchingWizardModeGuidanceBuilder.cs +++ b/XenAdmin/Wizards/PatchingWizard/PatchingWizardModeGuidanceBuilder.cs @@ -51,7 +51,7 @@ namespace XenAdmin.Wizards.PatchingWizard private static string Build(List servers, List guidance) { - return Build(servers, guidance); + return Build(servers, guidance, new Dictionary()); } private static string Build(List servers, List guidance, Dictionary LivePatchCodesByHost) diff --git a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_PatchingPage.cs b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_PatchingPage.cs index 0708b3536..acb41894c 100644 --- a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_PatchingPage.cs +++ b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_PatchingPage.cs @@ -177,6 +177,31 @@ namespace XenAdmin.Wizards.PatchingWizard }); } + if (SelectedUpdateType == UpdateType.ISO && AllServersElyOrGreater()) + { + // new ISOs + foreach (var hostVdiPair in SuppPackVdis) + { + var host = hostVdiPair.Key; + var vdi = hostVdiPair.Value; + + var poolUpdate = Pool_update.introduce(pool.Connection.Session, vdi.opaque_ref); + try + { + + Pool_update.apply(pool.Connection.Session, poolUpdate.opaque_ref, host.opaque_ref); + } + catch (Failure F) + { + + } + finally + { + Pool_update.pool_clean(host.Connection.Session, poolUpdate); + } + } + } + List poolHosts = new List(pool.Connection.Cache.Hosts); Host master = SelectedServers.Find(host => host.IsMaster() && poolHosts.Contains(host)); if (master != null && poolPatch != null && poolPatch.AppliedOn(master) == DateTime.MaxValue) @@ -422,6 +447,18 @@ namespace XenAdmin.Wizards.PatchingWizard #endregion + private bool AllServersElyOrGreater() + { + foreach (var server in SelectedServers) + { + if (!Helpers.ElyOrGreater(server.Connection)) + { + return false; + } + } + return true; + } + private void FinishedWithErrors(Exception exception) { labelTitle.Text = string.Format(Messages.UPDATE_WAS_NOT_COMPLETED, GetUpdateName()); diff --git a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_UploadPage.cs b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_UploadPage.cs index 5247b5ab4..1cfedeacf 100644 --- a/XenAdmin/Wizards/PatchingWizard/PatchingWizard_UploadPage.cs +++ b/XenAdmin/Wizards/PatchingWizard/PatchingWizard_UploadPage.cs @@ -47,6 +47,12 @@ namespace XenAdmin.Wizards.PatchingWizard get { return _patch; } } + private Pool_update _poolUpdate; + public Pool_update PoolUpdate + { + get { return _poolUpdate; } + } + public Dictionary AllDownloadedPatches = new Dictionary(); public readonly List AllCreatedSuppPackVdis = new List(); public Dictionary SuppPackVdis = new Dictionary(); @@ -423,6 +429,11 @@ namespace XenAdmin.Wizards.PatchingWizard SuppPackVdis[vdiRef.Key] = action.Connection.Resolve(vdiRef.Value); AllCreatedSuppPackVdis.AddRange(SuppPackVdis.Values.Where(vdi => !AllCreatedSuppPackVdis.Contains(vdi))); AddToUploadedUpdates(SelectedNewPatchPath, master); + + if (AllServersElyOrGreater()) + { + set_pool_update(); + } } if (action is DownloadAndUnzipXenServerPatchAction) { @@ -439,6 +450,34 @@ namespace XenAdmin.Wizards.PatchingWizard }); } + private void set_pool_update() + { + if (SelectedUpdateType == UpdateType.ISO && AllServersElyOrGreater()) + { + // new ISOs + foreach (var hostVdiPair in SuppPackVdis) + { + var host = hostVdiPair.Key; + var vdi = hostVdiPair.Value; + + var poolUpdate = Pool_update.introduce(host.Connection.Session, vdi.opaque_ref); + _poolUpdate = host.Connection.Resolve(poolUpdate); + } + } + } + + private bool AllServersElyOrGreater() + { + foreach (var server in SelectedServers) + { + if (!Helpers.ElyOrGreater(server.Connection)) + { + return false; + } + } + return true; + } + private void multipleAction_Completed(object sender) { var action = sender as AsyncAction; diff --git a/XenModel/Network/Cache.cs b/XenModel/Network/Cache.cs index 9212539da..97b56d82b 100644 --- a/XenModel/Network/Cache.cs +++ b/XenModel/Network/Cache.cs @@ -67,6 +67,7 @@ namespace XenAdmin.Network private readonly ChangeableDictionary, PIF_metrics> _pif_metrics = new ChangeableDictionary, PIF_metrics>(); private readonly ChangeableDictionary, Pool> _pool = new ChangeableDictionary, Pool>(); private readonly ChangeableDictionary, Pool_patch> _pool_patch = new ChangeableDictionary, Pool_patch>(); + private readonly ChangeableDictionary, Pool_update> _pool_update = new ChangeableDictionary, Pool_update>(); private readonly ChangeableDictionary, Role> _role = new ChangeableDictionary, Role>(); private readonly ChangeableDictionary, SM> _sm = new ChangeableDictionary, SM>(); private readonly ChangeableDictionary, SR> _sr = new ChangeableDictionary, SR>(); diff --git a/XenModel/XenAPI/Pool_update.cs b/XenModel/XenAPI/Pool_update.cs index bcd63485c..82c6221f8 100644 --- a/XenModel/XenAPI/Pool_update.cs +++ b/XenModel/XenAPI/Pool_update.cs @@ -372,30 +372,6 @@ namespace XenAPI return XenRef.Create(session.proxy.async_pool_update_pool_apply(session.uuid, (_pool_update != null) ? _pool_update : "").parse()); } - /// - /// Removes the update's files from the host - /// First published in . - /// - /// The session - /// The opaque_ref of the given pool_update - /// The host to clean the update from. - public static void clean(Session session, string _pool_update, string _host) - { - session.proxy.pool_update_clean(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse(); - } - - /// - /// Removes the update's files from the host - /// First published in . - /// - /// The session - /// The opaque_ref of the given pool_update - /// The host to clean the update from. - public static XenRef async_clean(Session session, string _pool_update, string _host) - { - return XenRef.Create(session.proxy.async_pool_update_clean(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse()); - } - /// /// Removes the update's files from all hosts in the pool, but does not revert the update /// First published in . @@ -440,54 +416,6 @@ namespace XenAPI return XenRef.Create(session.proxy.async_pool_update_destroy(session.uuid, (_pool_update != null) ? _pool_update : "").parse()); } - /// - /// Attach the pool update VDI - /// First published in . - /// - /// The session - /// The opaque_ref of the given pool_update - /// The host to attach the update to - public static string attach(Session session, string _pool_update, string _host) - { - return (string)session.proxy.pool_update_attach(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse(); - } - - /// - /// Attach the pool update VDI - /// First published in . - /// - /// The session - /// The opaque_ref of the given pool_update - /// The host to attach the update to - public static XenRef async_attach(Session session, string _pool_update, string _host) - { - return XenRef.Create(session.proxy.async_pool_update_attach(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse()); - } - - /// - /// Detach the pool update VDI - /// First published in . - /// - /// The session - /// The opaque_ref of the given pool_update - /// The host to detach the update from - public static void detach(Session session, string _pool_update, string _host) - { - session.proxy.pool_update_detach(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse(); - } - - /// - /// Detach the pool update VDI - /// First published in . - /// - /// The session - /// The opaque_ref of the given pool_update - /// The host to detach the update from - public static XenRef async_detach(Session session, string _pool_update, string _host) - { - return XenRef.Create(session.proxy.async_pool_update_detach(session.uuid, (_pool_update != null) ? _pool_update : "", (_host != null) ? _host : "").parse()); - } - /// /// Return a list of all the pool_updates known to the system. /// First published in . diff --git a/XenModel/XenAPI/Proxy.cs b/XenModel/XenAPI/Proxy.cs index 1dc5897ef..ed0b5869c 100644 --- a/XenModel/XenAPI/Proxy.cs +++ b/XenModel/XenAPI/Proxy.cs @@ -1244,14 +1244,6 @@ namespace XenAPI Response async_pool_update_pool_apply(string session, string _pool_update); - [XmlRpcMethod("pool_update.clean")] - Response - pool_update_clean(string session, string _pool_update, string _host); - - [XmlRpcMethod("Async.pool_update.clean")] - Response - async_pool_update_clean(string session, string _pool_update, string _host); - [XmlRpcMethod("pool_update.pool_clean")] Response pool_update_pool_clean(string session, string _pool_update); @@ -1268,22 +1260,6 @@ namespace XenAPI Response async_pool_update_destroy(string session, string _pool_update); - [XmlRpcMethod("pool_update.attach")] - Response - pool_update_attach(string session, string _pool_update, string _host); - - [XmlRpcMethod("Async.pool_update.attach")] - Response - async_pool_update_attach(string session, string _pool_update, string _host); - - [XmlRpcMethod("pool_update.detach")] - Response - pool_update_detach(string session, string _pool_update, string _host); - - [XmlRpcMethod("Async.pool_update.detach")] - Response - async_pool_update_detach(string session, string _pool_update, string _host); - [XmlRpcMethod("pool_update.get_all")] Response pool_update_get_all(string session); diff --git a/XenModel/XenAPI/Relation.cs b/XenModel/XenAPI/Relation.cs index 685432eb5..4942ce32b 100644 --- a/XenModel/XenAPI/Relation.cs +++ b/XenModel/XenAPI/Relation.cs @@ -143,10 +143,13 @@ namespace XenAPI new Relation("snapshots", "VM", "snapshot_of"), }); + relations.Add(typeof(Proxy_Pool_update), new Relation[] { + new Relation("hosts", "host", "updates"), + }); + relations.Add(typeof(Proxy_Host), new Relation[] { new Relation("PGPUs", "PGPU", "host"), new Relation("PCIs", "PCI", "host"), - new Relation("updates", "pool_update", "hosts"), new Relation("patches", "host_patch", "host"), new Relation("crashdumps", "host_crashdump", "host"), new Relation("host_CPUs", "host_cpu", "host"),