Skip to content

Commit c22f576

Browse files
committed
Added the checksum verification and basic concept of a progress bar
1 parent c16e3fc commit c22f576

File tree

278 files changed

+62380
-18
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

278 files changed

+62380
-18
lines changed

.vs/easyWSL/v16/.suo

16.5 KB
Binary file not shown.

easyWSL/App.config

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1-
<?xml version="1.0" encoding="utf-8" ?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<configuration>
33
<startup>
44
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
55
</startup>
6+
<runtime>
7+
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
8+
<dependentAssembly>
9+
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
10+
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
11+
</dependentAssembly>
12+
</assemblyBinding>
13+
</runtime>
614
</configuration>

easyWSL/DistroInstaller.cs

+59-15
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Diagnostics;
1010
using System.Threading;
1111
using System.Text.RegularExpressions;
12+
using System.Security.Cryptography;
1213

1314
namespace easyWSL
1415
{
@@ -67,24 +68,48 @@ string GetRequestWithHeader(string url, string token, string type)
6768
return responseStream;
6869
}
6970

70-
void GetRequestWithHeaderToFile(string url, string token, string type, string fileName)
71+
void GetRequestWithHeaderToFile(string url, string token, string type, string fileName, int size)
7172
{
72-
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
73-
request.Headers.Add("Authorization", "Bearer " + token);
74-
request.Accept = type;
75-
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
76-
Stream receiveStream = response.GetResponseStream();
77-
int bufferSize = 1024, bytesRead = 0;
78-
byte[] buffer = new byte[bufferSize];
7973

80-
FileStream fileStream = File.Create(fileName);
81-
while ((bytesRead = receiveStream.Read(buffer, 0, bufferSize)) != 0)
74+
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
75+
request.Headers.Add("Authorization", "Bearer " + token);
76+
request.Accept = type;
77+
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
78+
Stream receiveStream = response.GetResponseStream();
79+
int bufferSize = 1024, bytesRead = 0;
80+
byte[] buffer = new byte[bufferSize];
81+
82+
FileStream fileStream = File.Create(fileName);
83+
int bytes = 0;
84+
using (var progress = new ProgressBar())
8285
{
83-
fileStream.Write(buffer, 0, bytesRead);
84-
}
86+
while ((bytesRead = receiveStream.Read(buffer, 0, bufferSize)) != 0)
87+
{
88+
progress.Report((double)bytes * 100 / size);
89+
fileStream.Write(buffer, 0, bytesRead);
90+
bytes += bytesRead;
91+
//Console.Write($"\r{bytes}/{size} bytes downloaded");
92+
}
8593

94+
}
8695
response.Close();
87-
fileStream.Close();
96+
fileStream.Close();
97+
//Console.Write("\n");
98+
99+
}
100+
string ComputeSha256Hash(byte[] rawData)
101+
{
102+
using (SHA256 sha256Hash = SHA256.Create())
103+
{
104+
byte[] bytes = sha256Hash.ComputeHash(rawData);
105+
106+
StringBuilder builder = new StringBuilder();
107+
for (int i = 0; i < bytes.Length; i++)
108+
{
109+
builder.Append(bytes[i].ToString("x2"));
110+
}
111+
return builder.ToString();
112+
}
88113
}
89114

90115

