Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Transferring Changes Between Perforce Servers

4,300 views

Published on

Transferring changes between two unrelated Perforce Servers can be a challenge. This talk explains how this can be done using a Python tool called PerforceTransfer. The concepts of this tool, its internal workings as well as its applications and limitations are explained.

Published in: Technology
  • Be the first to comment

Transferring Changes Between Perforce Servers

  1. 1. # Sven Erik Technical Marketing Robert Cowham Professional Services
  2. 2. # • Background • Algorithm • Configuration • Adapting for continuous transfer • Customer Case Study
  3. 3. # Author of P4Python. Started as Lead Consultant at Perforce. Regular presenter at Perforce and other conferences. API experience includes P4OFC (P4COM) and P4Python. Author of 'Learning Perforce SCM' by PACKT Publishing, Sep 2013.
  4. 4. #
  5. 5. # • One project in two separate Perforce Servers? – e.g. Public Depot and Master Depot Source P4D Target P4D ?
  6. 6. # • Git? SHAs do not match. • Sandbox? Can only talk to one server. • Replication? Not practical. • Reconcile? Changes? Integrations? • Replay changes one by one ... ?
  7. 7. # • Transfer workspace sharing the same root Source Target transfer
  8. 8. # • One workspace on each server with shared root • Client views have to match – Depot views don’t have to match – Filter projects you want to transfer • Need to set options to allwrite Client: src-trans Root: /Users/sknop/perforce/transfer Options: allwrite View: //source/project1/... //src-trans/... Client: target-trans Root: /Users/sknop/perforce/transfer Options: allwrite View: //target/external/... //target-trans/...
  9. 9. # • Written in Python (2.6+ and 3.3+) using P4Python • Makes use of P4::Map and P4::Resolver – Use Map instead of “p4 where” – Resolver allows scripting of resolve results
  10. 10. # counter = getCounter() changes = p4 –p source changes ...@counter,#head for change in changes: filterChangeByClientView(change) p4 –p source sync if add: p4 –p target add if delete: p4 –p target delete -v if edit: p4 –p target sync –k ; p4 –p target edit if move: p4 –p target sync –f old; p4 –p target edit old; p4 –p target move old new integrate?
  11. 11. # • Integrations within workspace view are transferred – Resolve records match source records (details later) • Integrations from outside the view are downgraded – integrate  add/edit/delete • Use P4::Resolver to preserve resolve outcome
  12. 12. # Client: src-trans View: //depot/inside/... //src-trans/... Client: target-trans View: //target/... //target-trans/...
  13. 13. # • usage: P4Transfer.py [-h] [-n] [-c CONFIG] [-m MAXIMUM] [-k] [-p] [-r] [-s] • [--sample_config] [-i] • P4Transfer • optional arguments: • -h, --help show this help message and exit • -n, --preview Preview only, no transfer • -c CONFIG, --config CONFIG Default is transfer.cfg • -m MAXIMUM, --maximum MAXIMUM Maximum number of changes to transfer • -k, --nokeywords Do not expand keywords and remove +k from filetype • -p, --preflight Run a sanity check first to ensure target is empty • -r, --repeat Repeat transfer in a loop - for continuous transfer • -s, --stoponerror Stop on any error even if --repeat has been specified • --sample_config Print an example config file and exit • -i, --ignore Treat integrations as adds and edits
  14. 14. # • [general] • counter_name = p4transfer_counter • [source] • p4port = source.perforce.com:1666 • p4user = sknop • p4client = source_transfer • [target] • p4port = target.perforce.com:1777 • p4user = sknop • p4client = target_transfer P4Transfer.py --sample_config
  15. 15. # • How do we test P4Transfer with two servers? • Use the “rsh trick” – Spawn a local p4d but without consuming port P4PORT=rsh:/bin/p4d -r /path/to/target.root –i • Tests: – Inject changes into source – Transfer – Verify result in target
  16. 16. #
  17. 17. # • Experience based on source code migrations – which can take days • We want to keep an eye on things – But have a life at the same time  • Reliability/robustness in the face of (communication) errors • Status / Error reporting to support the above
  18. 18. # • Customer working with multiple third parties • Provide some level of backup/DR • Limited access to remote repositories – Replicas considered but rejected – Basically only read-only access • Data size/connectivity issues
  19. 19. # • Volume / connectivity bandwidth – 280 Gb of data • Seeding via offline backup would have been ideal – 1Gb per hour transfer rate – Single (early) changelist ~120Gb! • We wanted – Handle/report VPN disconnects – Peace of mind…!
  20. 20. # • Use standard Python logging module – Subclass for custom behavior – Beware of Python 2.x/3.x compatibility issues • Custom logging enhancements – Use circular buffer to remember last 50 lines – Automatically notify users via email, including those lines
  21. 21. # Transferring 16 changes Syncing 16 changes, files 5375, size 11.2 GB Processing : 87370 "Removed unused physx files from filelist." source = 87370 : target = 460 Processing : 87377 "Copying //depot/stable to live (//depot/live) various hotfixes" source = 87377 : target = 461 Synced 8/16 changes, files 676/5375 (12.6 %), size 482.8 MB/11.2 GB (4.3 %) Synced 8/16 changes, files 940/5375 (17.5 %), size 1.2 GB/11.2 GB (10.7 %)
  22. 22. # • P4API / P4Python has callback options # Report status per change self.progress.ReportChangeSync() # Create a custom callback object (next slide) mycallback = SyncOutput(self.progress) # Pass it to the P4 sync command self.p4.run('sync', '...@{},{}'.format(change, change), handler=mycallback )
  23. 23. # class SyncOutput(P4.OutputHandler): def __init__(self, progress): P4.OutputHandler.__init__(self) self.progress = progress # Save reporting object def outputStat(self, stat): # Function called by P4API if 'fileSize' in stat: # Report how much data synced for current file self.progress.ReportFileSync(int(stat['fileSize'])) return P4.OutputHandler.HANDLED
  24. 24. # • What happens when the Dragon King is: – Der Drachenkönig.jpg • Windows servers (not in Unicode mode) handle (some) Unicode filenames happily – no P4CHARSET required, but… • On Mac/Unix - UTF8 does the job • On Windows: – Python 2.7 fine / Python 3.x requires work…
  25. 25. # • On Windows run as a service – Install: srvcinst.exe – Run service: srvany.exe (or other equivalents)
  26. 26. # • Basic algorithm unchanged – Fixed a couple of bugs – TDD => Test Harness • Added repeat/polling options • Enhanced Robustness – Logging / Status reporting – Error handling
  27. 27. # Sven Erik Knop sknop@perforce.com Robert Cowham rcowham@perforce.com @robertcowham
  28. 28. # RESOURCES Public Depot: swarm.workshop.perforce.com/projects/perforce-software-p4transfer/

×