mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-12-13 10:56:17 +01:00
109 lines
3.0 KiB
Go
109 lines
3.0 KiB
Go
// Copyright (C) NHR@FAU, University Erlangen-Nuremberg.
|
|
// All rights reserved. This file is part of cc-backend.
|
|
// Use of this source code is governed by a MIT-style
|
|
// license that can be found in the LICENSE file.
|
|
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
cclog "github.com/ClusterCockpit/cc-lib/ccLogger"
|
|
)
|
|
|
|
func main() {
|
|
var archivePath string
|
|
var dryRun bool
|
|
var numWorkers int
|
|
var flagLogLevel string
|
|
var flagLogDateTime bool
|
|
|
|
flag.StringVar(&archivePath, "archive", "", "Path to job archive to migrate (required)")
|
|
flag.BoolVar(&dryRun, "dry-run", false, "Preview changes without modifying files")
|
|
flag.IntVar(&numWorkers, "workers", 4, "Number of parallel workers")
|
|
flag.StringVar(&flagLogLevel, "loglevel", "info", "Sets the logging level: `[debug,info,warn (default),err,fatal,crit]`")
|
|
flag.BoolVar(&flagLogDateTime, "logdate", false, "Add date and time to log messages")
|
|
flag.Parse()
|
|
|
|
// Initialize logger
|
|
cclog.Init(flagLogLevel, flagLogDateTime)
|
|
|
|
// Validate inputs
|
|
if archivePath == "" {
|
|
fmt.Fprintf(os.Stderr, "Error: --archive flag is required\n\n")
|
|
flag.Usage()
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Check if archive path exists
|
|
if _, err := os.Stat(archivePath); os.IsNotExist(err) {
|
|
cclog.Fatalf("Archive path does not exist: %s", archivePath)
|
|
}
|
|
|
|
// Check archive version
|
|
if err := checkVersion(archivePath); err != nil {
|
|
cclog.Fatalf("Version check failed: %v", err)
|
|
}
|
|
|
|
// Display warning for non-dry-run mode
|
|
if !dryRun {
|
|
cclog.Warn("WARNING: This will modify files in the archive!")
|
|
cclog.Warn("It is strongly recommended to backup your archive first.")
|
|
cclog.Warn("Run with --dry-run first to preview changes.")
|
|
cclog.Info("")
|
|
|
|
fmt.Print("Are you sure you want to continue? [y/N]: ")
|
|
reader := bufio.NewReader(os.Stdin)
|
|
input, err := reader.ReadString('\n')
|
|
if err != nil {
|
|
cclog.Fatalf("Error reading input: %v", err)
|
|
}
|
|
if strings.ToLower(strings.TrimSpace(input)) != "y" {
|
|
cclog.Info("Aborted by user.")
|
|
os.Exit(0)
|
|
}
|
|
}
|
|
|
|
// Run migration
|
|
migrated, failed, err := migrateArchive(archivePath, dryRun, numWorkers)
|
|
|
|
if err != nil {
|
|
cclog.Errorf("Migration completed with errors: %s", err.Error())
|
|
if failed > 0 {
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
if dryRun {
|
|
cclog.Infof("Dry run completed: %d jobs would be migrated", migrated)
|
|
} else {
|
|
if err := updateVersion(archivePath); err != nil {
|
|
cclog.Errorf("Failed to update archive version: %v", err)
|
|
os.Exit(1)
|
|
}
|
|
cclog.Infof("Migration completed successfully: %d jobs migrated", migrated)
|
|
}
|
|
}
|
|
|
|
func checkVersion(archivePath string) error {
|
|
versionFile := filepath.Join(archivePath, "version.txt")
|
|
data, err := os.ReadFile(versionFile)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to read version.txt: %v", err)
|
|
}
|
|
versionStr := strings.TrimSpace(string(data))
|
|
if versionStr != "2" {
|
|
return fmt.Errorf("archive version is %s, expected 2", versionStr)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func updateVersion(archivePath string) error {
|
|
versionFile := filepath.Join(archivePath, "version.txt")
|
|
return os.WriteFile(versionFile, []byte("3\n"), 0644)
|
|
}
|