voxpupuli / puppet-wildfly

Puppet module to install, configure and manage Wildfly (8/9/10+), JBoss EAP (6.1+/7.0+) and some Wildfly based products like apiman, Keycloak and Infinispan.
Apache License 2.0
29 stars 79 forks source link

wildfly::jgroups::stack::tcpping fails with "No resource definition" #283

Open EmersonPrado opened 1 year ago

EmersonPrado commented 1 year ago

Description

I'm struggling to get a TCPPing-enabled JGroup with type wildfly::jgroups::stack::tcpping. Every Puppet run fails with:

# Code is WFLYCTL0030 for Wildfly 10.1.0 and 9.0.2, and JBAS014883 for Wildfly 8.2.1
<Code>: No resource definition is registered for address [
    ("subsystem" => "jgroups"),
    ("stack" => "tcpping")
]

Indeed, there's no JGroup stack in Wildfly's profile setting:

sed -n '/<profile>/,\_</profile>_p' /opt/wildfly/standalone/configuration/standalone-full-ha.xml |
sed -n '1p;/<subsystem .*:jgroups/,\_</subsystem>_p;$p' |
grep -E '(profile|subsystem|stack[^=])'
    <profile>
        <subsystem xmlns="urn:jboss:domain:jgroups:3.0">
            <stacks default="udp">
                <stack name="udp">
                </stack>
                <stack name="tcp">
                </stack>
            </stacks>
        </subsystem>
    </profile>

I don't know if I'm missing some step or hitting a bug. This issue intends to find it out.

Test case

I set up a test environment with Vagrant, with a standalone server and a domain controller/managed server pair, the most similar I could get, both using wildfly::jgroups::stack::tcpping with the same minimal settings. All VMs are CentOS 7 (bento/centos-7 Vagrant box), tested with Puppet 5, 6 and 7, and with Wildfly 8, 9 and 10, with the same results.

See below my Puppet main manifest. Further details in the test environment repo mentioned above.

$tmp_dir = '/tmp/wildfly'
# IPs correspond to private network interfaces from Vagrant
$standalone_ip = '192.168.56.4'
$controller_ip = '192.168.56.5'
$managed_ip = '192.168.56.6'
$mgmt_port = '9990'

file { $tmp_dir:
  ensure => directory,
}

class { 'java':
  distribution => 'jdk',
}

$wildfly_defaults = {
  install_cache_dir => $tmp_dir,
  java_home         => '/usr',
  mgmt_user         => { username  => 'admin', password  => 'pass' },
  require           => [File[$tmp_dir], Class['java']],
}

# The Admin Console listens to the management interface
node /^standalone/ {
  class { 'wildfly':
    properties => {
      'jboss.bind.address.management' => $standalone_ip,
      'jboss.management.http.port'    => $mgmt_port,    # Needed for wildfly::jgroups::stack::tcpping
    },
    *          => $wildfly_defaults,
  }
  wildfly::jgroups::stack::tcpping { 'TCPPING':
   initial_hosts       => "${standalone_ip}[${mgmt_port}]",
   num_initial_members => 1
  }
}

node /^controller/ {
  class { 'wildfly':
    mode           => 'domain',
    host_config    => 'host-master.xml',
    properties     => {
      'jboss.bind.address.management' => $controller_ip,
      'jboss.management.http.port'    => $mgmt_port,    # Needed for wildfly::domain::server_group below
    },
    external_facts => true,
    *              => $wildfly_defaults,
  }
  wildfly::domain::server_group { ['main-server-group', 'other-server-group']:
    ensure => absent,
  }
  wildfly::domain::server_group { 'app-server-group':
    profile              => 'full-ha',
    socket_binding_group => 'full-ha-sockets',
  }
  wildfly::config::mgmt_user { 'managed':
    password => 'whatever',
  }
  wildfly::jgroups::stack::tcpping { 'TCPPING':
    initial_hosts       => "${managed_ip}[${mgmt_port}]",
    num_initial_members => 1
  }
}

node /^managed/ {
  ensure_packages(['nmap'])
  class { 'wildfly':
    mode         => 'domain',
    host_config  => 'host-slave.xml',
    properties   => {
      'jboss.bind.address.management' => $managed_ip,
      'jboss.domain.master.address'   => $controller_ip,
    },
    secret_value => 'd2hhdGV2ZXIK',     # Base64 encoding for 'whatever'
    *            => $wildfly_defaults,
  }
  wildfly::host::server_config { ['server-one', 'server-two']:
    ensure => absent,
    before => Class['wildfly::setup'],
  }
  wildfly::host::server_config { 'app':
    server_group => 'app-server-group',
    hostname     => 'managed',
    username     => 'managed',
    password     => 'whatever',
  }
}
EmersonPrado commented 1 year ago

