/[pxelator]/lib/PXElator/client.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /lib/PXElator/client.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 510 - (hide annotations)
Wed Jul 21 16:49:29 2010 UTC (13 years, 9 months ago) by dpavlin
File size: 4389 byte(s)
symlinks now return location which they point to

This allows to specify configuration options, like
memdisk.image as simple symlinks directly to files

1 dpavlin 156 package client;
2    
3     use warnings;
4     use strict;
5     use autodie;
6    
7     use File::Slurp;
8 dpavlin 329 use Data::Dump qw/dump/;
9 dpavlin 395 use File::Path;
10 dpavlin 219
11     use server;
12 dpavlin 208 use format;
13 dpavlin 322 use ip;
14 dpavlin 330 use ping;
15 dpavlin 406 use kvm;
16 dpavlin 156
17 dpavlin 220 our $debug = $server::debug;
18    
19 dpavlin 219 sub mkbasedir {
20     my $path = shift;
21     $path =~ s{(^.*)/[^/]+$}{$1};
22     mkdir $path unless -d $path;
23     return $path;
24     }
25    
26 dpavlin 200 sub mac_path { $server::conf . '/mac/' . $_[0] }
27     sub ip_path { $server::conf . '/ip/' . join('/', @_) }
28 dpavlin 219 sub conf_value {
29     my $path = shift;
30     my $value;
31     if ( -l $path ) {
32     $value = readlink $path;
33     $value =~ s{.*/([^/]+)$}{$1};
34     } elsif ( -f $path ) {
35     $value = read_file $path;
36     } else {
37 dpavlin 244 warn "W: $path not file or symlink\n";
38 dpavlin 219 }
39     return $value;
40     }
41 dpavlin 200
42 dpavlin 156 sub conf {
43     my $ip = shift;
44     my $name = shift;
45     my ( $default, $value );
46     if ( $#_ == 0 ) {
47     $value = shift;
48     } elsif ( $#_ == 1 && $_[0] eq 'default' ) {
49     $default = $_[1]
50     }
51    
52 dpavlin 200 my $path = ip_path $ip;
53 dpavlin 156 mkdir $path unless -d $path;
54     $path .= '/' . $name;
55    
56     if ( defined $value ) {
57 dpavlin 219 mkbasedir $path;
58 dpavlin 156 write_file $path, $value;
59     warn "update $path = $value";
60     } elsif ( ! -e $path && defined $default ) {
61 dpavlin 219 mkbasedir $path;
62 dpavlin 156 write_file $path, $default;
63     warn "default $path = $default";
64     $value = $default;
65 dpavlin 510 } elsif ( -l $path ) {
66     $value = readlink $path;
67 dpavlin 219 } elsif ( -f $path ) {
68     $value = read_file $path;
69 dpavlin 443 chomp $value;
70 dpavlin 219 } else {
71 dpavlin 220 warn "# $name missing $path\n" if $debug;
72 dpavlin 156 }
73     return $value;
74     }
75    
76 dpavlin 305 sub all_conf {
77     my $ip = shift;
78     my $path = ip_path $ip || return;
79     my $conf;
80 dpavlin 443 foreach my $file ( glob("$path/*"), glob("$path/*/*") ) {
81 dpavlin 305 my $name = $file;
82 dpavlin 443 $name =~ s{^$path/+}{} || die "can't remove $path from $name";
83 dpavlin 510 $conf->{ $name } =
84     -l $file ? readlink $file :
85     -f $file ? read_file $file :
86     '?';
87 dpavlin 305 }
88     return $conf;
89     }
90 dpavlin 200 sub next_ip($) {
91     my $mac = shift;
92 dpavlin 313 $mac = format::mac($mac);
93 dpavlin 168
94 dpavlin 409 if ( $server::new_clients > 0 ) {
95     warn "# clients left: ", --$server::new_clients;
96 dpavlin 391 } else {
97     warn "W: no new clients accepted";
98     return '0.0.0.0';
99     }
100    
101 dpavlin 168 my $prefix = $server::ip;
102     $prefix =~ s{\.\d+$}{.};
103     my $addr = $server::ip_from || die;
104     my $ip = $prefix . $addr;
105    
106 dpavlin 330 while ( -e ip_path($ip) || ping::host($ip) ) {
107 dpavlin 168 $ip = $prefix . $addr++;
108     die "all addresses allocated!" if $addr == $server::ip_to;
109     warn "skip $ip\n";
110     }
111    
112     warn "next_ip $ip\n";
113 dpavlin 200
114 dpavlin 244 save_ip_mac( $ip, $mac );
115    
116     return $ip;
117     }
118    
119     sub save_ip_mac {
120     my ($ip,$mac) = @_;
121 dpavlin 313 $mac = format::mac($mac);
122 dpavlin 412 return if $mac eq '00:00:00:00:00:00' || $ip eq '0.0.0.0';
123 dpavlin 244
124 dpavlin 254 mkdir ip_path($ip) unless -e ip_path($ip);
125 dpavlin 200
126 dpavlin 217 my $mac_path = mac_path($mac);
127 dpavlin 286 unlink $mac_path if -l $mac_path; # XXX audit?
128 dpavlin 217 symlink ip_path($ip), $mac_path;
129 dpavlin 323 write_file( ip_path($ip,'mac'), $mac );
130 dpavlin 168 }
131    
132 dpavlin 200 sub ip_from_mac($) {
133 dpavlin 194 my $mac = shift;
134 dpavlin 313 $mac = format::mac($mac);
135 dpavlin 194
136 dpavlin 200 my $mac_path = mac_path $mac;
137 dpavlin 194 return unless -e $mac_path;
138    
139     my $ip;
140    
141     if ( -f $mac_path ) {
142     $ip = read_file $mac_path;
143     unlink $mac_path;
144 dpavlin 200 symlink ip_path($ip), $mac_path;
145 dpavlin 194 warn "I: upgrade to mac symlink $mac_path\n";
146     } elsif ( -l $mac_path ) {
147 dpavlin 219 $ip = conf_value $mac_path;
148 dpavlin 194 } else {
149     die "$mac_path not file or symlink";
150     }
151    
152     return $ip;
153     }
154    
155 dpavlin 200 sub mac_from_ip($) {
156     my $ip = shift;
157 dpavlin 219 conf_value ip_path($ip, 'mac');
158 dpavlin 200 }
159    
160     sub change_ip($$) {
161     my ($old, $new) = @_;
162 dpavlin 323 return if $old eq $new;
163     my $mac = mac_from_ip($old) || die "no mac for $old";
164 dpavlin 200 rename ip_path($old), ip_path($new);
165     unlink mac_path($mac);
166     symlink ip_path($new), mac_path($mac);
167 dpavlin 323 return $new;
168 dpavlin 200 }
169    
170 dpavlin 322 sub all_ips {
171     sort { ip::to_int($a) cmp ip::to_int($b) }
172     map {
173     my $ip = $_;
174     $ip =~ s{^.+/ip/}{};
175 dpavlin 406 autocreate_params( $ip );
176 dpavlin 322 $ip;
177     } glob("$server::conf/ip/*")
178     }
179    
180 dpavlin 323 sub remove {
181     my $ip = shift;
182     if ( my $mac = mac_from_ip $ip ) {
183     unlink "$server::conf/mac/$mac";
184     }
185 dpavlin 395 rmtree "$server::conf/ip/$ip";
186 dpavlin 323 }
187    
188 dpavlin 329 sub arp_mac_dev {
189     my $arp = {
190     map {
191     my @c = split(/\s+/,$_);
192     if ( $#c == 5 ) {
193     client::save_ip_mac( $c[0], $c[3] );
194     ( uc $c[3] => $c[5] )
195     } else {
196     }
197     } read_file('/proc/net/arp')
198     };
199    
200     warn "# arp ",dump( $arp );
201     return $arp;
202     }
203    
204 dpavlin 403 sub rebuild_mac_links {
205     warn "# rebuild mac links";
206     foreach my $ip ( all_ips ) {
207     my $mac = ip_path $ip, 'mac';
208     if ( -e $mac ) {
209     $mac = read_file $mac;
210 dpavlin 455 chomp $mac;
211 dpavlin 403 save_ip_mac( $ip, $mac );
212     warn "## $ip $mac\n";
213     }
214     }
215     }
216    
217 dpavlin 406 sub autocreate_params {
218     my $ip = shift;
219     my $mac = mac_from_ip $ip;
220     if ( $mac =~ m{^AC:DE:48:00:00} && ! defined conf( $ip, 'kvm' ) ) {
221     conf( $ip, 'kvm', default => kvm::nr_from_mac( $mac ) );
222     warn "# create kvm for $ip";
223     }
224     }
225    
226 dpavlin 156 1;

  ViewVC Help
Powered by ViewVC 1.1.26