diff options
| author | Shulhan <ms@kilabit.info> | 2026-02-15 13:03:38 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2026-02-15 13:37:31 +0700 |
| commit | 19d58e9a4c900aec1d63de45a655657c760b1235 (patch) | |
| tree | 959af0093d9ed2aca4976c69deb25a2d48fca44b /awwan.go | |
| parent | 827a2741e4fcb8e6feb5bf76acb20799c2913451 (diff) | |
| download | awwan-19d58e9a4c900aec1d63de45a655657c760b1235.tar.xz | |
all: fix data race in Play and in integration tests
When the Play command executed from the web user interface, there is a
possibility that concurrent requests set the sshConfig field in Awwan
struct at the same time.
In the integration tests for TestAwwan_Play_withLocal and
TestExecLocal_sudo, the data race happens when writing to the same
buffer for stdout and stderr, so we split them into separate buffers.
There is also data race in SSE connection, when handler for ExecuteTail
write to the same buffer with worker keep alive.
This has been fixed on pakakeh.go module.
Diffstat (limited to 'awwan.go')
| -rw-r--r-- | awwan.go | 24 |
1 files changed, 11 insertions, 13 deletions
@@ -68,9 +68,6 @@ const defTmpDirPlay = `~/.cache/awwan` type Awwan struct { cryptoc *cryptoContext - // All the Host values from SSH config files. - sshConfig *sshconfig.Config - httpd *httpServer BaseDir string @@ -407,6 +404,7 @@ func (aww *Awwan) Play(ctx context.Context, req *ExecRequest) (err error) { sessionDir = filepath.Dir(req.scriptPath) ses *Session + sshConfig *sshconfig.Config sshSection *sshconfig.Section pos linePosition ) @@ -424,12 +422,12 @@ func (aww *Awwan) Play(ctx context.Context, req *ExecRequest) (err error) { // Always load the SSH config, in case we run on "serve" and // .ssh/config changed by user. - err = aww.loadSSHConfig() + sshConfig, err = aww.loadSSHConfig() if err != nil { goto out } - sshSection = aww.sshConfig.Get(ses.hostname) + sshSection = sshConfig.Get(ses.hostname) if sshSection == nil { err = fmt.Errorf(`can not find Host %q in SSH config`, ses.hostname) goto out @@ -507,7 +505,7 @@ func (aww *Awwan) Stop() (err error) { // loadSSHConfig load all SSH config from user's home and the awwan base // directory. -func (aww *Awwan) loadSSHConfig() (err error) { +func (aww *Awwan) loadSSHConfig() (sshConfig *sshconfig.Config, err error) { var ( logp = `loadSSHConfig` @@ -518,27 +516,27 @@ func (aww *Awwan) loadSSHConfig() (err error) { homeDir, err = os.UserHomeDir() if err != nil { - return fmt.Errorf("%s: %w", logp, err) + return nil, fmt.Errorf(`%s: %w`, logp, err) } configFile = filepath.Join(homeDir, defSSHDir, defSSHConfig) - aww.sshConfig, err = sshconfig.Load(configFile) + sshConfig, err = sshconfig.Load(configFile) if err != nil { - return fmt.Errorf("%s: %w", logp, err) + return nil, fmt.Errorf(`%s: %w`, logp, err) } configFile = filepath.Join(aww.BaseDir, defSSHDir, defSSHConfig) baseDirConfig, err = sshconfig.Load(configFile) if err != nil { - return fmt.Errorf("%s: %w", logp, err) + return nil, fmt.Errorf(`%s: %w`, logp, err) } if baseDirConfig == nil { - return nil + return nil, nil } - aww.sshConfig.Merge(baseDirConfig) + sshConfig.Merge(baseDirConfig) - return nil + return sshConfig, nil } // lookupBaseDir find the directory that contains ".ssh" directory from |
