mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-06-30 10:33:46 +00:00
fix(provider): EOF error when closing SSH session (#1113)
Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
parent
fed87bad3c
commit
b63f1b7889
4
main.go
4
main.go
@ -65,6 +65,10 @@ func main() {
|
|||||||
serveOpts = append(serveOpts, tf6server.WithManagedDebug())
|
serveOpts = append(serveOpts, tf6server.WithManagedDebug())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove any date and time prefix in log package function output to
|
||||||
|
// prevent duplicate timestamp and incorrect log level setting
|
||||||
|
log.SetFlags(log.Flags() &^ (log.Ldate | log.Ltime))
|
||||||
|
|
||||||
err = tf6server.Serve(
|
err = tf6server.Serve(
|
||||||
"registry.terraform.io/bpg/proxmox",
|
"registry.terraform.io/bpg/proxmox",
|
||||||
muxServer.ProviderServer,
|
muxServer.ProviderServer,
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@ -122,21 +123,42 @@ func (c *client) ExecuteNodeCommands(ctx context.Context, nodeName string, comma
|
|||||||
"commands": commands,
|
"commands": commands,
|
||||||
})
|
})
|
||||||
|
|
||||||
closeOrLogError := utils.CloseOrLogError(ctx)
|
|
||||||
|
|
||||||
sshClient, err := c.openNodeShell(ctx, node)
|
sshClient, err := c.openNodeShell(ctx, node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer closeOrLogError(sshClient)
|
defer func(sshClient *ssh.Client) {
|
||||||
|
e := sshClient.Close()
|
||||||
|
if e != nil {
|
||||||
|
tflog.Warn(ctx, "failed to close SSH client", map[string]interface{}{
|
||||||
|
"error": e,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}(sshClient)
|
||||||
|
|
||||||
|
output, err := c.executeCommands(ctx, sshClient, commands)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return output, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) executeCommands(ctx context.Context, sshClient *ssh.Client, commands []string) ([]byte, error) {
|
||||||
sshSession, err := sshClient.NewSession()
|
sshSession, err := sshClient.NewSession()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create SSH session: %w", err)
|
return nil, fmt.Errorf("failed to create SSH session: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer closeOrLogError(sshSession)
|
defer func(session *ssh.Session) {
|
||||||
|
e := session.Close()
|
||||||
|
if e != nil && !errors.Is(e, io.EOF) {
|
||||||
|
tflog.Warn(ctx, "failed to close SSH session", map[string]interface{}{
|
||||||
|
"error": e,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}(sshSession)
|
||||||
|
|
||||||
script := strings.Join(commands, "; ")
|
script := strings.Join(commands, "; ")
|
||||||
|
|
||||||
@ -188,7 +210,7 @@ func (c *client) NodeUpload(
|
|||||||
defer func(sshClient *ssh.Client) {
|
defer func(sshClient *ssh.Client) {
|
||||||
e := sshClient.Close()
|
e := sshClient.Close()
|
||||||
if e != nil {
|
if e != nil {
|
||||||
tflog.Error(ctx, "failed to close SSH client", map[string]interface{}{
|
tflog.Warn(ctx, "failed to close SSH client", map[string]interface{}{
|
||||||
"error": e,
|
"error": e,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -208,7 +230,7 @@ func (c *client) NodeUpload(
|
|||||||
defer func(sftpClient *sftp.Client) {
|
defer func(sftpClient *sftp.Client) {
|
||||||
e := sftpClient.Close()
|
e := sftpClient.Close()
|
||||||
if e != nil {
|
if e != nil {
|
||||||
tflog.Error(ctx, "failed to close SFTP client", map[string]interface{}{
|
tflog.Warn(ctx, "failed to close SFTP client", map[string]interface{}{
|
||||||
"error": e,
|
"error": e,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -227,7 +249,7 @@ func (c *client) NodeUpload(
|
|||||||
defer func(remoteFile *sftp.File) {
|
defer func(remoteFile *sftp.File) {
|
||||||
e := remoteFile.Close()
|
e := remoteFile.Close()
|
||||||
if e != nil {
|
if e != nil {
|
||||||
tflog.Error(ctx, "failed to close remote file", map[string]interface{}{
|
tflog.Warn(ctx, "failed to close remote file", map[string]interface{}{
|
||||||
"error": e,
|
"error": e,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -284,7 +306,7 @@ func (c *client) NodeStreamUpload(
|
|||||||
defer func(sshClient *ssh.Client) {
|
defer func(sshClient *ssh.Client) {
|
||||||
e := sshClient.Close()
|
e := sshClient.Close()
|
||||||
if e != nil {
|
if e != nil {
|
||||||
tflog.Error(ctx, "failed to close SSH client", map[string]interface{}{
|
tflog.Warn(ctx, "failed to close SSH client", map[string]interface{}{
|
||||||
"error": e,
|
"error": e,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -296,6 +318,29 @@ func (c *client) NodeStreamUpload(
|
|||||||
|
|
||||||
remoteFilePath := strings.ReplaceAll(filepath.Join(remoteFileDir, d.FileName), `\`, "/")
|
remoteFilePath := strings.ReplaceAll(filepath.Join(remoteFileDir, d.FileName), `\`, "/")
|
||||||
|
|
||||||
|
err = c.uploadFile(ctx, sshClient, d, remoteFilePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.checkUploadedFile(ctx, sshClient, remoteFilePath, fileSize)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tflog.Debug(ctx, "uploaded file to datastore", map[string]interface{}{
|
||||||
|
"remote_file_path": remoteFilePath,
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) uploadFile(
|
||||||
|
ctx context.Context,
|
||||||
|
sshClient *ssh.Client,
|
||||||
|
req *api.FileUploadRequest,
|
||||||
|
remoteFilePath string,
|
||||||
|
) error {
|
||||||
sshSession, err := sshClient.NewSession()
|
sshSession, err := sshClient.NewSession()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create SSH session: %w", err)
|
return fmt.Errorf("failed to create SSH session: %w", err)
|
||||||
@ -303,14 +348,14 @@ func (c *client) NodeStreamUpload(
|
|||||||
|
|
||||||
defer func(session *ssh.Session) {
|
defer func(session *ssh.Session) {
|
||||||
e := session.Close()
|
e := session.Close()
|
||||||
if e != nil {
|
if e != nil && !errors.Is(e, io.EOF) {
|
||||||
tflog.Error(ctx, "failed to close SSH session", map[string]interface{}{
|
tflog.Warn(ctx, "failed to close SSH session", map[string]interface{}{
|
||||||
"error": e,
|
"error": e,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}(sshSession)
|
}(sshSession)
|
||||||
|
|
||||||
sshSession.Stdin = d.File
|
sshSession.Stdin = req.File
|
||||||
|
|
||||||
output, err := sshSession.CombinedOutput(
|
output, err := sshSession.CombinedOutput(
|
||||||
fmt.Sprintf(`%s; try_sudo "/usr/bin/tee %s"`, TrySudo, remoteFilePath),
|
fmt.Sprintf(`%s; try_sudo "/usr/bin/tee %s"`, TrySudo, remoteFilePath),
|
||||||
@ -319,6 +364,15 @@ func (c *client) NodeStreamUpload(
|
|||||||
return fmt.Errorf("error transferring file: %s", string(output))
|
return fmt.Errorf("error transferring file: %s", string(output))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) checkUploadedFile(
|
||||||
|
ctx context.Context,
|
||||||
|
sshClient *ssh.Client,
|
||||||
|
remoteFilePath string,
|
||||||
|
fileSize int64,
|
||||||
|
) error {
|
||||||
sftpClient, err := sftp.NewClient(sshClient)
|
sftpClient, err := sftp.NewClient(sshClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create SFTP client: %w", err)
|
return fmt.Errorf("failed to create SFTP client: %w", err)
|
||||||
@ -327,7 +381,7 @@ func (c *client) NodeStreamUpload(
|
|||||||
defer func(sftpClient *sftp.Client) {
|
defer func(sftpClient *sftp.Client) {
|
||||||
e := sftpClient.Close()
|
e := sftpClient.Close()
|
||||||
if e != nil {
|
if e != nil {
|
||||||
tflog.Error(ctx, "failed to close SFTP client", map[string]interface{}{
|
tflog.Warn(ctx, "failed to close SFTP client", map[string]interface{}{
|
||||||
"error": e,
|
"error": e,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -349,11 +403,6 @@ func (c *client) NodeStreamUpload(
|
|||||||
remoteFilePath, bytesUploaded, fileSize)
|
remoteFilePath, bytesUploaded, fileSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
tflog.Debug(ctx, "uploaded file to datastore", map[string]interface{}{
|
|
||||||
"remote_file_path": remoteFilePath,
|
|
||||||
"size": bytesUploaded,
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user