Skip to content

Inspect tab#9989

Open
endemics wants to merge 3 commits intorancher-sandbox:mainfrom
endemics:inspect-tab
Open

Inspect tab#9989
endemics wants to merge 3 commits intorancher-sandbox:mainfrom
endemics:inspect-tab

Conversation

@endemics
Copy link
Copy Markdown
Contributor

@endemics endemics commented Mar 8, 2026

This is an implementation proposition for #9986

It provides the base features

  • additional default tab with information about the container pulled from docker inspect output
  • top group displays important information about the container: name, image, short hash, IP, created/started date
  • bottom group with collapsible sections for each of the following: Mounts, Environment, Commands & Args, Capabilities, Ports and Labels

@jandubois
Copy link
Copy Markdown
Member

Thanks for the PR.

I'm very busy right now and don't have time for a proper UI review right now. I'll try to do this later this week.

Can you rebase this branch on latest main to resolve the merge conflicts, and get the commits from your previous PR out of this branch?

Add a new Info tab as the default (leftmost) tab on the container info
page. It calls `docker inspect` via ddClient and displays a summary
table (name, short ID, image, status, IP, timestamps) plus collapsible
sections for mounts, environment, command/args, capabilities, ports and
labels.

Also adds a matching e2e page object and test suite, and marks Container
Exploration as released in the feature tracker.

Signed-off-by: Gildas Le Nadan <3ntr0p13+github@gmail.com>
@endemics
Copy link
Copy Markdown
Contributor Author

@jandubois should be done now. No worries, take your time!

Copy link
Copy Markdown
Contributor

@mook-as mook-as left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay.

- Reorder v-if/v-else-if/v-else so error/unknown state is the final
  fallback; use `{{ error || 'An unknown error has occurred' }}`
- Wrap Name and Image summary fields in <code> for consistent styling
- Replace .section-summary class with nested > summary selector in
  .inspect-section, removing the redundant class from all <summary>
  elements
- Move ContainerInspectData fetch into the container-engine store:
  export ContainerMount/ContainerInspectData interfaces, add
  inspectData state, SET_INSPECT_DATA mutation, and
  fetchContainerInspect action; clear inspectData on backend/namespace
  change; component now dispatches the action and reads data from store
- Simplify e2e nav helper usage (navPage.navigateTo returns the page)

Signed-off-by: Gildas Le Nadan <3ntr0p13+github@gmail.com>
@endemics endemics requested a review from mook-as March 28, 2026 06:22
- Change SET_INSPECT_DATA payload to Record<string, ContainerInspectData>
  to satisfy MutationsType<ContainersState> constraint
- Pass namespace as --namespace=<ns> CLI arg instead of ExecOptions
  property, consistent with the rest of the codebase
- Guard against null client before calling exec

Signed-off-by: Gildas Le Nadan <3ntr0p13+github@gmail.com>
Copy link
Copy Markdown
Contributor

@mook-as mook-as left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks basically fine; just needs some trivial fixes. Please feel free to push back on any comments you don't agree with; nothing here seems that important.

type ValidContainerEngine = Exclude<ContainerEngine, ContainerEngine.NONE>;
type SubscriberType = 'containers' | 'volumes';
type ErrorSource = 'containers' | 'volumes' | 'namespaces';
type ErrorSource = 'containers' | 'volumes' | 'namespaces' | 'inspect';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should still use containers for the error, since inspect is about containers.

const result = await client.docker.cli.exec('inspect', args);
const parsed = result.parseJsonObject() as ContainerInspectData[];

commit('SET_INSPECT_DATA', { ...state.inspectData, [containerId]: parsed[0] });
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess if the container is not found (it's deleted before it manages to run), the result is undefined, which is fine because the view handles it.

Also, this means that we'll accumulate data over time, since nothing ever removes values. That might need to be fixed.

Comment on lines +196 to +200
watch(containerId, () => {
activeTab.value = 'tab-info';
shellEverActivated.value = false;
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we automatically switching tabs on container id change again? But then, I guess the container id should be static while the page is up, so it doesn't matter…

subscriber: Subscriber | null;
containers: Record<string, Container> | null;
volumes: Record<string, Volume> | null;
inspectData: Record<string, ContainerInspectData>;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
inspectData: Record<string, ContainerInspectData>;
inspectData: Record<string, ContainerInspectData | undefined>;

Because of the case where the container might be missing on inspect.

Comment on lines +278 to +279
onMounted(fetchInspect);
watch(() => props.containerId, fetchInspect);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be done as an eager watch?

Suggested change
onMounted(fetchInspect);
watch(() => props.containerId, fetchInspect);
watch(() => props.containerId, fetchInspect, { immediate: true });

const result = await client.docker.cli.exec('inspect', args);
const parsed = result.parseJsonObject() as ContainerInspectData[];

commit('SET_INSPECT_DATA', { ...state.inspectData, [containerId]: parsed[0] });
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I don't understand why we can now assert that .NetworkSettings is always non-null here. Of course, the documentation really doesn't say either way…

const data = computed<ContainerInspectData | undefined>(
() => store.state['container-engine'].inspectData[props.containerId],
);
const loading = ref(false);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be initially true? Theoretically, this defaulting to false means it shows an error (because data isn't loaded), then it shows the loading screen. In practice, of course, that's unlikely to be an issue because fetchInspect should run fast enough…

@jandubois
Copy link
Copy Markdown
Member

I have some feedback on the "look & feel" of the UI:

CleanShot 2026-04-01 at 18 41 26@2x

(1) The top couple of rows are separated by horizontal lines. (2) The following sections are enclosed in boxes whose lengths don't match the horizontal lines.

I know the boxes are meant for grouping, but I think that is necessary if the data is arranged differently. Either way, I think we should only have a single style for each group.

Values are vertically aligned at 3 different lines, (3), (4), and (5). I think all values should be aligned at the right-most line (5), which could be positioned a little further left.

(6) There are some weird looking boxes around some values, with a differently coloured background, but not all of them. This style is normally used for monospaced "code blocks", but here it is used for text using a serif font. I don't think this style should be used for any values, use the same style as used by the Create/Started date values.

The top level values have a grey label, but the collapsible entries use the same colour as the values. They should match the colour, style, and size of the other labels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants