Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add remote pinning policy for mfs #7798

Merged
merged 66 commits into from
Jan 28, 2021
Merged

add remote pinning policy for mfs #7798

merged 66 commits into from
Jan 28, 2021

Conversation

petar
Copy link
Contributor

@petar petar commented Dec 1, 2020

This builds on top of #7559

Needed for #7559 & ipfs/ipfs-gui#91
Needs ipfs/go-ipfs-config#116

Closes #7818

@aschmahmann aschmahmann changed the base branch from master to petar/pincli December 1, 2020 23:31
cmd/ipfs/daemon.go Outdated Show resolved Hide resolved
core/commands/pin/remotepin.go Outdated Show resolved Hide resolved
cmd/ipfs/daemon.go Outdated Show resolved Hide resolved
cmd/ipfs/daemon.go Outdated Show resolved Hide resolved
cmd/ipfs/daemon.go Outdated Show resolved Hide resolved
Copy link
Contributor

@gammazero gammazero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couple of minor comments

cmd/ipfs/daemon.go Outdated Show resolved Hide resolved
cmd/ipfs/daemon.go Outdated Show resolved Hide resolved
cmd/ipfs/daemon.go Outdated Show resolved Hide resolved
@petar petar force-pushed the petar/pinmfs branch 4 times, most recently from 014cfd3 to 9864c13 Compare December 4, 2020 15:00
@aschmahmann aschmahmann changed the base branch from petar/pincli to master December 9, 2020 02:26
@lidel lidel changed the title Petar/pinmfs Add remote pinning policy for MFS Dec 9, 2020
@lidel lidel changed the title Add remote pinning policy for MFS add remote pinning policy for mfs Dec 9, 2020
cmd/ipfs/daemon.go Outdated Show resolved Hide resolved
aschmahmann and others added 2 commits January 21, 2021 13:00
fix: replace pre-existing pins for MFS root
This refactors `ipfs config replace` commands to ensure pinning service
section does not break WebUI:

- allow tweaking Policies via WebUI
- return an error if API credentials are modified
- restore API credentials if missing from input file
- make it impossible to add/remove pinning services via config replace
- make it impossble to proble if API.Key is valid
  (we return error even if API.Key does not change)
@lidel
Copy link
Member

lidel commented Jan 23, 2021

