TemporaryJobs writes state to disk so jobs can be cleaned up by subseque...

...nt runs.

If a run of TemporaryJobs is killed off while jobs are still deployed,
they will be left running. This can lead to a lot of abondoned jobs still
running. To prevent this, TemporaryJobs now genereates a random string for
run, and uses this as a prefix for each job name. This string is written
to disk as the name of file in /tmp/helios-temp-jobs. When TemporaryJobs
starts, it will read all files in this directory, and delete all jobs
which start with the prefix. If TemporaryJobs runs to completion, and
all jobs are undeployed successfully, the temporary file will be deleted.
There is a race condition here where another JobPrefixFile might delete this file after we create it but before we lock it.

Create the file with a suffix, lock it, and then rename it to its final name:
```java
final Path dir = Paths.get(PREFIX_FILE_DIRECTORY);
final Path file = dir.resolve(prefix);
final Path tmp = dir.resolve(prefix + ".tmp");
try {
  this.channel = FileChannel.open(tmp, CREATE_NEW, WRITE);
  this.lock = channel.lock();
  Files.move(tmp, file);
} catch (IOException e) {
  throw new RuntimeException("Failed to create lock file: " + file, e);
}
```

Then have the cleanup code exclude files ending with `.tmp`.