Draft: feat: add referrers data to internal List Tags API
What does this MR do?
Extends the List Tags API to include referrer info for each tag - i.e. each manifest that has a subject reference to the tag.
- Adds a
referral=true
query option to the List Tags endpoint. The value must betrue
for referrers to be included. - For each tag that would be output, the referrer info (if present) is appended in this format:
...
"referrers": [
{
"artifactType": "application/vnd.dev.cosign.artifact.sig.v1+json",
"digest": "sha256:eb110b254f038cd0d464b20de5070099a6f675b9d8eb7e5035d929540a041ab1"
},
...
]
...
Notes
-
models.TagDetail
was extended with theReferrers
field. -
The use ofWe should useartifactType
versusmediaType
is being discussed in #1133 (closed) which follows from this issue ( #1009 (closed)). This field in the internal API can be easily changed to fit our needs.artifactType
here. - Manifest subject is a very new feature and there is presumably limited data to analyze against. Below is an example query that ran quickly in DBL:
Query
SELECT
encode(m.digest, 'hex') AS digest,
mt.media_type,
encode(ms.digest, 'hex') AS subject_digest
FROM manifests AS m
JOIN media_types AS mt ON mt.id = m.media_type_id
JOIN manifests AS ms ON m.top_level_namespace_id = ms.top_level_namespace_id
AND m.repository_id = ms.repository_id
AND m.subject_id = ms.id
WHERE
m.top_level_namespace_id = 1
AND m.repository_id = 1
AND m.subject_id IN (
SELECT id
FROM manifests
WHERE
top_level_namespace_id = 1
AND repository_id = 1
AND digest IN (
SELECT decode(n, 'hex')
FROM unnest(ARRAY[
'01aa681fceae02d6f4bde6ca81bc09af8a95af71f513de8df709db0543fd4db382',
'016891eb23653d10cb8bb1cb5487565e31c4d39ce36db60584d98293fca75b0912',
'01176ddd66b2208eb1295989898e3264a5fb24b3a50584e120edd64e54d50feffa'
]) AS n
)
)
Plan
Nested Loop (cost=4.31..12.63 rows=1 width=107) (actual time=0.066..0.068 rows=0 loops=1)
Buffers: shared hit=7
I/O Timings: read=0.000 write=0.000
-> Nested Loop Semi Join (cost=3.88..9.17 rows=1 width=109) (actual time=0.066..0.068 rows=0 loops=1)
Buffers: shared hit=7
I/O Timings: read=0.000 write=0.000
-> Hash Join (cost=3.46..5.64 rows=1 width=101) (actual time=0.065..0.067 rows=0 loops=1)
Hash Cond: (mt.id = m.media_type_id)
Buffers: shared hit=7
I/O Timings: read=0.000 write=0.000
-> Seq Scan on public.media_types mt (cost=0.00..1.85 rows=85 width=45) (actual time=0.007..0.007 rows=1 loops=1)
Buffers: shared hit=1
I/O Timings: read=0.000 write=0.000
-> Hash (cost=3.44..3.44 rows=1 width=60) (actual time=0.036..0.036 rows=0 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 8kB
Buffers: shared hit=6
I/O Timings: read=0.000 write=0.000
-> Index Scan using manifests_p_56_top_level_namespace_id_repository_id_id_conf_key on partitions.manifests_p_56 m (cost=0.42..3.44 rows=1 width=60) (actual time=0.036..0.036 rows=0 loops=1)
Index Cond: ((m.top_level_namespace_id = 1) AND (m.repository_id = 1))
Buffers: shared hit=6
I/O Timings: read=0.000 write=0.000
-> Nested Loop Semi Join (cost=0.43..3.52 rows=1 width=8) (actual time=0.000..0.000 rows=0 loops=0)
I/O Timings: read=0.000 write=0.000
-> Index Scan using manifests_p_56_top_level_namespace_id_repository_id_id_conf_key on partitions.manifests_p_56 manifests (cost=0.42..3.44 rows=1 width=42) (actual time=0.000..0.000 rows=0 loops=0)
Index Cond: ((manifests.top_level_namespace_id = 1) AND (manifests.repository_id = 1))
I/O Timings: read=0.000 write=0.000
-> Function Scan on unnest n (cost=0.00..0.03 rows=3 width=32) (actual time=0.000..0.000 rows=0 loops=0)
I/O Timings: read=0.000 write=0.000
-> Index Scan using manifests_p_56_top_level_namespace_id_repository_id_id_conf_key on partitions.manifests_p_56 ms (cost=0.42..3.44 rows=1 width=58) (actual time=0.000..0.000 rows=0 loops=0)
Index Cond: ((ms.top_level_namespace_id = 1) AND (ms.repository_id = 1))
I/O Timings: read=0.000 write=0.000
Author checklist
-
Feature flags -
Added feature flag: -
This feature does not require a feature flag
-
-
I added unit tests or they are not required -
I added documentation (or it's not required) -
I followed code review guidelines -
I followed Go Style guidelines -
For database changes including schema migrations: -
Manually run up and down migrations in a postgres.ai production database clone and post a screenshot of the result here. -
If adding new queries, extract a query plan from postgres.ai and post the link here. If changing existing queries, also extract a query plan for the current version for comparison. -
Do not include code that depends on the schema migrations in the same commit. Split the MR into two or more.
-
-
Ensured this change is safe to deploy to individual stages in the same environment ( cny
->prod
). State-related changes can be troublesome due to having parts of the fleet processing (possibly related) requests in different ways.
Reviewer checklist
-
Ensure the commit and MR tittle are still accurate. -
If the change contains a breaking change, apply the breaking change label. -
If the change is considered high risk, apply the label high-risk-change -
Identify if the change can be rolled back safely. (note: all other reasons for not being able to rollback will be sufficiently captured by major version changes).
If the MR introduces database schema migrations:
-
Ensure the commit and MR tittle start with fix:
,feat:
, orperf:
so that the change appears on the Changelog
If the changes cannot be rolled back follow these steps:
-
If not, apply the label cannot-rollback. -
Add a section to the MR description that includes the following details: -
The reasoning behind why a release containing the presented MR can not be rolled back (e.g. schema migrations or changes to the FS structure) -
Detailed steps to revert/disable a feature introduced by the same change where a migration cannot be rolled back. (note: ideally MRs containing schema migrations should not contain feature changes.) -
Ensure this MR does not add code that depends on these changes that cannot be rolled back.
-
Related to #1009 (closed)
Edited by Aaron Huntsman