}␊ |
␊ |
/**␊ |
* Run mtn init command to create the corresponding monotone␊ |
* repository and add the database to the configured usher instance␊ |
* Four steps to setup a new monotone project:␊ |
*␊ |
* 1) run mtn db init to initialize a new database underknees␊ |
* 'mtn_repositories'␊ |
* 2) create a new server key in the same directory␊ |
* 3) write monotonerc for access control␊ |
* 4) add the database as new local server in the usher configuration␊ |
* 5) reload the running usher instance so it acknowledges the new␊ |
* server␊ |
*␊ |
* @param IDF_Project␊ |
*/␊ |
|
return;␊ |
}␊ |
␊ |
$repotempl = Pluf::f('mtn_repositories', false);␊ |
if ($repotempl === false) {␊ |
$projecttempl = Pluf::f('mtn_repositories', false);␊ |
if ($projecttempl === false) {␊ |
throw new IDF_Scm_Exception(␊ |
'"mtn_repositories" must be defined in your configuration file.'␊ |
);␊ |
}␊ |
␊ |
$usher_config = Pluf::f('mtn_usher', array());␊ |
if (!array_key_exists('rcfile', $usher_config) ||␊ |
!is_writable($usher_config['rcfile'])) {␊ |
$usher_config = Pluf::f('mtn_usher_conf', false);␊ |
if (!$usher_config || !is_writable($usher_config)) {␊ |
throw new IDF_Scm_Exception(␊ |
'"rcfile" in "mtn_usher" does not exist or is not writable.'␊ |
'"mtn_usher_conf" does not exist or is not writable.'␊ |
);␊ |
}␊ |
␊ |
$shortname = $project->shortname;␊ |
$dbfile = sprintf($repotempl, $shortname);␊ |
if (file_exists($dbfile)) {␊ |
$projectpath = sprintf($projecttempl, $shortname);␊ |
if (file_exists($projectpath)) {␊ |
throw new IDF_Scm_Exception(sprintf(␊ |
__('The project path %s already exists.'), $projectpath␊ |
));␊ |
}␊ |
␊ |
if (!mkdir($projectpath)) {␊ |
throw new IDF_Scm_Exception(sprintf(␊ |
__('The repository %s already exists.'), $dbfile␊ |
__('The project path %s could not be created.'), $projectpath␊ |
));␊ |
}␊ |
$return = 0;␊ |
$output = array();␊ |
␊ |
//␊ |
// step 1) create a new database␊ |
//␊ |
$dbfile = $projectpath.'/database.mtn';␊ |
$cmd = sprintf(␊ |
Pluf::f('mtn_path', 'mtn').' db init -d %s',␊ |
escapeshellarg($dbfile)␊ |
);␊ |
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;␊ |
$ll = exec($cmd, $output, $return);␊ |
$ll = exec($cmd, $output = array(), $return = 0);␊ |
if ($return != 0) {␊ |
throw new IDF_Scm_Exception(sprintf(␊ |
__('The database file %s could not be created.'), $dbfile␊ |
));␊ |
}␊ |
␊ |
//␊ |
// step 2) create a server key␊ |
//␊ |
// try to parse the key's domain part from the remote_url's host␊ |
// name, otherwise fall back to the configured Apache server name␊ |
$server = $_SERVER['SERVER_NAME'];␊ |
$remote_url = Pluf::f('mtn_remote_url');␊ |
if (($parsed = parse_url($remote_url)) !== false &&␊ |
!empty($parsed['host'])) {␊ |
$server = $parsed['host'];␊ |
}␊ |
␊ |
$keyname = $shortname.'-server@'.$server;␊ |
$cmd = sprintf(␊ |
Pluf::f('mtn_path', 'mtn').' au genkey --confdir=%s %s ""',␊ |
escapeshellarg($projectpath),␊ |
escapeshellarg($keyname)␊ |
);␊ |
$cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;␊ |
$ll = exec($cmd, $output = array(), $return = 0);␊ |
if ($return != 0) {␊ |
throw new IDF_Scm_Exception(sprintf(␊ |
__('Could not create repository %s - please check '.␊ |
'your error log for details.'),␊ |
$dbfile␊ |
__('The server key %s could not be created.'), $keyname␊ |
));␊ |
}␊ |
␊ |
$usher_rc = file_get_contents($usher_config['rcfile']);␊ |
//␊ |
// step 3) write monotonerc for access control␊ |
// FIXME: netsync access control is still missing!␊ |
//␊ |
$monotonerc =<<<END␊ |
function get_remote_automate_permitted(key_identity, command, options)␊ |
local read_only_commands = {␊ |
"get_corresponding_path", "get_content_changed", "tags", "branches",␊ |
"common_ancestors", "packet_for_fdelta", "packet_for_fdata",␊ |
"packets_for_certs", "packet_for_rdata", "get_manifest_of",␊ |
"get_revision", "select", "graph", "children", "parents", "roots",␊ |
"leaves", "ancestry_difference", "toposort", "erase_ancestors",␊ |
"descendents", "ancestors", "heads", "get_file_of", "get_file",␊ |
"interface_version", "get_attributes", "content_diff",␊ |
"file_merge", "show_conflicts", "certs", "keys"␊ |
}␊ |
␊ |
for _,v in ipairs(read_only_commands) do␊ |
if (v == command[1]) then␊ |
return true␊ |
end␊ |
end␊ |
␊ |
return false␊ |
end␊ |
END;␊ |
$rcfile = $projectpath.'/monotonerc';␊ |
␊ |
// FIXME: sanity␊ |
$fp = fopen($rcfile, 'w');␊ |
fwrite($fp, $monotonerc);␊ |
fclose($fp);␊ |
␊ |
//␊ |
// step 4) read in and append the usher config with the new server␊ |
//␊ |
$usher_rc = file_get_contents($usher_config);␊ |
$parsed_config = array();␊ |
try {␊ |
$parsed_config = IDF_Scm_Monotone_BasicIO::parse($usher_rc);␊ |
|
catch (Exception $e) {␊ |
throw new IDF_Scm_Exception(sprintf(␊ |
__('Could not parse usher configuration in "%s": %s'),␊ |
$usher_config['rcfile'], $e->getMessage()␊ |
$usher_config, $e->getMessage()␊ |
));␊ |
}␊ |
␊ |
|
␊ |
$new_server = array(␊ |
array('key' => 'server', 'values' => array($shortname)),␊ |
array('key' => 'local', 'values' => array('-d', $dbfile)),␊ |
array('key' => 'local', 'values' => array(␊ |
'--confdir', $projectpath,␊ |
'-d', $dbfile␊ |
)),␊ |
);␊ |
␊ |
$parsed_config[] = $new_server;␊ |
$usher_rc = IDF_Scm_Monotone_BasicIO::compile($parsed_config);␊ |
␊ |
// FIXME: more sanity - what happens on failing writes?␊ |
$fp = fopen($usher_config['rcfile'], 'w');␊ |
$fp = fopen($usher_config, 'w');␊ |
fwrite($fp, $usher_rc);␊ |
fclose($fp);␊ |
␊ |
//␊ |
// step 5) reload usher to pick up the new configuration␊ |
//␊ |
IDF_Scm_Monotone_Usher::reload();␊ |
}␊ |
}␊ |