Skip to content

Commit

Permalink
[tools] export snapshot as file tree. Fixes MER#1384
Browse files Browse the repository at this point in the history
git-vault-export shell script exports git tree corresponding to the snapshot and
resolves vault blobs symlinks to files. Vault C++ and QML API exportSnapshot()
to expose this functionality.

Signed-off-by: Denis Zalevskiy <denis.zalevskiy@jolla.com>
  • Loading branch information
Denis Zalevskiy committed Oct 26, 2015
1 parent 1d44135 commit a27e19b
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 2 deletions.
1 change: 1 addition & 0 deletions include/vault/vault.hpp
Expand Up @@ -102,6 +102,7 @@ class Vault
std::tuple<QString, bool, QString> restoreUnit
(const QString &, const QString &, const QString &);

std::tuple<int, QString, QString> exportSnapshot(QString const &, QString const&);
private:
bool setState(const QString &state);
bool backupUnit(const QString &home, const QString &unit, const ProgressCallback &callback);
Expand Down
20 changes: 20 additions & 0 deletions qml/Vault/vault.cpp
Expand Up @@ -224,6 +224,19 @@ class Worker : public QObject
}
}

Q_INVOKABLE void exportSnapshot(const QString &snapshot, const QString &dstDir)
{
auto res = m_vault->exportSnapshot(snapshot, dstDir);
int rc = std::get<0>(res);
auto data = map({{"snapshot", snapshot}, {"dst", dstDir}
, {"rc", std::get<0>(res)}, {"stdout", std::get<1>(res)}
, {"stderr", std::get<2>(res)}});
if (!rc)
emit done(Vault::ExportSnapshot, data);
else
emit error(Vault::ExportSnapshot, data);
}

signals:
void progress(Vault::Operation op, const QVariantMap &map);
void error(Vault::Operation op, const QVariantMap &error);
Expand Down Expand Up @@ -419,4 +432,11 @@ Q_INVOKABLE void Vault::restoreUnit(const QString &snapshot, const QString &unit
, Q_ARG(QString, unit));
}

void Vault::exportSnapshot(const QString &snapshot, const QString &dstDir)
{
QMetaObject::invokeMethod(m_worker, "exportSnapshot"
, Q_ARG(QString, snapshot)
, Q_ARG(QString, dstDir));
}

#include "vault.moc"
4 changes: 3 additions & 1 deletion qml/Vault/vault.hpp
Expand Up @@ -29,7 +29,8 @@ class Vault : public QObject
ExportImportPrepare,
ExportImportExecute,
Data,
Maintenance
Maintenance,
ExportSnapshot
}
Q_ENUMS(Operation);

Expand Down Expand Up @@ -67,6 +68,7 @@ class Vault : public QObject
Q_INVOKABLE void tagSnapshot(const QString &message);

Q_INVOKABLE void restoreUnit(const QString &, const QString &);
Q_INVOKABLE void exportSnapshot(const QString &, const QString &);

signals:
void rootChanged();
Expand Down
12 changes: 12 additions & 0 deletions src/vault.cpp
Expand Up @@ -797,6 +797,18 @@ bool Vault::restoreUnit(const QString &home, const QString &unit, const Progress
return true;
}

std::tuple<int, QString, QString>
Vault::exportSnapshot(const QString &snapshot, const QString &dstDir)
{
debug::debug("Export snapshot", snapshot, "to", dstDir);
auto l = lock();
auto snapshotName = snapshot;
if (snapshotName[0] != '>')
snapshotName = QString(">") + snapshot;

return executeIn(root(), "git-vault-export", snapshotName, dstDir);
}

/**
* \note thread-unsafe
*/
Expand Down
2 changes: 1 addition & 1 deletion tools/CMakeLists.txt
@@ -1,7 +1,7 @@
configure_file(vault-gc.service.in vault-gc.service @ONLY)

install(
PROGRAMS git-vault-gc gc-default git-vault-snapshot-units
PROGRAMS git-vault-gc gc-default git-vault-snapshot-units git-vault-export
DESTINATION ${TOOLS_DIR}
)

Expand Down
50 changes: 50 additions & 0 deletions tools/git-vault-export
@@ -0,0 +1,50 @@
#!/bin/bash

trace () {
echo "`basename $0`: ${@:1}" 1>&2;
}

error() {
trace $@
exit 1
}

[ $# -eq 2 ] || error "Usage: $0 snapshot dst_dir"

SNAP=$1
DST=$2

if [ "${SNAP:0:1}" != ">" ]; then
SNAP=">$SNAP"
fi

git rev-parse --show-toplevel || error "Not a git dir $(pwd)"
git rev-parse "$SNAP" >/dev/null || error "There is no snapshot $SNAP"
[ -d $DST ] || error "There is no destination dir $DST"

# only $DST itself is expected
COUNT=$(find $DST -maxdepth 1 -not -name '.' | wc -l)
if [ "x$COUNT" != "x1" ]; then
error "Dst dir $DST should be empty, found $COUNT entries"
fi

trace "Export $SNAP to the $DST"

GIT_DIR=$(pwd)
(git archive --format=tar "$SNAP" | tar -C $DST -xf -) || \
error "Export of $SNAP to the $DST is failed"

find $DST -type l | grep '/blobs/' | while read -r LINK
do
NAME=$(readlink $LINK)
# match minimal relative blob ref (path inside the tree is unit/blobs/link)
if [[ $NAME =~ \.\./\.\./\.git/blobs/ ]]; then
FNAME=$(basename $NAME)
DNAME="$GIT_DIR/.git/blobs/$(basename $(dirname $NAME))"
[ -d $DNAME ] || error "There is no blob dir $DNAME for $LINK"
FNAME="$DNAME/$FNAME"
[ -f $FNAME ] || error "There is no blob file $FNAME for $LINK"
unlink $LINK || error "Can't unlink $LINK"
cp $FNAME $LINK || error "Can't copy $FNAME to $LINK"
fi
done

0 comments on commit a27e19b

Please sign in to comment.