Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add the unified metadata manager #158

Merged
merged 6 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: add the metadata manager
  • Loading branch information
zyy17 committed Oct 8, 2023
commit b2dfc677b463850f7694e18b20db2f73e025e177
9 changes: 7 additions & 2 deletions pkg/artifacts/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ type Source struct {
type DownloadOptions struct {
// If UseCache is true, the manager will use the cache if the artifact already exists.
UseCache bool

// If the artifact is a binary, the manager will install the binary to the BinaryInstallDir after downloading its package.
BinaryInstallDir string
}

// manager is the implementation of Manager interface.
Expand Down Expand Up @@ -222,8 +225,10 @@ func (m *manager) DownloadTo(ctx context.Context, from *Source, destDir string,
}

if from.Type == ArtifactTypeBinary {
installDir := filepath.Join(filepath.Dir(destDir), "bin")
if err := m.installBinaries(artifactFile, installDir); err != nil {
if opts.BinaryInstallDir == "" {
return "", fmt.Errorf("binary install dir is empty")
}
if err := m.installBinaries(artifactFile, opts.BinaryInstallDir); err != nil {
return "", err
}
return filepath.Join(filepath.Dir(destDir), "bin", from.Name), nil
Expand Down
3 changes: 2 additions & 1 deletion pkg/artifacts/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"fmt"
"os"
"path/filepath"
"testing"

"sigs.k8s.io/kind/pkg/log"
Expand Down Expand Up @@ -146,7 +147,7 @@ func TestDownloadBinaries(t *testing.T) {
if err != nil {
t.Errorf("failed to create source: %v", err)
}
artifactFile, err := m.DownloadTo(ctx, src, destDir(tempDir, src), &DownloadOptions{UseCache: false})
artifactFile, err := m.DownloadTo(ctx, src, destDir(tempDir, src), &DownloadOptions{UseCache: false, BinaryInstallDir: filepath.Join(filepath.Dir(destDir(tempDir, src)), "bin")})
if err != nil {
t.Errorf("failed to download: %v", err)
}
Expand Down
30 changes: 19 additions & 11 deletions pkg/helm/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"context"
"fmt"
"os"
"path/filepath"
"reflect"
"strings"

Expand All @@ -31,6 +30,7 @@ import (

"github.com/GreptimeTeam/gtctl/pkg/artifacts"
"github.com/GreptimeTeam/gtctl/pkg/logger"
"github.com/GreptimeTeam/gtctl/pkg/metadata"
)

const (
Expand All @@ -39,7 +39,7 @@ const (

var (
// KubeVersion is the target version of the kubernetes.
KubeVersion string = "v1.20.0"
KubeVersion = "v1.20.0"
)

// Manager is the Helm charts manager. The implementation is based on Helm SDK.
Expand All @@ -50,11 +50,11 @@ type Manager struct {
// logger is the logger for the Manager.
logger logger.Logger

// artifactsManager is the artifacts manager to manage charts.
// am is the artifacts manager to manage charts.
am artifacts.Manager

// metadataDir is the directory to store the metadata of the gtctl.
metadataDir string
// mm is the metadata manager to manage the metadata.
mm metadata.Manager
}

type Option func(*Manager)
Expand All @@ -68,12 +68,11 @@ func NewManager(l logger.Logger, opts ...Option) (*Manager, error) {
}
r.am = am

// TODO(zyy17): The metadataDir will be managed by the independent manager in the future.
homeDir, err := os.UserHomeDir()
mm, err := metadata.New("")
if err != nil {
return nil, err
}
r.metadataDir = filepath.Join(homeDir, ".gtctl")
r.mm = mm

for _, opt := range opts {
opt(r)
Expand All @@ -82,9 +81,14 @@ func NewManager(l logger.Logger, opts ...Option) (*Manager, error) {
return r, nil
}

func WithMetadataDir(dir string) Option {
func WithHomeDir(dir string) Option {
return func(r *Manager) {
r.metadataDir = dir
metadataManager, err := metadata.New(dir)
if err != nil {
r.logger.Errorf("failed to create metadata manager: %v", err)
os.Exit(1)
}
r.mm = metadataManager
}
}

Expand All @@ -105,7 +109,11 @@ func (r *Manager) LoadAndRenderChart(ctx context.Context, name, namespace, chart
return nil, err
}

destDir := filepath.Join(r.metadataDir, "artifacts", "charts", chartName, chartVersion)
destDir, err := r.mm.AllocateArtifactFilePath(src, false)
if err != nil {
return nil, err
}

chartFile, err := r.am.DownloadTo(ctx, src, destDir, &artifacts.DownloadOptions{UseCache: true})
if err != nil {
return nil, err
Expand Down
89 changes: 89 additions & 0 deletions pkg/metadata/manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright 2023 Greptime Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package metadata

import (
"fmt"
"os"
"path/filepath"

"github.com/GreptimeTeam/gtctl/pkg/artifacts"
)

// Manager is the interface of the metadata manager.
// The metadata manager is responsible for managing all the metadata of gtctl.
type Manager interface {
// AllocateArtifactFilePath allocates the file path of the artifact.
AllocateArtifactFilePath(src *artifacts.Source, installBinary bool) (string, error)

// SetHomeDir sets the home directory of the metadata manager.
SetHomeDir(dir string) error

// Clean cleans up all the metadata. It will remove the working directory.
Clean() error
}

const (
// BaseDir is the working directory of gtctl and all the metadata will be stored in ${HomeDir}/${BaseDir}.
BaseDir = ".gtctl"
)

type manager struct {
workingDir string
}

var _ Manager = &manager{}

func New(homeDir string) (Manager, error) {
m := &manager{}
if homeDir == "" {
dir, err := os.UserHomeDir()
if err != nil {
return nil, err
}
m.workingDir = filepath.Join(dir, BaseDir)
} else {
m.workingDir = filepath.Join(homeDir, BaseDir)
}

return m, nil
}

func (m *manager) AllocateArtifactFilePath(src *artifacts.Source, installBinary bool) (string, error) {
var filePath string
switch src.Type {
case artifacts.ArtifactTypeChart:
filePath = filepath.Join(m.workingDir, "artifacts", "charts", src.Name, src.Version, "pkg")
case artifacts.ArtifactTypeBinary:
if installBinary {
filePath = filepath.Join(m.workingDir, "artifacts", "binaries", src.Name, src.Version, "bin")
} else {
filePath = filepath.Join(m.workingDir, "artifacts", "binaries", src.Name, src.Version, "pkg")
}
default:
return "", fmt.Errorf("unknown artifact type: %s", src.Type)
}

return filePath, nil
}

func (m *manager) SetHomeDir(dir string) error {
m.workingDir = filepath.Join(dir, BaseDir)
return nil
}

func (m *manager) Clean() error {
return os.RemoveAll(m.workingDir)
}