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

Support configuration file for export command #55

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,38 @@ run the command for more information:
### on target server
- **Run command: `inter-server-sync import --importDir ~/export/`

## Use configuration file
Create a file named `config.json`:

```json
{
"logLevel": "info",
"serverConfig": "/path/to/rhn.conf",
"cpuProfile": "/path/to/cpu/profile/folder",
"memProfile": "/path/to/memory/profile/folder",

"channelWithChildren": ["childChannel0", "childChannel1"],
"channels": ["testchannel", "channel0"],
"configChannels": ["configChannel0", "configChannel1"],
"containers": true,
"images": true,
"metadataOnly": true,
"orgLimit": [1, 2],
"outputDir": "~/export",
"packagesOnlyAfter": "2023-05-04 16:31:58",

"importDir": "~/export",
"xmlRpcUser": "WordlessEcho",
"xmlRpcPassword": "W0rd1essEch0"
}
```

Then run with:
```
inter-server-sync export --config /path/to/export.json
inter-server-sync import --config /path/to/export.json
```

## Database connection configuration

Database connection configuration are loaded by default from `/etc/rhn/rhn.conf`.
Expand Down
46 changes: 34 additions & 12 deletions cmd/export.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package cmd

import (
"os"
"path"

"encoding/json"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/uyuni-project/inter-server-sync/entityDumper"
"github.com/uyuni-project/inter-server-sync/utils"
"os"
"path"
)

