Introduction
¶ ↑
The Tungsten Ruby Library (TRL) is designed to simplify the process of writing scripts that interact with Tungsten Replication and Dataservices. Scripts using TRL may be run
It features support for the following common use cases. Features not covered by the TRL may be added using common Ruby libraries.
* Option Parsing * Logging * JSON parsing/generation * Local command execution * Remote command execution * Object-Oriented access to clustering or replication information
Minimum script contents
¶ ↑
The minimum script will contain the following and be executable.
#!/usr/bin/env ruby
require “/opt/continuent/tungsten/cluster-home/lib/ruby/tungsten”
class TungstenEnvironment
include TungstenScript def main # Script logic here end self.new().run()
end
Running a script in staging directories
¶ ↑
class TungstenEnvironment
…
def configure require_installed_directory?(false) end
… end
Adding command-line arguments
¶ ↑
The TRL will parse command-line arguments for you if you give it information about what is expected. It will automatically create the ‘–help` output.
class TungstenEnvironment
…
def configure super() add_option(:boolean, { :on => "--boolean", :help => "A boolean option that will true or false", :default => false }) # Access the value via opt(:boolean) add_option(:string, { :on => "--string String", :help => "A string option" }) # Access the value via opt(:string) add_option(:integer, { :on => "--integer String", :help => "An integer option", :default => 10 }) {|val| val.to_i() } # Access the value via opt(:integer) end
… end
Validating the arguments and current environment
¶ ↑
class TungstenEnvironment
…
def validate super() # Validate option values here end
… end
Logging output
¶ ↑
The TRL defines several logging functions and command line arguments fore enabling different levels of verbosity.
TU.error(msg) # Always enabled TU.warning(msg) # Enabled by adding ‘-q’ TU.notice(msg) # Enabled by default or by adding ‘-n’ TU.info(msg) # Enabled by adding ‘-i’ TU.debug(msg) # Enabled by adding by adding ‘-v’
Define the ‘script_log_path’ function in your script and the all messages will be saved to the path returned by the function.
Running commands locally and on remote hosts
¶ ↑
begin
cmd_output = TU.cmd_result("/command/to/run --arg")
rescue CommandError
=> ce
# Error with the command
end
begin
cmd_output = TU.ssh_result("/command/to/run --arg", host, user)
rescue MessageError
=> me
# Error with the SSH connection
rescue RemoteCommandError
=> rce
# Error with the command
end
Using JSON
¶ ↑
JSON.parse()
JSON.pretty_generate()
Reading/Storing configuration files
¶ ↑
The Properties
class enables you to read/write/access a nested Hash object. It will store the contents of the Hash in JSON
format to enabled easy compatibility.
To read a file into a new Properties
object
p = Properties.new()
p.load(“/path/to/config.json”)
To write the file when done making changes
p.store(“/path/to/config.json”)
Reading entries from the properties
The ‘getProperty’ function will return the nested value or nil if it doesn’t exist.
p.getProperty([“dataservices”, “alpha”, “master”])
The ‘getPropertyOr’ function will return the nested value or the second argument if a value doesn’t exist.
p.getProperty([“dataservices”, “alpha”, “type”], “master-slave”)
Writing entries into the properties
The ‘setProperty’ function will set nested value to the provided value.
p.setProperty([“dataservices”, “alpha”, “type”], “fan-in”)
The ‘setDefault’ function will only store the value if a value does not already exist.
p = Properties.new()
p.setDefault([“dataservices”, “alpha”, “type”], “fan-in”) p.setDefault([“dataservices”, “alpha”, “type”], “master-slave”) p.getProperty(([“dataservices”, “alpha”, “type”]) # => “fan-in”
Additional functions
The ‘reset’ function will clear all values p.reset()
The ‘to_s()’ function will return a formatted JSON
string p.to_s()
Working with Tungsten installations
¶ ↑
The TungstenInstall
class provides an interface to an installed Tungsten directory. The Ruby library will automatically create the constant TI as an instance of TungstenInstall
in two cases:
* If the library is loaded from an installed directory * If the '--directory' argument is provided
The TungstenInstall
class depends on the Tungsten services to be running. It will provide mixed results if you do not have all services running. You may create multiple TungstenInstall
objects to work with many directories. The TI object is just one instance and is provided as a courtesy.
Learning about the installation
# The hostname used to configure this directory. It may differ from the system hostname TI.hostname()
# The system user used for running Tungsten services in this directory TI.user()
TI.is_replicator?() # => true|false TI.is_manager?() # => true|false TI.is_connector?() # => true|false TI.is_running?(“manager”) # => true|false TI.is_commercial?() # => true|false
Reading dataservice information
The ‘dataservices’ function returns an array of all configured dataservices. TI.dataservices() # => [“alpha”]
Reading expected configuration information
topology = TI.topology(“alpha”)
pp topology.name pp topology.is_composite?() pp topology.members pp topology.master pp topology.connectors pp topology.dataservices
Reading dataservice status information
The ‘status’ function will provide an object that is populated with information for the given dataservice. status = TI.status(“alpha”) # => TungstenStatus
object
# Is this a replication-only service with no Manager involvement status.is_replication?() # => true|false
# Is this a physical dataservice? status.is_physical?() # => true|false
# Is this a composite dataservice? status.is_composite?() # => true|false
# Return the current policy, if it exists, for the dataservice status.policy() # => MANUAL|MAINTENANCE|AUTOMATIC
# Return the current coordinator, if it exists, for the dataservice status.coordinator() # => “db1.nyc.tu.com”
# Return an array of the available datasources or replicators status.datasources() # => [“db1.nyc.tu.com”, “db2.nyc.tu.com”] status.replicators() # => [“db1.nyc.tu.com”, “db2.nyc.tu.com”]
# Return information about the datasource or replicator status.datasource_role(“db1.nyc.tu”) status.datasource_status(“db1.nyc.tu”) status.datasource_value(“db1.nyc.tu”, “activeConnectionsCount”) status.replicator_role(“db1.nyc.tu”) status.replicator_status(“db1.nyc.tu”) status.replicator_latency(“db1.nyc.tu”) status.replicator_value(“db1.nyc.tu”, “masterListenUri”)
Interacting with the replicator
# Get an executable path to trepctl for the dataservice given TI.trepctl(“alpha”) # => “/opt/continuent/tungsten/tungsten-replicator/bin/trepctl -port 10000 -service alpha”
# Read a value from the trepctl status for a dataservice TI.trepctl(“alpha”, “masterListenUri”)
# Read a value from the configuration of a dataservice TI.trepctl_property(“alpha”, “replicator.storage.agent.fs.directory”)
Interacting with the manager
# Get an executable path to cctrl TI.cctrl()
# Execute a command against cctrl trying up to 5 times for a success TI.ensure_cctrl(“ls”, 5)
# Read from the manager API TI.manager_api_result(“status/alpha”, [“serviceState”])
Differences when running against a replication-only installation
The following TungstenInstall
functions will not provide values
* TI.ensure_cctrl()
The following Topology functions will not provide values
* topology.policy() * topology.coordinator() * topology.datasources()