mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-26 21:07:45 +08:00
Merge pull request #5477 from kjzz/fix/publish
error when publishing ipns records without a running daemon
This commit is contained in:
commit
e633eccee4
@ -25,6 +25,13 @@ type ResolvedPath struct {
|
||||
Path path.Path
|
||||
}
|
||||
|
||||
const (
|
||||
recursiveOptionName = "recursive"
|
||||
nocacheOptionName = "nocache"
|
||||
dhtRecordCountOptionName = "dht-record-count"
|
||||
dhtTimeoutOptionName = "dht-timeout"
|
||||
)
|
||||
|
||||
var IpnsCmd = &cmds.Command{
|
||||
Helptext: cmdkit.HelpText{
|
||||
Tagline: "Resolve IPNS names.",
|
||||
@ -67,10 +74,10 @@ Resolve the value of a dnslink:
|
||||
cmdkit.StringArg("name", false, false, "The IPNS name to resolve. Defaults to your node's peerID."),
|
||||
},
|
||||
Options: []cmdkit.Option{
|
||||
cmdkit.BoolOption("recursive", "r", "Resolve until the result is not an IPNS name."),
|
||||
cmdkit.BoolOption("nocache", "n", "Do not use cached entries."),
|
||||
cmdkit.UintOption("dht-record-count", "dhtrc", "Number of records to request for DHT resolution."),
|
||||
cmdkit.StringOption("dht-timeout", "dhtt", "Max time to collect values during DHT resolution eg \"30s\". Pass 0 for no timeout."),
|
||||
cmdkit.BoolOption(recursiveOptionName, "r", "Resolve until the result is not an IPNS name."),
|
||||
cmdkit.BoolOption(nocacheOptionName, "n", "Do not use cached entries."),
|
||||
cmdkit.UintOption(dhtRecordCountOptionName, "dhtrc", "Number of records to request for DHT resolution."),
|
||||
cmdkit.StringOption(dhtTimeoutOptionName, "dhtt", "Max time to collect values during DHT resolution eg \"30s\". Pass 0 for no timeout."),
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) {
|
||||
n, err := cmdenv.GetNode(env)
|
||||
@ -119,9 +126,10 @@ Resolve the value of a dnslink:
|
||||
name = req.Arguments[0]
|
||||
}
|
||||
|
||||
recursive, _ := req.Options["recursive"].(bool)
|
||||
rc, rcok := req.Options["dht-record-count"].(int)
|
||||
dhtt, dhttok := req.Options["dht-timeout"].(string)
|
||||
recursive, _ := req.Options[recursiveOptionName].(bool)
|
||||
rc, rcok := req.Options[dhtRecordCountOptionName].(int)
|
||||
dhtt, dhttok := req.Options[dhtTimeoutOptionName].(string)
|
||||
|
||||
var ropts []nsopts.ResolveOpt
|
||||
if !recursive {
|
||||
ropts = append(ropts, nsopts.Depth(1))
|
||||
|
||||
@ -19,6 +19,21 @@ import (
|
||||
path "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path"
|
||||
)
|
||||
|
||||
var (
|
||||
errAllowOffline = errors.New("can't publish while offline: pass `--allow-offline` to override")
|
||||
errIpnsMount = errors.New("cannot manually publish while IPNS is mounted")
|
||||
errIdentityLoad = errors.New("identity not loaded")
|
||||
)
|
||||
|
||||
const (
|
||||
ipfsPathOptionName = "ipfs-path"
|
||||
resolveOptionName = "resolve"
|
||||
allowOfflineOptionName = "allow-offline"
|
||||
lifeTimeOptionName = "lifetime"
|
||||
ttlOptionName = "ttl"
|
||||
keyOptionName = "key"
|
||||
)
|
||||
|
||||
var PublishCmd = &cmds.Command{
|
||||
Helptext: cmdkit.HelpText{
|
||||
Tagline: "Publish IPNS names.",
|
||||
@ -60,16 +75,17 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
|
||||
},
|
||||
|
||||
Arguments: []cmdkit.Argument{
|
||||
cmdkit.StringArg("ipfs-path", true, false, "ipfs path of the object to be published.").EnableStdin(),
|
||||
cmdkit.StringArg(ipfsPathOptionName, true, false, "ipfs path of the object to be published.").EnableStdin(),
|
||||
},
|
||||
Options: []cmdkit.Option{
|
||||
cmdkit.BoolOption("resolve", "Resolve given path before publishing.").WithDefault(true),
|
||||
cmdkit.StringOption("lifetime", "t",
|
||||
cmdkit.BoolOption(resolveOptionName, "Resolve given path before publishing.").WithDefault(true),
|
||||
cmdkit.StringOption(lifeTimeOptionName, "t",
|
||||
`Time duration that the record will be valid for. <<default>>
|
||||
This accepts durations such as "300s", "1.5h" or "2h45m". Valid time units are
|
||||
"ns", "us" (or "µs"), "ms", "s", "m", "h".`).WithDefault("24h"),
|
||||
cmdkit.StringOption("ttl", "Time duration this record should be cached for (caution: experimental)."),
|
||||
cmdkit.StringOption("key", "k", "Name of the key to be used or a valid PeerID, as listed by 'ipfs key list -l'. Default: <<default>>.").WithDefault("self"),
|
||||
cmdkit.BoolOption(allowOfflineOptionName, "When offline, save the IPNS record to the the local datastore without broadcasting to the network instead of simply failing."),
|
||||
cmdkit.StringOption(ttlOptionName, "Time duration this record should be cached for (caution: experimental)."),
|
||||
cmdkit.StringOption(keyOptionName, "k", "Name of the key to be used or a valid PeerID, as listed by 'ipfs key list -l'. Default: <<default>>.").WithDefault("self"),
|
||||
},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) {
|
||||
n, err := cmdenv.GetNode(env)
|
||||
@ -78,7 +94,12 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
|
||||
return
|
||||
}
|
||||
|
||||
allowOffline, _ := req.Options[allowOfflineOptionName].(bool)
|
||||
if !n.OnlineMode() {
|
||||
if !allowOffline {
|
||||
res.SetError(errAllowOffline, cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
err := n.SetupOfflineRouting()
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
@ -87,22 +108,22 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
|
||||
}
|
||||
|
||||
if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() {
|
||||
res.SetError(errors.New("cannot manually publish while IPNS is mounted"), cmdkit.ErrNormal)
|
||||
res.SetError(errIpnsMount, cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
pstr := req.Arguments[0]
|
||||
|
||||
if n.Identity == "" {
|
||||
res.SetError(errors.New("identity not loaded"), cmdkit.ErrNormal)
|
||||
res.SetError(errIdentityLoad, cmdkit.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
popts := new(publishOpts)
|
||||
|
||||
popts.verifyExists, _ = req.Options["resolve"].(bool)
|
||||
popts.verifyExists, _ = req.Options[resolveOptionName].(bool)
|
||||
|
||||
validtime, _ := req.Options["lifetime"].(string)
|
||||
validtime, _ := req.Options[lifeTimeOptionName].(string)
|
||||
d, err := time.ParseDuration(validtime)
|
||||
if err != nil {
|
||||
res.SetError(fmt.Errorf("error parsing lifetime option: %s", err), cmdkit.ErrNormal)
|
||||
@ -112,7 +133,7 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
|
||||
popts.pubValidTime = d
|
||||
|
||||
ctx := req.Context
|
||||
if ttl, found := req.Options["ttl"].(string); found {
|
||||
if ttl, found := req.Options[ttlOptionName].(string); found {
|
||||
d, err := time.ParseDuration(ttl)
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
@ -122,7 +143,7 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
|
||||
ctx = context.WithValue(ctx, "ipns-publish-ttl", d)
|
||||
}
|
||||
|
||||
kname, _ := req.Options["key"].(string)
|
||||
kname, _ := req.Options[keyOptionName].(string)
|
||||
k, err := keylookup(n, kname)
|
||||
if err != nil {
|
||||
res.SetError(err, cmdkit.ErrNormal)
|
||||
|
||||
@ -12,10 +12,11 @@ test_init_ipfs
|
||||
|
||||
# test publishing a hash
|
||||
|
||||
test_expect_success "'ipfs name publish' succeeds" '
|
||||
|
||||
test_expect_success "'ipfs name publish --allow-offline' succeeds" '
|
||||
PEERID=`ipfs id --format="<id>"` &&
|
||||
test_check_peerid "${PEERID}" &&
|
||||
ipfs name publish "/ipfs/$HASH_WELCOME_DOCS" >publish_out
|
||||
ipfs name publish --allow-offline "/ipfs/$HASH_WELCOME_DOCS" >publish_out
|
||||
'
|
||||
|
||||
test_expect_success "publish output looks good" '
|
||||
@ -34,10 +35,10 @@ test_expect_success "resolve output looks good" '
|
||||
|
||||
# now test with a path
|
||||
|
||||
test_expect_success "'ipfs name publish' succeeds" '
|
||||
test_expect_success "'ipfs name publish --allow-offline' succeeds" '
|
||||
PEERID=`ipfs id --format="<id>"` &&
|
||||
test_check_peerid "${PEERID}" &&
|
||||
ipfs name publish "/ipfs/$HASH_WELCOME_DOCS/help" >publish_out
|
||||
ipfs name publish --allow-offline "/ipfs/$HASH_WELCOME_DOCS/help" >publish_out
|
||||
'
|
||||
|
||||
test_expect_success "publish a path looks good" '
|
||||
@ -62,11 +63,11 @@ test_expect_success "ipfs cat on published content succeeds" '
|
||||
|
||||
# publish with an explicit node ID
|
||||
|
||||
test_expect_failure "'ipfs name publish <local-id> <hash>' succeeds" '
|
||||
test_expect_failure "'ipfs name publish --allow-offline <local-id> <hash>' succeeds" '
|
||||
PEERID=`ipfs id --format="<id>"` &&
|
||||
test_check_peerid "${PEERID}" &&
|
||||
echo ipfs name publish "${PEERID}" "/ipfs/$HASH_WELCOME_DOCS" &&
|
||||
ipfs name publish "${PEERID}" "/ipfs/$HASH_WELCOME_DOCS" >actual_node_id_publish
|
||||
echo ipfs name publish --allow-offline "${PEERID}" "/ipfs/$HASH_WELCOME_DOCS" &&
|
||||
ipfs name publish --allow-offline "${PEERID}" "/ipfs/$HASH_WELCOME_DOCS" >actual_node_id_publish
|
||||
'
|
||||
|
||||
test_expect_failure "publish with our explicit node ID looks good" '
|
||||
@ -81,8 +82,8 @@ test_expect_success "generate and verify a new key" '
|
||||
test_check_peerid "${NEWID}"
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name publish --key=<peer-id> <hash>' succeeds" '
|
||||
ipfs name publish --key=${NEWID} "/ipfs/$HASH_WELCOME_DOCS" >actual_node_id_publish
|
||||
test_expect_success "'ipfs name publis --allow-offline --key=<peer-id> <hash>' succeeds" '
|
||||
ipfs name publish --allow-offline --key=${NEWID} "/ipfs/$HASH_WELCOME_DOCS" >actual_node_id_publish
|
||||
'
|
||||
|
||||
test_expect_success "publish an explicit node ID as key name looks good" '
|
||||
@ -94,7 +95,7 @@ test_expect_success "publish an explicit node ID as key name looks good" '
|
||||
# test publishing nothing
|
||||
|
||||
test_expect_success "'ipfs name publish' fails" '
|
||||
printf '' | test_expect_code 1 ipfs name publish >publish_out 2>&1
|
||||
printf '' | test_expect_code 1 ipfs name publish --allow-offline >publish_out 2>&1
|
||||
'
|
||||
|
||||
test_expect_success "publish output has the correct error" '
|
||||
@ -115,4 +116,15 @@ test_expect_success "empty request to name publish doesn't panic and returns err
|
||||
test_kill_ipfs_daemon
|
||||
|
||||
|
||||
# Test daemon in offline mode
|
||||
test_launch_ipfs_daemon --offline
|
||||
|
||||
test_expect_success "'ipfs name publish' fails offline mode" '
|
||||
PEERID=`ipfs id --format="<id>"` &&
|
||||
test_check_peerid "${PEERID}" &&
|
||||
test_expect_code 1 ipfs name publish "/ipfs/$HASH_WELCOME_DOCS"
|
||||
'
|
||||
|
||||
test_kill_ipfs_daemon
|
||||
|
||||
test_done
|
||||
|
||||
@ -62,7 +62,7 @@ test_expect_success "GET IPFS non existent file returns code expected (404)" '
|
||||
'
|
||||
|
||||
test_expect_failure "GET IPNS path succeeds" '
|
||||
ipfs name publish "$HASH" &&
|
||||
ipfs name publish --allow-offline "$HASH" &&
|
||||
PEERID=$(ipfs config Identity.PeerID) &&
|
||||
test_check_peerid "$PEERID" &&
|
||||
curl -sfo actual "http://127.0.0.1:$port/ipns/$PEERID"
|
||||
|
||||
@ -19,7 +19,7 @@ test_resolve_setup_name() {
|
||||
|
||||
test_expect_success "resolve: prepare name" '
|
||||
id_hash=$(ipfs id -f="<id>") &&
|
||||
ipfs name publish "$ref" &&
|
||||
ipfs name publish --allow-offline "$ref" &&
|
||||
printf "$ref\n" >expected_nameval &&
|
||||
ipfs name resolve >actual_nameval &&
|
||||
test_cmp expected_nameval actual_nameval
|
||||
@ -31,7 +31,7 @@ test_resolve_setup_name_fail() {
|
||||
|
||||
test_expect_failure "resolve: prepare name" '
|
||||
id_hash=$(ipfs id -f="<id>") &&
|
||||
ipfs name publish "$ref" &&
|
||||
ipfs name publish --allow-offline "$ref" &&
|
||||
printf "$ref" >expected_nameval &&
|
||||
ipfs name resolve >actual_nameval &&
|
||||
test_cmp expected_nameval actual_nameval
|
||||
|
||||
Loading…
Reference in New Issue
Block a user