var exportCmd = &cobra.Command{
Expand All @@ -27,15 +28,20 @@ var includeContainers bool
var orgs []uint

func init() {
exportCmd.Flags().StringSliceVar(&channels, "channels", nil, "Channels to be exported")
exportCmd.Flags().StringSliceVar(&channelWithChildren, "channel-with-children", nil, "Channels to be exported")
exportCmd.Flags().StringVar(&outputDir, "outputDir", ".", "Location for generated data")
exportCmd.Flags().BoolVar(&metadataOnly, "metadataOnly", false, "export only metadata")
exportCmd.Flags().StringVar(&startingDate, "packagesOnlyAfter", "", "Only export packages added or modified after the specified date (date format can be 'YYYY-MM-DD' or 'YYYY-MM-DD hh:mm:ss')")
exportCmd.Flags().StringSliceVar(&configChannels, "configChannels", nil, "Configuration Channels to be exported")
exportCmd.Flags().BoolVar(&includeImages, "images", false, "Export OS images and associated metadata")
exportCmd.Flags().BoolVar(&includeContainers, "containers", false, "Export containers metadata")
exportCmd.Flags().UintSliceVar(&orgs, "orgLimit", nil, "Export only for specified organizations")
exportCmd.Flags().StringSlice("channels", nil, "Channels to be exported")
exportCmd.Flags().StringSlice("channelWithChildren", nil, "Channels to be exported")
exportCmd.Flags().String("outputDir", ".", "Location for generated data")
exportCmd.Flags().Bool("metadataOnly", false, "export only metadata")
exportCmd.Flags().String("packagesOnlyAfter", "", "Only export packages added or modified after the specified date (date format can be 'YYYY-MM-DD' or 'YYYY-MM-DD hh:mm:ss')")
exportCmd.Flags().StringSlice("configChannels", nil, "Configuration Channels to be exported")
exportCmd.Flags().Bool("images", false, "Export OS images and associated metadata")
exportCmd.Flags().Bool("containers", false, "Export containers metadata")
exportCmd.Flags().UintSlice("orgLimit", nil, "Export only for specified organizations")

if err := viper.BindPFlags(exportCmd.Flags()); err != nil {
log.Fatal().Err(err).Msg("Failed to bind PFlags")
}

exportCmd.Args = cobra.NoArgs

rootCmd.AddCommand(exportCmd)
Expand All @@ -45,6 +51,22 @@ func runExport(cmd *cobra.Command, args []string) {
log.Info().Msg("Export started")
// check output dir existence and create it if needed.

channels = viper.GetStringSlice("channels")
channelWithChildren = viper.GetStringSlice("channelWithChildren")
outputDir = viper.GetString("outputDir")
metadataOnly = viper.GetBool("metadataOnly")
startingDate = viper.GetString("packagesOnlyAfter")
configChannels = viper.GetStringSlice("configChannels")
includeImages = viper.GetBool("images")
includeContainers = viper.GetBool("containers")
// https://github.com/spf13/viper/issues/926
rawOrgs := viper.GetString("orgLimit")
var parsedOrgs []uint
if err := json.Unmarshal([]byte(rawOrgs), &parsedOrgs); err != nil {
log.Panic().Err(err).Msg("Failed to parse orgLimit")
}
orgs = parsedOrgs

// Validate data
validatedDate, ok := utils.ValidateDate(startingDate)
if !ok {
Expand Down
15 changes: 12 additions & 3 deletions cmd/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"fmt"
"github.com/spf13/viper"
"io"
"os"
"os/exec"
Expand All @@ -26,16 +27,24 @@ var xmlRpcUser string
var xmlRpcPassword string

func init() {
importCmd.Flags().String("importDir", ".", "Location import data from")
importCmd.Flags().String("xmlRpcUser", "admin", "A username to access the XML-RPC Api")
importCmd.Flags().String("xmlRpcPassword", "admin", "A password to access the XML-RPC Api")

if err := viper.BindPFlags(importCmd.Flags()); err != nil {
log.Fatal().Err(err).Msg("Failed to bind PFlags")
}

importCmd.Flags().StringVar(&importDir, "importDir", ".", "Location import data from")
importCmd.Flags().StringVar(&xmlRpcUser, "xmlRpcUser", "admin", "A username to access the XML-RPC Api")
importCmd.Flags().StringVar(&xmlRpcPassword, "xmlRpcPassword", "admin", "A password to access the XML-RPC Api")
importCmd.Args = cobra.NoArgs

rootCmd.AddCommand(importCmd)
}

func runImport(cmd *cobra.Command, args []string) {
importDir = viper.GetString("importDir")
xmlRpcUser = viper.GetString("xmlRpcUser")
xmlRpcPassword = viper.GetString("xmlRpcPassword")

absImportDir := utils.GetAbsPath(importDir)
log.Info().Msg(fmt.Sprintf("starting import from dir %s", absImportDir))
fversion, fproduct := getImportVersionProduct(absImportDir)
Expand Down
35 changes: 30 additions & 5 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package cmd

import (
"fmt"
"github.com/spf13/viper"
"github.com/uyuni-project/inter-server-sync/utils"
"log/syslog"
"os"
"runtime/pprof"
Expand All @@ -24,25 +26,48 @@ func Execute() {
cobra.CheckErr(rootCmd.Execute())
}

//var cfgFile string
var cfgFile string
var logLevel string
var serverConfig string
var cpuProfile string
var memProfile string

func init() {
cobra.OnInitialize(initConfig)

rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "Location of configuration file")
rootCmd.PersistentFlags().String("logLevel", "error", "application log level")
rootCmd.PersistentFlags().String("serverConfig", "/etc/rhn/rhn.conf", "Server configuration file")
rootCmd.PersistentFlags().String("cpuProfile", "", "cpuProfile export folder location")
rootCmd.PersistentFlags().String("memProfile", "", "memProfile export folder location")

if err := viper.BindPFlags(rootCmd.PersistentFlags()); err != nil {
log.Fatal().Err(err).Msg("Failed to bind PFlags")
}

rootCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
logLevel = viper.GetString("logLevel")
cpuProfile = viper.GetString("cpuProfile")
memProfile = viper.GetString("memProfile")
serverConfig = viper.GetString("serverConfig")

logInit()
cpuProfileInit()
memProfileDump()
}
rootCmd.PersistentPostRun = func(cmd *cobra.Command, args []string) {
cpuProfileTearDown()
}
rootCmd.PersistentFlags().StringVar(&logLevel, "logLevel", "error", "application log level")
rootCmd.PersistentFlags().StringVar(&serverConfig, "serverConfig", "/etc/rhn/rhn.conf", "Server configuration file")
rootCmd.PersistentFlags().StringVar(&cpuProfile, "cpuProfile", "", "cpuProfile export folder location")
rootCmd.PersistentFlags().StringVar(&memProfile, "memProfile", "", "memProfile export folder location")
}

func initConfig() {
if cfgFile != "" {
viper.SetConfigFile(utils.GetAbsPath(cfgFile))

if err := viper.ReadInConfig(); err != nil {
log.Panic().Err(err).Msg("Failed to read config file")
}
}
}

func logCallerMarshalFunction(file string, line int) string {
Expand Down
3 changes: 1 addition & 2 deletions entityDumper/dumper.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ package entityDumper
import (
"bufio"
"compress/gzip"
"os"

"github.com/rs/zerolog/log"
"github.com/uyuni-project/inter-server-sync/schemareader"
"os"
)

func DumpAllEntities(options DumperOptions) {
Expand Down
14 changes: 14 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ require (
)

require (
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/spf13/afero v1.9.3 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.15.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading