@@ -23,6 +23,20 @@ import (
2323 "github.com/pingcap/tiup/pkg/cluster/module"
2424)
2525
26+ // PrivilegeEscalationMethod defiles availabile linux privilege escalation commands
27+ type PrivilegeEscalationMethod int
28+
29+ const (
30+ // Invalid privilege escalation mathod as a default
31+ Invalid PrivilegeEscalationMethod = 0
32+ // Sudo command
33+ Sudo PrivilegeEscalationMethod = 1
34+ //Su command
35+ Su PrivilegeEscalationMethod = 2
36+ //Runuser command
37+ Runuser PrivilegeEscalationMethod = 3
38+ )
39+
2640var (
2741 errNSEnvInit = errNS .NewSubNamespace ("env_init" )
2842 errEnvInitSubCommandFailed = errNSEnvInit .NewType ("sub_command_failed" )
@@ -74,18 +88,58 @@ func (e *EnvInit) execute(ctx *Context) error {
7488 return wrapError (err )
7589 }
7690
91+ // some of the privilege escalation commands might be prohibited by the linux administrator
92+ // try different methods and choose the one that works (su, runuser, sudo)
93+ // raise an error when there is no privilege escalation method available
94+ var privilegeEscalationMethod PrivilegeEscalationMethod = Invalid
95+ pems := map [PrivilegeEscalationMethod ]string {
96+ Su : fmt .Sprintf (`su - %s -c 'echo 0'` , e .deployUser ),
97+ Runuser : fmt .Sprintf (`runuser -l %s -c 'echo 0'` , e .deployUser ),
98+ Sudo : `sudo echo 0` ,
99+ }
100+ for pem , cmd := range pems {
101+ _ , _ , err = exec .Execute (cmd , true )
102+ if err == nil {
103+ privilegeEscalationMethod = pem
104+ break
105+ }
106+ }
107+ if privilegeEscalationMethod == Invalid {
108+ return wrapError (errEnvInitSubCommandFailed .
109+ Wrap (err , "No privilege escalation method available" ))
110+ }
111+
77112 // Authorize
78- cmd := `su - ` + e .deployUser + ` -c 'mkdir -p ~/.ssh && chmod 700 ~/.ssh'`
113+ var cmd string
114+ switch privilegeEscalationMethod {
115+ case Su :
116+ cmd = fmt .Sprintf (`su - %s -c 'test -d ~/.ssh || mkdir -p ~/.ssh && chmod 700 ~/.ssh'` , e .deployUser )
117+ case Runuser :
118+ cmd = fmt .Sprintf (`runuser -l %s -c 'test -d ~/.ssh || mkdir -p ~/.ssh && chmod 700 ~/.ssh'` , e .deployUser )
119+ case Sudo :
120+ cmd = fmt .Sprintf (`sudo test -d ~/.ssh || sudo mkdir -p ~/.ssh && sudo chmod 700 ~/.ssh && sudo chown %s:%s ~/.ssh` , e .deployUser , e .userGroup )
121+ }
79122 _ , _ , err = exec .Execute (cmd , true )
80123 if err != nil {
81124 return wrapError (errEnvInitSubCommandFailed .
82125 Wrap (err , "Failed to create '~/.ssh' directory for user '%s'" , e .deployUser ))
83126 }
84127
85128 pk := strings .TrimSpace (string (pubKey ))
129+
86130 sshAuthorizedKeys := executor .FindSSHAuthorizedKeysFile (exec )
87- cmd = fmt .Sprintf (`su - %[1]s -c 'grep $(echo %[2]s) %[3]s || echo %[2]s >> %[3]s && chmod 600 %[3]s'` ,
88- e .deployUser , pk , sshAuthorizedKeys )
131+ switch privilegeEscalationMethod {
132+ case Su :
133+ cmd = fmt .Sprintf (`su - %[1]s -c 'grep $(echo %[2]s) %[3]s || echo %[2]s >> %[3]s && chmod 600 %[3]s'` ,
134+ e .deployUser , pk , sshAuthorizedKeys )
135+ case Runuser :
136+ cmd = fmt .Sprintf (`runuser -l %[1]s -c 'grep $(echo %[2]s) %[3]s || echo %[2]s >> %[3]s && chmod 600 %[3]s'` ,
137+ e .deployUser , pk , sshAuthorizedKeys )
138+ case Sudo :
139+ cmd = fmt .Sprintf (`sudo grep $(echo %[1]s) %[2]s || sudo echo %[1]s >> %[2]s && chmod 600 %[2]s && sudo chown %[3]s:%[4]s %[2]s` ,
140+ pk , sshAuthorizedKeys , e .deployUser , e .userGroup )
141+ }
142+
89143 _ , _ , err = exec .Execute (cmd , true )
90144 if err != nil {
91145 return wrapError (errEnvInitSubCommandFailed .
0 commit comments