diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /devtools/build_solution_remote.py | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'devtools/build_solution_remote.py')
| -rw-r--r-- | devtools/build_solution_remote.py | 615 |
1 files changed, 615 insertions, 0 deletions
diff --git a/devtools/build_solution_remote.py b/devtools/build_solution_remote.py new file mode 100644 index 0000000..3cccc16 --- /dev/null +++ b/devtools/build_solution_remote.py @@ -0,0 +1,615 @@ +#!/usr/bin/env python + +# +# build "my current enlistment" remotely +# does a handful of steps: +# 1. makes sure the users has ssh key auth setup to the target host (as automatic as possible) +# 2. creates a p4 client on the remote host that's a mirror of their local client +# 3. sync's the remote client to the same (submitted) change as the local client +# 4. pickles up local changes, scp's them to the remote host, and applies them to the remote client +# 5. runs vpc and make, reporting status/errors to the user +# + +import getopt +import getpass +import marshal +import os +import p4helpers +import stat +import sys +import subprocess +import tempfile + +##### Don't merge this block to another branch, this section needs to be altered to match the requirements +##### of the p4 branch you are merging into!! +g_Branch = "//ValveGames/staging" +# branchspec needs the leading \t to make the p4 formatting happy when making a changelist +g_BranchSpec = "\t//ValveGames/staging/src/... //%s/src/..." +g_VPCCommand = { 'linux' : "dedicated /dedicated /f /tf /dod /cstrike /hl2mp" , 'osx' : "port /tf /dod /portal /hl2 /episodic /hl2mp /cstrike" } +##### +#### merge block ends +#### + +g_bVerbose = True +g_bDebugVerbose = False +g_bBatchMode = False +g_bSimulateOnly = False + +g_lRemotePlatforms = [ 'linux', 'osx' ] +g_lBuildConfigs = [ 'debug', 'release' ] + +g_szSSHBin = 'ssh' +g_szSCPBin = 'scp' +g_szVCodePickle = os.path.join( "src", "devtools", "vcodepickle.py" ) +g_szMoreBin = 'less' +g_szSSHKeyDir = '.ssh' +g_szSSHAgentAddKeyCmd = 'ssh-add' +g_szCleanTarget = '' + +if sys.platform == 'win32': + # relative to the top of the enlistment + g_szSSHBin = 'src\\devtools\\bin\\putty\\plink.exe' + g_szSCPBin = 'src\\devtools\\bin\\putty\\pscp.exe' + g_szMoreBin = '%WINDIR%\\notepad.exe' + g_szSSHKeyDir = 'ssh' + g_szSSHKeyConvertCmd = 'start /wait src\\devtools\\bin\\putty\\puttygen.exe' + g_szSSHAgentAddKeyCmd = 'src\\devtools\\bin\\putty\\pageant.exe' + +g_mapPlatformToBuildHostInfo = { "linux" : { "hostname" : "linuxpiston.valvesoftware.com", + "sshkey" : { "win32" : { "regkey" : "Software\\SimonTatham\\Putty\\SshHostKeys", + "valueName" : "rsa2@22:linuxpiston.valvesoftware.com", + "value" : "0x23,0xb9a05c086f2b8fd5ffcb5270f4d4479e2462459cf6716e297bcf15aef2696f29ac28661f45b8a427e1e9e224eba3a96ceb88f821fddfba950722bcd1bcb46fca3a1065f5e17270d1de605091cc77ee839acbcb8ac09e6c36d10f517f294e9b033bc52f969511cfc2157a2c711de8d4a54ef8eab46d6aed7b38b0ddf3a35dd2412b48ab91378415d9a01c5d0ff2423ea059d8c5d38b342c106cc860989c65607887b552d599a018baee98f382d03a733ad0c26a91d9366df3b43bab72ea030856a85721379e71521f38280aa9aad36455810e3ac1c9ea53a829a92a92c3d6dbb7ee075618c1931ff075798e284e6c7871588e64abc9719d159819cfb729fb517d" }, + "posix": "linuxpiston.valvesoftware.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAuaBcCG8rj9X/y1Jw9NRHniRiRZz2cW4pe88VrvJpbymsKGYfRbikJ+Hp4iTro6ls64j4If3fupUHIrzRvLRvyjoQZfXhcnDR3mBQkcx37oOay8uKwJ5sNtEPUX8pTpsDO8UvlpURz8IVeixxHejUpU746rRtau17OLDd86Nd0kErSKuRN4QV2aAcXQ/yQj6gWdjF04s0LBBsyGCYnGVgeIe1UtWZoBi67pjzgtA6czrQwmqR2TZt87Q7q3LqAwhWqFchN55xUh84KAqpqtNkVYEOOsHJ6lOoKakqksPW27fuB1YYwZMf8HV5jihObHhxWI5kq8lxnRWYGc+3KftRfQ==" } }, + "osx" : { "hostname" : "macslave01.valvesoftware.com", + "sshkey" : { "win32" : { "regkey" : "Software\\SimonTatham\\Putty\\SshHostKeys", + "valueName" : "rsa2@22:macslave01.valvesoftware.com", + "value" : "0x23,0xc50ecfe57fef329f442a652566fc8734fcf42f7c20beb2593ee55ce05c432a5047887ee28d6f24f3c60c5d6daf582fcd8d074f20de467893ad858ffa6809cc59427cde2c86536bf6c98810dc374b7afceb49a69b607fb29ce7eaa28751fcd78d45b59b409e665800e91b09a0615b16118bfbfebb638ef63d9bdd23a66a1cda493e17d529b4d9fcf96a8c73c947e86a0a41936b236c798a35620af65ae50459f4602ef1434f06f596cffa8dbebf985e588335e00a9f67e52c97e9d9b0cf420a04e92f56c124f430be4dc72e701244bbf005d361da048b9e8d3d56ce5d3fc45b083ded2315a7692bcd1ab7c197dd588fd695993442371aa6db863f17a3d0fbb1f9" }, + "posix": "macslave01.valvesoftware.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxQ7P5X/vMp9EKmUlZvyHNPz0L3wgvrJZPuVc4FxDKlBHiH7ijW8k88YMXW2vWC/NjQdPIN5GeJOthY/6aAnMWUJ83iyGU2v2yYgQ3DdLevzrSaabYH+ynOfqoodR/NeNRbWbQJ5mWADpGwmgYVsWEYv7/rtjjvY9m90jpmoc2kk+F9UptNn8+WqMc8lH6GoKQZNrI2x5ijViCvZa5QRZ9GAu8UNPBvWWz/qNvr+YXliDNeAKn2flLJfp2bDPQgoE6S9WwST0ML5Nxy5wEkS78AXTYdoEi56NPVbOXT/EWwg97SMVp2krzRq3wZfdWI/WlZk0QjcaptuGPxej0Pux+Q==" } } } + +g_szFetchSSHPrivateKeyScriptlet = ''' +export LANG="C"; +KEYFILE=~/.ssh/id_rsa; +if [ -f ${KEYFILE} -a -f ${KEYFILE}.pub ]; then + echo "using existing ssh private/public key" >&2; +else + echo "generating ssh keypair" >&2; + mkdir -p ~/.ssh; + ssh-keygen -t rsa -b 1024 -f ${KEYFILE} -q -N ""; +fi; +grep -q "`head -2 ${KEYFILE}.pub | tail -1`" ~/.ssh/authorized_keys; +if [ $? -ne 0 ]; then + echo "adding key to authorized keys file" >&2; + cat ${KEYFILE}.pub >> ~/.ssh/authorized_keys; +fi; +cat ${KEYFILE}; +exit $?;''' + +g_szCreateClientScriptletTemplate = ''' +export LANG="C"; +export P4CLIENT=%(P4CLIENT)s; +export P4PORT=perforce.valvesoftware.com:1666; + +mkdir -p P4Clients/${P4CLIENT}; +cd P4Clients/${P4CLIENT}; + +echo "creating p4 client ${P4CLIENT}" >&2; +p4 client -i << EOF + +Client: ${P4CLIENT} + +Owner: ${USER} + +Root: ${PWD} + +Options: noallwrite clobber nocompress unlocked nomodtime rmdir + +SubmitOptions: revertunchanged + +LineEnd: local + +View: +%(VIEWSPEC)s + +EOF + +RET=$?; +if [ $RET -ne 0 ]; then + echo "client creation failed" >&2; + exit $RET; +fi; +''' + +g_szRemoteP4ScriptletTemplate = ''' +export LANG="C"; +export P4CLIENT=%(P4CLIENT)s; +export P4PORT=perforce.valvesoftware.com:1666; + +mkdir -p P4Clients/${P4CLIENT}; +cd P4Clients/${P4CLIENT}; + +p4 %(P4COMMAND)s; +exit $?; +''' + +g_szRemoteUnpickleScriptletTemplate = ''' +export LANG="C"; +export P4CLIENT=%(P4CLIENT)s; +export P4PORT=perforce.valvesoftware.com:1666; + +mkdir -p P4Clients/${P4CLIENT}; +cd P4Clients/${P4CLIENT}; + +/usr/bin/env python ./src/devtools/vcodepickle.py --restore --file %(PICKLEFILE)s; +exit $?; +''' + +g_szRemoteBuildScriptletTemplate = ''' +export LANG="C"; +export P4CLIENT=%(P4CLIENT)s; +export P4PORT=perforce.valvesoftware.com:1666; +export BUILDLOG=remote_build.log +export CRITWARNLOG=critical_warnings.log +export SOLUTION=remote_build + +mkdir -p P4Clients/${P4CLIENT}; +cd P4Clients/${P4CLIENT}/src; +cp /dev/null ${BUILDLOG} + +./devtools/bin/vpc /mksln ${SOLUTION} +%(VPCGROUP)s >> ${BUILDLOG} 2>> ${BUILDLOG}; + +echo -e "\n\n\n=================== Starting %(CONFIG)s Build ===================\n" >> ${BUILDLOG}; +make -f ${SOLUTION}.mak CFG=%(CONFIG)s -k %(TARGET)s >> ${BUILDLOG} 2>> ${BUILDLOG}; +BUILDFAIL=$? + +# look for warnings we promote to errors - needs to be kept +# in sync with the buildbot rules +grep "call will abort" ${BUILDLOG} > ${CRITWARNLOG}; +let "NOCRITICALWARNINGS=$?"; +grep "is used uninitialized" ${BUILDLOG} >> ${CRITWARNLOG}; +let "NOCRITICALWARNINGS=$NOCRITICALWARNINGS & $?"; + +RET=1; +if [ $BUILDFAIL -eq 0 -a $NOCRITICALWARNINGS -eq 1 ]; then + RET=0; + echo "BUILD SUCCESS"; +else + echo "BUILD FAILED"; +fi; + +if [ $NOCRITICALWARNINGS -eq 0 ]; then + echo "!!! The following warnings will be promoted to errors !!!" >&2 + echo >&2; + cat ${CRITWARNLOG} >&2 + echo >&2 +fi; + +cat ${BUILDLOG} >&2 +exit $RET +''' + +g_szRemoteVsignTestTemplate = ''' +export P4CLIENT=%(P4CLIENT)s; +cd P4Clients/${P4CLIENT}/src; +cp ./devtools/bin/vsign ./devtools/bin/vsign_test; +chmod +w ./devtools/bin/vsign_test +./devtools/bin/vsign -signvalve ./devtools/bin/vsign_test; +exit $?; +''' + +g_szRemoteVsignSetPassphraseTemplate = ''' +export P4CLIENT=%(P4CLIENT)s; +cd P4Clients/${P4CLIENT}/src; +mkdir -p ~/Library/Application\ Support/Steam; +./devtools/bin/vsign -set_passphrase CodeSignature %(PASSPHRASE)s; +exit $?; +''' + +def usage(): + global g_mapPlatformToBuildHostInfo + print "usage: ", sys.argv[0], " [options]" + print "" + print "-p,--platform= %s" % g_mapPlatformToBuildHostInfo.keys() + print "-c,--config= [ 'debug', 'release' ] (default builds both )" + print "-e,--exhaustive build all build configurations on all platforms" + print "--rebuild do a clean build" + print "-b,--batch supress user prompts" + print "-r,--root= if you have a strange p4 client spec (cough, JoeR, cough)" + print " specify the directory *containing* src" + print "output related options:" + print "-q,--quiet reduce spew" + print "-d,--debug debug level spew" + print "-s,--simulate dry-run" + +def runLocalCommand( szCommand, bWait=True ): + global g_bSimulateOnly + global g_bDebugVerbose + + if g_bDebugVerbose: + print ">>> runLocalCommand( %s )\n" % szCommand + if g_bSimulateOnly: + return( 0, None, None ) + + po = subprocess.Popen( szCommand, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=sys.stdin ) + if bWait: + ( stdout, stderr ) = po.communicate() + if g_bDebugVerbose: + print stdout + print stderr + return ( po.returncode, stdout, stderr ) + else: + return ( 0, "", "" ) + +def runRemoteCommand( szRemoteUser, szRemoteHost, szCommand, bPromptForPasswd = False, bCheckReturn = True ): + global g_bSimulateOnly + global g_bDebugVerbose + global g_bBatchMode + global g_szSSHBin + global g_mapPlatformToBuildHostInfo + szSSHCmd = g_szSSHBin + + if bPromptForPasswd and g_bBatchMode: + raise RuntimeError( "can't prompt for password in batch mode" ) + + if sys.platform == 'win32': + szSSHCmd += " -agent -batch" + if bPromptForPasswd: + szPasswd = getpass.getpass( "password for %s@%s: " % (szRemoteUser, szRemoteHost) ) + szSSHCmd += ' -pw "%s"' % szPasswd + + cmd = '%s %s@%s' % ( szSSHCmd, + szRemoteUser, + szRemoteHost ) + + fd = fname = None + if sys.platform == 'win32': + # windows shell FTW + (fd, fname) = tempfile.mkstemp() + os.write( fd, szCommand ) + os.close( fd ) + cmd += " -m %s" % fname + if g_bDebugVerbose: print "tmpfile %s contains %s" % ( fname, szCommand ) + else: + cmd += " '%s'" % szCommand + + if g_bDebugVerbose: + print ">>> runRemoteCommand( %s )\n" % cmd + if g_bSimulateOnly: + return ( 0, "simulation mode", "" ) + + po = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=sys.stdin ) + ( stdout, stderr ) = po.communicate() + + if fd is not None: + os.unlink( fname ) + + if po.returncode != 0 and bCheckReturn: + print "looks like something went wrong with a remote command" + print ">>> %s " % cmd + print "returned %d" % po.returncode + if sys.platform == 'win32': + print "tempfile contains %s" % szCommand + print "produced stdout:" + print stdout + print "" + print "produced stderr:" + print stderr + raise RuntimeError( "runRemoteCommand returned non-zero result" ) + + if g_bDebugVerbose: print "return: %d\nstdout: %s\nstderr: %s" % ( po.returncode, stdout, stderr ) + + return ( po.returncode, stdout, stderr ) + +def addHostKeyToKnownHostKeys( szPlatformName ): + global g_mapPlatformToBuildHostInfo + global g_bDebugVerbose + + if sys.platform == 'win32': + mapRegKeyInfo = g_mapPlatformToBuildHostInfo[ szPlatformName ][ 'sshkey' ][ 'win32' ] + import _winreg + try: + knownHostsKey = _winreg.OpenKey( _winreg.HKEY_CURRENT_USER, + mapRegKeyInfo[ 'regkey' ], + sam = _winreg.KEY_SET_VALUE ) + if g_bDebugVerbose: print "OpenKey %s succeeded" % mapRegKeyInfo[ 'regkey' ] + except: + knownHostsKey = _winreg.CreateKey( _winreg.HKEY_CURRENT_USER, + mapRegKeyInfo[ 'regkey' ] ) + if g_bDebugVerbose: print "CreateKey %s succeeded" % mapRegKeyInfo[ 'regkey' ] + try: + value, type = _winreg.QueryValueEx( knownHostsKey, mapRegKeyInfo[ 'valueName' ] ) + assert( type == _winreg.REG_SZ and value == mapRegKeyInfo[ 'value' ] ) + if g_bDebugVerbose: print "QueryValueEx %s succeeded" % mapRegKeyInfo[ 'valueName' ] + except: + _winreg.SetValueEx( knownHostsKey, + mapRegKeyInfo[ 'valueName' ], False, + _winreg.REG_SZ, mapRegKeyInfo[ 'value' ] ) + if g_bDebugVerbose: print "SetValueEx %s=%s succeeded" % ( mapRegKeyInfo[ 'valueName' ], + mapRegKeyInfo[ 'value' ] ) + try: + _winreg.CloseKey( knownHostsKey ) + if g_bDebugVerbose: print "CloseKey succeeded" + except: + pass + else: + assert( "implement addHostKeyToKnownKeys" ) + + +def calculateRemoteView( mapClientInfo, szRemoteClientName, szBranchName ): + global g_BranchSpec + szRemoteView = g_BranchSpec % ( szRemoteClientName ) + return szRemoteView + + +def main(): + global g_bVerbose + global g_bDebugVerbose + global g_bSimulateOnly + global g_bBatchMode + global g_lRemotePlatforms + global g_lBuildConfigs + global g_szSSHKeyDir + global g_szSSHAddKeyCmd + global g_szCleanTarget + global g_szSSHKeyConvertCmd + global g_szVCodePickle + global g_szMoreBin + global g_szFetchSSHPrivateKeyScriptlet + global g_szCreateClientScriptletTemplate + global g_szRemoteP4ScriptletTemplate + global g_szRemoteBuildScriptletTemplate + global g_mapPlatformToBuildHostInfo + global g_VPCCommand + global g_Branch + + bSetBuildConfigs = False + bSetBuildPlatform = False + szBranchName = "" + szUserName = getpass.getuser() + szP4ChangeToSync = "all" + + clientInfo = p4helpers.GetClientInfo() + szLocalClientName = clientInfo[ 'Client' ] + szLocalClientRoot = clientInfo[ 'Root' ] + + try: + opts, args = getopt.getopt( sys.argv[1:], "bdsvqp:c:r:e?l", [ "change=", "batch", "config=", "exhaustive", "debug", "simulate", "verbose", "quiet", "platform=", "root=", "rebuild", "limited-sync" ] ) + except getopt.GetoptError, e: + print "" + print "Argument error: ", e + print "" + usage() + sys.exit(1) + for o, a in opts: + if o in ( "-?" ): + usage() + sys.exit(1) + if o in ( "-b", "--batch" ): + g_bBatchMode = True + if o in ( "--rebuild" ): + g_szCleanTarget = "clean" + if o in ( "-c", "--config" ): + if a not in [ 'debug', 'release' ]: + raise RuntimeError( "configuration '%s' not understood" % a ) + g_lBuildConfigs = [ a ] + bSetBuildConfigs = True; + if o in ( "-r", "--root" ): + szLocalClientRoot = a + if o in ( "-e", "--exhaustive" ): + g_lRemotePlatforms = g_mapPlatformToBuildHostInfo.keys() + if o in ( "-p", "--platform" ): + if a not in g_mapPlatformToBuildHostInfo.keys(): + raise RuntimeError( "platform '%s' not supported" % a ) + g_lRemotePlatforms = [ a ] + bSetBuildPlatform = True + if o in ( "-v", "--verbose" ): + g_bVerbose = True + if o in ( "-q", "--quiet" ): + g_bVerbose = False + g_bDebugVerbose = False + if o in ( "-d", "--debug" ): + g_bDebugVerbose = True + if o in ( "-s", "--simulate" ): + g_bSimulateOnly = True + if o in ( "--change" ): + szP4ChangeToSync = a + + if not os.getcwd().lower().startswith( clientInfo[ 'Root' ].lower() ): + print "" + print "I need to be run from the root (%s)" % szLocalClientRoot + print "or any subdirectory of your p4 client (%s)" % szLocalClientName + print "" + print "If these values look wrong, make sure you have p4 configured" + print "correctly for command-line use." + sys.exit(1) + + try: + p4path = p4helpers.P4Where( os.path.join( szLocalClientRoot, "src\..." ) ) + except: + try: + # try the cwd as the place src/ is to support "interesting" client specs + szLocalClientRoot = os.path.split( os.getcwd() )[0] + p4path = p4helpers.P4Where( os.path.join( szLocalClientRoot, "src\..." ) ) + except: + print "couldn't find src where I expected it, perhaps you need the -r option?" + usage() + sys.exit(1) + + # on source only build release by default + if ( bSetBuildConfigs == False ): + g_lBuildConfigs = ['release' ] + + if not p4path.lower().startswith( g_Branch ): + raise RunTimeError( "couldn't map local enlistment to staging branch" ) + + # do everything relative to the client root directory + os.chdir( szLocalClientRoot ) + + if g_bVerbose: print "building configuration(s) %s on platform(s) %s" % ( g_lBuildConfigs, g_lRemotePlatforms ) + + szLocallySyncedRevision = p4helpers.GetSyncedRevision( szLocalClientRoot ) + + szPickleFile = 'vcodepickle_%s.zip' % szLocalClientName + if g_bVerbose: print "pickling local changes to %s..." % szPickleFile, + ( ret, stdout, stderr ) = runLocalCommand( '%s --backup --file %s -c %s --exclude "*.exe" --exclude "*.dll" --exclude "*.pdb" --include "*/src/*"' % ( g_szVCodePickle, szPickleFile, szP4ChangeToSync ) ) + if g_bVerbose: sys.stdout.flush(); print "done." + + for platform in g_lRemotePlatforms: + if g_bVerbose: print "\nbuilding on platform %s\n" % ( platform ) + szRemoteHost = g_mapPlatformToBuildHostInfo[ platform ][ 'hostname' ] + + szRemoteClientName = "%s_%s_remote_build_%s" % ( szUserName, g_Branch.replace( "//", "" ).replace( "/", "_" ), szRemoteHost[ : szRemoteHost.find(".") ] ) + + # figure out where the private key for this host would be, if we were to have one + absKeyDirPath = os.path.join( os.path.expanduser("~"), g_szSSHKeyDir ) + szSSHPrivKeyFile = os.path.join( absKeyDirPath, 'id_rsa_%s@%s' % ( szUserName, szRemoteHost ) ) + if sys.platform == 'win32': + szSSHPrivKeyFile += '.ppk' + + if g_bDebugVerbose: print "adding remote host key for %s to known keys..." % platform + addHostKeyToKnownHostKeys( platform ) + + # if we don't have a key for this host, run the scriptlet to create one + if not os.path.exists( szSSHPrivKeyFile ): + if not os.path.exists( absKeyDirPath ): + os.makedirs( absKeyDirPath ) + + if g_bVerbose: print "creating ssh public/private keypair..." + ( ret, stdout, stderr ) = runRemoteCommand( szUserName, szRemoteHost, g_szFetchSSHPrivateKeyScriptlet, bPromptForPasswd = True ) + + if not g_bSimulateOnly: + assert( len( stdout ) ) + assert( not g_bBatchMode ) + f = open( szSSHPrivKeyFile, "w" ) + f.write( stdout ) + f.close() + + if sys.platform == 'win32': + os.rename( szSSHPrivKeyFile, szSSHPrivKeyFile + ".tmp" ) + # let's assume we need to convert their key into putty format + print "" + print " !!!!! ACHTUNG !!!!!" + print "" + print "your private key doesn't seem to be in putty format (yet)." + print "" + print "I'm going to launch puttygen, which should present a dialog" + print "saying it's successfully imported the key, and that you need" + print "to save it in putty format before use." + print "" + print "1. click OK to dismiss this dialog" + print "2. Choose File->Save Private Key" + print "3. Confirm saving the key without a passphrase" + print "4. paste this path into the save dialog:" + print " %s" % szSSHPrivKeyFile.replace( "/", "\\" ) + print "5. quit puttygen" + print "" + raw_input( "Press return to continue: " ) + runLocalCommand( "%s %s" % ( g_szSSHKeyConvertCmd, szSSHPrivKeyFile + ".tmp" ) ) + os.remove( szSSHPrivKeyFile + ".tmp" ) + else: + # on posix, ssh wants the keyfile to be tightly controlled + os.chmod( szSSHPrivKeyFile, stat.S_IRUSR | stat.S_IWUSR ) + + # try loading the ssh key into their agent + if g_bDebugVerbose: print "adding private key to ssh authentication agent..." + ( ret, stdout, stderr ) = runLocalCommand( "%s %s" % ( g_szSSHAgentAddKeyCmd, szSSHPrivKeyFile ), bWait = False ) + + # figure out what the remote view should look like + if g_bDebugVerbose: print "calculating remote view..." + szRemoteView = calculateRemoteView( clientInfo, szRemoteClientName, szBranchName ) + if g_bDebugVerbose: print "remote view: %s" % szRemoteView + + # do the magic substituion on the client create scriptlet + if g_bVerbose: print "syncing remote p4 client spec...", + szClientCreateScriptlet = g_szCreateClientScriptletTemplate % { "P4CLIENT" : szRemoteClientName, + "VIEWSPEC" : szRemoteView, + "REVISION" : szLocallySyncedRevision } + ( ret, stdout, stderr ) = runRemoteCommand( szUserName, szRemoteHost, szClientCreateScriptlet ) + if g_bVerbose: sys.stdout.flush(); print "done." + + if platform == "osx": + if g_bVerbose: print "checking if vsign is set up...", + szRemoteCheckVsignScriptlet = g_szRemoteVsignTestTemplate % { "P4CLIENT" : szRemoteClientName } + ( ret, stdout, stderr ) = runRemoteCommand( szUserName, szRemoteHost, szRemoteCheckVsignScriptlet, False, False ) + if g_bVerbose: sys.stdout.flush(); print "done." + + if( ret != 0 ): + passphrase = raw_input("Please enter code signature passphrase for public universe: ") + if g_bVerbose: print "setting vsign passphrase...", + szremoteSetVsignPassphraseScriptlet = g_szRemoteVsignSetPassphraseTemplate % { "P4CLIENT" : szRemoteClientName, + "PASSPHRASE": passphrase} + ( ret, stdout, stderr ) = runRemoteCommand( szUserName, szRemoteHost, szremoteSetVsignPassphraseScriptlet, False, False ) + if g_bVerbose: sys.stdout.flush(); print "done." + + if g_bVerbose: print "reverting any open files on remote p4client...", + szClientSyncScriptlet = g_szRemoteP4ScriptletTemplate % { "P4CLIENT" : szRemoteClientName, + "P4COMMAND": 'revert ...' } + ( ret, stdout, stderr ) = runRemoteCommand( szUserName, szRemoteHost, szClientSyncScriptlet ) + if g_bVerbose: sys.stdout.flush(); print "done." + + if g_bVerbose: print "syncing remote p4client to changelist %s (this could take a while)..." % szLocallySyncedRevision, + szClientSyncScriptlet = g_szRemoteP4ScriptletTemplate % { "P4CLIENT" : szRemoteClientName, + "P4COMMAND": 'sync @%s' % szLocallySyncedRevision } + ( ret, stdout, stderr ) = runRemoteCommand( szUserName, szRemoteHost, szClientSyncScriptlet ) + if g_bVerbose: sys.stdout.flush(); print "done." + + if g_bVerbose: print "transferring pickled changes...", + ( ret, stdout, stderr ) = runLocalCommand( "%s %s %s@%s:P4Clients/%s/" % ( g_szSCPBin, szPickleFile, szUserName, szRemoteHost, szRemoteClientName ) ) + if g_bVerbose: sys.stdout.flush(); print "done." + + if g_bVerbose: print "applying changes to remote client...", + szUnpickleScriptlet = g_szRemoteUnpickleScriptletTemplate % { "P4CLIENT" : szRemoteClientName, + "PICKLEFILE": szPickleFile } + ( ret, stdout, stderr ) = runRemoteCommand( szUserName, szRemoteHost, szUnpickleScriptlet ) + if g_bVerbose: sys.stdout.flush(); print "done." + + for buildConfig in g_lBuildConfigs: + if g_bVerbose: print "running remote %s build..." % buildConfig, + szBuildScriptlet = g_szRemoteBuildScriptletTemplate % { "P4CLIENT" : szRemoteClientName, + "VPCGROUP" : g_VPCCommand[ platform ], + "CONFIG" : buildConfig, + "TARGET" : "%s all" % g_szCleanTarget } + ( ret, stdout, stderr ) = runRemoteCommand( szUserName, szRemoteHost, szBuildScriptlet, bCheckReturn = False ) + if g_bVerbose: sys.stdout.flush(); print "done." + + if len(stderr): + # figure out the correct newline character - can't we all just get along? + NL = "\n" + if sys.platform == "win32": + NL = "\r\n" + + # look for a couple common cases + errlines = stderr.split( "\n" ) + + (fd, name) = tempfile.mkstemp( suffix=".txt" ) + os.write( fd, NL.join( errlines ) ) + os.close( fd ) + print "build output in file://%s" % name + + bFoundErrors = False + for errline in errlines: + if errline.lower().find( "error:" ) >= 0: + bFoundErrors = True + print " " + errline + + if ret !=0 and not bFoundErrors: + iLines = 5 + print "first %d lines of build log:" % iLines + print NL.join( errlines[ :iLines ] ) + if len(errlines) > iLines: + print "..." + + if ret != 0: + if not g_bBatchMode: + resp = raw_input( "display full build log (Y/N)? " ) + if resp.lower() == "y": + cmd = "%s %s" % ( g_szMoreBin, name ) + runLocalCommand( cmd ) + + print stdout + + if ret != 0: + break; + +if __name__ == '__main__': + main() + |