Skip to content

Commit

Permalink
Merge pull request #16 from deztructor/vault-gc
Browse files Browse the repository at this point in the history
Garbage collection support
  • Loading branch information
Denis Zalevskiy committed Oct 29, 2014
2 parents 4da0ddd + c201710 commit 03a379c
Show file tree
Hide file tree
Showing 14 changed files with 370 additions and 5 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -23,4 +23,5 @@ units/vault-*
*.moc
tests/tests.xml
tests/*_unit.cpp
tests/*_vault_test
tests/*_vault_test
src/config.hpp
3 changes: 3 additions & 0 deletions CMakeLists.txt
@@ -1,6 +1,8 @@
PROJECT(VAULT)
cmake_minimum_required(VERSION 2.8.8)

set(prefix ${CMAKE_INSTALL_PREFIX})

IF(NOT DEFINED VERSION OR VERSION STREQUAL "")
message(FATAL_ERROR "Define VERSION")
ENDIF(NOT DEFINED VERSION OR VERSION STREQUAL "")
Expand Down Expand Up @@ -61,6 +63,7 @@ add_subdirectory(src)
add_subdirectory(examples)
add_subdirectory(tests)
add_subdirectory(qml/Vault)
add_subdirectory(tools)

configure_file(vault-unit.pc.in vault-unit.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/vault-unit.pc DESTINATION ${DST_LIB}/pkgconfig)
Expand Down
6 changes: 6 additions & 0 deletions qml/Vault/vault.cpp
Expand Up @@ -308,4 +308,10 @@ void Vault::registerUnit(const QJSValue &unit, bool global)
}
}

void Vault::startGc()
{
if (os::system("systemctl", {"--user", "start", "vault-gc.service"}) != 0)
debug::error("Can't start vault-gc.service");
}

#include "vault.moc"
1 change: 1 addition & 0 deletions qml/Vault/vault.hpp
Expand Up @@ -52,6 +52,7 @@ class Vault : public QObject
Q_INVOKABLE QString notes(const QString &snapshot) const;

Q_INVOKABLE void registerUnit(const QJSValue &unit, bool global);
Q_INVOKABLE void startGc();

signals:
void rootChanged();
Expand Down
29 changes: 26 additions & 3 deletions rpm/vault.spec
@@ -1,3 +1,5 @@
%{!?_with_usersession: %{!?_without_usersession: %define _with_usersession --with-usersession}}

Summary: Incremental backup/restore framework
Name: vault
Version: 0.1.0
Expand All @@ -12,13 +14,15 @@ BuildRequires: pkgconfig(gittin)
BuildRequires: pkgconfig(tut) >= 0.0.3
BuildRequires: pkgconfig(Qt5Core) >= 5.2.0
BuildRequires: pkgconfig(Qt5Qml)
BuildRequires: pkgconfig(qtaround) >= 0.2.0
%{?_with_usersession:Requires: systemd-user-session-targets}
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig

%description
Incremental backup/restore framework

%{?_with_usersession:%define _userunitdir %{_libdir}/systemd/user/}

%package devel
Summary: vault headers etc.
Group: Development/Libraries
Expand All @@ -45,16 +49,26 @@ make %{?jobs:-j%jobs}
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=%{buildroot}

%if 0%{?_with_usersession:1}
install -D -p -m644 tools/vault-gc.service %{buildroot}%{_userunitdir}/vault-gc.service
%endif

%clean
rm -rf $RPM_BUILD_ROOT

%define tools_dir %{_libexecdir}/vault

%files
%defattr(-,root,root,-)
%{_libdir}/libvault-core.so*
%{_libdir}/libvault-transfer.so*
%{_libdir}/libvault-unit.so*
%{_libdir}/qt5/qml/NemoMobile/Vault/*
%{_bindir}/vault
%{tools_dir}/*
%if 0%{?_with_usersession:1}
%{_userunitdir}/vault-gc.service
%endif

%files devel
%defattr(-,root,root,-)
Expand All @@ -66,5 +80,14 @@ rm -rf $RPM_BUILD_ROOT
%defattr(-,root,root,-)
/opt/tests/vault/*

%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%post
/sbin/ldconfig || :
%if 0%{?_with_usersession:1}
systemctl-user daemon-reload || :
%endif

%postun
/sbin/ldconfig || :
%if 0%{?_with_usersession:1}
systemctl-user daemon-reload || :
%endif
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Expand Up @@ -9,6 +9,8 @@ link_directories(

set(CMAKE_AUTOMOC TRUE)

configure_file(config.hpp.in config.hpp @ONLY)

add_library(vault-core SHARED vault.cpp vault_config.cpp)
qt5_use_modules(vault-core Core)
target_link_libraries(vault-core
Expand Down
6 changes: 6 additions & 0 deletions src/config.hpp.in
@@ -0,0 +1,6 @@
#ifndef _SRC_VAULT_CONFIG_HPP_
#define _SRC_VAULT_CONFIG_HPP_

#define VAULT_LIBEXEC_PATH "@prefix@/libexec/vault"

#endif // _SRC_VAULT_CONFIG_HPP_
12 changes: 11 additions & 1 deletion src/vault.cpp
Expand Up @@ -6,6 +6,7 @@
* @par License: LGPL 2.1 http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
*/

