How does Proxmox know when an LXC container finished booting? Any way to trick it to think a container is still booting?

wigg3

Member
Sep 5, 2018
4
1
21
30
I have some VMs that depend on a shared storage to be initialized (ZFS pool) before they are started. This takes anywhere from 15-20 minutes.

I want to setup a container with 1st boot priority, and have a script loop to check if the storage has been initiated. The other VMs will only be initialized after this container finishes booting.

How can I trick Proxmox to think the container is still booting while the script loop is running? After the loop finishes, it will complete the "boot" and then Proxmox can move to startup the remaining VMs.

Edit: I just saw /usr/share/pve-docs/examples/guest-example-hookscript.pl. I'll see if I can do something like this on the pre-start phase for now. If there's a better way, please let me know :)
 
Last edited:
  • Like
Reactions: LEI
I came up with this hookscript, it's my first time with Perl (I thought it had to be a Perl script) but it's working fine for what I needed:

Perl:
#!/usr/bin/perl

# Checks if a given storage is available before staring the given VM/CT.
# You can set this via pct/qm with
# pct set <vmid> -hookscript <volume-id>
# qm set <vmid> -hookscript <volume-id>
# where <volume-id> has to be an executable file in the snippets folder
# of any storage with directories e.g.:
# qm set 100 -hookscript local:snippets/check_for_storage_before_startup.pl
# pct set 100 -hookscript local:snippets/check_for_storage_before_startup.pl

use strict;
use warnings;

print "GUEST HOOK: " . join( ' ', @ARGV ) . "\n";

# First argument is the vmid
my $vmid = shift;

# Second argument is the phase
my $phase = shift;

# Options
my $maxDelayMinutes = 20;
my $storageName = 'Proxmox_TrueNAS';

if ( $phase eq 'pre-start' ) {
    print "$vmid is starting, doing preparations.\n";

    my $time            = time();
    my $maxDelaySeconds = $maxDelayMinutes * 60;
    my $abortAfterTime  = $time + $maxDelaySeconds;
    my $timeRemainging;

    while ( $time < $abortAfterTime ) {
        my $isStorageAvailable = `pvesm status -enabled | grep '$storageName'`;

        if ( length($isStorageAvailable) > 0 ) {
            print "$storageName is available, continuing...\n";
            exit(0);
        }

        $time           = time();
        $timeRemainging = $abortAfterTime - $time;

        print
"$storageName is not available yet, waiting for $timeRemainging seconds\n";
        sleep(10);
    }

    print "Max Delay reached, continuing startup...\n";
    exit(0);

}
elsif ( $phase eq 'post-start' ) {
    print "$vmid started successfully.\n";

}
elsif ( $phase eq 'pre-stop' ) {
    print "$vmid will be stopped.\n";

}
elsif ( $phase eq 'post-stop' ) {
    print "$vmid stopped. Doing cleanup.\n";

}
else {
    die "got unknown phase '$phase'\n";
}
exit(0);

It intentionally doesn't stop the VM/CT from being boot up after the max delay expires.
 
Last edited: