예제 #1
0
        public Dictionary <string, string> ParseSource(ref string[] paths, ref string filter, Dictionary <string, string> commandlineOptions)
        {
            var pathshyperv = new List <string>();
            var ret         = new Dictionary <string, string>();

            if (paths != null)
            {
                if (paths.Contains(m_HyperVPathAllRegExp, StringComparer.OrdinalIgnoreCase))
                {
                    if (Utility.Utility.IsClientWindows)
                    {
                        pathshyperv = new HyperVUtility().GetHyperVGuests().Select(x => string.Format(@"%HYPERV%\{0}", x.ID)).ToList();
                    }
                }
                else
                {
                    pathshyperv = paths.Where(x => Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)).ToList();
                }

                paths = paths.Where(x => !x.Equals(m_HyperVPathAllRegExp, StringComparison.OrdinalIgnoreCase) && !Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)).ToArray();
            }

            if (!string.IsNullOrEmpty(filter))
            {
                var filters = filter.Split(new string[] { System.IO.Path.PathSeparator.ToString() }, StringSplitOptions.RemoveEmptyEntries);

                var filtersInclude = filters.Where(x => x.StartsWith("+") && Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)).Select(x => x.Substring(1)).ToList();
                var filtersExclude = filters.Where(x => x.StartsWith("-") && Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)).Select(x => x.Substring(1)).ToList();

                var remainingfilters = filters.Where(x => !Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase)).ToArray();
                filter = string.Join(System.IO.Path.PathSeparator.ToString(), remainingfilters);

                pathshyperv = pathshyperv.Union(filtersInclude).Except(filtersExclude).ToList();
            }

            pathshyperv = pathshyperv.Select(x => Regex.Match(x, m_HyperVGuidRegExp).Value).ToList();

            if (pathshyperv.Count != 0 && Utility.Utility.IsClientWindows && (!commandlineOptions.Keys.Contains("snapshot-policy") || commandlineOptions["snapshot-policy"] != "required"))
            {
                Logging.Log.WriteMessage("Snapshot strategy have to be set to \"required\" when backuping Hyper-V virtual machines. Changing to \"required\" to continue.", Logging.LogMessageType.Information);
                ret["snapshot-policy"] = "required";
            }

            if (pathshyperv.Count != 0)
            {
                if (Utility.Utility.IsClientWindows)
                {
                    ret[OPTION_SOURCE] = string.Join(System.IO.Path.PathSeparator.ToString(), pathshyperv);
                }
                else
                {
                    Logging.Log.WriteMessage("Hyper-V backup works only on Windows OS.", Logging.LogMessageType.Warning);
                }
            }

            return(ret);
        }
예제 #2
0
파일: HyperV.cs 프로젝트: yuhisa/duplicati
        private void RealGET(string key, RequestInfo info)
        {
            var hypervUtility = new HyperVUtility();

            if (!hypervUtility.IsHyperVInstalled || !new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator))
            {
                info.OutputOK(new string[0]);
                return;
            }

            try
            {
                if (string.IsNullOrEmpty(key))
                {
                    hypervUtility.QueryHyperVGuestsInfo();
                    info.OutputOK(hypervUtility.Guests.Select(x => new { id = x.ID, name = x.Name }).ToList());
                }
                else
                {
                    hypervUtility.QueryHyperVGuestsInfo(true);
                    var foundVMs = hypervUtility.Guests.FindAll(x => x.ID.Equals(new Guid(key)));

                    if (foundVMs.Count == 1)
                    {
                        info.OutputOK(foundVMs[0].DataPaths.Select(x => new { text = x, id = x, cls = "folder", iconCls = "x-tree-icon-leaf", check = "false", leaf = "true" }).ToList());
                    }
                    else
                    {
                        info.ReportClientError(string.Format("Cannot find VM with ID {0}.", key), System.Net.HttpStatusCode.NotFound);
                    }
                }
            }
            catch (Exception ex)
            {
                info.ReportServerError("Failed to enumerate Hyper-V virtual machines: " + ex.Message);
            }
        }
