forked from InsightSoftwareConsortium/ITK
-
Notifications
You must be signed in to change notification settings - Fork 0
/
UploadBinaryData.sh
executable file
·197 lines (162 loc) · 7.33 KB
/
UploadBinaryData.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#!/usr/bin/env bash
#==========================================================================
#
# Copyright NumFOCUS
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#==========================================================================*/
# Utility functions
print_help() {
cat << EOF
Usage: $0 [--folder-id <folder_id>] <binary/file/path/in/repo/1> [<binary/file/path/in/repo/2> ...]
Use this script to upload binary testing data for ITK and related projects.
Binary data, e.g. test input images, are not stored in Git because they
will bloat a Git repository's size.
To use the script:
1. Sign up for an account at https://data.kitware.com
2. Place the binary file at the desired location in the Git repository.
3. Run this script, and pass in the binary file(s) as arguments to script.
4. In test/CMakeLists.txt, use the itk_add_test macro and reference the file
path with \`DATA\` and braces, e.g.: DATA{<Relative/Path/To/Source/Tree/File>}.
5. Re-build ITK, and the testing data will be downloaded into the build tree.
If the Git `girder.api-key` config or `GIRDER_API_KEY` environmental variable
is not set, a prompt will appear for your username and password. The API key
can be created in the data.kitware.com user account web browser interface.
The script will authenticate to data.kitware.com, upload the file to your
user account's Public folder, and create a *.sha512 CMake ExternalData
content link file. To specify a different folder, use the --folder flag.
After the content link has been created, add the *.sha512 file to your
git commit. The binary file will be removed from the source tree following
upload.
EOF
}
die() {
echo "$@" 1>&2; exit 1
}
json_field() {
local key=$1
local json=$2
echo $json | awk 'BEGIN { FS="\""; RS="," }; { if ($2 == "'$key'") {print $4} }'
}
# Parse arguments
help=false
folder_id=""
while test $# -gt 0;
do
opt="$1";
case "$opt" in
"-h"|"--help")
shift;
help=true
break;;
"-f"|"--folder-id")
shift;
folder_id="$1"
shift;;
*)
break;;
esac
done
binary_files="$@"
if test "${binary_files}" = "" || $help; then
print_help
exit 1
fi
# Check for required dependencies
if ! type curl > /dev/null; then
die "Please install the curl executable."
fi
if ! type wc > /dev/null; then
die "Please install the wc executable."
fi
# Authenticate
token=""
git_config_api_key=$(git config --get girder.api-key || echo '')
if test -n "${git_config_api_key}"; then
token_response=$(curl -s -X POST --header 'Content-Length: 0' --header 'Content-Type: application/json' --header 'Accept: application/json' "https://data.kitware.com/api/v1/api_key/token?key=${git_config_api_key}&duration=1" || die "Could not retrieve token from API key.")
token=$(json_field "token" "${token_response}")
fi
if test -z "${token}" -a -n "${GIRDER_API_KEY}"; then
token_response=$(curl -s -X POST --header 'Content-Length: 0' --header 'Content-Type: application/json' --header 'Accept: application/json' "https://data.kitware.com/api/v1/api_key/token?key=${GIRDER_API_KEY}&duration=1" || die "Could not retrieve token from API key.")
token=$(json_field "token" "${token_response}")
fi
if test -z "${token}"; then
if ! type base64 > /dev/null; then
die "Please install the base64 executable."
fi
echo "Please provide your"
echo ""
echo " https://data.kitware.com"
echo ""
read -p "username: " username
read -p "password: " -s password
basic_content=$(echo -n "${username}:${password}" | base64)
token_response=$(curl -s -X GET --header "Girder-Authorization: Basic ${basic_content}" --header 'Accept: */*' --header 'Host: data.kitware.com' --header 'Referer: https://data.kitware.com' 'https://data.kitware.com/api/v1/user/authentication' || die "Could not retrieve token from username / password.")
token=$(json_field "token" "${token_response}")
fi
if test -z "${token}"; then
die "Could not authenticate to https://data.kitware.com"
fi
# Get user / folder
user_id_response=$(curl -s -X GET --header 'Accept: application/json' --header "Girder-Token: ${token}" 'https://data.kitware.com/api/v1/user/me' || die 'Could not get user id.')
user_id=$(json_field "_id" "${user_id_response}")
if test -z "$folder_id"; then
folder_id_response=$(curl -s -X GET --header 'Accept: application/json' --header "Girder-Token: ${token}" "https://data.kitware.com/api/v1/folder?parentType=user&parentId=${user_id}&name=Public&limit=3&sort=lowerName&sortdir=1" || die 'Could not get folder id.')
folder_id=$(json_field "_id" "${folder_id_response}")
fi
# Upload files and create content links
generated_content_links=""
md5_content_link_conflicts=""
for binary_file in $binary_files; do
if test ! -e $binary_file; then
die "$binary_file does not exist."
fi
item_name=$(basename "$binary_file")
create_item_response=$(curl -s -X POST --header 'Content-Length: 0' --header 'Content-Type: application/x-www-form-urlencoded' --header 'Accept: application/json' --header "Girder-Token: ${token}" "https://data.kitware.com/api/v1/item?folderId=${folder_id}&name=${item_name}&description=ITK%20testing%20data%20uploaded%20by%20ITK%2FUtilities%2FUploadBinaryData.sh&reuseExisting=true" || die 'Could not create item.')
item_id=$(json_field "_id" "${create_item_response}")
size=$(wc -c < "$binary_file" | sed 's/^[[:space:]]*//')
echo "Uploading ${item_name}..."
upload_file_response=$(curl -X POST --data-binary "@${binary_file}" --header 'Content-Type: application/json' --header 'Accept: application/json' --header "Girder-Token: ${token}" "https://data.kitware.com/api/v1/file?parentType=item&parentId=${item_id}&name=${item_name}&size=${size}" || die 'Could not upload file.')
file_id=$(json_field "_id" "${upload_file_response}")
curl -s -X GET --output "${binary_file}.sha512" --header 'Accept: text/plain' --header "Girder-Token: ${token}" "https://data.kitware.com/api/v1/file/${file_id}/hashsum_file/sha512" || die 'Could not get file sha512sum.'
generated_content_links="$generated_content_links ${binary_file}.sha512"
if type cmake > /dev/null; then
cmake_sha512sum=$(cmake -E sha512sum "$binary_file" 2> /dev/null)
# If sufficient CMake version, ...
if test $? -eq 0; then
local_sha512=$(echo $cmake_sha512sum | awk '{print $1}')
remote_sha512=$(cat "${binary_file}.sha512")
if test "$local_sha512" != "$remote_sha512"; then
die "Local file hash does not match uploaded file hash."
fi
fi
fi
md5_content_link="${binary_file}.md5"
if test -e "$md5_content_link"; then
md5_content_link_conflicts="$md5_content_link_conflicts $md5_content_link"
fi
rm $binary_file
done
# Recommend next steps
cat << EOF
Testing data upload complete.
Now run:
git add --$generated_content_links
EOF
if test -n "$md5_content_link_conflicts"; then
cat << EOF
and:
git rm --$md5_content_link_conflicts
EOF
fi