Skip to content

Commit 2cfd325

Browse files
author
SamCHogg
committed
Use docker config file and check latest for upgrade
1 parent f8fdb31 commit 2cfd325

File tree

3 files changed

+63
-58
lines changed

3 files changed

+63
-58
lines changed

cmd/images.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ import (
1111

1212
const (
1313
successIcon = "\xE2\x9C\x85"
14-
failedIcon = "\xE2\x9D\x97"
15-
warningIcon = "\xE2\x9D\x8C"
14+
warningIcon = "\xE2\x9D\x97"
15+
failedIcon = "\xE2\x9D\x8C"
16+
upgradeIcon = "\xE2\xAC\x86"
1617
)
1718

1819
var imagesCmd = &cobra.Command{
@@ -23,6 +24,11 @@ var imagesCmd = &cobra.Command{
2324
}
2425

2526
func imagesCmdRun(cmd *cobra.Command, args []string) {
27+
debug, err := cmd.Flags().GetBool("debug")
28+
if err != nil {
29+
log.Fatal(err)
30+
}
31+
2632
k8sClient, err := k8s.NewKubernetesClient()
2733
if err != nil {
2834
log.Fatal(err)
@@ -31,17 +37,25 @@ func imagesCmdRun(cmd *cobra.Command, args []string) {
3137
if err != nil {
3238
log.Fatal(err)
3339
}
34-
fmt.Printf("Legends:\n%s - Supports arm64, %s - Do not support arm64, %s - Some error occurred\n", successIcon, warningIcon, failedIcon)
35-
fmt.Print("------------------------------------------------------------------------\n\n")
40+
fmt.Printf("Legends:\n%s - Supports arm64, %s - Does not support arm64, %s - Upgrade for arm64 support, %s - Some error occurred\n", successIcon, failedIcon, upgradeIcon, warningIcon)
41+
fmt.Print("------------------------------------------------------------------------------------------------\n\n")
3642
for _, image := range imageList {
3743
var icon string
38-
supportsArm, err := images.CheckLinuxArm64Support(images.ToFullURL(image))
44+
supportsArm, err := images.CheckLinuxArm64Support(image)
3945
if err != nil {
46+
if debug {
47+
fmt.Printf("error: %s\n", err)
48+
}
4049
icon = warningIcon
4150
} else if supportsArm {
4251
icon = successIcon
4352
} else {
44-
icon = failedIcon
53+
latestSupportsArm, _ := images.CheckLatestLinuxArm64Support(image)
54+
if latestSupportsArm {
55+
icon = upgradeIcon
56+
} else {
57+
icon = failedIcon
58+
}
4559
}
4660
fmt.Printf("%s %s\n", image, icon)
4761
}
@@ -50,6 +64,8 @@ func imagesCmdRun(cmd *cobra.Command, args []string) {
5064
func init() {
5165
rootCmd.AddCommand(imagesCmd)
5266

67+
imagesCmd.Flags().BoolP("debug", "d", false, "Enable debug mode")
68+
5369
// Here you will define your flags and configuration settings.
5470

5571
// Cobra supports Persistent Flags which will work for this command

internal/images/images.go

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,75 @@ package images
33
import (
44
"context"
55
"fmt"
6+
"os"
7+
"path/filepath"
68
"strings"
79

810
"github.com/containers/image/v5/manifest"
911
"github.com/containers/image/v5/transports/alltransports"
1012
"github.com/containers/image/v5/types"
1113
)
1214

13-
// ToFullURL converts the provided image name to the full URL, if already not in that format.
14-
// e.g. nginx becomes docker.io/library/nginx
15-
// If already in full URL format, image name is returned as is.
16-
func ToFullURL(imgName string) string {
17-
splits := strings.Split(imgName, "/")
18-
if len(splits) > 2 {
19-
return imgName
20-
}
21-
if len(splits) == 2 {
22-
return fmt.Sprintf("docker.io/%s", imgName)
15+
func getDockerConfigPath() string {
16+
home, err := os.UserHomeDir()
17+
if err != nil {
18+
return ""
2319
}
24-
return fmt.Sprintf("docker.io/library/%s", imgName)
20+
return filepath.Join(home, ".docker", "config.json")
2521
}
2622

2723
// CheckLinuxArm64Support checks for the existance of an arm64 linux image in the manifest
2824
func CheckLinuxArm64Support(imgName string) (bool, error) {
2925
sys := &types.SystemContext{
30-
ArchitectureChoice: "arm64",
31-
OSChoice: "linux",
26+
ArchitectureChoice: "arm64",
27+
OSChoice: "linux",
28+
DockerCompatAuthFilePath: getDockerConfigPath(),
3229
}
3330

3431
ref, err := alltransports.ParseImageName(fmt.Sprintf("docker://%s", imgName))
3532
if err != nil {
36-
return false, err
33+
return false, fmt.Errorf("error parsing image name: %w", err)
3734
}
3835

3936
imageSource, err := ref.NewImageSource(context.Background(), sys)
4037
if err != nil {
41-
return false, err
38+
return false, fmt.Errorf("error getting image source: %w", err)
4239
}
4340
defer imageSource.Close()
4441

4542
rawManifest, mimeType, err := imageSource.GetManifest(context.Background(), nil)
4643
if err != nil {
47-
return false, err
44+
return false, fmt.Errorf("error getting manifest: %w", err)
4845
}
4946

50-
manifestList, err := manifest.ListFromBlob(rawManifest, mimeType)
51-
if err != nil {
52-
return false, err
47+
if manifest.MIMETypeIsMultiImage(mimeType) {
48+
manifestList, err := manifest.ListFromBlob(rawManifest, mimeType)
49+
if err != nil {
50+
return false, err
51+
}
52+
53+
// This call will error if it cannot find a instance that supports linux arm64
54+
_, err = manifestList.ChooseInstance(sys)
55+
return err == nil, nil
56+
} else {
57+
// m, err := manifest.FromBlob(rawManifest, mimeType)
58+
// if err != nil {
59+
// return false, nil
60+
// }
61+
// mInfo, err := m.Inspect(nil)
62+
// if err != nil {
63+
// return false, nil
64+
// }
65+
// return mInfo.Architecture == "arm64", nil
66+
return false, fmt.Errorf("image manifests not supported")
5367
}
68+
}
5469

55-
// This call will error if it cannot find a instance that supports linux arm64
56-
_, err = manifestList.ChooseInstance(sys)
57-
return err == nil, nil
70+
func CheckLatestLinuxArm64Support(imgName string) (bool, error) {
71+
split := strings.Split(imgName, ":")
72+
if len(split) < 2 {
73+
return false, fmt.Errorf("invalid image name")
74+
}
75+
latestImageName := split[0] + ":latest"
76+
return CheckLinuxArm64Support(latestImageName)
5877
}

internal/images/images_test.go

Lines changed: 0 additions & 30 deletions
This file was deleted.

0 commit comments

Comments
 (0)