Skip to content

Commit 76ea813

Browse files
Merge pull request #1278 from wking/update-godocs-skill
NO-ISSUE: .claude/commands/update-godocs: New command for Go doc updates
2 parents 8bfba29 + 3054f3c commit 76ea813

File tree

2 files changed

+149
-37
lines changed

2 files changed

+149
-37
lines changed

.claude/commands/update-godocs.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
name: update-godocs
3+
description: Update comments on functions, structures, and properties within a Go file.
4+
parameters:
5+
- name: path
6+
description: Path to the Go file to update. One path at a time to make it easy to spread out review load.
7+
required: true
8+
---
9+
10+
You are helping users update comments on functions, structures, and properties in Go files to make it easier for new users to understand package behavior.
11+
12+
## Context
13+
14+
15+
## Your Task
16+
17+
Based on the user's path: "{{path}}"
18+
19+
1. Read the Go code for that path and other Go files (with the `.go` suffix, excluding the `_test.go` suffix) in that directory to understand the package's functionality.
20+
2. Ensure that there is a Go file in the directory with the package-summary `// Package ...` comment.
21+
If there is not yet such a file, create one, including a comment that summarizes the overall package functionality.
22+
3. For {{path}}, update the Go comments describing API elements to improve accuracy and clarity.
23+
Prioritize public functions, structures, and properties.
24+
If all public APIs already have accurate, clear comments, update comments on the file's internal APIs.

pkg/cincinnati/cincinnati.go

Lines changed: 125 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
// Package cincinnati provides a client for interacting with the Cincinnati update service.
2+
//
3+
// Cincinnati is the OpenShift update recommendation service that provides update graphs
4+
// indicating which cluster versions can safely upgrade to which target versions. The service
5+
// returns both unconditional update recommendations (via edges in the update graph) and
6+
// conditional update recommendations (via conditionalEdges with associated risks).
7+
//
8+
// The Client fetches update graphs from an upstream Cincinnati server using the Cincinnati v1
9+
// Graph API. It handles:
10+
// - Querying for available updates based on the current cluster version, architecture, and channel
11+
// - Parsing the update graph response to identify recommended next-hop updates
12+
// - Processing conditional updates that may have associated risks requiring evaluation
13+
// - Handling transitions between single and multi-architecture deployments
14+
//
15+
// Update graphs consist of nodes (representing cluster versions) and edges (representing
16+
// valid upgrade paths). Conditional edges represent upgrades that are only recommended
17+
// when certain risk conditions are evaluated and deemed acceptable.
118
package cincinnati
219

