Skip to content

Commit 88f5f45

Browse files
committed
Merging with upstream
2 parents 269f3d7 + 682ea87 commit 88f5f45

File tree

33 files changed

+548
-445
lines changed

33 files changed

+548
-445
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ src/Publish/
33
src/Package/
44
drop/
55

6+
# external tools
7+
tools/CLU/7zip/
8+
69
obj
710
TestResults
811
*.orig

clu-getstart.md

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
# Work on CLU cmdlets
1+
# Work on CLU cmdlets
22

33
## Prerequsites
44

55
* Visual Studio 2015 RTM with ASP.NET. For details, check out the [installation doc](http://docs.asp.net/en/latest/getting-started/installing-on-windows.html).
66

77
Note, after done, run `dnvm list` command to check the 'coreclr' runtime is installed with right version of `1.0.0-rc1-final`. If not, run `dnvm install 1.0.0-rc1-final -r coreclr -a x64 -p`. Remember always use `-p` flag, so the selection can persist.
88

9-
* Get the latest dotnet from "https://azureclu.blob.core.windows.net/tools/dotnet-win-x64.latest.zip", unzip, then add its bin folder to the PATH
9+
* Get the latest dotnet from "https://azureclu.blob.core.windows.net/tools/dotnet-win-x64.latest.zip", unzip, then add its bin folder to the PATH. NOTE: With this version of dotnet, the path to dotnet.exe must not contain any spaces.
1010

1111
## Project Artifacts
1212

@@ -25,7 +25,7 @@ CLUPackages require some additional files to direct generation of indexing, and
2525
| ------------- |:-------------:|
2626
| CommandAssemblies | File name of cmdlets assembly(ies) |
2727
| NounPrefix | ‘AzureRm’ The part of the cmdlet noun to remove in clu commands|
28-
| NounFirst | if true, the verb comes at the end of the command (e.g. az resource get)|
28+
| NounFirst | if true, the verb comes at the end of the command (e.g. az resource ls)|
2929

3030
* \<modulename\>.nuspec.template, which contains nuspec format metadata about the package – the base temaplate is in tools\clu\Microsoft.Azure.Commands.nuspec.template. Here are the special fields defined in this template:
3131
* %PackageId% - replace with the module name (Microsoft.Azure.Commands.\<rp-name\>)
@@ -60,19 +60,26 @@ There is also `<repo-root>\tools\CLU\SetupEnv.bat` which is a windows batch wrap
6060

6161
To test on osx/linux boxes, do #1, open `<repo-root>\drop\clurun`, copy the flavor folder to your target machine, and run the "az.sh" inside. Make sure set execution permission using `chmod +x az.sh clurun`
6262

63-
(All of those are subject to change, contact yugangw or adxsdkdev for any questions)
63+
### Nightly Builds
64+
You can also consume tarballs from the nightly build. The latest drops are available at:
65+
- ubuntu: [download](https://azurecludrops.blob.core.windows.net/drops/ubuntu.14.04-x64.latest.tar.gz)
66+
- osx: [download](https://azurecludrops.blob.core.windows.net/drops/osx.10.10-x64.latest.tar.gz)
67+
- windows: [download](https://azurecludrops.blob.core.windows.net/drops/win7-x64.latest.tar.gz)
68+
69+
70+
(All of those are subject to change, contact adxsdkdev for any questions)
6471

6572
## Quick introductions on cmdlets
66-
* Run commands using the ‘az’ prefix, cmdlet nouns, and cmdlet verbs, for example, `az env get` maps to the cmdlet `Get-AzureRmEnvironment`
67-
* Cmdlet parameters use the double dash (--) so for example, getting a subscription with a particular name would be: `az subscription get –-SubscriptionName “name of subscription"`
73+
* Run commands using the ‘az’ prefix, cmdlet nouns, and cmdlet verbs, for example, `az env ls` maps to the cmdlet `Get-AzureRmEnvironment`
74+
* Cmdlet parameters use the double dash (--) so for example, getting a subscription with a particular name would be: `az subscription ls –-SubscriptionName “name of subscription"`
6875
* To log in, 3 options
69-
* login interactively using device flow, this is the only option for msa account or any org-id with 2fa enforced, example: `az account add`
70-
* login with user and password, this works on org-id w/o 2fa enforced, example: `az account add --Username [email protected] --Password password1`
71-
* login as service principal. Example: `az account add --ServicePrincipal --TenantId <tenant> --ApplicationId <id> --Secret <secret>`
76+
* login interactively using device flow, this is the only option for msa account or any org-id with 2fa enforced, example: `az login`
77+
* login with user and password, this works on org-id w/o 2fa enforced, example: `az login --Username [email protected] --Password password1`
78+
* login as service principal. Example: `az login --ServicePrincipal --TenantId <tenant> --ApplicationId <id> --Secret <secret>`
7279
* Piping between cmdlets should work the same way that Powerhell piping works
73-
```az subscription get --SubscriptionName | az context set```
80+
```az subscription ls --SubscriptionName | az context set```
7481
* You can capture piped output using redirection to a file - the result will be the json serialization of the output object.
75-
```az subscription get > subscriptions.json```
82+
```az subscription ls > subscriptions.json```
7683
* You can use file input to a parameter using '@' notation:
7784
```az command --param1 @file1.json```
7885
Reads input from file1.json and attempts to deserialize the .net object that is the Parameter type for ```param1```

dockerfiles/latest-trusty/Dockerfile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
FROM ubuntu:14.04
2+
3+
# all in one RUN to produce less, smaller layers
4+
RUN bash -c "\
5+
sudo apt-get -qqy update && \
6+
sudo apt-get -qqy upgrade && \
7+
sudo apt-get -qqy install wget libicu-dev libunwind8-dev libcurl3 libcurl4-gnutls-dev && \
8+
sudo apt-get clean && \
9+
sudo rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*"
10+
11+
RUN bash -c "\
12+
mkdir /opt/az && \
13+
cd /opt/az && \
14+
wget https://azurecludrops.blob.core.windows.net/drops/ubuntu.14.04-x64.latest.tar.gz && \
15+
tar xvzf ubuntu.14.04-x64.latest.tar.gz"
16+
17+
ENV PATH "$PATH:/opt/az/ubuntu.14.04-x64/"
18+
19+
WORKDIR /opt/az/ubuntu.14.04-x64/

src/CLU/CLUCoreCLR.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Sync", "Sync\Sync.xproj", "
6666
EndProject
6767
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Azure.Commands.Network", "Microsoft.Azure.Commands.Network\Microsoft.Azure.Commands.Network.xproj", "{C4DCF4EA-62E7-431E-ADB5-16FD6CFEA5D6}"
6868
EndProject
69+
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.CLU.Test", "Microsoft.CLU.Test\Microsoft.CLU.Test.xproj", "{13C34370-51A4-4726-81B8-BE0996FC9CF0}"
70+
EndProject
6971
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "StaticAnalysis", "StaticAnalysis\StaticAnalysis.xproj", "{84F9573A-449E-4159-8493-EFD6C3C8F0A5}"
7072
EndProject
7173
Global
@@ -168,6 +170,10 @@ Global
168170
{C4DCF4EA-62E7-431E-ADB5-16FD6CFEA5D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
169171
{C4DCF4EA-62E7-431E-ADB5-16FD6CFEA5D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
170172
{C4DCF4EA-62E7-431E-ADB5-16FD6CFEA5D6}.Release|Any CPU.Build.0 = Release|Any CPU
173+
{13C34370-51A4-4726-81B8-BE0996FC9CF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
174+
{13C34370-51A4-4726-81B8-BE0996FC9CF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
175+
{13C34370-51A4-4726-81B8-BE0996FC9CF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
176+
{13C34370-51A4-4726-81B8-BE0996FC9CF0}.Release|Any CPU.Build.0 = Release|Any CPU
171177
{84F9573A-449E-4159-8493-EFD6C3C8F0A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
172178
{84F9573A-449E-4159-8493-EFD6C3C8F0A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
173179
{84F9573A-449E-4159-8493-EFD6C3C8F0A5}.Release|Any CPU.ActiveCfg = Release|Any CPU

src/CLU/Commands.Common.Authentication/Models/AzureRMProfile.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,21 @@ public AzureRMProfile(IDataStore dataStore)
7171
[JsonIgnore]
7272
public string ProfilePath { get; private set; }
7373

74+
/// <summary>
75+
/// When set to true, collects telemetry information.
76+
/// </summary>
77+
public bool? IsTelemetryCollectionEnabled { get; set; }
78+
7479
private void Load(string path)
7580
{
7681
this.ProfilePath = path;
7782
if (_dataStore.FileExists(ProfilePath))
7883
{
7984
string contents = _dataStore.ReadFileAsText(ProfilePath);
80-
AzureRMProfile profile = JsonConvert.DeserializeObject<AzureRMProfile>(contents);
81-
Debug.Assert(profile != null);
82-
this.Context = profile.Context;
83-
this.Environments = profile.Environments;
85+
JsonConvert.PopulateObject(contents, this);
8486
}
8587
}
8688

87-
8889
/// <summary>
8990
/// Writes profile to the disk it was opened from disk.
9091
/// </summary>

src/CLU/Commands.Common/AzureDataCmdlet.cs

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -60,64 +60,11 @@ public AzureRMProfile RMProfile
6060
get { return GetSessionVariableValue<PSAzureProfile>(AzurePowerShell.ProfileVariable, null); }
6161
}
6262

63-
protected override void SaveDataCollectionProfile()
63+
protected override bool IsTelemetryCollectionEnabled
6464
{
65-
if (_dataCollectionProfile == null)
66-
{
67-
InitializeDataCollectionProfile();
68-
}
69-
70-
string fileFullPath = Path.Combine(AzurePowerShell.ProfileDirectory, AzurePSDataCollectionProfile.DefaultFileName);
71-
var contents = JsonConvert.SerializeObject(_dataCollectionProfile);
72-
if (!DataStore.DirectoryExists(AzurePowerShell.ProfileDirectory))
73-
{
74-
DataStore.CreateDirectory(AzurePowerShell.ProfileDirectory);
75-
}
76-
DataStore.WriteFile(fileFullPath, contents);
77-
WriteWarning(string.Format(Resources.DataCollectionSaveFileInformation, fileFullPath));
78-
}
79-
80-
protected override void PromptForDataCollectionProfileIfNotExists()
81-
{
82-
// Initialize it from the environment variable or profile file.
83-
InitializeDataCollectionProfile();
84-
85-
if (!_dataCollectionProfile.EnableAzureDataCollection.HasValue && CheckIfInteractive())
65+
get
8666
{
87-
WriteWarning(Resources.DataCollectionPrompt);
88-
89-
const double timeToWaitInSeconds = 60;
90-
var status = string.Format(Resources.DataCollectionConfirmTime, timeToWaitInSeconds);
91-
ProgressRecord record = new ProgressRecord(0, Resources.DataCollectionActivity, status);
92-
93-
var startTime = DateTime.Now;
94-
var endTime = DateTime.Now;
95-
//double elapsedSeconds = 0;
96-
97-
//while (!this.Host.UI.RawUI.KeyAvailable && elapsedSeconds < timeToWaitInSeconds)
98-
//{
99-
// Thread.Sleep(TimeSpan.FromMilliseconds(10));
100-
// endTime = DateTime.Now;
101-
102-
// elapsedSeconds = (endTime - startTime).TotalSeconds;
103-
// record.PercentComplete = ((int) elapsedSeconds*100/(int) timeToWaitInSeconds);
104-
// WriteProgress(record);
105-
//}
106-
107-
bool enabled = false;
108-
//if (this.Host.UI.RawUI.KeyAvailable)
109-
//{
110-
// KeyInfo keyInfo =
111-
// this.Host.UI.RawUI.ReadKey(ReadKeyOptions.NoEcho | ReadKeyOptions.AllowCtrlC |
112-
// ReadKeyOptions.IncludeKeyDown);
113-
// enabled = (keyInfo.Character == 'Y' || keyInfo.Character == 'y');
114-
//}
115-
116-
_dataCollectionProfile.EnableAzureDataCollection = enabled;
117-
118-
WriteWarning(enabled ? Resources.DataCollectionConfirmYes : Resources.DataCollectionConfirmNo);
119-
120-
SaveDataCollectionProfile();
67+
return false;
12168
}
12269
}
12370

src/CLU/Commands.Common/AzurePSCmdlet.cs

Lines changed: 12 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,7 @@ namespace Microsoft.Azure.Commands.Utilities.Common
4141
public abstract class AzurePSCmdlet : PSCmdlet, IDisposable
4242
{
4343
protected readonly ConcurrentQueue<string> _debugMessages;
44-
45-
4644
private DebugStreamTraceListener _adalListener;
47-
protected static AzurePSDataCollectionProfile _dataCollectionProfile = null;
4845
protected static string _errorRecordFolderPath = null;
4946
protected const string _fileTimeStampSuffixFormat = "yyyy-MM-dd-THH-mm-ss-fff";
5047
protected string _clientRequestId = Guid.NewGuid().ToString();
@@ -56,7 +53,8 @@ public abstract class AzurePSCmdlet : PSCmdlet, IDisposable
5653

5754
protected AzurePSQoSEvent QosEvent;
5855

59-
protected virtual bool IsUsageMetricEnabled {
56+
protected virtual bool IsUsageMetricEnabled
57+
{
6058
get { return true; }
6159
}
6260

@@ -67,9 +65,9 @@ protected virtual bool IsErrorMetricEnabled
6765

6866
/// <summary>
6967
/// Gets the PowerShell module name used for user agent header.
70-
/// By default uses "Azurepowershell"
68+
/// By default uses "AzureCLU"
7169
/// </summary>
72-
protected virtual string ModuleName { get { return "AzurePowershell"; } }
70+
protected virtual string ModuleName { get { return "AzureCLU"; } }
7371

7472
/// <summary>
7573
/// Gets PowerShell module version used for user agent header.
@@ -158,128 +156,21 @@ protected virtual void SetSessionVariable<T>(string name, T value) where T : cla
158156
DataStore.WriteFile(variablePath, JsonConvert.SerializeObject(value));
159157
}
160158
}
161-
/// <summary>
162-
/// Initialize the data collection profile
163-
/// </summary>
164-
protected static void InitializeDataCollectionProfile()
165-
{
166-
if (_dataCollectionProfile != null && _dataCollectionProfile.EnableAzureDataCollection.HasValue)
167-
{
168-
return;
169-
}
170-
171-
// Get the value of the environment variable for Azure PS data collection setting.
172-
string value = Environment.GetEnvironmentVariable(AzurePSDataCollectionProfile.EnvironmentVariableName);
173-
if (!string.IsNullOrWhiteSpace(value))
174-
{
175-
if (string.Equals(value, bool.FalseString, StringComparison.OrdinalIgnoreCase))
176-
{
177-
// Disable data collection only if it is explicitly set to 'false'.
178-
_dataCollectionProfile = new AzurePSDataCollectionProfile(true);
179-
}
180-
else if (string.Equals(value, bool.TrueString, StringComparison.OrdinalIgnoreCase))
181-
{
182-
// Enable data collection only if it is explicitly set to 'true'.
183-
_dataCollectionProfile = new AzurePSDataCollectionProfile(false);
184-
}
185-
}
186-
187-
// If the environment value is null or empty, or not correctly set, try to read the setting from default file location.
188-
if (_dataCollectionProfile == null)
189-
{
190-
string fileFullPath = Path.Combine(AzurePowerShell.ProfileDirectory, AzurePSDataCollectionProfile.DefaultFileName);
191-
if (File.Exists(fileFullPath))
192-
{
193-
string contents = File.ReadAllText(fileFullPath);
194-
_dataCollectionProfile = JsonConvert.DeserializeObject<AzurePSDataCollectionProfile>(contents);
195-
}
196-
}
197-
198-
// If the environment variable or file content is not set, create a new profile object.
199-
if (_dataCollectionProfile == null)
200-
{
201-
_dataCollectionProfile = new AzurePSDataCollectionProfile();
202-
}
203-
}
204-
205-
/// <summary>
206-
/// Get the data collection profile
207-
/// </summary>
208-
protected static AzurePSDataCollectionProfile GetDataCollectionProfile()
209-
{
210-
if (_dataCollectionProfile == null)
211-
{
212-
InitializeDataCollectionProfile();
213-
}
214-
215-
return _dataCollectionProfile;
216-
}
217159

218160
/// <summary>
219161
/// Check whether the data collection is opted in from user
220162
/// </summary>
221163
/// <returns>true if allowed</returns>
222-
public static bool IsDataCollectionAllowed()
164+
protected abstract bool IsTelemetryCollectionEnabled
223165
{
224-
//TODO: CLU - remove before final release
225-
return true;
226-
227-
//if (_dataCollectionProfile != null &&
228-
// _dataCollectionProfile.EnableAzureDataCollection.HasValue &&
229-
// _dataCollectionProfile.EnableAzureDataCollection.Value)
230-
//{
231-
// return true;
232-
//}
233-
234-
//return false;
166+
get;
235167
}
236168

237-
/// <summary>
238-
/// Save the current data collection profile Json data into the default file path
239-
/// </summary>
240-
protected abstract void SaveDataCollectionProfile();
241-
242-
protected bool CheckIfInteractive()
243-
{
244-
bool interactive = false;
245-
//if (this.Host == null ||
246-
// this.Host.UI == null ||
247-
// this.Host.UI.RawUI == null ||
248-
// Environment.GetCommandLineArgs().Any(s => s.Equals("-NonInteractive", StringComparison.OrdinalIgnoreCase)))
249-
//{
250-
// interactive = false;
251-
//}
252-
//else
253-
//{
254-
// try
255-
// {
256-
// var test = this.Host.UI.RawUI.KeyAvailable;
257-
// }
258-
// catch
259-
// {
260-
// interactive = false;
261-
// }
262-
//}
263-
264-
if (!interactive && !_dataCollectionProfile.EnableAzureDataCollection.HasValue)
265-
{
266-
_dataCollectionProfile.EnableAzureDataCollection = false;
267-
}
268-
return interactive;
269-
}
270-
271-
/// <summary>
272-
/// Prompt for the current data collection profile
273-
/// </summary>
274-
/// <param name="profile"></param>
275-
protected abstract void PromptForDataCollectionProfileIfNotExists();
276-
277169
/// <summary>
278170
/// Cmdlet begin process. Write to logs, setup Http Tracing and initialize profile
279171
/// </summary>
280172
protected override void BeginProcessing()
281173
{
282-
PromptForDataCollectionProfileIfNotExists();
283174
InitializeQosEvent();
284175
if (string.IsNullOrEmpty(ParameterSetName))
285176
{
@@ -352,7 +243,7 @@ protected bool IsVerbose()
352243

353244
protected new void WriteError(ErrorRecord errorRecord)
354245
{
355-
FlushDebugMessages(IsDataCollectionAllowed());
246+
FlushDebugMessages(IsTelemetryCollectionEnabled);
356247
if (QosEvent != null && errorRecord != null)
357248
{
358249
QosEvent.Exception = errorRecord.Exception;
@@ -524,7 +415,7 @@ protected void LogQosEvent()
524415
return;
525416
}
526417

527-
if (!IsDataCollectionAllowed())
418+
if (!IsTelemetryCollectionEnabled)
528419
{
529420
return;
530421
}
@@ -533,8 +424,10 @@ protected void LogQosEvent()
533424

534425
try
535426
{
536-
MetricHelper.LogQoSEvent(QosEvent, IsUsageMetricEnabled, IsErrorMetricEnabled);
537-
MetricHelper.FlushMetric();
427+
MetricHelper.LogQoSEvent(QosEvent,
428+
IsUsageMetricEnabled && IsTelemetryCollectionEnabled,
429+
IsErrorMetricEnabled && IsTelemetryCollectionEnabled);
430+
MetricHelper.FlushMetric(IsTelemetryCollectionEnabled);
538431
WriteDebug("Finish sending metric.");
539432
}
540433
catch (Exception e)

0 commit comments

Comments
 (0)