Skip to content

Commit

Permalink
Allow version upgrades for specific containers and initContainers
Browse files Browse the repository at this point in the history
  • Loading branch information
agouin committed Jun 17, 2024
1 parent 8eb22e7 commit c06bd96
Show file tree
Hide file tree
Showing 10 changed files with 6,204 additions and 5,825 deletions.
8 changes: 8 additions & 0 deletions api/v1/cosmosfullnode_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,14 @@ type ChainVersion struct {
// The docker image for this version in "repository:tag" format. E.g. busybox:latest.
Image string `json:"image"`

// Version overrides for initContainers of the fullnode/sentry pods.
// +optional
InitContainers map[string]string `json:"initContainers"`

// Version overrides for containers of the fullnode/sentry pods.
// +optional
Containers map[string]string `json:"containers"`

// Determines if the node should forcefully halt at the upgrade height.
// +optional
SetHaltHeight bool `json:"setHaltHeight,omitempty"`
Expand Down
25 changes: 20 additions & 5 deletions api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5,202 changes: 2,621 additions & 2,581 deletions config/crd/bases/cosmos.strange.love_cosmosfullnodes.yaml

Large diffs are not rendered by default.

213 changes: 103 additions & 110 deletions config/crd/bases/cosmos.strange.love_scheduledvolumesnapshots.yaml

Large diffs are not rendered by default.

6,466 changes: 3,355 additions & 3,111 deletions config/crd/bases/cosmos.strange.love_statefuljobs.yaml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null
name: manager-role
rules:
- apiGroups:
Expand Down
23 changes: 23 additions & 0 deletions internal/fullnode/build_pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,36 @@ func BuildPods(crd *cosmosv1.CosmosFullNode, cksums ConfigChecksums) ([]diff.Res
return pods, nil
}

func setChainContainerImages(pod *corev1.Pod, v *cosmosv1.ChainVersion) {
setChainContainerImage(pod, v.Image)

for name, image := range v.InitContainers {
for i := range pod.Spec.InitContainers {
if pod.Spec.InitContainers[i].Name == name {
pod.Spec.InitContainers[i].Image = image
break
}
}
}

for name, image := range v.Containers {
for i := range pod.Spec.Containers {
if pod.Spec.Containers[i].Name == name {
pod.Spec.Containers[i].Image = image
break
}
}
}
}

func setChainContainerImage(pod *corev1.Pod, image string) {
for i := range pod.Spec.Containers {
if pod.Spec.Containers[i].Name == mainContainer {
pod.Spec.Containers[i].Image = image
break
}
}

for i := range pod.Spec.InitContainers {
if pod.Spec.InitContainers[i].Name == chainInitContainer {
pod.Spec.InitContainers[i].Image = image
Expand Down
22 changes: 12 additions & 10 deletions internal/fullnode/pod_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,22 +181,28 @@ func podReadinessProbes(crd *cosmosv1.CosmosFullNode) []*corev1.Probe {
func (b PodBuilder) Build() (*corev1.Pod, error) {
pod := b.pod.DeepCopy()

if err := kube.ApplyStrategicMergePatch(pod, podPatch(b.crd)); err != nil {
return nil, err
}

if len(b.crd.Spec.ChainSpec.Versions) > 0 {
instanceHeight := uint64(0)
if height, ok := b.crd.Status.Height[pod.Name]; ok {
instanceHeight = height
}
var image string
for _, version := range b.crd.Spec.ChainSpec.Versions {
if instanceHeight < version.UpgradeHeight {
var vrs *cosmosv1.ChainVersion
for _, v := range b.crd.Spec.ChainSpec.Versions {
v := v
if instanceHeight < v.UpgradeHeight {
break
}
image = version.Image
vrs = &v
}
if image != "" {
setChainContainerImage(pod, image)
if vrs != nil {
setChainContainerImages(pod, vrs)
}
}

if o, ok := b.crd.Spec.InstanceOverrides[pod.Name]; ok {
if o.DisableStrategy != nil {
return nil, nil
Expand All @@ -206,10 +212,6 @@ func (b PodBuilder) Build() (*corev1.Pod, error) {
}
}

if err := kube.ApplyStrategicMergePatch(pod, podPatch(b.crd)); err != nil {
return nil, err
}

kube.NormalizeMetadata(&pod.ObjectMeta)
return pod, nil
}
Expand Down
68 changes: 60 additions & 8 deletions internal/fullnode/pod_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -606,27 +606,79 @@ gaiad start --home /home/operator/cosmos`
}
crd.Spec.ChainSpec.Versions = []cosmosv1.ChainVersion{
{
UpgradeHeight: 1,
UpgradeHeight: 0,
Image: "image:v1.0.0",
},
{
UpgradeHeight: 100,
Image: "image:v2.0.0",
},
{
UpgradeHeight: 300,
Image: "image:v3.0.0",
InitContainers: map[string]string{
"chain-init": "chain-init:v3.0.0",
"new-init": "new-init:v3.0.0",
},
Containers: map[string]string{
"new-sidecar": "new-sidecar:v3.0.0",
},
},
}

crd.Status.Height = map[string]uint64{
"osmosis-0": 1,
"osmosis-1": 150,
"osmosis-2": 300,
}

builder := NewPodBuilder(&crd)
pod, err := builder.WithOrdinal(0).Build()

pod0, err := builder.WithOrdinal(0).Build()
require.NoError(t, err)

containers := lo.SliceToMap(pod.Spec.Containers, func(c corev1.Container) (string, corev1.Container) { return c.Name, c })
containers := lo.SliceToMap(pod0.Spec.Containers, func(c corev1.Container) (string, corev1.Container) { return c.Name, c })
require.ElementsMatch(t, []string{"node", "new-sidecar", "healthcheck", "version-check-interval"}, lo.Keys(containers))
})

test.HasTypeLabel(t, func(crd cosmosv1.CosmosFullNode) []map[string]string {
builder := NewPodBuilder(&crd)
pod, _ := builder.WithOrdinal(5).Build()
return []map[string]string{pod.Labels}
initContainers := lo.SliceToMap(pod0.Spec.InitContainers, func(c corev1.Container) (string, corev1.Container) { return c.Name, c })
require.ElementsMatch(t, []string{"chain-init", "new-init", "genesis-init", "addrbook-init", "config-merge", "version-check", "clean-init"}, lo.Keys(initContainers))

require.Equal(t, "osmosis-0", pod0.Name)

require.Equal(t, "node", pod0.Spec.Containers[0].Name)
require.Equal(t, "image:v1.0.0", pod0.Spec.Containers[0].Image)

require.Equal(t, "chain-init", pod0.Spec.InitContainers[1].Name)
require.Equal(t, "image:v1.0.0", pod0.Spec.InitContainers[1].Image)

pod1, err := builder.WithOrdinal(1).Build()
require.NoError(t, err)

require.Equal(t, "osmosis-1", pod1.Name)

require.Equal(t, "node", pod1.Spec.Containers[0].Name)
require.Equal(t, "image:v2.0.0", pod1.Spec.Containers[0].Image)

require.Equal(t, "chain-init", pod1.Spec.InitContainers[1].Name)
require.Equal(t, "image:v2.0.0", pod1.Spec.InitContainers[1].Image)

pod2, err := builder.WithOrdinal(2).Build()
require.NoError(t, err)

require.Equal(t, "osmosis-2", pod2.Name)

require.Equal(t, "node", pod2.Spec.Containers[0].Name)
require.Equal(t, "image:v3.0.0", pod2.Spec.Containers[0].Image)

require.Equal(t, "new-sidecar", pod2.Spec.Containers[1].Name)
require.Equal(t, "new-sidecar:v3.0.0", pod2.Spec.Containers[1].Image)

require.Equal(t, "chain-init", pod2.Spec.InitContainers[1].Name)
require.Equal(t, "chain-init:v3.0.0", pod2.Spec.InitContainers[1].Image)

require.Equal(t, "new-init", pod2.Spec.InitContainers[2].Name)
require.Equal(t, "new-init:v3.0.0", pod2.Spec.InitContainers[2].Image)

})
}

Expand Down

0 comments on commit c06bd96

Please sign in to comment.