| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- # The contents of this file are subject to the BitTorrent Open Source License
- # Version 1.1 (the License). You may not copy or use this file, in either
- # source code or executable form, except in compliance with the License. You
- # may obtain a copy of the License at http://www.bittorrent.com/license/.
- #
- # Software distributed under the License is distributed on an AS IS basis,
- # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- # for the specific language governing rights and limitations under the
- # License.
- # by David Harrison
- import sys, os, shutil
- from distutils import core
- if sys.platform == "win32":
- setup = core.setup
- # no need to import anything further. None of the remaining
- # functionality is available in windows.
- else:
- import pwd
- from distutils.sysconfig import get_python_lib
- import distutils.sysconfig
- from stat import S_IMODE, S_IRUSR, S_IXUSR, S_IRGRP, S_IXGRP, S_IROTH, S_IXOTH
- from daemon import getuid_from_username, getgid_from_username
- from daemon import getgid_from_groupname
-
- months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
- 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
-
- class SetupException(Exception):
- pass
-
- def getuid_for_path(path):
- return os.stat(path).st_uid
-
- def seteugid_to_login():
- """set effective user id and effective group id to the user and group ids
- of the user logged into this terminal."""
- uid = pwd.getpwnam(os.getlogin())[2] # search /etc/passwd for uid and
- gid = pwd.getpwnam(os.getlogin())[3] # gid of user logged into this
- # terminal.
- os.setegid(gid)
- os.seteuid(uid) # Is there a better way? --Dave
-
- def get_svn_change_code():
- """Returns the svn repository's date and revision number for the current
- working directory. The returned string has the format 'YYYY_MM_DD_revXXXX'
- where XXXX is the revision number."""
- def to_dict(lines):
- # FRAGILE XXX
- splitted = [l.split(':') for l in lines]
- pairs = [(s[0].strip(), ':'.join(s[1:]).strip()) for s in splitted]
- d = dict(pairs)
- return d
-
- # returns date and revision number
- d = to_dict(os.popen("svn info").readlines())
- url = d["URL"]
- revision = int(d["Last Changed Rev"])
- date = d["Last Changed Date"]
- date = date.split(' ')[0] # keep only "YYYY-MM-DD"
- date = "_".join(date.split('-')) # replace dash with underscore
- date_rev = "%s_rev%.4d" % (date,revision)
- return date_rev
-
- def get_cdv_change_code():
-
- # cdv won't run on the dev machines as root. nfs does not allow
- # root access to mounted drives. --Dave
- if os.getuid() == 0 and getuid_for_path(".") != 0:
- seteugid_to_login()
-
- # fragile. XXXX
- l = os.popen("cdv history -c 1").readlines()[0].split(" ")
- if os.getuid() == 0:
- os.seteuid(0)
- #os.setegid(oldgid)
-
- l = [x.strip() for x in l if x.strip() != ''] # remove empty strings.
- x,code,x,x,x,x,dow,mo,dom,t,y = l
- month = "%.2d" % (months.index(mo)+1)
- dom = "%.2d" % int(dom) # single digit day of month like 3 becomes 03
- t = "_".join(t.split(':')) # convert ':' to underscores in time.
- return y+"_"+month+"_"+dom+"_"+t+"_"+code
-
- def get_install_prefix( appname ):
- """Generates directory name /opt/appname_YYYY_MM_DD_revXXXX"""
-
- # fragile. XXXX
- #change = get_cdv_change_code()
- change = get_svn_change_code()
- path = os.path.join("/opt", appname+"_"+change)
- return os.path.normpath(path)
-
- def get_unique_install_prefix( appname ):
- """Generates a directory name /opt/appname_YYYY_MM_DD_revXX or
- /opt/appname_YYYY_MM_DD_revXX_vVVV if the prior exists.
- VVV is a counter that is incremented with each install of
- the distribution with the same svn change code.
-
- Unlike get_install_prefix, this does not assume that cdv exists
- on the system, but instead assumes there is a version.txt
- file in the distribution root directory containing the cdv change
- date and code information. This file is created in the install
- directory whenever bdistutils is run with the installdev option."""
- vfile = os.path.join(sys.path[0], "version.txt")
- if not os.path.exists(vfile):
- raise SetupException( "Cannot derive install prefix from cdv change date "
- "code, because there is no version.txt file in the "
- "root of the distribution tree." )
- cfp = open(vfile, 'r')
- change_str = cfp.readline().strip()
- prefix = os.path.join("/opt", appname+"_"+change_str)
- while os.path.exists(prefix):
- path, name = os.path.split(prefix)
- code_or_cnt = prefix.split("_")[-1]
- if code_or_cnt[0] == 'v':
- cnt = int(code_or_cnt[1:])
- cnt += 1
- prefix = "_".join(prefix.split("_")[:-1])
- else:
- cnt = 1
- prefix = "%s_v%03.f" % (prefix, cnt)
- return os.path.normpath(prefix)
-
- def setup( **kwargs ):
- """site-specific setup.
-
- If sys.argv[1] is not installdev then this behaves
- as python's distutils.core.setup.
-
- If sys.argv[1] is installdev then this installs into a
- directory like:
-
- /opt/Mitte_2006_10_16_14_39_51_78a5
-
- The date and time is the commit time for this version in the svn repository
- and 78a5 is the code for the version in svn.
-
- Also creates a symbolic link like /opt/mitte pointing to
- /opt/Mitte_2006_10_16_14_39_51_78a5.
- """
-
- name = kwargs['name']
-
- # setup doesn't like kwargs it doesn't know.
- destname = kwargs.get('destname', name)
- if kwargs.has_key('destname'): del kwargs['destname']
- username = kwargs.get('username',None)
- if kwargs.has_key('username'): del kwargs['username']
- groupname = kwargs.get('groupname',None)
- if kwargs.has_key('groupname'): del kwargs['groupname']
- symlinks = kwargs.get('symlinks',None)
- if kwargs.has_key('symlinks'): del kwargs['symlinks']
-
- installdev=False
- installprod = False
- old_prefix = None
-
- if len(sys.argv)>1 and sys.argv[1] == "force-installdev":
- # force install simply installs in a new directory.
- sys.prefix = get_unique_install_prefix(destname)
- distutils.sysconfig.PREFIX=sys.prefix
- print "get_unique_install_prefix returned sys.prefix=", sys.prefix
- installdev = True
- sys.argv[1] = "install"
-
- # determine old install directory.
- if os.path.exists( os.path.join("/opt/",destname) ):
- old_prefix = os.path.realpath(os.path.join("/opt/", destname))
- old_prefix = os.path.split(old_prefix)[0]
-
- elif len(sys.argv)>1 and sys.argv[1] == "installdev":
- installdev=True
- sys.argv[1] = "install"
-
- # create change code file.
- code = get_svn_change_code()
- if code:
- # may fail if root and destination is nfs mounted.
- try:
- cfp = open(os.path.join(sys.path[0],"version.txt"), 'w')
- cfp.write( code )
- cfp.close()
- except IOError:
- # try again as login username.
- old_uid = os.geteuid()
- seteugid_to_login()
- cfp = open(os.path.join(sys.path[0],"version.txt"), 'w')
- cfp.write( code )
- cfp.close()
- os.seteuid(old_uid) # require root access to install into /opt or python site-packages.
-
- # determine install directory
- sys.prefix = get_install_prefix(destname)
- distutils.sysconfig.PREFIX=sys.prefix
- if os.path.exists(sys.prefix):
- raise SetupException( "This code revision has already been installed %s."
- " If you want to install it again then move the "
- "existing directory or use force-installdev." % sys.prefix )
-
- # determine old install directory.
- if os.path.exists( os.path.join("/opt/",destname) ):
- old_prefix = os.path.realpath(os.path.join("/opt/", destname))
- old_prefix = os.path.split(old_prefix)[0]
-
- if len(sys.argv)>1 and sys.argv[1] == "install":
- # building with root privilege can fail if the destination of the
- # build is nfs mounted.
- sys.argv[1] = "build"
- try:
- # try as root if I am root.
- core.setup(**kwargs)
- except:
- # try using login username
- old_uid = os.geteuid()
- seteugid_to_login()
- core.setup(**kwargs)
- os.seteuid(old_uid)
- sys.argv[1] = "install"
-
- try:
- core.setup(**kwargs)
- except:
- # try using login username
- old_uid = os.geteuid()
- seteugid_to_login()
- core.setup(**kwargs)
- os.seteuid(old_uid)
-
- if installdev:
- print "installdev is True."
-
- # shortened the directory path.
- #long_path = os.path.join(sys.path[0], "build", "lib", name)
- long_path = os.path.join(sys.prefix, "lib", "python2.4", "site-packages", name)
- print "long_path=",long_path
- dest = os.path.join(sys.prefix,name)
- print "dest=", dest
- if os.path.exists(long_path):
- print "copytree from ", long_path, " to ", dest
- shutil.copytree(long_path,dest)
- #shutil.rmtree(os.path.join(sys.prefix, "lib" ))
-
- # copy all files not in packages into /opt.
- for f in os.listdir('.'):
- if f == "build": continue
- if f == ".cdv": continue
- if f == ".svn": continue
- if f == "lib": continue
- if not os.path.exists( os.path.join(sys.prefix,f)):
- if os.path.isdir(f):
- shutil.copytree(f,os.path.join(sys.prefix,f),False)
- else:
- shutil.copyfile(f,os.path.join(sys.prefix,f))
-
- # create symlink from /opt/blah to /opt/blah_YYYY_MM_DD_HH:MM:SS_code
- link_to = sys.prefix
- symlnk = os.path.join( '/opt', destname )
- print "removing symlink from", symlnk
- if os.path.islink(symlnk):
- print "removing", symlnk
- os.remove(symlnk)
- print "creating symlink", symlnk, "to", link_to
- os.symlink(link_to, symlnk)
-
- if username:
- uid = getuid_from_username(username)
- else:
- uid = -1
- if groupname:
- gid = getgid_from_groupname(groupname)
- elif username:
- gid = getgid_from_username(username)
- else:
- gid = -1
-
- # recursively change owner and group name of install directory.
- ## Turns out that this is a bad idea. The account in which the
- ## service runs should not own its own install directory, because
- ## it could modify its own code.
- #if uid != -1 or gid != -1:
- # os.chown(sys.prefix,uid,gid)
- # dirs = os.walk(sys.prefix)
- # for path, dirnames, filenames in dirs:
- # for dir in dirnames:
- # os.chown(os.path.join(path, dir),uid,gid)
- # for fname in filenames:
- # os.chown(os.path.join(path, fname),uid,gid)
-
- # make world readable and make directories world cd'able (i.e., world executable)
- dirs = os.walk(sys.prefix)
- for path, dirnames, filenames in dirs:
- for dir in dirnames:
- dir = os.path.join(path,dir)
- mode = os.stat(dir).st_mode
- mode = S_IMODE(mode)
- mode |= S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH
- os.chmod(dir,mode)
- for fname in filenames:
- fname = os.path.join(path, fname)
- mode = os.stat(fname).st_mode
- mode |= S_IRUSR | S_IRGRP | S_IROTH
- os.chmod(fname, mode)
-
- # create pid dir.
- pid_dir = os.path.join("/var/run/", name )
- if not os.path.exists(pid_dir):
- os.mkdir(pid_dir)
- os.chown(pid_dir,uid,gid)
-
|