Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Obsidian

A set of python scripts for starting and working with Java processes with complex configurations in production and development.

Installation:
python setup.py install
3 changes: 3 additions & 0 deletions cnf
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@ port = 9555
[hello]
class = Hello
classpath = java

[tomcat]
file = /opt/tomcat/logs/catalina.out
53 changes: 53 additions & 0 deletions obsidian/ocommon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/python

import os

# ./.obs.cnf and ~/.obs.cnf
project_conf_name = '.obs.cnf'
# /etc/obs.cnf
system_conf_name = '/etc/obsidian.cnf'


def find_conf_file():
conf_file = find_in_parent_dir(project_conf_name)
if(conf_file):
return conf_file

conf_file = os.path.expanduser(os.path.join('~', project_conf_name))
if os.path.exists(conf_file):
return open(conf_file, 'r')

if os.path.exists(system_conf_name):
return open(system_conf_name, 'r')

return None

def find_in_parent_dir(fname):
"""
Look in the current directory and then each parent
until root.
Inspired from 'findrepo()' in http://selenic.com/hg/file/2c9f5897d4b7/mercurial/cmdutil.py
"""
p = os.path.abspath(os.path.curdir)

while not os.path.exists(os.path.join(p, project_conf_name)):
oldp, p = p, os.path.dirname(p)
if p == oldp:
return None

return open(os.path.join(p, project_conf_name), 'r')

"""
Sets the environment variables specified in the following format:
ENV_NAME1=loc1, ENV_NAME2=loc2
"""
def set_env(env_str):
env_list = env_str.replace(" ","")
env_list = env_list.split(",")
for setting in env_list:
split = setting.split("=")
os.environ[split[0]] = os.path.expandvars(split[1])

class ConfigError(Exception):
def __init__(self, message):
self.message = message
85 changes: 29 additions & 56 deletions obsidian/ostart.py → scripts/ostart
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
#!/usr/bin/python

import os

# ./.obs.cnf and ~/.obs.cnf
project_conf_name = '.obs.cnf'
# /etc/obs.cnf
system_conf_name = '/etc/obsidian.cnf'

#!/usr/bin/env python
from ocommon import *
import ConfigParser
from ConfigParser import NoOptionError
import sys
import argparse
"""
Starts a Java program defined by file 'cnf'.
"""
def ostart():
import sys
import argparse
import ConfigParser

parser = argparse.ArgumentParser(description='Starts the process named by \'appid\'')
parser.add_argument('appid', metavar='appid', type=str)
parser.add_argument('--dry-run', '-d', action='store_true')
Expand Down Expand Up @@ -53,8 +46,14 @@ def ostart():
java_cmd = config.get(appid, 'java_home') + "/bin/java"
classpath = config.get(appid, 'classpath')
class_ = config.get(appid, 'class')

jvm_opts = config.get(appid, 'java_opts')

#for compatability with flint, try both java_opts
#and opts.
jvm_opts = ''
if config.has_option(appid, 'java_opts'):
jvm_opts = config.get(appid,'java_opts')
elif config.has_option(appid, 'opts'):
jvm_opts = config.get(appid, 'opts')
jvm_opts = jvm_opts.split(' ')

if config.has_option(appid, 'system_opts'):
Expand All @@ -63,63 +62,37 @@ def ostart():
else:
system_opts = []

if config.has_option(appid, 'conf'):
app_args = config.get(appid, 'conf')
if config.has_option(appid, 'args'):
app_args = config.get(appid, 'args')
app_args = app_args.split(' ')
else:
app_args = []

if config.has_option(appid, 'env'):
env = config.get(appid, 'env')
set_env(env)


c_args = [java_cmd]
c_args = []
c_args.append(java_cmd)
c_args.extend(jvm_opts)
c_args.append("-classpath")
c_args.append(classpath)
c_args.extend(system_opts)
c_args.append(class_)
c_args.extend(app_args)

#Expand environment variables
c_args = [os.path.expandvars(x) for x in c_args if x]
#print " ".join(args)
if args.dry_run:
print " ".join(c_args)
return

os.execv(java_cmd, c_args)

def find_conf_file():
conf_file = find_in_parent_dir(project_conf_name)
if(conf_file):
return conf_file

conf_file = os.path.expanduser(os.path.join('~', project_conf_name))
if os.path.exists(conf_file):
return open(conf_file, 'r')

if os.path.exists(system_conf_name):
return open(system_conf_name, 'r')

return None

def find_in_parent_dir(fname):
"""
Look in the current directory and then each parent
until root.
Inspired from 'findrepo()' in http://selenic.com/hg/file/2c9f5897d4b7/mercurial/cmdutil.py
"""
p = os.path.abspath(os.path.curdir)

while not os.path.exists(os.path.join(p, project_conf_name)):
oldp, p = p, os.path.dirname(p)
if p == oldp:
return None

return open(os.path.join(p, project_conf_name), 'r')

class ConfigError(Exception):
def __init__(self, msg):
self.msg = msg
os.execv(c_args[0], c_args)

if __name__ == "__main__":
try:
ostart()
except ConfigError as e:
print e.msg

print e.message
except NoOptionError as e:
print e.message
79 changes: 79 additions & 0 deletions scripts/otail
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/usr/bin/env python
from ocommon import *
import ConfigParser
from ConfigParser import NoOptionError
import sys
import argparse
"""
Starts a Java program defined by file 'cnf'.
"""
def otail():
parser = argparse.ArgumentParser(description='Starts the process named by \'appid\'')
parser.add_argument('appid', metavar='appid', type=str)
parser.add_argument('--dry-run', '-d', action='store_true')
parser.add_argument('--file', '-f', dest='conf_file', type=str)

args = parser.parse_args()
appid = args.appid
conf_file = args.conf_file

if conf_file:
conf_file = open(conf_file, 'r')
else:
conf_file = find_conf_file()

if not conf_file:
raise ConfigError('could not find config file')

if appid:
print "tailing [%s]" % appid
else:
print "appid required"
exit(1)

config = ConfigParser.ConfigParser()
config.readfp(conf_file)

# get the config file defaults out first, and recreate
# the config, providing those
defaults = dict(config.items('default'))
config = ConfigParser.ConfigParser(defaults)

#readfp reads the whole file, must rewind
conf_file.seek(0)
config.readfp(conf_file)

if config.has_option(appid, 'env'):
env = config.get(appid, 'env')
set_env(env)
tailFile = ''
if config.has_option(appid, 'file'):
tailFile = config.get(appid, 'file')
else:
print "Missing file, exiting"
return

lines = '25'
if config.has_option(appid, 'lines'):
lines = config.get(appid, 'lines')

c_args = ['/usr/bin/tail']
c_args.append('-n')
c_args.append(lines)
c_args.append('-f')
c_args.append(tailFile)
#Expand environment variables
c_args = [os.path.expandvars(x) for x in c_args if x]
#print " ".join(args)
if args.dry_run:
print " ".join(c_args)
return
os.execv(c_args[0], c_args)

if __name__ == "__main__":
try:
otail()
except ConfigError as e:
print e.message
except NoOptionError as e:
print e.message
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
import sys

sys.path.append('obsidian')
import ostart
import ocommon

setup(name='ostart',
version='0.1',
author='Adam Lehenbauer',
description='Start and manage Java processes declaratively',
package_dir={'': 'obsidian'},
py_modules=['ostart']
py_modules=['ocommon'],
scripts=['scripts/ostart', 'scripts/otail']
)