215 lines
5.8 KiB
Go
215 lines
5.8 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
|
|
"github.com/Nathan13888/mirror-checker2/v2/checkers"
|
|
"github.com/Nathan13888/mirror-checker2/v2/config"
|
|
"github.com/Nathan13888/mirror-checker2/v2/web"
|
|
"github.com/rs/zerolog/log"
|
|
"github.com/urfave/cli/v2"
|
|
)
|
|
|
|
var configPath string
|
|
|
|
func loadConfig() {
|
|
path := config.GetAbsPath(configPath)
|
|
// TODO: check if file exists
|
|
|
|
log.Info().Str("path", path).Msg("Loading config file.")
|
|
err := checkers.LoadFromFile(path)
|
|
if err != nil {
|
|
log.Fatal().Err(err).Msg("Failed to load config file.")
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
config.SetupLogger(true) // TODO: flag for debug mode
|
|
|
|
// TODO: give option to give checker a particular name (or autogen one)
|
|
|
|
// Start CLI
|
|
// TODO: documentation - https://cli.urfave.org/v2/examples/full-api-example/
|
|
app := &cli.App{
|
|
Name: "CSC Mirror Checker 2",
|
|
Usage: "sees if the mirror is up!",
|
|
Version: config.BuildVersion,
|
|
EnableBashCompletion: true,
|
|
// https://cli.urfave.org/v2/examples/combining-short-options/
|
|
// TODO: flags for config file (mirrors.json), defaults to mirrors.json
|
|
Flags: []cli.Flag{
|
|
&cli.StringFlag{
|
|
Name: "config",
|
|
Aliases: []string{"c"},
|
|
Usage: "path to config file",
|
|
Destination: &configPath,
|
|
Value: "data/mirrors.json",
|
|
EnvVars: []string{"MC_CONFIG_FILE"},
|
|
},
|
|
},
|
|
Commands: []*cli.Command{
|
|
{
|
|
Name: "daemon",
|
|
Aliases: []string{"s", "d", "serve", "web", "server"},
|
|
Usage: "starts web API",
|
|
Action: func(cCtx *cli.Context) error {
|
|
// TODO: flags for port, listen address
|
|
// TODO: flag --config or --stdin-config
|
|
|
|
// TODO: enable all projects by default
|
|
// checkers.LoadDefaultProjects()
|
|
|
|
loadConfig()
|
|
|
|
return web.StartServer()
|
|
},
|
|
},
|
|
{
|
|
Name: "list",
|
|
Usage: "lists all available projects",
|
|
Action: func(cCtx *cli.Context) error {
|
|
loadConfig()
|
|
|
|
log.Info().Msg("Listing supported projects")
|
|
|
|
projects := checkers.SupportedProjects
|
|
for _, proj := range projects {
|
|
status := "supported"
|
|
// check if project is in enabled list
|
|
// TODO: ...
|
|
|
|
// supported checkers
|
|
var checkers []string
|
|
for _, c := range proj.Checkers {
|
|
checkers = append(checkers, c.Name)
|
|
}
|
|
|
|
log.Info().Str("project", proj.Name).
|
|
Str("status", status).
|
|
Strs("checkers", checkers).
|
|
Msg("Supported project.")
|
|
|
|
// list configs
|
|
log.Info().
|
|
Str("project", proj.Name).
|
|
Int("num_checkers", proj.NumOfCheckers).
|
|
Time("out_of_sync_since", proj.Properties.OOSSince).
|
|
Int64("out_of_sync_interval", proj.Properties.OOSInterval).
|
|
Str("csc", proj.Properties.CSC).
|
|
Strs("mirrors", proj.Properties.Mirrors).
|
|
Str("upstream", proj.Properties.Upstream).
|
|
Str("file", proj.Properties.File).
|
|
Msg("Found project config.")
|
|
}
|
|
|
|
return nil
|
|
},
|
|
},
|
|
{
|
|
Name: "check",
|
|
Aliases: []string{"c"},
|
|
Usage: "checks particular mirror (once)",
|
|
Flags: []cli.Flag{
|
|
&cli.BoolFlag{
|
|
Name: "all",
|
|
Aliases: []string{"a"},
|
|
Usage: "check all (supported) mirrors",
|
|
Value: false,
|
|
},
|
|
},
|
|
Action: func(cCtx *cli.Context) error {
|
|
checkers.LoadDefaultProjects()
|
|
loadConfig()
|
|
|
|
// attempt to look up and check all projects
|
|
var projects []string
|
|
|
|
if cCtx.Bool("all") {
|
|
// iterate through all supported projects and add names
|
|
for _, proj := range checkers.SupportedProjects {
|
|
projects = append(projects, proj.Name)
|
|
}
|
|
} else {
|
|
projects = cCtx.Args().Slice()
|
|
if len(projects) == 0 {
|
|
log.Fatal().Msg("No projects specified.")
|
|
}
|
|
}
|
|
|
|
checkers.StartWorkers()
|
|
|
|
log.Debug().Msgf("Checking all specified projects.")
|
|
|
|
for _, arg := range projects {
|
|
log.Info().Msgf("Pulling project information for '%s'.", arg)
|
|
proj, err := checkers.LoadProject(arg)
|
|
if err != nil {
|
|
log.Fatal().Err(err).
|
|
Str("project", arg).
|
|
Msg("Failed to load project.")
|
|
return err
|
|
}
|
|
|
|
res, err := proj.RunChecks(nil)
|
|
// res, err := proj.RunChecks(func(res checkers.CheckerResult) {
|
|
// // if res.Error != nil {
|
|
// // log.Error().Err(res.Error).
|
|
// // Time("time", res.Time).
|
|
// // Msgf("Failed check %s for project %s", res.CheckerName, res.ProjectName)
|
|
// // } else {
|
|
// // log.Info().
|
|
// // Time("time", res.Time).
|
|
// // Str("status", string(res.Status)).
|
|
// // Msgf("Completed check %s for project %s", res.CheckerName, res.ProjectName)
|
|
// // }
|
|
// })
|
|
|
|
if err != nil {
|
|
// code is shit whoopsies
|
|
log.Fatal().Err(err).Msg("Failed to check project.")
|
|
}
|
|
|
|
status := <-*res.FinalStatus
|
|
if status == checkers.CHECKER_ERROR {
|
|
log.Error().Err(err).
|
|
Str("project", arg).
|
|
Msg("Failed to check project.")
|
|
continue
|
|
}
|
|
|
|
if status == checkers.CHECKER_FAIL {
|
|
log.Error().Str("final_status", string(status)).
|
|
Str("project", arg).
|
|
Msg("Error found when checking project.")
|
|
continue
|
|
}
|
|
|
|
log.Info().Str("final_status", string(status)).
|
|
Msgf("Completed all checks for project `%s`", arg)
|
|
}
|
|
|
|
checkers.StopWorkers()
|
|
|
|
return nil
|
|
},
|
|
// TODO: auto complete available mirrors, https://cli.urfave.org/v2/examples/combining-short-options/
|
|
// BashComplete: func(cCtx *cli.Context) {
|
|
// // This will complete if no args are passed
|
|
// if cCtx.NArg() > 0 {
|
|
// return
|
|
// }
|
|
// for _, t := range config.Mirrors {
|
|
// log.Println(t)
|
|
// }
|
|
// },
|
|
},
|
|
},
|
|
}
|
|
|
|
cli.VersionPrinter = config.PrintVersion
|
|
|
|
if err := app.Run(os.Args); err != nil {
|
|
log.Fatal().Err(err).Msg("An error occurred.")
|
|
}
|
|
}
|