hashicorp / packer

Packer is a tool for creating identical machine images for multiple platforms from a single source configuration.
http://www.packer.io
Other
15.05k stars 3.32k forks source link

builder - orphaned http_directory/kickstart `port` files #9447

Open rjhornsby opened 4 years ago

rjhornsby commented 4 years ago

Overview of the Issue

Packer, when setting up an internal http/kickstart server inside a virtualbox-iso builder, is leaving behind a directory of files called packer_cache/port/ which contains zero byte files that aren't being cleaned up. The files appear to be named after the randomly selected HTTP port used as the {{ .HTTPPort }} variable.

This a minor annoyance, and is easily cleaned by hand. However, if packer is using this list to exclude port numbers as in-use when selecting a random port, eventually it will exhaust the supply - especially in automated/continuous build setups.

Reproduction Steps

Build a VM with Packer using the http_directory to serve as an internal kickstart config host.

The result looks something like this

$ tree packer_cache | head -10
packer_cache
├── 2a0087cd8f9bca710e935b3b59e1e8befa9a8d93.iso
├── 2a0087cd8f9bca710e935b3b59e1e8befa9a8d93.iso.lock
├── aa03c0a867ff9ac2ced7bf834d5d94db36e914b4.iso
├── aa03c0a867ff9ac2ced7bf834d5d94db36e914b4.iso.lock
└── port
    ├── 2717
    ├── 2927
    ├── 3010
    ├── 3051
...

Each packer build ... creates and leaves behind a new file in the port directory.

Packer version

1.6.0

Simplified Packer Buildfile

  "builders": [
    {
      "type": "virtualbox-iso",
      "boot_command": [
        "<tab><wait> net.ifnames=0 inst.text inst.noninteractive inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ami.ks.cfg<enter><wait>"
      ],
      "guest_os_type": "RedHat_64",
       "http_directory": "http"
...

Operating system and Environment details

Host OS running Packer is macOS 10.15.5. Guest OSes (vm builds) are CentOS 7 and CentOS 8.

rjhornsby commented 4 years ago

I don't know golang, so I'm trying my best to read the Packer code here.

It looks like the port file should get removed by common/net/configure_port.go#L108-L110.

This function, cleanupFunc, is passed back to the caller of ListenRangeConfig#L118.

As far as I can tell, however, this function is never called. In common/step_http_server.go#L70-L75, the Cleanup function only closes the socket, but doesn't remove the lockfile or call s.l.cleanupFunc?

There might be a specific reason for this behavior I'm not aware of.