YaleUniversity / packer-plugin-goss

Goss Provisioner for Packer
MIT License
136 stars 45 forks source link

Add support for supplying --var file #15

Closed petemounce closed 6 years ago

petemounce commented 6 years ago

So that one can take advantage of goss' templating feature, add support to upload, then use, a vars file.

goss docs: https://github.com/aelsabbahy/goss/blob/master/docs/manual.md#templates

petemounce commented 6 years ago

I looked at supplying environment variables as well, but that was a bit more involved so if necessary, a later PR.

petemounce commented 6 years ago

I should have mentioned - worked with packer 1.2.4.

==> googlecompute: Provisioning with Goss
    googlecompute: Installing Goss from, https://github.com/aelsabbahy/goss/releases/download/v0.3.5/goss-linux-amd64
    googlecompute: Downloading Goss to /tmp/goss-0.3.5-linux-amd64
    googlecompute:   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
    googlecompute:                                  Dload  Upload   Total   Spent    Left  Speed
    googlecompute: 100   606    0   606    0     0    827      0 --:--:-- --:--:-- --:--:--   826
    googlecompute: 100 8312k  100 8312k    0     0  1969k      0  0:00:04  0:00:04 --:--:-- 2699k
    googlecompute: goss version v0.3.5
==> googlecompute: Uploading goss tests...
    googlecompute: Creating directory: /tmp/goss
    googlecompute: Uploading vars file ansible/tests/production.vars.goss.yaml
    googlecompute: Uploading ansible/tests/baseline.goss.yaml
    googlecompute: Uploading ansible/tests/bd_platform.goss.yaml
    googlecompute: Uploading ansible/tests/buildkite_agent.goss.yaml
    googlecompute: Uploading ansible/tests/local_only.goss.yaml
    googlecompute: Uploading ansible/tests/node_metrics.goss.yaml
==> googlecompute: Running goss tests...
    googlecompute: ......................................................................................................................................................................................
    googlecompute:
    googlecompute: Total Duration: 0.194s
    googlecompute: Count: 182, Failed: 0, Skipped: 0
==> googlecompute: Goss tests ran successfully
==> googlecompute: Provisioning with Goss
    googlecompute: Installing Goss from, https://github.com/aelsabbahy/goss/releases/download/v0.3.5/goss-linux-amd64
    googlecompute: Downloading Goss to /tmp/goss-0.3.5-linux-amd64
    googlecompute:   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
    googlecompute:                                  Dload  Upload   Total   Spent    Left  Speed
    googlecompute: 100   606    0   606    0     0   1050      0 --:--:-- --:--:-- --:--:--  1050
    googlecompute: Warning: Failed to create the file /tmp/goss-0.3.5-linux-amd64: Permission
    googlecompute: Warning: denied
    googlecompute:   0 8312k    0 16360    0     0  14099      0  0:10:03  0:00:01  0:10:02 14099
    googlecompute: curl: (23) Failed writing body (0 != 16360)
    googlecompute: /tmp/goss-0.3.5-linux-amd64: Permission denied
    googlecompute: goss version v0.3.5
==> googlecompute: Uploading goss tests...
    googlecompute: Creating directory: /tmp/goss
    googlecompute: Uploading vars file ansible/tests/production.vars.goss.yaml
    googlecompute: Uploading ansible/tests/remote_dependencies.goss.yaml
==> googlecompute: Running goss tests...
    googlecompute: ....
    googlecompute:
    googlecompute: Total Duration: 0.403s
    googlecompute: Count: 4, Failed: 0, Skipped: 0
==> googlecompute: Goss tests ran successfully
==> googlecompute: Deleting instance...
    googlecompute: Instance has been deleted!
==> googlecompute: Creating image...
==> googlecompute: Deleting disk...
    googlecompute: Disk has been deleted!
Build 'googlecompute' finished.
petemounce commented 6 years ago

(I'm pretty sure the permission-denied part is because I have two goss provisioners and there's no exists-check for the previously-downloaded binary, or that I've previously installed goss to /usr/local/bin/ and this plugin hasn't checked, or something like that - I haven't dug into why.

mschuchard commented 6 years ago

I was looking at PR'ing this myself, so big thanks for you taking it on.

My big question when going through writing the code myself was how to associate a vars file with each test. It kind of seems to me that currently this plugin does not allow per-test gossfile specification and then therefore also per-test var file specification. That seems like a problem unless you cram all of your tests together and are not doing i.e. role-based testing.

petemounce commented 6 years ago

I address that by different provisioner blocks (one for assertions that are not subject to e.g. network transients, one for ones that are), and by using a packer variable substitution to choose the name of the vars file to use.

For example

    {
      "goss_file": "local_only.goss.yaml",
      "tests": [
        "ansible/tests/baseline.goss.yaml",
        "ansible/tests/bd_platform.goss.yaml",
        "ansible/tests/buildkite_agent.goss.yaml",
        "ansible/tests/local_only.goss.yaml",
        "ansible/tests/node_metrics.goss.yaml"
      ],
      "type": "goss",
      "use_sudo": true,
      "vars_file": "ansible/tests/{{user `environment`}}.vars.goss.yaml",
      "version": "0.3.5"
    },
    {
      "goss_file": "remote_dependencies.goss.yaml",
      "tests": [
        "ansible/tests/remote_dependencies.goss.yaml"
      ],
      "type": "goss",
      "use_sudo": true,
      "vars_file": "ansible/tests/{{user `environment`}}.vars.goss.yaml",
      "version": "0.3.5"
    }
mschuchard commented 6 years ago

Oh nice workaround. However, intrinsic support for that in the plugin would be nice as the Packer template would then be cleaner.

petemounce commented 6 years ago

@mschuchard Sure - I wasn't able to think of how goss would be invoked in the way that I think you mean, though, so I haven't made an attempt.

mschuchard commented 6 years ago

Something like this for the interface would be great.

"tests": [{
  "dir": "ansible/tests",
  "goss_file": "local_only.goss.yaml",
  "vars_file": "ansible/tests/{{user `environment`}}.vars.goss.yaml"
},
{
  "dir": "other/tests",
  "goss_file": "goss_tests.yaml",
  "vars_file": "other/more_vars.yaml"
}]

Which would require a refactoring of the plugin. Additionally, using the GOSS API instead of the CLI would be nice, but one step at a time.

petemounce commented 6 years ago

I understand a bit more, but have not yet grokked what it means you can achieve?

fishnix commented 6 years ago

Thanks for this PR @petemounce! We'll have a look asap.

petemounce commented 6 years ago

@fishnix thanks :)

petemounce commented 6 years ago

Thanks for the merge!

If you have any ideas for how to support environment variable pass through (I had a look and the packer remote command API is a little limited; I could only come up with a way that would work on non Windows), I might be up for that as well.