1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
/*
* Copyright (c) 2022. Nydus Developers. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
package command
import (
"fmt"
"reflect"
"strconv"
"github.com/pkg/errors"
)
type Opt = func(cmd *DaemonCommand)
// Define how to build a command line to start a nydusd daemon
type DaemonCommand struct {
// "singleton" "fuse"
Mode string `type:"subcommand"`
// "blobcache" "fscache" "virtiofs"
FscacheDriver string `type:"param" name:"fscache"`
FscacheThreads string `type:"param" name:"fscache-threads"`
Upgrade bool `type:"flag" name:"upgrade" default:""`
ThreadNum string `type:"param" name:"thread-num"`
// `--id` is required by `--supervisor` when starting nydusd
ID string `type:"param" name:"id"`
Config string `type:"param" name:"config"`
Bootstrap string `type:"param" name:"bootstrap"`
Mountpoint string `type:"param" name:"mountpoint"`
APISock string `type:"param" name:"apisock"`
LogLevel string `type:"param" name:"log-level"`
LogRotationSize int `type:"param" name:"log-rotation-size"`
Supervisor string `type:"param" name:"supervisor"`
LogFile string `type:"param" name:"log-file"`
PrefetchFiles string `type:"param" name:"prefetch-files"`
}
// Build exec style command line
func BuildCommand(opts []Opt) ([]string, error) {
var cmd DaemonCommand
var subcommand string
for _, o := range opts {
o(&cmd)
}
args := make([]string, 0, 32)
t := reflect.TypeOf(cmd)
v := reflect.ValueOf(cmd)
for i := 0; i < t.NumField(); i++ {
tag := t.Field(i).Tag
argType := tag.Get("type")
switch argType {
case "param":
// Zero value will be skipped appending to command line
if v.Field(i).IsZero() {
continue
}
value := v.Field(i).Interface()
pair := []string{fmt.Sprintf("--%s", tag.Get("name")), fmt.Sprintf("%v", value)}
args = append(args, pair...)
case "subcommand":
// Zero value will be skipped appending to command line
if v.Field(i).IsZero() {
continue
}
subcommand = v.Field(i).String()
case "flag":
kind := v.Field(i).Kind()
if kind != reflect.Bool {
return nil, errors.Errorf("flag must be boolean")
}
v := v.Field(i).Bool()
if v {
flag := fmt.Sprintf("--%s", tag.Get("name"))
args = append(args, flag)
} else {
continue
}
default:
return nil, errors.Errorf("unknown tag type: %s ", argType)
}
}
if subcommand != "" {
// Ensure subcommand is at the first place.
args = append([]string{subcommand}, args...)
}
return args, nil
}
func WithMode(m string) Opt {
return func(cmd *DaemonCommand) {
cmd.Mode = m
}
}
func WithPrefetchFiles(p string) Opt {
return func(cmd *DaemonCommand) {
cmd.PrefetchFiles = p
}
}
func WithFscacheDriver(w string) Opt {
return func(cmd *DaemonCommand) {
cmd.FscacheDriver = w
}
}
func WithFscacheThreads(num int) Opt {
return func(cmd *DaemonCommand) {
cmd.FscacheThreads = strconv.Itoa(num)
}
}
func WithThreadNum(num int) Opt {
return func(cmd *DaemonCommand) {
cmd.ThreadNum = strconv.Itoa(num)
}
}
func WithConfig(config string) Opt {
return func(cmd *DaemonCommand) {
cmd.Config = config
}
}
func WithBootstrap(b string) Opt {
return func(cmd *DaemonCommand) {
cmd.Bootstrap = b
}
}
func WithMountpoint(m string) Opt {
return func(cmd *DaemonCommand) {
cmd.Mountpoint = m
}
}
func WithAPISock(api string) Opt {
return func(cmd *DaemonCommand) {
cmd.APISock = api
}
}
func WithLogFile(l string) Opt {
return func(cmd *DaemonCommand) {
cmd.LogFile = l
}
}
func WithLogLevel(l string) Opt {
return func(cmd *DaemonCommand) {
cmd.LogLevel = l
}
}
func WithLogRotationSize(l int) Opt {
return func(cmd *DaemonCommand) {
cmd.LogRotationSize = l
}
}
func WithSupervisor(s string) Opt {
return func(cmd *DaemonCommand) {
cmd.Supervisor = s
}
}
func WithID(id string) Opt {
return func(cmd *DaemonCommand) {
cmd.ID = id
}
}
func WithUpgrade() Opt {
return func(cmd *DaemonCommand) {
cmd.Upgrade = true
}
}
|