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

Add pwsh provisioner to linux #12429

Open
jachin84 opened this issue May 17, 2023 · 6 comments
Open

Add pwsh provisioner to linux #12429

jachin84 opened this issue May 17, 2023 · 6 comments
Labels
enhancement stage/needs-discussion stage/thinking Flagged for internal discussions about possible enhancements

Comments

@jachin84
Copy link

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Please search the existing issues for relevant feature requests, and use the
reaction feature
(https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/)
to add upvotes to pre-existing requests.

Description

Add support for using the powershell provisioner on linux. I'm currently using the standard shell provisioner and changing the run command like so:

provisioner "shell" {
    execute_command  = "sudo sh -c '{{ .Vars }} pwsh -f {{ .Path }}'"
    scripts          = ["${path.root}/scripts/Install-stuff.ps1"]
  }

This doesn't seem to work when specifying inline.

Use Case(s)

When building linux images using pwsh as the primary scripting language instead of bash.

Potential configuration

I'd love it if something like this worked:

provisioner "pwsh" {
    inline          = [ "Write-Host \"Hello from PowerShell\""]
}
@tenthirtyam
Copy link
Contributor

Did you happen to try use_pwsh = true with the provisioner?

Although, if that works the docs should be updated to note that it's pwsh for cross platform and remove the .exe reference.

Ryan

cc @lbajolet-hashicorp

@lbajolet-hashicorp
Copy link
Contributor

Hey @tenthirtyam,

Thanks for the update here. I believe the intent of the Powershell provisioner is mostly for users building Windows VMs (as the first sentence of the provisioner hints: "The PowerShell Packer provisioner runs PowerShell scripts on Windows machines"), though that is essentially cross-platform now that pwsh is built for Linux and macOS these days.

I've never tried running pwsh on Linux guests tbf, not even sure if the option will work on non-Windows machines, but it very well might. If possible @jachin84 could you update us on using this option in that context? If it persists in not calling the shell you're expecting, we can probably fix that, otherwise as Ryan said, we can update the docs to lessen the dependency on Windows in there.

Thanks!

@jachin84
Copy link
Author

I tried the use_pwsh = true

provisioner "powershell" {
    use_pwsh = true
    environment_vars = ["HELPER_SCRIPTS=${var.helper_script_folder}", "INSTALLER_SCRIPT_FOLDER=${var.installer_script_folder}"]
    scripts          = ["${path.root}/../scripts/build/Install-PowerShellModules.ps1", "${path.root}/../scripts/build/Install-PowerShellAzModules.ps1"]
  }

This gives me an error:

==> azure-arm.build_image: Provisioning with powershell script: S:/Kallipr/runner-images/images/linux/templates/../scripts/build/Install-PowerShellModules.ps1
==> azure-arm.build_image: Error processing command: Error uploading ps script containing env vars: scp: c:/Windows/Temp: No such file or directory

Looking at that log (c:/Windows/Temp) it looks like it is assuming windows when using the powershell provisioner.

My scenario, which is probably not common, is building a Linux guest but using PowerShell core scripts to customize the guest rather than bash. As I mentioned the workaround is something like:

  provisioner "shell" {
    environment_vars = ["HELPER_SCRIPTS=${var.helper_script_folder}", "INSTALLER_SCRIPT_FOLDER=${var.installer_script_folder}"]
    execute_command  = "sudo sh -c '{{ .Vars }} pwsh -f {{ .Path }}'"
    scripts          = ["${path.root}/../scripts/build/Install-PowerShellModules.ps1", "${path.root}/../scripts/build/Install-PowerShellAzModules.ps1"]
  }

It would be nice if this was handled by default as I often forget to add execute_command = "sudo sh -c '{{ .Vars }} pwsh -f {{ .Path }}'" to the shell provisioner.

Maybe it would be easier to add a use_pwsh = true option to the shell provisioner?

@tenthirtyam
Copy link
Contributor

@lbajolet-hashicorp feel free to assign to me and I'll work on this one.

@lbajolet-hashicorp
Copy link
Contributor

Thanks for the experiment and reporting back @jachin84, much appreciated!

Yeah, the fact that the powershell provisioner assumes Windows doesn't surprise me, not a lot of people use it on other platforms, and assuming Windows enables us to perform some boilerplate actions that are OS-specific without having to specify everything manually.
This approach may need to be revisited at some point though, but for now we'll make do with what we have.

Regarding a use_pwsh attribute to the shell provisioner, I'm not certain this is a good idea. My main gripe with this is that if we start having use_.* for shell, we'll be tempted to add more and more variants (e.g. use_zsh, use_fish, use_powershell, etc.).
Additionally, I imagine use_pwsh has more implications than changing execute_command, we'd need to check that.

Not sure what'd be best for handling this as idiomatically as possible. I'll bring this up for discussion internally and we'll pop back here later to address this issue.

Thanks again to the both of you!

@lbajolet-hashicorp lbajolet-hashicorp added stage/thinking Flagged for internal discussions about possible enhancements stage/needs-discussion and removed stage/waiting-reply labels Jun 20, 2024
@darrens280
Copy link

Thanks @jachin84 . Your syntax worked for me to use the Packer shell provisioner to invoke a PS1 script on an Ubuntu 22.04 target VM image.

provisioner "shell" {
    execute_command  = "sudo sh -c '{{ .Vars }} pwsh -f {{ .Path }}'"
    scripts          = ["./scripts/install-powershellmodules.ps1"]
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement stage/needs-discussion stage/thinking Flagged for internal discussions about possible enhancements
Projects
None yet
Development

No branches or pull requests

4 participants