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

Add declarative installation #780

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 38 additions & 15 deletions cmd/kubectl-directpv/install.go
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/minio/directpv/pkg/volume"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/version"
)

Expand All @@ -52,6 +53,7 @@ var (
k8sVersion = "1.27.0"
kubeVersion *version.Version
legacyFlag bool
declarativeFlag bool
)

var installCmd = &cobra.Command{
Expand Down Expand Up @@ -122,6 +124,8 @@ func init() {
addOutputFormatFlag(installCmd, "Generate installation manifest. One of: yaml|json")
installCmd.PersistentFlags().StringVar(&k8sVersion, "kube-version", k8sVersion, "Select the kubernetes version for manifest generation")
installCmd.PersistentFlags().BoolVar(&legacyFlag, "legacy", legacyFlag, "Enable legacy mode (Used with '-o')")
installCmd.PersistentFlags().BoolVar(&declarativeFlag, "declarative", declarativeFlag, "Output YAML for declarative installation")
installCmd.PersistentFlags().MarkHidden("declarative")
}

func validateNodeSelectorArgs() error {
Expand Down Expand Up @@ -254,22 +258,26 @@ func getLegacyFlag(ctx context.Context) bool {
func installMain(ctx context.Context) {
legacyFlag = getLegacyFlag(ctx)

auditFile := fmt.Sprintf("install.log.%v", time.Now().UTC().Format(time.RFC3339Nano))
file, err := openAuditFile(auditFile)
if err != nil {
utils.Eprintf(quietFlag, true, "unable to open audit file %v; %v\n", auditFile, err)
utils.Eprintf(false, false, "%v\n", color.HiYellowString("Skipping audit logging"))
}
var file *utils.SafeFile
var err error
if dryRunPrinter == nil && !declarativeFlag {
auditFile := fmt.Sprintf("install.log.%v", time.Now().UTC().Format(time.RFC3339Nano))
file, err = openAuditFile(auditFile)
if err != nil {
utils.Eprintf(quietFlag, true, "unable to open audit file %v; %v\n", auditFile, err)
utils.Eprintf(false, false, "%v\n", color.HiYellowString("Skipping audit logging"))
}

defer func() {
if file != nil {
if err := file.Close(); err != nil {
utils.Eprintf(quietFlag, true, "unable to close audit file; %v\n", err)
defer func() {
if file != nil {
if err := file.Close(); err != nil {
utils.Eprintf(quietFlag, true, "unable to close audit file; %v\n", err)
}
}
}
}()
}()
}

args, err := installer.NewArgs(image, file)
args := installer.NewArgs(image)
if err != nil {
utils.Eprintf(quietFlag, true, "%v\n", err)
os.Exit(1)
Expand All @@ -285,12 +293,27 @@ func installMain(ctx context.Context) {
args.Quiet = quietFlag
args.KubeVersion = kubeVersion
args.Legacy = legacyFlag
args.DryRunPrinter = dryRunPrinter
if file != nil {
args.ObjectWriter = file
}
if dryRunPrinter != nil {
args.DryRun = true
if outputFormat == "yaml" {
args.ObjectMarshaler = func(obj runtime.Object) ([]byte, error) {
return utils.ToYAML(obj)
}
} else {
args.ObjectMarshaler = func(obj runtime.Object) ([]byte, error) {
return utils.ToJSON(obj)
}
}
}
args.Declarative = declarativeFlag

var failed bool
var installedComponents []installer.Component
var wg sync.WaitGroup
if dryRunPrinter == nil && !quietFlag {
if dryRunPrinter == nil && !declarativeFlag && !quietFlag {
m := newProgressModel(true)
teaProgram := tea.NewProgram(m)
wg.Add(1)
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubectl-directpv/list_drives.go
Expand Up @@ -138,7 +138,7 @@ func listDrivesMain(ctx context.Context) {
driveList := types.DriveList{
TypeMeta: metav1.TypeMeta{
Kind: "List",
APIVersion: string(directpvtypes.VersionLabelKey),
APIVersion: "v1",
},
Items: drives,
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubectl-directpv/list_volumes.go
Expand Up @@ -179,7 +179,7 @@ func listVolumesMain(ctx context.Context) {
volumeList := types.VolumeList{
TypeMeta: metav1.TypeMeta{
Kind: "List",
APIVersion: string(directpvtypes.VersionLabelKey),
APIVersion: "v1",
},
Items: volumes,
}
Expand Down
32 changes: 31 additions & 1 deletion cmd/kubectl-directpv/migrate.go
Expand Up @@ -21,13 +21,16 @@ import (
"fmt"
"os"
"strings"
"time"

"github.com/minio/directpv/pkg/consts"
"github.com/minio/directpv/pkg/installer"
"github.com/minio/directpv/pkg/utils"
"github.com/spf13/cobra"
)

var retainFlag bool

var migrateCmd = &cobra.Command{
Use: "migrate",
Short: "Migrate drives and volumes from legacy DirectCSI",
Expand All @@ -51,18 +54,45 @@ func init() {
migrateCmd.PersistentFlags().SortFlags = false

addDryRunFlag(migrateCmd, "Run in dry run mode")
migrateCmd.PersistentFlags().BoolVar(&retainFlag, "retain", retainFlag, "retain legacy CRD after migration")
}

func migrateMain(ctx context.Context) {
if err := installer.Migrate(ctx, &installer.Args{
Quiet: quietFlag,
Legacy: true,
}); err != nil {
}, false); err != nil {
utils.Eprintf(quietFlag, true, "migration failed; %v", err)
os.Exit(1)
}

if !quietFlag {
fmt.Println("Migration successful; Please restart the pods in '" + consts.AppName + "' namespace.")
}

if retainFlag {
return
}

suffix := time.Now().Format(time.RFC3339)

drivesBackupFile := "directcsidrives-" + suffix + ".yaml"
backupCreated, err := installer.RemoveLegacyDrives(ctx, drivesBackupFile)
if err != nil {
utils.Eprintf(quietFlag, true, "unable to remove legacy drive CRDs; %v", err)
os.Exit(1)
}
if backupCreated && !quietFlag {
fmt.Println("Legacy drive CRDs backed up to", drivesBackupFile)
}

volumesBackupFile := "directcsivolumes-" + suffix + ".yaml"
backupCreated, err = installer.RemoveLegacyVolumes(ctx, volumesBackupFile)
if err != nil {
utils.Eprintf(quietFlag, true, "unable to remove legacy volume CRDs; %v", err)
os.Exit(1)
}
if backupCreated && !quietFlag {
fmt.Println("Legacy volume CRDs backed up to", volumesBackupFile)
}
}
20 changes: 17 additions & 3 deletions cmd/kubectl-directpv/utils.go
Expand Up @@ -28,16 +28,27 @@ import (
"github.com/minio/directpv/pkg/consts"
"github.com/minio/directpv/pkg/utils"
"github.com/mitchellh/go-homedir"
"k8s.io/klog/v2"
)

const dot = "•"

func printYAML(obj interface{}) {
fmt.Print(utils.MustGetYAML(obj))
data, err := utils.ToYAML(obj)
if err != nil {
klog.Fatalf("unable to marshal object to YAML; %w", err)
}

fmt.Print(string(data))
}

func printJSON(obj interface{}) {
fmt.Print(utils.MustGetJSON(obj))
data, err := utils.ToJSON(obj)
if err != nil {
klog.Fatalf("unable to marshal object to JSON; %w", err)
}

fmt.Print(string(data))
}

func getDefaultAuditDir() (string, error) {
Expand Down Expand Up @@ -109,7 +120,10 @@ func validateOutputFormat(isWideSupported bool) error {
case "json":
dryRunPrinter = printJSON
default:
return errors.New("--output flag value must be one of wide|json|yaml or empty")
if isWideSupported {
return errors.New("--output flag value must be one of wide|json|yaml or empty")
}
return errors.New("--output flag value must be one of yaml|json")
}
return nil
}