#!/usr/bin/perl use warnings; use strict; use JSON; use Data::Dumper; =pod depends: libjson-perl on Debian perl::JSON on RH & clones launch: sudo perl json-to-xl.pl > myout prep: suppress errors about garbage, for i in /var/lib/xen/*.libxl-json ; do sudo sed -i -e 's|\x00||' $i ;done env: developed/tested on CentOS 8 tested on deb13/Trixie sorting: cfg files are sorted by mtime (to tmp array), then by uuid then only the latest version of that uuid is saved archive post: https://lists.xenproject.org/archives/html/xen-users/2019-11/msg00052.html =cut my $json=JSON->new->allow_nonref; my $OUT=""; my $fn=""; my $nm=""; my $nmlast=""; my $vmid=48; my $head=""; chdir "/var/lib/xen" ; #my @fyls = sort { $a=~s/^userdata-d\.\d+\.// <=> $b=~s/^userdata-d\.\d+\.// || -M $a <=> -M $b } glob("*.libxl-json"); #my @files = glob("*.libxl-json"); #foreach (@files) { # print "$_\n"; #} print "\n"; # sort on the guid and we enforce uniqueness my @fyls = sort { my ($an) = $a =~ /^userdata-d\.\d+\.(.*)$/ ; my ($bn) = $b =~ /^userdata-d\.\d+\.(.*)$/ ; $an cmp $bn || -M $a <=> -M $b } glob("*.libxl-json");; foreach (@fyls) { print "$_\n"; } print "size=$#fyls \n\n"; ### main loop over xl json config files foreach ( @fyls ) { $head=""; $OUT=""; $fn=$_; $head .= "# fn=$fn\n"; { # get the domid $fn=~m/userdata-d\.(\d+)\..*/; $vmid=$1; $head .= "# domid=$vmid\n"; } # high domid means domU is in testing - not in regular use next if $vmid > 10000; ### prelim # skip dom0 next if $fn=~m/userdata-d\.0/; #my $jt=`cat /home/tlviewer/buster/my.json`; my $jt=`cat $fn`; #$jt =~ s/\^\@$//; # final chars: \n '\00' must be stripped $jt =~ s/}\n.*$/}/g; #print "$jt,\n"; #exit 0; #$jt =~ s/^\[//; #$jt =~ s/\]$//; ### create perl objects from json object my $ps=$json->decode($jt); #print "type=",ref($ps),"\n"; $nm=$ps->{c_info}->{name}; $OUT.="name=\"$nm\"\n"; $OUT.="$head"; next if $nmlast eq $nm ; #print Dumper($ps),"\n"; #exit 0; { # local namespace # get name & uuid my $zz=$ps->{c_info}; foreach (keys %$zz) { next if ( $_ eq "name"); $OUT.="$_=\"$zz->{$_}\"\n" ; # print "$_\n"; } } # end local { # start local my $zz=$ps->{b_info}; $OUT.="vcpus=$zz->{max_vcpus}\n"; $OUT.="max_memkb=$zz->{max_memkb}\n"; $OUT.="kernel=\"$zz->{kernel}\"\n" if defined $zz->{kernel}; $OUT.="bootloader=\"$zz->{bootloader}\"\n" if defined $zz->{bootloader}; $OUT.="cmdline=\"$zz->{cmdline}\"\n" if defined $zz->{cmdline}; } # end local # # vif=['bridge=br0,mac=00:16:3e:2c:a3:e6'] # iterate through vif array reference $OUT.="vif=["; # 'phy:/dev/maxvm/buster,xvda,w', foreach my $zz (@{$ps->{nics}}) { #print $zz,"\n"; $OUT.="\'bridge=$zz->{bridge},mac=$zz->{mac}\'," if defined $zz->{bridge}; } # strip off final comma $OUT=~ s/\,$//; $OUT.="]\n"; #print "type=",ref($ps->{disks}),"\n"; # iterate through disks array reference $OUT.="disk=["; # 'phy:/dev/maxvm/buster,xvda,w', foreach my $zz (@{$ps->{disks}}) { #print $zz,"\n"; $OUT.="\'phy:$zz->{pdev_path},$zz->{vdev},w\'," if defined $zz->{pdev_path}; } # strip off final comma $OUT=~ s/\,$//; $OUT.="]\n\n"; print "$OUT\n\n"; $nmlast=$nm; } # end while exit 0; __DATA__ for (keys %$zz) { print "$_\n"; }