pf-tools/pf-tools: 13 new changesets
parmelan-guest at users.alioth.debian.org
parmelan-guest at users.alioth.debian.org
Mon Nov 22 10:03:33 UTC 2010
details: http://hg.debian.org/hg/pf-tools/pf-tools/rev/c7fc608106e2
changeset: 1037:c7fc608106e2
user: Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date: Thu Nov 18 18:38:48 2010 +0100
description:
make_interfaces_file() now takes named arguments
details: http://hg.debian.org/hg/pf-tools/pf-tools/rev/edd35d081e43
changeset: 1038:edd35d081e43
user: Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date: Thu Nov 18 19:08:12 2010 +0100
description:
New make_zone_file() function + tests
details: http://hg.debian.org/hg/pf-tools/pf-tools/rev/b6953b2c6294
changeset: 1039:b6953b2c6294
user: Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date: Thu Nov 18 19:10:55 2010 +0100
description:
Rename make_zone_for_site() to __build_zone() and move towards the end of the file with other private functions
details: http://hg.debian.org/hg/pf-tools/pf-tools/rev/332414a94ada
changeset: 1040:332414a94ada
user: Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date: Thu Nov 18 23:21:57 2010 +0100
description:
__build_zone() now takes named arguments
details: http://hg.debian.org/hg/pf-tools/pf-tools/rev/f60925c5f0f2
changeset: 1041:f60925c5f0f2
user: Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date: Thu Nov 18 23:37:14 2010 +0100
description:
More tests for __build_zone()
details: http://hg.debian.org/hg/pf-tools/pf-tools/rev/73098c5041b5
changeset: 1042:73098c5041b5
user: Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date: Fri Nov 19 00:00:01 2010 +0100
description:
Fix tests for make_resolv_conf_file()
details: http://hg.debian.org/hg/pf-tools/pf-tools/rev/5cea11979d4e
changeset: 1043:5cea11979d4e
user: Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date: Fri Nov 19 00:13:13 2010 +0100
description:
__build_interfaces() now takes named arguments
details: http://hg.debian.org/hg/pf-tools/pf-tools/rev/f092fb7b8c60
changeset: 1044:f092fb7b8c60
user: Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date: Fri Nov 19 08:48:57 2010 +0100
description:
New __make_file() function + tests
details: http://hg.debian.org/hg/pf-tools/pf-tools/rev/4bba68d92bc7
changeset: 1045:4bba68d92bc7
user: Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date: Sat Nov 20 11:32:40 2010 +0100
description:
make_sources_list_file(), __build_sources_list() and tests
details: http://hg.debian.org/hg/pf-tools/pf-tools/rev/92677d022426
changeset: 1046:92677d022426
user: Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date: Sat Nov 20 11:34:12 2010 +0100
description:
move __build_sources_list() towards the end of the file
details: http://hg.debian.org/hg/pf-tools/pf-tools/rev/1ee5f40d5689
changeset: 1047:1ee5f40d5689
user: Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date: Sun Nov 21 00:38:54 2010 +0100
description:
New function: __build_interface_lines_ref()
details: http://hg.debian.org/hg/pf-tools/pf-tools/rev/7e40bebcf425
changeset: 1048:7e40bebcf425
user: Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date: Mon Nov 22 09:05:34 2010 +0100
description:
mk_sourceslist, make_sources_list_file() and __build_sources_list(): use an array ref instead of a scalar for the list of additional sections (+ tests)
details: http://hg.debian.org/hg/pf-tools/pf-tools/rev/dd4873cacd2e
changeset: 1049:dd4873cacd2e
user: Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date: Mon Nov 22 11:01:19 2010 +0100
description:
__build_sources_list(): listen to perlcritic and don't use a multiple-statements map
diffstat:
2 files changed, 29 insertions(+), 10 deletions(-)
t/20.zone.t | 34 ++++++++++++++++++++++++++--------
templates/sources.list | 5 +++--
diffs (1991 lines):
diff -r 75b485e19166 -r dd4873cacd2e lib/PFTools/Utils.pm
--- a/lib/PFTools/Utils.pm Thu Nov 18 16:55:31 2010 +0100
+++ b/lib/PFTools/Utils.pm Mon Nov 22 11:01:19 2010 +0100
@@ -47,7 +47,6 @@
Fix_hosts
Mk_dhcp
Mk_PXE_bootfile
- Mk_sourceslist
Change_kopt_for_hostname
Search_and_replace
@@ -56,7 +55,8 @@
our @EXPORT_OK = qw(
make_interfaces_file
make_resolv_conf_file
- make_zone_for_site
+ make_sources_list_file
+ make_zone_file
);
########################################################################
@@ -102,6 +102,8 @@
return ( $pf_config, $global_struct );
}
+# FIXME convert to __make_file()
+# builds both the preseed and PXE files
sub Mk_PXE_bootfile {
my ( $hostname, $host_ref, $pxe_template_filename, $preseed_template,
$default_preseed, $pf_script, $pf_config )
@@ -174,131 +176,33 @@
return $pxe_boot_file;
}
-=head2 make_zone_for_site( $zone_name, $site_name, $global_config )
+=head2 make_zone_file($arguments_ref)
-This function creates the zone file content for the I<$zone_name> zone on site
-I<$site_name>. I<$global_config> references the global configuration hash. It
-returns a reference to the array of lines.
+This function creates a zone file. It takes the
+following named arguments in %{$arguments_ref}:
+
+=over
+
+=item I<zone_name> the zone name
+
+=item I<site_name> the site name
+
+=item I<filename> the output file name
+
+=item I<global_config> a reference to the global configuration hash
=cut
-sub make_zone_for_site {
- my ( $zone_name, $site_name, $global_config ) = @_;
+sub make_zone_file {
+ my ($arguments_ref) = @_;
- if ( not $zone_name ) {
- croak q{ERROR: Invalid empty $zone_name};
- }
- if ( ref $zone_name ) {
- croak q{ERROR: Invalid non-scalar $zone_name};
+ unless ( ref $arguments_ref eq 'HASH' ) {
+ croak q{ERROR: Invalid $arguments_ref};
}
- if ( not $site_name ) {
- croak q{ERROR: Invalid empty $site_name};
- }
- if ( ref $site_name ) {
- croak q{ERROR: Invalid non-scalar $site_name};
- }
+ __make_file( { file_type => q{zone}, %{ $arguments_ref } } );
- if ( not $global_config ) {
- croak q{ERROR: Invalid empty $global_config};
- }
- if ( ref $global_config ne 'HASH' ) {
- croak q{ERROR: Invalid non-hashref $global_config};
- }
-
- # This is not a complete check but it will catch obvious errors,
- # like $global_config referencing a non-config hash
- if ( not exists $global_config->{'ZONE'} ) {
- croak q{ERROR: Invalid $global_config hashref: no 'ZONE' key found};
- }
-
- my $zone_ref = $global_config->{'ZONE'}->{'BY_NAME'}->{$zone_name};
- if ( not $zone_ref ) {
- croak qq{ERROR: Unknown zone_name: $zone_name};
- }
-
- my $zone_part = $zone_ref->{'BY_SITE'}->{$site_name};
- if ( not $zone_part ) {
- croak qq{ERROR: Unknown site_name: $zone_name};
- }
-
- # Building Header (SOA, NS an MX fields)
- my $zone_result = __make_zone_header( $zone_name, $site_name, $zone_ref );
-
- ### Building Networks part
- push @{$zone_result},
- q{;;},
- q{;; Networks},
- q{;;============================================================================},
- q{};
-
- my $network_order_ref
- = $global_config->{'ZONE'}->{'BY_NAME'}->{$zone_name}
- ->{'__network_order'}->{$site_name};
- foreach my $network ( @{$network_order_ref} ) {
- my $head = qq{; $network};
- if ( $zone_part->{$network}->{'comment'} ) {
- $head .= ": $zone_part->{$network}->{'comment'}";
- }
-
- push @{$zone_result},
- $head,
- q{;----------------------------------------------------------------------------};
-
- foreach my $spec ( 'network', 'netmask', 'broadcast', 'gateway' ) {
- my $value = $zone_part->{$network}->{$spec};
- next unless defined $value;
- push @{$zone_result},
- sprintf( q{%-29s IN %s},
- qq{$spec.$network}, $zone_part->{$network}->{$spec} );
- }
-
- push @{$zone_result}, q{};
- }
-
- ### Servers
- push @{$zone_result},
- q{},
- q{},
- q{;;},
- q{;; Servers},
- q{;;============================================================================},
- q{};
-
- my $hostclass_order_ref
- = $global_config->{'ZONE'}->{'BY_NAME'}->{$zone_name}
- ->{'__hostclass_order'}->{$site_name};
- foreach my $server ( @{$hostclass_order_ref} ) {
- my $head = qq{; $server};
-
- if ( $zone_part->{$server}->{'comment'} ) {
- $head .= ": $zone_part->{$server}->{'comment'}";
- }
-
- push @{$zone_result},
- $head,
- q{;----------------------------------------------------------------------------};
-
- foreach my $field ( sort keys %{ $zone_part->{$server} } ) {
- next if $field eq 'comment';
-
- if ( ref $zone_part->{$server}->{$field} eq 'ARRAY' ) {
- foreach my $elt ( @{ $zone_part->{$server}->{$field} } ) {
- push @{$zone_result},
- sprintf( q{%-29s IN %s}, $field, $elt );
- }
- }
- else {
- push @{$zone_result},
- sprintf( q{%-29s IN %s},
- $field, $zone_part->{$server}->{$field} );
- }
- }
-
- push @{$zone_result}, q{};
- }
-
- return $zone_result;
+ return 1;
}
=head2 make_resolv_conf_file( $hostname, $global_config, $site_name, $filename );
@@ -310,70 +214,13 @@
=cut
sub make_resolv_conf_file {
- my ( $hostname, $global_config, $site_name, $filename ) = @_;
+ my ($arguments_ref) = @_;
- if ( not $hostname ) {
- croak q{ERROR: Invalid empty $hostname};
- }
- if ( ref $hostname ) {
- croak q{ERROR: Invalid non-scalar $hostname};
+ unless ( ref $arguments_ref eq 'HASH' ) {
+ croak q{ERROR: Invalid $arguments_ref};
}
- if ( not $global_config ) {
- croak q{ERROR: Invalid empty $global_config};
- }
- if ( ref $global_config ne 'HASH' ) {
- croak q{ERROR: Invalid non-hashref $global_config};
- }
-
- # This is not a complete check but it will catch obvious errors,
- # like $global_config referencing a non-config hash
- if ( not exists $global_config->{'ZONE'} ) {
- croak q{ERROR: Invalid $global_config hashref: no 'ZONE' key found};
- }
-
- if ( not $site_name ) {
- croak q{ERROR: Invalid empty $site_name};
- }
- if ( ref $site_name ) {
- croak q{ERROR: Invalid non-scalar $site_name};
- }
-
- if ( not $filename ) {
- croak q{ERROR: Invalid empty $filename};
- }
- if ( ref $filename ) {
- croak q{ERROR: Invalid non-scalar $filename};
- }
-
- my $host_props = get_host_config( $hostname, $global_config, $site_name );
- my $domain = get_zone_from_hostname( $hostname, $global_config, $site_name );
-
- my @dns = split qr{ \s* [,] \s* }xms, $host_props->{'dns'}->{'resolver'};
-
- my $out_fh = IO::File->new( $filename, q{>} );
- unless ($out_fh) {
- croak qq{ERROR: open $filename: $OS_ERROR};
- }
-
- my @lines = (
- q{###############################################},
- q{# This file was auto-genrated by mk_resolvconf},
- q{},
- qq{search $domain},
- q{},
- );
-
- foreach my $ip_type ( qw( ipv4 ipv6 ) ) {
- foreach my $dns (@dns) {
- my $resolved = Resolv( q{cnf}, $ip_type, $dns, $global_config, $site_name );
- foreach my $ip ( @{$resolved} ) {
- push @lines, qq{nameserver $ip};
- }
- }
- }
-
- __write_array_to_filehandle( $out_fh, $filename, \@lines, qq{\n} );
+ __make_file( { file_type => q{resolv.conf}, %{ $arguments_ref } } );
return 1;
}
@@ -547,50 +394,45 @@
return [ @{$dhcp_headers}, @dhcp_subnets, @dhcp_hosts ];
}
-sub Mk_sourceslist {
- my ($hostname, $site_name, $dst, $sections, $template, $backports,
- $global_config, $pf_config
- )
- = @_;
+=head2 make_sources_list_file($arguments_ref)
- my $host_ref = get_host_config( $hostname, $global_config, $site_name );
- my $mode = $host_ref->{'deployment'}->{'mode'};
+This function creates the I<sources.list> file. It takes the following named
+arguments in I<%{$arguments_ref}:
- $template ||= join q{/}, $pf_config->{'path'}->{'templates_dir'},
- $pf_config->{$mode}->{'sources_list'};
+=over
- my $tpl = Template::Tiny->new( TRIM => 1 );
- my $sources_template = __read_file_in_scalar($template);
- my $sources_subst = {
- 'mode' => $host_ref->{'deployment'}->{'mode'},
- 'distrib' => $host_ref->{'deployment'}->{'distrib'},
- 'default_sections' => $pf_config->{$mode}->{'default_sections'},
- 'custom_sections' => $sections
- };
- my $sources_content = q{};
- $tpl->process( \$sources_template, $sources_subst, \$sources_content );
+=item I<hostname> the host name
- if ($backports) {
- my $back_src = $mode eq 'debian' ? $mode . "-backports" : $mode;
- $sources_content .= <<"BACKPORTS_TEXT";
+=item I<site_name> the site name
-deb http://mirrors.private/$back_src $host_ref->{'deployment'}->{'distrib'}-backports $pf_config->{$mode}->{'default_sections'}
+=item I<sections> a whitespace-separated list of repository sections (ie:
+q{common} or q{common foo1 foo2})
-BACKPORTS_TEXT
+=item I<template> the filename of the sources.list template
+
+=item I<backports> whether to add an entry for backports (used as a boolean)
+
+=item I<global_config> a reference to the global configuration hash
+
+=item I<pf_config> a reference to the pf-tools configuration hash
+
+=back
+
+=cut
+
+sub make_sources_list_file {
+ my ($arguments_ref) = @_;
+
+ unless ( ref $arguments_ref eq 'HASH' ) {
+ croak q{ERROR: Invalid $arguments_ref};
}
- $sources_content .= qq{\n};
-
- my $dst_fh = IO::File->new( $dst, q{>} );
- unless ($dst_fh) {
- croak qq{ERROR: open $dst: $OS_ERROR};
- }
-
- __write_scalar_to_filehandle($dst_fh, $dst, $sources_content);
+ __make_file( { file_type => q{sources.list}, %{ $arguments_ref } } );
return 1;
}
+# FIXME convert to __make_file()
sub Change_kopt_for_hostname {
my ($hostname, $site_name, $grub_src, $dst, $grub_version, $global_config,
$pf_config
@@ -646,35 +488,35 @@
return 1;
}
-=head2 make_interfaces_file( $hostname, $global_config, $pf_config, $site_name, $filename );
+=head2 make_interfaces_file($arguments_ref)
-Writes the I<interfaces> configuration for I<$hostname> at I<$site_name> to
-I<$filename>. I<$global_config> is a reference to the global configuration
-hash. I<$pf_config> is a reference to the pf-tools configuration hash.
+This function writes the I<interfaces> configuration file. It takes the
+following named arguments in %{$arguments_ref}:
+
+=over
+
+=item I<hostname> the host name
+
+=item I<site_name> the site name
+
+=item I<global_config> a reference to the global configuration hash
+
+=item I<pf_config> a reference to the pf-tools configuration hash
+
+=item I<filename> the output file name
+
+=back
=cut
sub make_interfaces_file {
- my ( $hostname, $global_config, $pf_config, $site_name, $filename ) = @_;
+ my ($arguments_ref) = @_;
- # NOTE: all parameters (except $filename) are properly checked by
- # make_interfaces() => no need to check them twice
-
- if ( not $filename ) {
- croak q{ERROR: Invalid empty $filename};
- }
- if ( ref $hostname ) {
- croak q{ERROR: Invalid non-scalar $filename};
+ unless ( ref $arguments_ref eq 'HASH' ) {
+ croak q{ERROR: Invalid $arguments_ref};
}
- my $lines_ref = __build_interfaces( $hostname, $global_config, $pf_config, $site_name );
-
- my $out_fh = IO::File->new( $filename, q{>} );
- unless ($out_fh) {
- croak qq{ERROR: open $filename: $OS_ERROR};
- }
-
- __write_array_to_filehandle( $out_fh, $filename, $lines_ref, qq{\n} );
+ __make_file( { file_type => q{interfaces}, %{ $arguments_ref } } );
return 1;
}
@@ -1017,16 +859,21 @@
return $preseed_filename;
}
-=head2 __build_interfaces( FIXME)
+=head2 __build_interfaces($arguments_ref)
-FIXME
+Builds the content for the I<interfaces> configuration file for I<hostname> at
+I<site_name>. I<global_config> is a reference to the global configuration
+hash. I<pf_config> is a referenfe to the pf-tools configuration hash. This
+function takes named arguments in I<%{$arguments_ref}> and returns a reference
+to an array of lines.
=cut
-# FIXME more generic build_foo (using File::Tmp and __move_if_different, but also handling STDOUT)
+sub __build_interfaces {
+ my ($arguments_ref) = @_;
-sub __build_interfaces {
- my ( $hostname, $global_config, $pf_config, $site_name ) = @_;
+ my ( $hostname, $global_config, $pf_config, $site_name )
+ = @{$arguments_ref}{qw( hostname global_config pf_config site_name )};
if ( not $hostname ) {
croak q{ERROR: Invalid empty $hostname};
@@ -1068,85 +915,15 @@
croak q{ERROR: Invalid non-scalar $site_name};
}
- my $resolve = 0;
my $host_ref = get_host_config( $hostname, $global_config, $site_name );
+
my $interfaces = {};
my $routes = {};
-
foreach my $iface ( 'lo', sort keys %{ $host_ref->{'interfaces'} } ) {
push @{ $interfaces->{'__order'} }, $iface;
-
- my $if_part = $host_ref->{'interfaces'}->{$iface};
- my $if_method
- = $if_part->{'method'}
- ? $if_part->{'method'}
- : $iface eq 'lo' ? q{loopback}
- : q{static};
- push @{ $interfaces->{$iface} },
- qq{auto $iface},
- qq{iface $iface inet $if_method};
-
- if (( $if_part->{'method'} and $if_part->{'method'} eq 'dhcp' )
- or $iface eq 'lo'
- )
- {
- next;
- }
-
- foreach my $ip_type ( 'ipv4', 'ipv6' ) {
- next if not $pf_config->{'features'}->{$ip_type};
-
- my $ip = NetAddr::IP->new( $if_part->{$ip_type} );
- if ( $if_part->{'slaves'} ) {
- push @{ $interfaces->{$iface} },
- qq{\tslaves\t\t} . $if_part->{'slaves'};
- }
- push @{ $interfaces->{$iface} },
- qq{\taddress\t\t} . $ip->addr(),
- qq{\tnetmask\t\t} . $ip->mask(),
- qq{\tnetwork\t\t} . $ip->network()->addr(),
- qq{\tbroadcast\t} . $ip->broadcast()->addr();
-
- # Routes
- my $suffix = get_suffix_from_ip_type( $ip_type );
- foreach my $route ( @{ $if_part->{ '@route' . $suffix } } ) {
- if ( $route =~ m{ \A (\S+) \s* (?: via (?: \S+ ) )? \z }xms )
- {
- my $destination = $1;
- push @{ $routes->{$destination} }, qq{$iface $route};
- }
- }
-
- # 802.1Q VLAN ID
- if ( $iface =~ m{ \A ([^.]+) [.] \d+ \z }xms ) {
- my $raw_device = $1;
- push @{ $interfaces->{$iface} },
- qq{\tvlan_raw_device\t$raw_device};
-
- # Set MTU to 1496 unless told otherwise
- if ($if_part->{'iface_opt'}
- and $if_part->{'iface_opt'} !~ m{ mtu }xms
- )
- {
- $if_part->{'iface_opt'} .= q{, mtu 1496};
- }
- else {
- $if_part->{'iface_opt'} = q{mtu 1496};
- }
- }
-
- # Options
- if ( $if_part->{'iface_opt'} ) {
- foreach my $option (
- split qr{ \s* [,] \s* }xms,
- $if_part->{'iface_opt'}
- )
- {
- push @{ $interfaces->{$iface} },
- qq{\tup\t\t/sbin/ip link set $iface $option};
- }
- }
- }
+ $interfaces->{$iface}
+ = __build_interface_lines_ref( $iface, $routes, $host_ref,
+ $pf_config );
}
DESTINATION:
@@ -1163,21 +940,26 @@
push @{ $interfaces->{$if} },
qq{\tup\t\t/sbin/ip route add $dst scope global via $gw dev $if};
}
+
next DESTINATION;
}
- # Only one route
+ # Only one route...
my ($entry) = @{ $routes->{$dest} };
my ( $if, $dst, $via, $gw ) = split qr{ \s+ }xms, $entry;
+
+ # ... default route
if ( $dst eq 'default' ) {
unless ( defined $gw ) {
croak
qq{ERROR: host $hostname: default route needs a gateway};
}
push @{ $interfaces->{$if} }, qq{\tgateway\t\t$gw};
+
next DESTINATION;
}
+ # ... device route
push @{ $interfaces->{$if} },
qq{\tup\t\t/sbin/ip route add $entry dev $if};
}
@@ -1194,6 +976,415 @@
}
return \@lines;
+}
+
+=head2 __build_interface_lines_ref( $iface, $routes, $host_ref, $pf_config )
+
+Builds a list of configuration lines for an interface and returns a reference
+to it. Also, fill %{$routes}.
+
+=cut
+
+sub __build_interface_lines_ref {
+ my ($iface, $routes, $host_ref, $pf_config) = @_;
+
+ my @iface_lines;
+
+ my $if_part = $host_ref->{'interfaces'}->{$iface};
+ my $if_method
+ = $if_part->{'method'} ? $if_part->{'method'}
+ : $iface eq 'lo' ? q{loopback}
+ : q{static};
+ push @iface_lines,
+ qq{auto $iface},
+ qq{iface $iface inet $if_method};
+
+ if ( ( $if_part->{'method'} and $if_part->{'method'} eq 'dhcp' )
+ or $iface eq 'lo' )
+ {
+ return \@iface_lines;
+ }
+
+ if ( $if_part->{'slaves'} ) {
+ push @iface_lines, qq{\tslaves\t\t} . $if_part->{'slaves'};
+ }
+
+ foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+ next if not $pf_config->{'features'}->{$ip_type};
+
+ my $ip = NetAddr::IP->new( $if_part->{$ip_type} );
+ push @iface_lines,
+ qq{\taddress\t\t} . $ip->addr(),
+ qq{\tnetmask\t\t} . $ip->mask(),
+ qq{\tnetwork\t\t} . $ip->network()->addr(),
+ qq{\tbroadcast\t} . $ip->broadcast()->addr();
+
+ # Routes
+ # FIXME add tests cases for non-default routes
+ my $suffix = get_suffix_from_ip_type($ip_type);
+ foreach my $route ( @{ $if_part->{ '@route' . $suffix } } ) {
+ if ( $route =~ m{ \A (\S+) \s* (?: via (?: \S+ ) )? \z }xms ) {
+ my $destination = $1;
+ push @{ $routes->{$destination} }, qq{$iface $route};
+ }
+ }
+
+ # 802.1Q VLAN ID
+ if ( $iface =~ m{ \A ([^.]+) [.] \d+ \z }xms ) {
+ my $raw_device = $1;
+ push @iface_lines, qq{\tvlan_raw_device\t$raw_device};
+
+ # Set MTU to 1496 unless told otherwise
+ if ( $if_part->{'iface_opt'}
+ and $if_part->{'iface_opt'} !~ m{ mtu }xms )
+ {
+ $if_part->{'iface_opt'} .= q{, mtu 1496};
+ }
+ else {
+ $if_part->{'iface_opt'} = q{mtu 1496};
+ }
+ }
+
+ # Options
+ if ( $if_part->{'iface_opt'} ) {
+ foreach my $option ( split qr{ \s* [,] \s* }xms,
+ $if_part->{'iface_opt'} )
+ {
+ push @iface_lines,
+ qq{\tup\t\t/sbin/ip link set $iface $option};
+ }
+ }
+ }
+
+ return \@iface_lines;
+}
+
+=head2 __build_resolv_conf($arguments_ref)
+
+Writes the I<resolv.conf> configuration for I<hostname> at I<site_name>.
+I<global_config> is a reference to the global configuration hash. This
+function takes named arguments in I<%{$arguments_ref}> and returns a reference
+to an array of lines.
+
+=cut
+
+sub __build_resolv_conf {
+ my ($arguments_ref) = @_;
+
+ my ( $hostname, $global_config, $site_name )
+ = @{$arguments_ref}{qw( hostname global_config site_name )};
+
+ if ( not $hostname ) {
+ croak q{ERROR: Invalid empty $hostname};
+ }
+ if ( ref $hostname ) {
+ croak q{ERROR: Invalid non-scalar $hostname};
+ }
+
+ if ( not $global_config ) {
+ croak q{ERROR: Invalid empty $global_config};
+ }
+ if ( ref $global_config ne 'HASH' ) {
+ croak q{ERROR: Invalid non-hashref $global_config};
+ }
+
+ # This is not a complete check but it will catch obvious errors,
+ # like $global_config referencing a non-config hash
+ if ( not exists $global_config->{'ZONE'} ) {
+ croak q{ERROR: Invalid $global_config hashref: no 'ZONE' key found};
+ }
+
+ if ( not $site_name ) {
+ croak q{ERROR: Invalid empty $site_name};
+ }
+ if ( ref $site_name ) {
+ croak q{ERROR: Invalid non-scalar $site_name};
+ }
+
+ my $host_props = get_host_config( $hostname, $global_config, $site_name );
+ my $domain = get_zone_from_hostname( $hostname, $global_config, $site_name );
+
+ my @dns = split qr{ \s* [,] \s* }xms, $host_props->{'dns'}->{'resolver'};
+
+ my @lines = (
+ q{#},
+ q{# This file was auto-generated by mk_resolvconf -- DO NOT EDIT!},
+ q{#},
+ q{},
+ qq{search $domain},
+ q{},
+ );
+
+ foreach my $ip_type ( qw( ipv4 ipv6 ) ) {
+ foreach my $dns (@dns) {
+ my $resolved = Resolv( q{cnf}, $ip_type, $dns, $global_config, $site_name );
+ foreach my $ip ( @{$resolved} ) {
+ push @lines, qq{nameserver $ip};
+ }
+ }
+ }
+
+ push @lines, q{};
+
+ return \@lines;
+}
+
+=head2 __build_zone($arguments_ref)
+
+This function creates the zone file content for the I<zone_name> zone on site
+I<site_name>. I<global_config> references the global configuration hash. It
+takes named arguments in I<%{$arguments_ref}> and returns a reference to the
+array of lines.
+
+=cut
+
+sub __build_zone {
+ my ($arguments_ref) = @_;
+
+ my ( $zone_name, $site_name, $global_config )
+ = @{$arguments_ref}{qw( zone_name site_name global_config )};
+
+ if ( not $zone_name ) {
+ croak q{ERROR: Invalid empty $zone_name};
+ }
+ if ( ref $zone_name ) {
+ croak q{ERROR: Invalid non-scalar $zone_name};
+ }
+
+ if ( not $site_name ) {
+ croak q{ERROR: Invalid empty $site_name};
+ }
+ if ( ref $site_name ) {
+ croak q{ERROR: Invalid non-scalar $site_name};
+ }
+
+ if ( not $global_config ) {
+ croak q{ERROR: Invalid empty $global_config};
+ }
+ if ( ref $global_config ne 'HASH' ) {
+ croak q{ERROR: Invalid non-hashref $global_config};
+ }
+
+ # This is not a complete check but it will catch obvious errors,
+ # like $global_config referencing a non-config hash
+ if ( not exists $global_config->{'ZONE'} ) {
+ croak q{ERROR: Invalid $global_config hashref: no 'ZONE' key found};
+ }
+
+ my $zone_ref = $global_config->{'ZONE'}->{'BY_NAME'}->{$zone_name};
+ if ( not $zone_ref ) {
+ croak qq{ERROR: Unknown zone_name: $zone_name};
+ }
+
+ my $zone_part = $zone_ref->{'BY_SITE'}->{$site_name};
+ if ( not $zone_part ) {
+ croak qq{ERROR: Unknown site_name: $zone_name};
+ }
+
+ # Building Header (SOA, NS an MX fields)
+ my $header_lines_ref
+ = __make_zone_header( $zone_name, $site_name, $zone_ref );
+ my @lines = @{$header_lines_ref};
+
+ ### Building Networks part
+ push @lines,
+ q{;;},
+ q{;; Networks},
+ q{;;============================================================================},
+ q{};
+
+ my $network_order_ref
+ = $global_config->{'ZONE'}->{'BY_NAME'}->{$zone_name}
+ ->{'__network_order'}->{$site_name};
+ foreach my $network ( @{$network_order_ref} ) {
+ my $head = qq{; $network};
+ if ( $zone_part->{$network}->{'comment'} ) {
+ $head .= ": $zone_part->{$network}->{'comment'}";
+ }
+
+ push @lines,
+ $head,
+ q{;----------------------------------------------------------------------------};
+
+ foreach my $spec ( 'network', 'netmask', 'broadcast', 'gateway' ) {
+ my $value = $zone_part->{$network}->{$spec};
+ next unless defined $value;
+ push @lines,
+ sprintf( q{%-29s IN %s},
+ qq{$spec.$network}, $zone_part->{$network}->{$spec} );
+ }
+
+ push @lines, q{};
+ }
+
+ ### Servers
+ push @lines,
+ q{},
+ q{},
+ q{;;},
+ q{;; Servers},
+ q{;;============================================================================},
+ q{};
+
+ my $hostclass_order_ref
+ = $global_config->{'ZONE'}->{'BY_NAME'}->{$zone_name}
+ ->{'__hostclass_order'}->{$site_name};
+ foreach my $server ( @{$hostclass_order_ref} ) {
+ my $head = qq{; $server};
+
+ if ( $zone_part->{$server}->{'comment'} ) {
+ $head .= ": $zone_part->{$server}->{'comment'}";
+ }
+
+ push @lines,
+ $head,
+ q{;----------------------------------------------------------------------------};
+
+ foreach my $field ( sort keys %{ $zone_part->{$server} } ) {
+ next if $field eq 'comment';
+
+ if ( ref $zone_part->{$server}->{$field} eq 'ARRAY' ) {
+ foreach my $elt ( @{ $zone_part->{$server}->{$field} } ) {
+ push @lines,
+ sprintf( q{%-29s IN %s}, $field, $elt );
+ }
+ }
+ else {
+ push @lines,
+ sprintf( q{%-29s IN %s},
+ $field, $zone_part->{$server}->{$field} );
+ }
+ }
+
+ push @lines, q{};
+ }
+
+ return \@lines;
+}
+
+=head2 __build_sources_list($arguments_ref)
+
+This function creates the I<sources.list> file content and returns a reference
+to the array of lines. It takes the following named arguments in
+I<%{$arguments_ref}:
+
+=over
+
+=item I<hostname> the host name
+
+=item I<site_name> the site name
+
+=item I<sections_ref> a reference to a list of repository sections
+
+=item I<template> the filename of the sources.list template
+
+=item I<backports> whether to add an entry for backports (used as a boolean)
+
+=item I<global_config> a reference to the global configuration hash
+
+=item I<pf_config> a reference to the pf-tools configuration hash
+
+=back
+
+=cut
+
+sub __build_sources_list {
+ my ($arguments_ref) = @_;
+
+ my ($hostname, $site_name, $sections_ref, $template, $backports,
+ $global_config, $pf_config
+ )
+ = @{$arguments_ref}{
+ qw(
+ hostname site_name sections_ref template backports
+ global_config pf_config
+ )
+ };
+
+ # NOTE: hostname and global_config are properly checked in
+ # get_host_config(), so there's no need to check them here.
+
+ if ( not $template ) {
+ croak q{ERROR: Invalid empty $template};
+ }
+ if ( ref $template ) {
+ croak q{ERROR: Invalid non-scalar $template};
+ }
+
+ # FIXME is site_name optional or not?
+
+ if ( not $sections_ref ) {
+ croak q{ERROR: Invalid empty $sections_ref};
+ }
+ if ( ref $sections_ref ne 'ARRAY' ) {
+ croak q{ERROR: Invalid non-array-ref $sections_ref};
+ }
+ if ( not @{$sections_ref} ) {
+ croak q{ERROR: Invalid empty-array-ref $sections_ref};
+ }
+
+ my @sections = ();
+ foreach my $section ( @{$sections_ref} ) {
+
+ # Remove leading and trailink whitespace
+ $section =~ s{ \A \s* (\S*) \s* \z }{$1}xms;
+ if ( not $section ) {
+ croak
+ q{ERROR: Invalid empty or blank section in array-ref $sections_ref};
+ }
+ push @sections, $section;
+ }
+ my $sections = join q{ }, @sections;
+
+ # $backports is optional
+ if ( ref $backports ) {
+ croak q{ERROR: Invalid non-scalar $backports};
+ }
+
+ if ( ref $global_config ne 'HASH' ) {
+ croak q{ERROR: Invalid non-hashref $global_config};
+ }
+
+ # This is not a complete check but it will catch obvious errors,
+ # like $global_config referencing a non-config hash
+ if ( not exists $global_config->{'ZONE'} ) {
+ croak q{ERROR: Invalid $global_config hashref: no 'ZONE' key found};
+ }
+
+ my $host_ref = get_host_config( $hostname, $global_config, $site_name );
+ my $deployment_mode = $host_ref->{'deployment'}->{'mode'};
+
+ $template ||= join q{/}, $pf_config->{'path'}->{'templates_dir'},
+ $pf_config->{$deployment_mode}->{'sources_list'};
+
+ my $tpl = Template::Tiny->new( TRIM => 1 );
+ my $sources_template = __read_file_in_scalar($template);
+ my $sources_subst = {
+ 'mode' => $deployment_mode,
+ 'distrib' => $host_ref->{'deployment'}->{'distrib'},
+ 'default_sections' =>
+ $pf_config->{$deployment_mode}->{'default_sections'},
+ 'custom_sections' => $sections,
+ };
+ my $sources_content = q{};
+ $tpl->process( \$sources_template, $sources_subst, \$sources_content );
+
+ # FIXME why not in the template?
+ if ($backports) {
+ my $dash_backports
+ = $deployment_mode eq q{debian} ? q{-backports} : q{};
+ my $back_src = $deployment_mode . $dash_backports;
+ $sources_content .= <<"BACKPORTS_TEXT";
+
+deb http://mirrors.private/$back_src $host_ref->{'deployment'}->{'distrib'}-backports $pf_config->{$deployment_mode}->{'default_sections'}
+
+BACKPORTS_TEXT
+ }
+
+ # This cannot be in the template because of the TRIM option
+ $sources_content .= qq{\n};
+
+ return [$sources_content];
}
=head2 __get_kpkg_from_kernel( $pxefilename, $deploymode )
@@ -1437,16 +1628,8 @@
sub __write_scalar_to_filehandle {
my ($fh, $filename, $scalar) = @_;
- # IO::File does not implement filename()
- #my $filename = $fh->filename();
-
- unless ( $fh->print($scalar) ) {
- croak qq{ERROR: write $filename: $OS_ERROR};
- }
-
- unless ( $fh->close() ) {
- croak qq{ERROR: close $filename: $OS_ERROR};
- }
+ # FIXME should be q{}, but wait for proper tests to really correct it
+ __write_array_to_filehandle( $fh, $filename, [$scalar], qq{\n} );
return 1;
}
@@ -1479,5 +1662,84 @@
}
}
+=head2 __make_file($arguments_ref)
+
+This function creates a specific file. It takes the
+following named arguments in %{$arguments_ref}:
+
+=over
+
+=item I<file_type> the type of file to create. The allowed types are
+I<interfaces>, I<resolv.conf> and I<zone>.
+
+=item I<filename> the output file name
+
+All other named arguments are passed to the specialized function to which the
+content creation for this I<file_type> is delegated.
+
+The content is written to a temporary file and only moved to I<filename> if it
+is different from the original content. STDOUT is also supported (if
+I<filename> is '-').
+
+=cut
+
+sub __make_file {
+ my ($arguments_ref) = @_;
+
+ my %build_content_for = (
+ interfaces => \&__build_interfaces,
+ q{resolv.conf} => \&__build_resolv_conf,
+ q{sources.list} => \&__build_sources_list,
+ zone => \&__build_zone,
+ );
+
+ # NOTE: all other parameters are properly checked by
+ # __build_FOO() => no need to check them here
+
+ my ( $file_type, $filename )
+ = @{$arguments_ref}{qw( file_type filename )};
+
+ if ( not $file_type ) {
+ croak q{ERROR: Invalid empty $file_type};
+ }
+ if ( ref $file_type ) {
+ croak q{ERROR: Invalid non-scalar $file_type};
+ }
+ if ( not exists $build_content_for{$file_type} ) {
+ croak qq{ERROR: Unknown file_type: $file_type};
+ }
+
+ if ( not $filename ) {
+ croak q{ERROR: Invalid empty $filename};
+ }
+ if ( ref $filename ) {
+ croak q{ERROR: Invalid non-scalar $filename};
+ }
+
+ my $lines_ref = $build_content_for{$file_type}->($arguments_ref);
+
+ # Either STDOUT or a tempfile...
+ my ($out_fh, $out_fn);
+ if ( $filename eq q{-} ) {
+ $out_fh = IO::File->new();
+ unless ( $out_fh->fdopen( fileno(STDOUT), q{>} ) ) {
+ croak qq{ERROR: fdopen STDOUT: $OS_ERROR};
+ }
+ $out_fn = $filename;
+ }
+ else {
+ $out_fh = File::Temp->new( unlink => 0 ); # will croak() on error
+ $out_fn = $out_fh->filename();
+ }
+
+ __write_array_to_filehandle( $out_fh, $out_fn, $lines_ref, qq{\n} );
+
+ if ( $filename ne q{-} ) {
+ __move_if_different( $out_fn, $filename );
+ }
+
+ return 1;
+}
+
1; # Magic true value required at end of module
diff -r 75b485e19166 -r dd4873cacd2e sbin/mk_interfaces
--- a/sbin/mk_interfaces Thu Nov 18 16:55:31 2010 +0100
+++ b/sbin/mk_interfaces Mon Nov 22 11:01:19 2010 +0100
@@ -30,7 +30,7 @@
use Sys::Hostname;
use PFTools::Structqueries;
-use PFTools::Utils qw( make_interfaces_file );
+use PFTools::Utils qw( Init_TOOLS make_interfaces_file );
#################################
# VARS
@@ -95,11 +95,13 @@
}
make_interfaces_file(
- $options->{'host'},
- $GLOBAL_STRUCT,
- $PF_CONFIG,
- $options->{'site'},
- $options->{'output'},
+ {
+ hostname => $options->{'host'},
+ global_config => $GLOBAL_STRUCT,
+ pf_config => $PF_CONFIG,
+ site_name => $options->{'site'},
+ filename => $options->{'output'},
+ }
);
exit 0;
diff -r 75b485e19166 -r dd4873cacd2e sbin/mk_resolvconf
--- a/sbin/mk_resolvconf Thu Nov 18 16:55:31 2010 +0100
+++ b/sbin/mk_resolvconf Mon Nov 22 11:01:19 2010 +0100
@@ -28,7 +28,7 @@
use Sys::Hostname;
use PFTools::Structqueries;
-use PFTools::Utils qw( make_resolv_conf_file );
+use PFTools::Utils qw( Init_Tools make_resolv_conf_file );
#################################
# VARS
@@ -92,15 +92,13 @@
|| get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
}
-unless(
- make_resolv_conf_file(
- $options->{'host'},
- $GLOBAL_STRUCT,
- $options->{'site'},
- $options->{'output'}
- )
-) {
- die "An error occured during build of file $options->{'output'}";
-}
+make_resolv_conf_file(
+ {
+ hostname => $options->{'host'},
+ global_config => $GLOBAL_STRUCT,
+ site_name => $options->{'site'},
+ filename => $options->{'output'},
+ }
+);
exit 0;
diff -r 75b485e19166 -r dd4873cacd2e sbin/mk_sitezone
--- a/sbin/mk_sitezone Thu Nov 18 16:55:31 2010 +0100
+++ b/sbin/mk_sitezone Mon Nov 22 11:01:19 2010 +0100
@@ -26,7 +26,7 @@
use Getopt::Long qw( :config ignore_case_always bundling );
use IO::File;
-use PFTools::Utils qw( make_zone_for_site );
+use PFTools::Utils qw( Init_TOOLS make_zone_file );
#################################
# VARS
@@ -91,17 +91,15 @@
die "Site $options->{'site'} is not defined into global configuration";
}
-my $zone = make_zone_for_site(
- $GLOBAL_STRUCT->{'SITE'}->{'BY_NAME'}->{$options->{'site'}}->{'zone'},
- $options->{'site'},
- $GLOBAL_STRUCT
+my $zone_name
+ = $GLOBAL_STRUCT->{'SITE'}->{'BY_NAME'}->{ $options->{'site'} }->{'zone'};
+make_zone_file(
+ {
+ zone_name => $zone_name,
+ site_name => $options->{'site'},
+ filename => $options->{'output'},
+ global_config => $GLOBAL_STRUCT,
+ }
);
-my $output_fh = IO::File->new ( '>' . $options->{'output'} )
- or die "Unable to open destination $options->{'output'} : $OS_ERROR";
-$output_fh->print( join "\n", @{$zone} )
- or die "Unable to write on destination $options->{'output'} : $OS_ERROR";
-$output_fh->close()
- or die "Unable to close destination$options->{'output'} : $OS_ERROR";
-
exit 0;
diff -r 75b485e19166 -r dd4873cacd2e sbin/mk_sourceslist
--- a/sbin/mk_sourceslist Thu Nov 18 16:55:31 2010 +0100
+++ b/sbin/mk_sourceslist Mon Nov 22 11:01:19 2010 +0100
@@ -27,7 +27,7 @@
use Sys::Hostname;
use PFTools::Structqueries;
-use PFTools::Utils;
+use PFTools::Utils qw( Init_TOOLS make_sources_list_file );
############################################
# Vars
@@ -37,7 +37,7 @@
'host|h=s',
'site|s=s',
'tpl|t=s',
- 'a|add=s',
+ 'add|a=s@',
'config|c=s',
'store=s',
'backport|b',
@@ -47,12 +47,11 @@
my $options = {
'help' => 0,
'host' => hostname,
- 'add' => '',
+ 'add' => [],
'backport' => 0,
'output' => '-',
};
-my $SECTIONS = "common";
my $PF_CONFIG = {};
my $GLOBAL_STRUCT = {};
@@ -67,29 +66,32 @@
Synopsis : $program [--help] [-h|--host hostname <hostname>] [-s|--site <site_name>]
[-o|--output <sources.list dest>] [ -t|--tpl <sources.list template>] [-b|--backports]
- [-a|--add <sections to add>] [-c|--config <pf_tools_file>] [--store <filename>]
+ [-a|--add <section to add>] [-c|--config <pf_tools_file>] [--store <filename>]
This tool permits to build the sources.list file according to distribution defined
in private-network file from PF-Tools configuration. It can also add some sections
to custom repository
- --help Displays this message and exits
+ --help Display this message and exit
- -h | --host Defines here the hostname you want to build the sources.list
+ -h | --host Define here the hostname you want to build the sources.list
- -s | --site Defines here the site on which the hostname is defined
+ -s | --site Define here the site on which the hostname is defined
- -o | --output Defines here where to build the sources.list file
+ -o | --output Define here where to build the sources.list file
- -t | --tpl Defines here where to find the sources.list template. If not defined
+ -t | --tpl Define here where to find the sources.list template. If not defined
the program will use template path issued from pf-tools.conf file
- -a | --add Defines here the list(comma-separated) of sections you want to add into custom repository
+ -a | --add Define here the section you want to add to the custom repository (in
+ addtion to the "common" section). For multiple values, specify multiple
+ times (-a section1 -a section2) or use a comma-separated list
+ (-a section1,section2).
- -b | --backports Adds the backport repository from offical source according to hostname's
- deployment mode
+ -b | --backports Add the backport repository from offical sources according to
+ hostname's deployment mode
- -c | --config Define here where is the pf-tools.conf file
+ -c | --config Define here where is the pf-tools.conf file
--store Define here where the storable file which contains the global structure is
@@ -131,22 +133,21 @@
|| get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
}
-$options->{'add'} =~ s{,}{ }g;
-$SECTIONS .= " " . $options->{'add'};
-$SECTIONS =~ s{\A \s*}{}xms; # Removing trailing space(s)
-unless(
- Mk_sourceslist(
- $options->{'host'},
- $options->{'site'},
- $options->{'output'},
- $SECTIONS,
- $options->{'tpl'},
- $options->{'backport'},
- $GLOBAL_STRUCT,
- $PF_CONFIG
- )
-) {
- die q{ERROR: An error occured during sources.list generation};
-}
+my @sections = (q{common});
+push @sections, split qr{ \s* [,] \s* }xms, join q{,}, @{ $options->{'add'} };
+
+make_sources_list_file(
+ {
+ hostname => $options->{'host'},
+ site_name => $options->{'site'},
+ filename => $options->{'output'},
+ sections => \@sections,
+ template => $options->{'tpl'},
+ backports => $options->{'backport'},
+ global_config => $GLOBAL_STRUCT,
+ pf_config => $PF_CONFIG,
+ }
+);
exit 0;
+
diff -r 75b485e19166 -r dd4873cacd2e t/20.zone.t
--- a/t/20.zone.t Thu Nov 18 16:55:31 2010 +0100
+++ b/t/20.zone.t Mon Nov 22 11:01:19 2010 +0100
@@ -92,47 +92,99 @@
########################################################################
-note('Testing PFTools::Utils::make_zone_for_site');
-can_ok( 'PFTools::Utils', qw( make_zone_for_site ) );
+note('Testing PFTools::Utils::__build_zone');
+can_ok( 'PFTools::Utils', qw( __build_zone ) );
-throws_ok { make_zone_for_site(); }
+throws_ok { PFTools::Utils::__build_zone(); }
qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] zone_name }xms
=> q{Dies if empty $zone_name};
-throws_ok { make_zone_for_site( {} ); }
+throws_ok { PFTools::Utils::__build_zone( { zone_name => {} } ); }
qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] zone_name }xms
=> q{Dies if non-scalar $zone_name};
-throws_ok { make_zone_for_site( q{name} ); }
+throws_ok { PFTools::Utils::__build_zone( { zone_name => q{name} } ); }
qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] site_name }xms
=> q{Dies if empty $site_name};
-throws_ok { make_zone_for_site( q{name}, {} ); }
+throws_ok {
+ PFTools::Utils::__build_zone(
+ {
+ zone_name => q{name},
+ site_name => {},
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] site_name }xms
=> q{Dies if non-scalar $site_name};
-throws_ok { make_zone_for_site( q{name}, q{site} ); }
+throws_ok {
+ PFTools::Utils::__build_zone(
+ {
+ zone_name => q{name},
+ site_name => q{site},
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] global_config }xms
=> q{Dies if empty $global_config};
-throws_ok { make_zone_for_site( q{name}, q{site}, q{ref} ); }
+throws_ok {
+ PFTools::Utils::__build_zone(
+ {
+ zone_name => q{name},
+ site_name => q{site},
+ global_config => q{ref},
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] global_config }xms
=> q{Dies if non-hashref $global_config};
-throws_ok { make_zone_for_site( q{name}, q{site}, {} ); }
+throws_ok {
+ PFTools::Utils::__build_zone(
+ {
+ zone_name => q{name},
+ site_name => q{site},
+ global_config => {},
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] [\$] global_config [ ] hashref:
[ ] no [ ] 'ZONE' [ ] key [ ] found }xms
=> q{Dies if non-config hashref $global_config};
-throws_ok { make_zone_for_site( q{name}, q{site}, $global_config ); }
+throws_ok {
+ PFTools::Utils::__build_zone(
+ {
+ zone_name => q{name},
+ site_name => q{site},
+ global_config => $global_config,
+ }
+ );
+}
qr{ \A ERROR: [ ] Unknown [ ] zone_name: [ ] }xms
=> q{Dies if unknown zone_name};
-throws_ok { make_zone_for_site( q{private}, q{site}, $global_config ); }
+throws_ok {
+ PFTools::Utils::__build_zone(
+ {
+ zone_name => q{private},
+ site_name => q{site},
+ global_config => $global_config
+ }
+ );
+}
qr{ \A ERROR: [ ] Unknown [ ] site_name: [ ] }xms
=> q{Dies if unknown site_name};
-$result = make_zone_for_site( q{private}, q{cbv4-pfds}, $global_config );
+$result = PFTools::Utils::__build_zone(
+ {
+ zone_name => q{private},
+ site_name => q{cbv4-pfds},
+ global_config => $global_config,
+ }
+);
$expected_result = [
';;',
';; BIND configuration file for zone: private',
@@ -247,75 +299,155 @@
########################################################################
+note('Testing PFTools::Utils::make_zone_file');
+can_ok( 'PFTools::Utils', qw( make_zone_file ) );
+
+throws_ok { make_zone_file(); }
+qr{ \A ERROR: [ ] Invalid [ ] [\$] arguments_ref }xms
+ => q{Dies if no args};
+
+my $test_output_file = q{test.zone};
+$result = make_zone_file(
+ {
+ zone_name => q{private},
+ site_name => q{cbv4-pfds},
+ filename => $test_output_file,
+ global_config => $global_config,
+ }
+);
+ok $result => q{Returns true on success};
+
+$result = PFTools::Utils::__read_file_in_array( $test_output_file, 1 );
+
+is_deeply $result, $expected_result
+ => q{Returns the expected result for host cbv4-rdeploy01 site cbv4'}
+ or note explain $result;
+
+ok unlink($test_output_file)
+ => q{Removed the test-generated zone file};
+
+
+########################################################################
note('Testing PFTools::Utils::make_resolv_conf_file');
can_ok( 'PFTools::Utils', qw( make_resolv_conf_file ) );
throws_ok { make_resolv_conf_file(); }
+qr{ \A ERROR: [ ] Invalid [ ] [\$] arguments_ref }xms
+ => q{Dies if no args};
+
+throws_ok { make_resolv_conf_file( {} ); }
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] filename }xms
+ => q{Dies if empty $filename};
+
+throws_ok { make_resolv_conf_file( { filename => {} } ); }
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] filename }xms
+ => q{Dies if non-scalar $filename};
+
+throws_ok { make_resolv_conf_file( { filename => q{filename} } ); }
qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] hostname }xms
=> q{Dies if empty $hostname};
-throws_ok { make_resolv_conf_file( {} ); }
+throws_ok {
+ make_resolv_conf_file(
+ {
+ filename => q{filename},
+ hostname => {},
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] hostname }xms
=> q{Dies if non-scalar $hostname};
-throws_ok { make_resolv_conf_file( q{hostname} ); }
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] global_config }xms
+throws_ok {
+ make_resolv_conf_file(
+ {
+ filename => q{filename},
+ hostname => q{name},
+ }
+ );
+}
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] global_config}xms
=> q{Dies if empty $global_config};
-throws_ok { make_resolv_conf_file( q{hostname}, q{global_config} ); }
-qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] global_config }xms
+throws_ok {
+ make_resolv_conf_file(
+ {
+ filename => q{filename},
+ hostname => q{name},
+ global_config => q{global_config},
+ }
+ );
+}
+qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] global_config [ ]}xms
=> q{Dies if non-hashref $global_config};
-throws_ok { make_resolv_conf_file( q{name}, {} ); }
+throws_ok {
+ make_resolv_conf_file(
+ {
+ filename => q{filename},
+ hostname => q{name},
+ global_config => {},
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] [\$] global_config [ ] hashref:
[ ] no [ ] 'ZONE' [ ] key [ ] found }xms
=> q{Dies if non-config hashref $global_config};
-throws_ok { make_resolv_conf_file( q{hostname}, $global_config ); }
+throws_ok {
+ make_resolv_conf_file(
+ {
+ filename => q{filename},
+ hostname => q{hostname},
+ global_config => $global_config,
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] site_name }xms
=> q{Dies if empty $site_name};
-throws_ok { make_resolv_conf_file( q{hostname}, $global_config, {} ); }
+throws_ok {
+ make_resolv_conf_file(
+ {
+ filename => q{filename},
+ hostname => q{name},
+ global_config => $global_config,
+ site_name => {},
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] site_name }xms
=> q{Dies if non-scalar $site_name};
-throws_ok { make_resolv_conf_file( q{hostname}, $global_config, q{site_name} ); }
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] filename }xms
- => q{Dies if empty $filename};
-
-throws_ok { make_resolv_conf_file( q{hostname}, $global_config, q{site_name}, {} ); }
-qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] filename }xms
- => q{Dies if non-scalar $filename};
-
-throws_ok { make_resolv_conf_file( q{hostname}, $global_config, q{cbv4}, q{filename} ); }
-qr{ \A ERROR: [ ] Unknown [ ] hostname [ ] }xms
- => q{Dies if unknown $hostname};
-
-throws_ok { make_resolv_conf_file( q{cbv4-spawn00}, $global_config, q{cbv4}, q{filename} ); }
-qr{ \A ERROR: [ ] Unknown [ ] hostname [ ] }xms
- => q{Dies if unknown $hostname};
-
-my $test_resolv_conf_file = q{test.resolv.conf};
-$result = make_resolv_conf_file( q{cbv4-rdeploy01}, $global_config, q{cbv4}, $test_resolv_conf_file );
+$test_output_file = q{test.resolv.conf};
+$result = make_resolv_conf_file(
+ {
+ hostname => q{cbv4-rdeploy01},
+ global_config => $global_config,
+ site_name => q{cbv4},
+ filename => $test_output_file,
+ }
+);
ok $result => q{Returns true on success};
-$result = PFTools::Utils::__read_file_in_array( $test_resolv_conf_file, 1 );
+$result = PFTools::Utils::__read_file_in_array( $test_output_file, 1 );
$expected_result = [
- q{###############################################},
- q{# This file was auto-genrated by mk_resolvconf},
+ q{#},
+ q{# This file was auto-generated by mk_resolvconf -- DO NOT EDIT!},
+ q{#},
q{},
q{search private},
q{},
q{nameserver 10.1.167.0},
q{nameserver 10.1.167.1},
+ q{},
];
-
is_deeply $result, $expected_result
=> q{Returns the expected result for host cbv4-rdeploy01 site cbv4'}
or note explain $result;
-ok unlink($test_resolv_conf_file)
+ok unlink($test_output_file)
=> q{Removed the test-generated resolv.conf file};
@@ -327,81 +459,356 @@
qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] hostname }xms
=> q{Dies if empty $hostname};
-throws_ok { PFTools::Utils::__build_interfaces( {} ); }
+throws_ok { PFTools::Utils::__build_interfaces( { hostname => {} } ); }
qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] hostname }xms
=> q{Dies if non-scalar $hostname};
-throws_ok { PFTools::Utils::__build_interfaces( q{hostname} ); }
+throws_ok {
+ PFTools::Utils::__build_interfaces( { hostname => q{hostname} } );
+}
qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] global_config }xms
=> q{Dies if empty $global_config};
-throws_ok { PFTools::Utils::__build_interfaces( q{hostname}, q{global_config} ); }
+throws_ok {
+ PFTools::Utils::__build_interfaces(
+ {
+ hostname => q{hostname},
+ global_config => q{global_config},
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] global_config }xms
=> q{Dies if non-hashref $global_config};
-throws_ok { PFTools::Utils::__build_interfaces( q{name}, {} ); }
+throws_ok {
+ PFTools::Utils::__build_interfaces(
+ {
+ hostname => q{name},
+ global_config => {},
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] [\$] global_config [ ] hashref:
[ ] no [ ] 'ZONE' [ ] key [ ] found }xms
=> q{Dies if non-config hashref $global_config};
-throws_ok { PFTools::Utils::__build_interfaces( q{hostname}, $global_config ); }
+throws_ok {
+ PFTools::Utils::__build_interfaces(
+ {
+ hostname => q{hostname},
+ global_config => $global_config,
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] pf_config }xms
=> q{Dies if empty $pf_config};
-throws_ok { PFTools::Utils::__build_interfaces( q{hostname}, $global_config, q{pf_config} ); }
+throws_ok {
+ PFTools::Utils::__build_interfaces(
+ {
+ hostname => q{hostname},
+ global_config => $global_config,
+ pf_config => q{pf_config},
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] pf_config }xms
=> q{Dies if non-hashref $pf_config};
-throws_ok { PFTools::Utils::__build_interfaces( q{hostname}, $global_config, {} ); }
+throws_ok {
+ PFTools::Utils::__build_interfaces(
+ {
+ hostname => q{hostname},
+ global_config => $global_config,
+ pf_config => {},
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] [\$] pf_config [ ] hashref:
[ ] no [ ] 'vcs' [ ] key [ ] found }xms
=> q{Dies if non-config hashref $pf_config};
-throws_ok { PFTools::Utils::__build_interfaces( q{hostname}, $global_config, $pf_config ); }
+throws_ok {
+ PFTools::Utils::__build_interfaces(
+ {
+ hostname => q{hostname},
+ global_config => $global_config,
+ pf_config => $pf_config,
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] site_name }xms
=> q{Dies if empty $site_name};
-throws_ok { PFTools::Utils::__build_interfaces( q{hostname}, $global_config, $pf_config, {} ); }
+throws_ok {
+ PFTools::Utils::__build_interfaces(
+ {
+ hostname => q{hostname},
+ global_config => $global_config,
+ pf_config => $pf_config,
+ site_name => {},
+ }
+ );
+}
qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] site_name }xms
=> q{Dies if non-scalar $site_name};
-$result = PFTools::Utils::__build_interfaces( q{cbv4-rdeploy01}, $global_config, $pf_config, q{cbv4} );
+$result = PFTools::Utils::__build_interfaces(
+ {
+ hostname => q{cbv4-spawn01},
+ global_config => $global_config,
+ pf_config => $pf_config,
+ site_name => q{cbv4-pfds},
+ }
+);
$expected_result = [
- q{#},
- q{# This file was auto-generated by mk_interfaces -- DO NOT EDIT!},
- q{#},
- q{},
- q{auto lo},
- q{iface lo inet loopback},
- q{},
- q{auto eth0},
- q{iface eth0 inet static},
+ qq{#},
+ qq{# This file was auto-generated by mk_interfaces -- DO NOT EDIT!},
+ qq{#},
+ qq{},
+ qq{auto lo},
+ qq{iface lo inet loopback},
+ qq{},
+ qq{auto bond0},
+ qq{iface bond0 inet static},
+ qq{\tslaves\t\teth2 eth3},
+ qq{\taddress\t\t192.168.1.98},
+ qq{\tnetmask\t\t255.255.255.0},
+ qq{\tnetwork\t\t192.168.1.0},
+ qq{\tbroadcast\t192.168.1.255},
+ qq{},
+ qq{auto eth0},
+ qq{iface eth0 inet static},
qq{\taddress\t\t10.1.167.1},
qq{\tnetmask\t\t255.255.0.0},
qq{\tnetwork\t\t10.1.0.0},
qq{\tbroadcast\t10.1.255.255},
- q{},
+ qq{},
+ qq{auto eth0.39},
+ qq{iface eth0.39 inet static},
+ qq{\taddress\t\t10.2.167.1},
+ qq{\tnetmask\t\t255.255.0.0},
+ qq{\tnetwork\t\t10.2.0.0},
+ qq{\tbroadcast\t10.2.255.255},
+ qq{\tvlan_raw_device\teth0},
+ qq{\tup\t\t/sbin/ip link set eth0.39 mtu 1496},
+ qq{},
+ qq{auto eth4},
+ qq{iface eth4 inet static},
+ qq{\taddress\t\t10.3.1.42},
+ qq{\tnetmask\t\t255.255.255.0},
+ qq{\tnetwork\t\t10.3.1.0},
+ qq{\tbroadcast\t10.3.1.255},
+ qq{},
+ qq{auto eth5},
+ qq{iface eth5 inet static},
+ qq{\taddress\t\t10.3.2.42},
+ qq{\tnetmask\t\t255.255.255.0},
+ qq{\tnetwork\t\t10.3.2.0},
+ qq{\tbroadcast\t10.3.2.255},
+ qq{},
];
+
+is_deeply $result, $expected_result
+ => q{Returns the expected result for host cbv4-spawn01 site cbv4-pfds'}
+ or note explain $result;
+
+########################################################################
+note('Testing PFTools::Utils::make_interfaces_file');
+can_ok( 'PFTools::Utils', qw( make_interfaces_file ) );
+
+throws_ok { make_interfaces_file(); }
+qr{ \A ERROR: [ ] Invalid [ ] [\$] arguments_ref }xms
+ => q{Dies if no args};
+
+$test_output_file = q{test.interfaces};
+$result = make_interfaces_file(
+ {
+ hostname => q{cbv4-spawn01},
+ global_config => $global_config,
+ pf_config => $pf_config,
+ site_name => q{cbv4-pfds},
+ filename => $test_output_file,
+ }
+);
+ok $result => q{Returns true on success};
+
+$result = PFTools::Utils::__read_file_in_array( $test_output_file, 1 );
+
+is_deeply $result, $expected_result
+ => q{Returns the expected result for host cbv4-spawn01 site cbv4-pfds'}
+ or note explain $result;
+
+ok unlink($test_output_file)
+ => q{Removed the test-generated interfaces file};
+
+########################################################################
+note('Testing PFTools::Utils::__build_sources_list');
+can_ok( 'PFTools::Utils', qw( __build_sources_list ) );
+
+throws_ok { PFTools::Utils::__build_sources_list(); }
+qr{ \A ERROR: }xms
+ => q{Dies if no $arguments_ref};
+
+throws_ok { PFTools::Utils::__build_sources_list( {} ); }
+qr{ \A ERROR: }xms
+ => q{Dies if empty $arguments_ref};
+
+throws_ok { PFTools::Utils::__build_sources_list( { template => q{} } ); }
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] template }xms
+ => q{Dies if empty $template};
+
+throws_ok { PFTools::Utils::__build_sources_list( { template => {} } ); }
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] template }xms
+ => q{Dies if non-scalar $template};
+
+throws_ok {
+ PFTools::Utils::__build_sources_list(
+ { template => q{template}, hostname => q{}, sections_ref => q{} }
+ );
+}
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] sections_ref }xms
+ => q{Dies if empty $sections_ref};
+
+throws_ok {
+ PFTools::Utils::__build_sources_list(
+ { template => q{template}, hostname => q{}, sections_ref => {} }
+ );
+}
+qr{ \A ERROR: [ ] Invalid [ ] non-array-ref [ ] [\$] sections_ref }xms
+ => q{Dies if non-array-ref $sections_ref};
+
+throws_ok {
+ PFTools::Utils::__build_sources_list(
+ { template => q{template}, hostname => q{}, sections_ref => [] }
+ );
+}
+qr{ \A ERROR: [ ] Invalid [ ] empty-array-ref [ ] [\$] sections_ref }xms
+ => q{Dies if empty-array-ref $sections_ref};
+
+throws_ok {
+ PFTools::Utils::__build_sources_list(
+ { template => q{template}, hostname => q{}, sections_ref => [q{}] }
+ );
+}
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] or [ ] blank [ ] section [ ] in [ ] array-ref [ ] [\$] sections_ref }xms
+ => q{Dies if empty section in array-ref $sections_ref};
+
+throws_ok {
+ PFTools::Utils::__build_sources_list(
+ { template => q{template}, hostname => q{}, sections_ref => [q{ }] }
+ );
+}
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] or [ ] blank [ ] section [ ] in [ ] array-ref [ ] [\$] sections_ref }xms
+ => q{Dies if blank section in array-ref $sections_ref};
+
+throws_ok {
+ PFTools::Utils::__build_sources_list(
+ {
+ template => q{template},
+ sections_ref => [q{section}],
+ backports => {}
+ }
+ );
+}
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] backports }xms
+ => q{Dies if non-scalar $backports};
+
+throws_ok {
+ PFTools::Utils::__build_sources_list(
+ {
+ template => q{template},
+ sections_ref => [q{section}],
+ hostname => q{hostname},
+ global_config => q{foo},
+ }
+ );
+}
+qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] global_config }xms
+ => q{Dies if non-hashref $global_config};
+
+throws_ok {
+ PFTools::Utils::__build_sources_list(
+ {
+ template => q{template},
+ sections_ref => [q{section}],
+ hostname => q{hostname},
+ global_config => {},
+ }
+ );
+}
+qr{ \A ERROR: [ ] Invalid [ ] [\$] global_config [ ] hashref: }xms
+ => q{Dies if non-config hashref $global_config};
+
+throws_ok {
+ PFTools::Utils::__build_sources_list(
+ {
+ template => q{template},
+ sections_ref => [q{section}],
+ hostname => q{hostname},
+ global_config => $global_config,
+ hostname => q{},
+ }
+ );
+}
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] hostname }xms
+ => q{Dies if empty $hostname};
+
+throws_ok {
+ PFTools::Utils::__build_sources_list(
+ {
+ template => q{template},
+ sections_ref => [q{section}],
+ hostname => q{hostname},
+ global_config => $global_config,
+ hostname => {},
+ }
+ );
+}
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] hostname }xms
+ => q{Dies if non-scalar $hostname};
+
+my $test_sections_ref = [qw(common uncommon)];
+
+$expected_result = <<'EOT';
+#
+# Generated by mk_sourceslist -- DO NOT EDIT!
+#
+
+deb http://mirrors.private/debian lenny main contrib non-free
+deb http://mirrors.private/debian-custom lenny-custom common uncommon
+deb http://mirrors.private/debian-security lenny/updates main contrib non-free
+
+EOT
+
+########################################################################
+note('Testing PFTools::Utils::make_sources_list_file');
+can_ok( 'PFTools::Utils', qw( make_sources_list_file ) );
+
+throws_ok { make_sources_list_file(); }
+qr{ \A ERROR: [ ] Invalid [ ] [\$] arguments_ref }xms
+ => q{Dies if no args};
+
+$test_output_file = q{test.sources.list};
+$result = make_sources_list_file(
+ {
+ hostname => q{cbv4-rdeploy01},
+ site_name => q{cbv4},
+ filename => $test_output_file,
+ sections_ref => $test_sections_ref,
+ template => q{templates/sources.list},
+ global_config => $global_config,
+ pf_config => $pf_config,
+ }
+);
+ok $result => q{Returns true on success};
+
+$result = PFTools::Utils::__read_file_in_scalar( $test_output_file );
is_deeply $result, $expected_result
=> q{Returns the expected result for host cbv4-rdeploy01 site cbv4'}
or note explain $result;
-
-########################################################################
-note('Testing PFTools::Utils::make_interfaces_file');
-can_ok( 'PFTools::Utils', qw( make_interfaces_file ) );
-
-my $test_interfaces_file = q{test.interfaces};
-$result = make_interfaces_file( q{cbv4-rdeploy01}, $global_config, $pf_config, q{cbv4}, $test_interfaces_file );
-ok $result => q{Returns true on success};
-
-$result = PFTools::Utils::__read_file_in_array( $test_interfaces_file, 1 );
-
-is_deeply $result, $expected_result
- => q{Returns the expected result for host cbv4-rdeploy01 site cbv4'}
- or note explain $result;
-
-ok unlink($test_interfaces_file)
+ok unlink($test_output_file)
=> q{Removed the test-generated interfaces file};
diff -r 75b485e19166 -r dd4873cacd2e templates/sources.list
--- a/templates/sources.list Thu Nov 18 16:55:31 2010 +0100
+++ b/templates/sources.list Mon Nov 22 11:01:19 2010 +0100
@@ -1,8 +1,8 @@
-# Generated by mk_sourceslist : DO NOT EDIT MANUALLY !
-# Except if you know what you're doing
+#
+# Generated by mk_sourceslist -- DO NOT EDIT!
+#
deb http://mirrors.private/[% mode %] [% distrib %] [% default_sections %]
+deb http://mirrors.private/[% mode %]-custom [% distrib %]-custom [% custom_sections %]
+deb http://mirrors.private/[% mode %]-security [% distrib %]/updates [% default_sections %]
-deb http://mirrors.private/[% mode %]-custom [% distrib %]-custom [% custom_sections %]
-
-deb http://mirrors.private/[% mode %]-security [% distrib %]/updates [% default_sections %]
More information about the pf-tools-commits
mailing list