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 Hyper-V builder #2576

Merged
merged 108 commits into from
Dec 13, 2016
Merged

Add Hyper-V builder #2576

merged 108 commits into from
Dec 13, 2016

Conversation

taliesins
Copy link
Collaborator

@taliesins taliesins commented Aug 10, 2015

Add on all the good work done by https://github.com/pbolduc/packer-hyperv/
Supports hyper-v 1 and 2 generation machines
Supports boot_command so you can use it to automate linux builds
Documentation added

@ducke
Copy link

ducke commented Aug 10, 2015

👍

@taliesins
Copy link
Collaborator Author

If Linux supported powershell it would work. Otherwise it would be a case of using winrm to remote in and then executing packer.

@pecigonzalo
Copy link
Contributor

I think that would be the correct way to implement it, using the already existing code for WinRM communicator you can communicate to any windows box running hyper-v using GO, being local or remote. That will keep the code multi platform.
I was going to start such a project re using part of the code form @pbolduc, i though this was it.

@taliesins
Copy link
Collaborator Author

@pbolduc based his work on the original basic Microsoft implementation.

I have done the bulk of the work to make it a full fledged builder, that follows the standard builder configuration.

The intention of this merge is to get hyperv included by default with packer. I do realise that it would only be useful on windows boxes at the moment. Kind of like the qemu builder is only really useful for Linux.

I think this would bring in a large number of users to the packer community.

As a side note I also been sending pull requests to vagrant for hyperv and windows guests and hosts. So once hyperv is in packer it starts being useful for vagrant straight away.

@pbolduc
Copy link

pbolduc commented Aug 11, 2015

Hey @taliesins, thanks so much for continuing the development. 👍 When I was building it, there were a few reasons why I stopped committing. I overhauled the way the PowerShell was executed to make it easier for me to debug/maintain. This really caused my code to diverge from the original packer-hyper code base. I assumed the original source would get more activity and be extended for more OS'es like I had.

I had originally planned on supporting Win7,Win8, Server 2008 R2, 2012 etc. I struggled on getting a consistent pack using these OS'es and the PowerShell provisioner. It always came down getting the security correct. I started needing to use the SSH provisioner.

It would be great to see a variation of my work merged into the main packer project if possible.

@taliesins
Copy link
Collaborator Author

@pbolduc I believe the problem you are describing is the second hop problem: http://blogs.technet.com/b/askds/archive/2008/06/13/understanding-kerberos-double-hop.aspx

E.g. if you winrm into a box and run a powershell script that uses integrated authentication to execute some SQL, you are gonna have a bad time. The issue is that 2nd hop on delegated authentication.

Ssh does not suffer this restriction. Making it great for jump boxes.

I feel you should not be doing anything during the creation of base boxes that will run into this problem.

Workflow should most likely be:

  • create base box with packer
    ** do enough to get winrm working
    ** install provisioner like chef (contentious as it should be able to be bootstrapped by vagrant. Not currently supported by vagrant chef but its simple fix)
    ** maybe install Windows updates (contentious as it will be in a different state each run)
    ** run sys prep on shutdown
  • create vm with vagrant
    ** run provisioner like chef
  • profit!

So how does vagrant get away with the 2nd hop? It uses a clever work around. It winrm into the box and creates a scheduled task which executes your code immediately. It also redirects output to a text file which the winrm executing code forwards to caller.

https://github.com/mitchellh/vagrant/blob/master/plugins/communicators/winrm/scripts/elevated_shell.ps1.erb

@pecigonzalo
Copy link
Contributor

Packer does the same thing with the powershell elevated provider.

@vvchik
Copy link
Contributor

vvchik commented Sep 28, 2015

+1 for this!
It will be great have this merged!

@PierrickLozach
Copy link

+1 for this too! Any estimated date on when this could get reviewed?

@taliesins
Copy link
Collaborator Author

I have even gone to the trouble of updating the documentation as well :>

@vvchik
Copy link
Contributor

vvchik commented Oct 9, 2015

But why AppVeyor build Falls?

@gildas
Copy link

gildas commented Oct 9, 2015

Just went to the appveyor (amd64) page, and it seems like 11 tests fail:

Line 493:

=== RUN TestBuilderPrepare_Defaults
2015/08/10 09:18:52 DiskSize: 40000
2015/08/10 09:18:52 RamSize: 1024
. . .
--- FAIL: TestBuilderPrepare_Defaults (7.89s)
    builder_test.go:34: bad: []string{"Hyper-V might fail to create a VM if there is not enough free memory in the system."}

