Class: Puppet::Provider::Websphere_Helper

Inherits:
Puppet::Provider
  • Object
show all
Defined in:
lib/puppet/provider/websphere_helper.rb

Instance Method Summary collapse

Instance Method Details

#flushObject

We want to make sure we sync the app node with the dmgr when things change. This happens automatically anyway, but with a delay.



192
193
194
# File 'lib/puppet/provider/websphere_helper.rb', line 192

def flush
  sync_node
end

#get_xml_val(section, element, attribute, server_xml = nil) ⇒ Object

Helper method to query the ‘server.xml’ file for an attribute. value. Ideally, we could have this query any arbitrary xml value with any depth. It’s rigid and stuck at three levels deep for now.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/puppet/provider/websphere_helper.rb', line 96

def get_xml_val(section,element,attribute,server_xml=nil)

  unless server_xml
    server_xml = resource[:profile_base] + '/' \
      + resource[:dmgr_profile] + '/config/cells/' \
      + resource[:cell] + '/nodes/' + resource[:node] \
      + '/servers/' + resource[:name] + '/server.xml'
  end

  unless File.exists?(server_xml)
    raise Puppet::Error, "Websphere_cluster_member[#{resource[:name]}]: "\
      + "Unable to open server.xml at #{server_xml}. Make sure the profile "\
      + "exists, the node has been federated, a corresponding app instance "\
      + "exists, and the names are correct. Hint:  The DMGR may need to "\
      + "Puppet."
    return false
  end
  xml_data = File.open(server_xml)

  doc = REXML::Document.new(xml_data)

  value = doc.root.elements[section].elements[element].attributes[attribute]

  self.debug "#{server_xml}/" + "#{element}:#{attribute}: #{value}"

  unless value
    false
  end
  value.to_s
end

#restart_serverObject



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/puppet/provider/websphere_helper.rb', line 168

def restart_server
  if resource[:server]
cmd = <<-EOT
ns = AdminControl.queryNames('WebSphere:*,type=Server,name=#{resource[:server]}').splitlines()
server = ns[0]
AdminControl.invoke(server, 'restart')
EOT
    self.debug "Restarting #{resource[:node]} #{resource[:server]} with #{cmd}"
    result = wsadmin(:file => cmd, :user => resource[:user], :failonfail => false)
    self.debug "Result: #{result}"
  end

  if resource[:node]
    cmd = "\"na = AdminControl.queryNames('type=NodeAgent,node=#{resource[:node]},*');"
    cmd += "AdminControl.invoke(na,'restart','true true')\""

    self.debug "Restarting node: #{resource[:node]} with #{cmd}"
    result = wsadmin(:command => cmd, :user => resource[:user], :failonfail => false)
    self.debug "Result: #{result}"
  end
end

#sync_nodeObject

This synchronizes the app node(s) with the dmgr



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/puppet/provider/websphere_helper.rb', line 128

def sync_node

  sync_status = "\"the_id = AdminControl.completeObjectName('type=NodeSync,"
  sync_status += "node=" + resource[:node] + ",*');"
  sync_status += "AdminControl.invoke(the_id, 'isNodeSynchronized')\""

  status = wsadmin(
    :command => sync_status,
    :user => resource[:user],
    :failonfail => false
  )
  self.debug "Sync status " + resource[:node] + ": #{status}"

  unless status.include?("'true'")
    if status =~ /Error found in String ""; cannot create ObjectName/
      msg = <<-EOT
      Attempt to synchronize node failed because the node service likely
      isn't running or reachable.  A message about "cannot create ObjectName
      often indicates this.  Ensure that the NODE service is running.
      If the node service isn't running, synchronization will happen once
      it's started.  Node: #{resource[:node]}
      "
      EOT
      self.debug msg
    else
      sync = "\"the_id = AdminControl.completeObjectName('type=NodeSync,"
      sync += "node=" + resource[:node] + ",*');"
      sync += "AdminControl.invoke(the_id, 'sync')\""

      result = wsadmin(
        :command => sync,
        :user => resource[:user],
        :failonfail => false
      )
      self.debug "Sync node " + resource[:node] + ": #{result}"
      result
    end
  end
end

#wascmd(file = nil) ⇒ Object

Build the base ‘wsadmin’ command that we’ll use to make changes. This command is derived from whatever the ‘profile_base’ is (since wsadmin is profile-specific), the name of the profile, and credentials, if provided. Can we use the ‘commands’ method for this?



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/puppet/provider/websphere_helper.rb', line 12

def wascmd(file=nil)

  wsadmin_cmd = resource[:profile_base] + '/' + resource[:dmgr_profile]
  wsadmin_cmd += '/bin/wsadmin.sh -lang jython'

  if resource[:wsadmin_user] && resource[:wsadmin_pass]
    wsadmin_cmd += " -username '" + resource[:wsadmin_user] + "'"
    wsadmin_cmd += " -password '" + resource[:wsadmin_pass] + "'"
  end

  if file
    wsadmin_cmd += " -f #{file} "
  else
    wsadmin_cmd += " -c "
  end

  wsadmin_cmd
end

#wsadmin(args = {}) ⇒ Object

Method to make changes to the WAS configuration. Pass: :command => ‘some jython stuff’

The value will be sent to 'wsadmin' with the '-c' argument - evaluating
the code on the command line.

:file => ‘some jython stuff’

The value will be written to a temporary file and read in by wsadmin
using the '-f' argument.  This is for more complicated jython that
doesn't take kindly to being fed in on the command-line.


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/puppet/provider/websphere_helper.rb', line 39

def wsadmin(args={})

  if args[:failonfail] == false
    failonfail = false
  else
    failonfail = true
  end

  if args[:user]
    user = args[:user]
  else
    user = 'root'
  end

  if args[:file]
    cmdfile = Tempfile.new('wascmd_')

    ## File needs to be readable by the specified user.
    cmdfile.chmod(0644)
    cmdfile.write(args[:file])
    cmdfile.rewind
    modify = wascmd(cmdfile.path)
  else
    modify = wascmd + args[:command]
  end

  result = nil

  begin
    self.debug "Executing as user #{user}: #{modify}"
    Dir.chdir('/tmp') do
      result = Puppet::Util::Execution.execute(
        modify,
        :failonfail => failonfail,
        :uid => user,
        :combine => true
      )
    end

    result
  rescue
    if failonfail == true
      raise Puppet::Error, "Command failed for #{resource[:name]}: #{result}"
    else
      result
    end
  ensure
    if args[:file]
      cmdfile.close
      cmdfile.unlink
    end
  end
end