66 "context"
77 "encoding/base64"
88 "fmt"
9- "os"
109 "regexp"
11- "strings"
1210 "time"
1311
1412 "github.com/k0sproject/dig"
@@ -23,8 +21,8 @@ import (
2321
2422 "github.com/replicatedhq/embedded-cluster/pkg/addons/registry"
2523 "github.com/replicatedhq/embedded-cluster/pkg/defaults"
26- "github.com/replicatedhq/embedded-cluster/pkg/goods"
2724 "github.com/replicatedhq/embedded-cluster/pkg/helpers"
25+ "github.com/replicatedhq/embedded-cluster/pkg/kotscli"
2826 "github.com/replicatedhq/embedded-cluster/pkg/kubeutils"
2927 "github.com/replicatedhq/embedded-cluster/pkg/metrics"
3028 "github.com/replicatedhq/embedded-cluster/pkg/prompts"
@@ -210,99 +208,6 @@ func (a *AdminConsole) GetAdditionalImages() []string {
210208 return nil
211209}
212210
213- // MaskKotsOutputForOnline masks the kots cli output during online installations. For
214- // online installations we only want to print "Finalizing" until it is done and then
215- // print "Finished!".
216- func (a * AdminConsole ) MaskKotsOutputForOnline () spinner.MaskFn {
217- return func (message string ) string {
218- if strings .Contains (message , "Finished" ) {
219- return message
220- }
221- return "Finalizing"
222- }
223- }
224-
225- // MaskKotsOutputForAirgap masks the kots cli output during airgap installations. This
226- // function replaces some of the messages being printed to the user so the output looks
227- // nicer.
228- func (a * AdminConsole ) MaskKotsOutputForAirgap () spinner.MaskFn {
229- current := "Uploading air gap bundle"
230- return func (message string ) string {
231- switch {
232- case strings .Contains (message , "Pushing application images" ):
233- current = message
234- case strings .Contains (message , "Pushing embedded cluster artifacts" ):
235- current = message
236- case strings .Contains (message , "Waiting for Admin Console" ):
237- current = "Finalizing"
238- case strings .Contains (message , "Finished!" ):
239- current = message
240- }
241- return current
242- }
243- }
244-
245- // KostsOutputLineBreaker creates a line break (new spinner) when some of the messages
246- // are printed to the user. For example: after finishing all image uploads we want to
247- // have a new spinner for the artifacts upload.
248- func (a * AdminConsole ) KostsOutputLineBreaker () spinner.LineBreakerFn {
249- // finished is an auxiliary function that evaluates if a message refers to a
250- // step that has been finished. We determine that by inspected if the message
251- // contains %d/%d and both integers are equal.
252- finished := func (message string ) bool {
253- matches := CounterRegex .FindStringSubmatch (message )
254- if len (matches ) != 3 {
255- return false
256- }
257- var counter int
258- if _ , err := fmt .Sscanf (matches [1 ], "%d" , & counter ); err != nil {
259- return false
260- }
261- var total int
262- if _ , err := fmt .Sscanf (matches [2 ], "%d" , & total ); err != nil {
263- return false
264- }
265- return counter == total
266- }
267-
268- var previous string
269- var seen = map [string ]bool {}
270- return func (current string ) (bool , string ) {
271- defer func () {
272- previous = current
273- }()
274-
275- // if we have already seen this message we certainly have already assessed
276- // if a break line as necessary or not, on this case we return false so we
277- // do not keep breaking lines indefinitely.
278- if _ , ok := seen [current ]; ok {
279- return false , ""
280- }
281- seen [current ] = true
282-
283- // if the previous message evaluated does not relate to an end of a process
284- // we don't want to break the line. i.e. we only want to break the line when
285- // the previous evaluated message contains %d/%d and both integers are equal.
286- if ! finished (previous ) {
287- return false , ""
288- }
289-
290- // if we are printing a message about pushing the embedded cluster artifacts
291- // it means that we have finished with the images and we want to break the line.
292- if strings .Contains (current , "Pushing embedded cluster artifacts" ) {
293- return true , "Application images are ready!"
294- }
295-
296- // if we are printing a message about the finalization of the installation it
297- // means that the embedded cluster artifacts are ready and we want to break the
298- // line.
299- if current == "Finalizing" {
300- return true , "Embedded cluster artifacts are ready!"
301- }
302- return false , ""
303- }
304- }
305-
306211// Outro waits for the adminconsole to be ready.
307212func (a * AdminConsole ) Outro (ctx context.Context , cli client.Client ) error {
308213 loading := spinner .Start ()
@@ -345,59 +250,21 @@ func (a *AdminConsole) Outro(ctx context.Context, cli client.Client) error {
345250 return nil
346251 }
347252
348- kotsBinPath , err := goods .MaterializeInternalBinary ("kubectl-kots" )
349- if err != nil {
350- return fmt .Errorf ("unable to materialize kubectl-kots binary: %w" , err )
351- }
352- defer os .Remove (kotsBinPath )
353-
354253 license , err := helpers .ParseLicense (a .licenseFile )
355254 if err != nil {
356255 loading .CloseWithError ()
357256 return fmt .Errorf ("unable to parse license: %w" , err )
358257 }
359258
360- var appVersionLabel string
361- var channelSlug string
362- if channelRelease , err := release .GetChannelRelease (); err != nil {
363- loading .CloseWithError ()
364- return fmt .Errorf ("unable to get channel release: %w" , err )
365- } else if channelRelease != nil {
366- appVersionLabel = channelRelease .VersionLabel
367- channelSlug = channelRelease .ChannelSlug
368- }
369-
370- upstreamURI := license .Spec .AppSlug
371- if channelSlug != "" && channelSlug != "stable" {
372- upstreamURI = fmt .Sprintf ("%s/%s" , upstreamURI , channelSlug )
373- }
374-
375- var lbreakfn spinner.LineBreakerFn
376- maskfn := a .MaskKotsOutputForOnline ()
377- installArgs := []string {
378- "install" ,
379- upstreamURI ,
380- "--license-file" ,
381- a .licenseFile ,
382- "--namespace" ,
383- a .namespace ,
384- "--app-version-label" ,
385- appVersionLabel ,
386- "--exclude-admin-console" ,
387- }
388- if a .airgapBundle != "" {
389- installArgs = append (installArgs , "--airgap-bundle" , a .airgapBundle )
390- maskfn = a .MaskKotsOutputForAirgap ()
391- lbreakfn = a .KostsOutputLineBreaker ()
392- }
393-
394- loading = spinner .Start (spinner .WithMask (maskfn ), spinner .WithLineBreaker (lbreakfn ))
395- if err := helpers .RunCommandWithWriter (loading , kotsBinPath , installArgs ... ); err != nil {
396- loading .CloseWithError ()
397- return fmt .Errorf ("unable to install the application: %w" , err )
259+ if err := kotscli .Install (kotscli.InstallOptions {
260+ AppSlug : license .Spec .AppSlug ,
261+ LicenseFile : a .licenseFile ,
262+ Namespace : a .namespace ,
263+ AirgapBundle : a .airgapBundle ,
264+ }); err != nil {
265+ return err
398266 }
399267
400- loading .Closef ("Finished!" )
401268 a .printSuccessMessage (license .Spec .AppSlug )
402269 return nil
403270}
0 commit comments