I guess I found the cause: defined types wildfly::jgroups::stack, wildfly::jgroups::stack::tcp, wildfly::jgroups::stack::tcpgossip and wildfly::jgroups::stack::tcpping have no profile parameter, which is a required information for wildfly::resource in domain mode.

I confirmed that in my Vagrant test setup, in branch resource_direct_calls. Long story short, I changed the calls to wildfly::jgroups::stack::tcpping for the same wildfly::resource calls they'd do, but adding the profile parameter:

$mgmt_port = '9990'
$tcpp_port = '7600'
...
node /^controller/ {
  class { 'wildfly':
    mode           => 'domain',
    host_config    => 'host-master.xml',
    properties     => {
      'jboss.bind.address.management' => $controller_ip,
      'jboss.management.http.port'    => $mgmt_port,    # Needed for wildfly::domain::server_group below
    },
    external_facts => true,
    *              => $wildfly_defaults,
  }
  wildfly::domain::server_group { ['main-server-group', 'other-server-group']:
    ensure => absent,
  }
  wildfly::domain::server_group { 'app-server-group':
    profile              => 'full-ha',
    socket_binding_group => 'full-ha-sockets',
  }
  wildfly::config::mgmt_user { 'managed':
    password => 'whatever',
  }
  wildfly::resource { '/subsystem=jgroups/stack=tcpping':
    recursive => true,
    profile   => 'full-ha',
    content   => {
      'protocol'  => wildfly::objectify([
        'TCPPING',
        'MERGE3',
        { 'FD_SOCK' => { 'socket-binding' => 'jgroups-tcp-fd' } },
        'FD',
        'VERIFY_SUSPECT',
        'pbcast.NAKACK2',
        'UNICAST3',
        'pbcast.STABLE',
        'pbcast.GMS',
        'UFC',
        'MFC',
        'FRAG2',
        'RSVP',
      ]),
      'transport' => {
        'TCP' => {
          'socket-binding' => 'jgroups-tcp',
        },
      },
    },
  }
  -> wildfly::resource { '/subsystem=jgroups/stack=tcpping/protocol=TCPPING':
    profile => 'full-ha',
    content => {
      'properties' => {
        'initial_hosts'       => "${managed_ip}[${tcpp_port}]",
        'timeout'             => 3000,
        'num_initial_members' => 1,
        'port_range'          => 0,
      }
    },
  }
  -> wildfly::resource { '/subsystem=jgroups':
    profile => 'full-ha',
    content => {
      'default-stack' => 'tcpping',
    },
  }
}

node /^managed/ {
  ensure_packages(['nmap'])
  class { 'wildfly':
    mode         => 'domain',
    host_config  => 'host-slave.xml',
    properties   => {
      'jboss.bind.address.management' => $managed_ip,
      'jboss.domain.master.address'   => $controller_ip,
    },
    secret_value => 'd2hhdGV2ZXIK',     # Base64 encoding for 'whatever'
    *            => $wildfly_defaults,
  }
  wildfly::host::server_config { ['server-one', 'server-two']:
    ensure => absent,
    before => Class['wildfly::setup'],
  }
  wildfly::host::server_config { 'app':
    server_group => 'app-server-group',
    hostname     => 'managed',
    username     => 'managed',
    password     => 'whatever',
    require      => Class['wildfly::install'],
  }
}

So the proposed fix is just add the profile parameter in all affected defined types. I confirmed it's working with tcpping - didn't test tcpgossip, but added the same fix out of hope - with branch resource_with_profile_parameter of my Vagrant test fixture. In this test, I just added profile parameter to tcpping call for the domain controller, and left the same call intact for the standalone host:

node /^standalone/ {
  ...
  wildfly::jgroups::stack::tcpping { 'TCPPING':
    initial_hosts       => "${standalone_ip}[${tcpp_port}]",
    num_initial_members => 1,
  }
}

node /^controller/ {
  ...
  wildfly::jgroups::stack::tcpping { 'TCPPING':
    initial_hosts       => "${managed_ip}[${tcpp_port}]",
    num_initial_members => 1,
    profile             => 'full-ha',
  }
}

Next step is updating the affected tests, but I can't run them on my computer - my old OS (LMDE 4) couldn't catch the required versions for the test gems. Since the changes are quite straightforward, I'll try to add, then ask someone else to run them.