Commit Graph

62440 Commits

Author SHA1 Message Date
svcscm
f7c5eff6c5 Updating submodules
Summary:
GitHub commits:

c3c332f652
b7d217aad3
444d3f0343
731276a4e3
e628f59e87
c807ffa68a
260cc6e82d

Reviewed By: yns88

fbshipit-source-id: d35624cb08df3a08072b4f04409bda548c6debb2
2021-01-06 12:21:52 -08:00
Stanislau Hlebik
a09d7264f8 mononoke: allow selecting a multiplex blobstore component in fixrepocontents
Summary:
In some cases we might have chunked file content in one blobstore component and
unchunked file content in another. And rechunking the second component was
awkward since we never know which version a filestore will fetch - filestore
can fetch a chunked version and decide that rechunking is not necessary.

This diff makes it possible to rechunk only a single component of a multiplexed
blobstore. It does so by manually creating BlobRepo with the single-component
blobstore.

Reviewed By: krallin

Differential Revision: D25803821

fbshipit-source-id: f2a992b73d0c5fc9d389a4b81e0f3e312c17fdea
2021-01-06 11:20:32 -08:00
Durham Goode
b52168c4c8 auth: backout D25454687 cert validatio
Summary:
The cert path isn't correctly set up on all platforms, so this can
cause Mercurial to throw an error complaining about missing certs, even when
edenapi isn't enabled.

Let's back this out for now until we can fix the cert paths or only hit this
path when we actually use edenapi.

Reviewed By: singhsrb

Differential Revision: D25792491

fbshipit-source-id: 022a89a089cabcc709a07934eb62b883082261c2
2021-01-06 09:17:13 -08:00
Simon Farnsworth
b4a234bbe5 convert changesets to new type futures
Summary: Convert `Changsets` trait and all its uses to new type futures

Reviewed By: krallin

Differential Revision: D25638875

fbshipit-source-id: 947423e2ee47a463861678b146641bcc6b899a4a
2021-01-06 07:11:36 -08:00
Thomas Orozco
669d08df0e http-client: raise errors on trailing data in CBOR streams
Summary:
Lots of things can look like CBOR data, such as ... strings representing
errors. Right now, if the data in our CBOR stream is actually an error message,
then we'll just ignore it (see details in T80406893).

This isn't how we normally handle invalid data on the stream (we'd raise an
error) — it only happens with trailing data. This fixes our decoding to raise
an error in this case.

Reviewed By: quark-zju

Differential Revision: D25759082

fbshipit-source-id: c3d8be5007112ec1d2e7f25a102d8caaf0dbba56
2021-01-06 02:20:29 -08:00
Liubov Dmitrieva
19b20b43a1 enable switching from a draft commit possible for most of cases
Summary:
enable switching from a draft commit possible for most of the cases

make it possible if the public root of the current commit is an ancestor of the main bookmark

this condition we need because the remote bookmarks can be different for different workspaces and they define phases

I think it will cover most of workflows

Reviewed By: mitrandir77

Differential Revision: D25780999

fbshipit-source-id: b1c25b29a7668d51244ca43d6b0c30fa2fc068d9
2021-01-06 01:59:16 -08:00
svcscm
d50939b1de Updating submodules
Summary:
GitHub commits:

c1c8f9e901
15ad56f8fe

Reviewed By: yns88

fbshipit-source-id: 0d0888c004fdd4e68ca21b4e826ac4d136707472
2021-01-06 01:59:16 -08:00
svcscm
b158e4a9c4 Updating submodules
Summary:
GitHub commits:

c149d089ee
17468b65bf
bd2a627268
d37cb242a5
a167354e6a
15a9db744a

Reviewed By: yns88

fbshipit-source-id: 99349f6d7074f2b94cbc151026acaeab2f9b01b8
2021-01-05 19:08:28 -08:00
Jun Wu
9605d08b98 rage: skip long configs
Summary: Skip some very long configs to make rage output cleaner.

Reviewed By: DurhamG

Differential Revision: D25625452

fbshipit-source-id: 44bf8b9f93d9cb06d065a89f5d0ffa53ad6d6286
2021-01-05 18:01:33 -08:00
svcscm
f2dd98829e Updating submodules
Summary:
GitHub commits:

32f379b098
f07f33e52b
c50c5651df
a07a6bc9ee
fa49a9f6b5
0c31103033
6b3d7ecf2f

