Skip to content

Commit

Permalink
Merge pull request #101 from iawia002/icon
Browse files Browse the repository at this point in the history
Unify the parsing process of extension metadata
  • Loading branch information
iawia002 authored Jun 27, 2024
2 parents 7d3a772 + 382d7f4 commit edce88b
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 84 deletions.
16 changes: 3 additions & 13 deletions cmd/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/spf13/cobra"
"helm.sh/helm/v3/pkg/chart/loader"
Expand Down Expand Up @@ -48,12 +47,12 @@ func (o *pushOptions) push(_ *cobra.Command, args []string) error {
return err
}

metadata, err := extension.LoadMetadata(tempDir)
metadata, err := extension.LoadMetadata(tempDir, extension.WithEncodeIcon(false))
if err != nil {
return err
}
// upload images to cloud
if needUpload(metadata.Icon) {
if extension.IsLocalFile(metadata.Icon) {
resp, err := client.UploadFiles(metadata.Name, metadata.Version, tempDir, metadata.Icon)
if err != nil {
return err
Expand All @@ -63,7 +62,7 @@ func (o *pushOptions) push(_ *cobra.Command, args []string) error {
screenshots := make([]string, 0)
localScreenshots := make([]string, 0)
for _, p := range metadata.Screenshots {
if needUpload(p) {
if extension.IsLocalFile(p) {
localScreenshots = append(localScreenshots, p)
} else {
screenshots = append(screenshots, p)
Expand Down Expand Up @@ -125,12 +124,3 @@ func (o *pushOptions) push(_ *cobra.Command, args []string) error {
fmt.Println("Extension pushed and submitted to KubeSphere Cloud, waiting for review")
return nil
}

func needUpload(path string) bool {
if strings.HasPrefix(path, "http://") ||
strings.HasPrefix(path, "https://") ||
strings.HasPrefix(path, "data:image") {
return false
}
return true
}
37 changes: 30 additions & 7 deletions pkg/extension/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,42 @@ import (

const MetadataFilename = "extension.yaml"

func LoadMetadata(path string) (*Metadata, error) {
content, err := os.ReadFile(path + "/" + MetadataFilename)
type Options struct {
encodeIcon bool
}

func WithEncodeIcon(encodeIcon bool) func(opts *Options) {
return func(opts *Options) {
opts.encodeIcon = encodeIcon
}
}

func LoadMetadata(path string, options ...func(*Options)) (*Metadata, error) {
opts := &Options{
encodeIcon: true,
}
for _, f := range options {
f(opts)
}

content, err := os.ReadFile(ospath.Join(path, MetadataFilename))
if err != nil {
return nil, err
}
metadata := new(Metadata)
if err = yaml.Unmarshal(content, metadata); err != nil {
metadata, err := ParseMetadata(content)
if err != nil {
return nil, err
}
if err = metadata.Validate(); err != nil {
return nil, err

if IsLocalFile(metadata.Icon) && opts.encodeIcon {
base64EncodedIcon, err := encodeIcon(ospath.Join(path, metadata.Icon))
if err != nil {
return nil, err
}
metadata.Icon = base64EncodedIcon
}
if err = metadata.Init(path); err != nil {

if err = metadata.Validate(); err != nil {
return nil, err
}
return metadata, nil
Expand Down
51 changes: 26 additions & 25 deletions pkg/extension/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1alpha1 "kubesphere.io/api/core/v1alpha1"
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"

"github.com/kubesphere/ksbuilder/pkg/iso639"
)
Expand Down Expand Up @@ -57,8 +58,19 @@ type Metadata struct {
Namespace string `json:"namespace,omitempty"`
Images []string `json:"images,omitempty"`
ExternalDependencies []corev1alpha1.ExternalDependency `json:"externalDependencies,omitempty"`
}

func ParseMetadata(data []byte) (*Metadata, error) {
metadata := new(Metadata)
if err := yaml.Unmarshal(data, metadata); err != nil {
return nil, err
}

base64EncodedIcon string
// set default value for necessary fields
if metadata.InstallationMode == "" {
metadata.InstallationMode = corev1alpha1.InstallationModeHostOnly
}
return metadata, nil
}

func validateLanguageCode(code corev1alpha1.LanguageCode) error {
Expand Down Expand Up @@ -94,19 +106,6 @@ func (md *Metadata) Validate() error {
return md.validateLanguageCode()
}

func (md *Metadata) Init(root string) error {
if md.InstallationMode == "" {
md.InstallationMode = corev1alpha1.InstallationModeHostOnly
}

icon, err := encodeIcon(root, md.Icon)
if err != nil {
return err
}
md.base64EncodedIcon = icon
return nil
}

func (md *Metadata) ToChartYaml() (*chart.Metadata, error) {
var c = chart.Metadata{
APIVersion: chart.APIVersionV2,
Expand All @@ -118,21 +117,23 @@ func (md *Metadata) ToChartYaml() (*chart.Metadata, error) {
Home: md.Home,
Dependencies: md.Dependencies,
Description: string(md.Description[corev1alpha1.DefaultLanguageCode]),
Icon: md.base64EncodedIcon,
Icon: md.Icon,
Maintainers: md.Maintainers,
}
return &c, nil
}

func encodeIcon(root, iconPath string) (string, error) {
// If the icon is url or base64, you can use it directly.
// Otherwise, load the file encoding as base64
if strings.HasPrefix(iconPath, "http://") ||
strings.HasPrefix(iconPath, "https://") ||
strings.HasPrefix(iconPath, "data:image") {
return iconPath, nil
func IsLocalFile(path string) bool {
if strings.HasPrefix(path, "http://") ||
strings.HasPrefix(path, "https://") ||
strings.HasPrefix(path, "data:image") {
return false
}
content, err := os.ReadFile(path.Join(root, iconPath))
return true
}

func encodeIcon(iconPath string) (string, error) {
content, err := os.ReadFile(iconPath)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -192,7 +193,7 @@ func (ext *Extension) ToKubernetesResources() []runtimeclient.Object {
ExtensionInfo: corev1alpha1.ExtensionInfo{
Description: ext.Metadata.Description,
DisplayName: ext.Metadata.DisplayName,
Icon: ext.Metadata.base64EncodedIcon,
Icon: ext.Metadata.Icon,
Provider: ext.Metadata.Provider,
Created: metav1.Now(),
},
Expand All @@ -218,7 +219,7 @@ func (ext *Extension) ToKubernetesResources() []runtimeclient.Object {
ExtensionInfo: corev1alpha1.ExtensionInfo{
Description: ext.Metadata.Description,
DisplayName: ext.Metadata.DisplayName,
Icon: ext.Metadata.base64EncodedIcon,
Icon: ext.Metadata.Icon,
Provider: ext.Metadata.Provider,
Created: metav1.Now(),
},
Expand Down
35 changes: 1 addition & 34 deletions pkg/parser/extension.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
package parser

import (
"encoding/base64"
"fmt"
"mime"
"net/http"
"path"
"strings"

"helm.sh/helm/v3/pkg/chart"
"k8s.io/apimachinery/pkg/util/sets"
corev1alpha1 "kubesphere.io/api/core/v1alpha1"
"sigs.k8s.io/yaml"

"github.com/kubesphere/ksbuilder/pkg/extension"
"github.com/kubesphere/ksbuilder/pkg/utils"
Expand All @@ -37,7 +32,7 @@ func ParseExtension(name string, zipFile []byte) (*Extension, error) {
return nil, err
}

metadata, err := parseMetadata(name, data)
metadata, err := extension.ParseMetadata(data[path.Join(name, extension.MetadataFilename)])
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -81,31 +76,3 @@ func ParseExtension(name string, zipFile []byte) (*Extension, error) {
Docs: metadata.Docs,
}, nil
}

func parseMetadata(name string, data map[string][]byte) (*extension.Metadata, error) {
metadata := new(extension.Metadata)
if err := yaml.Unmarshal(data[path.Join(name, extension.MetadataFilename)], metadata); err != nil {
return nil, err
}
if err := metadata.Validate(); err != nil {
return nil, fmt.Errorf("validate the extension metadata failed: %s", err.Error())
}
if strings.HasPrefix(metadata.Icon, "http://") ||
strings.HasPrefix(metadata.Icon, "https://") ||
strings.HasPrefix(metadata.Icon, "data:image") {
return metadata, nil
}

iconData := data[path.Join(name, metadata.Icon)]

var base64Encoding string
mimeType := mime.TypeByExtension(path.Ext(metadata.Icon))
if mimeType == "" {
mimeType = http.DetectContentType(iconData)
}

base64Encoding += "data:" + mimeType + ";base64,"
base64Encoding += base64.StdEncoding.EncodeToString(iconData)
metadata.Icon = base64Encoding
return metadata, nil
}
8 changes: 3 additions & 5 deletions pkg/parser/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
"io"
"path"

"sigs.k8s.io/yaml"

"github.com/kubesphere/ksbuilder/pkg/extension"
)

Expand Down Expand Up @@ -42,9 +40,9 @@ func ValidateExtension(name string, zipFile []byte) error {
if _, err = io.ReadFull(tr, buffer); err != nil && err != io.EOF {
return fmt.Errorf("read tar file failed: %s", err.Error())
}
metadata := new(extension.Metadata)
if err = yaml.Unmarshal(buffer, metadata); err != nil {
return fmt.Errorf("unmarshal the extension metadata failed: %s", err.Error())
metadata, err := extension.ParseMetadata(buffer)
if err != nil {
return fmt.Errorf("parse the extension metadata failed: %s", err.Error())
}
if err = metadata.Validate(); err != nil {
return fmt.Errorf("validate the extension metadata failed: %s", err.Error())
Expand Down

0 comments on commit edce88b

Please sign in to comment.