/[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 409 - (hide annotations)
Wed Sep 9 10:36:00 2009 UTC (14 years, 8 months ago) by dpavlin
File size: 4249 byte(s)
don't allow $server::net_clients to go negative (sigh!)

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

  ViewVC Help
Powered by ViewVC 1.1.26