예제 #3
0
        public void GET(string key, RequestInfo info)
        {
            var hypervUtility = new HyperVUtility();

            if (!hypervUtility.IsHyperVInstalled)
            {
                info.OutputOK();
            }

            try
            {
                if (string.IsNullOrEmpty(key))
                {
                    hypervUtility.QueryHyperVGuestsInfo();
                    info.OutputOK(hypervUtility.Guests.Select(x => new { id = x.ID, name = x.Name }).ToList());
                }
                else
                {
                    hypervUtility.QueryHyperVGuestsInfo(true);
                    var foundVMs = hypervUtility.Guests.FindAll(x => x.ID.Equals(new Guid(key)));

                    if (foundVMs.Count == 1)
                    {
                        info.OutputOK(foundVMs[0].DataPaths.Select(x => new { text = x, id = x, cls = "folder", iconCls = "x-tree-icon-leaf", check = "false", leaf = "true" }).ToList());
                    }
                    else
                    {
                        info.ReportClientError(string.Format("Cannot find VM with ID {0}.", key));
                    }
                }
            }
            catch (Exception ex)
            {
                info.ReportClientError("Failed to enumerate Hyper-V virtual machines: " + ex.Message);
            }
        }
예제 #4
0
        private Dictionary <string, string> RealParseSourcePaths(ref string[] paths, ref string filter, Dictionary <string, string> commandlineOptions)
        {
            var changedOptions = new Dictionary <string, string>();
            var filtersInclude = new List <string>();
            var filtersExclude = new List <string>();

            if (!string.IsNullOrEmpty(filter))
            {
                var filters = filter.Split(new string[] { System.IO.Path.PathSeparator.ToString() }, StringSplitOptions.RemoveEmptyEntries);

                filtersInclude = filters.Where(x => x.StartsWith("+") && Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
                                 .Select(x => Regex.Match(x.Substring(1), m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant).Groups[1].Value).ToList();
                filtersExclude = filters.Where(x => x.StartsWith("-") && Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
                                 .Select(x => Regex.Match(x.Substring(1), m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant).Groups[1].Value).ToList();

                var remainingfilters = filters.Where(x => !Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)).ToArray();
                filter = string.Join(System.IO.Path.PathSeparator.ToString(), remainingfilters);
            }

            var hypervUtility = new HyperVUtility();

            if (paths == null || !ContainFilesForBackup(paths) || !hypervUtility.IsHyperVInstalled)
            {
                return(changedOptions);
            }

            if (commandlineOptions.Keys.Contains("vss-exclude-writers"))
            {
                var excludedWriters = commandlineOptions["vss-exclude-writers"].Split(';').Where(x => !string.IsNullOrWhiteSpace(x) && x.Trim().Length > 0).Select(x => new Guid(x)).ToArray();

                if (excludedWriters.Contains(HyperVUtility.HyperVWriterGuid))
                {
                    Logging.Log.WriteMessage(string.Format("Excluded writers for VSS cannot contain Hyper-V writer when backuping Hyper-V virtual machines. Removing \"{0}\" to continue", HyperVUtility.HyperVWriterGuid.ToString()), Logging.LogMessageType.Warning);
                    changedOptions["vss-exclude-writers"] = string.Join(";", excludedWriters.Where(x => x != HyperVUtility.HyperVWriterGuid));
                }
            }

            if (!commandlineOptions.Keys.Contains("snapshot-policy") || !commandlineOptions["snapshot-policy"].Equals("required", StringComparison.OrdinalIgnoreCase))
            {
                Logging.Log.WriteMessage("Snapshot strategy have to be set to \"required\" when backuping Hyper-V virtual machines. Changing to \"required\" to continue", Logging.LogMessageType.Warning);
                changedOptions["snapshot-policy"] = "required";
            }

            if (!hypervUtility.IsVSSWriterSupported)
            {
                Logging.Log.WriteMessage("This is client version of Windows. Hyper-V VSS writer is present only on Server version. Backup will continue, but will be crash consistent only in opposite to application consistent in Server version", Logging.LogMessageType.Warning);
            }

            Logging.Log.WriteMessage("Starting to gather Hyper-V information", Logging.LogMessageType.Information);
            hypervUtility.QueryHyperVGuestsInfo(true);
            Logging.Log.WriteMessage(string.Format("Found {0} virtual machines on Hyper-V", hypervUtility.Guests.Count), Logging.LogMessageType.Information);

            foreach (var guest in hypervUtility.Guests)
            {
                Logging.Log.WriteMessage(string.Format("Found VM name {0}, ID {1}, files {2}", guest.Name, guest.ID, string.Join(";", guest.DataPaths)), Logging.LogMessageType.Profiling);
            }

            List <HyperVGuest> guestsForBackup = new List <HyperVGuest>();

            if (paths.Contains(m_HyperVPathAllRegExp, StringComparer.OrdinalIgnoreCase))
            {
                guestsForBackup = hypervUtility.Guests;
            }
            else
            {
                foreach (var guestID in paths.Where(x => Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
                         .Select(x => Regex.Match(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant).Groups[1].Value).ToArray())
                {
                    var foundGuest = hypervUtility.Guests.Where(x => x.ID == new Guid(guestID));

                    if (foundGuest.Count() != 1)
                    {
                        throw new Duplicati.Library.Interface.UserInformationException(string.Format("Hyper-V guest specified in source with ID {0} cannot be found", guestID));
                    }

                    guestsForBackup.Add(foundGuest.First());
                }
            }

            if (filtersInclude.Count > 0)
            {
                foreach (var guestID in filtersInclude)
                {
                    var foundGuest = hypervUtility.Guests.Where(x => x.ID == new Guid(guestID));

                    if (foundGuest.Count() != 1)
                    {
                        throw new Duplicati.Library.Interface.UserInformationException(string.Format("Hyper-V guest specified in include filter with ID {0} cannot be found", guestID));
                    }

                    guestsForBackup.Add(foundGuest.First());
                    Logging.Log.WriteMessage(string.Format("Including {0} based on including filters", guestID), Logging.LogMessageType.Information);
                }
            }

            guestsForBackup = guestsForBackup.Distinct().ToList();

            if (filtersExclude.Count > 0)
            {
                foreach (var guestID in filtersExclude)
                {
                    var foundGuest = guestsForBackup.Where(x => x.ID == new Guid(guestID));

                    if (foundGuest.Count() != 1)
                    {
                        throw new Duplicati.Library.Interface.UserInformationException(string.Format("Hyper-V guest specified in exclude filter with ID {0} cannot be found", guestID));
                    }

                    guestsForBackup.Remove(foundGuest.First());
                    Logging.Log.WriteMessage(string.Format("Excluding {0} based on excluding filters", guestID), Logging.LogMessageType.Information);
                }
            }

            var pathsForBackup = new List <string>(paths);
            var filterhandler  = new Utility.FilterExpression(
                filter.Split(new string[] { System.IO.Path.PathSeparator.ToString() }, StringSplitOptions.RemoveEmptyEntries).Where(x => x.StartsWith("-")).Select(x => x.Substring(1)).ToList());

            foreach (var guestForBackup in guestsForBackup)
            {
                foreach (var pathForBackup in guestForBackup.DataPaths)
                {
                    bool            bResult;
                    Utility.IFilter matchFilter;

                    if (!filterhandler.Matches(pathForBackup, out bResult, out matchFilter))
                    {
                        Logging.Log.WriteMessage(string.Format("For VM {0} - adding {1}", guestForBackup.Name, pathForBackup), Logging.LogMessageType.Information);
                        pathsForBackup.Add(pathForBackup);
                    }
                    else
                    {
                        Logging.Log.WriteMessage(string.Format("Excluding {0} based on excluding filters", pathForBackup), Logging.LogMessageType.Information);
                    }
                }
            }

            paths = pathsForBackup.Where(x => !x.Equals(m_HyperVPathAllRegExp, StringComparison.OrdinalIgnoreCase) && !Regex.IsMatch(x, m_HyperVPathGuidRegExp, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
                    .Distinct(Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToArray();

            return(changedOptions);
        }