ipfs-cluster/sharness/t0030-ctl-pin.sh
Hector Sanjuan 1eade4ae58 Fix #732: Introduce native pin/update
This introduces a pin/update operation which allows to Pin a new item to
cluster indicating that said pin is an update to an already-existing pin.

When this is the case, all the configuration for the existing pin is copied to
the new one (including allocations). The IPFS connector will then trigger
pin/update directly in IPFS, allowing an efficient pinning based on
DAG-differences. Since the allocations where the same for both pins,
the pin/update can proceed.

PinUpdate does not unpin the previous pin (it is not possible to do this
atomically in cluster like it happens in IPFS). The user can manually do it
after the pin/update is done.

Internally, after a lot of deliberations on what the optimal way for this is,
I opted for adding a `PinUpdate` option to the `PinOptions` type (carries the
CID to update from). In order to carry this option from the REST API to the
IPFS Connector, it is serialized in the Protobuf (and stored in the
datastore). There is no other way to do this in a simple fashion since the Pin
object is piece of information that is sent around.

Additionally, making it a PinOption plays well with the Pin/PinPath APIs which
need little changes. Effectively, you are pinning a new thing. You are just
indicating that it should be configured from an existing one.

Fixes #732
2019-08-09 16:11:52 +02:00

103 lines
4.3 KiB
Bash
Executable File

#!/bin/bash
test_description="Test cluster-ctl's pinning and unpinning functionality"
. lib/test-lib.sh
test_ipfs_init
test_cluster_init
test_expect_success IPFS,CLUSTER "pin data to cluster with ctl" '
cid=`docker exec ipfs sh -c "echo test | ipfs add -q"`
ipfs-cluster-ctl pin add "$cid" &&
ipfs-cluster-ctl pin ls "$cid" | grep -q "$cid" &&
ipfs-cluster-ctl status "$cid" | grep -q -i "PINNED"
'
test_expect_success IPFS,CLUSTER "unpin data from cluster with ctl" '
cid=`ipfs-cluster-ctl --enc=json pin ls | jq -r ".[] | .cid | .[\"/\"]" | head -1`
ipfs-cluster-ctl pin rm "$cid" &&
!(ipfs-cluster-ctl pin ls "$cid" | grep -q "$cid") &&
ipfs-cluster-ctl status "$cid" | grep -q -i "UNPINNED"
'
test_expect_success IPFS,CLUSTER "wait for data to pin to cluster with ctl" '
cid=`docker exec ipfs sh -c "dd if=/dev/urandom bs=1024 count=2048 | ipfs add -q"`
ipfs-cluster-ctl pin add --wait "$cid" | grep -q -i "PINNED" &&
ipfs-cluster-ctl pin ls "$cid" | grep -q "$cid" &&
ipfs-cluster-ctl status "$cid" | grep -q -i "PINNED"
'
test_expect_success IPFS,CLUSTER "wait for data to unpin from cluster with ctl" '
cid=`ipfs-cluster-ctl --enc=json pin ls | jq -r ".[] | .cid | .[\"/\"]" | head -1`
ipfs-cluster-ctl pin rm --wait "$cid" | grep -q -i "UNPINNED" &&
!(ipfs-cluster-ctl pin ls "$cid" | grep -q "$cid") &&
ipfs-cluster-ctl status "$cid" | grep -q -i "UNPINNED"
'
test_expect_success IPFS,CLUSTER "wait for data to pin to cluster with ctl with timeout" '
cid=`docker exec ipfs sh -c "dd if=/dev/urandom bs=1024 count=2048 | ipfs add -q"`
ipfs-cluster-ctl pin add --wait --wait-timeout 2s "$cid" | grep -q -i "PINNED" &&
ipfs-cluster-ctl pin ls "$cid" | grep -q "$cid" &&
ipfs-cluster-ctl status "$cid" | grep -q -i "PINNED"
'
test_expect_success IPFS,CLUSTER "wait for data to unpin from cluster with ctl with timeout" '
cid=`ipfs-cluster-ctl --enc=json pin ls | jq -r ".[] | .cid | .[\"/\"]" | head -1`
ipfs-cluster-ctl pin rm --wait --wait-timeout 2s "$cid" | grep -q -i "UNPINNED" &&
!(ipfs-cluster-ctl pin ls "$cid" | grep -q "$cid") &&
ipfs-cluster-ctl status "$cid" | grep -q -i "UNPINNED"
'
cid=(`docker exec ipfs sh -c "mkdir -p /tmp/test1/test2 && touch /tmp/test1/test2/test3.txt && ipfs add -qr /tmp/test1"`)
test_expect_success IPFS,CLUSTER "pin data to cluster with ctl using ipfs paths" '
ipfs-cluster-ctl pin add "/ipfs/${cid[2]}/test2/test3.txt" &&
ipfs-cluster-ctl pin ls "${cid[0]}" | grep -q "${cid[0]}" &&
ipfs-cluster-ctl status "${cid[0]}" | grep -q -i "PINNED"
'
test_expect_success IPFS,CLUSTER "unpin data to cluster with ctl using ipfs paths" '
removed=(`ipfs-cluster-ctl pin rm "/ipfs/${cid[2]}/test2/test3.txt"`) &&
echo "${removed[0]}" | grep -q "${cid[0]}" &&
!(ipfs-cluster-ctl pin ls "${cid[0]}" | grep -q "${cid[0]}") &&
ipfs-cluster-ctl status "${cid[0]}" | grep -q -i "UNPINNED"
'
test_expect_success IPFS,CLUSTER "pin data to cluster with ctl using ipns paths" '
name=`docker exec ipfs sh -c "ipfs name publish -Q ${cid[0]}"`
ipfs-cluster-ctl pin add "/ipns/$name" &&
ipfs-cluster-ctl pin ls "${cid[0]}" | grep -q "${cid[0]}" &&
ipfs-cluster-ctl status "${cid[0]}" | grep -q -i "PINNED"
'
test_expect_success IPFS,CLUSTER "unpin data to cluster with ctl using ipns paths" '
removed=(`ipfs-cluster-ctl pin rm "/ipns/$name"`) &&
echo "${removed[0]}" | grep -q "${cid[0]}" &&
!(ipfs-cluster-ctl pin ls "${cid[0]}" | grep -q "${cid[0]}") &&
ipfs-cluster-ctl status "${cid[0]}" | grep -q -i "UNPINNED"
'
test_expect_success IPFS,CLUSTER "pin data to cluster with user allocations" '
pid=`ipfs-cluster-ctl --enc=json id | jq -r ".id"`
ipfs-cluster-ctl pin add --allocations ${pid} -r 1 "${cid[0]}"
ipfs-cluster-ctl pin ls "${cid[0]}" | grep -q "${cid[0]}" &&
ipfs-cluster-ctl status "${cid[0]}" | grep -q -i "PINNED"
allocations=`ipfs-cluster-ctl --enc=json pin ls | jq .[0].allocations[]`
echo $allocations | wc -w | grep -q 1 &&
echo $allocations | grep -q ${pid}
'
test_expect_success IPFS,CLUSTER "pin update a pin" '
cid1=`docker exec ipfs sh -c "echo test | ipfs add -q"`
ipfs-cluster-ctl pin add "$cid1"
cid2=`docker exec ipfs sh -c "echo test2 | ipfs add -q"`
ipfs-cluster-ctl pin update $cid1 $cid2 &&
ipfs-cluster-ctl pin ls $cid2
'
test_clean_ipfs
test_clean_cluster
test_done