#include "config.hpp"
#include <vault/vault.hpp>

#include <qtaround/util.hpp>
Expand All @@ -29,7 +30,6 @@ namespace subprocess = qtaround::subprocess;
namespace error = qtaround::error;
namespace debug = qtaround::debug;


namespace vault {

static const QMap<File, QString> fileNames = {
Expand Down Expand Up @@ -185,6 +185,16 @@ int Vault::execute(const QVariantMap &options)
error::raise({{"action", action}, {"msg", "Needs unit name"}});
}
vault.unregisterUnit(options.value("unit").toString());
} else if (action == "gc") {
auto p = subprocess::Process();
p.setWorkingDirectory(vault.root());
p.start(os::path::join(VAULT_LIBEXEC_PATH, "git-vault-gc"), {});
p.wait(-1);
QTextStream out(stdout, QIODevice::WriteOnly);
QTextStream err(stderr, QIODevice::WriteOnly);
out << p.stdout() << endl;
err << p.stderr() << endl;
return p.rc();
} else {
error::raise({{"msg", "Unknown action"}, {"action", action}});
}
Expand Down
11 changes: 11 additions & 0 deletions tools/CMakeLists.txt
@@ -0,0 +1,11 @@
configure_file(vault-gc.service.in vault-gc.service @ONLY)

install(
PROGRAMS git-vault-gc gc-default
DESTINATION libexec/vault
)

install(
FILES git-vault-rebase-generate.awk git-vault-rebase-prepare.awk
DESTINATION libexec/vault
)
2 changes: 2 additions & 0 deletions tools/gc-default
@@ -0,0 +1,2 @@
#!/bin/sh
/usr/bin/vault -H $HOME -V $HOME/.vault -a gc
131 changes: 131 additions & 0 deletions tools/git-vault-gc
@@ -0,0 +1,131 @@
#!/bin/bash

function error {
echo "`basename $0`: Error: ${@:1}" 1>&2;
exit 1
}

ARGS=$(getopt -o fdD -- "$@");

if [ $? -ne 0 ]; then
exit 1
fi

force=false
dump=false
dump_intention=false

while true; do
case "$1" in
-f)
force=true
shift;
;;
-d)
dump=true
shift;
;;
-D)
dump_intention=true
shift;
;;
*)
if [ $# -eq 0 ]; then
break;
fi
error "Unknown option $1"
break;
esac
done

src=$(dirname $0)
src=$(cd $src;pwd)

root=$(git rev-parse --show-toplevel)
rc=$?

if [ $rc -ne 0 ] || [ "x$root" == "x" ]; then
error "Not a git $root"
fi

test -d "$root" || error "Not a dir $root"
test -e "$root/.vault" || error "Not a vault $root"

cd $root || error "Can't enter $root"

cmd_file=$(mktemp)
git log --pretty=format:%H$%d$%s \
| gawk -f $src/git-vault-rebase-prepare.awk \
| tac > $cmd_file
trap "rm $cmd_file" EXIT

function gen_cmd {
cat $cmd_file | gawk -f $src/git-vault-rebase-generate.awk
}

if ($dump || $dump_intention); then
$dump_intention && cat $cmd_file
$dump && gen_cmd
exit 0
fi

if ! grep '^\(old_tag\|skip\)' $cmd_file; then
echo "There is no need in gc for the $root"
if ! $force; then
exit 0
fi
echo "Forcing gc"
fi

cmd=$(gen_cmd)

function git_gc {
echo "GC"
git prune
git gc --aggressive
echo "PRUNE+"
git prune
}

function rollback {
echo "ROLLBACK"
git reset --hard
git clean -fd
git checkout master
git branch -D migrate
for t in $(git tag | grep '^migrate/'); do
git tag -d "$t"
done
git_gc
error "during migration"
}

export -f rollback

eval "$cmd" || error "$cmd"

echo "REPLACE MASTER"
# do it separetely to be on the safe side and keep old master until the last moment
(git branch -m migrate migrated && \
git branch -m master old-master && \
git branch -m migrated master && \
git branch -D old-master) || error "replacing master"

echo "CLEAR REFLOG"
git reflog expire --expire=now --all || error "clearing reflog"

echo "REMOVING DANGLING BLOBS"
for obj in $(git fsck --unreachable master \
| grep '^unreachable blob' \
| sed 's/unreachable blob //'); do
for blob in $(git show $obj \
| head -n 1 \
| grep '\.\./\.git/blobs' \
| sed 's:^[./]*\.git/blobs:.git/blobs:'); do
echo "Orphan $blob"
(test -f $blob && (rm $blob -f || echo "Can't remove $blob")) \
|| echo "No such blob $blob"
done
done
git_gc
echo "OK"

0 comments on commit 03a379c

Please sign in to comment.