Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@JohnMertz
Created July 20, 2019 07:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JohnMertz/9a80c185b6581f873a218f48374a69c9 to your computer and use it in GitHub Desktop.
Save JohnMertz/9a80c185b6581f873a218f48374a69c9 to your computer and use it in GitHub Desktop.
Extract and Configure LXC from Archived Backup
#!/usr/bin/perl
# Note for GitHub:
# This script makes several assumptions based on the backup image I use.
# Mine is a freshly installed Debian image preconfigured just how I want it.
# The script relies on the name 'fresh-lxc' and IP '10.0.3.1' being set.
# It is also written with Debian Buster as the host, some paths may differ.
# Make changes appropriately.
use strict;
use warnings;
my ($name,$ip);
unless (scalar(@ARGV) == 2) {
help();
}
# Be flexible about which order the arguments are provided
foreach (@ARGV) {
if ($_ =~ m/\d{1,3}/) {
if ($_ > 1 && $_ < 256) {
if (defined $ip) {
$name = $_;
} else {
$ip = $_;
}
} else {
if (defined $name) {
help();
} else {
$name = $_;
}
}
} else {
if (defined $name) {
help();
} else {
$name = $_;
}
}
}
# Prevent the invalid filename character /, and the end-of-clause ;
if ($name =~ m|[;/]|) {
print "You're trying to be sneaky... Sorry, no deal!\n";
exit();
}
# Collect all of the files and directories currently set up in the LXC directory
my $existing = `ls /var/lib/lxc`;
my @existing = split(" ", $existing);
foreach (@existing) {
# Bail if $name already belongs to a file or directory
if ($name eq $_) {
print "The name \"$_\" is already taken by another container or file in /var/lib/lxc/\n";
exit();
}
# If the item found is a directory, check it's configuration for conflicts
if (-d "/var/lib/lxc/$_") {
if (-r "/var/lib/lxc/$_/config") {
# Get the configured IPv4 address for that container
my $tmp_ip = `grep lxc.net.0.ipv4.address /var/lib/lxc/$_/config`;
chomp $tmp_ip;
$tmp_ip =~ s/.*10\.0\.3\.(\d+)/$1/;
# Bail if the IP address conflicts
if ($tmp_ip eq $ip) {
print "The IP 10.0.3.$ip is already taken by \"$_\"\n";
exit();
}
}
}
}
print "Hurray! Those variables are available!\n";
# Check to make sure that my TGZ backup still exists
unless (-r "/var/lib/lxc/fresh-lxc.tgz") {
die 'Uh oh. Looks like "/var/lib/lxc/fresh-lxc.tgz" is missing. Abort.' . "\n";
}
print "Creating directory /var/lib/lxc/$name\n";
system("mkdir /var/lib/lxc/$name");
# Use pv to get a nice progress bar while uncompressing
print "Decompressing fresh-lxc.tgz...\n";
system("pv /var/lib/lxc/fresh-lxc.tgz | tar xzf - -C /var/lib/lxc/$name");
print "Moving contents of /var/lib/lxc/$name/fresh-lxc to /var/lib/lxc/$name/; removing empty dir.\n";
system("mv /var/lib/lxc/$name/fresh-lxc/* /var/lib/lxc/$name/");
system("rmdir /var/lib/lxc/$name/fresh-lxc");
print "Replacing 'fresh-lxc' with $name in config and /etc/hostname.\n";
system("sed -i 's/fresh-lxc/$name/' /var/lib/lxc/$name/config /var/lib/lxc/$name/rootfs/etc/hostname");
print "Replacing '10.0.3.2' with 10.0.3.$ip in config and /etc/network/interfaces.\n";
system("sed -i 's/10.0.3.2/10.0.3.$ip/' /var/lib/lxc/$name/config /var/lib/lxc/$name/rootfs/etc/network/interfaces");
print "Cloning complete. You can start the container with: lxc-start -n $name\n";
print "Then either attach to the container with: lxc-attach -n $name\n";
print "or connect via SSH to the IP: 10.0.3.$ip\n";
sub help {
print "\nUsage: $0 [name|ip]\n\n";
print "Command requires exactly 2 arguments:\n\n";
print " The last octet of the IP address [2-255]\n";
print " The name of the container.\n\n";
print "These will both be checked to ensure that they are not taken.\n\n";
exit();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment