/[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 443 - (hide annotations)
Tue Sep 29 19:28:24 2009 UTC (14 years, 7 months ago) by dpavlin
File size: 4280 byte(s)
support directories in client configuration directory to separate deploy options
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 dpavlin 443 chomp $value;
68 dpavlin 219 } else {
69 dpavlin 220 warn "# $name missing $path\n" if $debug;
70 dpavlin 156 }
71     return $value;
72     }
73    
74 dpavlin 305 sub all_conf {
75     my $ip = shift;
76     my $path = ip_path $ip || return;
77     my $conf;
78 dpavlin 443 foreach my $file ( glob("$path/*"), glob("$path/*/*") ) {
79 dpavlin 305 my $name = $file;
80 dpavlin 443 $name =~ s{^$path/+}{} || die "can't remove $path from $name";
81     $conf->{ $name } = read_file $file if -f $file;
82 dpavlin 305 }
83     return $conf;
84     }
85 dpavlin 200 sub next_ip($) {
86     my $mac = shift;
87 dpavlin 313 $mac = format::mac($mac);
88 dpavlin 168
89 dpavlin 409 if ( $server::new_clients > 0 ) {
90     warn "# clients left: ", --$server::new_clients;
91 dpavlin 391 } else {
92     warn "W: no new clients accepted";
93     return '0.0.0.0';
94     }
95    
96 dpavlin 168 my $prefix = $server::ip;
97     $prefix =~ s{\.\d+$}{.};
98     my $addr = $server::ip_from || die;
99     my $ip = $prefix . $addr;
100    
101 dpavlin 330 while ( -e ip_path($ip) || ping::host($ip) ) {
102 dpavlin 168 $ip = $prefix . $addr++;
103     die "all addresses allocated!" if $addr == $server::ip_to;
104     warn "skip $ip\n";
105     }
106    
107     warn "next_ip $ip\n";
108 dpavlin 200
109 dpavlin 244 save_ip_mac( $ip, $mac );
110    
111     return $ip;
112     }
113    
114     sub save_ip_mac {
115     my ($ip,$mac) = @_;
116 dpavlin 313 $mac = format::mac($mac);
117 dpavlin 412 return if $mac eq '00:00:00:00:00:00' || $ip eq '0.0.0.0';
118 dpavlin 244
119 dpavlin 254 mkdir ip_path($ip) unless -e ip_path($ip);
120 dpavlin 200
121 dpavlin 217 my $mac_path = mac_path($mac);
122 dpavlin 286 unlink $mac_path if -l $mac_path; # XXX audit?
123 dpavlin 217 symlink ip_path($ip), $mac_path;
124 dpavlin 323 write_file( ip_path($ip,'mac'), $mac );
125 dpavlin 168 }
126    
127 dpavlin 200 sub ip_from_mac($) {
128 dpavlin 194 my $mac = shift;
129 dpavlin 313 $mac = format::mac($mac);
130 dpavlin 194
131 dpavlin 200 my $mac_path = mac_path $mac;
132 dpavlin 194 return unless -e $mac_path;
133    
134     my $ip;
135    
136     if ( -f $mac_path ) {
137     $ip = read_file $mac_path;
138     unlink $mac_path;
139 dpavlin 200 symlink ip_path($ip), $mac_path;
140 dpavlin 194 warn "I: upgrade to mac symlink $mac_path\n";
141     } elsif ( -l $mac_path ) {
142 dpavlin 219 $ip = conf_value $mac_path;
143 dpavlin 194 } else {
144     die "$mac_path not file or symlink";
145     }
146    
147     return $ip;
148     }
149    
150 dpavlin 200 sub mac_from_ip($) {
151     my $ip = shift;
152 dpavlin 219 conf_value ip_path($ip, 'mac');
153 dpavlin 200 }
154    
155     sub change_ip($$) {
156     my ($old, $new) = @_;
157 dpavlin 323 return if $old eq $new;
158     my $mac = mac_from_ip($old) || die "no mac for $old";
159 dpavlin 200 rename ip_path($old), ip_path($new);
160     unlink mac_path($mac);
161     symlink ip_path($new), mac_path($mac);
162 dpavlin 323 return $new;
163 dpavlin 200 }
164    
165 dpavlin 322 sub all_ips {
166     sort { ip::to_int($a) cmp ip::to_int($b) }
167     map {
168     my $ip = $_;
169     $ip =~ s{^.+/ip/}{};
170 dpavlin 406 autocreate_params( $ip );
171 dpavlin 322 $ip;
172     } glob("$server::conf/ip/*")
173     }
174    
175 dpavlin 323 sub remove {
176     my $ip = shift;
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