-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathy-cluster-blobs
More file actions
executable file
·162 lines (143 loc) · 4.4 KB
/
Copy pathy-cluster-blobs
File metadata and controls
executable file
·162 lines (143 loc) · 4.4 KB
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
#!/usr/bin/env bash
[ -z "$DEBUG" ] || set -x
set -eo pipefail
YHELP='y-cluster-blobs - List and read objects in cluster blob storage
Usage: y-cluster-blobs SUBCOMMAND [options] [CONTEXT://BUCKET/PATH]
Subcommands:
ls [CONTEXT://BUCKET[/PREFIX]] List buckets or objects
cat CONTEXT://BUCKET/OBJECT Print object contents to stdout
help Show this help
Options:
-l Long listing with size and timestamp (ls only)
-r Recursive listing (ls only)
URL format:
local:// List all buckets
local://BUCKET List objects in bucket
local://BUCKET/PREFIX List objects matching prefix
local://BUCKET/KEY Read object (cat)
The CONTEXT part maps to --context for kubectl (currently only local).
Modeled after gcloud storage ls / gcloud storage cat.
Reads VersityGW filesystem directly via kubectl exec for speed.
Environment:
NAMESPACE Override blob store namespace (default: blobs)
Exit codes:
0 Success
1 Usage error
2 Bucket not found
'
case "${1:-}" in
help|--help) echo "$YHELP"; exit 0 ;;
esac
SUBCMD="${1:-}"
shift || true
case "$SUBCMD" in
ls|cat) ;;
"") echo "ERROR: subcommand required (ls, cat, help)" >&2; exit 1 ;;
*) echo "ERROR: unknown subcommand '$SUBCMD'" >&2; exit 1 ;;
esac
# Parse flags
LONG=false
RECURSIVE=false
while [ $# -gt 0 ]; do
case "$1" in
-l) LONG=true; shift ;;
-r) RECURSIVE=true; shift ;;
-lr|-rl) LONG=true; RECURSIVE=true; shift ;;
-*) echo "ERROR: unknown flag '$1'" >&2; exit 1 ;;
*) break ;;
esac
done
URL="${1:-}"
[ -z "$NAMESPACE" ] && NAMESPACE=blobs
# Parse URL: context://bucket/path
CTX=""
BUCKET=""
OBJPATH=""
if [ -n "$URL" ]; then
case "$URL" in
*://*)
CTX_NAME="${URL%%://*}"
CTX="--context=$CTX_NAME"
rest="${URL#*://}"
BUCKET="${rest%%/*}"
if [ "$rest" = "$BUCKET" ]; then
OBJPATH=""
else
OBJPATH="${rest#*/}"
fi
;;
*)
echo "ERROR: URL must use context:// format, got '$URL'" >&2
exit 1
;;
esac
fi
if [ -z "$CTX" ]; then
echo "ERROR: URL required, e.g. local://" >&2
exit 1
fi
vgw() {
kubectl $CTX -n "$NAMESPACE" exec deploy/versitygw -- "$@"
}
DATA_ROOT="/data"
case "$SUBCMD" in
ls)
PREFIX="$CTX_NAME://"
if [ -z "$BUCKET" ]; then
# List buckets
if [ "$LONG" = "true" ]; then
vgw find "$DATA_ROOT" -mindepth 1 -maxdepth 1 -type d -exec stat -c '%Y %n' {} \; 2>/dev/null \
| while read -r epoch name; do
ts=$(date -d "@$epoch" '+%Y-%m-%d %H:%M:%S' 2>/dev/null || echo "$epoch")
echo "[$ts] 0B ${PREFIX}$(basename "$name")/"
done
else
vgw ls "$DATA_ROOT" 2>/dev/null | while read -r name; do
echo "${PREFIX}$name/"
done
fi
else
PREFIX="$CTX_NAME://$BUCKET/"
BUCKET_PATH="$DATA_ROOT/$BUCKET"
if ! vgw test -d "$BUCKET_PATH" 2>/dev/null; then
echo "ERROR: bucket '$BUCKET' not found" >&2
exit 2
fi
TARGET="$BUCKET_PATH${OBJPATH:+/$OBJPATH}"
DEPTH_ARGS=""
if [ "$RECURSIVE" = "false" ]; then
DEPTH_ARGS="-mindepth 1 -maxdepth 1"
fi
if [ "$LONG" = "true" ]; then
vgw sh -c "find '$TARGET' $DEPTH_ARGS -type d ! -path '$TARGET' -exec stat -c 'd %s %Y %n' {} \\; -o -type f -exec stat -c 'f %s %Y %n' {} \\;" 2>/dev/null \
| while read -r type size epoch name; do
ts=$(date -d "@$epoch" '+%Y-%m-%d %H:%M:%S' 2>/dev/null || echo "$epoch")
rel="${name#$BUCKET_PATH/}"
if [ "$type" = "d" ]; then
echo "[$ts] 0B ${PREFIX}$rel/"
else
echo "[$ts] ${size}B ${PREFIX}$rel"
fi
done
else
vgw sh -c "find '$TARGET' $DEPTH_ARGS -type d ! -path '$TARGET' -exec echo d {} \\; -o -type f -exec echo f {} \\;" 2>/dev/null \
| while read -r type name; do
rel="${name#$BUCKET_PATH/}"
if [ "$type" = "d" ]; then
echo "${PREFIX}$rel/"
else
echo "${PREFIX}$rel"
fi
done
fi
fi
;;
cat)
if [ -z "$BUCKET" ] || [ -z "$OBJPATH" ]; then
echo "ERROR: cat requires a full object path, e.g. local://bucket/key" >&2
exit 1
fi
OBJ_FILE="$DATA_ROOT/$BUCKET/$OBJPATH"
vgw cat "$OBJ_FILE"
;;
esac