gdkbox 0.1.12 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/gdkbox/box.rb +44 -7
- data/lib/gdkbox/docker.rb +0 -15
- data/lib/gdkbox/provisioner.rb +0 -33
- data/lib/gdkbox/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8df6faa5d2c2a7a0fe888195af92305774354b997ef5e0e2d1a7ee61469b60bf
|
|
4
|
+
data.tar.gz: 4c859a064721f68cdadc7a7140dc73b0d3a179a57fe3b538c63699c021115109
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9ebd61583a5e01145206ba5407e2fbaad1cf456bbfbb040ecc58e66d0d471c3a5566fca4d194467f9dcc988f5540f57f54c73edf96ac5805248a3c34996f4095
|
|
7
|
+
data.tar.gz: fd01809df5f90d1eff5229918f424c311577f15a756ea32328157ebdcaf237e5d1c998a1db87d004a07dbc77be413c4260cc17baaa9db58248f5087cd3488467
|
data/lib/gdkbox/box.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "shellwords"
|
|
3
4
|
require "time"
|
|
4
5
|
|
|
5
6
|
module GDKBox
|
|
@@ -209,22 +210,58 @@ module GDKBox
|
|
|
209
210
|
url
|
|
210
211
|
end
|
|
211
212
|
|
|
213
|
+
# The hydrate fetch, run inside the box. The filter is passed to `git
|
|
214
|
+
# fetch` directly and only persisted to config after the fetch succeeds
|
|
215
|
+
# (and, for a full hydrate, the previous filter is put back on failure),
|
|
216
|
+
# so an interrupted hydrate cannot leave the config claiming objects the
|
|
217
|
+
# store does not have (issue #8).
|
|
218
|
+
HYDRATE_SCRIPT = <<~'BASH'
|
|
219
|
+
set -e
|
|
220
|
+
if [ -n "$GDKBOX_HYDRATE_FILTER" ]; then
|
|
221
|
+
git fetch --refetch --progress --filter="$GDKBOX_HYDRATE_FILTER" origin
|
|
222
|
+
git config remote.origin.partialclonefilter "$GDKBOX_HYDRATE_FILTER"
|
|
223
|
+
else
|
|
224
|
+
prev=$(git config --get remote.origin.partialclonefilter || true)
|
|
225
|
+
git config --unset-all remote.origin.partialclonefilter || true
|
|
226
|
+
if ! git fetch --refetch --progress origin; then
|
|
227
|
+
if [ -n "$prev" ]; then git config remote.origin.partialclonefilter "$prev"; fi
|
|
228
|
+
echo "hydrate: fetch failed; previous filter config restored" >&2
|
|
229
|
+
exit 1
|
|
230
|
+
fi
|
|
231
|
+
git config --unset remote.origin.promisor || true
|
|
232
|
+
fi
|
|
233
|
+
BASH
|
|
234
|
+
|
|
212
235
|
# Backfill the box's treeless GitLab clone so deep-history operations
|
|
213
236
|
# (old rebases, blame, bisect) work. trees: true fetches only the missing
|
|
214
|
-
# trees (much smaller; file contents stay lazy).
|
|
215
|
-
#
|
|
216
|
-
#
|
|
217
|
-
#
|
|
237
|
+
# trees (much smaller; file contents stay lazy).
|
|
238
|
+
#
|
|
239
|
+
# The fetch runs over SSH (`ssh -F <generated config> <alias>`), not
|
|
240
|
+
# `docker exec`: the remote is typically git@gitlab.com, and only an SSH
|
|
241
|
+
# session carries the user's forwarded agent — docker exec has no
|
|
242
|
+
# SSH_AUTH_SOCK, so it cannot authenticate at all (issue #8). The SSH
|
|
243
|
+
# client stanza (host key + multiplexing) is seeded first for SSH
|
|
244
|
+
# origins. Streams git's progress lines to the block; raises
|
|
245
|
+
# CommandError when the fetch fails.
|
|
218
246
|
def hydrate!(trees: false, &progress)
|
|
219
|
-
provisioner = Provisioner.new(docker: @docker, config: @config)
|
|
220
247
|
origin = @docker.exec(
|
|
221
248
|
container_name, "git remote get-url origin",
|
|
222
249
|
user: @config.ssh_user, workdir: @config.gitlab_checkout_path
|
|
223
250
|
).stdout.strip
|
|
224
251
|
if (host = self.class.remote_ssh_host(origin))
|
|
225
|
-
|
|
252
|
+
Provisioner.new(docker: @docker, config: @config)
|
|
253
|
+
.setup_git_ssh(container_name, host)
|
|
226
254
|
end
|
|
227
|
-
|
|
255
|
+
|
|
256
|
+
filter = trees ? "blob:none" : ""
|
|
257
|
+
remote_cmd = "cd #{Shellwords.escape(@config.gitlab_checkout_path)} && " \
|
|
258
|
+
"GDKBOX_HYDRATE_FILTER=#{Shellwords.escape(filter)} " \
|
|
259
|
+
"bash -c #{Shellwords.escape(HYDRATE_SCRIPT)}"
|
|
260
|
+
argv = ["ssh", "-F", @config.ssh_config_path, ssh_host_alias, remote_cmd]
|
|
261
|
+
result = @shell.stream_tty(*argv, &progress)
|
|
262
|
+
raise CommandError.new(argv, result.status, "") unless result.success?
|
|
263
|
+
|
|
264
|
+
result
|
|
228
265
|
end
|
|
229
266
|
|
|
230
267
|
# Seed a git identity into the box so `git commit` works there. Falls back
|
data/lib/gdkbox/docker.rb
CHANGED
|
@@ -223,21 +223,6 @@ module GDKBox
|
|
|
223
223
|
check ? @shell.run!(*cmd, input: input) : @shell.run(*cmd, input: input)
|
|
224
224
|
end
|
|
225
225
|
|
|
226
|
-
# Like #exec, but for long-running scripts whose output should be seen
|
|
227
|
-
# live (e.g. a multi-GB git fetch): runs under a PTY and yields each
|
|
228
|
-
# output line as it appears. Raises CommandError on a non-zero exit.
|
|
229
|
-
def exec_stream(name, script, user: nil, workdir: nil, env: {}, &block)
|
|
230
|
-
cmd = ["docker", "exec"]
|
|
231
|
-
cmd.push("-u", user) if user
|
|
232
|
-
cmd.push("-w", workdir) if workdir
|
|
233
|
-
env.each { |key, value| cmd.push("-e", "#{key}=#{value}") }
|
|
234
|
-
cmd.push(name, "bash", "-lc", script)
|
|
235
|
-
result = @shell.stream_tty(*cmd, &block)
|
|
236
|
-
raise CommandError.new(cmd, result.status, "") unless result.success?
|
|
237
|
-
|
|
238
|
-
result
|
|
239
|
-
end
|
|
240
|
-
|
|
241
226
|
# Copy a host path into a container at dest (a full destination path).
|
|
242
227
|
def cp_into(name, src, dest)
|
|
243
228
|
@shell.run!("docker", "cp", src, "#{name}:#{dest}")
|
data/lib/gdkbox/provisioner.rb
CHANGED
|
@@ -183,27 +183,6 @@ module GDKBox
|
|
|
183
183
|
git fetch --quiet origin
|
|
184
184
|
BASH
|
|
185
185
|
|
|
186
|
-
# Backfills the treeless GitLab clone (the image clones with
|
|
187
|
-
# --filter=tree:0, so operations spanning a large history gap storm the
|
|
188
|
-
# network with lazy fetches and fail; see #7). Two levels:
|
|
189
|
-
#
|
|
190
|
-
# - GDKBOX_HYDRATE_FILTER=blob:none — fetch all missing trees, keep file
|
|
191
|
-
# contents lazy. A fraction of the download; enough for deep rebases,
|
|
192
|
-
# which mostly storm tree fetches.
|
|
193
|
-
# - no filter (full) — fetch everything and drop the promisor config;
|
|
194
|
-
# the repository behaves like a normal full clone afterwards.
|
|
195
|
-
HYDRATE = <<~'BASH'
|
|
196
|
-
set -e
|
|
197
|
-
if [ -n "$GDKBOX_HYDRATE_FILTER" ]; then
|
|
198
|
-
git config remote.origin.partialclonefilter "$GDKBOX_HYDRATE_FILTER"
|
|
199
|
-
git fetch --refetch --progress origin
|
|
200
|
-
else
|
|
201
|
-
git config --unset-all remote.origin.partialclonefilter || true
|
|
202
|
-
git fetch --refetch --progress origin
|
|
203
|
-
git config --unset remote.origin.promisor || true
|
|
204
|
-
fi
|
|
205
|
-
BASH
|
|
206
|
-
|
|
207
186
|
def initialize(docker:, config:)
|
|
208
187
|
@docker = docker
|
|
209
188
|
@config = config
|
|
@@ -252,18 +231,6 @@ module GDKBox
|
|
|
252
231
|
)
|
|
253
232
|
end
|
|
254
233
|
|
|
255
|
-
# Hydrate the GitLab checkout, streaming git's progress lines to the
|
|
256
|
-
# block. trees: true fetches trees only (blobs stay lazy).
|
|
257
|
-
def hydrate(container_name, trees: false, &block)
|
|
258
|
-
@docker.exec_stream(
|
|
259
|
-
container_name, HYDRATE,
|
|
260
|
-
user: @config.ssh_user,
|
|
261
|
-
workdir: @config.gitlab_checkout_path,
|
|
262
|
-
env: { "GDKBOX_HYDRATE_FILTER" => (trees ? "blob:none" : "") },
|
|
263
|
-
&block
|
|
264
|
-
)
|
|
265
|
-
end
|
|
266
|
-
|
|
267
234
|
def setup_git_ssh(container_name, host)
|
|
268
235
|
@docker.exec(
|
|
269
236
|
container_name, GIT_SSH_SETUP,
|
data/lib/gdkbox/version.rb
CHANGED