2
2
* This file is protected and may not be modified without permission.
3
3
* See LICENSE_ADDENDUM.txt for details.
4
4
*/
5
+
5
6
using System . Net ;
6
7
using Docker . DotNet ;
7
8
using Docker . DotNet . Models ;
@@ -95,9 +96,20 @@ await _client.Containers.RemoveContainerAsync(container.ContainerId,
95
96
} ;
96
97
}
97
98
98
- CreateContainerResponse ? containerRes = null ;
99
+ CreateContainerResponse ? containerRes ;
100
+ var retry = 0 ;
101
+
102
+ CreateDockerContainer :
99
103
try
100
104
{
105
+ if ( retry ++ >= 3 )
106
+ {
107
+ _logger . SystemLog (
108
+ Program . StaticLocalizer [ nameof ( Resources . Program . ContainerManager_ContainerCreationFailed ) ,
109
+ parameters . Name ] , TaskStatus . Failed , LogLevel . Information ) ;
110
+ return null ;
111
+ }
112
+
101
113
containerRes = await _client . Containers . CreateContainerAsync ( parameters , token ) ;
102
114
}
103
115
catch ( DockerImageNotFoundException )
@@ -106,23 +118,45 @@ await _client.Containers.RemoveContainerAsync(container.ContainerId,
106
118
Program . StaticLocalizer [ nameof ( Resources . Program . ContainerManager_PullContainerImage ) , config . Image ] ,
107
119
TaskStatus . Pending , LogLevel . Information ) ;
108
120
121
+ // pull the image and retry
109
122
await _client . Images . CreateImageAsync ( new ( ) { FromImage = config . Image } , _meta . Auth ,
110
123
new Progress < JSONMessage > ( msg =>
111
124
{
112
125
Console . WriteLine ( $@ "{ msg . Status } |{ msg . ProgressMessage } |{ msg . ErrorMessage } ") ;
113
126
} ) , token ) ;
127
+
128
+ goto CreateDockerContainer ;
114
129
}
115
- catch ( Exception e )
130
+ catch ( DockerApiException e )
116
131
{
117
- _logger . LogError ( e ,
118
- Program . StaticLocalizer [ nameof ( Resources . Program . ContainerManager_ContainerCreationFailed ) ,
119
- parameters . Name ] ) ;
120
- return null ;
121
- }
132
+ if ( e . StatusCode == HttpStatusCode . Conflict )
133
+ {
134
+ // the container already exists, remove it and retry
135
+ try
136
+ {
137
+ await _client . Containers . RemoveContainerAsync ( parameters . Name ,
138
+ new ( ) { Force = true } , token ) ;
139
+ }
140
+ catch ( Exception ex )
141
+ {
142
+ _logger . LogError ( ex ,
143
+ Program . StaticLocalizer [ nameof ( Resources . Program . ContainerManager_ContainerDeletionFailed ) ,
144
+ parameters . Name ] ) ;
145
+ return null ;
146
+ }
122
147
123
- try
124
- {
125
- containerRes ??= await _client . Containers . CreateContainerAsync ( parameters , token ) ;
148
+ goto CreateDockerContainer ;
149
+ }
150
+
151
+ _logger . SystemLog (
152
+ Program . StaticLocalizer [ nameof ( Resources . Program . ContainerManager_ContainerCreationFailedStatus ) ,
153
+ parameters . Name ,
154
+ e . StatusCode ] , TaskStatus . Failed , LogLevel . Warning ) ;
155
+ _logger . SystemLog (
156
+ Program . StaticLocalizer [ nameof ( Resources . Program . ContainerManager_ContainerCreationFailedResponse ) ,
157
+ parameters . Name ,
158
+ e . ResponseBody ] , TaskStatus . Failed , LogLevel . Error ) ;
159
+ return null ;
126
160
}
127
161
catch ( Exception e )
128
162
{
@@ -134,14 +168,13 @@ await _client.Images.CreateImageAsync(new() { FromImage = config.Image }, _meta.
134
168
135
169
var container = new Models . Data . Container { ContainerId = containerRes . ID , Image = config . Image } ;
136
170
137
- var retry = 0 ;
171
+ retry = 0 ;
138
172
bool started ;
139
173
140
174
do
141
175
{
142
176
started = await _client . Containers . StartContainerAsync ( container . ContainerId , new ( ) , token ) ;
143
- retry ++ ;
144
- if ( retry == 3 )
177
+ if ( retry ++ >= 3 )
145
178
{
146
179
_logger . SystemLog (
147
180
Program . StaticLocalizer [ nameof ( Resources . Program . ContainerManager_ContainerInstanceStartFailed ) ,
@@ -170,6 +203,8 @@ await _client.Images.CreateImageAsync(new() { FromImage = config.Image }, _meta.
170
203
nameof ( Resources . Program . ContainerManager_ContainerInstanceCreationFailedWithError ) ,
171
204
config . Image . Split ( "/" ) . LastOrDefault ( ) ?? "" , info . State . Error ] ,
172
205
TaskStatus . Failed , LogLevel . Warning ) ;
206
+
207
+ await DestroyContainerAsync ( container , token ) ;
173
208
return null ;
174
209
}
175
210
@@ -213,6 +248,9 @@ CreateContainerParameters GetCreateContainerParameters(ContainerConfig config) =
213
248
[ "ChallengeId" ] = config . ChallengeId . ToString ( )
214
249
} ,
215
250
Name = DockerMetadata . GetName ( config ) ,
251
+ // The GZCTF identifier is protected by the License.
252
+ // DO NOT REMOVE OR MODIFY THE FOLLOWING LINE.
253
+ // Please see LICENSE_ADDENDUM.txt for details.
216
254
Env = config . Flag is null
217
255
? [ $ "GZCTF_TEAM_ID={ config . TeamId } "]
218
256
: [ $ "GZCTF_FLAG={ config . Flag } ", $ "GZCTF_TEAM_ID={ config . TeamId } "] ,
0 commit comments