1 ab9f3da9 2020-05-26 mischa #!/usr/bin/env perl
3 3481b7e3 2023-05-05 mischa # Copyright (c) 2019-2023 Mischa Peters <mischa @ openbsd.amsterdam>
5 ab9f3da9 2020-05-26 mischa # Permission to use, copy, modify, and distribute this software for any
6 ab9f3da9 2020-05-26 mischa # purpose with or without fee is hereby granted, provided that the above
7 ab9f3da9 2020-05-26 mischa # copyright notice and this permission notice appear in all copies.
9 ab9f3da9 2020-05-26 mischa # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 ab9f3da9 2020-05-26 mischa # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 ab9f3da9 2020-05-26 mischa # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 ab9f3da9 2020-05-26 mischa # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 ab9f3da9 2020-05-26 mischa # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 ab9f3da9 2020-05-26 mischa # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 ab9f3da9 2020-05-26 mischa # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 ab9f3da9 2020-05-26 mischa # vmm(4)/vmd(8) VM remove script for OpenBSD Amsterdam
18 ab9f3da9 2020-05-26 mischa # 2020/05/25 version 2 - Perl again! :)
20 ab9f3da9 2020-05-26 mischa use 5.024;
21 ab9f3da9 2020-05-26 mischa use strict;
22 ab9f3da9 2020-05-26 mischa use warnings;
23 ab9f3da9 2020-05-26 mischa use autodie;
24 ab9f3da9 2020-05-26 mischa use Cwd qw(cwd);
25 ab9f3da9 2020-05-26 mischa use User::pwent;
27 ab9f3da9 2020-05-26 mischa # Get vmXX.txt from arguments
28 ab9f3da9 2020-05-26 mischa if (! $ARGV[0]) {
29 1408dd21 2020-05-26 mischa print STDERR "usage: $0 vmXX.txt\n";
32 ab9f3da9 2020-05-26 mischa my $vmid = $ARGV[0];
34 ab9f3da9 2020-05-26 mischa # fuction to parse _deploy.conf and vm*.txt files
35 ab9f3da9 2020-05-26 mischa # all variables are stripped and added to either %vms or %conf
36 ab9f3da9 2020-05-26 mischa sub get_variables {
37 ab9f3da9 2020-05-26 mischa my ($hash_name, @files) = @_;
39 ab9f3da9 2020-05-26 mischa my $filename;
40 ab9f3da9 2020-05-26 mischa my $vm_name;
41 ab9f3da9 2020-05-26 mischa my $vm_number;
43 ab9f3da9 2020-05-26 mischa for my $file (@files) {
44 ab9f3da9 2020-05-26 mischa # When hash is 'vms' use the vm_name as key
45 ab9f3da9 2020-05-26 mischa # Otherwise use 'conf' as key
46 ab9f3da9 2020-05-26 mischa if ($hash_name eq "vms") {
47 ab9f3da9 2020-05-26 mischa ($filename = $file) =~ s/.*\///;
48 ab9f3da9 2020-05-26 mischa ($vm_name = $filename) =~ s/\.txt//;
49 ab9f3da9 2020-05-26 mischa ($vm_number = $vm_name) =~ s/^vm//;
50 ab9f3da9 2020-05-26 mischa $hash{$vm_name}{'vm_number'} = $vm_number;
53 ab9f3da9 2020-05-26 mischa open my $fh, "<", "$file";
54 ab9f3da9 2020-05-26 mischa while (my $row = <$fh>) {
55 ab9f3da9 2020-05-26 mischa next if ($row =~ /^\s*($|#)/);
56 ab9f3da9 2020-05-26 mischa chomp($row);
57 ab9f3da9 2020-05-26 mischa (my $key, my $val) = split(/=/, $row, 2);
58 ab9f3da9 2020-05-26 mischa if ($hash_name eq "vms") {
59 ab9f3da9 2020-05-26 mischa ($hash{$vm_name}{$key} .= $val) =~ s/^"+|"+$//g;
61 ab9f3da9 2020-05-26 mischa ($hash{$hash_name}{$key} .= $val) =~ s/^"+|"+$//g;
64 ab9f3da9 2020-05-26 mischa close $fh;
66 ab9f3da9 2020-05-26 mischa return %hash;
69 ab9f3da9 2020-05-26 mischa # function to create accounts on the host for vmctl(8) access
70 ab9f3da9 2020-05-26 mischa sub remove_accounts {
71 ab9f3da9 2020-05-26 mischa my %conf = %{$_[0]};
72 ab9f3da9 2020-05-26 mischa my %vms = %{$_[1]};
74 6050bab4 2020-05-26 mischa printf "userdel(8) user:\n";
75 ab9f3da9 2020-05-26 mischa for my $vm_name (sort keys %vms) {
76 ab9f3da9 2020-05-26 mischa my $_instance = $vms{$vm_name}{'instance'} || $vm_name;
77 3481b7e3 2023-05-05 mischa my $_owner = $vms{$vm_name}{'username'};
78 ab9f3da9 2020-05-26 mischa my $_group = $conf{'conf'}{'VMDUSERS'};
79 ab9f3da9 2020-05-26 mischa my $id = getpwnam("$_owner");
81 ab9f3da9 2020-05-26 mischa if ($id) {
82 ab9f3da9 2020-05-26 mischa qx(/usr/sbin/userdel -r $_owner);
83 ab9f3da9 2020-05-26 mischa printf "%16s %s account removed\n", $_instance, $_owner;
84 ab9f3da9 2020-05-26 mischa qx(/usr/sbin/groupdel $_owner);
85 ab9f3da9 2020-05-26 mischa printf "%16s %s group removed\n", $_instance, $_owner;
90 ab9f3da9 2020-05-26 mischa # function to create the disk image files for vmm(4)/vmd(8)
91 ab9f3da9 2020-05-26 mischa sub backup_img_files {
92 ab9f3da9 2020-05-26 mischa my %conf = %{$_[0]};
93 ab9f3da9 2020-05-26 mischa my %vms = %{$_[1]};
95 ab9f3da9 2020-05-26 mischa printf "vmm(4)/vmd(8) files:\n";
96 ab9f3da9 2020-05-26 mischa for my $vm_name (sort keys %vms) {
97 ab9f3da9 2020-05-26 mischa my $_instance = $vms{$vm_name}{'instance'} || $vm_name;
98 ab9f3da9 2020-05-26 mischa my $_disk_format = $vms{$vm_name}{'format'} || $conf{'conf'}{'FORMAT'};
99 ab9f3da9 2020-05-26 mischa my $_disk = $conf{'conf'}{'IMAGES'} . "/" . $_instance . "." . $_disk_format;
100 ab9f3da9 2020-05-26 mischa my $_disk2 = $conf{'conf'}{'IMAGES'} . "/" . $_instance . "_extra." . $_disk_format if $vms{$vm_name}{'disk2'};
102 ab9f3da9 2020-05-26 mischa if (-e $_disk) {
103 ab9f3da9 2020-05-26 mischa qx(mv $_disk $_disk-backup);
104 ab9f3da9 2020-05-26 mischa printf "%16s %s mv(1) %s-backup\n", $_instance, $_disk, $_disk;
106 ab9f3da9 2020-05-26 mischa if ($_disk2) {
107 ab9f3da9 2020-05-26 mischa if (-e $_disk2) {
108 ab9f3da9 2020-05-26 mischa qx(mv $_disk2 $_disk2-backup);
109 ab9f3da9 2020-05-26 mischa printf "%16s %s mv(1) $_disk2-backup\n", $_instance, $_disk2;
115 ab9f3da9 2020-05-26 mischa sub backup_vm_files {
116 ab9f3da9 2020-05-26 mischa my %conf = %{$_[0]};
117 ab9f3da9 2020-05-26 mischa my %vms = %{$_[1]};
119 6050bab4 2020-05-26 mischa printf "vmXX.txt file:\n";
120 ab9f3da9 2020-05-26 mischa for my $vm_name (sort keys %vms) {
121 ab9f3da9 2020-05-26 mischa my $_instance = $vms{$vm_name}{'instance'} || $vm_name;
122 ab9f3da9 2020-05-26 mischa my $filename = $conf{'conf'}{'VMS'} . "/" . $vmid;
123 ab9f3da9 2020-05-26 mischa qx(cp $filename $filename-backup);
124 ab9f3da9 2020-05-26 mischa printf "%16s %s cp(1) %s-backup\n", $_instance, $filename, $filename;
125 ab9f3da9 2020-05-26 mischa qx(mv $filename $filename.free);
126 ab9f3da9 2020-05-26 mischa printf "%16s %s mv(1) %s.free\n", $_instance, $filename, $filename;
127 ab9f3da9 2020-05-26 mischa qx(chown -R mischa:mischa $filename-backup $filename.free);
131 ab9f3da9 2020-05-26 mischa # function to print all keys & values for debug purposes
132 ab9f3da9 2020-05-26 mischa sub debug_parse {
133 ab9f3da9 2020-05-26 mischa my %conf = %{$_[0]};
134 ab9f3da9 2020-05-26 mischa my %vms = %{$_[1]};
136 ab9f3da9 2020-05-26 mischa for my $vm_name (sort keys %vms) {
137 ab9f3da9 2020-05-26 mischa for my $key (keys %{$vms{$vm_name}}) {
138 ab9f3da9 2020-05-26 mischa printf "VMS: %s %s = %s\n", $vm_name, $key, $vms{$vm_name}{$key};
143 ab9f3da9 2020-05-26 mischa # check if _deploy.conf exists in current working directory
144 ab9f3da9 2020-05-26 mischa my %conf;
145 ab9f3da9 2020-05-26 mischa my $dir = cwd;
146 ab9f3da9 2020-05-26 mischa if (-e "$dir/_deploy.conf") {
147 ab9f3da9 2020-05-26 mischa %conf = get_variables('conf', "$dir/_deploy.conf");
149 ab9f3da9 2020-05-26 mischa printf "Unable to find config file in current directory (%s).\n", $dir;
150 ab9f3da9 2020-05-26 mischa printf "Create the config file _deploy.conf in %s.\n", $dir;
154 ab9f3da9 2020-05-26 mischa # parse all vm*.txt files in the VMS directory
156 ab9f3da9 2020-05-26 mischa my @files = glob "$conf{'conf'}{'VMS'}/$vmid";
157 ab9f3da9 2020-05-26 mischa %vms = get_variables('vms', @files);
159 ab9f3da9 2020-05-26 mischa # run all functions
160 ab9f3da9 2020-05-26 mischa #debug_parse(\%conf, \%vms);
161 ab9f3da9 2020-05-26 mischa remove_accounts(\%conf, \%vms);
162 ab9f3da9 2020-05-26 mischa backup_img_files(\%conf, \%vms);
163 ab9f3da9 2020-05-26 mischa backup_vm_files(\%conf, \%vms);