Line 503:

=== RUN TestBuilderPrepare_DiskSize
2015/08/10 09:19:00 DiskSize: 40000
. . .
--- FAIL: TestBuilderPrepare_DiskSize (2.51s)
    builder_test.go:52: bad: []string{"Hyper-V might fail to create a VM if there is not enough free memory in the system."}

Line 515:

=== RUN TestBuilderPrepare_ISOChecksum
. . .
--- FAIL: TestBuilderPrepare_ISOChecksum (2.54s)
    builder_test.go:100: bad: []string{"Hyper-V might fail to create a VM if there is not enough free memory in the system."}

Line 525:

=== RUN TestBuilderPrepare_ISOChecksumType
. . .
--- FAIL: TestBuilderPrepare_ISOChecksumType (2.50s)
    builder_test.go:130: bad: []string{"Hyper-V might fail to create a VM if there is not enough free memory in the system."}

Line 535:

=== RUN TestBuilderPrepare_ISOUrl
. . .
--- FAIL: TestBuilderPrepare_ISOUrl (2.49s)
    builder_test.go:189: bad: []string{"Hyper-V might fail to create a VM if there is not enough free memory in the system."}

Line 2571:

=== RUN TestProvisionerPrepare_Defaults
--- FAIL: TestProvisionerPrepare_Defaults (0.00s)
    provisioner_test.go:99: Default command should be powershell "{{.Vars}}{{.Path}}", but got $env:%s=\"%s\";

Line 2604:

=== RUN TestProvisionerProvision_Inline
2015/08/10 09:20:22 ui: Provisioning with Powershell...
2015/08/10 09:20:22 Found command: whoami
2015/08/10 09:20:22 ui: Provisioning with shell script: C:\Users\appveyor\AppData\Local\Temp\1\packer-powershell-provisioner249167056
2015/08/10 09:20:22 Opening C:\Users\appveyor\AppData\Local\Temp\1\packer-powershell-provisioner249167056 for reading
--- FAIL: TestProvisionerProvision_Inline (0.00s)
    provisioner_test.go:396: Expect command to be: powershell "& { $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; c:/Windows/Temp/inlineScript.bat; exit $LastExitCode}", got powershell '& { $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; c:/Windows/Temp/inlineScript.bat; exit $LastExitCode}'

Line 2611:

=== RUN TestProvisionerProvision_Scripts
2015/08/10 09:20:22 ui: Provisioning with Powershell...
2015/08/10 09:20:22 ui: Provisioning with shell script: C:\Users\appveyor\AppData\Local\Temp\1\packer125354991
2015/08/10 09:20:22 Opening C:\Users\appveyor\AppData\Local\Temp\1\packer125354991 for reading
--- FAIL: TestProvisionerProvision_Scripts (0.00s)
    provisioner_test.go:442: Expect command to be powershell "& { $env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; c:/Windows/Temp/script.ps1; exit $LastExitCode}" NOT powershell '& { $env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; c:/Windows/Temp/script.ps1; exit $LastExitCode}'

Line 2617:

=== RUN TestProvisionerProvision_ScriptsWithEnvVars
2015/08/10 09:20:22 ui: Provisioning with Powershell...
2015/08/10 09:20:22 ui: Provisioning with shell script: C:\Users\appveyor\AppData\Local\Temp\1\packer472159362
2015/08/10 09:20:22 Opening C:\Users\appveyor\AppData\Local\Temp\1\packer472159362 for reading
--- FAIL: TestProvisionerProvision_ScriptsWithEnvVars (0.00s)
    provisioner_test.go:475: Expect command to be powershell "& { $env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; c:/Windows/Temp/script.ps1; exit $LastExitCode}" NOT powershell '& { $env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; c:/Windows/Temp/script.ps1; exit $LastExitCode}'

Line 2625:

=== RUN TestProvisioner_createFlattenedElevatedEnvVars_windows
--- FAIL: TestProvisioner_createFlattenedElevatedEnvVars_windows (0.00s)
    provisioner_test.go:504: unexpected flattened env vars: $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\";

Line 2630:

=== RUN TestProvision_createCommandText
--- FAIL: TestProvision_createCommandText (0.00s)
    provisioner_test.go:586: Got unexpected non-elevated command: powershell '& { $env:PACKER_BUILDER_TYPE=\"\"; $env:PACKER_BUILD_NAME=\"\"; c:/Windows/Temp/script.ps1; exit $LastExitCode}'

@bbrala
Copy link

bbrala commented Oct 9, 2015

Hmm. The builder needs 512 RAM free at least PLUS the default RAM size of the machine. Seems the default appveyor boxes have 1.7GB RAM for open source projects.
Open-Source (Free) 2 cores 1.7 GB 1 Gbp

The other few seem to be some inconsitent quotes.

@vvchik
Copy link
Contributor

vvchik commented Oct 9, 2015

To be true, errors with powershell quoting looks right
usually right call is: powershell "& {Code}", not powershell '& {Code}'
looks like in these strings single quite should be replaced by double quote:

.//provisioner/powershell/provisioner.go:       p.config.ExecuteCommand = `powershell '& { {{.Vars}}{{.Path}}; exit $LastExitCode}'`  
.//provisioner/powershell/provisioner_test.go:  if p.config.ExecuteCommand != "powershell '& { {{.Vars}}{{.Path}}; exit $LastExitCode}'" {  
.//provisioner/powershell/provisioner_test.go:      t.Fatalf("Default command should be powershell '& { {{.Vars}}{{.Path}}; exit $LastExitCode}', but got %s", p.config.ExecuteCommand)

or, if it is really right, here should be single quotes:

.//provisioner/powershell/provisioner_test.go:  expectedCommand := `powershell "& { $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; c:/Windows/Temp/inlineScript.bat; exit $LastExitCode}"`
.//provisioner/powershell/provisioner_test.go:  expectedCommand = `powershell "& { $env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; c:/Windows/Temp/inlineScript.bat; exit $LastExitCode}"`
.//website/source/docs/provisioners/powershell.html.markdown:    default this is `powershell "& { {{.Vars}}{{.Path}}; exit $LastExitCode}"`.

@vvchik
Copy link
Contributor

vvchik commented Oct 9, 2015

Strange situation with that part of provisioner_test.go, line 98:

▸ if p.config.ElevatedEnvVarFormat != `$env:%s="%s"; ` {¬                                                                                         
    1 ▸ ▸ t.Fatalf("Default command should be powershell \"{{.Vars}}{{.Path}}\", but got %s", p.config.ElevatedEnvVarFormat)¬
    2 ▸ }¬   

here should be quoted (or unquoted) string of vars $env:%s=\"%s\"; not powershell command
anyway need to add backslashes here or remove it from line 119 of provisioner.go file

@taliesins
Copy link
Collaborator Author

I think I forgot to update this in the tests. If i remember correctly, it was issues with escaping powershell strings inside go strings. The point of the single quotes in powershell is then we don't need to escape it as it is a string literal. If we don't escape $lastexitcode it is replaced and not interrupted.

@PierrickLozach
Copy link

@taliesins Are you able to re-run the tests?

@taliesins
Copy link
Collaborator Author

The the unit tests related to quoting are now passing.

I am not sure how to tackle "Hyper-V might fail to create a VM if there is not enough free memory in the system."

If anyone has any ideas please shout.

@taliesins
Copy link
Collaborator Author

Using sensible minimums solves the problem. Don't need to force Windows Server virtual machine defaults.

@bbrala
Copy link

bbrala commented Oct 19, 2015

Thanks for going through this again! @taliesins

@gildas
Copy link

gildas commented Oct 20, 2015

Thanks a lot and congrats for passing the tests.
Now, all we need is someone to merge the pull request!
@mitchellh , @sethvargo, @rickard-von-essen ?!? Sorry for being pushy, but we really need that stuff.

@mitchellh
Copy link
Contributor

Thanks everybody for this work! We'll be prioritizing Hyper-V and Azure support in Packer over the next few months. Unfortunately, I did just say "few months." Until then, we'd like to ask everyone continue to use a 3rd party plugin.

We've decided not to merge this as-is because we want to bring the code quality and styling more in line with the rest of the project and our current standards. This isn't to say anything negative about what has been done so far: we are deeply appreciative of the thousands of lines written so far and we'll be using this as a base for cleaning up. However, this will take some time, hence "few months" (since we're juggling other tasks as well).

In addition to this, we have an acceptance test framework coming in shortly that we'll want to hook up to this to verify the features. As Packer has grown, it has become more difficult to avoid regressions without a proper test framework in place. Due to the large requirement on side effects by hitting cloud platforms, this needs to be an acceptance test framework. This framework will come in in the next two weeks and we'll have that to build into when we work on this again.

Sorry for the huge delays, but we appreciate the work and will have this in in the near future. Until then, due to Packer's plugin model, it should be simple to continue using this as a separate binary.

Thanks everyone!

@PierrickLozach
Copy link

@mitchellh do you have a particular 3rd party that you can recommend?

@mitchellh
Copy link
Contributor

A couple choices, either the https://github.com/pbolduc/packer-hyperv/ repo directly or you can pull this PR and compile the plugin and copy it into any Packer release (it can work with the currently released version).

@taliesins
Copy link
Collaborator Author

My advice is to not use https://github.com/pbolduc/packer-hyperv/ and https://github.com/MSOpenTech/packer-hyperv as they are missing a lot of functionality and it is no longer maintained.

@vvchik
Copy link
Contributor

vvchik commented Oct 26, 2015

I Agree with @taliesins much better to manually build packer with this PR merged.
to be true I did so and using for my Images creation.

@taliesins
Copy link
Collaborator Author

I would have appreciated a code review on this PR. I went to great pains to ensure that it follows the exact coding standards that other builders use. I rewrote it based on a mixture of Vmware and VirtualBox buiders. So there are large sections that are copy and pasted from your existing code base .

Perhaps same suggestions on how to deal with powershell with an approach that would make you comfortable to include this as an experimental feature. If we can have Linux only features surely it couldn't hurt to have some Windows only features.

If the ability to test this PR is a problem. Perhaps I could help? I do have some hardware resources at my disposal. So I am running the branch through CI via Teamcity and have a couple of build agents with large amounts of RAM and cores.

I am putting together a few demo packer templates at https://github.com/taliesins/packer-baseboxes. If we are able to build Windows 10, Windows 2012, Ubuntu 14.04, Ubuntu 15.04, Ubuntu 15.10 successfully surely that would be enough to prove the PR is ready for beta.

Hell it can be ripped out 100% as soon as you guys have a working provider. It feels like there is good demand for it now.

Keep voting guys! Hopefully we will get HyperV support soon

@mwhooker
Copy link
Contributor

got it working by setting the switch to external. running in to lots of ubuntu problems now

but making progress

@PatrickLang
Copy link
Contributor

@mwhooker
Here's the two that worked for me:

Both of these needed this change to succeed:
taliesins#10

And there's still an outstanding issue where Go formats in boot_cmd such as

"{{ user \`boot_command_prefix\` }}"

are not expanded correctly

@mwhooker
Copy link
Contributor

got it working with your preseed. Solved many issues for me! Will add to docs

@mwhooker mwhooker merged commit c9fcaf4 into hashicorp:master Dec 13, 2016
@mwhooker
Copy link
Contributor

made a few additional commits:

thanks everyone and especially @taliesins for the hard work to get this in!

@taliesins
Copy link
Collaborator Author

Awesome!

@theogq
Copy link

theogq commented Jan 13, 2017

@taliesins great work on your repository https://github.com/taliesins/packer-baseboxes
helped me a lot.

Has anybody managed to create debian (gen 2) packer template?
Or it is not supported yet?

@bbrala
Copy link

bbrala commented Jan 13, 2017

I've only really used it for ubuntu boxes really.

@taliesins
Copy link
Collaborator Author

@theogq thanks. I have made a few significant improvements to the Windows Packer templates the last couple of days.

Can specify username and password instead of being hard coded

Specify wsus server

Specify proxy server

Skipping of steps makes it quicker to debug failing builds.

Updated to use latest dependencies

Fixed bugs with maximum argument length being exceeded in autoattend.xml

They are now building base boxes in teamcity successfully again.

@pvandervelde
Copy link
Contributor

@taliesins Is there any way I can help getting the ability to create a packer box from a VHD into this pull request? I have no skills with Go but I have build a few powershell scripts to create Hyper-V boxes (see here: https://github.com/ops-resource/ops-tools-hyperv/tree/release/0.1.0/src/ps). Would really love to be able to use packer with a pre-generated base box / base VHD(X)

@rickard-von-essen
Copy link
Collaborator

This have been merged. Please open a new GitHub Issues for reporting bugs and feature requests. Do not ask for general help here. Use IRC #packer-tool on Freenode or the mailing list for that.

See https://www.packer.io/community/

Looking.

@hashicorp hashicorp locked and limited conversation to collaborators Jan 16, 2017
@taliesins
Copy link
Collaborator Author

No promises guys but have a look at https://github.com/taliesins/packer/tree/hyperv-vmcx

My Teamcity is down at the moment (Windows Server 2016 remote install gone wrong ;>). As soon as I get hands and eyes I will get it up and running. I will test it, and send in a pull request shortly after that.

May need some help testing it on Windows Server 2012.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.