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

Improve env init on deploying and scale-out cluster #678

Merged
merged 8 commits into from
Aug 17, 2020
Merged
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions components/cluster/command/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ func newDeploy() *cobra.Command {
}

cmd.Flags().StringVarP(&opt.User, "user", "u", tiuputils.CurrentUser(), "The user name to login via SSH. The user must has root (or sudo) privilege.")
cmd.Flags().BoolVarP(&opt.SkipCreateUser, "skip-create-user", "", false, "Skip creating the user specified in topology.")
cmd.Flags().StringVarP(&opt.IdentityFile, "identity_file", "i", opt.IdentityFile, "The path of the SSH identity file. If specified, public key authentication will be used.")
cmd.Flags().BoolVarP(&opt.UsePassword, "password", "p", false, "Use password of target hosts. If specified, password authentication will be used.")
cmd.Flags().BoolVarP(&opt.IgnoreConfigCheck, "ignore-config-check", "", opt.IgnoreConfigCheck, "Ignore the config check result")
Expand Down
1 change: 1 addition & 0 deletions components/cluster/command/scale_out.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func newScaleOutCmd() *cobra.Command {
}

cmd.Flags().StringVarP(&opt.User, "user", "u", tiuputils.CurrentUser(), "The user name to login via SSH. The user must has root (or sudo) privilege.")
cmd.Flags().BoolVarP(&opt.SkipCreateUser, "skip-create-user", "", false, "Skip creating the user specified in topology.")
cmd.Flags().StringVarP(&opt.IdentityFile, "identity_file", "i", opt.IdentityFile, "The path of the SSH identity file. If specified, public key authentication will be used.")
cmd.Flags().BoolVarP(&opt.UsePassword, "password", "p", false, "Use password of target hosts. If specified, password authentication will be used.")