Reviewed By: yns88

fbshipit-source-id: 535a3717964747bc4a2b4e0a8747a584da36b401
2021-01-05 18:01:33 -08:00
svcscm
52fd07d0fb Updating submodules
Summary:
GitHub commits:

d316af9bcb
e7be6ca596
e8d1509c22
a7c84c391a
ffa8d706c6
74556c7257
11de2425f2
72a1d86a7c
c8abe66775
199b498a0a
7b4e1a9597

Reviewed By: yns88

fbshipit-source-id: 3258f5d59abbb8e7c3d11bf1b42c6bdadd4fe412
2021-01-05 15:26:37 -08:00
Stanislau Hlebik
220baef735 mononoke: add a tunable to disable all x-repo syncs
Reviewed By: krallin

Differential Revision: D25781199

fbshipit-source-id: cc0c515487447c5af8290aff4793e8f026732a50
2021-01-05 15:16:50 -08:00
Xavier Deguillard
7d6d6f3714 model: remove test-only constructor for TreeEntry
Summary:
The StringPiece constructor is untyped, and was only used in test. We can
afford to build the PathComponent in tests instead to avoid future headaches.

Reviewed By: genevievehelsel

Differential Revision: D25434556

fbshipit-source-id: 4b10bf2576870e81412d76c4b9755b45e26986b3
2021-01-05 14:08:14 -08:00
Xavier Deguillard
978cd4549c hg: ignore invalid filename when importing manifest
Summary:
Mercurial support files with `\` in their name, which can't be represented on
Windows due to `\` being the path separator. Currently, EdenFS will throw
errors at the user when such file are encountered, let's simply warn, and
continue.

Reviewed By: chadaustin

Differential Revision: D25430523

fbshipit-source-id: 4167b4cd81380226aead8e4f4850a7738087fd95
2021-01-05 14:08:14 -08:00
Durham Goode
912fa781b6 hg: unset DYLD_* environment variables
Summary:
On OSX, if Mercurial is built from fbcode, these environment variables
(which point specifically to Eden's own par file data) can break Mercurial's
ability to load dynamic libraries. Let's unset them.

Reviewed By: xavierd

Differential Revision: D25783552

fbshipit-source-id: 74e6232d225856fedc0382abc6cd223a6c47d8bc
2021-01-05 14:05:21 -08:00
Xavier Deguillard
adf6aa8d4f inodes: move strace logging to PrjfsChannel
Summary:
All of the strace logging was done in PrjfsChannel except for the notification
callbacks, let's remediate this.

Reviewed By: kmancini

Differential Revision: D25643491

fbshipit-source-id: 7eaed2503557b0e486d7d1b0637c68287ee9df90
2021-01-05 12:17:33 -08:00
Xavier Deguillard
0855712a77 prjfs: refactor some common code
Summary:
In a previous diff, chadaustin noted that there was a bunch of duplicated code
prior to calling into the PrjfsChannel, let's use template to solve this.

One of the non-refactored piece is the BAIL_ON_RECURSIVE_CALL, and I'm not sure
of a good way to move it into runCallback while still being able to understand
what callback is recursive. Previously, the line number from XLOG was
sufficient, moving it into the runCallback function would lose that.

Reviewed By: chadaustin

Differential Revision: D25576860

fbshipit-source-id: 619ed0c9fecf05cda2263dfcdf2fbcbaec85e45a
2021-01-05 12:17:33 -08:00
Xavier Deguillard
1106d40eae prjfs: replace Synchronized<shared_ptr> with RcuPtr
Summary:
The RcuPtr abstraction allows us to use RCU instead of the significantly more
expensive Synchronized<shared_ptr>. This should reduce the cost of all the
callbacks while not sacrificing the guarantee that unmounting a repository
needs to wait for all the pending callbacks to complete.

A new rcu_domain is used as the pending callbacks may sleep and take a long
time to complete when the servers aren't reachable. To avoid penalizing all the
other RCU clients, it's best to be isolated in its own domain.

Reviewed By: kmancini

Differential Revision: D25351535

fbshipit-source-id: bd40d59056e3e710c28c42d651b79876be496bc3
2021-01-05 12:17:32 -08:00
Kostia Balytskyi
175b9157f1 observability: fix double-filtering bug
Summary:
We should not filter based on parsed level when passiing an inner drain into
the `DynamicLevelDrain`, as in cases when the binary is ran
`--with-dynamic-observability=true`, this would default the level to `INFO` and
make the inner drain filter on that level, which would essentially make debug
logging impossible. Instead, we should pass unfiltering inner drain into
`DynamicLevelDrain`, as `DynamicLevelDrain` actually uses
`ObservabilityContext`, which when the binary is called with `--debug` or
`--level=SOMETHING` would [instantiate](https://fburl.com/diffusion/sib8ayrn) a `Static` variant, behaving just as
current static level filtering.

Note also that this bug does not affect production, as we never actually try to
control the logging levels dynamically: we always run either with `--debug` or
with `--level=SOMETHING`, which again uses `Static` variant of
`ObservabilityContext`, which in turn filters the same way as the inner drain.

Reviewed By: krallin

Differential Revision: D25783488

fbshipit-source-id: 8054863fb655dd66747b6d2306a38c13cbc64443
2021-01-05 11:41:16 -08:00
svcscm
0a78c77962 Updating submodules
Summary:
GitHub commits:

8ccfa096d8
75673e1a16
f525afdfdb

Reviewed By: yns88

fbshipit-source-id: 2144b16208c618af1b102c7afb03b03c47b5a671
2021-01-05 10:36:42 -08:00
Kostia Balytskyi
7995ae5e85 observability: add scuba verbose logging
Summary:
This diff adds an (as yet unused) option to log verbose scuba samples.

Here's the high-level overview.

In addition to doing `scuba_sample.log_with_msg` and `scuba_sample.log()`, you can now do `scuba_sample.log_with_msg_verbose()` and `scuba_sample.log_verbose()`. These two methods indicate that the intended sample is verbose and should go through some filtering prior to logging.

By default verbose samples are just not logged, but there are ways to override this via `ScubaObservabilityConfig`. Namely, the config has a "system" `ScubaVerbosityLevel`, which is either `Normal` or `Verbose`. When the level is `Verbose`, all samples are logged (those triggered by `.log_with_msg()`, `.log()`, `.log_with_msg_verbose()` and `.log_verbose()`. In addition to the "system" verbosity level, `ScubaObservabilityConfig` supports a few filtering overrides: a list of verbose sessions, a list of verbose unixnames and a list of verbose hostnames. Whenever a verbose sample's session, unixname or source hostname belongs to a corresponding list, the sample is logged.

`ScubaObservabilityConfig` is a struct, queried from `configerator` without the need to restart a service. Querying/figuring out whether logging is needed is done by the `ObservabilityContext` struct, which was introduced a few diffs earlier.

Note: I also want to add regex-based filtering for hostnames, as it's likely to be more useful than exact-match filtering, but I will do that later.

Reviewed By: StanislavGlebik

Differential Revision: D25232429

fbshipit-source-id: 057af95fc31f70d796063cefac5b8f7c69d7b3ef
2021-01-05 09:21:38 -08:00
Thomas Orozco
9cb16524e4 edenapi: deduplicate fetch and fetch_raw
Summary:
In the previous diff I had to make the same change in two places, this change
deduplicates the code so we can reuse the change. This isn't 100% equivalent,
since now we have 2 layers of boxing on the stream in `Fetch`.

That being said, that seems quite unlikely to matter considering that this is
ultimately handling responses that came to us over HTTP, so one pointer
traversal seems to be reasonable overhead (also, similar experience in Mononoke
suggests it really does not matter).

Reviewed By: quark-zju

Differential Revision: D25758652

fbshipit-source-id: 399ead1b67ffbb241597615a29129411580cf194
2021-01-05 07:42:30 -08:00
Thomas Orozco
01f51a92b3 edenapi: check server status codes
Summary:
This updates the edenapi fetch mechanism to check status codes from the server.
If the server responds with an error, we propagate the error up to the caller.
This is equivalent to what we would do if e.g. the server had just crashed.

Reviewed By: quark-zju

Differential Revision: D25758653

fbshipit-source-id: f44f6384be7944dce670c3825ccbb60b5fa2090a
2021-01-05 07:42:30 -08:00
Thomas Orozco
a05ba6a383 mononoke/cache_warmup: fix a typo in logging
Summary: This was a bit triggering while looking at logs :p

Reviewed By: StanislavGlebik

Differential Revision: D25781047

fbshipit-source-id: 22ebf1273b8b8d0b765c1bc7df2ba93752bf45e8
2021-01-05 07:39:46 -08:00
Thomas Orozco
cd2c83a6c9 mononoke/cache_warmup: log changesets warmup
Summary:
See D25780870 for a bit of context. Our admin server was failing to start up
because of changesets warmup taking too long, but that's not easy to figure out
if all you have are the logs that don't tell you what we are doing (you'd have
to look at counters to work this out).

Let's just log this stuff.

Reviewed By: StanislavGlebik

Differential Revision: D25781048

fbshipit-source-id: 57a783dadc618956f577f32df3d2ec92ee729d56
2021-01-05 07:39:46 -08:00
svcscm
1cce3ecff4 Updating submodules
Summary:
GitHub commits:

bfbef4e0f3

Reviewed By: yns88

fbshipit-source-id: 19e26364a1568507bf1dd6081b249d4c2a33bb19
2021-01-05 07:07:49 -08:00
Thomas Orozco
7480825838 mononoke/cmdlib: log errors when servers exit unexpectedly
Summary:
Like it says in the title. This is helpful with e.g. Mononoke server where the
"server" handle includes a long winded startup sequence. Right now, if we get
an error, then we don't get an error message immediately, even if we have one.
This leaves you with logs like this:

```
0105 04:20:48.563924 995374 [main] eden/mononoke/cmdlib/src/helpers.rs:229] Server has exited! Starting shutdown...
I0105 04:20:48.564076 995374 [main] eden/mononoke/cmdlib/src/helpers.rs:240] Waiting 0s before shutting down server
I0105 04:20:48.564238 995374 [main] eden/mononoke/cmdlib/src/helpers.rs:248] Shutting down...
E0105 04:20:48.564315 995374 [main] eden/mononoke/server/src/main.rs:119] could not send termination signal: ()
```

This isn't great because you might have to wait for a while to see the error,
and if something hangs in the shutdown sequence later, then you might not see
it at all.

The downside is we might log twice if we have a server that crashes like this,
but I guess that's probably better than not logging at all.

Reviewed By: StanislavGlebik

Differential Revision: D25781095

fbshipit-source-id: bf5bf016d7aa36e3ff6302175bef1aab826977bc
2021-01-05 07:01:13 -08:00
svcscm
82caafc6a4 Updating submodules
Summary:
GitHub commits:

6a9961b07a

Reviewed By: yns88

fbshipit-source-id: 4727eab9ddb1b4fad048cdac0b3a889d002ee3f9
2021-01-05 07:01:13 -08:00
svcscm
1d6be102bb Updating submodules
Summary:
GitHub commits:

af0721ad91

Reviewed By: yns88

fbshipit-source-id: dae03b31d3e4172dbf9dc1fde18709cf650fc9de
2021-01-05 01:06:53 -08:00
Stanislau Hlebik
faf88d25b2 mononoke: use get_common_pushrebase_bookmarks from CommitSyncer
Summary:
After the refactoring in the previous diff let's stop using CommitSyncConfig in
PushRedirectorArgs and start using get_common_pushrebase_bookmarks() method.

Reviewed By: mitrandir77

Differential Revision: D25636577

fbshipit-source-id: 126b38860b011c5a9506a38d4568e5d51b2af648
2021-01-04 23:29:46 -08:00
Stanislau Hlebik
515c94e666 mononoke: add a method to return common pushrebase bookmarks in CommitSyncer
Summary:
At the moment we are in the bit of a mess with cross repo sync configuration,
and this diff will try to clean it up a bit.
In particular, we have LiveCommitSyncConfig which is refreshed automatically,
and also we have CommitSyncConfig which is stored in RepoConfig. The latter is
deprecated and is not supposed to be used, however there are still a few places
that do that. This stack is an attempt to clean it up.

In particular deprecated CommitSyncConfig is used to fetch common pushrebase
bookmarks i.e. bookmarks where pushes from both repos are sent. This diff adds
get_common_pushrebase_bookmarks() method to CommitSyncer so that in the later
diffs we can avoid using CommitSyncConfig for that.

Reviewed By: mitrandir77

Differential Revision: D25636394

fbshipit-source-id: 09b049eb8a54834881d215bc6b9c4150377e387f
2021-01-04 23:29:46 -08:00
Stanislau Hlebik
11111b6676 mononoke: remove get_source_target_mover method
Summary: It's not needed

Reviewed By: mitrandir77

Differential Revision: D25635865

fbshipit-source-id: 1b1f4395182d9bb1b47c661cf3f98eaf342f403e
2021-01-04 23:29:46 -08:00
svcscm
6b6e52eb6a Updating submodules
Summary:
GitHub commits:

5d938798a4

Reviewed By: yns88

fbshipit-source-id: 93e33118db80717481c1c6cfa887a72235917554
2021-01-04 23:29:46 -08:00
svcscm
424e85f6b4 Updating submodules
Summary:
GitHub commits:

b15c1cea31
e127df07f3
aa7a2d72a7
af1c7898a7
c1a65a4de4
655ef8bad4

Reviewed By: yns88

fbshipit-source-id: 2e123cb68d902afa236a2fc97a62894df030cc7b
2021-01-04 18:10:37 -08:00
Zeyi (Rice) Fan
bcfd491b98 big sur: fix osxfuse loading path
Summary: Starting from 3.11.1, OSXFUSE switched into using macOS's major version number for different system versions. So we need to consider that when calculating path to the kernel extensions on macOS.

Reviewed By: xavierd

Differential Revision: D25675984

fbshipit-source-id: ea8c76ce7204ba5da3ca98ceca2cfbeb9c84fa8f
2021-01-04 16:46:48 -08:00
svcscm
74e16016ad Updating submodules
Summary:
GitHub commits:

9c5e1719f4

Reviewed By: yns88

fbshipit-source-id: 4a2cc35811450d32cd6116664e28aac24017204b
2021-01-04 16:46:48 -08:00
svcscm
32ce0b9e64 Updating submodules
Summary:
GitHub commits:

714e8b6973
9e6e36c4f7
ec50838e37
22467dd5df
58660bf21a
4fe9d6a066
124d9fd00f
d127013859
8d184adaa2
88455a8572
2be9fc3eb0

Reviewed By: yns88

fbshipit-source-id: 7c231f443dfa91aad5d81dfc95845d0f8ff30e59
2021-01-04 14:03:05 -08:00
Johan Schuijt-Li
e763e98b56 add tls explanations for errors
Summary:
Make sure we give more explanation to users to they can self-fix any errors
related to certificates that might pop up.

Reviewed By: xavierd

Differential Revision: D25758517

fbshipit-source-id: 3b9929be3d1c0c44a5e13cc9c1e7b2a4f785abf4
2021-01-04 13:14:37 -08:00
svcscm
8ea78c9e42 Updating submodules
Summary:
GitHub commits:

2e1e68b35a
91a6723380
1a7695093f
225abffd8f
3cf3566b19

Reviewed By: yns88

fbshipit-source-id: 7e55479d24444ddde5eadf657faf9a73f86bbcda
2021-01-04 13:00:12 -08:00
Xavier Deguillard
788c438cd0 cli: allow compiling on Windows with Buck
Summary:
The introduction of `eden trace` broke the Buck build on Windows due to its use
of streaming thrift which unfortunately doesn't compile on Windows. Since `eden
trace` is not supported on Windows for now, let's only depend on the streaming
thrift on Linux and macOS.

With this, we can now compile edenfsctl on Windows with Buck. This will later
enable integration tests to be run on Windows.

Reviewed By: genevievehelsel

Differential Revision: D25758445

fbshipit-source-id: d4be2cafd9472840f65dcfab63a5fcfb8eceffb7
2021-01-04 11:15:54 -08:00
Thomas Orozco
015f739351 mononoke: fix flakiness in test-walker-enable-derive.t
Summary:
Like it says in the title. Judging by an earlier similar change (D21092866 (15f98fe58c)),
this kind of flakiness in walker tests occurs when a node's children are
reachable via other paths.

Reviewed By: HarveyHunt

Differential Revision: D25756891

fbshipit-source-id: 05bc0697381e068d466ea6dfe85529dbd9ef1a50
2021-01-04 08:58:18 -08:00
Thomas Orozco
a37f92d807 revisionstore: retry recv & send error
Summary:
Like it says in the title. Note that I did *not* retry stuff like resolving
hosts or connecting, so this should only really temporary blips in
connectivity. We probably shouldn't go much beyond that at a low level like
this.

Reviewed By: HarveyHunt

Differential Revision: D25615915

fbshipit-source-id: 78c33eff2e9ce380a260708e9fbeb929eede383c
2021-01-04 06:22:55 -08:00
Thomas Orozco
aad6b20224 revisionstore: retry curl transfer time outs
Summary:
This is the goal of this stack: retry errors that occur when Curl detects that
the transfer speed is too low. This should let us eventually set a much higher
timeout on overall request completion, thus ensuring that we don't uploads
that make progress, all the while aborting connections early and retrying them
if they are legitimately stuck.

Reviewed By: farnz

Differential Revision: D25615790

fbshipit-source-id: fe294aee090758b1a3aef138788ac2926c741b79
2021-01-04 06:22:55 -08:00
Thomas Orozco
d7ebbe7f56 revisionstore: refactor error hierarchy to make transfer errors recoverable
Summary:
Right now, the error handling in LFS doesn't handle e.g. transfer timeouts. I'd
like us to support that, notably so that we can have curl require a minimum
transfer speed and retry if we fail.

To do so, I need to be able to capture the errors and figure out if they're
retryable. Right now, everything is either a `FetchError` that includes a HTTP
status and URL, or just an `Error` that aborts.

This diff introduces a `TransferError` that explains why a transfer failed and
can be used for retry decisions. We later add the request details if we decide
to not retry and turn it into a `FetchError`.

Reviewed By: xavierd

Differential Revision: D25615789

fbshipit-source-id: e4a2f4f16a34ca2f86bd61491bb26e7f328dec63
2021-01-04 06:22:54 -08:00
Thomas Orozco
06e016600b revisionstore: make min transfer speed configurable
Summary:
Like it says in the title. This adds support for setting a min-transfer-speed
in Curl. My goal with this is to fix two problems we have:

- a) Uploads that timeout on slow connections. Right now we set a transfer
  timeout on requests, but given files to upload can be arbitrarily large, that
  can fail. This happened earlier this week to a user (T81365552).
- b) Transfer timeouts in LFS. Right now, we have a very high timeout on
  requests and we can't lower it due to this problem with uploads. Besides,
  the reason for lowering the timeout would be to retry thing, but right now
  we don't support this anyway.

Reviewed By: xavierd

Differential Revision: D25615788

fbshipit-source-id: 57d75ee8f522cf8524f9d12103e34b0765b6846a
2021-01-04 06:22:54 -08:00
Thomas Orozco
0403998080 revisionstore: group http options in a struct
Summary:
I'd like to make it a little easier to add more options without having to
thread them all the way through to the HTTP transfer callsite.

Reviewed By: xavierd

Differential Revision: D25615787

fbshipit-source-id: 4c6274dc2e6b5ba878e0027aae9a08b04f974463
2021-01-04 06:22:54 -08:00
svcscm
816165e6b0 Updating submodules
Summary:
GitHub commits:

f79b70efb9
49875b201a
b7931d6b75
a5e9ac31d1

Reviewed By: jurajh-fb

fbshipit-source-id: 40348345070506c9a76b3560712a23f8f871c214
2021-01-02 20:37:42 -08:00
svcscm
e8adf55634 Updating submodules
Summary:
GitHub commits:

217dd45f75
a010928123
87d32b733d
79bf710959
2ca021659f
4010259964

Reviewed By: jurajh-fb

fbshipit-source-id: 88ed0aaad779a91819fdc80cb2caa0ae9beb1934
2021-01-01 23:22:21 -08:00
svcscm
e2aa278b39 Updating submodules
Summary:
GitHub commits:

4274a6d198
d27c9a1fb5
6c6b097fc8
0d74e1de94

Reviewed By: jurajh-fb

fbshipit-source-id: 8c64c58dc2d231d043d73aa11c2d2f8df589e04a
2021-01-01 19:22:27 -08:00
svcscm
7230031187 Updating submodules
Summary:
GitHub commits:

e06d5f94cc
28f593246f
3db829eacb
cc09a71fc2
5b634d443a
d6ed8042a0
900fbdf44d

Reviewed By: jurajh-fb

fbshipit-source-id: 4d386eae9c222a814ba9b5533bf8f358a6a647aa
2020-12-31 22:23:01 -08:00