Skip to content

Commit 43749e5

Browse files
authored
Merge pull request #5 from redcode-labs/any-image
added an option to specify a custom docker image
2 parents d27ea04 + 35fa773 commit 43749e5

File tree

7 files changed

+165
-143
lines changed

7 files changed

+165
-143
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
easyWSL\bin
2+
easyWSL\obj
3+
.vs

.gitignore.txt

Lines changed: 0 additions & 2 deletions
This file was deleted.

.vs/easyWSL/v16/.suo

-58.5 KB
Binary file not shown.

easyWSL/DistroInstaller.cs

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
using System.Threading.Tasks;
99
using System.Diagnostics;
1010
using System.Threading;
11+
using System.Text.RegularExpressions;
1112

1213
namespace easyWSL
1314
{
1415
class DistroInstaller
1516
{
16-
public class TokenFromResponse
17+
public class autorizationResponse
1718
{
1819
public string token { get; set; }
1920
public string access_token { get; set; }
@@ -25,7 +26,7 @@ public class TokenFromResponse
2526
}
2627

2728

28-
public static void InstallDistro(string distroID, string distroName, string distroPath, string easyWSLDataDirectory, string easyWSLDirectory)
29+
public static void InstallDistro(string distroImage, string distroName, string distroPath, string easyWSLDataDirectory, string easyWSLDirectory)
2930
{
3031

3132
void StartProcessSilently(string processName, string processArguments)
@@ -54,6 +55,20 @@ string GetRequest(string url)
5455
return responseStream;
5556
}
5657

58+
string GetRequestWithHeader(string url, string token, string type)
59+
{
60+
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
61+
request.Headers.Add("Authorization", "Bearer " + token);
62+
request.Accept = type;
63+
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
64+
Stream receiveStream = response.GetResponseStream();
65+
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
66+
string responseStream = readStream.ReadToEnd();
67+
response.Close();
68+
readStream.Close();
69+
return responseStream;
70+
}
71+
5772
void GetRequestWithHeaderToFile(string url, string token, string type, string fileName)
5873
{
5974
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
@@ -65,74 +80,80 @@ void GetRequestWithHeaderToFile(string url, string token, string type, string fi
6580
byte[] buffer = new byte[bufferSize];
6681

6782
FileStream fileStream = File.Create(fileName);
68-
while((bytesRead = receiveStream.Read(buffer, 0, bufferSize)) != 0)
83+
while ((bytesRead = receiveStream.Read(buffer, 0, bufferSize)) != 0)
6984
{
7085
fileStream.Write(buffer, 0, bytesRead);
7186
}
72-
87+
7388
response.Close();
7489
fileStream.Close();
7590
}
7691

7792

78-
SortedDictionary<string, Sources> sources = JsonSerializer.Deserialize<SortedDictionary<string, Sources>>(File.ReadAllText("sources.json"), new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
93+
dynamic sources = JsonSerializer.Deserialize<Sources>(File.ReadAllText("sources.json"));
7994
string repository = "", tag = "", registry = "registry-1.docker.io", authorizationUrl = "https://auth.docker.io/token", registryUrl = "registry.docker.io";
8095

81-
if (sources[distroID].Image.Contains('/'))
96+
97+
if (distroImage.Contains('/'))
8298
{
83-
string[] imageArray = sources[distroID].Image.Split('/');
99+
string[] imageArray = distroImage.Split('/');
84100
tag = "latest";
85-
repository = sources[distroID].Image;
101+
repository = distroImage;
86102
}
87103

88104
else
89105
{
90-
string[] imageArray = sources[distroID].Image.Split(':');
106+
string[] imageArray = distroImage.Split(':');
91107
string imgage = imageArray[0];
92108
tag = imageArray[1];
93109
repository = $"library/{imgage}";
94110
}
95111

112+
dynamic autorizationResponse = JsonSerializer.Deserialize<autorizationResponse>(GetRequest($"{authorizationUrl}?service={registryUrl}&scope=repository:{repository}:pull"));
96113

97-
dynamic tokenFromResponse = JsonSerializer.Deserialize<TokenFromResponse>(GetRequest($"{authorizationUrl}?service={registryUrl}&scope=repository:{repository}:pull"));
114+
string layersResponse = GetRequestWithHeader($"https://{registry}/v2/{repository}/manifests/{tag}", autorizationResponse.token, "application/vnd.docker.distribution.manifest.v2+json");
115+
116+
MatchCollection layersRegex = Regex.Matches(layersResponse, @"sha256:\w{64}");
117+
var layersList = layersRegex.Cast<Match>().Select(match => match.Value).ToList();
118+
layersList.RemoveAt(0);
98119

99120
string layersDirectory = $"{easyWSLDataDirectory}\\layers";
100121
Directory.CreateDirectory(layersDirectory);
101122

102-
string concatTarCommand = $" cf {layersDirectory}\\install.tar";
123+
string concatTarCommand = $" cf {layersDirectory}\\{distroName}-install.tar";
103124

104125
int count = 0;
105-
foreach (string layer in sources[distroID].Layers)
126+
foreach (string layer in layersList)
106127
{
107128
count++;
108129
Console.WriteLine($"Downloading {count}. layer ...");
109130

110-
tokenFromResponse = JsonSerializer.Deserialize<TokenFromResponse>(GetRequest($"{authorizationUrl}?service={registryUrl}&scope=repository:{repository}:pull"));
131+
autorizationResponse = JsonSerializer.Deserialize<autorizationResponse>(GetRequest($"{authorizationUrl}?service={registryUrl}&scope=repository:{repository}:pull"));
111132

112-
string layerName = $"layer{count}.tar.bz";
133+
string layerName = $"{distroName}-layer{count}.tar.bz";
113134
string layerPath = $"{layersDirectory}\\{layerName}";
114135

115-
GetRequestWithHeaderToFile($"https://{registry}/v2/{repository}/blobs/{layer}", tokenFromResponse.token, "application/vnd.docker.distribution.manifest.v2+json", layerPath);
136+
GetRequestWithHeaderToFile($"https://{registry}/v2/{repository}/blobs/{layer}", autorizationResponse.token, "application/vnd.docker.distribution.manifest.v2+json", layerPath);
116137
concatTarCommand += $" @{layerPath} ";
117138
}
118-
139+
119140

120141
Console.WriteLine("Creating install.tar file ...");
121-
if(sources[distroID].Layers.Count == 1)
142+
if (layersList.Count == 1)
122143
{
123-
File.Move($"{layersDirectory}\\layer1.tar.bz", $"{layersDirectory}\\install.tar.bz");
144+
File.Move($"{layersDirectory}\\{distroName}-layer1.tar.bz", $"{layersDirectory}\\{distroName}-install.tar.bz");
124145

125146
Console.WriteLine("Registering the distro ...");
126-
StartProcessSilently("wsl.exe", $"--import {distroName} {distroPath} {easyWSLDataDirectory}\\layers\\install.tar.bz");
147+
StartProcessSilently("wsl.exe", $"--import {distroName} {distroPath} {easyWSLDataDirectory}\\layers\\{distroName}-install.tar.bz");
127148
}
128149
else
129150
{
130151
StartProcessSilently($"{easyWSLDirectory}\\dep\\bsdtar.exe", concatTarCommand);
131152

132153
Console.WriteLine("Registering the distro ...");
133-
StartProcessSilently("wsl.exe", $"--import {distroName} {distroPath} {easyWSLDataDirectory}\\layers\\install.tar");
154+
StartProcessSilently("wsl.exe", $"--import {distroName} {distroPath} {easyWSLDataDirectory}\\layers\\{distroName}-install.tar");
134155
}
135-
156+
136157

137158
Console.WriteLine("Cleaning up ...");
138159
Directory.Delete(layersDirectory, true);

easyWSL/Program.cs

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ static void Main(string[] args)
3030
Console.ResetColor();
3131
}
3232

33-
SortedDictionary<string, Sources> sources = JsonSerializer.Deserialize<SortedDictionary<string, Sources>>(File.ReadAllText("sources.json"), new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
34-
35-
string distroID = "", distroName = "", distroPath = "";
36-
int distroNumber;
33+
dynamic sources = JsonSerializer.Deserialize<Sources>(File.ReadAllText("sources.json"));
34+
35+
string distroImage = "", distroName = "", distroPath = "";
36+
int distroNumber = 0;
3737

3838
bool isConversionSuccessful;
3939

@@ -47,9 +47,9 @@ static void Main(string[] args)
4747
{
4848
foreach (int argument in Enumerable.Range(0, args.Length))
4949
{
50-
if ((args[argument] == "-d") ^ (args[argument] == "--distro"))
50+
if ((args[argument] == "-i") ^ (args[argument] == "--image"))
5151
{
52-
distroID = args[argument + 1];
52+
distroImage = args[argument + 1];
5353
}
5454

5555
else if ((args[argument] == "-n") ^ (args[argument] == "--name"))
@@ -59,47 +59,64 @@ static void Main(string[] args)
5959

6060
else if ((args[argument] == "-p") ^ (args[argument] == "--path"))
6161
{
62-
distroID = args[argument + 1];
62+
distroPath = args[argument + 1];
6363
}
6464
}
6565
}
6666

67-
if (distroID == "")
67+
if (distroImage == "")
6868
{
6969
int count = 1;
70-
foreach (KeyValuePair<string, Sources> kvp in sources)
70+
foreach (var source in sources.sources)
7171
{
72-
Console.WriteLine($"{count}. {sources[kvp.Key].Name}");
72+
Console.WriteLine($"{count}. {source.name}");
7373
count++;
7474
}
7575

76+
// additional entry for a custom image option
77+
Console.WriteLine($"{count}. Specify a docker image");
78+
7679
do
7780
{
7881
Console.Write("A number of a distro you want to install: ");
7982

8083
isConversionSuccessful = Int32.TryParse(Console.ReadLine(), out distroNumber);
81-
} while ((distroNumber > sources.Count) ^ (isConversionSuccessful == false));
82-
83-
84+
} while ((distroNumber < 1) ^ (distroNumber > sources.sources.Count + 1) ^ (isConversionSuccessful == false) ^ (distroNumber == 0));
8485

85-
count = 1;
86-
foreach (KeyValuePair<string, Sources> kvp in sources)
86+
if(distroNumber == sources.sources.Count+1)
8787
{
88-
distroID = kvp.Key;
89-
count++;
90-
if (count > distroNumber)
91-
break;
88+
while (distroImage == "")
89+
{
90+
Console.Write("Specify a docker container: ");
91+
distroImage = Console.ReadLine();
92+
}
93+
}
94+
else
95+
{
96+
distroImage = sources.sources[distroNumber - 1].image;
9297
}
9398
}
94-
99+
95100
if(distroName == "")
96101
{
97-
Console.Write("A name for your distro (default " + sources[distroID].Name + "): ");
102+
if ((distroNumber == sources.sources.Count + 1) || (distroNumber == 0))
103+
Console.Write("A name for your distro: ");
104+
else
105+
Console.Write("A name for your distro (default " + sources.sources[distroNumber - 1].name + "): ");
98106
distroName = Console.ReadLine();
99107

100108
if (distroName == "")
101109
{
102-
distroName = sources[distroID].Name;
110+
if (distroNumber == sources.sources.Count + 1)
111+
{
112+
while(distroName == "")
113+
{
114+
Console.Write("A name for your distro: ");
115+
distroName = Console.ReadLine();
116+
}
117+
}
118+
else
119+
distroName = sources.sources[distroNumber-1].name;
103120
}
104121

105122
distroName = Regex.Replace(distroName, @"\s+", "");
@@ -124,7 +141,7 @@ static void Main(string[] args)
124141

125142
Directory.CreateDirectory(distroPath);
126143

127-
DistroInstaller.InstallDistro(distroID, distroName, distroPath, easyWSLDataDirectory, easyWSLDirectory);
144+
DistroInstaller.InstallDistro(distroImage, distroName, distroPath, easyWSLDataDirectory, easyWSLDirectory);
128145
}
129146
}
130147
}

easyWSL/Sources.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ namespace easyWSL
88
{
99
class Sources
1010
{
11-
public string Name { get; set; }
12-
public string Image { get; set; }
13-
public List<string> Layers { get; set; }
11+
public List<SourceProperties> sources { get; set; }
12+
}
13+
14+
public class SourceProperties
15+
{
16+
public string image { get; set; }
17+
public string name { get; set; }
1418
}
1519
}

0 commit comments

Comments
 (0)