@@ -10,12 +10,14 @@ import (
10
10
"io"
11
11
"os"
12
12
"sync"
13
+ "time"
13
14
14
15
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
15
16
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
16
17
"github.com/go-logr/logr"
17
18
"github.com/rotisserie/eris"
18
19
"github.com/spf13/cobra"
20
+ "github.com/vbauerster/mpb/v8"
19
21
20
22
"github.com/Azure/azure-service-operator/v2/api"
21
23
"github.com/Azure/azure-service-operator/v2/cmd/asoctl/pkg/importreporter"
@@ -111,6 +113,13 @@ https://docs.microsoft.com/azure/active-directory/develop/authentication-nationa
111
113
4 ,
112
114
"The number of parallel workers to use when importing resources" )
113
115
116
+ cmd .Flags ().BoolVarP (
117
+ & options .simpleLogging ,
118
+ "simple-logging" ,
119
+ "s" ,
120
+ false ,
121
+ "Use simple logging instead of progress bars" )
122
+
114
123
return cmd
115
124
}
116
125
@@ -131,30 +140,51 @@ func importAzureResource(
131
140
return eris .Wrapf (err , "failed to create ARM client" )
132
141
}
133
142
134
- // Caution: the progress bar can deadlock if no bar is ever created, so make sure the gap between
135
- // this and the call to importer.Import() is as small as possible.
136
- log , progressBar := CreateLoggerAndProgressBar ()
137
-
138
143
done := make (chan struct {}) // signal for when we're done
139
- pb := importreporter .NewBar ("Import Azure Resources" , progressBar , done )
144
+
145
+ var log logr.Logger
146
+ var progress importreporter.Interface
147
+ var output io.Writer
148
+ if options .simpleLogging {
149
+ log = CreateLogger ()
150
+ progress = importreporter .NewLog ("Import Azure Resources" , log , done )
151
+ output = os .Stderr
152
+ } else {
153
+ var bar * mpb.Progress
154
+
155
+ // Caution: the progress bar can deadlock if no bar is ever created, so make sure the gap between
156
+ // this and the call to importer.Import() is as small as possible.
157
+ log , bar = CreateLoggerAndProgressBar ()
158
+ progress = importreporter .NewBar ("Import Azure Resources" , bar , done )
159
+
160
+ // The progress bar can deadlock if no bar is ever created - which can happen if we need to return an error
161
+ // between here and the call to importer.Import(). To avoid this, we create a dummy bar that will complete
162
+ // asynchronously after a short delay.
163
+ setup := progress .Create ("Initalizing" )
164
+ setup .AddPending (1 )
165
+ go func () {
166
+ time .Sleep (200 * time .Millisecond )
167
+ setup .Completed (1 )
168
+ }()
169
+
170
+ output = bar
171
+
172
+ // Ensure the progress bar is closed when we're done
173
+ defer bar .Wait ()
174
+ }
140
175
141
176
importerOptions := importresources.ResourceImporterOptions {
142
177
Workers : options .workers ,
143
178
}
144
179
145
- importer := importresources .New (api .CreateScheme (), client , log , pb , importerOptions )
180
+ importer := importresources .New (api .CreateScheme (), client , log , progress , importerOptions )
146
181
for _ , armID := range armIDs {
147
182
err = importer .AddARMID (armID )
148
183
if err != nil {
149
184
return eris .Wrapf (err , "failed to add %q to import list" , armID )
150
185
}
151
186
}
152
187
153
- // Make sure all output is written when we're done.
154
- // This defer has to be immediately before the call the importer.Import();
155
- // if you move it earlier, any `return err` between there and here will cause a deadlock.
156
- defer progressBar .Wait ()
157
-
158
188
result , err := importer .Import (ctx , done )
159
189
160
190
if ctx .Err () != nil {
@@ -180,7 +210,7 @@ func importAzureResource(
180
210
return eris .Wrap (err , "failed to apply options to imported resources" )
181
211
}
182
212
183
- err = writeResources (result , options , log , progressBar )
213
+ err = writeResources (result , options , log , output )
184
214
if err != nil {
185
215
return eris .Wrap (err , "failed to write resources" )
186
216
}
@@ -274,12 +304,13 @@ func writeResources(
274
304
}
275
305
276
306
type importAzureResourceOptions struct {
277
- outputPath string
278
- outputFolder string
279
- namespace string
280
- annotations []string
281
- labels []string
282
- workers int
307
+ outputPath string
308
+ outputFolder string
309
+ namespace string
310
+ annotations []string
311
+ labels []string
312
+ workers int
313
+ simpleLogging bool
283
314
284
315
readCloud sync.Once
285
316
azureAuthorityHost string
0 commit comments