mirror of
https://github.com/opnsense/plugins.git
synced 2026-05-28 04:34:15 -04:00
Git backup: work in progress for https://github.com/opnsense/plugins/issues/2049
o add missing dependancy in Makefile o add branch in Model o implement backup() method, which is responsible for setting up a git repo and pushing it upstream. The actual "git add+commit" is a responsibility of the syshook config event (todo) sponsored by : Modirum (https://www.modirum.com/)
This commit is contained in:
parent
23bca983e6
commit
c73274fc64
3 changed files with 81 additions and 7 deletions
|
|
@ -1,7 +1,7 @@
|
|||
PLUGIN_NAME= git-backup
|
||||
PLUGIN_VERSION= 0.1
|
||||
PLUGIN_COMMENT= Track config changes using git
|
||||
PLUGIN_MAINTAINER= ad@opnsense.org
|
||||
PLUGIN_DEVEL= yes
|
||||
PLUGIN_NAME= git-backup
|
||||
PLUGIN_VERSION= 0.1
|
||||
PLUGIN_COMMENT= Track config changes using git
|
||||
PLUGIN_DEPENDS= git
|
||||
PLUGIN_MAINTAINER= ad@opnsense.org
|
||||
|
||||
.include "../../Mk/plugins.mk"
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
namespace OPNsense\Backup;
|
||||
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Core\Config;
|
||||
use OPNsense\Backup\GitSettings;
|
||||
|
||||
|
|
@ -59,6 +60,13 @@ class Git extends Base implements IBackupProvider
|
|||
"help" => gettext("Target location, which defined transport protocol, such as ssh://server/project.git or https://server/project.git."),
|
||||
"value" => null
|
||||
],
|
||||
[
|
||||
"name" => "branch",
|
||||
"type" => "text",
|
||||
"label" => gettext("Branch"),
|
||||
"help" => gettext("Target branch to push to."),
|
||||
"value" => null
|
||||
],
|
||||
[
|
||||
"name" => "privkey",
|
||||
"type" => "textarea",
|
||||
|
|
@ -110,11 +118,73 @@ class Git extends Base implements IBackupProvider
|
|||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* Backup is responsible for initialising the local repo and pusing it to upstream.
|
||||
* To ensure initial content, we should trigger a 'system event config_changed' which should enforce a
|
||||
* add + commit in our (newly created) repo.
|
||||
*
|
||||
* Since our backup method is also called from the userinterface directly, we should try to prevent the need
|
||||
* for elevated rights. Since all actions are concentrated within the config directory, we only need read/exec
|
||||
* access on git. (detaching this further would deviate the implementation from the existing ones)
|
||||
*
|
||||
* @return array filelist
|
||||
*/
|
||||
public function backup()
|
||||
{
|
||||
return ['config.xml'];
|
||||
$targetdir = "/conf/backup/git";
|
||||
$git = "/usr/local/bin/git";
|
||||
$mdl = new GitSettings();
|
||||
if (!is_dir($targetdir)) {
|
||||
mkdir($targetdir);
|
||||
}
|
||||
if (!is_dir('{$targetdir}/.git')) {
|
||||
exec("{$git} init {$targetdir}");
|
||||
}
|
||||
// XXX: since our git backup is plain text and already contains the private key, it doesn't really matter
|
||||
// to keep the same key in the git directory (we're not going to push it)
|
||||
$ident_file = "{$targetdir}/identity";
|
||||
$privkey = trim(str_replace("\r", "", (string)$mdl->privkey)) . "\n";
|
||||
file_put_contents($ident_file, $privkey);
|
||||
chmod("{$targetdir}/identity", 0600);
|
||||
// When there are unprocessed config backups, flush them out.
|
||||
(new Backend())->configdRun("system event config_changed");
|
||||
// configure upstream
|
||||
exec("cd {$targetdir} && ".
|
||||
"{$git} config core.sshCommand ".
|
||||
"\"ssh -i {$ident_file} -o StrictHostKeyChecking=accept-new -o PasswordAuthentication=no\""
|
||||
);
|
||||
$url = (string)$mdl->url;
|
||||
$pos = strpos($url, '//');
|
||||
// inject credentials in url (either username or username:password, depending on transport)
|
||||
if (stripos(trim((string)$mdl->$url),'http')) {
|
||||
$cred = urlencode((string)$mdl->user) . ":" . urlencode((string)$mdl->password);
|
||||
$url = substr($url,0, $pos+2) . "{$cred}@" . substr($url, $pos+2);
|
||||
} else {
|
||||
$url = substr($url,0, $pos+2) . urlencode((string)$mdl->user) . "@" . substr($url, $pos+2);
|
||||
}
|
||||
exec("cd {$targetdir} && git remote remove origin");
|
||||
exec("cd {$targetdir} && git remote add origin ". escapeshellarg($url));
|
||||
$pushtxt = shell_exec(
|
||||
"(cd {$targetdir} && git push origin " . escapeshellarg("master:{$mdl->branch}") .
|
||||
" && echo '__exit_ok__') 2>&1"
|
||||
);
|
||||
if (strpos($pushtxt, '__exit_ok__')) {
|
||||
$error_type = null;
|
||||
} elseif (strpos($pushtxt, 'Permission denied')) {
|
||||
$error_type = "authentication failure";
|
||||
} elseif (strpos($pushtxt, 'WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED')) {
|
||||
$error_type = "ssh hostkey changed";
|
||||
} elseif (strpos($pushtxt, "remote contains work that you do")) {
|
||||
$error_type = "git out of sync";
|
||||
} else {
|
||||
$error_type = "unknown error, check log for details";
|
||||
}
|
||||
if (!empty($error_type)) {
|
||||
syslog(LOG_ERR, "git-backup {$error_type} (".str_replace("\n", " ", $pushtxt).")");
|
||||
throw new \Exception($error_type);
|
||||
} else {
|
||||
// return filelist in git
|
||||
return explode("\n", shell_exec("cd {$targetdir} && git ls-files"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@
|
|||
</check001>
|
||||
</Constraints>
|
||||
</url>
|
||||
<branch type="TextField">
|
||||
<default>master</default>
|
||||
<Required>Y</Required>
|
||||
</branch>
|
||||
<privkey type="TextField">
|
||||
<Required>N</Required>
|
||||
</privkey>
|
||||
|
|
|
|||
Loading…
Reference in a new issue