2015-09-18 03:23:50 +08:00
|
|
|
syncsource.py
|
2015-09-18 01:14:31 +08:00
|
|
|
|
|
|
|
OVERVIEW
|
|
|
|
|
2015-09-18 03:23:50 +08:00
|
|
|
The syncsource.py utility transfers groups of files between
|
2015-09-18 01:14:31 +08:00
|
|
|
computers. The primary use case is to enable developing LLVM project
|
|
|
|
software on one machine, transfer it efficiently to other machines ---
|
2015-09-18 03:23:50 +08:00
|
|
|
possibly of other architectures --- and test it there. syncsource.py
|
2015-09-18 01:14:31 +08:00
|
|
|
supports configurable, named source-to-destination mappings and has a
|
|
|
|
transfer agent plug-in architecture. The current distribution provides
|
|
|
|
an rsync-over-ssh transfer agent.
|
|
|
|
|
2015-09-18 03:23:50 +08:00
|
|
|
The primary benefits of using syncsource.py are:
|
2015-09-18 01:14:31 +08:00
|
|
|
|
|
|
|
* Provides a simple, reliable way to get a mirror copy of primary-
|
|
|
|
machine files onto several different destinations without concern
|
|
|
|
of compromising the patch during testing on different machines.
|
|
|
|
|
|
|
|
* Handles directory-mapping differences between two machines. For
|
|
|
|
LLDB, this is helpful when going between OS X and any other non-OS X
|
|
|
|
target system.
|
|
|
|
|
|
|
|
EXAMPLE WORKFLOW
|
|
|
|
|
|
|
|
This utility was developed in the context of working on the LLDB
|
|
|
|
project. Below we show the transfers we'd like to have happen,
|
|
|
|
and the configuration that supports it.
|
|
|
|
|
|
|
|
Workflow Example:
|
|
|
|
|
|
|
|
* Develop on OS X (primary machine)
|
|
|
|
* Test candidate changes on OS X.
|
|
|
|
* Test candidate changes on a Linux machine (machine-name: lldb-linux).
|
|
|
|
* Test candidate changes on a FreeBSD machine (machine-name: lldb-freebsd).
|
|
|
|
* Do check-ins from OS X machine.
|
|
|
|
|
|
|
|
Requirements:
|
|
|
|
|
|
|
|
* OS X machine requires the lldb source layout: lldb, lldb/llvm,
|
|
|
|
lldb/llvm/tools/clang. Note this is different than the canonical
|
|
|
|
llvm, llvm/tools/clang, llvm/tools/lldb layout that we'll want on
|
|
|
|
the Linux and FreeBSD test machines.
|
|
|
|
|
|
|
|
* Linux machine requires the llvm, llvm/tools/clang and
|
|
|
|
llvm/tools/lldb layout.
|
|
|
|
|
|
|
|
* FreeBSD machine requires the same layout as the llvm machine.
|
|
|
|
|
2015-09-18 03:23:50 +08:00
|
|
|
syncsource.py configuration in ~/.syncsourcerc:
|
2015-09-18 01:14:31 +08:00
|
|
|
|
|
|
|
# This is my configuration with a comment. Configuration
|
|
|
|
# files are JSON-based.
|
|
|
|
{ "configurations": [
|
|
|
|
# Here we have a collection of named configuration blocks.
|
|
|
|
# Configuration blocks can chain back to a parent by name.
|
|
|
|
{
|
|
|
|
# Every block has a name so it can be referenced from
|
|
|
|
# the command line or chained back to by a child block
|
|
|
|
# for sharing.
|
|
|
|
"name": "base_tot_settings",
|
|
|
|
|
|
|
|
# This directive lists the "directory ids" that we'll care
|
|
|
|
# about. If your local repository has additional directories
|
|
|
|
# for other projects that need to ride along, add them here.
|
|
|
|
# For defaulting purposes, it makes sense to name the
|
|
|
|
# directory IDs as the most likely name for the directory
|
|
|
|
# itself. For stock LLDB from top of tree, we generally only
|
|
|
|
# care about lldb, llvm and clang.
|
|
|
|
"dir_names": [ "llvm", "clang", "lldb" ],
|
|
|
|
|
|
|
|
# This section describes where the source files live on
|
|
|
|
# the primary machine. There should always be a base_dir
|
|
|
|
# entry, which indicates where in the local filesystem the
|
|
|
|
# projects are rooted. For each dir in dir_names, there
|
|
|
|
# should be either:
|
|
|
|
# 1. an entry named {dir-id}_dir (e.g. llvm_dir), which
|
|
|
|
# specifies the source directory for the given dir id
|
|
|
|
# relative to the base_dir entry, OR
|
|
|
|
# 2. no entry, in which case the directory is assumed to
|
|
|
|
# be the same as {dir-id}. In the example below, the
|
|
|
|
# base_dir-relative directory for the "lldb" dir-id is
|
|
|
|
# defaulted to being "lldb". That's exactly what
|
|
|
|
# we need in an OS X-style lldb dir layout.
|
|
|
|
"source": {
|
|
|
|
"base_dir": "~/work/lldb-tot",
|
|
|
|
"llvm_dir": "lldb/llvm",
|
|
|
|
"clang_dir": "lldb/llvm/tools/clang"
|
|
|
|
},
|
|
|
|
|
|
|
|
# source_excludes covers any exclusions that:
|
|
|
|
# * should be applied when copying files from the source
|
|
|
|
# * should be excluded from deletion on the destination
|
|
|
|
#
|
|
|
|
# By default, ".git", ".svn" and ".pyc" are added to
|
|
|
|
# all dir-id exclusions. The default excludes can be
|
2015-09-18 03:23:50 +08:00
|
|
|
# controlled by the syncsource.py --default-excludes
|
2015-09-18 01:14:31 +08:00
|
|
|
# option.
|
|
|
|
#
|
|
|
|
# Below, I have transfer of the lldb dir skip everything
|
|
|
|
# rooted at "/llvm" below the the lldb dir. This is
|
|
|
|
# because we want the source OS X lldb to move to
|
|
|
|
# a destination of {some-dest-root}/llvm/tools/lldb, and
|
|
|
|
# not have the OS-X-inverted llvm copy over with the lldb
|
|
|
|
# transfer portion. We'll see the complete picture of
|
|
|
|
# how this works when we get to specifying destinations
|
|
|
|
# later on in the config.
|
|
|
|
#
|
|
|
|
# We also exclude the "/build" and "/llvm-build" dir rooted in
|
|
|
|
# the OS X-side sources. The Xcode configuration on this
|
|
|
|
# OS X machine will dump lldb builds in the /build directory
|
|
|
|
# relative to the lldb dir, and it will build llvm+clang in
|
|
|
|
# the /llvm-build dir relative to the lldb dir.
|
|
|
|
#
|
|
|
|
# Note the first forward slash in "/build" indicates to the
|
|
|
|
# transfer agent that we only want to exclude the
|
|
|
|
# ~/work/lldb-tot/lldb/build dir, not just any file or
|
|
|
|
# directory named "build" somewhere underneath the lldb
|
|
|
|
# directory. Without the leading forward slash, any file
|
|
|
|
# or directory called build anywhere underneath the lldb dir
|
|
|
|
# will be excluded, which is definitely not what we want here.
|
|
|
|
#
|
|
|
|
# For the llvm dir, we do a source-side exclude for
|
|
|
|
# "/tools/clang". We manage the clang transfer as a separate
|
|
|
|
# entity, so we don't want the movement of llvm to also move
|
|
|
|
# clang.
|
|
|
|
#
|
|
|
|
# The llvm_dir exclusion of "/tools/lldb" is the first example
|
|
|
|
# of an exclude targeting a requirement of the destination
|
|
|
|
# side. Normally the transfer agent will delete anything on
|
|
|
|
# the destination that is not present on the source. It is
|
|
|
|
# trying to mirror, and ensure both sides have the same
|
|
|
|
# content. The source side of llvm on OS X does not have a
|
|
|
|
# "/tools/lldb", so at first this exclude looks non-sensical.
|
|
|
|
# But on the canonical destination layout, lldb lives in
|
|
|
|
# {some-dest-root}/llvm/tools/lldb. Without this exclude,
|
|
|
|
# the transfer agent would blow away the tools/lldb directory
|
|
|
|
# on the destination every time we transfer, and then have to
|
|
|
|
# copy the lldb dir all over again. For rsync+ssh, that
|
|
|
|
# totally would defeat the huge transfer efficiencies gained
|
|
|
|
# by using rsync in the first place.
|
|
|
|
#
|
|
|
|
# Note the overloading of both source and dest style excludes
|
|
|
|
# ultimately comes from the rsync-style exclude mechanism.
|
|
|
|
# If it wasn't for that, I would have separated source and
|
|
|
|
# dest excludes out better.
|
|
|
|
"source_excludes": {
|
|
|
|
"lldb_dir": ["/llvm", "/build", "/llvm-build"],
|
|
|
|
"llvm_dir": ["/tools/lldb", "/tools/clang"]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
# Top of tree public, common settings for all destinations.
|
|
|
|
{
|
|
|
|
# The name for this config block.
|
|
|
|
"name": "common_tot",
|
|
|
|
|
|
|
|
# Here is our first chaining back to a parent config block.
|
|
|
|
# Any settings in "common_tot" not specified here are going
|
|
|
|
# to be retrieved from the parent.
|
|
|
|
"parent": "base_tot_settings",
|
|
|
|
|
|
|
|
# The transfer agent class to use. Right now, the only one
|
|
|
|
# available is this one here that uses rsync over ssh.
|
|
|
|
# If some other mechanism is needed to reach this destination,
|
|
|
|
# it can be specified here in full [[package.]module.]class form.
|
|
|
|
"transfer_class": "transfer.rsync.RsyncOverSsh",
|
|
|
|
|
|
|
|
# Specifies the destination-root-relative directories.
|
|
|
|
# Here our desination is rooted at:
|
|
|
|
# {some-yet-to-be-specified-destination-root} + "base_dir".
|
|
|
|
# In other words, each destination will have some kind of root
|
|
|
|
# for all relative file placement. We'll see those defined
|
|
|
|
# later, as they can change per destination machine.
|
|
|
|
# The block below describes the settings relative to that
|
|
|
|
# destination root.
|
|
|
|
#
|
|
|
|
# As before, each dir-id used in this configuration is
|
|
|
|
# expected to have either:
|
|
|
|
# 1. an entry named {dir-id}_dir (e.g. llvm_dir), which
|
|
|
|
# specifies the destination directory for the given dir id
|
|
|
|
# relative to the dest_root+base_dir entries, OR
|
|
|
|
# 2. no entry, in which case the directory is assumed to
|
|
|
|
# be the same as {dir-id}. In the example below, the
|
|
|
|
# dest_root+base_dir-relative directory for the "llvm" dir-id is
|
|
|
|
# defaulted to being "llvm". That's exactly what
|
|
|
|
# we need in a canonical llvm/clang/lldb setup on
|
|
|
|
# Linux/FreeBSD.
|
|
|
|
#
|
|
|
|
# Note we see the untangling of the OS X lldb-centric
|
|
|
|
# directory structure to the canonical llvm,
|
|
|
|
# llvm/tools/clang, llvm/tools/lldb structure below.
|
|
|
|
# We are mapping lldb into a subdirectory of the llvm
|
|
|
|
# directory.
|
|
|
|
#
|
|
|
|
# The transfer logic figures out which directories to copy
|
|
|
|
# first by finding the shortest destination absolute path
|
|
|
|
# and doing them in that order. For our case, this ensures
|
|
|
|
# llvm is copied over before lldb or clang.
|
|
|
|
"dest": {
|
|
|
|
"base_dir": "work/mirror/git",
|
|
|
|
"lldb_dir": "llvm/tools/lldb",
|
|
|
|
"clang_dir": "llvm/tools/clang"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
# Describe the lldb-linux destination. With this,
|
|
|
|
# we're done with the mapping for transfer setup
|
|
|
|
# for the lldb-linux box. This configuration can
|
|
|
|
# be used either by:
|
|
|
|
# 1. having a parent "default" blockthat points to this one,
|
|
|
|
# which then gets used by default, or
|
|
|
|
# 2. using the --configuration/-c CONFIG option to
|
2015-09-18 03:23:50 +08:00
|
|
|
# specify using this name on the syncsource.py command line.
|
2015-09-18 01:14:31 +08:00
|
|
|
{
|
|
|
|
"name": "lldb-linux"
|
|
|
|
"parent": "common_tot",
|
|
|
|
|
|
|
|
# The ssh block is understood by the rsync+ssh transfer
|
|
|
|
# agent. Other agents would probably require different
|
|
|
|
# agent-specific details that they could read from
|
|
|
|
# other blocks.
|
|
|
|
"ssh": {
|
|
|
|
# This specifies the host name (or IP address) as would
|
|
|
|
# be used as the target for an ssh command.
|
|
|
|
"dest_host": "lldb-linux.example.com",
|
|
|
|
|
|
|
|
# root_dir specifies the global root directory for
|
|
|
|
# this destination. All destinations on this target
|
|
|
|
# will be in a directory that is built from
|
|
|
|
# root_dir + base_dir + {dir_id}_dir.
|
|
|
|
"root_dir" : "/home/tfiala",
|
|
|
|
|
|
|
|
# The ssh user is specified here.
|
|
|
|
"user": "tfiala",
|
|
|
|
|
|
|
|
# The ssh port is specified here.
|
|
|
|
"port": 22
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
# Describe the lldb-freebsd destination.
|
|
|
|
# Very similar to the lldb-linux one.
|
|
|
|
{
|
|
|
|
"name": "lldb-freebsd"
|
|
|
|
"parent": "common_tot",
|
|
|
|
"ssh": {
|
|
|
|
"dest_host": "lldb-freebsd.example.com",
|
|
|
|
# Specify a different destination-specific root dir here.
|
|
|
|
"root_dir" : "/mnt/ssd02/fialato",
|
|
|
|
"user": "fialato",
|
|
|
|
# The ssh port is specified here.
|
|
|
|
"port": 2022
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
# If a block named "default" exists, and if no configuration
|
|
|
|
# is specified on the command line, then the default block
|
|
|
|
# will be used. Use this block to point to the most common
|
|
|
|
# transfer destination you would use.
|
|
|
|
{
|
|
|
|
"name": "default",
|
|
|
|
"parent": "lldb-linux"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
Using it
|
|
|
|
|
2015-09-18 03:23:50 +08:00
|
|
|
Now that we have a .syncsourcerc file set up, we can do a transfer.
|
|
|
|
The .syncsourcerc file will be searched for as follows, using the
|
2015-09-18 01:14:31 +08:00
|
|
|
first one that is found:
|
|
|
|
|
|
|
|
* First check the --rc-file RCFILE option. If this is specified
|
|
|
|
and doesn't exist, it will raise an error and quit.
|
|
|
|
|
2015-09-18 03:23:50 +08:00
|
|
|
* Check if the current directory has a .syncsourcerc file. If so,
|
2015-09-18 01:14:31 +08:00
|
|
|
use that.
|
|
|
|
|
2015-09-18 03:23:50 +08:00
|
|
|
* Use the .syncsourcerc file from the user's home directory.
|
2015-09-18 01:14:31 +08:00
|
|
|
|
|
|
|
Run the command:
|
2015-09-18 03:23:50 +08:00
|
|
|
python /path/to/syncsource.rc -c {configuration-name}
|
2015-09-18 01:14:31 +08:00
|
|
|
|
|
|
|
The -c {configuration-name} can be left off, in which case a
|
|
|
|
configuration with the name 'default' will be used.
|
|
|
|
|
|
|
|
After that, the transfer will occur. With the rsync-over-ssh
|
|
|
|
transfer agent, one rsync per dir-id will be used. rsync output
|
|
|
|
is redirected to the console.
|
|
|
|
|
|
|
|
FEEDBACK
|
|
|
|
|
|
|
|
Feel free to pass feedback along to Todd Fiala (todd.fiala@gmail.com).
|