X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=meta-starlingx%2Fmeta-stx-cloud%2Frecipes-support%2Fpuppet%2Ffiles%2Fnetwork%2Fpuppet-network-Kilo-quilt-changes.patch;fp=meta-starlingx%2Fmeta-stx-cloud%2Frecipes-support%2Fpuppet%2Ffiles%2Fnetwork%2Fpuppet-network-Kilo-quilt-changes.patch;h=841198fb652f4333b86d92ae336a393652506ba9;hb=e0634c6eaf2fe2641a0fb90e84a5defb880b1335;hp=0000000000000000000000000000000000000000;hpb=210d0f78485e760dffcdd3f630f59cec797f3f11;p=pti%2Frtp.git diff --git a/meta-starlingx/meta-stx-cloud/recipes-support/puppet/files/network/puppet-network-Kilo-quilt-changes.patch b/meta-starlingx/meta-stx-cloud/recipes-support/puppet/files/network/puppet-network-Kilo-quilt-changes.patch new file mode 100644 index 0000000..841198f --- /dev/null +++ b/meta-starlingx/meta-stx-cloud/recipes-support/puppet/files/network/puppet-network-Kilo-quilt-changes.patch @@ -0,0 +1,658 @@ +From 8e14e2e258a8f2f7189ed37c6337c41fbff0362a Mon Sep 17 00:00:00 2001 +From: Al Bailey +Date: Mon, 6 Jun 2016 17:13:09 -0400 +Subject: [PATCH] puppet-network Kilo quilt changes + +--- + .../lib/puppet/provider/network_config/redhat.rb | 39 ++- + .../lib/puppet/provider/network_config/wrlinux.rb | 296 +++++++++++++++++++++ + .../lib/puppet/provider/network_route/wrlinux.rb | 109 ++++++++ + .../network/lib/puppet/type/network_config.rb | 4 + + packstack/puppet/modules/network/manifests/bond.pp | 22 ++ + .../puppet/modules/network/manifests/bond/setup.pp | 2 + + .../modules/network/manifests/bond/wrlinux.pp | 56 ++++ + 7 files changed, 521 insertions(+), 7 deletions(-) + create mode 100644 packstack/puppet/modules/network/lib/puppet/provider/network_config/wrlinux.rb + create mode 100644 packstack/puppet/modules/network/lib/puppet/provider/network_route/wrlinux.rb + create mode 100644 packstack/puppet/modules/network/manifests/bond/wrlinux.pp + +diff --git a/packstack/puppet/modules/network/lib/puppet/provider/network_config/redhat.rb b/packstack/puppet/modules/network/lib/puppet/provider/network_config/redhat.rb +index 4b6de7e..758f387 100644 +--- a/packstack/puppet/modules/network/lib/puppet/provider/network_config/redhat.rb ++++ b/packstack/puppet/modules/network/lib/puppet/provider/network_config/redhat.rb +@@ -19,7 +19,12 @@ Puppet::Type.type(:network_config).provide(:redhat) do + has_feature :provider_options + + # @return [String] The path to network-script directory on redhat systems +- SCRIPT_DIRECTORY = "/etc/sysconfig/network-scripts" ++ # SCRIPT_DIRECTORY = "/etc/sysconfig/network-scripts" ++ # WRS: Generate temporary copies. It will get compared to files under ++ # /etc/sysconfig/network-scripts afterward. Only config that have changed ++ # will get replaced. Don't let puppet directly manage them, else it will ++ # trigger un-wanted networking actions (like up/down). ++ SCRIPT_DIRECTORY = "/var/run/network-scripts.puppet" + + # The valid vlan ID range is 0-4095; 4096 is out of range + VLAN_RANGE_REGEX = %r[\d{1,3}|40[0-9][0-5]] +@@ -35,6 +40,7 @@ Puppet::Type.type(:network_config).provide(:redhat) do + :name => 'DEVICE', + :hotplug => 'HOTPLUG', + :mtu => 'MTU', ++ :gateway => 'GATEWAY', + } + + # Map provider instances to files based on their name +@@ -60,8 +66,14 @@ Puppet::Type.type(:network_config).provide(:redhat) do + # RedhatProvider.target_files + # # => ['/etc/sysconfig/network-scripts/ifcfg-eth0', '/etc/sysconfig/network-scripts/ifcfg-eth1'] + def self.target_files(script_dir = SCRIPT_DIRECTORY) +- entries = Dir.entries(script_dir).select {|entry| entry.match SCRIPT_REGEX} +- entries.map {|entry| File.join(SCRIPT_DIRECTORY, entry)} ++ entries = [] ++ if Dir.exists?(SCRIPT_DIRECTORY) ++ Dir.foreach(SCRIPT_DIRECTORY) do |item| ++ next if not item.match SCRIPT_REGEX ++ entries << item ++ end ++ end ++ entries + end + + # Convert a redhat network script into a hash +@@ -184,6 +196,8 @@ Puppet::Type.type(:network_config).provide(:redhat) do + end + + def self.format_file(filename, providers) ++ Dir.mkdir(SCRIPT_DIRECTORY) unless File.exists?(SCRIPT_DIRECTORY) ++ + if providers.length == 0 + return "" + elsif providers.length > 1 +@@ -193,11 +207,11 @@ Puppet::Type.type(:network_config).provide(:redhat) do + provider = providers[0] + props = {} + +- # Map everything to a flat hash +- props = (provider.options || {}) ++ props = provider.options if provider.options && provider.options != :absent + ++ # Map everything to a flat hash + NAME_MAPPINGS.keys.each do |type_name| +- if (val = provider.send(type_name)) ++ if (val = provider.send(type_name)) && val != :absent + props[type_name] = val + end + end +@@ -214,11 +228,11 @@ Puppet::Type.type(:network_config).provide(:redhat) do + str << %{#{key}=#{val}\n} + end + ++ content.prepend(header) + content + end + + def self.unmunge(props) +- + pairs = {} + + [:onboot, :hotplug].each do |bool_property| +@@ -245,6 +259,17 @@ Puppet::Type.type(:network_config).provide(:redhat) do + pairs + end + ++ def self.header ++ str = <<-HEADER ++# HEADER: This file is is being managed by puppet. Changes to ++# HEADER: interfaces that are not being managed by puppet will persist; ++# HEADER: however changes to interfaces that are being managed by puppet will ++# HEADER: be overwritten. In addition, file order is NOT guaranteed. ++# HEADER: Last generated at: #{Time.now} ++HEADER ++ str ++ end ++ + def self.post_flush_hook(filename) + File.chmod(0644, filename) + end +diff --git a/packstack/puppet/modules/network/lib/puppet/provider/network_config/wrlinux.rb b/packstack/puppet/modules/network/lib/puppet/provider/network_config/wrlinux.rb +new file mode 100644 +index 0000000..44c645a +--- /dev/null ++++ b/packstack/puppet/modules/network/lib/puppet/provider/network_config/wrlinux.rb +@@ -0,0 +1,296 @@ ++require 'puppetx/filemapper' ++ ++Puppet::Type.type(:network_config).provide(:wrlinux) do ++ # Wind River Linux network_config interfaces provider. ++ # ++ # This provider uses the filemapper mixin to map the interfaces file to a ++ # collection of network_config providers, and back. ++ # ++ include PuppetX::FileMapper ++ ++ desc "Wind River interfaces style provider" ++ ++ confine :osfamily => :wrlinux ++ defaultfor :osfamily => :wrlinux ++ ++ has_feature :provider_options ++ has_feature :hotpluggable ++ ++ def select_file ++ '/var/run/interfaces.puppet' ++ end ++ ++ def self.target_files ++ ['/var/run/interfaces.puppet'] ++ end ++ ++ class MalformedInterfacesError < Puppet::Error ++ def initialize(msg = nil) ++ msg = 'Malformed wrlinux interfaces file; cannot instantiate network_config resources' if msg.nil? ++ super ++ end ++ end ++ ++ def self.raise_malformed ++ @failed = true ++ raise MalformedInterfacesError ++ end ++ ++ class Instance ++ ++ attr_reader :name ++ ++ # Booleans ++ attr_accessor :onboot, :hotplug ++ ++ ++ # These fields are going to get rearranged to resolve issue 16 ++ # https://github.com/adrienthebo/puppet-network/issues/16 ++ attr_accessor :ipaddress, :netmask, :family, :method, :mtu ++ ++ # Options hash ++ attr_reader :options ++ ++ def initialize(name) ++ @name = name ++ ++ @options = Hash.new {|hash, key| hash[key] = []} ++ end ++ ++ def to_hash ++ h = { ++ :name => @name, ++ :onboot => @onboot, ++ :hotplug => @hotplug, ++ :ipaddress => @ipaddress, ++ :netmask => @netmask, ++ :family => @family, ++ :method => @method, ++ :mtu => @mtu, ++ :options => squeeze_options ++ } ++ ++ h.inject({}) do |hash, (key, val)| ++ hash[key] = val unless val.nil? ++ hash ++ end ++ end ++ ++ def squeeze_options ++ @options.inject({}) do |hash, (key, value)| ++ if value.size <= 1 ++ hash[key] = value.pop ++ else ++ hash[key] = value ++ end ++ ++ hash ++ end ++ end ++ ++ class << self ++ ++ def reset! ++ @interfaces = {} ++ end ++ ++ # @return [Array] All class instances ++ def all_instances ++ @interfaces ||= {} ++ @interfaces ++ end ++ ++ def [](name) ++ if all_instances[name] ++ obj = all_instances[name] ++ else ++ obj = self.new(name) ++ all_instances[name] = obj ++ end ++ ++ obj ++ end ++ end ++ end ++ ++ def self.parse_file(filename, contents) ++ # Debian has a very irregular format for the interfaces file. The ++ # parse_file method is somewhat derived from the ifup executable ++ # supplied in the debian ifupdown package. The source can be found at ++ # http://packages.debian.org/squeeze/ifupdown ++ ++ ++ # The debian interfaces implementation requires global state while parsing ++ # the file; namely, the stanza being parsed as well as the interface being ++ # parsed. ++ status = :none ++ current_interface = nil ++ ++ lines = contents.split("\n") ++ # TODO Join lines that end with a backslash ++ ++ # Iterate over all lines and determine what attributes they create ++ lines.each do |line| ++ ++ # Strip off any trailing comments ++ line.sub!(/#.*$/, '') ++ ++ case line ++ when /^\s*#|^\s*$/ ++ # Ignore comments and blank lines ++ next ++ ++ when /^auto|^allow-auto/ ++ # Parse out any auto sections ++ interfaces = line.split(' ') ++ interfaces.delete_at(0) ++ ++ interfaces.each do |name| ++ Instance[name].onboot = true ++ end ++ ++ # Reset the current parse state ++ current_interface = nil ++ ++ when /^allow-hotplug/ ++ # parse out allow-hotplug lines ++ ++ interfaces = line.split(' ') ++ interfaces.delete_at(0) ++ ++ interfaces.each do |name| ++ Instance[name].hotplug = true ++ end ++ ++ # Don't reset Reset the current parse state ++ when /^iface/ ++ ++ # Format of the iface line: ++ # ++ # iface ++ # zero or more options for ++ ++ if match = line.match(/^iface\s+(\S+)\s+(\S+)\s+(\S+)/) ++ name = match[1] ++ family = match[2] ++ method = match[3] ++ ++ # If an iface block for this interface has been seen, the file is ++ # malformed. ++ raise_malformed if Instance[name] and Instance[name].family ++ ++ status = :iface ++ current_interface = name ++ ++ # This is done automatically ++ #Instance[name].name = name ++ Instance[name].family = family ++ Instance[name].method = method ++ ++ else ++ # If we match on a string with a leading iface, but it isn't in the ++ # expected format, malformed blar blar ++ raise_malformed ++ end ++ ++ when /^mapping/ ++ ++ # XXX dox ++ raise Puppet::DevError, "Debian interfaces mapping parsing not implemented." ++ status = :mapping ++ ++ else ++ # We're currently examining a line that is within a mapping or iface ++ # stanza, so we need to validate the line and add the options it ++ # specifies to the known state of the interface. ++ ++ case status ++ when :iface ++ if match = line.match(/(\S+)\s+(\S.*)/) ++ # If we're parsing an iface stanza, then we should receive a set of ++ # lines that contain two or more space delimited strings. Append ++ # them as options to the iface in an array. ++ ++ key = match[1] ++ val = match[2] ++ ++ name = current_interface ++ ++ case key ++ when 'address'; Instance[name].ipaddress = val ++ when 'netmask'; Instance[name].netmask = val ++ when 'mtu'; Instance[name].mtu = val ++ else Instance[name].options[key] << val ++ end ++ else ++ raise_malformed ++ end ++ when :mapping ++ raise Puppet::DevError, "Debian interfaces mapping parsing not implemented." ++ when :none ++ raise_malformed ++ end ++ end ++ end ++ ++ Instance.all_instances.map {|name, instance| instance.to_hash } ++ end ++ ++ # Generate an array of sections ++ def self.format_file(filename, providers) ++ contents = [] ++ contents << header ++ ++ # Add onboot interfaces ++ if (auto_interfaces = providers.select {|provider| provider.onboot == true }) ++ stanza = [] ++ stanza << "auto " + auto_interfaces.map(&:name).sort.join(" ") ++ contents << stanza.join("\n") ++ end ++ ++ # Build iface stanzas ++ providers.sort_by(&:name).each do |provider| ++ # TODO add validation method ++ raise Puppet::Error, "#{provider.name} does not have a method." if provider.method.nil? ++ raise Puppet::Error, "#{provider.name} does not have a family." if provider.family.nil? ++ ++ stanza = [] ++ stanza << %{iface #{provider.name} #{provider.family} #{provider.method}} ++ ++ [ ++ [:ipaddress, 'address'], ++ [:netmask, 'netmask'], ++ [:mtu, 'mtu'], ++ ].each do |(property, section)| ++ stanza << " #{section} #{provider.send property}" if provider.send(property) and provider.send(property) != :absent ++ end ++ ++ if provider.options and provider.options != :absent ++ provider.options.each_pair do |key, val| ++ if val.is_a? String ++ stanza << " #{key} #{val}" ++ elsif val.is_a? Array ++ val.each { |entry| stanza << " #{key} #{entry}" } ++ else ++ raise Puppet::Error, "#{self} options key #{key} expects a String or Array, got #{val.class}" ++ end ++ end ++ end ++ ++ contents << stanza.join("\n") ++ end ++ ++ contents.map {|line| line + "\n\n"}.join ++ end ++ ++ def self.header ++ str = <<-HEADER ++# HEADER: This file is is being managed by puppet. Changes to ++# HEADER: interfaces that are not being managed by puppet will persist; ++# HEADER: however changes to interfaces that are being managed by puppet will ++# HEADER: be overwritten. In addition, file order is NOT guaranteed. ++# HEADER: Last generated at: #{Time.now} ++HEADER ++ str ++ end ++end +diff --git a/packstack/puppet/modules/network/lib/puppet/provider/network_route/wrlinux.rb b/packstack/puppet/modules/network/lib/puppet/provider/network_route/wrlinux.rb +new file mode 100644 +index 0000000..d3fa7b5 +--- /dev/null ++++ b/packstack/puppet/modules/network/lib/puppet/provider/network_route/wrlinux.rb +@@ -0,0 +1,109 @@ ++require 'ipaddr' ++require 'puppetx/filemapper' ++ ++Puppet::Type.type(:network_route).provide(:wrlinux) do ++ # Wind River Linux network_route routes provider. ++ # ++ # This provider uses the filemapper mixin to map the routes file to a ++ # collection of network_route providers, and back. ++ # ++ include PuppetX::FileMapper ++ ++ desc "Wind River routes style provider" ++ ++ confine :osfamily => :wrlinux ++ ++ # $ dpkg -S /etc/network/if-up.d/20static-routes ++ # ifupdown-extra: /etc/network/if-up.d/20static-routes ++ confine :exists => '/etc/network/if-up.d/20static-routes' ++ ++ defaultfor :osfamily => :wrlinux ++ ++ has_feature :provider_options ++ ++ def select_file ++ '/etc/network/routes' ++ end ++ ++ def self.target_files ++ ['/etc/network/routes'] ++ end ++ ++ class MalformedRoutesError < Puppet::Error ++ def initialize(msg = nil) ++ msg = 'Malformed wrlinux routes file; cannot instantiate network_route resources' if msg.nil? ++ super ++ end ++ end ++ ++ def self.raise_malformed ++ @failed = true ++ raise MalformedRoutesError ++ end ++ ++ def self.parse_file(filename, contents) ++ # Build out an empty hash for new routes for storing their configs. ++ route_hash = Hash.new do |hash, key| ++ hash[key] = {} ++ hash[key][:name] = key ++ hash[key] ++ end ++ ++ lines = contents.split("\n") ++ lines.each do |line| ++ # Strip off any trailing comments ++ line.sub!(/#.*$/, '') ++ ++ if line =~ /^\s*#|^\s*$/ ++ # Ignore comments and blank lines ++ next ++ end ++ ++ route = line.split(' ', 5) ++ ++ if route.length < 4 ++ raise_malformed ++ end ++ ++ # use the CIDR version of the target as :name ++ cidr_target = "#{route[0]}/#{IPAddr.new(route[1]).to_i.to_s(2).count('1')}" ++ ++ route_hash[cidr_target][:network] = route[0] ++ route_hash[cidr_target][:netmask] = route[1] ++ route_hash[cidr_target][:gateway] = route[2] ++ route_hash[cidr_target][:interface] = route[3] ++ route_hash[cidr_target][:options] = route[4] if route[4] ++ end ++ ++ route_hash.values ++ end ++ ++ # Generate an array of sections ++ def self.format_file(filename, providers) ++ contents = [] ++ contents << header ++ ++ # Build routes ++ providers.sort_by(&:name).each do |provider| ++ raise Puppet::Error, "#{provider.name} is missing the required parameter 'network'." if provider.network.nil? ++ raise Puppet::Error, "#{provider.name} is missing the required parameter 'netmask'." if provider.netmask.nil? ++ raise Puppet::Error, "#{provider.name} is missing the required parameter 'gateway'." if provider.gateway.nil? ++ raise Puppet::Error, "#{provider.name} is missing the required parameter 'interface'." if provider.interface.nil? ++ ++ contents << "#{provider.network} #{provider.netmask} #{provider.gateway} #{provider.interface} #{provider.options}\n" ++ end ++ ++ contents.join ++ end ++ ++ def self.header ++ str = <<-HEADER ++# HEADER: This file is is being managed by puppet. Changes to ++# HEADER: routes that are not being managed by puppet will persist; ++# HEADER: however changes to routes that are being managed by puppet will ++# HEADER: be overwritten. In addition, file order is NOT guaranteed. ++# HEADER: Last generated at: #{Time.now} ++HEADER ++ str ++ end ++end +diff --git a/packstack/puppet/modules/network/lib/puppet/type/network_config.rb b/packstack/puppet/modules/network/lib/puppet/type/network_config.rb +index a50a0df..1297ad7 100644 +--- a/packstack/puppet/modules/network/lib/puppet/type/network_config.rb ++++ b/packstack/puppet/modules/network/lib/puppet/type/network_config.rb +@@ -95,6 +95,10 @@ Puppet::Type.newtype(:network_config) do + defaultto :raw + end + ++ newproperty(:gateway) do ++ desc 'The IP address of the network router or gateway device (if any)' ++ end ++ + # `:options` provides an arbitrary passthrough for provider properties, so + # that provider specific behavior doesn't clutter up the main type but still + # allows for more powerful actions to be taken. +diff --git a/packstack/puppet/modules/network/manifests/bond.pp b/packstack/puppet/modules/network/manifests/bond.pp +index d6d98ce..26ca104 100644 +--- a/packstack/puppet/modules/network/manifests/bond.pp ++++ b/packstack/puppet/modules/network/manifests/bond.pp +@@ -188,6 +188,28 @@ define network::bond( + require => Kmod::Alias[$name], + } + } ++ WRLinux: { ++ network::bond::wrlinux { $name: ++ slaves => $slaves, ++ ensure => $ensure, ++ ipaddress => $ipaddress, ++ netmask => $netmask, ++ method => $method, ++ family => $family, ++ onboot => $onboot, ++ ++ mode => $mode, ++ miimon => $miimon, ++ downdelay => $downdelay, ++ updelay => $updelay, ++ lacp_rate => $lacp_rate, ++ primary => $primary, ++ primary_reselect => $primary_reselect, ++ xmit_hash_policy => $xmit_hash_policy, ++ ++ require => Kmod::Alias[$name], ++ } ++ } + RedHat: { + network::bond::redhat { $name: + ensure => $ensure, +diff --git a/packstack/puppet/modules/network/manifests/bond/setup.pp b/packstack/puppet/modules/network/manifests/bond/setup.pp +index abe1252..0a30767 100644 +--- a/packstack/puppet/modules/network/manifests/bond/setup.pp ++++ b/packstack/puppet/modules/network/manifests/bond/setup.pp +@@ -10,5 +10,7 @@ class network::bond::setup { + ensure => present, + } + } ++ WRLinux: { ++ } + } + } +diff --git a/packstack/puppet/modules/network/manifests/bond/wrlinux.pp b/packstack/puppet/modules/network/manifests/bond/wrlinux.pp +new file mode 100644 +index 0000000..e240341 +--- /dev/null ++++ b/packstack/puppet/modules/network/manifests/bond/wrlinux.pp +@@ -0,0 +1,56 @@ ++# = Define: network::bond::wrlinux ++# ++# Instantiate bonded interfaces on Debian based systems. ++# ++# == See also ++# ++# * Debian Network Bonding http://wiki.wrlinux.org/Bonding ++define network::bond::wrlinux( ++ $slaves, ++ $ensure = present, ++ $ipaddress = undef, ++ $netmask = undef, ++ $method = undef, ++ $family = undef, ++ $onboot = undef, ++ ++ $mode = undef, ++ $miimon = undef, ++ $downdelay = undef, ++ $updelay = undef, ++ $lacp_rate = undef, ++ $primary = undef, ++ $primary_reselect = undef, ++ $xmit_hash_policy = undef, ++) { ++ ++ $raw = { ++ 'bond-slaves' => join($slaves, ' '), ++ 'bond-mode' => $mode, ++ 'bond-miimon' => $miimon, ++ 'bond-downdelay' => $downdelay, ++ 'bond-updelay' => $updelay, ++ 'bond-lacp-rate' => $lacp_rate, ++ 'bond-primary' => $primary, ++ 'bond-primary-reselect' => $primary_reselect, ++ 'bond-xmit-hash-policy' => $xmit_hash_policy, ++ } ++ ++ $opts = compact_hash($raw) ++ ++ network_config { $name: ++ ensure => $ensure, ++ ipaddress => $ipaddress, ++ netmask => $netmask, ++ family => $family, ++ method => $method, ++ onboot => $onboot, ++ options => $opts, ++ } ++ ++ network_config { $slaves: ++ ensure => absent, ++ reconfigure => true, ++ before => Network_config[$name], ++ } ++} +-- +1.8.3.1 +