feat(cli): set interactive stages in register command

This commit is contained in:
fuxiaohei 2022-11-15 21:28:07 +08:00 committed by Jason Song
parent 561bfad7c5
commit 8f9d7506dc
3 changed files with 146 additions and 19 deletions

View file

@ -5,33 +5,15 @@ import (
"os" "os"
"strconv" "strconv"
"gitea.com/gitea/act_runner/config"
"gitea.com/gitea/act_runner/engine" "gitea.com/gitea/act_runner/engine"
"gitea.com/gitea/act_runner/runtime" "gitea.com/gitea/act_runner/runtime"
"github.com/mattn/go-isatty"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
const version = "0.1.5" const version = "0.1.5"
// initLogging setup the global logrus logger.
func initLogging(cfg config.Config) {
isTerm := isatty.IsTerminal(os.Stdout.Fd())
log.SetFormatter(&log.TextFormatter{
DisableColors: !isTerm,
FullTimestamp: true,
})
if cfg.Debug {
log.SetLevel(log.DebugLevel)
}
if cfg.Trace {
log.SetLevel(log.TraceLevel)
}
}
func Execute(ctx context.Context) { func Execute(ctx context.Context) {
task := runtime.NewTask("gitea", 0, nil, nil) task := runtime.NewTask("gitea", 0, nil, nil)

View file

@ -2,6 +2,7 @@ package cmd
import ( import (
"context" "context"
"os"
"time" "time"
"gitea.com/gitea/act_runner/client" "gitea.com/gitea/act_runner/client"
@ -15,6 +16,7 @@ import (
"github.com/bufbuild/connect-go" "github.com/bufbuild/connect-go"
"github.com/joho/godotenv" "github.com/joho/godotenv"
"github.com/mattn/go-isatty"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
@ -162,3 +164,19 @@ func runDaemon(ctx context.Context, envFile string) func(cmd *cobra.Command, arg
return err return err
} }
} }
// initLogging setup the global logrus logger.
func initLogging(cfg config.Config) {
isTerm := isatty.IsTerminal(os.Stdout.Fd())
log.SetFormatter(&log.TextFormatter{
DisableColors: !isTerm,
FullTimestamp: true,
})
if cfg.Debug {
log.SetLevel(log.DebugLevel)
}
if cfg.Trace {
log.SetLevel(log.TraceLevel)
}
}

View file

@ -1,8 +1,14 @@
package cmd package cmd
import ( import (
"bufio"
"context" "context"
"os"
"os/signal"
"runtime"
"strings"
"github.com/mattn/go-isatty"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -10,7 +16,35 @@ import (
// runRegister registers a runner to the server // runRegister registers a runner to the server
func runRegister(ctx context.Context, regArgs *registerArgs) func(*cobra.Command, []string) error { func runRegister(ctx context.Context, regArgs *registerArgs) func(*cobra.Command, []string) error {
return func(cmd *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error {
log.Infoln("Starting register to gitea instance") log.SetReportCaller(false)
isTerm := isatty.IsTerminal(os.Stdout.Fd())
log.SetFormatter(&log.TextFormatter{
DisableColors: !isTerm,
DisableTimestamp: true,
})
log.Infof("Registering runner, arch=%s, os=%s, version=%s.",
runtime.GOARCH, runtime.GOOS, version)
// runner always needs root permission
if os.Getuid() != 0 {
// TODO: use a better way to check root permission
log.Warnf("Runner in user-mode.")
}
go func() {
if err := registerInteractive(); err != nil {
// log.Errorln(err)
os.Exit(2)
return
}
os.Exit(0)
}()
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<-c
return nil return nil
} }
} }
@ -21,3 +55,96 @@ type registerArgs struct {
InstanceAddr string InstanceAddr string
Token string Token string
} }
type registerStage int8
const (
StageUnknown registerStage = -1
StageInputInstance registerStage = iota + 1
StageInputToken
StageInputRunnerName
StageInputCustomLabels
StageWaitingForRegistration
)
type registerInputs struct {
InstanceAddr string
Token string
RunnerName string
CustomLabels []string
}
func (r *registerInputs) assignToNext(stage registerStage, value string) registerStage {
// must set instance address and token.
// if empty, keep current stage.
if stage == StageInputInstance || stage == StageInputToken {
if value == "" {
return stage
}
}
// set hostname for runner name if empty
if stage == StageInputRunnerName && value == "" {
value, _ = os.Hostname()
}
switch stage {
case StageInputInstance:
r.InstanceAddr = value
return StageInputToken
case StageInputToken:
r.Token = value
return StageInputRunnerName
case StageInputRunnerName:
r.RunnerName = value
return StageInputCustomLabels
case StageInputCustomLabels:
r.CustomLabels = strings.Split(value, ",")
return StageWaitingForRegistration
}
return StageUnknown
}
func registerInteractive() error {
var (
reader = bufio.NewReader(os.Stdin)
stage = StageInputInstance
inputs = new(registerInputs)
)
for {
printStageHelp(stage)
cmdString, err := reader.ReadString('\n')
if err != nil {
return err
}
stage = inputs.assignToNext(stage, strings.TrimSpace(cmdString))
if stage == StageWaitingForRegistration {
log.Infof("Registering runner, name=%s, instance=%s, labels=%v.", inputs.RunnerName, inputs.InstanceAddr, inputs.CustomLabels)
return nil
}
if stage <= StageUnknown {
log.Errorf("Invalid input, please re-run act command.")
return nil
}
}
}
func printStageHelp(stage registerStage) {
switch stage {
case StageInputInstance:
log.Infoln("Enter the Gitea instance URL (for example, https://gitea.com/):")
case StageInputToken:
log.Infoln("Enter the runner token:")
case StageInputRunnerName:
hostname, _ := os.Hostname()
log.Infof("Enter the runner name (if set empty, use hostname:%s ):\n", hostname)
case StageInputCustomLabels:
log.Infoln("Enter the runner custom labels (comma-separated, for example, label1,label2):")
case StageWaitingForRegistration:
log.Infoln("Waiting for registration...")
}
}