320
import (
@@ -20,29 +37,40 @@ import (
2037
)
2138

2239
const (
23-
// GraphMediaType is the media-type specified in the HTTP Accept header
24-
// of requests sent to the Cincinnati-v1 Graph API.
40+
// GraphMediaType is the media type specified in the HTTP Accept header
41+
// for requests sent to the Cincinnati v1 Graph API.
2542
GraphMediaType = "application/json"
2643

27-
// Timeout when calling upstream Cincinnati stack.
44+
// getUpdatesTimeout is the maximum duration allowed for a single request
45+
// to the upstream Cincinnati service.
2846
getUpdatesTimeout = time.Minute * 60
2947
)
3048

31-
// Client is a Cincinnati client which can be used to fetch update graphs from
32-
// an upstream Cincinnati stack.
49+
// Client is a Cincinnati client for fetching update graphs from an upstream
50+
// Cincinnati service. It maintains connection settings and cluster identification
51+
// for making requests to the update service.
3352
type Client struct {
34-
id uuid.UUID
53+
// id is the unique cluster identifier sent with each update request.
54+
id uuid.UUID
55+
56+
// transport configures HTTP transport settings including TLS configuration,
57+
// proxy settings, and connection pooling.
3558
transport *http.Transport
3659

37-
// userAgent configures the User-Agent header for upstream
38-
// requests. If empty, the User-Agent header will not be
39-
// populated.
60+
// userAgent is the User-Agent header value for upstream requests.
61+
// If empty, the User-Agent header will not be set.
4062
userAgent string
4163

64+
// conditionRegistry evaluates conditional update risks and prunes invalid
65+
// matching rules before storing conditional updates.
4266
conditionRegistry clusterconditions.ConditionRegistry
4367
}
4468

45-
// NewClient creates a new Cincinnati client with the given client identifier.
69+
// NewClient creates a new Cincinnati client with the specified configuration.
70+
// The id parameter uniquely identifies the cluster making update requests.
71+
// The transport parameter configures HTTP settings including TLS and proxy configuration.
72+
// The userAgent parameter sets the User-Agent header for requests (optional).
73+
// The conditionRegistry parameter is used to evaluate and prune conditional update risks.
4674
func NewClient(id uuid.UUID, transport *http.Transport, userAgent string, conditionRegistry clusterconditions.ConditionRegistry) Client {
4775
return Client{
4876
id: id,
@@ -52,15 +80,17 @@ func NewClient(id uuid.UUID, transport *http.Transport, userAgent string, condit
5280
}
5381
}
5482

55-
// Error is returned when are unable to get updates.
83+
// Error represents a failure when fetching updates from the Cincinnati service.
5684
type Error struct {
57-
// Reason is the reason suggested for the ClusterOperator status condition.
85+
// Reason is the machine-readable reason code for the ClusterVersion
86+
// RetrievedUpdates condition (e.g., "RemoteFailed", "ResponseInvalid").
5887
Reason string
5988

60-
// Message is the message suggested for the ClusterOperator status condition.
89+
// Message is the human-readable error message for the ClusterVersion
90+
// RetrievedUpdates condition.
6191
Message string
6292

63-
// cause is the upstream error, if any, being wrapped by this error.
93+
// cause is the underlying error that triggered this failure, if any.
6494
cause error
6595
}
6696

@@ -69,19 +99,35 @@ func (err *Error) Error() string {
6999
return fmt.Sprintf("%s: %s", err.Reason, err.Message)
70100
}
71101

72-
// GetUpdates fetches the current and next-applicable update payloads from the specified
73-
// upstream Cincinnati stack given the current version, desired architecture, and channel.
74-
// The command:
102+
// GetUpdates retrieves available cluster updates from the Cincinnati service.
103+
// It returns the current release information, a list of unconditionally recommended
104+
// updates, a list of conditionally recommended updates, and any error encountered.
75105
//
76-
// 1. Downloads the update graph from the requested URI for the requested desired arch and channel.
77-
// 2. Finds the current version entry under .nodes.
78-
// 3. If a transition from single to multi architecture has been requested, the only valid
79-
// version is the current version so it's returned.
80-
// 4. Finds recommended next-hop updates by searching .edges for updates from the current
81-
// version. Returns a slice of target Releases with these unconditional recommendations.
82-
// 5. Finds conditionally recommended next-hop updates by searching .conditionalEdges for
83-
// updates from the current version. Returns a slice of ConditionalUpdates with these
84-
// conditional recommendations.
106+
// The method performs the following steps:
107+
// 1. Constructs a query to the Cincinnati service including the cluster architecture,
108+
// update channel, cluster ID, and current version.
109+
// 2. Downloads and parses the update graph from the service.
110+
// 3. Locates the current version within the graph nodes.
111+
// 4. For single-to-multi architecture transitions, returns only the current version
112+
// in multi-architecture form as the sole valid update.
113+
// 5. Identifies unconditional update recommendations by following edges from the
114+
// current version to destination nodes.
115+
// 6. Identifies conditional update recommendations from conditionalEdges, filtering
116+
// out duplicates and pruning invalid risk matching rules.
117+
//
118+
// Parameters:
119+
// - ctx: Context for the HTTP request, allowing cancellation
120+
// - uri: Base URI of the Cincinnati service
121+
// - desiredArch: Target architecture for updates (e.g., "amd64", "Multi")
122+
// - currentArch: Current cluster architecture
123+
// - channel: Update channel name (e.g., "stable-4.14", "fast-4.15")
124+
// - version: Current semantic version of the cluster
125+
//
126+
// Returns:
127+
// - Current release metadata from the update graph
128+
// - Slice of unconditionally recommended update releases (nil if none)
129+
// - Slice of conditionally recommended updates with associated risks (nil if none)
130+
// - Error if the request fails or the response is invalid
85131
func (c Client) GetUpdates(ctx context.Context, uri *url.URL, desiredArch, currentArch, channel string,
86132
version semver.Version) (configv1.Release, []configv1.Release, []configv1.ConditionalUpdate, error) {
87133

@@ -283,36 +329,69 @@ func (c Client) GetUpdates(ctx context.Context, uri *url.URL, desiredArch, curre
283329
return current, updates, conditionalUpdates, nil
284330
}
285331

332+
// graph represents the update graph structure returned by the Cincinnati service.
333+
// It defines all available cluster versions and the valid upgrade paths between them.
286334
type graph struct {
287-
Nodes []node
288-
Edges []edge
335+
// Nodes contains all cluster version releases available in this channel.
336+
Nodes []node
337+
338+
// Edges defines unconditional upgrade paths as index pairs referencing Nodes.
339+
// Each edge indicates a recommended upgrade from one version to another.
340+
Edges []edge
341+
342+
// ConditionalEdges defines upgrade paths that require risk evaluation.
343+
// These upgrades are only recommended if their associated risks are acceptable.
289344
ConditionalEdges []conditionalEdges `json:"conditionalEdges"`
290345
}
291346

347+
// node represents a single cluster version in the update graph.
292348
type node struct {
293-
Version semver.Version `json:"version"`
294-
Image string `json:"payload"`
349+
// Version is the semantic version of this release.
350+
Version semver.Version `json:"version"`
351+
352+
// Image is the release image pullspec (payload) for this version.
353+
Image string `json:"payload"`
354+
355+
// Metadata contains additional release information such as URL, architecture,
356+
// and supported update channels.
295357
Metadata map[string]interface{} `json:"metadata,omitempty"`
296358
}
297359

360+
// edge represents an unconditional upgrade path between two versions in the graph.
361+
// It is serialized as a two-element array [origin, destination] in JSON.
298362
type edge struct {
299-
Origin int
363+
// Origin is the index of the source version node.
364+
Origin int
365+
366+
// Destination is the index of the target version node.
300367
Destination int
301368
}
302369

370+
// conditionalEdge represents a single conditional upgrade path between two versions
371+
// identified by their version strings rather than node indices.
303372
type conditionalEdge struct {
373+
// From is the semantic version string of the source release.
304374
From string `json:"from"`
305-
To string `json:"to"`
375+
376+
// To is the semantic version string of the target release.
377+
To string `json:"to"`
306378
}
307379

380+
// conditionalEdges groups a set of conditional upgrade edges with their shared risks.
381+
// All edges in this group are subject to the same risk conditions.
308382
type conditionalEdges struct {
309-
Edges []conditionalEdge `json:"edges"`
383+
// Edges contains the conditional upgrade paths sharing these risks.
384+
Edges []conditionalEdge `json:"edges"`
385+
386+
// Risks defines the conditions that must be evaluated to determine if
387+
// these conditional updates are recommended for a particular cluster.
310388
Risks []configv1.ConditionalUpdateRisk `json:"risks"`
311389
}
312390

313-
// UnmarshalJSON unmarshals an edge in the update graph. The edge's JSON
314-
// representation is a two-element array of indices, but Go's representation is
315-
// a struct with two elements so this custom unmarshal method is required.
391+
// UnmarshalJSON deserializes an edge from its JSON representation.
392+
// Edges are represented in JSON as two-element arrays [origin, destination],
393+
// but are stored in Go as a struct with named fields, requiring this custom
394+
// unmarshaling logic.
316395
func (e *edge) UnmarshalJSON(data []byte) error {
317396
var fields []int
318397
if err := json.Unmarshal(data, &fields); err != nil {
@@ -329,14 +408,23 @@ func (e *edge) UnmarshalJSON(data []byte) error {
329408
return nil
330409
}
331410

411+
// convertRetrievedUpdateToRelease converts a Cincinnati graph node to a ClusterVersion Release.
412+
// It combines the node's version and image with metadata parsed from the node's metadata map.
332413
func convertRetrievedUpdateToRelease(update node) (configv1.Release, error) {
333414
release, err := ParseMetadata(update.Metadata)
334415
release.Version = update.Version.String()
335416
release.Image = update.Image
336417
return release, err
337418
}
338419

339-
// ParseMetadata parses release metadata (URL, channels, etc.). It does not populate the version or image properties.
420+
// ParseMetadata extracts release metadata from a node's metadata map.
421+
// It parses the release URL, architecture, and supported update channels.
422+
// The version and image fields are not populated by this function and must
423+
// be set separately by the caller.
424+
//
425+
// Returns a partially populated Release struct and an aggregated error containing
426+
// all parsing errors encountered. Parsing continues even after errors to extract
427+
// as much valid metadata as possible.
340428
func ParseMetadata(metadata map[string]interface{}) (configv1.Release, error) {
341429
release := configv1.Release{}
342430
errs := []error{}

0 commit comments

Comments
 (0)