API.Key restore in config replace was nearly ok, but I had to refactor it to comply with output of ipfs config show
(webui reads config via config show and when user edits it, it is saved with config replace, so we can't break the cycle)

I cleaned up func replaceConfig a bit, should be easier to follow now + added tests and the sharness should be green (will check on Monday).

Remaining TODO:

  • confirm the sharness is green
  • add MFS policy docs to docs/config.md
  • test with Pinata again (and decide if we want to cleanup duplicate pins)

Copy link
Contributor

@aschmahmann aschmahmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taking another look through the main part of this PR, but added some comments on config + API key scrubbing

core/commands/config.go Outdated Show resolved Hide resolved
core/commands/config.go Outdated Show resolved Hide resolved
core/commands/config.go Show resolved Hide resolved
core/commands/config.go Outdated Show resolved Hide resolved
core/commands/config.go Outdated Show resolved Hide resolved
test/sharness/t0700-remotepin.sh Show resolved Hide resolved
'

test_expect_success "'ipfs config replace' injects remote services back" '
test_expect_code 1 grep -q -E "test_.+_svc" show_config &&
test_expect_success "'ipfs config replace' injects Pinning.RemoteServices[*].API.Key back" '
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about another test to make sure that we can change or add a policy in the config and the keys + endpoints stay the same?

cmd/ipfs/pinmfs.go Outdated Show resolved Hide resolved
cmd/ipfs/daemon.go Outdated Show resolved Hide resolved
cmd/ipfs/pinmfs.go Outdated Show resolved Hide resolved
cmd/ipfs/pinmfs.go Outdated Show resolved Hide resolved
cmd/ipfs/pinmfs.go Outdated Show resolved Hide resolved
cmd/ipfs/pinmfs.go Show resolved Hide resolved
cmd/ipfs/pinmfs.go Outdated Show resolved Hide resolved
cmd/ipfs/pinmfs.go Outdated Show resolved Hide resolved
cmd/ipfs/pinmfs.go Outdated Show resolved Hide resolved
cmd/ipfs/pinmfs.go Outdated Show resolved Hide resolved
core/commands/config.go Outdated Show resolved Hide resolved
core/commands/config.go Outdated Show resolved Hide resolved
test/sharness/t0700-remotepin.sh Show resolved Hide resolved
Comment on lines 443 to 444
pinErr := make(chan error)
err = pinMFSOnChange(daemonConfigPollInterval, cctx, &ipfsPinMFSNode{node}, pinErr)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect we can move all of this code into core/node and referenced in the Online group in groups.go. There's no reason we need to treat this much differently then whether to start up the DHT or not.

I'm not sure if this is painful or trivial. If it's painful we can refactor in a separate PR.

pinTime := time.Now().UTC()
for ps := range lsPinCh {
existingRequestID = ps.GetRequestId()
if ps.GetPin().GetCid() == cid && ps.GetStatus() != pinclient.StatusFailed {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lidel @petar WDYT about if the state is StatusPinning performing a connection to the Delegates? This would help us out if we submitted an MFS pin but then went offline/router blip before it was fully pinned.

}

type ipfsPinMFSNode struct {
node *core.IpfsNode
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we move into the constructor code then we may be able to take an interface here instead of the raw IpfsNode

}

func pinMFSOnChange(configPollInterval time.Duration, cctx pinMFSContext, node pinMFSNode, errCh chan<- error) error {
go func() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This goroutine seems to be the only thing we do. Any reason not to have the function be synchronous and then call go pinMFSOnChange?

Also, this function seems pretty long/difficult to follow, perhaps we can separate out the timer + state polling logic from the update logic or separate out parts of the update logic. This may also help reduce the number of channels for us to consider at any given point.

Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took it for a spin and works as expected with our reference pinning service implementation at rb-pinning-service-api. 👍

Found some minor issues around edge cases (not blockers, we can fix them in separate PRs/RC, but would be nice to include in this one if possible):

Swallowed errors from pinning service client

I also tested with Pinata and they had a small bug in message format (fix wip), which breaks our client with remote pinning service returned http error 400: json: cannot unmarshal object into Go struct field FailureError.error.details of type string error, which makes it retry pin over and over again, which accumulates errors in memory until I exit the process.

Those pending errors are then returned in bulk when one exits the process :

2021-01-28T14:11:16.251+0100	DEBUG	remotepinning/mfs	pinning loop is awake, 1 remote services
2021-01-28T14:11:16.251+0100	DEBUG	remotepinning/mfs	pinning considering service pinata-test for mfs pinning
2021-01-28T14:11:16.251+0100	DEBUG	remotepinning/mfs	pinning MFS root QmebJqoF9hdcmr2XwfHHv6FjQxkWSvjN266E7PPu9aZboP to pinata-test
2021-01-28T14:11:17.489+0100	DEBUG	remotepinning/mfs	pinning to pinata-test: replacing existing MFS root pin with QmebJqoF9hdcmr2XwfHHv6FjQxkWSvjN266E7PPu9aZboP
^C
Received interrupt signal, shutting down...
(Hit ctrl-c again to force-shutdown the daemon.)

Error: 36 errors occurred:
	* remote pinning service returned http error 400: json: cannot unmarshal object into Go struct field FailureError.error.details of type string
	* remote pinning service returned http error 400: json: cannot unmarshal object into Go struct field FailureError.error.details of type string
	* remote pinning service returned http error 400: json: cannot unmarshal object into Go struct field FailureError.error.details of type string
[...]

Pinata is working on a fix and this should not be a blocker, but I am not sure if silently swallowing this type of errors is a good idea in general.

👉 We should log those error responses via remotepinning/mfs or remotepinning/client logger to save a lot of time in debugging.

Bogus error on disabling MFS policy via ipfs config

This is cosmetic, but when I disable MFS policy I get this error (but it gets disabled just fine):

$ ipfs config --json Pinning.RemoteServices.rb-pinning-service.Policies.MFS.Enable true
$ ipfs config --json Pinning.RemoteServices.rb-pinning-service.Policies.MFS.Enable false
Error: failed to get config value: "Pinning.RemoteServices.rb-pinning-service.Policies.MFS key has no attributes"

@petar
Copy link
Contributor Author

petar commented Jan 28, 2021

Fixed the swallowing issue.

Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 💚 config replace works fine with http://127.0.0.1:5001/webui/
  • 💚 logger remotepinning/mfs shows errors correctly now (but as debug – I think we should change this, see below)
    2021-01-28T20:45:07.412+0100	DEBUG	remotepinning/mfs	pinning MFS root QmdLUV2zPmXpZGyb3ASyxyFwP9fHJZom87KF9Lpr3bCVA9 to pinata-test error (remote pinning service returned http error 400: json: cannot unmarshal object into Go struct field FailureError.error.details of type string)
    
  • 🤔 If there were pinning issues, I still see the accumulated errors when i interrupt ipfs daemon:
    ^C
    Received interrupt signal, shutting down...
    (Hit ctrl-c again to force-shutdown the daemon.)
    
    Error: 5 errors occurred:
      * remote pinning service returned http error 400: json: cannot unmarshal object into Go struct field FailureError.error.details of type string
      * remote pinning service returned http error 400: json: cannot unmarshal object into Go struct field FailureError.error.details of type string
      * remote pinning service returned http error 400: json: cannot unmarshal object into Go struct field FailureError.error.details of type string
      * remote pinning service returned http error 400: json: cannot unmarshal object into Go struct field FailureError.error.details of type string
      * remote pinning service returned http error 400: json: cannot unmarshal object into Go struct field FailureError.error.details of type string
    
    I believe printing errors in realtime is better (see below)

cmd/ipfs/pinmfs.go Outdated Show resolved Hide resolved
Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚢 RC2

@aschmahmann aschmahmann merged commit 8794928 into master Jan 28, 2021
@aschmahmann aschmahmann deleted the petar/pinmfs branch January 28, 2021 23:58
kingwel-xie pushed a commit to kingwel-xie/go-ipfs that referenced this pull request Feb 5, 2021
* remote pinning service MFS policy
* update go-ipfs-config
* hardening secret sanitization in `ipfs config` commands

Co-authored-by: Adin Schmahmann <adin.schmahmann@gmail.com>
Co-authored-by: Marcin Rataj <lidel@lidel.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Error in config show: case mismatch in config
4 participants