88using System . Threading . Tasks ;
99using System . Diagnostics ;
1010using System . Threading ;
11+ using System . Text . RegularExpressions ;
1112
1213namespace 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 ) ;
0 commit comments