forked from microsoft/winget-cli
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathFindDscPackageStateMachine.cs
More file actions
186 lines (167 loc) · 7.16 KB
/
FindDscPackageStateMachine.cs
File metadata and controls
186 lines (167 loc) · 7.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// -----------------------------------------------------------------------------
// <copyright file="FindDscPackageStateMachine.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation. Licensed under the MIT License.
// </copyright>
// -----------------------------------------------------------------------------
namespace Microsoft.Management.Configuration.Processor.DSCv3.Helpers
{
using System;
/// <summary>
/// Provides the state machine that decides which DSC package to use.
/// </summary>
internal class FindDscPackageStateMachine
{
private const string StableDscPackageFamilyName = "Microsoft.DesiredStateConfiguration_8wekyb3d8bbwe";
private const string PreviewDscPackageFamilyName = "Microsoft.DesiredStateConfiguration-Preview_8wekyb3d8bbwe";
private readonly Version minimumStableVersion = new Version(3, 1);
private readonly Version minimumPreviewVersion = new Version(3, 1, 7);
private State currentState = State.Initial;
private string? dscExecutablePath;
/// <summary>
/// A state of the state machine.
/// </summary>
public enum State
{
/// <summary>
/// The initial state.
/// </summary>
Initial,
/// <summary>
/// A stable installation attempt has been made.
/// </summary>
StableInstallAttempted,
/// <summary>
/// A preview installation attempt has been made.
/// </summary>
PreviewInstallAttempted,
/// <summary>
/// The state machine is terminated.
/// </summary>
Terminated,
}
/// <summary>
/// A transition of the state machine.
/// </summary>
public enum Transition
{
/// <summary>
/// Transition to a terminated state with DSC being found.
/// </summary>
Found,
/// <summary>
/// Attempt to install the stable version of DSC.
/// </summary>
InstallStable,
/// <summary>
/// Attempt to install the preview version of DSC.
/// </summary>
InstallPreview,
/// <summary>
/// Transition to a terminated state with DSC *not* being found.
/// </summary>
NotFound,
}
/// <summary>
/// Gets the file path of the DSC (Desired State Configuration) executable.
/// </summary>
public string? DscExecutablePath
{
get
{
if (this.currentState == State.Terminated)
{
return this.dscExecutablePath;
}
else
{
PackageInformation stableInformation = new PackageInformation(StableDscPackageFamilyName);
if (stableInformation.IsInstalled && stableInformation.Version >= this.minimumStableVersion)
{
return stableInformation.AliasPath;
}
else
{
PackageInformation previewInformation = new PackageInformation(PreviewDscPackageFamilyName);
if (previewInformation.IsInstalled && previewInformation.Version >= this.minimumPreviewVersion)
{
return previewInformation.AliasPath;
}
else
{
return null;
}
}
}
}
}
/// <summary>
/// Determines the next state transition based on the current context or conditions.
/// </summary>
/// <returns>
/// A string representing the name of the next transition.
/// </returns>
public Transition DetermineNextTransition()
{
switch (this.currentState)
{
case State.Initial:
{
PackageInformation stableInformation = new PackageInformation(StableDscPackageFamilyName);
if (stableInformation.IsInstalled && stableInformation.Version >= this.minimumStableVersion)
{
return this.Found(stableInformation);
}
else
{
this.currentState = State.StableInstallAttempted;
return Transition.InstallStable;
}
}
case State.StableInstallAttempted:
{
PackageInformation stableInformation = new PackageInformation(StableDscPackageFamilyName);
if (stableInformation.IsInstalled && stableInformation.Version >= this.minimumStableVersion)
{
return this.Found(stableInformation);
}
else
{
PackageInformation previewInformation = new PackageInformation(PreviewDscPackageFamilyName);
if (previewInformation.IsInstalled && previewInformation.Version >= this.minimumPreviewVersion)
{
return this.Found(previewInformation);
}
else
{
this.currentState = State.PreviewInstallAttempted;
return Transition.InstallPreview;
}
}
}
case State.PreviewInstallAttempted:
{
PackageInformation previewInformation = new PackageInformation(PreviewDscPackageFamilyName);
if (previewInformation.IsInstalled && previewInformation.Version >= this.minimumPreviewVersion)
{
return this.Found(previewInformation);
}
else
{
this.currentState = State.Terminated;
return Transition.NotFound;
}
}
case State.Terminated:
return this.DscExecutablePath == null ? Transition.NotFound : Transition.Found;
default:
throw new InvalidOperationException($"Unexpected state: {this.currentState}");
}
}
private Transition Found(PackageInformation packageInformation)
{
this.dscExecutablePath = packageInformation.AliasPath;
this.currentState = State.Terminated;
return Transition.Found;
}
}
}