Skip to content

Commit 26f22e2

Browse files
Uninstall progress (#283)
* wip * wip * wip * wip * CR-9588 * wip * wip * bump * codegen * codegen * wip * CR-9650 uninstall ignore not found * wip * wip * change token verification message to start with capital letter * bump
1 parent 089e837 commit 26f22e2

File tree

6 files changed

+145
-22
lines changed

6 files changed

+145
-22
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION=v0.0.260
1+
VERSION=v0.0.261
22

33
OUT_DIR=dist
44
YEAR?=$(shell date +"%Y")

cmd/commands/runtime.go

Lines changed: 131 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import (
5353
apstore "github.com/argoproj-labs/argocd-autopilot/pkg/store"
5454
aputil "github.com/argoproj-labs/argocd-autopilot/pkg/util"
5555
argocdv1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
56+
argocdv1alpha1cs "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned"
5657
aev1alpha1 "github.com/argoproj/argo-events/pkg/apis/eventsource/v1alpha1"
5758

5859
"github.com/Masterminds/semver/v3"
@@ -743,7 +744,7 @@ func createGitSources(ctx context.Context, opts *RuntimeInstallOptions) error {
743744
mpCloneOpts.Parse()
744745

745746
createGitSrcMessgae := fmt.Sprintf("Creating %s", store.Get().MarketplaceGitSourceName)
746-
747+
747748
err = RunGitSourceCreate(ctx, &GitSourceCreateOptions{
748749
InsCloneOpts: opts.InsCloneOpts,
749750
GsCloneOpts: mpCloneOpts,
@@ -796,7 +797,7 @@ func removeGitIntegrations(ctx context.Context, opts *RuntimeUninstallOptions) e
796797
for _, intg := range integrations {
797798
if err = RunGitIntegrationRemoveCommand(ctx, appProxyClient, intg.Name); err != nil {
798799
command := util.Doc(fmt.Sprintf("\t<BIN> integration git remove %s", intg.Name))
799-
800+
800801
return fmt.Errorf(`%w. You can try to remove it manually by running: %s`, err, command)
801802
}
802803
}
@@ -1264,9 +1265,13 @@ func NewRuntimeUninstallCommand() *cobra.Command {
12641265
createAnalyticsReporter(ctx, reporter.UninstallFlow)
12651266

12661267
err := runtimeUninstallCommandPreRunHandler(cmd, args, &uninstallationOpts)
1267-
handleCliStep(reporter.UninstallPhasePreCheckFinish, "Finished pre installation checks", err, false)
1268+
handleCliStep(reporter.UninstallPhasePreCheckFinish, "Finished pre run checks", err, false)
12681269
if err != nil {
1269-
return fmt.Errorf("pre installation error: %w", err)
1270+
if errors.Is(err, promptui.ErrInterrupt) {
1271+
return fmt.Errorf("uninstallation canceled by user")
1272+
}
1273+
1274+
return fmt.Errorf("pre run error: %w", err)
12701275
}
12711276

12721277
finalParameters = map[string]string{
@@ -1339,6 +1344,13 @@ func RunRuntimeUninstall(ctx context.Context, opts *RuntimeUninstallOptions) err
13391344
return err
13401345
}
13411346

1347+
subCtx, cancel := context.WithCancel(ctx)
1348+
go func() {
1349+
if err := printApplicationsState(subCtx, opts.RuntimeName, opts.KubeFactory); err != nil {
1350+
log.G(ctx).WithError(err).Debug("failed to print uninstallation progress")
1351+
}
1352+
}()
1353+
13421354
err = apcmd.RunRepoUninstall(ctx, &apcmd.RepoUninstallOptions{
13431355
Namespace: opts.RuntimeName,
13441356
Timeout: opts.Timeout,
@@ -1347,6 +1359,7 @@ func RunRuntimeUninstall(ctx context.Context, opts *RuntimeUninstallOptions) err
13471359
Force: opts.Force,
13481360
FastExit: opts.FastExit,
13491361
})
1362+
cancel() // to tell the progress to stop displaying even if it's not finished
13501363
if opts.Force {
13511364
err = nil
13521365
}
@@ -1372,6 +1385,115 @@ func RunRuntimeUninstall(ctx context.Context, opts *RuntimeUninstallOptions) err
13721385
return nil
13731386
}
13741387

1388+
func printApplicationsState(ctx context.Context, runtime string, f kube.Factory) error {
1389+
apps := map[string]*argocdv1alpha1.Application{}
1390+
lock := sync.Mutex{}
1391+
1392+
rc, err := f.ToRESTConfig()
1393+
if err != nil {
1394+
return err
1395+
}
1396+
1397+
cs, err := argocdv1alpha1cs.NewForConfig(rc)
1398+
if err != nil {
1399+
return err
1400+
}
1401+
1402+
appIf := cs.ArgoprojV1alpha1().Applications(runtime)
1403+
componentsLabelSelector := fmt.Sprintf("%s=%s", store.Get().LabelKeyCFType, store.Get().CFComponentType)
1404+
1405+
curApps, err := appIf.List(ctx, metav1.ListOptions{LabelSelector: componentsLabelSelector})
1406+
if err != nil {
1407+
return err
1408+
}
1409+
1410+
if len(curApps.Items) == 0 {
1411+
// all apps already deleted nothing to wait for
1412+
return nil
1413+
}
1414+
1415+
for i, a := range curApps.Items {
1416+
apps[a.Name] = &curApps.Items[i]
1417+
}
1418+
1419+
// refresh components state
1420+
go func() {
1421+
t := time.NewTicker(time.Second)
1422+
for {
1423+
select {
1424+
case <-ctx.Done():
1425+
return
1426+
case <-t.C:
1427+
}
1428+
1429+
curApps, err := appIf.List(ctx, metav1.ListOptions{LabelSelector: componentsLabelSelector})
1430+
if err != nil {
1431+
log.G(ctx).WithError(err).Debug("failed to refresh components state")
1432+
continue
1433+
}
1434+
1435+
newApps := make(map[string]*argocdv1alpha1.Application, len(curApps.Items))
1436+
for i, a := range curApps.Items {
1437+
newApps[a.Name] = &curApps.Items[i]
1438+
}
1439+
1440+
lock.Lock()
1441+
// update existing
1442+
for i, a := range curApps.Items {
1443+
apps[a.Name] = &curApps.Items[i]
1444+
}
1445+
1446+
// clear deleted apps
1447+
for name := range apps {
1448+
if _, ok := newApps[name]; !ok {
1449+
delete(apps, name)
1450+
}
1451+
}
1452+
lock.Unlock()
1453+
}
1454+
}()
1455+
1456+
checkers := make([]checklist.Checker, len(curApps.Items))
1457+
for i, a := range curApps.Items {
1458+
name := a.Name
1459+
checkers[i] = func(ctx context.Context) (checklist.ListItemState, checklist.ListItemInfo) {
1460+
lock.Lock()
1461+
defer lock.Unlock()
1462+
return getApplicationChecklistState(name, apps[name], runtime)
1463+
}
1464+
}
1465+
1466+
cl := checklist.NewCheckList(
1467+
os.Stdout,
1468+
checklist.ListItemInfo{"COMPONENT", "STATUS"},
1469+
checkers,
1470+
&checklist.CheckListOptions{
1471+
WaitAllReady: true,
1472+
},
1473+
)
1474+
1475+
if err := cl.Start(ctx); err != nil && ctx.Err() == nil {
1476+
return err
1477+
}
1478+
1479+
return nil
1480+
}
1481+
1482+
func getApplicationChecklistState(name string, a *argocdv1alpha1.Application, runtime string) (checklist.ListItemState, checklist.ListItemInfo) {
1483+
state := checklist.Waiting
1484+
name = strings.TrimPrefix(name, fmt.Sprintf("%s-", runtime))
1485+
status := "N/A"
1486+
1487+
if a == nil {
1488+
status = "Deleted"
1489+
state = checklist.Ready
1490+
} else if string(a.Status.Health.Status) != "" {
1491+
status = string(a.Status.Health.Status)
1492+
}
1493+
1494+
return state, []string{name, status}
1495+
}
1496+
13751497
func deleteRuntimeFromPlatform(ctx context.Context, opts *RuntimeUninstallOptions) error {
13761498
log.G(ctx).Infof("Deleting runtime \"%s\" from the platform", opts.RuntimeName)
13771499
_, err := cfConfig.NewClient().V2().Runtime().Delete(ctx, opts.RuntimeName)
@@ -1414,9 +1536,12 @@ func NewRuntimeUpgradeCommand() *cobra.Command {
14141536
createAnalyticsReporter(ctx, reporter.UpgradeFlow)
14151537

14161538
err := runtimeUpgradeCommandPreRunHandler(cmd, args, &opts)
1417-
handleCliStep(reporter.UpgradePhasePreCheckFinish, "Finished pre installation checks", err, false)
1539+
handleCliStep(reporter.UpgradePhasePreCheckFinish, "Finished pre run checks", err, false)
14181540
if err != nil {
1419-
return fmt.Errorf("Pre installation error: %w", err)
1541+
if errors.Is(err, promptui.ErrInterrupt) {
1542+
return fmt.Errorf("upgrade canceled by user")
1543+
}
1544+
return fmt.Errorf("Pre run error: %w", err)
14201545
}
14211546

14221547
finalParameters = map[string]string{

docs/releases/release_notes.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ cf version
2323

2424
```bash
2525
# download and extract the binary
26-
curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.260/cf-linux-amd64.tar.gz | tar zx
26+
curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.261/cf-linux-amd64.tar.gz | tar zx
2727

2828
# move the binary to your $PATH
2929
mv ./cf-linux-amd64 /usr/local/bin/cf
@@ -36,7 +36,7 @@ cf version
3636

3737
```bash
3838
# download and extract the binary
39-
curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.260/cf-darwin-amd64.tar.gz | tar zx
39+
curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.261/cf-darwin-amd64.tar.gz | tar zx
4040

4141
# move the binary to your $PATH
4242
mv ./cf-darwin-amd64 /usr/local/bin/cf

manifests/argo-cd/kustomization.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ resources:
77
images:
88
- name: quay.io/codefresh/argocd
99
newName: quay.io/codefresh/argocd
10-
newTag: v2.1.10-cap-CR-9018
10+
newTag: v2.1.10-cap-CR-9134
1111

1212
# will be effective on argo-cd 2.1
1313
configMapGenerator:

manifests/runtime.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ metadata:
55
namespace: "{{ namespace }}"
66
spec:
77
defVersion: 1.0.1
8-
version: 0.0.260
8+
version: 0.0.261
99
bootstrapSpecifier: github.com/codefresh-io/cli-v2/manifests/argo-cd
1010
components:
1111
- name: events

pkg/git/git.go

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,22 @@ import (
2626
type TokenTypes string
2727

2828
const (
29-
RuntimeToken TokenTypes = "runtime token"
29+
RuntimeToken TokenTypes = "runtime token"
3030
PersonalToken TokenTypes = "personal token"
3131
)
3232

3333
var (
34-
requiredGitHubRuntimeScopes = []string{ "repo", "admin:repo_hook" }
35-
requiredGitHubGitSourceScopes = []string{ "repo" }
36-
37-
typeToGitHubScopes = map[TokenTypes][]string {
38-
RuntimeToken: requiredGitHubRuntimeScopes,
34+
requiredGitHubRuntimeScopes = []string{"repo", "admin:repo_hook"}
35+
requiredGitHubGitSourceScopes = []string{"repo"}
36+
37+
typeToGitHubScopes = map[TokenTypes][]string{
38+
RuntimeToken: requiredGitHubRuntimeScopes,
3939
PersonalToken: requiredGitHubGitSourceScopes,
4040
}
4141
)
4242

43-
44-
4543
func VerifyToken(ctx context.Context, provider string, token string, tokenType TokenTypes) error {
46-
providerToVerifier := map[string]func(context.Context, string, TokenTypes)error {
44+
providerToVerifier := map[string]func(context.Context, string, TokenTypes) error{
4745
"github": verifyGitHubTokenScope,
4846
}
4947

@@ -57,7 +55,7 @@ func VerifyToken(ctx context.Context, provider string, token string, tokenType T
5755

5856
func verifyGitHubTokenScope(ctx context.Context, token string, tokenType TokenTypes) error {
5957
errMessage := fmt.Sprintf("the provided %s is missing one or more of the required scopes: %s", tokenType, strings.Join(typeToGitHubScopes[tokenType], ", "))
60-
58+
6159
req, err := http.NewRequestWithContext(ctx, "HEAD", "https://api.github.com/", nil)
6260
if err != nil {
6361
return err
@@ -92,7 +90,7 @@ func verifyGitHubTokenScope(ctx context.Context, token string, tokenType TokenTy
9290
}
9391
}
9492

95-
log.G(ctx).Infof("%s verified", tokenType)
93+
log.G(ctx).Infof("Verified %s", tokenType)
9694

9795
return nil
9896
}

0 commit comments

Comments
 (0)