@@ -123,6 +148,9 @@ void GetRequestWithHeaderToFile(string url, string token, string type, string fi
123148
var layersList = layersRegex.Cast<Match>().Select(match => match.Value).ToList();
124149
layersList.RemoveAt(0);
125150

151+
MatchCollection layersSizeRegex = Regex.Matches(layersResponse, @"""size"": \d*");
152+
var layersSizeList = layersSizeRegex.Cast<Match>().Select(match => Convert.ToInt32(match.Value.Remove(0,8))).ToList();
153+
126154
string layersDirectory = $"{easyWSLDataDirectory}\\layers";
127155
Directory.CreateDirectory(layersDirectory);
128156

@@ -139,7 +167,24 @@ void GetRequestWithHeaderToFile(string url, string token, string type, string fi
139167
string layerName = $"{distroName}-layer{count}.tar.bz";
140168
string layerPath = $"{layersDirectory}\\{layerName}";
141169

142-
GetRequestWithHeaderToFile($"https://{registry}/v2/{repository}/blobs/{layer}", autorizationResponse.token, "application/vnd.docker.distribution.manifest.v2+json", layerPath);
170+
GetRequestWithHeaderToFile($"https://{registry}/v2/{repository}/blobs/{layer}", autorizationResponse.token, "application/vnd.docker.distribution.manifest.v2+json", layerPath, layersSizeList[count]);
171+
172+
Console.Write("Veryfing the layer... ");
173+
string layerHash = ComputeSha256Hash(File.ReadAllBytes(layerPath));
174+
if (layerHash == layer.Remove(0,7))
175+
{
176+
Console.ForegroundColor = ConsoleColor.Green;
177+
Console.Write("PASSED\n");
178+
Console.ResetColor();
179+
}
180+
else
181+
{
182+
Console.ForegroundColor = ConsoleColor.Red;
183+
Console.Write("NOT PASSED\n");
184+
Console.ResetColor();
185+
Console.WriteLine("Aborting...");
186+
Environment.Exit(0);
187+
}
143188
concatTarCommand += $" @{layerPath} ";
144189
}
145190

@@ -160,7 +205,6 @@ void GetRequestWithHeaderToFile(string url, string token, string type, string fi
160205
StartProcessSilently("wsl.exe", $"--import {distroName} {distroPath} {easyWSLDataDirectory}\\layers\\{distroName}-install.tar");
161206
}
162207

163-
164208
Console.WriteLine("Cleaning up ...");
165209
Directory.Delete(layersDirectory, true);
166210

easyWSL/ProgressBar.cs

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
using System;
2+
using System.Text;
3+
using System.Threading;
4+
5+
namespace easyWSL
6+
{
7+
public class ProgressBar : IDisposable, IProgress<double>
8+
{
9+
private const int blockCount = 10;
10+
private readonly TimeSpan animationInterval = TimeSpan.FromSeconds(1.0 / 8);
11+
private const string animation = @"|/-\";
12+
13+
private readonly Timer timer;
14+
15+
private double currentProgress = 0;
16+
private string currentText = string.Empty;
17+
private bool disposed = false;
18+
private int animationIndex = 0;
19+
20+
public ProgressBar()
21+
{
22+
timer = new Timer(TimerHandler);
23+
24+
// A progress bar is only for temporary display in a console window.
25+
// If the console output is redirected to a file, draw nothing.
26+
// Otherwise, we'll end up with a lot of garbage in the target file.
27+
if (!Console.IsOutputRedirected)
28+
{
29+
ResetTimer();
30+
}
31+
}
32+
33+
public void Report(double value)
34+
{
35+
// Make sure value is in [0..1] range
36+
value = Math.Max(0, Math.Min(1, value));
37+
Interlocked.Exchange(ref currentProgress, value);
38+
}
39+
40+
private void TimerHandler(object state)
41+
{
42+
lock (timer)
43+
{
44+
if (disposed) return;
45+
46+
int progressBlockCount = (int)(currentProgress * blockCount);
47+
int percent = (int)(currentProgress * 100);
48+
string text = string.Format("[{0}{1}] {2,3}% {3}",
49+
new string('#', progressBlockCount), new string('-', blockCount - progressBlockCount),
50+
percent,
51+
animation[animationIndex++ % animation.Length]);
52+
UpdateText(text);
53+
54+
ResetTimer();
55+
}
56+
}
57+
58+
private void UpdateText(string text)
59+
{
60+
// Get length of common portion
61+
int commonPrefixLength = 0;
62+
int commonLength = Math.Min(currentText.Length, text.Length);
63+
while (commonPrefixLength < commonLength && text[commonPrefixLength] == currentText[commonPrefixLength])
64+
{
65+
commonPrefixLength++;
66+
}
67+
68+
// Backtrack to the first differing character
69+
StringBuilder outputBuilder = new StringBuilder();
70+
outputBuilder.Append('\b', currentText.Length - commonPrefixLength);
71+
72+
// Output new suffix
73+
outputBuilder.Append(text.Substring(commonPrefixLength));
74+
75+
// If the new text is shorter than the old one: delete overlapping characters
76+
int overlapCount = currentText.Length - text.Length;
77+
if (overlapCount > 0)
78+
{
79+
outputBuilder.Append(' ', overlapCount);
80+
outputBuilder.Append('\b', overlapCount);
81+
}
82+
83+
Console.Write(outputBuilder);
84+
currentText = text;
85+
}
86+
87+
private void ResetTimer()
88+
{
89+
timer.Change(animationInterval, TimeSpan.FromMilliseconds(-1));
90+
}
91+
92+
public void Dispose()
93+
{
94+
lock (timer)
95+
{
96+
disposed = true;
97+
UpdateText(string.Empty);
98+
}
99+
}
100+
101+
}
102+
}
Binary file not shown.

0 commit comments

Comments
 (0)