Expand Down
12 changes: 7 additions & 5 deletions pkg/cluster/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -840,15 +840,17 @@ func (m *Manager) Patch(clusterName string, packagePath string, opt operator.Opt

// ScaleOutOptions contains the options for scale out.
type ScaleOutOptions struct {
User string // username to login to the SSH server
IdentityFile string // path to the private key file
UsePassword bool // use password instead of identity file for ssh connection
User string // username to login to the SSH server
SkipCreateUser bool // don't create user
IdentityFile string // path to the private key file
UsePassword bool // use password instead of identity file for ssh connection
}

// DeployOptions contains the options for scale out.
// TODO: merge ScaleOutOptions, should check config too when scale out.
type DeployOptions struct {
User string // username to login to the SSH server
SkipCreateUser bool // don't create the user
IdentityFile string // path to the private key file
UsePassword bool // use password instead of identity file for ssh connection
IgnoreConfigCheck bool // ignore config check result
Expand Down Expand Up @@ -977,7 +979,7 @@ func (m *Manager) Deploy(
sshTimeout,
nativeSSH,
).
EnvInit(inst.GetHost(), globalOptions.User).
EnvInit(inst.GetHost(), globalOptions.User, globalOptions.Group, opt.SkipCreateUser || globalOptions.User == opt.User).
Mkdir(globalOptions.User, inst.GetHost(), dirs...).
BuildAsStep(fmt.Sprintf(" - Prepare %s:%d", inst.GetHost(), inst.GetSSHPort()))
envInitTasks = append(envInitTasks, t)
Expand Down Expand Up @@ -1675,7 +1677,7 @@ func buildScaleOutTask(
sshTimeout,
nativeSSH,
).
EnvInit(instance.GetHost(), base.User).
EnvInit(instance.GetHost(), base.User, base.Group, opt.SkipCreateUser || globalOptions.User == opt.User).
Mkdir(globalOptions.User, instance.GetHost(), dirs...).
Build()
envInitTasks = append(envInitTasks, t)
Expand Down
16 changes: 13 additions & 3 deletions pkg/cluster/module/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ const (
// TODO: in RHEL/CentOS, the commands are in /usr/sbin, but in some
// other distros they may be in other location such as /usr/bin, we'll
// need to check and find the proper path of commands in the future.
useraddCmd = "/usr/sbin/useradd"
userdelCmd = "/usr/sbin/userdel"
useraddCmd = "/usr/sbin/useradd"
userdelCmd = "/usr/sbin/userdel"
groupaddCmd = "/usr/sbin/groupadd"
//usermodCmd = "/usr/sbin/usermod"
)

Expand All @@ -48,6 +49,7 @@ var (
type UserModuleConfig struct {
Action string // add, del or modify user
Name string // username
Group string // group name
lucklove marked this conversation as resolved.
Show resolved Hide resolved
Home string // home directory of user
Shell string // login shell of the user
Sudoer bool // when true, the user will be added to sudoers list
Expand Down Expand Up @@ -80,10 +82,17 @@ func NewUserModule(config UserModuleConfig) *UserModule {
cmd = fmt.Sprintf("%s -s %s", cmd, defaultShell)
}

// set user's group
if config.Group != "" {
cmd = fmt.Sprintf("%s -g %s", cmd, config.Group)
}

cmd = fmt.Sprintf("%s %s", cmd, config.Name)

groupAdd := fmt.Sprintf("%s -f %s", groupaddCmd, config.Group)

// prevent errors when username already in use
cmd = fmt.Sprintf("id -u %s > /dev/null 2>&1 || %s", config.Name, cmd)
cmd = fmt.Sprintf("%s && (id -u %s > /dev/null 2>&1 || %s)", groupAdd, config.Name, cmd)
lucklove marked this conversation as resolved.
Show resolved Hide resolved

// add user to sudoers list
if config.Sudoer {
Expand All @@ -93,6 +102,7 @@ func NewUserModule(config UserModuleConfig) *UserModule {
cmd,
fmt.Sprintf("echo '%s' > /etc/sudoers.d/%s", sudoLine, config.Name))
}

case UserActionDel:
cmd = fmt.Sprintf("%s -r %s", userdelCmd, config.Name)
// prevent errors when user does not exist
Expand Down
2 changes: 2 additions & 0 deletions pkg/cluster/spec/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type (
// specification in topology.yaml
GlobalOptions struct {
User string `yaml:"user,omitempty" default:"tidb"`
Group string `yaml:"group,omitempty"`
SSHPort int `yaml:"ssh_port,omitempty" default:"22" validate:"ssh_port:editable"`
DeployDir string `yaml:"deploy_dir,omitempty" default:"deploy"`
DataDir string `yaml:"data_dir,omitempty" default:"data"`
Expand Down Expand Up @@ -134,6 +135,7 @@ type Topology interface {
// BaseMeta is the base info of metadata.
type BaseMeta struct {
User string
Group string
Version string
OpsVer *string `yaml:"last_ops_ver,omitempty"` // the version of ourself that updated the meta last time
}
Expand Down
8 changes: 5 additions & 3 deletions pkg/cluster/task/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,12 @@ func (b *Builder) SSHKeySet(privKeyPath, pubKeyPath string) *Builder {
}

// EnvInit appends a EnvInit task to the current task collection
func (b *Builder) EnvInit(host, deployUser string) *Builder {
func (b *Builder) EnvInit(host, deployUser string, userGroup string, skipCreateUser bool) *Builder {
b.tasks = append(b.tasks, &EnvInit{
host: host,
deployUser: deployUser,
host: host,
deployUser: deployUser,
userGroup: userGroup,
skipCreateUser: skipCreateUser,
})
return b
}
Expand Down
27 changes: 16 additions & 11 deletions pkg/cluster/task/env_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ var (
// 1. Generate SSH key
// 2. ssh-copy-id
type EnvInit struct {
host string
deployUser string
host string
deployUser string
userGroup string
skipCreateUser bool
}

// Execute implements the Task interface
Expand All @@ -54,15 +56,18 @@ func (e *EnvInit) execute(ctx *Context) error {
panic(ErrNoExecutor)
}

um := module.NewUserModule(module.UserModuleConfig{
Action: module.UserActionAdd,
Name: e.deployUser,
Sudoer: true,
})

_, _, errx := um.Execute(exec)
if errx != nil {
return wrapError(errx)
if !e.skipCreateUser {
um := module.NewUserModule(module.UserModuleConfig{
Action: module.UserActionAdd,
Name: e.deployUser,
Group: e.userGroup,
Sudoer: true,
})

_, _, errx := um.Execute(exec)
if errx != nil {
return wrapError(errx)
}
}

pubKey, err := ioutil.ReadFile(ctx.PublicKeyPath)
Expand Down
4 changes: 2 additions & 2 deletions pkg/cluster/task/mkdir.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type Mkdir struct {
func (m *Mkdir) Execute(ctx *Context) error {
exec, found := ctx.GetExecutor(m.host)
if !found {
return ErrNoExecutor
panic(ErrNoExecutor)
lucklove marked this conversation as resolved.
Show resolved Hide resolved
}
for _, dir := range m.dirs {
if !strings.HasPrefix(dir, "/") {
Expand All @@ -52,7 +52,7 @@ func (m *Mkdir) Execute(ctx *Context) error {
continue
}
cmd := fmt.Sprintf(
`test -d %[1]s || (mkdir -p %[1]s && chown %[2]s:%[2]s %[1]s)`,
`test -d %[1]s || (mkdir -p %[1]s && chown %[2]s:$(id -g -n %[2]s) %[1]s)`,
strings.Join(xs[:i+1], "/"),
m.user,
)
Expand Down