mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-08-23 03:48:35 +00:00
fix(vm): regression: sudo: command not found
when creating a VM (#966)
Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
parent
0363986374
commit
01a8f9779c
@ -136,6 +136,10 @@ This is because the provider needs to know which PAM user to use for the SSH con
|
|||||||
|
|
||||||
When using a non-root user for the SSH connection, the user **must** have the `sudo` privilege on the target node without requiring a password.
|
When using a non-root user for the SSH connection, the user **must** have the `sudo` privilege on the target node without requiring a password.
|
||||||
|
|
||||||
|
-> If you run clustered Proxmox VE, you will need to configure the `sudo` privilege for the user on all nodes in the cluster.
|
||||||
|
|
||||||
|
-> `sudo` is not installed by default on Proxmox VE nodes. You can install it via the command line on the Proxmox host: `apt install sudo`
|
||||||
|
|
||||||
You can configure the `sudo` privilege for the user via the command line on the Proxmox host. In the example below, we create a user `terraform` and assign the `sudo` privilege to it:
|
You can configure the `sudo` privilege for the user via the command line on the Proxmox host. In the example below, we create a user `terraform` and assign the `sudo` privilege to it:
|
||||||
|
|
||||||
- Create a new system user:
|
- Create a new system user:
|
||||||
|
@ -29,6 +29,9 @@ import (
|
|||||||
|
|
||||||
// Client is an interface for performing SSH requests against the Proxmox Nodes.
|
// Client is an interface for performing SSH requests against the Proxmox Nodes.
|
||||||
type Client interface {
|
type Client interface {
|
||||||
|
// Username returns the SSH username.
|
||||||
|
Username() string
|
||||||
|
|
||||||
// ExecuteNodeCommands executes a command on a node.
|
// ExecuteNodeCommands executes a command on a node.
|
||||||
ExecuteNodeCommands(ctx context.Context, nodeName string, commands []string) ([]byte, error)
|
ExecuteNodeCommands(ctx context.Context, nodeName string, commands []string) ([]byte, error)
|
||||||
|
|
||||||
@ -71,6 +74,10 @@ func NewClient(
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *client) Username() string {
|
||||||
|
return c.username
|
||||||
|
}
|
||||||
|
|
||||||
// ExecuteNodeCommands executes commands on a given node.
|
// ExecuteNodeCommands executes commands on a given node.
|
||||||
func (c *client) ExecuteNodeCommands(ctx context.Context, nodeName string, commands []string) ([]byte, error) {
|
func (c *client) ExecuteNodeCommands(ctx context.Context, nodeName string, commands []string) ([]byte, error) {
|
||||||
node, err := c.nodeResolver.Resolve(ctx, nodeName)
|
node, err := c.nodeResolver.Resolve(ctx, nodeName)
|
||||||
|
@ -2974,6 +2974,7 @@ func vmCreateCustomDisks(ctx context.Context, d *schema.ResourceData, m interfac
|
|||||||
commands = append(
|
commands = append(
|
||||||
commands,
|
commands,
|
||||||
`set -e`,
|
`set -e`,
|
||||||
|
`try_sudo(){ if [ $(sudo -n echo tfpve 2>&1 | grep "tfpve" | wc -l) -gt 0 ]; then sudo $1; else $1; fi }`,
|
||||||
fmt.Sprintf(`file_id="%s"`, fileID),
|
fmt.Sprintf(`file_id="%s"`, fileID),
|
||||||
fmt.Sprintf(`file_format="%s"`, fileFormat),
|
fmt.Sprintf(`file_format="%s"`, fileFormat),
|
||||||
fmt.Sprintf(`datastore_id_target="%s"`, datastoreID),
|
fmt.Sprintf(`datastore_id_target="%s"`, datastoreID),
|
||||||
@ -2982,11 +2983,11 @@ func vmCreateCustomDisks(ctx context.Context, d *schema.ResourceData, m interfac
|
|||||||
fmt.Sprintf(`disk_interface="%s"`, diskInterface),
|
fmt.Sprintf(`disk_interface="%s"`, diskInterface),
|
||||||
fmt.Sprintf(`file_path_tmp="%s"`, filePathTmp),
|
fmt.Sprintf(`file_path_tmp="%s"`, filePathTmp),
|
||||||
fmt.Sprintf(`vm_id="%d"`, vmID),
|
fmt.Sprintf(`vm_id="%d"`, vmID),
|
||||||
`source_image=$(sudo pvesm path "$file_id")`,
|
`source_image=$(try_sudo "pvesm path $file_id")`,
|
||||||
`imported_disk="$(sudo qm importdisk "$vm_id" "$source_image" "$datastore_id_target" -format $file_format | grep "unused0" | cut -d ":" -f 3 | cut -d "'" -f 1)"`,
|
`imported_disk="$(try_sudo "qm importdisk $vm_id $source_image $datastore_id_target -format $file_format" | grep "unused0" | cut -d ":" -f 3 | cut -d "'" -f 1)"`,
|
||||||
`disk_id="${datastore_id_target}:$imported_disk${disk_options}"`,
|
`disk_id="${datastore_id_target}:$imported_disk${disk_options}"`,
|
||||||
`sudo qm set "$vm_id" "-${disk_interface}" "$disk_id"`,
|
`try_sudo "qm set $vm_id -${disk_interface} $disk_id"`,
|
||||||
`sudo qm resize "$vm_id" "${disk_interface}" "${disk_size}G"`,
|
`try_sudo "qm resize $vm_id ${disk_interface} ${disk_size}G"`,
|
||||||
)
|
)
|
||||||
|
|
||||||
importedDiskCount++
|
importedDiskCount++
|
||||||
@ -3006,6 +3007,11 @@ func vmCreateCustomDisks(ctx context.Context, d *schema.ResourceData, m interfac
|
|||||||
|
|
||||||
out, err := api.SSH().ExecuteNodeCommands(ctx, nodeName, commands)
|
out, err := api.SSH().ExecuteNodeCommands(ctx, nodeName, commands)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "pvesm: not found") {
|
||||||
|
return diag.Errorf("The configured SSH user '%s' does not have the required permissions to import disks. "+
|
||||||
|
"Make sure `sudo` is installated and the user is a member of sudoers.", api.SSH().Username())
|
||||||
|
}
|
||||||
|
|
||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user