Skip to content

Commit

Permalink
feat: display init container images on the rollout dashboard
Browse files Browse the repository at this point in the history
Signed-off-by: Chetan Banavikalmutt <[email protected]>
  • Loading branch information
chetan-rns committed Mar 26, 2024
1 parent 3bd955a commit 65c5aa7
Show file tree
Hide file tree
Showing 9 changed files with 352 additions and 147 deletions.
353 changes: 238 additions & 115 deletions pkg/apiclient/rollout/rollout.pb.go

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions pkg/apiclient/rollout/rollout.proto
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ message RolloutInfo {
repeated ContainerInfo containers = 19;

repeated github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.CanaryStep steps = 20;

repeated ContainerInfo initContainers = 21;
}

message ExperimentInfo {
Expand Down Expand Up @@ -125,6 +127,7 @@ message ReplicaSetInfo {
repeated PodInfo pods = 14;
bool ping = 15;
bool pong = 16;
repeated string initContainerImages = 17;
}

message PodInfo {
Expand Down
12 changes: 12 additions & 0 deletions pkg/apiclient/rollout/rollout.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -5990,6 +5990,12 @@
},
"pong": {
"type": "boolean"
},
"initContainerImages": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
Expand Down Expand Up @@ -6097,6 +6103,12 @@
"items": {
"$ref": "#/definitions/github.com.argoproj.argo_rollouts.pkg.apis.rollouts.v1alpha1.CanaryStep"
}
},
"initContainers": {
"type": "array",
"items": {
"$ref": "#/definitions/rollout.ContainerInfo"
}
}
}
},
Expand Down
5 changes: 5 additions & 0 deletions pkg/kubectl-argo-rollouts/info/replicaset_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ func GetReplicaSetInfo(ownerUID types.UID, ro *v1alpha1.Rollout, allReplicaSets
for _, ctr := range rs.Spec.Template.Spec.Containers {
rsInfo.Images = append(rsInfo.Images, ctr.Image)
}

for _, ctr := range rs.Spec.Template.Spec.InitContainers {
rsInfo.InitContainerImages = append(rsInfo.InitContainerImages, ctr.Image)
}

rsInfos = append(rsInfos, rsInfo)
}
sort.Slice(rsInfos[:], func(i, j int) bool {
Expand Down
7 changes: 7 additions & 0 deletions pkg/kubectl-argo-rollouts/info/rollout_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,23 @@ func NewRolloutInfo(
roInfo.Containers = []*rollout.ContainerInfo{}

var containerList []corev1.Container
var initContainerList []corev1.Container
if workloadRef != nil {
containerList = workloadRef.Spec.Template.Spec.Containers
initContainerList = workloadRef.Spec.Template.Spec.InitContainers
} else {
containerList = ro.Spec.Template.Spec.Containers
initContainerList = ro.Spec.Template.Spec.InitContainers
}

for _, c := range containerList {
roInfo.Containers = append(roInfo.Containers, &rollout.ContainerInfo{Name: c.Name, Image: c.Image})
}

for _, c := range initContainerList {
roInfo.InitContainers = append(roInfo.InitContainers, &rollout.ContainerInfo{Name: c.Name, Image: c.Image})
}

if ro.Status.RestartedAt != nil {
roInfo.RestartedAt = ro.Status.RestartedAt.String()
} else {
Expand Down
5 changes: 3 additions & 2 deletions ui/src/app/components/rollout/containers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import {faExclamationCircle, faPencilAlt, faSave, faTimes} from '@fortawesome/fr
interface ContainersWidgetProps {
containers: RolloutContainerInfo[];
images: ImageInfo[];
name: string;
interactive?: {
editState: ReactStatePair;
setImage: (container: string, image: string, tag: string) => void;
};
}

export const ContainersWidget = (props: ContainersWidgetProps) => {
const {containers, images, interactive} = props;
const {containers, images, name, interactive} = props;
const [editing, setEditing] = interactive?.editState || [null, null];
const inputMap: {[key: string]: string} = {};
for (const container of containers) {
Expand All @@ -29,7 +30,7 @@ export const ContainersWidget = (props: ContainersWidgetProps) => {
<React.Fragment>
<div style={{display: 'flex', alignItems: 'center', height: '2em'}}>
<div className='info__title' style={{marginBottom: '0'}}>
Containers
{name}
</div>

{interactive &&
Expand Down
6 changes: 4 additions & 2 deletions ui/src/app/components/rollout/revision.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as moment from 'moment';
import {RolloutAnalysisRunInfo, RolloutExperimentInfo, RolloutReplicaSetInfo} from '../../../models/rollout/generated';
import {IconForTag} from '../../shared/utils/utils';
import {ReplicaSets} from '../pods/pods';
import {ImageInfo, parseImages} from './rollout';
import {ImageInfo, parseImages, parseInitContainerImages} from './rollout';
import './rollout.scss';
import '../pods/pods.scss';
import {ConfirmButton} from '../confirm-button/confirm-button';
Expand Down Expand Up @@ -61,6 +61,8 @@ export const RevisionWidget = ({current, initCollapsed, revision, rollback}: Rev
const [collapsed, setCollapsed] = React.useState(initCollapsed);
const icon = collapsed ? faChevronCircleDown : faChevronCircleUp;
const images = parseImages(revision.replicaSets ?? []);
const initContainerImages = parseInitContainerImages(revision.replicaSets ?? []);
const combinedImages = images.concat(initContainerImages);
const hasPods = (revision.replicaSets || []).some((rs) => rs.pods?.length > 0);

return (
Expand All @@ -81,7 +83,7 @@ export const RevisionWidget = ({current, initCollapsed, revision, rollback}: Rev
</div>
</div>
<div className='revision__images'>
<ImageItems images={images} />
<ImageItems images={combinedImages} />
</div>

{!collapsed && (
Expand Down
96 changes: 68 additions & 28 deletions ui/src/app/components/rollout/rollout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,35 +48,23 @@ export const parseImages = (replicaSets: RolloutReplicaSetInfo[]): ImageInfo[] =
const unknownImages: {[key: string]: boolean} = {};
(replicaSets || []).forEach((rs) => {
(rs.images || []).forEach((img) => {
const tags: ImageTag[] = [];

if (rs.canary) {
tags.push(ImageTag.Canary);
}
if (rs.stable) {
tags.push(ImageTag.Stable);
}
if (rs.active) {
tags.push(ImageTag.Active);
}
if (rs.preview) {
tags.push(ImageTag.Preview);
}
updateImageInfo(rs,img,images,unknownImages);
});
});

if (images[img]) {
images[img].tags = [...tags, ...images[img].tags];
} else {
images[img] = {
image: img,
tags: tags,
};
}
const imgArray = Object.values(images);
imgArray.sort((a, b) => {
return unknownImages[a.image] ? 1 : -1;
});
return imgArray;
};

if (images[img].tags.length === 0) {
unknownImages[img] = true;
} else {
unknownImages[img] = false;
}
export const parseInitContainerImages = (replicaSets: RolloutReplicaSetInfo[]): ImageInfo[] => {
const images: {[key: string]: ImageInfo} = {};
const unknownImages: {[key: string]: boolean} = {};
(replicaSets || []).forEach((rs) => {
(rs.initContainerImages || []).forEach((img) => {
updateImageInfo(rs,img,images,unknownImages);
});
});

Expand All @@ -87,15 +75,49 @@ export const parseImages = (replicaSets: RolloutReplicaSetInfo[]): ImageInfo[] =
return imgArray;
};

const updateImageInfo = (rs: RolloutReplicaSetInfo,img: string ,images: {[key: string]: ImageInfo},unknownImages:{[key: string]: boolean}) => {
const tags: ImageTag[] = [];

if (rs.canary) {
tags.push(ImageTag.Canary);
}
if (rs.stable) {
tags.push(ImageTag.Stable);
}
if (rs.active) {
tags.push(ImageTag.Active);
}
if (rs.preview) {
tags.push(ImageTag.Preview);
}

if (images[img]) {
images[img].tags = [...tags, ...images[img].tags];
} else {
images[img] = {
image: img,
tags: tags,
};
}

if (images[img].tags.length === 0) {
unknownImages[img] = true;
} else {
unknownImages[img] = false;
}
};

export type ReactStatePair = [boolean, React.Dispatch<React.SetStateAction<boolean>>];

export const RolloutWidget = (props: {rollout: RolloutRolloutInfo; interactive?: {editState: ReactStatePair; api: RolloutServiceApi; namespace: string}}) => {
const {rollout, interactive} = props;
const curStep = parseInt(rollout.step, 10) || (rollout.steps || []).length;
const revisions = ProcessRevisions(rollout);

const images = parseImages(rollout?.replicaSets || []);
const initContainerEditState = React.useState(false);
const initContainerImages = parseInitContainerImages(rollout?.replicaSets || []);

const images = parseImages(rollout?.replicaSets || []);
for (const img of images) {
for (const container of rollout.containers || []) {
if (img.image === container.image) {
Expand Down Expand Up @@ -132,6 +154,7 @@ export const RolloutWidget = (props: {rollout: RolloutRolloutInfo; interactive?:
<div className='info rollout__info'>
<ContainersWidget
images={images}
name='Containers'
containers={rollout.containers || []}
interactive={
interactive
Expand All @@ -145,6 +168,23 @@ export const RolloutWidget = (props: {rollout: RolloutRolloutInfo; interactive?:
}
/>
</div>
{rollout.initContainers && <div className='info rollout__info'>
<ContainersWidget
images={initContainerImages}
name='Init Containers'
containers={rollout.initContainers || []}
interactive={
interactive
? {
editState: initContainerEditState,
setImage: (container, image, tag) => {
interactive.api.rolloutServiceSetRolloutImage({}, interactive.namespace, rollout.objectMeta?.name, container, image, tag);
},
}
: null
}
/>
</div>}
</div>

<div className='rollout__row rollout__row--bottom'>
Expand Down
12 changes: 12 additions & 0 deletions ui/src/models/rollout/generated/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7361,6 +7361,12 @@ export interface RolloutReplicaSetInfo {
* @memberof RolloutReplicaSetInfo
*/
pong?: boolean;
/**
*
* @type {Array<string>}
* @memberof RolloutReplicaSetInfo
*/
initContainerImages?: Array<string>;
}
/**
*
Expand Down Expand Up @@ -7526,6 +7532,12 @@ export interface RolloutRolloutInfo {
* @memberof RolloutRolloutInfo
*/
steps?: Array<GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1CanaryStep>;
/**
*
* @type {Array<RolloutContainerInfo>}
* @memberof RolloutRolloutInfo
*/
initContainers?: Array<RolloutContainerInfo>;
}
/**
*
Expand Down

0 comments on commit 65c5aa7

Please sign in to comment.