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**3and 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.