-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests(e2e): add script to destroy old Azure image versions (#991)
While checking on our Azure costs I noticed that Gallery costs were slightly increasing over time. This happens because we are charged per VM image version and up until now we had no policy to clean up unused versions. To mitigate this I've devised a script intended to be run just after the image finishes building (as part of the weekly image build workflow). The script destroys the oldest N-2 image versions of the specified codename by default, with the number of versions to keep being configurable via CLI argument in case we ever need to run it by hand. A future commit will integrate this step as part of the scheduled workflow. Fixes UDENG-2786 ------------- I've tested this script locally and it's currently running on my fork for `mantic`: https://github.com/GabrielNagy/adsys/actions/runs/9031928826/job/24819142947
- Loading branch information
Showing
3 changed files
with
104 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
e2e/cmd/build_base_image/99_destroy_previous_versions/main.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Package main provides a script to destroy previous versions of an Azure VM | ||
// image in order to optimize storage costs. | ||
package main | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
log "github.com/sirupsen/logrus" | ||
"github.com/ubuntu/adsys/e2e/internal/az" | ||
"github.com/ubuntu/adsys/e2e/internal/command" | ||
) | ||
|
||
var codename string | ||
var versionsToKeep int | ||
|
||
func main() { | ||
os.Exit(run()) | ||
} | ||
|
||
func run() int { | ||
cmd := command.New(action, command.WithValidateFunc(validate)) | ||
cmd.Usage = fmt.Sprintf(`go run ./%s [options] | ||
Generalize an Azure VM to use as a template for E2E tests. | ||
Options: | ||
--codename codename for which to delete image versions | ||
--versions-to-keep number of versions to keep in storage (default: 2) | ||
This script will: | ||
- query all image versions for the specified codename | ||
- delete all but the latest N versions, as specified by --versions-to-keep | ||
The machine must be authenticated to Azure via the Azure CLI.`, filepath.Base(os.Args[0])) | ||
|
||
cmd.AddStringFlag(&codename, "codename", "", "") | ||
cmd.AddIntFlag(&versionsToKeep, "versions-to-keep", 2, "") | ||
|
||
return cmd.Execute(context.Background()) | ||
} | ||
|
||
func action(ctx context.Context, _ *command.Command) error { | ||
log.Infof("Getting image versions for %q", codename) | ||
|
||
out, _, err := az.RunCommand(ctx, "sig", "image-version", "list", | ||
"--resource-group", "AD", | ||
"--gallery-name", "AD", | ||
"--gallery-image-definition", az.ImageDefinitionName(codename), | ||
"--output", "tsv", | ||
"--query", "[].name", | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
versions := strings.Split(string(out), "\n") | ||
if len(versions) <= versionsToKeep { | ||
log.Infof("No versions to delete for %q", codename) | ||
return nil | ||
} | ||
|
||
versionsToDelete := versions[:len(versions)-versionsToKeep-1] | ||
log.Infof("Deleting %d versions for %q: %v", len(versionsToDelete), codename, versionsToDelete) | ||
|
||
for _, version := range versionsToDelete { | ||
_, _, err := az.RunCommand(ctx, "sig", "image-version", "delete", | ||
"--resource-group", "AD", | ||
"--gallery-name", "AD", | ||
"--gallery-image-definition", az.ImageDefinitionName(codename), | ||
"--gallery-image-version", version, | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
log.Infof("Successfully deleted %d image versions", len(versionsToDelete)) | ||
|
||
return nil | ||
} | ||
|
||
func validate(_ context.Context, _ *command.Command) (err error) { | ||
if codename == "" { | ||
return errors.New("codename must be specified") | ||
} | ||
if versionsToKeep < 1 { | ||
return errors.New("versions-to-keep must be a positive number") | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters