winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

ProcessorSettings.cs (8905B)


      1 // -----------------------------------------------------------------------------
      2 // <copyright file="ProcessorSettings.cs" company="Microsoft Corporation">
      3 //     Copyright (c) Microsoft Corporation. Licensed under the MIT License.
      4 // </copyright>
      5 // -----------------------------------------------------------------------------
      6 
      7 namespace Microsoft.Management.Configuration.Processor.DSCv3.Helpers
      8 {
      9     using System;
     10     using System.Collections.Generic;
     11     using System.IO;
     12     using System.Text;
     13     using Microsoft.Management.Configuration.Processor.DSCv3.Model;
     14     using Microsoft.Management.Configuration.Processor.Helpers;
     15 
     16     /// <summary>
     17     /// Contains settings for the DSC v3 processor components to share.
     18     /// </summary>
     19     internal class ProcessorSettings
     20     {
     21         private readonly object dscV3Lock = new ();
     22         private readonly object defaultPathLock = new ();
     23 
     24         private FindDscPackageStateMachine dscPackageStateMachine = new ();
     25         private IDSCv3? dscV3 = null;
     26         private string? defaultPath = null;
     27 
     28         private Dictionary<string, ResourceDetails> resourceDetailsDictionary = new ();
     29 
     30         /// <summary>
     31         /// Gets or sets the path to the DSC v3 executable.
     32         /// </summary>
     33         public string? DscExecutablePath { get; set; }
     34 
     35         /// <summary>
     36         /// Gets the path to the DSC v3 executable.
     37         /// </summary>
     38         public string EffectiveDscExecutablePath
     39         {
     40             get
     41             {
     42                 if (this.DscExecutablePath != null)
     43                 {
     44                     return this.DscExecutablePath;
     45                 }
     46 
     47                 lock (this.defaultPathLock)
     48                 {
     49                     if (this.defaultPath != null)
     50                     {
     51                         return this.defaultPath;
     52                     }
     53                 }
     54 
     55                 string? localDefaultPath = this.GetFoundDscExecutablePath();
     56 
     57                 if (localDefaultPath == null)
     58                 {
     59                     throw new FileNotFoundException("Could not find DSC v3 executable path.");
     60                 }
     61 
     62                 lock (this.defaultPathLock)
     63                 {
     64                     if (this.defaultPath == null)
     65                     {
     66                         this.defaultPath = localDefaultPath;
     67                     }
     68 
     69                     return this.defaultPath;
     70                 }
     71             }
     72         }
     73 
     74         /// <summary>
     75         /// Gets an object for interacting with the DSC executable at EffectiveDscExecutablePath.
     76         /// </summary>
     77         [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1623:Property summary documentation should match accessors", Justification = "Set is only provided for tests.")]
     78         public IDSCv3 DSCv3
     79         {
     80             get
     81             {
     82                 lock (this.dscV3Lock)
     83                 {
     84                     if (this.dscV3 == null)
     85                     {
     86                         this.dscV3 = IDSCv3.Create(this);
     87                     }
     88 
     89                     return this.dscV3;
     90                 }
     91             }
     92 
     93 #if !AICLI_DISABLE_TEST_HOOKS
     94             set
     95             {
     96                 lock (this.dscV3Lock)
     97                 {
     98                     this.dscV3 = value;
     99                 }
    100             }
    101 #endif
    102         }
    103 
    104         /// <summary>
    105         /// Gets or sets the diagnostics sink to use.
    106         /// </summary>
    107         public IDiagnosticsSink? DiagnosticsSink { get; set; } = null;
    108 
    109         /// <summary>
    110         /// Gets or sets a value indicating whether the processor should produce more verbose output.
    111         /// </summary>
    112         public bool DiagnosticTraceEnabled { get; set; } = false;
    113 
    114         /// <summary>
    115         /// Find the DSC v3 executable.
    116         /// </summary>
    117         /// <returns>The full path to the dsc.exe executable, or null if not found.</returns>
    118         public string? GetFoundDscExecutablePath()
    119         {
    120             return this.dscPackageStateMachine.DscExecutablePath;
    121         }
    122 
    123         /// <summary>
    124         /// Invokes a step in the DSC search state machine.
    125         /// </summary>
    126         /// <returns>The transition to take in the state machine.</returns>
    127         public FindDscPackageStateMachine.Transition PumpFindDscStateMachine()
    128         {
    129             return this.dscPackageStateMachine.DetermineNextTransition();
    130         }
    131 
    132         /// <summary>
    133         /// Create a deep copy of this settings object.
    134         /// </summary>
    135         /// <returns>A deep copy of this object.</returns>
    136         public ProcessorSettings Clone()
    137         {
    138             ProcessorSettings result = new ProcessorSettings();
    139 
    140             result.resourceDetailsDictionary = this.resourceDetailsDictionary;
    141             result.DiagnosticsSink = this.DiagnosticsSink;
    142             result.DscExecutablePath = this.DscExecutablePath;
    143             result.DiagnosticTraceEnabled = this.DiagnosticTraceEnabled;
    144 #if !AICLI_DISABLE_TEST_HOOKS
    145             result.dscV3 = this.DSCv3;
    146 #endif
    147 
    148             return result;
    149         }
    150 
    151         /// <summary>
    152         /// Gets a string representation of this object.
    153         /// </summary>
    154         /// <returns>A string representation of this object.</returns>
    155         public override string ToString()
    156         {
    157             StringBuilder sb = new StringBuilder();
    158 
    159             sb.Append("EffectiveDscExecutablePath: ");
    160             sb.AppendLine(this.EffectiveDscExecutablePath);
    161 
    162             sb.Append("DiagnosticTraceLevel: ");
    163             sb.Append(this.DiagnosticTraceEnabled);
    164 
    165             return sb.ToString();
    166         }
    167 
    168         /// <summary>
    169         /// Gets the ResourceDetails for a configuration unit.
    170         /// </summary>
    171         /// <param name="configurationUnitInternal">The configuration unit to find details for.</param>
    172         /// <param name="detailFlags">The level of detail to get.</param>
    173         /// <returns>The ResourceDetails for the unit, or null if not found.</returns>
    174         public ResourceDetails? GetResourceDetails(ConfigurationUnitInternal configurationUnitInternal, ConfigurationUnitDetailFlags detailFlags)
    175         {
    176             ResourceDetails? result = null;
    177             bool inDictionary = false;
    178 
    179             lock (this.resourceDetailsDictionary)
    180             {
    181                 inDictionary = this.resourceDetailsDictionary.TryGetValue(configurationUnitInternal.QualifiedName, out result);
    182             }
    183 
    184             if (result == null)
    185             {
    186                 result = new ResourceDetails(configurationUnitInternal.QualifiedName);
    187             }
    188 
    189             result.EnsureDetails(this, detailFlags);
    190 
    191             if (result.Exists)
    192             {
    193                 if (!inDictionary)
    194                 {
    195                     lock (this.resourceDetailsDictionary)
    196                     {
    197                         this.resourceDetailsDictionary.Add(configurationUnitInternal.QualifiedName, result);
    198                     }
    199                 }
    200 
    201                 return result;
    202             }
    203             else
    204             {
    205                 return null;
    206             }
    207         }
    208 
    209         /// <summary>
    210         /// Gets all ResourceDetails matching find options.
    211         /// </summary>
    212         /// <param name="findOptions">The find options.</param>
    213         /// <returns>A list of ResourceDetails.</returns>
    214         public List<ResourceDetails> FindAllResourceDetails(FindUnitProcessorsOptions findOptions)
    215         {
    216             List<ResourceDetails> result = new List<ResourceDetails>();
    217 
    218             var resourceItemList = this.DSCv3.GetAllResources(ProcessorRunSettings.CreateFromFindUnitProcessorsOptions(findOptions));
    219 
    220             foreach (var item in resourceItemList)
    221             {
    222                 ResourceDetails? details = null;
    223                 bool inDictionary = false;
    224                 lock (this.resourceDetailsDictionary)
    225                 {
    226                     inDictionary = this.resourceDetailsDictionary.TryGetValue(item.Type, out details);
    227                 }
    228 
    229                 if (details == null)
    230                 {
    231                     details = new ResourceDetails(item.Type);
    232                 }
    233 
    234                 if (!details.Exists)
    235                 {
    236                     details.SetResourceListItem(item);
    237                 }
    238 
    239                 details.EnsureDetails(this, findOptions.UnitDetailFlags);
    240 
    241                 if (!inDictionary)
    242                 {
    243                     lock (this.resourceDetailsDictionary)
    244                     {
    245                         this.resourceDetailsDictionary.Add(item.Type, details);
    246                     }
    247                 }
    248 
    249                 result.Add(details);
    250             }
    251 
    252             return result;
    253         }
    254     }
    255 }