commit 44f21712387b9a4d37dc05c4aca5796d08af9556
parent e5108dc86261ca9c7902d7740c04c3648a4cb39a
Author: Remy Noulin (Spartatek) <remy.noulin@spartatek.se>
Date: Tue, 22 Nov 2016 22:19:06 +0100
Fix ssh config, add integrity check
README.md | 13 +++++
package.json | 2 +-
src/git-off | 143 ++++++++++++++++++++++++----------------------------
src/gitoff.coffee | 146 +++++++++++++++++++++++++-----------------------------
4 files changed, 148 insertions(+), 156 deletions(-)
Diffstat:
| M | README.md | | | 13 | +++++++++++++ |
| M | package.json | | | 2 | +- |
| M | src/git-off | | | 143 | +++++++++++++++++++++++++++++++++++++------------------------------------------- |
| M | src/gitoff.coffee | | | 146 | +++++++++++++++++++++++++++++++++++++------------------------------------------ |
4 files changed, 148 insertions(+), 156 deletions(-)
diff --git a/README.md b/README.md
@@ -10,6 +10,14 @@ By default the files are stored in the home directory.
npm install -g git-off
```
+Then
+
+```
+git off
+```
+
+for help.
+
[https://www.npmjs.com/package/git-off](https://www.npmjs.com/package/git-off)
# USAGE
@@ -60,6 +68,11 @@ git off install [thisrepo]
git off mode [thisrepo] [copy|scp]
set/show git off mode
+git off integrity [thisrepo] [enable|disable]
+ set/show git off integrity.
+ when enabled, the SHA of the file received from the store is
+ checked again the SHA of the original file
+
git off scp [thisrepo] [host]
setup scp config
host has format host:path
diff --git a/package.json b/package.json
@@ -1,6 +1,6 @@
{
"name": "git-off",
- "version": "0.0.2",
+ "version": "0.0.3",
"description": "large file handler for git",
"bin": "./src/git-off",
"scripts": {
diff --git a/src/git-off b/src/git-off
@@ -1,65 +1,5 @@
#! /usr/bin/env node
/*
- * USAGE
- *
- * COMMANDS
- *
- * git off install [thisrepo]
- * setup git config (default global)
- * thisrepo sets up config in current repo
- *
- * git off mode [thisrepo] [copy|scp]
- * set/show git off mode
- *
- * git off scp [thisrepo] [host]
- * setup scp config
- * host has format host:path
- * Example: localhost:/tmp/offStore
- *
- * git off scpuser [thisrepo] [username]
- * setup scp username config
- *
- * git off track
- * setup gitattribute filters
- * example: git off track '*.bin'
- * without parameter, list git off attributes
- * calls git off install
- *
- * git off clean
- * internal filter
- *
- * git off smudge
- * internal filter
- *
- * git off pre-push
- * internal filter
- *
- * git off smudge
- * internal filter
- *
- * git off clearAll
- * git off ca
- * delete store, cache and log
- *
- * git off clearCache
- * git off cc
- * deletes cache in current git
- *
- * git off defaults
- * shows first time config
- *
- * git off env
- * shows config
- *
- * git off help
- * shows git off help
- *
- * config:
- * gitoff mode rsync, http, copy
- * store=/we
- */
-
-/*
* CODE
*
* modules
@@ -149,6 +89,7 @@ runtimeConfig = {
'objectPath': '',
'offStore': '',
'offMode': '',
+ 'offIntegrity': '',
'offScp': '',
'offScpUser': '',
'log': ''
@@ -157,6 +98,7 @@ runtimeConfig = {
offDEFAULTS = {
'objectPath': '/.git/off/objects',
'mode': 'copy',
+ 'integrity': 'disable',
'store': '~/.git-off/offStore',
'log': '~/.git-off/log',
'prePush': '#!/bin/sh\ncommand -v git-off >/dev/null 2>&1 || { echo >&2 "\\nThis repository is configured for Git off but \'git-off\' was not found on your path. If you no longer wish to use git off, remove this hook by deleting .git/hooks/pre-push.\\n"; exit 2; }\ngit off pre-push "$@"',
@@ -284,6 +226,14 @@ offHelpers = {
}
return runtimeConfig.offMode;
},
+ 'offIntegrity': function() {
+ var r;
+ if (runtimeConfig.offIntegrity === '') {
+ r = gitConfig.get('off.integrity');
+ runtimeConfig.offIntegrity = expandHome(r);
+ }
+ return runtimeConfig.offIntegrity;
+ },
'offScp': function() {
if (runtimeConfig.offScp === '') {
runtimeConfig.offScp = gitConfig.get('off.scphost');
@@ -327,9 +277,13 @@ offHelpers = {
var h_l, host, port, portAndPath_l, storePath, user;
user = offHelpers.userAt();
h_l = offHelpers.offScp().split(':');
- portAndPath_l = h_l[1].split('/');
- port = parseInt(portAndPath_l[0]);
- if (port === NaN) {
+ if (h_l[1] === void 0) {
+ port = NaN;
+ } else {
+ portAndPath_l = h_l[1].split('/');
+ port = parseInt(portAndPath_l[0]);
+ }
+ if (isNaN(port)) {
host = h_l[0];
storePath = h_l[1];
} else {
@@ -343,7 +297,7 @@ offHelpers = {
h_l = offHelpers.getSSHConfig();
sshCmd = '"mkdir -p ' + h_l[1] + '/' + path;
sshCmd += '"';
- if (h_l[2] === NaN) {
+ if (isNaN(h_l[2])) {
exec('ssh', [h_l[0], sshCmd], true);
} else {
exec('ssh', ['-p ' + h_l[2], h_l[0], sshCmd], true);
@@ -354,12 +308,27 @@ offHelpers = {
h_l = offHelpers.getSSHConfig();
sshCmd = '"rm -rf ' + h_l[1] + '/' + path;
sshCmd += '"';
- if (h_l[2] === NaN) {
+ if (isNaN(h_l[2])) {
exec('ssh', [h_l[0], sshCmd], true);
} else {
exec('ssh', ['-p ' + h_l[2], h_l[0], sshCmd], true);
}
},
+ 'checkIntegrity': function(path) {
+ var path_l, r, receivedSha, result;
+ result = true;
+ if (offHelpers.offIntegrity() === 'disable') {
+ return true;
+ }
+ r = exec('sha', [path]);
+ receivedSha = r.stdout.split(' ')[0].trim();
+ path_l = path.split('/');
+ if (path_l[path_l.length - 1] !== receivedSha) {
+ console.log('git-off: The file ' + path + ' differs from the one that was pushed.');
+ result = false;
+ }
+ return result;
+ },
'setTransport': function() {
if (offHelpers.offMode() === 'copy') {
transport['send'] = function(file) {
@@ -373,37 +342,39 @@ offHelpers = {
};
transport['receive'] = function(file) {
var readStream;
- readStream = fs.createReadStream(offHelpers.offStore() + '/' + file);
- readStream.pipe(process.stdout);
+ if (offHelpers.checkIntegrity(offHelpers.offStore() + '/' + file)) {
+ readStream = fs.createReadStream(offHelpers.offStore() + '/' + file);
+ readStream.pipe(process.stdout);
+ }
};
} else if (offHelpers.offMode() === 'scp') {
transport['send'] = function(file) {
- var f_l, h_l, user;
- user = offHelpers.userAt();
+ var f_l, h_l;
f_l = file.split('/');
offHelpers.mkdirStore(f_l[0] + '/' + f_l[1]);
h_l = offHelpers.getSSHConfig();
- if (h_l[2] === NaN) {
- exec('scp', [offHelpers.objectPath() + '/' + file, user + offHelpers.offScp() + '/' + file]);
+ if (isNaN(h_l[2])) {
+ exec('scp', [offHelpers.objectPath() + '/' + file, h_l[0] + ':' + h_l[1] + '/' + file]);
} else {
exec('scp', ['-P ' + h_l[2], offHelpers.objectPath() + '/' + file, h_l[0] + ':' + h_l[1] + '/' + file]);
}
};
transport['receive'] = function(file) {
- var f_l, h_l, readStream, user;
+ var f_l, h_l, readStream;
f_l = file.split('/');
if (fs.existsSync(offHelpers.objectPath() + '/' + f_l[0] + '/' + f_l[1]) === false) {
mkdirParents(offHelpers.objectPath() + '/' + f_l[0] + '/' + f_l[1]);
}
- user = offHelpers.userAt();
h_l = offHelpers.getSSHConfig();
- if (h_l[2] === NaN) {
- exec('scp', [user + offHelpers.offScp() + '/' + file, offHelpers.objectPath() + '/' + file]);
+ if (isNaN(h_l[2])) {
+ exec('scp', [h_l[0] + ':' + h_l[1] + '/' + file, offHelpers.objectPath() + '/' + file]);
} else {
exec('scp', ['-P ' + h_l[2], h_l[0] + ':' + h_l[1] + '/' + file, offHelpers.objectPath() + '/' + file]);
}
- readStream = fs.createReadStream(offHelpers.objectPath() + '/' + file);
- readStream.pipe(process.stdout);
+ if (offHelpers.checkIntegrity(offHelpers.objectPath() + '/' + file)) {
+ readStream = fs.createReadStream(offHelpers.objectPath() + '/' + file);
+ readStream.pipe(process.stdout);
+ }
};
}
},
@@ -461,6 +432,9 @@ offCommands = {
if (offHelpers.offMode() === '' || setCfg !== gitConfig.set) {
setCfg('off.mode', offDEFAULTS.mode);
}
+ if (offHelpers.offIntegrity() === '' || setCfg !== gitConfig.set) {
+ setCfg('off.integrity', offDEFAULTS.integrity);
+ }
if (offHelpers.offStore() === '' || setCfg !== gitConfig.set) {
setCfg('off.store', offDEFAULTS.store);
}
@@ -491,6 +465,16 @@ offCommands = {
console.log('off.scp '.blue.bold + offHelpers.offScp());
}
},
+ 'integrity': function(setCfg) {
+ var integrity, len;
+ len = process.argv.length;
+ integrity = process.argv[len - 1];
+ if (integrity !== 'integrity' && integrity !== 'thisrepo') {
+ setCfg('off.integrity', integrity);
+ } else {
+ console.log('off.integrity '.blue.bold + offHelpers.offIntegrity());
+ }
+ },
'scpUser': function(setCfg) {
var len, scpUser;
len = process.argv.length;
@@ -639,6 +623,7 @@ offCommands = {
},
'env': function() {
console.log('off.mode '.blue.bold + offHelpers.offMode());
+ console.log('off.integrity '.blue.bold + offHelpers.offIntegrity());
console.log('off.store '.blue.bold + offHelpers.offStore());
console.log('off.scphost '.blue.bold + offHelpers.offScp());
console.log('off.scpuser '.blue.bold + offHelpers.offScpUser());
@@ -671,6 +656,10 @@ if (process.argv[2] === 'scp') {
thisrepo(offCommands['scp']);
}
+if (process.argv[2] === 'integrity') {
+ thisrepo(offCommands['integrity']);
+}
+
if (process.argv[2] === 'scpuser') {
thisrepo(offCommands['scpUser']);
}
diff --git a/src/gitoff.coffee b/src/gitoff.coffee
@@ -7,70 +7,14 @@
# add pem config
# handle wrong config like getLog
# add a command to copy stores
+# check parameters from CLI
#
# parse params
# use logger
#
-
-###
-# USAGE
-#
-# COMMANDS
-#
-# git off install [thisrepo]
-# setup git config (default global)
-# thisrepo sets up config in current repo
-#
-# git off mode [thisrepo] [copy|scp]
-# set/show git off mode
-#
-# git off scp [thisrepo] [host]
-# setup scp config
-# host has format host:path
-# Example: localhost:/tmp/offStore
-#
-# git off scpuser [thisrepo] [username]
-# setup scp username config
-#
-# git off track
-# setup gitattribute filters
-# example: git off track '*.bin'
-# without parameter, list git off attributes
-# calls git off install
-#
-# git off clean
-# internal filter
-#
-# git off smudge
-# internal filter
-#
-# git off pre-push
-# internal filter
-#
-# git off smudge
-# internal filter
-#
-# git off clearAll
-# git off ca
-# delete store, cache and log
-#
-# git off clearCache
-# git off cc
-# deletes cache in current git
-#
-# git off defaults
-# shows first time config
-#
-# git off env
-# shows config
-#
-# git off help
-# shows git off help
-#
-# config:
-# gitoff mode rsync, http, copy
-# store=/we
-###
+# How to add a new config
+# How to add a new transport
+# How to add a new command
###
# CODE
@@ -155,6 +99,7 @@ runtimeConfig =
'objectPath': ''
'offStore': ''
'offMode': ''
+ 'offIntegrity': ''
'offScp': ''
'offScpUser': ''
'log': ''
@@ -164,6 +109,7 @@ runtimeConfig =
offDEFAULTS =
'objectPath': '/.git/off/objects'
'mode': 'copy'
+ 'integrity': 'disable'
'store': '~/.git-off/offStore'
'log': '~/.git-off/log'
'prePush': '#!/bin/sh\ncommand -v git-off >/dev/null 2>&1 || { echo >&2 "\\nThis repository is configured for Git off but \'git-off\' was not found on your path. If you no longer wish to use git off, remove this hook by deleting .git/hooks/pre-push.\\n"; exit 2; }\ngit off pre-push "$@"'
@@ -270,6 +216,7 @@ copy = (src, dst) ->
# objectPath: sets and returns runtimeConfig.objectPath
# offStore: sets and returns runtimeConfig.offStore
# offMode: sets and returns runtimeConfig.offMode
+# offIntegrity sets and returns runtimeConfig.offIntegrity
# offScp: sets and returns runtimeConfig.offScp
# offScpUser: sets and returns runtimeConfig.offScpUser
# log: sets and returns runtimeConfig.log
@@ -278,6 +225,7 @@ copy = (src, dst) ->
# getSSHConfig extracts host, port and path from off.sshhost
# mkdirStore mkdir in remote store
# rmAllStore rm in remote store
+# checkIntegrity check integrity of files coming from the store
# setTransport: set send and receive functions for transport
# getOffFilePath: creates path for offFile
offHelpers =
@@ -304,6 +252,12 @@ offHelpers =
runtimeConfig.offMode = expandHome r
runtimeConfig.offMode
+ 'offIntegrity': ->
+ if runtimeConfig.offIntegrity == ''
+ r = gitConfig.get 'off.integrity'
+ runtimeConfig.offIntegrity = expandHome r
+ runtimeConfig.offIntegrity
+
'offScp': ->
if runtimeConfig.offScp == ''
runtimeConfig.offScp = gitConfig.get 'off.scphost'
@@ -343,9 +297,12 @@ offHelpers =
user = offHelpers.userAt()
h_l = offHelpers.offScp().split(':')
- portAndPath_l = h_l[1].split('/')
- port = parseInt portAndPath_l[0]
- if port == NaN
+ if h_l[1] == undefined
+ port = NaN
+ else
+ portAndPath_l = h_l[1].split('/')
+ port = parseInt portAndPath_l[0]
+ if isNaN port
# use default port
host = h_l[0]
storePath = h_l[1]
@@ -365,7 +322,7 @@ offHelpers =
sshCmd += '"'
# ignore error from mkdir for already existing store
- if h_l[2] == NaN
+ if isNaN h_l[2]
exec 'ssh', [h_l[0], sshCmd], true
else
exec 'ssh', ['-p ' + h_l[2], h_l[0], sshCmd], true
@@ -380,12 +337,33 @@ offHelpers =
sshCmd = '"rm -rf '+ h_l[1] + '/' + path
sshCmd += '"'
# ignore error from rm
- if h_l[2] == NaN
+ if isNaN h_l[2]
exec 'ssh', [h_l[0], sshCmd], true
else
exec 'ssh', ['-p ' + h_l[2], h_l[0], sshCmd], true
return
+ 'checkIntegrity': (path) ->
+ # check integrity of files coming from the store
+
+ result = true
+
+ if offHelpers.offIntegrity() == 'disable'
+ return true
+
+ r = exec 'sha', [path]
+ # trim because git hash-object adds \n
+ receivedSha = r.stdout.split(' ')[0].trim()
+
+ path_l = path.split('/')
+
+ if path_l[path_l.length-1] != receivedSha
+ # the file received is different from the one that was sent.
+ console.log 'git-off: The file ' + path + ' differs from the one that was pushed.'
+ result = false
+
+ result
+
'setTransport': ->
# set send and receive functions for transport
# copy, scp
@@ -401,22 +379,21 @@ offHelpers =
fs.chmodSync offHelpers.offStore() + '/' + file, '444'
return
transport['receive'] = (file) ->
- readStream = fs.createReadStream(offHelpers.offStore() + '/' + file)
- readStream.pipe(process.stdout)
+ if offHelpers.checkIntegrity offHelpers.offStore() + '/' + file
+ readStream = fs.createReadStream(offHelpers.offStore() + '/' + file)
+ readStream.pipe(process.stdout)
return
else if offHelpers.offMode() == 'scp'
transport['send'] = (file) ->
- user = offHelpers.userAt()
# create file directories in store
f_l = file.split '/'
offHelpers.mkdirStore f_l[0] + '/' + f_l[1]
- #TODO remove user
h_l = offHelpers.getSSHConfig()
- if h_l[2] == NaN
- exec 'scp', [offHelpers.objectPath() + '/' + file, user + offHelpers.offScp() + '/' + file]
+ if isNaN h_l[2]
+ exec 'scp', [offHelpers.objectPath() + '/' + file, h_l[0] + ':' + h_l[1] + '/' + file]
else
exec 'scp', ['-P ' + h_l[2], offHelpers.objectPath() + '/' + file, h_l[0] + ':' + h_l[1] + '/' + file]
return
@@ -426,17 +403,15 @@ offHelpers =
if fs.existsSync(offHelpers.objectPath() + '/' + f_l[0] + '/' + f_l[1]) == false
mkdirParents offHelpers.objectPath() + '/' + f_l[0] + '/' + f_l[1]
- user = offHelpers.userAt()
-
- #TODO remove user
h_l = offHelpers.getSSHConfig()
- if h_l[2] == NaN
- exec 'scp', [user + offHelpers.offScp() + '/' + file, offHelpers.objectPath() + '/' + file]
+ if isNaN h_l[2]
+ exec 'scp', [h_l[0] + ':' + h_l[1] + '/' + file, offHelpers.objectPath() + '/' + file]
else
exec 'scp', ['-P ' + h_l[2], h_l[0] + ':' + h_l[1] + '/' + file, offHelpers.objectPath() + '/' + file]
- readStream = fs.createReadStream(offHelpers.objectPath() + '/' + file)
- readStream.pipe(process.stdout)
+ if offHelpers.checkIntegrity offHelpers.objectPath() + '/' + file
+ readStream = fs.createReadStream(offHelpers.objectPath() + '/' + file)
+ readStream.pipe(process.stdout)
return
return
'getOffFilePath': (offFile) ->
@@ -516,6 +491,8 @@ offCommands =
if offHelpers.offMode() == '' or setCfg != gitConfig.set
setCfg('off.mode', offDEFAULTS.mode)
+ if offHelpers.offIntegrity() == '' or setCfg != gitConfig.set
+ setCfg('off.integrity', offDEFAULTS.integrity)
if offHelpers.offStore() == '' or setCfg != gitConfig.set
setCfg('off.store',offDEFAULTS.store)
@@ -546,6 +523,15 @@ offCommands =
console.log 'off.scp '.blue.bold + offHelpers.offScp()
return
+ 'integrity': (setCfg) ->
+ len = process.argv.length
+ integrity = process.argv[len-1]
+ if integrity != 'integrity' and integrity != 'thisrepo'
+ setCfg('off.integrity', integrity)
+ else
+ console.log 'off.integrity '.blue.bold + offHelpers.offIntegrity()
+ return
+
'scpUser': (setCfg) ->
len = process.argv.length
scpUser = process.argv[len-1]
@@ -764,6 +750,7 @@ offCommands =
'env': ->
console.log 'off.mode '.blue.bold + offHelpers.offMode()
+ console.log 'off.integrity '.blue.bold + offHelpers.offIntegrity()
console.log 'off.store '.blue.bold + offHelpers.offStore()
console.log 'off.scphost '.blue.bold + offHelpers.offScp()
console.log 'off.scpuser '.blue.bold + offHelpers.offScpUser()
@@ -796,6 +783,9 @@ if process.argv[2] == 'mode'
if process.argv[2] == 'scp'
thisrepo offCommands['scp']
+if process.argv[2] == 'integrity'
+ thisrepo offCommands['integrity']
+
if process.argv[2] == 'scpuser'
thisrepo offCommands['scpUser']