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

  ViewVC Help
Powered by ViewVC 1.1.26