# # # add_file "contrib/monotone-cluster-push.lua" # content [66d2897185856543e780ea2f97ac55f8376aaf80] # # patch "contrib/README" # from [ec7b4698c6a257d1ec91a18c74b0dd1a3bef71c6] # to [90c3e67f623b4bc39fc774a09e792989f42e36fd] # ============================================================ --- contrib/monotone-cluster-push.lua 66d2897185856543e780ea2f97ac55f8376aaf80 +++ contrib/monotone-cluster-push.lua 66d2897185856543e780ea2f97ac55f8376aaf80 @@ -0,0 +1,200 @@ +-- Copyright (c) 2007 by Richard Levitte
+-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- 1. Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +-- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------------------------------------------------------------------- +-- Usage: +-- +-- NOTE: THIS SOFTWARE IS ONLY MEANT FOR SERVER PROCESSES! +-- Anything else will fail miserably! +-- +-- in your server's monotonerc, add the following include: +-- +-- include("/PATH/TO/monotone-cluster-push.lua") +-- +-- You may want to change the following variables: +-- +-- MCP_rcfile +-- The absolute path to the configuration file used +-- by this script. It contains basio stanza with the +-- following keys: +-- +-- pattern Branch pattern, as in +-- read-permissions. MUST +-- come first in each stanza. +-- server Server address or address:port +-- to which this pattern should +-- be pushed. There may be many +-- of these. +-- +-- The default is cluster-push.rc located in the server's +-- configuration directory. +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- Variables +------------------------------------------------------------------------------- +MCP_default_rcfile = get_confdir() .. "/cluster-push.rc" + + +if not MCP_rcfile then MCP_rcfile = MCP_default_rcfile end + +------------------------------------------------------------------------------- +-- Local hack of the note_netsync_* functions +------------------------------------------------------------------------------- +do + local debug = false + + local branches = {} + + local saved_note_netsync_start = note_netsync_start + function note_netsync_start(nonce, ...) + if saved_note_netsync_start then + saved_note_netsync_start(nonce, + unpack(arg)) + end + if debug then + io.stderr:write("note_netsync_start: initialise branches\n") + end + branches[nonce] = {} + end + + local saved_note_netsync_cert_received = note_netsync_cert_received + function note_netsync_cert_received(rev_id, key, name, value, nonce, ...) + if saved_note_netsync_cert_received then + saved_note_netsync_cert_received(rev_id, key, name, value, nonce, + unpack(arg)) + end + if debug then + io.stderr:write("note_netsync_cert_received: cert ", name, + " with value ", value, " received\n") + end + if name == "branch" then + if debug then + io.stderr:write("note_netsync_cert_received: branch ", value, + " identified\n") + end + branches[nonce][value] = true + end + end + + local saved_note_netsync_revision_received = note_netsync_revision_received + function note_netsync_revision_received(new_id, revision, certs, nonce, ...) + if saved_note_netsync_revision_received then + saved_note_netsync_revision_received(new_id, revision, certs, nonce, + unpack(arg)) + end + for _, item in pairs(certs) + do + if debug then + io.stderr:write("note_netsync_revision_received: cert ", item.name, + " with value ", item.value, " received\n") + end + if item.name == "branch" then + if debug then + io.stderr:write("note_netsync_revision_received: branch ", + item.value, " identified\n") + end + branches[nonce][item.value] = true + end + end + end + + local saved_note_netsync_end = note_netsync_end + function note_netsync_end(nonce, status, + bytes_in, bytes_out, + certs_in, certs_out, + revs_in, revs_out, + keys_in, keys_out, + ...) + if saved_note_netsync_end then + saved_note_netsync_end(nonce, status, + bytes_in, bytes_out, + certs_in, certs_out, + revs_in, revs_out, + keys_in, keys_out, + unpack(arg)) + end + if debug then + io.stderr:write("note_netsync_end: ", + string.format("%d certs, %d revs, %d keys", + certs_in, revs_in, keys_in), + "\n") + end + if certs_in > 0 or revs_in > 0 or keys_in > 0 then + if debug then + io.stderr:write("note_netsync_end: reading ", MCP_rcfile, "\n") + end + local rcfile = io.open(MCP_rcfile, "r") + if (rcfile == nil) then return false end + local dat = rcfile:read("*a") + io.close(rcfile) + local res = parse_basic_io(dat) + if res == nil then + io.stderr:write("file " .. MCP_rcfile .. " cannot be parsed\n") + return false + end + + local matches = false + local patterns = {} + for i, item in pairs(res) do + if item.name == "pattern" then + matches = false + patterns = {} + for j, val in pairs(item.values) do + if debug then + io.stderr:write("note_netsync_end: found pattern ", val, + "\n") + end + for branch, b in pairs(branches[nonce]) do + if debug then + io.stderr:write("note_netsync_end: trying to match branch ", + branch, "\n") + end + if globish_match(val, branch) then + if debug then + io.stderr:write("note_netsync_end: it matches branch ", + branch, "\n") + end + matches = true + patterns[val] = true + end + end + end + elseif matches then + if item.name == "server" then + for k, server in pairs(item.values) do + for pattern, b in pairs(patterns) do + io.stderr:write("pushing pattern \"" .. pattern .. + "\" to server " .. server .. "\n") + server_request_sync("push", server, pattern, "") + end + end + end + end + end + end + end +end ============================================================ --- contrib/README ec7b4698c6a257d1ec91a18c74b0dd1a3bef71c6 +++ contrib/README 90c3e67f623b4bc39fc774a09e792989f42e36fd @@ -56,3 +56,6 @@ licenses. -- mtn_makepermissions: creates read-permissions and write-permissions from files in the subdirectories read-permissions.d and write-permissions.d, Debian-style. + + -- monotone-cluster-push.lua: A simple script to push changes to other + servers upon receiving them. This will only work on a server instance.