##// END OF EJS Templates
clone-bundles: garbage collect older bundle when generating new ones...
marmoute -
r51300:971dc236 default
parent child Browse files
Show More
@@ -209,7 +209,8 b' It is possible to set Mercurial to autom'
209 new content is available.
209 new content is available.
210
210
211 Mercurial will take care of the process asynchronously. The defined list of
211 Mercurial will take care of the process asynchronously. The defined list of
212 bundle type will be generated, uploaded, and advertised.
212 bundle-type will be generated, uploaded, and advertised. Older bundles will get
213 decommissioned as newer ones replace them.
213
214
214 Bundles Generation:
215 Bundles Generation:
215 ...................
216 ...................
@@ -235,11 +236,26 b' basename in the "public" URL is accessib'
235 upload-command=sftp put $HGCB_BUNDLE_PATH \
236 upload-command=sftp put $HGCB_BUNDLE_PATH \
236 sftp://bundles.host/clone-bundles/$HGCB_BUNDLE_BASENAME
237 sftp://bundles.host/clone-bundles/$HGCB_BUNDLE_BASENAME
237
238
239 If the file was already uploaded, the command must still succeed.
240
238 After upload, the file should be available at an url defined by
241 After upload, the file should be available at an url defined by
239 `clone-bundles.url-template`.
242 `clone-bundles.url-template`.
240
243
241 [clone-bundles]
244 [clone-bundles]
242 url-template=https://bundles.host/cache/clone-bundles/{basename}
245 url-template=https://bundles.host/cache/clone-bundles/{basename}
246
247 Old bundles cleanup:
248 ....................
249
250 When new bundles are generated, the older ones are no longer necessary and can
251 be removed from storage. This is done through the `clone-bundles.delete-command`
252 configuration. The command is given the url of the artifact to delete through
253 the `$HGCB_BUNDLE_URL` environment variable.
254
255 [clone-bundles]
256 delete-command=sftp rm sftp://bundles.host/clone-bundles/$HGCB_BUNDLE_BASENAME
257
258 If the file was already deleted, the command must still succeed.
243 """
259 """
244
260
245
261
@@ -299,6 +315,8 b" configitem(b'clone-bundles', b'auto-gene"
299
315
300 configitem(b'clone-bundles', b'upload-command', default=None)
316 configitem(b'clone-bundles', b'upload-command', default=None)
301
317
318 configitem(b'clone-bundles', b'delete-command', default=None)
319
302 configitem(b'clone-bundles', b'url-template', default=None)
320 configitem(b'clone-bundles', b'url-template', default=None)
303
321
304 configitem(b'devel', b'debug.clonebundles', default=False)
322 configitem(b'devel', b'debug.clonebundles', default=False)
@@ -666,6 +684,34 b' def finalize_one_bundle(repo, target):'
666 cleanup_tmp_bundle(repo, target)
684 cleanup_tmp_bundle(repo, target)
667
685
668
686
687 def find_outdated_bundles(repo, bundles):
688 """finds outdated bundles"""
689 olds = []
690 per_types = {}
691 for b in bundles:
692 if not b.valid_for(repo):
693 olds.append(b)
694 continue
695 l = per_types.setdefault(b.bundle_type, [])
696 l.append(b)
697 for key in sorted(per_types):
698 all = per_types[key]
699 if len(all) > 1:
700 all.sort(key=lambda b: b.revs, reverse=True)
701 olds.extend(all[1:])
702 return olds
703
704
705 def collect_garbage(repo):
706 """finds outdated bundles and get them deleted"""
707 with repo.clonebundles_lock():
708 bundles = read_auto_gen(repo)
709 olds = find_outdated_bundles(repo, bundles)
710 for o in olds:
711 delete_bundle(repo, o)
712 update_bundle_list(repo, del_bundles=olds)
713
714
669 def upload_bundle(repo, bundle):
715 def upload_bundle(repo, bundle):
670 """upload the result of a GeneratingBundle and return a GeneratedBundle
716 """upload the result of a GeneratingBundle and return a GeneratedBundle
671
717
@@ -691,12 +737,34 b' def upload_bundle(repo, bundle):'
691 return bundle.uploaded(url, basename)
737 return bundle.uploaded(url, basename)
692
738
693
739
740 def delete_bundle(repo, bundle):
741 """delete a bundle from storage"""
742 assert bundle.ready
743 msg = b'clone-bundles: deleting bundle %s\n'
744 msg %= bundle.basename
745 if repo.ui.configbool(b'devel', b'debug.clonebundles'):
746 repo.ui.write(msg)
747 else:
748 repo.ui.debug(msg)
749
750 cmd = repo.ui.config(b'clone-bundles', b'delete-command')
751 variables = {
752 b'HGCB_BUNDLE_URL': bundle.file_url,
753 b'HGCB_BASENAME': bundle.basename,
754 }
755 env = procutil.shellenviron(environ=variables)
756 ret = repo.ui.system(cmd, environ=env)
757 if ret:
758 raise error.Abort(b"command returned status %d: %s" % (ret, cmd))
759
760
694 def auto_bundle_needed_actions(repo, bundles, op_id):
761 def auto_bundle_needed_actions(repo, bundles, op_id):
695 """find the list of bundles that need action
762 """find the list of bundles that need action
696
763
697 returns a list of RequestedBundle objects that need to be generated and
764 returns a list of RequestedBundle objects that need to be generated and
698 uploaded."""
765 uploaded."""
699 create_bundles = []
766 create_bundles = []
767 delete_bundles = []
700 repo = repo.filtered(b"immutable")
768 repo = repo.filtered(b"immutable")
701 targets = repo.ui.configlist(b'clone-bundles', b'auto-generate.formats')
769 targets = repo.ui.configlist(b'clone-bundles', b'auto-generate.formats')
702 revs = len(repo.changelog)
770 revs = len(repo.changelog)
@@ -712,7 +780,8 b' def auto_bundle_needed_actions(repo, bun'
712 data['bundle_type'] = t
780 data['bundle_type'] = t
713 b = RequestedBundle(**data)
781 b = RequestedBundle(**data)
714 create_bundles.append(b)
782 create_bundles.append(b)
715 return create_bundles
783 delete_bundles.extend(find_outdated_bundles(repo, bundles))
784 return create_bundles, delete_bundles
716
785
717
786
718 def start_one_bundle(repo, bundle):
787 def start_one_bundle(repo, bundle):
@@ -759,6 +828,8 b' def debugmakeclonebundles(ui, repo):'
759 requested_bundle = util.pickle.load(procutil.stdin)
828 requested_bundle = util.pickle.load(procutil.stdin)
760 procutil.stdin.close()
829 procutil.stdin.close()
761
830
831 collect_garbage(repo)
832
762 fname = requested_bundle.suggested_filename
833 fname = requested_bundle.suggested_filename
763 fpath = repo.vfs.makedirs(b'tmp-bundles')
834 fpath = repo.vfs.makedirs(b'tmp-bundles')
764 fpath = repo.vfs.join(b'tmp-bundles', fname)
835 fpath = repo.vfs.join(b'tmp-bundles', fname)
@@ -778,7 +849,7 b' def make_auto_bundler(source_repo):'
778 repo = reporef()
849 repo = reporef()
779 assert repo is not None
850 assert repo is not None
780 bundles = read_auto_gen(repo)
851 bundles = read_auto_gen(repo)
781 new = auto_bundle_needed_actions(repo, bundles, b"%d_txn" % id(tr))
852 new, __ = auto_bundle_needed_actions(repo, bundles, b"%d_txn" % id(tr))
782 for data in new:
853 for data in new:
783 start_one_bundle(repo, data)
854 start_one_bundle(repo, data)
784 return None
855 return None
@@ -11,6 +11,7 b' initial setup'
11 > [clone-bundles]
11 > [clone-bundles]
12 > auto-generate.formats = v2
12 > auto-generate.formats = v2
13 > upload-command = cp "\$HGCB_BUNDLE_PATH" "$TESTTMP"/final-upload/
13 > upload-command = cp "\$HGCB_BUNDLE_PATH" "$TESTTMP"/final-upload/
14 > delete-command = rm -f "$TESTTMP/final-upload/\$HGCB_BASENAME"
14 > url-template = file://$TESTTMP/final-upload/{basename}
15 > url-template = file://$TESTTMP/final-upload/{basename}
15 >
16 >
16 > [devel]
17 > [devel]
@@ -68,3 +69,28 b' Newer bundles are generated with more pu'
68 full-v2-2_revs-aaff8d2ffbbf_tip-*_txn.hg (glob)
69 full-v2-2_revs-aaff8d2ffbbf_tip-*_txn.hg (glob)
69 full-v2-4_revs-6427147b985a_tip-*_txn.hg (glob)
70 full-v2-4_revs-6427147b985a_tip-*_txn.hg (glob)
70 $ ls -1 ../server/.hg/tmp-bundles
71 $ ls -1 ../server/.hg/tmp-bundles
72
73 Older bundles are cleaned up with more pushes
74 ---------------------------------------------
75
76 $ touch faz
77 $ hg -q commit -A -m 'add faz'
78 $ touch fuz
79 $ hg -q commit -A -m 'add fuz'
80 $ hg push
81 pushing to $TESTTMP/server
82 searching for changes
83 adding changesets
84 adding manifests
85 adding file changes
86 clone-bundles: deleting bundle full-v2-2_revs-aaff8d2ffbbf_tip-*_txn.hg (glob)
87 6 changesets found
88 added 2 changesets with 2 changes to 2 files
89 clone-bundles: starting bundle generation: v2
90
91 $ cat ../server/.hg/clonebundles.manifest
92 file:/*/$TESTTMP/final-upload/full-v2-6_revs-b1010e95ea00_tip-*_txn.hg BUNDLESPEC=v2 REQUIRESNI=true (glob)
93 $ ls -1 ../final-upload
94 full-v2-4_revs-6427147b985a_tip-*_txn.hg (glob)
95 full-v2-6_revs-b1010e95ea00_tip-*_txn.hg (glob)
96 $ ls -1 ../server/.hg/tmp-bundles
General Comments 0
You need to be logged in to leave comments. Login now