If the osh configuration file is going to be used for database access, then it will contain a plaintext database password. It is therefore good practice to restrict access to this file, e.g. set permissions to 600.
from osh.config import *
Database and cluster configuration is done using field and slice notation. For example,
to specify that access to the cluster named fred will be done as root:
osh.remote.fred.user = 'root'
osh.remote['fred'].user = 'root'
This is useful in case a database or cluster name is known dynamically, or is not
a legal Python identifier.
osh sql mydb "select count(*) from request" $
mydb is the name of a database profile, specified in .oshrc, e.g.
osh.sql.mydb.dbtype = 'postgres'
osh.sql.mydb.host = 'localhost'
osh.sql.mydb.db = 'sales_db'
osh.sql.mydb.user = 'fred'
osh.sql.mydb.password = 'l3tme1n'
osh.sql = 'mydb'
If this is done, then the sql command can omit the database profile name, e.g.
osh sql "select count(*) from request" $
osh @fred [ sql familydb "select name, age from person" ] $
Each node of fred's cluster must
configure a database profile named familydb in its
.oshrc file.
On the local node (the one on which the above command is entered), the cluster fred must be configured, e.g.
osh.remote.fred.user = 'root'
osh.remote.fred.hosts = ['192.168.100.101',
'192.168.100.102',
'192.168.100.103']
This says that the cluster fred is accessed by root
and that the cluster consists of
nodes 192.168.100.101, 192.168.100.102
and 192.168.100.103.
When a remote command is run on a cluster, each row of output identifies the node that generated the output, e.g.
zack$ osh @fred [ sql familydb "select name, age from person" ] $
('192.168.111.101', 'hannah', 14)
('192.168.111.101', 'julia', 9)
('192.168.111.102', 'alexander', 15)
('192.168.111.102', 'nathan', 13)
('192.168.111.102', 'zoe', 11)
('192.168.111.103', 'danica', 1)
The hosts part of a cluster specification can also be done using a dict, in which
the key is a name for the node, and the value is the IP address, e.g.
osh.remote.fred.user = 'root'
osh.remote.fred.hosts = {'101': '192.168.100.101',
'102': '192.168.100.102',
'103': '192.168.100.103'}
The node names are used in command output in place of IP addresses, e.g.
zack$ osh @fred [ sql familydb "select name, age from person" ] $
('101', 'hannah', 14)
('101', 'julia', 9)
('102', 'alexander', 15)
('102', 'nathan', 13)
('102', 'zoe', 11)
('103', 'danica', 1)
These examples assume that each node of cluster fred has
a .oshrc file that configures a database profile
named familydb. It is also possible to configure database
access even when each node specifies a different database profile, e.g.
osh.remote.fred.user = 'root'
osh.remote.fred.hosts = {'101': {'host': '192.168.100.101', 'db_profile': 'db1'},
'102': {'host': '192.168.100.102', 'db_profile': 'db2'},
'103': {'host': '192.168.100.103', 'db_profile': 'db3'}}
With this configuration osh @fred [ sql "select ..." ] ...
accesses db1 on node 101, db2 on node 102, and db3 on
node 103.
The complete rules for selecting a database profile are as follows:
zack$ osh gen 10 ^ f 'x: (x**2, x**3)' $
The same computation can be done by writing a function to compute squares and cubes:
def square_and_cube(x):
return x**2, x**3
and putting this function definition in .oshrc. Then, the osh
command above can be rewritten as:
zack$ osh gen 10 ^ f 'x: square_and_cube(x)' $
osh.path = ['/usr/local/foobar']
or the osh interpreter will not find xyz when used in an osh command sequence.
The value of osh.path is a list so that custom commands can be placed in any number of directories.