PK 'g@ patched_war.pyimport sys
import os, os.path
import re
import fileinput
import shutil
import zipfile
#patched play war command
def package_as_war(app, env, war_path, war_zip_path, war_exclusion_list = None):
if war_exclusion_list is None:
war_exclusion_list = []
app.check()
modules = app.modules()
classpath = app.getClasspath()
print "~ patched war starting"
if not war_path:
print "~ Oops. Please specify a path where to generate the WAR, using the -o or --output option"
print "~"
sys.exit(-1)
if os.path.exists(war_path) and not os.path.exists(os.path.join(war_path, 'WEB-INF')):
print "~ Oops. The destination path already exists but does not seem to host a valid WAR structure"
print "~"
sys.exit(-1)
if isParentOf(app.path, war_path) and not isExcluded(war_path, war_exclusion_list):
print "~ Oops. Please specify a destination directory outside of the application"
print "~"
sys.exit(-1)
print "~ Packaging current version of the framework and the application to %s ..." % (os.path.normpath(war_path))
if os.path.exists(war_path): shutil.rmtree(war_path)
if os.path.exists(os.path.join(app.path, 'war')):
copy_directory(os.path.join(app.path, 'war'), war_path)
else:
os.makedirs(war_path)
if not os.path.exists(os.path.join(war_path, 'WEB-INF')): os.mkdir(os.path.join(war_path, 'WEB-INF'))
if not os.path.exists(os.path.join(war_path, 'WEB-INF/web.xml')):
shutil.copyfile(os.path.join(env["basedir"], 'resources/war/web.xml'), os.path.join(war_path, 'WEB-INF/web.xml'))
application_name = app.readConf('application.name')
replaceAll(os.path.join(war_path, 'WEB-INF/web.xml'), r'%APPLICATION_NAME%', application_name)
if env["id"] is not "":
replaceAll(os.path.join(war_path, 'WEB-INF/web.xml'), r'%PLAY_ID%', env["id"])
else:
replaceAll(os.path.join(war_path, 'WEB-INF/web.xml'), r'%PLAY_ID%', 'war')
if os.path.exists(os.path.join(war_path, 'WEB-INF/application')): shutil.rmtree(os.path.join(war_path, 'WEB-INF/application'))
copy_directory(app.path, os.path.join(war_path, 'WEB-INF/application'), war_exclusion_list)
if os.path.exists(os.path.join(war_path, 'WEB-INF/application/war')):
shutil.rmtree(os.path.join(war_path, 'WEB-INF/application/war'))
if os.path.exists(os.path.join(war_path, 'WEB-INF/application/logs')):
shutil.rmtree(os.path.join(war_path, 'WEB-INF/application/logs'))
if os.path.exists(os.path.join(war_path, 'WEB-INF/application/tmp')):
shutil.rmtree(os.path.join(war_path, 'WEB-INF/application/tmp'))
if os.path.exists(os.path.join(war_path, 'WEB-INF/application/modules')):
shutil.rmtree(os.path.join(war_path, 'WEB-INF/application/modules'))
copy_directory(os.path.join(app.path, 'conf'), os.path.join(war_path, 'WEB-INF/classes'))
if os.path.exists(os.path.join(war_path, 'WEB-INF/lib')): shutil.rmtree(os.path.join(war_path, 'WEB-INF/lib'))
os.mkdir(os.path.join(war_path, 'WEB-INF/lib'))
for jar in classpath:
if jar.endswith('.jar') and jar.find('provided-') == -1:
shutil.copyfile(jar, os.path.join(war_path, 'WEB-INF/lib/%s' % os.path.split(jar)[1]))
if os.path.exists(os.path.join(war_path, 'WEB-INF/framework')): shutil.rmtree(os.path.join(war_path, 'WEB-INF/framework'))
os.mkdir(os.path.join(war_path, 'WEB-INF/framework'))
copy_directory(os.path.join(env["basedir"], 'framework/templates'), os.path.join(war_path, 'WEB-INF/framework/templates'))
# modules
for module in modules:
to = os.path.join(war_path, 'WEB-INF/application/modules/%s' % os.path.basename(module))
copy_directory(module, to)
if os.path.exists(os.path.join(to, 'src')):
shutil.rmtree(os.path.join(to, 'src'))
if os.path.exists(os.path.join(to, 'dist')):
shutil.rmtree(os.path.join(to, 'dist'))
if os.path.exists(os.path.join(to, 'samples-and-tests')):
shutil.rmtree(os.path.join(to, 'samples-and-tests'))
if os.path.exists(os.path.join(to, 'build.xml')):
os.remove(os.path.join(to, 'build.xml'))
if os.path.exists(os.path.join(to, 'commands.py')):
os.remove(os.path.join(to, 'commands.py'))
if os.path.exists(os.path.join(to, 'lib')):
shutil.rmtree(os.path.join(to, 'lib'))
if os.path.exists(os.path.join(to, 'nbproject')):
shutil.rmtree(os.path.join(to, 'nbproject'))
if os.path.exists(os.path.join(to, 'documentation')):
shutil.rmtree(os.path.join(to, 'documentation'))
if not os.path.exists(os.path.join(war_path, 'WEB-INF/resources')): os.mkdir(os.path.join(war_path, 'WEB-INF/resources'))
shutil.copyfile(os.path.join(env["basedir"], 'resources/messages'), os.path.join(war_path, 'WEB-INF/resources/messages'))
if war_zip_path:
print "~ Creating zipped archive to %s ..." % (os.path.normpath(war_zip_path))
if os.path.exists(war_zip_path):
os.remove(war_zip_path)
zip = zipfile.ZipFile(war_zip_path, 'w', zipfile.ZIP_STORED)
dist_dir = os.path.join(app.path, 'dist')
for (dirpath, dirnames, filenames) in os.walk(war_path):
if dirpath == dist_dir:
continue
if dirpath.find('/.') > -1:
continue
for file in filenames:
if file.find('~') > -1 or file.startswith('.'):
continue
zip.write(os.path.join(dirpath, file), os.path.join(dirpath[len(war_path):], file))
zip.close()
def replaceAll(file, searchExp, replaceExp, regexp=False):
if not regexp:
replaceExp = replaceExp.replace('\\', '\\\\')
searchExp = searchExp.replace('$', '\\$')
searchExp = searchExp.replace('{', '\\{')
searchExp = searchExp.replace('}', '\\}')
searchExp = searchExp.replace('.', '\\.')
for line in fileinput.input(file, inplace=1):
line = re.sub(searchExp, replaceExp, line)
sys.stdout.write(line)
# Copy a directory, skipping dot-files
def copy_directory(source, target, exclude = None):
if exclude is None:
exclude = []
skip = None
if not os.path.exists(target):
os.makedirs(target)
for root, dirs, files in os.walk(source):
path_from_source = root[len(source):]
# Ignore path containing '.' in path
# But keep those with relative path '..'
if re.search(r'/\.[^\.]|\\\.[^\.]', path_from_source):
continue
for file in files:
if root.find('/.') > -1 or root.find('\\.') > -1:
continue
if file.find('~') == 0 or file.startswith('.'):
continue
# Loop to detect files to exclude (coming from exclude list)
# Search is done only on path for the moment
skip = 0
for exclusion in exclude:
if root.find(exclusion) > -1:
skip = 1
# Skipping the file if exclusion has been found
if skip == 1:
continue
from_ = os.path.join(root, file)
to_ = from_.replace(source, target, 1)
to_directory = os.path.split(to_)[0]
if not os.path.exists(to_directory):
os.makedirs(to_directory)
shutil.copyfile(from_, to_)
def isParentOf(path1, path2):
relpath = os.path.relpath(path1, path2)
sep = os.sep
if sep == '\\':
sep = '\\\\'
ptn = '^\.\.(' + sep + '\.\.)*$'
return re.match(ptn, relpath) != None
def isExcluded(path, exclusion_list = None):
if exclusion_list is None: return False
for exclusion in exclusion_list:
if isParentOf(exclusion, path): return True
return False
PK U[:@G G build.xml
PK A@m
appinfo.pyimport sys
import os
#add current dir to syspath to import local modules
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
#local imports
from utils import *
def appsinfo(options):
info_cmd = ["rhc-domain-info", "--apps", "--rhlogin=%s" % options.rhlogin]
if options.password != '': info_cmd.append("--password=%s" % options.password)
out, err, ret = shellexecute( info_cmd, msg="Contacting openshift...", debug=options.debug, exit_on_error=True )
return parseuserinfo(out)
def appinfo(options):
apps = appsinfo(options)
if not apps.has_key(options.app): return None
return apps[options.app]
def parseuserinfo(data):
apps, app = {}, None
lines = data.splitlines()
for line in lines:
if ignoreline(line): continue
if isApplication(line):
if app != None: apps[app.name] = app
app = openshift_application(line)
else:
if line.find(":") != -1:
line = line.strip().lower()
key, value = line.split(":", 1)
if key == "creation": app.creation = value.strip()
if key == "framework": app.framework = value.strip()
if key == "git url": app.repo = value.strip()
if key == "public url": app.url = value.strip()
#add last application
if app != None: apps[app.name] = app
return apps
def isApplication(line):
if ignoreline(line): return False
return not line.startswith(" ")
def ignoreline(line):
return line == '' or startswithany(line, ["Contacting", "Application Info", "=="])
def startswithany(text, prefixes):
for prefix in prefixes:
if text.startswith(prefix):
return True
return False
class openshift_application:
def __init__(self, name='', creation='', framework='', repo='', url=''):
self.name, self.creation, self.framework, self.repo, self.url = \
name, creation, framework, repo, url
def __repr__(self):
return 'name: %s, creation: %s, framework: %s, repo: %s, url: %s' % \
(self.name, self.creation, self.framework, self.repo, self.url)
PK Ҷ;@˞' ' LICENSE.txt
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
PK =@Hr+ + readme.textileh1. Openshift Module for Play! Framework Applications
Openshift is Red Hat's free, auto-scaling, cloud-based platform-as-a-service for Java, Perl, PHP, Python, and Ruby applications.
With this module, you'll be able to easily deploy and manage your play application on Red Hat's cloud platform.
The module does not depend on any external Java libray. You'll just need an openshift account, git and openshift command line tools installed on your workstation.
Source code is available at https://github.com/opensas/openshift
Written by Sebastián Scarano (@develsas)
h2. Licence
Openshift module for Play Framework is distributed under the "Apache 2 licence":http://www.apache.org/licenses/LICENSE-2.0.html.
PK f@ib\ utils.pyimport sys
import subprocess
import os
import shutil
import time
import re
def message(lines):
if isinstance(lines, str): lines = [lines]
#print lines
for line in lines: print "~ " + line.rstrip('\n')
print "~"
def error_message(err):
message(err)
sys.exit(-1)
def shellexecute(params, output=False, location=None, debug=False, msg=None, err_msg=None,
raw_error=False, exit_on_error=False):
#development
#debug = True
std_out, std_err, ret = '', '', -1
err = ''
if msg != None: message(msg)
if debug: message("about to execute: '" + " ".join(params) + "'")
try:
if location != None:
if not os.path.exists(location):
err = "directory '%s' does not exists" % location
return out, err
save_dir = os.getcwd()
os.chdir(location)
if output:
ret = subprocess.call(params)
else:
proc = subprocess.Popen(params, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(std_out, std_err) = proc.communicate()
ret = proc.returncode
except Exception as e:
std_err = "Error %s (%s)" % ( str(e), str(sys.exc_info()[0]) )
out = std_out
#there was an error
if std_err != '' or ret !=0:
if std_err != '':
err = [std_err]
else:
err = []
if not raw_error: err.insert(0, "error executing: %s (return code %s)" % (" ".join(params), ret ) )
if location != None: os.chdir(save_dir)
if debug:
print "out: %s" % out
print "err: %s" % err
print "ret: %s" % ret
if exit_on_error and (std_err != '' or ret != 0):
if out != '': err.insert(0, out)
if err_msg != None:
err.insert(0, err_msg)
else:
if msg != None: err.insert(0, "ERROR - error " + lowerFirst(msg))
error_message(err)
return out, err, ret
#returns True if text has at least a char in uppercase
def hasUpperChar(text):
return (re.match("^.*[A-Z].*$", text) != None)
def lowerFirst(text):
return text[:1].lower() + text[1:]
def elapsed(start):
return format_time(time.time() - start)
def format_time(seconds):
return "%d:%02d:%02d.%03d" % \
reduce(lambda ll,b : divmod(ll[0],b) + ll[1:],
[(seconds*1000,),1000,60,60])
def is_array(var):
return isinstance(var, (list, tuple))
def remove_folder(folder, silent=False):
#delete deploy_folder folder to start it all over again
if os.path.exists(folder):
if not silent: message( "removing %s folder" % folder)
shutil.rmtree(folder)
if os.path.exists(folder):
error_message("ERROR - '%s' folder already exists and could not be deleted\nremove it and try again" % folder)
def remove_file(file, silent=False):
#delete deploy_folder folder to start it all over again
if os.path.exists(file):
if not silent: message( "removing %s file" % file)
os.remove(file)
if os.path.exists(file):
error_message("ERROR - '%s' file could not be deleted\nremove it and try again" % file)
def remove_fsobject(fs, silent=False):
if os.path.isfile(fs): remove_file(fs, silent)
if os.path.isdir(fs): remove_folder(fs, silent)
def remove_all(path, silent=False, exclude=[]):
if not os.path.isdir(path): return "err: %s path not found" % path
for file in os.listdir(path):
if file in exclude:
if not silent: message( "skipping %s" % file)
else:
remove_fsobject(os.path.join(path,file), silent)
return ""
def move_all(source, target):
if not os.path.isdir(source): return "err: source path %s not found" % source
if not os.path.isdir(target): return "err: target path %s not found" % target
for file in os.listdir(source):
shutil.move(os.path.join(source,file), os.path.join(target,file))
return ""
def create_folder(folder, silent=False):
remove_folder(folder, silent=True)
os.mkdir(folder)
if not os.path.exists(folder):
if not silent: message( "creating %s folder" % folder)
error_message("ERROR - '%s' deployment folder could not be created" % folder)
PK tg@BR~i ~i commands.pyimport sys
import re
import os
import shutil
import webbrowser
import getpass
from datetime import datetime
from optparse import OptionParser
import play.commands.precompile
#add current dir to syspath to import local modules
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
#local imports
from utils import *
from appinfo import appinfo
import patched_war
MODULE = 'openshift'
# Commands that are specific to your module
COMMANDS = [
"rhc:test", "rhc:hello", "rhc:chk", "rhc:fetch", "rhc:deploy", "rhc:destroy", "rhc:logs", "rhc:info", "rhc:open"
]
HELP = {
'rhc:chk': 'Check openshift prerequisites, application and git repo.',
'rhc:fetch': 'Fetches application from remote openshift repository.',
'rhc:deploy': 'Deploys application on openshift.',
'rhc:destroy': 'Destroys application on openshift.',
'rhc:logs': 'Show the logs of the application on openshift.',
'rhc:info': 'Displays information about user and configured applications.',
'rhc:open': 'Opens the application deployed on openshift in web browser.'
}
class OpenshiftOptionParser(OptionParser):
def error(self, msg):
pass
def execute(**kargs):
command = kargs.get("command")
app = kargs.get("app")
args = kargs.get("args")
env = kargs.get("env")
command = command[command.index(":")+1:]
parser = OpenshiftOptionParser()
parser.add_option("-a", "--app", default='', dest="app", help="Application name (alphanumeric) (required)")
parser.add_option("-s", "--subdomain", default='', dest="subdomain", help="Application subdomain, root by default (alphanumeric) (optional)")
parser.add_option("-l", "--rhlogin", default='', dest="rhlogin", help="Red Hat login (RHN or OpenShift login with OpenShift Express access)")
parser.add_option("-p", "--password", default='', dest="password", help="RHLogin password (optional, will prompt)")
parser.add_option("-d", "--debug", default=False, dest="debug", action="store_true", help="Print Debug info")
parser.add_option("-m", "--message", default='', dest="message", help="Commit message")
parser.add_option("", "--timeout", default='', dest="timeout", help="Timeout, in seconds, for connection")
parser.add_option("-o", "--open", default=False, dest="open", action="store_true", help="Open site after deploying")
parser.add_option("-b", "--bypass", default=False, dest="bypass", action="store_true", help="Bypass questions, asume yes.")
options, args = parser.parse_args(args)
if options.app == '': options.app = app.readConf('openshift.application.name')
if options.app == '': options.app = app.readConf('application.name')
options.app = check_appname(options.app)
if options.subdomain == '': options.subdomain = app.readConf('openshift.application.subdomain')
if options.rhlogin == '': options.rhlogin = app.readConf('openshift.rhlogin')
if options.rhlogin == '':
message("You can also provide your openshift login using the -l RHLOGIN command line option or setting openshift.rhlogin in application.conf file.")
options.rhlogin = raw_input("~ Enter your openshift login: ")
if options.rhlogin == '': error_message("ERROR - No openshift login specified.")
message("")
if options.password == '': options.password = app.readConf('openshift.password')
if options.password == '':
message("You can also provide your openshift password using the -p PASSWORD command line option or setting openshift.password in application.conf file.")
options.password = getpass.getpass("~ Enter your openshift password: ")
if options.password == '': error_message("ERROR - No openshift login specified.")
message("")
if options.debug == False: options.debug = ( app.readConf('openshift.debug') in [True, '1', 'y', 'on', 'yes', 'enabled'] )
if options.timeout == '': options.timeout = app.readConf('openshift.timeout')
if options.timeout == '': del options.timeout
app.check()
#test: force use-local
options.use_remote = False
options.use_local = True
check_windows()
if command == "hello": print "~ Hello from openshift module"
if command == "test": openshift_test(args, app, env, options)
if command == "chk": openshift_check(app, options)
if command == "fetch": openshift_fetch(args, app, env, options)
if command == "deploy": openshift_deploy(args, app, env, options)
if command == "destroy": openshift_destroy(app, options)
if command == "logs": openshift_logs(options)
if command == "info": openshift_info(options)
if command == "open": openshift_open(options)
# This will be executed before any command (new, run...)
def before(**kargs):
command = kargs.get("command")
app = kargs.get("app")
args = kargs.get("args")
env = kargs.get("env")
# This will be executed after any command (new, run...)
def after(**kargs):
command = kargs.get("command")
app = kargs.get("app")
args = kargs.get("args")
env = kargs.get("env")
if command == "new":
pass
def openshift_test(args, app, env, options):
print "testing 1,2,3"
def openshift_fetch(args, app, env, options):
openshift_app = check_app(app, options)
if not options.bypass:
message( [
"!!!! WARNING !!!! WARNING !!!! WARNING !!!!",
"You are about to destroy your local application and local git repository",
"and we will clone your openshift '%s' git repository" % options.app,
"This is NOT reversible, all remote data for this application will be removed."
] )
answer = raw_input("~ Do you want to destroy your local application (y/n): [%s] " % "no")
answer = answer.strip().lower()
if answer not in ['yes', 'y']:
error_message("openshift application fetch canceled")
try:
app_folder = app.path
#clone the repo into a tmp folder
tmp_folder = os.path.join(app_folder, '.tmp')
create_folder(tmp_folder)
shellexecute( ['git', 'clone', openshift_app.repo, '--origin', 'openshift'], location=tmp_folder, debug=options.debug, exit_on_error=True,
msg="Clonning openshift repo at (%s)" % tmp_folder, output=True )
cloned_app_folder = os.path.join(tmp_folder, openshift_app.name)
message("removing local app at %s" % app_folder)
remove_all(app_folder, exclude=['.tmp'], silent=True)
move_all(cloned_app_folder, app_folder)
message("application succesfully fetched")
finally:
remove_folder(tmp_folder)
def openshift_deploy(args, app, env, options, openshift_app=None):
start = time.time()
if openshift_app == None: openshift_app = check_app(app, options) # check remote repo
if openshift_app == None: error_message("ERROR - '%s' application not found at openshift" % options.app)
check_local_repo(app, openshift_app, options) # check local repo
commit_local_repo(app, options)
merge_repos(app, openshift_app, options) # merge local and remote repo
app_folder = app.path
deploy_folder = os.path.join(app_folder, 'deployments')
create_folder(deploy_folder)
if options.subdomain == '':
war_file = 'ROOT.war'
else:
war_file = options.subdomain + '.war'
date = str(datetime.now())
dodeploy_filename = os.path.join(deploy_folder, war_file + '.dodeploy')
dodeploy_file = open(dodeploy_filename, 'w')
dodeploy_file.write(date)
dodeploy_file.close()
war_path = os.path.join(deploy_folder, war_file)
war_path = os.path.normpath(os.path.abspath(war_path))
# Precompile first
play.commands.precompile.execute(command='war', app=app, args=args, env=env)
start_war = time.time()
patched_war.package_as_war(app, env, war_path, war_zip_path=None, war_exclusion_list=[deploy_folder])
if not os.path.exists(war_path):
error_message("ERROR - '%s' exploded war folder could not be created" % war_path)
message([ "", "war successfully generated to %s in %s" % ( war_path, elapsed(start) ) ])
precompiled_folder = os.path.join(app_folder, 'precompiled')
remove_folder(precompiled_folder)
#add files
shellexecute( ['git', 'add', 'deployments'], location=app_folder, debug=options.debug, exit_on_error=True,
msg="Adding deployments folder index (%s)" % deploy_folder, output=True )
commit_message = options.message
commit_message = 'deployed at ' + date
if options.message != '': commit_message += " (%s)" % options.message
commit_message = '"' + commit_message + '"'
shellexecute( ['git', 'commit', '-m', commit_message], location=app_folder,
msg="Commiting deployment", debug=options.debug, output=True, exit_on_error=True )
shellexecute( ['git', 'push', 'openshift', '--force'], location=app_folder,
msg="Pushing changes to openshift", debug=options.debug, output=True, exit_on_error=True)
message([ "", "app successfully deployed in %s" % elapsed(start) ])
if options.open == True:
message([
"waiting 10 seconds before opening application, if it's not ready, just give openshift some time and press F5",
"if it's still not working try with 'play rhc:logs' to see what's going on"
])
time.sleep(10)
openshift_open(options, openshift_app)
else:
message("issue play rhc:open to see your application running on openshift")
def openshift_open(options, openshift_app=None):
if openshift_app == None: openshift_app = appinfo(options)
if openshift_app == None:
error_message("the application '%s' does not exist for login '%s' in openshift" % (options.app, options.rhlogin))
url = openshift_app.url
if options.subdomain != '': url = url.rstrip('/') + '/' + options.subdomain.strip('/')
webbrowser.open(url, new=2)
def openshift_logs(options):
create_cmd = ["rhc-tail-files"]
if options.debug == True: create_cmd.append("-d")
for item in ["app", "rhlogin", "password", "timeout"]:
if hasattr(options, item) and eval('options.%s' % item) != None and eval('options.%s' % item) != '':
create_cmd.append("--%s=%s" % (item, eval('options.%s' % item)))
out, err, ret = shellexecute( create_cmd, output=True, debug=options.debug,
msg="Running rhc-tail-files", exit_on_error=False )
#will always return error 255, because user has to stop process
if err != '' and ret != 255:
err.insert(0, "Failed to execute rhc-tail-files, check that rhc-tail-files is installed.")
error_message(err)
def openshift_destroy(app, options):
start = time.time()
if not options.bypass:
message( [
"!!!! WARNING !!!! WARNING !!!! WARNING !!!!",
"You are about to destroy the '%s' application." % options.app,
"",
"This is NOT reversible, all remote data for this application will be removed."
] )
answer = raw_input("~ Do you want to destroy this application (y/n): [%s] " % "no")
answer = answer.strip().lower()
if answer not in ['yes', 'y']:
error_message("the application '%s' was not destroyed" % options.app)
app_folder = app.path
openshift_app = appinfo(options)
if openshift_app != None:
destroy_cmd = ["rhc-ctl-app"]
if options.debug == True: destroy_cmd.append("--debug")
destroy_cmd.append('--command=destroy')
destroy_cmd.append('--bypass')
for item in ["app", "rhlogin", "password", "timeout"]:
if hasattr(options, item) and eval('options.%s' % item) != None and eval('options.%s' % item) != '':
destroy_cmd.append("--%s=%s" % (item, eval('options.%s' % item)))
shellexecute( destroy_cmd, output=True, debug=options.debug,
msg="Destroy application %s" % options.app, exit_on_error=True)
else:
message( "application %s does not exist on openshit. skipping destroy." % options.app )
#delete local files
message("deleting .git, deployments, .openshift folders and .gitignore file at %s" % app_folder)
remove_folder(os.path.join(app_folder, '.git'))
remove_folder(os.path.join(app_folder, 'deployments'))
remove_folder(os.path.join(app_folder, '.openshift'))
remove_file(os.path.join(app_folder, '.gitignore'))
message([ "app successfully removed from openshift in %s" % elapsed(start) ])
def openshift_check(app, options):
check_java(options)
check_git(options)
check_ruby(options)
check_rhc(options)
options.app = check_appname(options.app)
openshift_app = check_app(app, options)
check_local_repo(app, openshift_app, options)
check_rhc_chk(options)
def check_windows():
#not supported on windows
if os.name == 'nt':
error_message([
"ERROR - Windows OS is not supported in the current version of openshift module",
"(Reason: no git support in standard windows shell.)"
])
def check_java(options):
out, err, ret = shellexecute(["java", "-version"], debug=options.debug, raw_error=True, exit_on_error=False)
#java -version outputs to stderr
if ret != 0:
err.insert(0, "ERROR - Failed to execute 'java -version', check that java 1.6.x or lower is installed.")
error_message(err)
java_version = parse_java_version(err[0].splitlines())
if java_version == '':
err = "ERROR - Could not get java version executing 'java -version', check that java 1.6.x or lower is installed."
error_message(err)
if not (java_version < "1.7"):
err = "ERROR - Java %s found. Java 1.7 or higher is not supported on openshift yet, check that java 1.6.x or lower is installed." % java_version
error_message(err)
message("OK! - checked java version: %s" % java_version)
def parse_java_version(lines):
for line in lines:
match = re.search("1\.[0-9]\.[0-9_]+", line)
if match != None: break
if match == None: return ""
return match.group(0)
def check_git(options):
out, err, ret = shellexecute(["git", "version"], debug=options.debug,
err_msg="Failed to execute git, check that git is installed.", exit_on_error=True )
message("OK! - checked git version: %s" % out)
def check_ruby(options):
out, err, ret = shellexecute(["ruby", "-v"], debug=options.debug,
err_msg="Failed to execute ruby, check that ruby is installed.", exit_on_error=True )
message("OK! - checked ruby version: %s" % out)
def check_rhc(options):
out, err, ret = shellexecute(["gem", "list", "rhc", "--local"], debug=options.debug,
err_msg="Failed to execute gem list rhc, check that gem is installed.", exit_on_error=True )
#0.84.15 or higher
if "rhc " not in out:
error_message("rhc ruby gem not found. Try installing it with 'gem install rhc'")
versions = re.findall("\d{1,2}\.\d{1,2}\.\d{1,2}",out)
if len(versions) == 0:
error_message("no version of rhc ruby gem found. Try installing it with 'gem install rhc'")
#check current version
current = versions[0]
if current < "0.84.15":
error_message( [
"the latest rhc ruby gem version found on your system is %s" % current,
"openshift module requires rhc ruby gem 0.8.15 or higher, you can upgrade it running 'gem update rhc'"
] )
message("OK! - checked rhc version: %s" % out)
if len(versions) > 1:
message( [
"Tip: you have %s versions of rhc ruby gem installed." % len(versions),
"You can remove old versions running 'gem cleanup rhc'."
] )
def check_rhc_chk(options):
check_cmd = ["rhc-chk"]
if options.debug == True: create_cmd.append("-d")
for item in ["rhlogin", "password", "timeout"]:
if hasattr(options, item) and eval('options.%s' % item) != None and eval('options.%s' % item) != '':
check_cmd.append("--%s=%s" % (item, eval('options.%s' % item)))
shellexecute(check_cmd, output=True, debug=options.debug,
msg="Running rhc-chk", err_msg="Failed to execute rhc-chk, check that rhc-chk is installed.", exit_on_error=True)
def check_appname(appname):
if re.match("^[a-zA-Z0-9]+$", appname) == None:
error_message( [
"ERROR - Invalid application name: '%s'. It should only contain alphanumeric characters" % appname,
"You can change application's name from the 'application.name' setting " +
"or specify a custom name for openshift application adding an 'openshift.application.name' setting " +
"in your application.conf file."
] )
if hasUpperChar(appname):
appname = appname.lower()
message("WARNING! - application name should be lowercase, setting appname to '%s'" % appname)
message("OK! - checked application name: %s - OK!" % appname)
return appname
#
# Verifies that application exists at openshift, and returns it's information
#
# If it doesn't exist, it asks the user to create it
#
def check_app(app, options):
openshift_app = appinfo(options)
if openshift_app == None:
if options.bypass == True:
answer = 'yes'
else:
message("the application '%s' does not exist for login '%s' in openshift" % (options.app, options.rhlogin))
answer = raw_input("~ Do you want to create it? [%s] " % "yes")
answer = answer.strip().lower()
if answer in ['yes', 'y', '']:
openshift_app = create_app(app, options)
else:
error_message("the application '%s' does not exist for login '%s' in openshift" % (options.app, options.rhlogin))
message("OK! - checked application: %s at %s for user %s!" % (openshift_app.name, openshift_app.url, options.rhlogin))
return openshift_app
def check_local_repo(app, openshift_app, options):
app_folder = app.path
git_folder = os.path.join(app_folder, '.git')
if not os.path.exists(git_folder):
create_local_repo(app, openshift_app, options, confirmMessage="!!! - '%s' does not seem to be a valid git repository, .git folder not found." % app_folder )
out, err, ret = shellexecute( ['git', 'status'], location=app_folder, debug=options.debug, exit_on_error=False)
if err != '' or ret != 0:
create_local_repo(app, openshift_app, options, confirmMessage="ERROR - folder '%s' exists but does not seem to be a valid git repo." % git_folder )
out, err, ret = shellexecute( ['git', 'remote', '-v'], location=app_folder, debug=options.debug, exit_on_error=False)
if err != '' or ret != 0:
create_local_repo(app, openshift_app, options, confirmMessage="ERROR - error fetching folder remotes for '%s' git repository" )
remote_found = False
remotes = out.splitlines()
for remote in remotes:
values = remote.split(None, 2)
#check if the repo is somewhere listed
for value in values:
if value.strip().lower() == openshift_app.repo:
remote_found = True
break
if not remote_found:
create_local_repo(app, openshift_app, options,
confirmMessage="ERROR - could not found remote '%s' in '%s' git repo" % (openshift_app.repo, git_folder) )
#create .gitignore file
gitignore_dest = os.path.join(app_folder, '.gitignore')
if not os.path.exists(gitignore_dest):
gitignore_src = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'resources', 'gitignore')
shutil.copyfile(gitignore_src, gitignore_dest)
if not os.path.exists(gitignore_dest):
error_message("Could not create .gitignore file at %s" % gitignore_dest)
message("OK! - folder '%s' exists and seems to be a valid git repo" % git_folder)
# by default, it asumes the application doesn't exist
# if check_app == True -> it will contact openshift to check for the existence of the app
def create_app(app, options, check_app = False):
openshift_app = None
if check_app:
openshift_app = appinfo(options)
#create openshift application
if openshift_app == None:
tmp_folder = os.path.join(app.path, '.tmp')
try:
create_folder(tmp_folder)
start = time.time()
create_cmd = ["rhc-create-app", "--type", 'jbossas-7']
if options.debug == True: create_cmd.append("-d")
for item in ["app", "rhlogin", "password", "timeout"]:
if hasattr(options, item) and eval('options.%s' % item) != None and eval('options.%s' % item) != '':
create_cmd.append("--%s=%s" % (item, eval('options.%s' % item)))
shellexecute( create_cmd, location=tmp_folder, debug=options.debug, output=True,
msg="Creating %s application at openshift" % options.app, exit_on_error=True )
openshift_app = appinfo(options)
if openshift_app == None: error_message("Failed to create app, check that rhc-create-app is installed.")
app_folder = os.path.join(tmp_folder, options.app)
local_repo_remove_default_app(app_folder, options)
message( "Application %s successfully created at %s in %s" % (options.app, app_folder, elapsed(start)) )
finally:
remove_folder(tmp_folder, silent=True)
return openshift_app
def create_local_repo(app, openshift_app, options, confirmMessage=''):
app_folder = app.path
if openshift_app == None:
error_message("Application not found at openshift.")
if confirmMessage != '' and not options.bypass:
message(confirmMessage)
answer = raw_input("~ Do you want to create your local repo and merge openshift application? [%s] " % "yes")
answer = answer.strip().lower()
if answer not in ['yes', 'y', '']:
error_message("the local repo is not correct")
#init repo
shellexecute( ['git', 'init'], location=app_folder, debug=options.debug,
msg="Creating git repo at '%s'" % app_folder, exit_on_error=True )
#add remote
shellexecute( ['git', 'remote', 'add', 'openshift', openshift_app.repo], location=app_folder, debug=options.debug,
msg="Adding %s as a remote repo to '%s'" % (openshift_app.repo, app_folder), exit_on_error=True )
#just in case the default openshift app is there
local_repo_remove_default_app(app_folder, options)
message("Local git repository at %s successfully created" % app.path)
def commit_local_repo(app, options):
app_folder = app.path
#add files
shellexecute( ['git', 'add', '-A'], location=app_folder, debug=options.debug, exit_on_error=True,
msg="Adding changes to index", output=True )
#add files
out, err, ret = shellexecute( ['git', 'status'], location=app_folder, debug=options.debug, exit_on_error=True,
msg="Checking for files to commit", output=False )
#nothing to do, already committed
if "nothing to commit" in out: return
date = str(datetime.now())
commit_message = options.message
if commit_message == '': commit_message = 'commiting at ' + date
commit_message = '"' + commit_message + '"'
shellexecute( ['git', 'commit', '-m', commit_message], location=app_folder,
msg="Commiting changes", debug=options.debug, output=True, exit_on_error=True )
def merge_repos(app, openshift_app, options):
#fetch remote
shellexecute( ['git', 'fetch', 'openshift'], location=app.path, debug=options.debug,
msg="fetching from openshift remote (%s) repo" % openshift_app.repo, output=True, exit_on_error=True )
conflict = False
use_local = options.use_local
use_remote = options.use_remote
# no strategy specified for solving conflicts
if not use_local and not use_remote:
#merge remote
out, err, ret = shellexecute( ['git', 'merge', 'openshift/master'], location=app.path, debug=options.debug,
msg="Merging from openshift/master (%s)" % openshift_app.repo, exit_on_error=False )
#Conflicts detected
if ret == 1 and "CONFLICT" in out:
concflict = True
message(out)
message( [ "",
"Attention!, conflicts detected when trying to merge changes from openshift repo.",
"You have the following options:",
"(L) Use your local version to solve conflicts, changes from remote repo will be overwritten (same as using --use-local).",
"(R) Use remote version to solve conflicts, changes from your local repo will be overwritten (same as using --use-remote).",
"(M) Manually solve conflicts: look the above files and manually edit them to solve conflicts.",
" After manually solving your issues youl'll have to redeploy your app.",
"(C) Cancel merge."
] )
answer = raw_input("~ Choose your option %s %s %s %s or press enter for Local: " % ("[L]ocal", "[R]emote", "[M]anual", "[C]ancel") )
answer = answer.strip().lower()
if answer == '': answer = 'l'
print "answer: %s" % answer
if answer in ['m', 'manual']:
error_message( [
"You'll have to manually edit the files to solve the files in conflict.",
"After that run play rhc:deploy once again to deploy your changes.",
] )
#back to last commit
our, err, ret = shellexecute( ['git', 'reset', '--hard', 'HEAD'], location=app.path, debug=options.debug,
msg="Reverting to last commit", exit_on_error=True )
if answer in ['c', 'cancel']:
error_message( "Merge from remote repo at openshift has been canceled." )
if answer in ['l', 'local', '']: use_local = True
if answer in ['r', 'remote']: use_remote = True
#invalid answer
if answer not in ['c', 'cancel', 'l', 'local', 'r', 'remote', 'm', 'manual']:
error_message( "Invalid answer, canceled merge with remote repo at openshift." )
if ret != 0 or err != '': error_message(err)
if ret == 0 and err == '':
message( "Remote repository at openshift successfully merged with local repository." )
return
if conflict == True and (not use_local) and (not use_remote):
error_message( [
"Conflict has been detected and no strategy has been specified.",
"Use play rhc_deploy with the --use-local or --use-remote option."
] )
merge_command = ['git', 'merge', '-s', 'recursive', '-X']
if use_local: merge_command.append("ours")
if use_remote: merge_command.append("theirs")
merge_command.append("openshift/master")
#merge remote
our, err, ret = shellexecute( merge_command, location=app.path, debug=options.debug,
msg="Merging from openshift/master (%s)" % openshift_app.repo, exit_on_error=True )
def local_repo_remove_default_app(repo_folder, options):
commit_changes = False
#remove useless openshift app
src_folder = os.path.join(repo_folder, 'src')
if os.path.exists(src_folder):
commit_changes = True
remove_folder(src_folder, silent=True)
pom_file = os.path.join(repo_folder, 'pom.xml')
if os.path.exists(pom_file):
commit_changes = True
remove_file(pom_file, silent=True)
gitignore_file = os.path.join(repo_folder, '.gitignore')
if os.path.exists(gitignore_file):
commit_changes = True
remove_file(gitignore_file, silent=True)
if commit_changes:
shellexecute( ['git', 'add', '-A'], location=repo_folder, debug=options.debug,
msg="Adding changes to be committed (removing default app)", exit_on_error=True )
shellexecute( ['git', 'commit', '-m', '"Removed default app"'], location=repo_folder, debug=options.debug,
msg="Committing changes (removing default app)", exit_on_error=True )
#we'll push it right now, because we will delete the local repo
shellexecute( ['git', 'push'], location=repo_folder,
msg="Pushing changes to remote openshift repo... (removing default app)", debug=options.debug, output=True, exit_on_error=True)
def openshift_info(options):
info_cmd = ["rhc-domain-info", "--apps"]
if options.debug == True: info_cmd.append("-d")
del options.debug
for item in ["rhlogin", "password", "timeout"]:
if hasattr(options, item) and eval('options.%s' % item) != None and eval('options.%s' % item) != '':
info_cmd.append("--%s=%s" % (item, eval('options.%s' % item)))
shellexecute( info_cmd, output=True,
msg="Getting information for %s account" % options.rhlogin, exit_on_error=True )
def openshift_app(options):
openshift_app = appinfo(options)
if openshift_app == None:
error_message("The application '%s' does not exist for login '%s' in openshift" % (options.app, options.rhlogin))
for key in openshift_app.__dict__:
print '%s: %s' % (key, openshift_app.__dict__[key])
PK g@,)zpp pp commands.pyc
XOc @ s9 d d k Z d d k Z d d k Z d d k Z d d k Z d d k Z d d k l Z d d k l Z d d k Z
e i i e i i
e i i e d d k Td d k l Z d d k Z d Z d d d d
d d d
d d g Z h d d 6d d
6d d 6d d 6d d
6d d 6d d 6Z d e f d YZ d Z d Z d Z d Z d Z d d Z d d Z d Z d! Z d" Z! d# Z" d$ Z# d% Z$ d&