Skip to content

Commit

Permalink
Create a container in a pod
Browse files Browse the repository at this point in the history
This adds the ability to create a new container in a pod group, a
container cannot be moved out or into a pod once it has been created.

Closes: #487
  • Loading branch information
jelly committed Dec 21, 2021
1 parent 6966d39 commit b22f4ae
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 2 deletions.
10 changes: 9 additions & 1 deletion src/Containers.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ class Containers extends React.Component {
this.state = {
width: 0,
showCreateContainerModal: false,
createPod: null,
downloadingContainers: [],
};
this.renderRow = this.renderRow.bind(this);
Expand Down Expand Up @@ -502,7 +503,8 @@ class Containers extends React.Component {
<ImageRunModal
user={this.props.user}
localImages={localImages}
close={() => this.setState({ showCreateContainerModal: false })}
close={() => this.setState({ showCreateContainerModal: false, createPod: null })}
pod={this.state.createPod}
registries={this.props.registries}
selinuxAvailable={this.props.selinuxAvailable}
podmanRestartAvailable={this.props.podmanRestartAvailable}
Expand Down Expand Up @@ -566,6 +568,12 @@ class Containers extends React.Component {
<span>{_("pod group")}</span>
</CardTitle>
<CardActions className='panel-actions'>
<Button
variant="primary"
className="create-container-in-pod"
onClick={() => this.setState({ showCreateContainerModal: true, createPod: this.props.pods[section] })}>
{_("Create container in pod")}
</Button>
<Badge isRead className={"ct-badge-pod-" + podStatus.toLowerCase()}>{_(podStatus)}</Badge>
<PodActions onAddNotification={this.props.onAddNotification} pod={this.props.pods[section]} />
</CardActions>
Expand Down
6 changes: 5 additions & 1 deletion src/ImageRunModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,10 @@ export class ImageRunModal extends React.Component {
getCreateConfig() {
const createConfig = {};

if (this.props.pod) {
createConfig.pod = this.props.pod.Id;
}

if (this.state.image) {
createConfig.image = this.state.image.RepoTags ? this.state.image.RepoTags[0] : "";
} else {
Expand Down Expand Up @@ -1021,7 +1025,7 @@ export class ImageRunModal extends React.Component {
this.props.close();
}
}}
title={_("Create container")}
title={this.props.pod ? cockpit.format(_("Create container in $0"), this.props.pod.Name) : _("Create container")}
footer={<>
{this.state.dialogError && <ErrorNotification errorMessage={this.state.dialogError} errorDetail={this.state.dialogErrorDetail} />}
<Button variant='primary' onClick={this.onCreateClicked} isDisabled={!image && selectedImage === ""}>
Expand Down
33 changes: 33 additions & 0 deletions test/check-application
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class TestApplication(testlib.MachineCase):
# HACK: sometimes podman leaks mounts
self.addCleanup(m.execute, "podman rm --force --all && "
"findmnt --list -otarget | grep /var/lib/containers/. | xargs -r umount || true")
self.addCleanup(m.execute, "podman pod rm --force --all || true")

# Create admin session
m.execute("""
Expand All @@ -77,6 +78,7 @@ class TestApplication(testlib.MachineCase):
self.restore_dir("/home/admin/.local/share/containers", reboot_safe=True)
self.addCleanup(self.admin_s.execute, "systemctl --user stop podman.service podman.socket || true")
self.addCleanup(self.admin_s.execute, "podman rm --force --all || true")
self.addCleanup(self.admin_s.execute, "podman pod rm --force --all || true")

# But disable it globally so that "systemctl --user disable" does what we expect
m.execute("systemctl --global disable podman.socket")
Expand Down Expand Up @@ -1804,6 +1806,37 @@ class TestApplication(testlib.MachineCase):
podmanRestartEnabled = self.execute(True, "systemctl is-enabled podman-restart.service || true").strip()
self.assertEqual(podmanRestartEnabled, 'enabled')

def _testCreateContainerInPod(self, auth):
b = self.browser

container_name = 'containerinpod'
podname = "pod1"
self.execute(auth, f"podman pod create --infra=false --name={podname}")

self.login(auth)

self.filter_containers('all')
b.click(".create-container-in-pod")

# the podname should be in the "Create container" header
self.assertIn(podname, b.text("#pf-modal-part-1"))

b.set_input_text("#run-image-dialog-name", container_name)
b.set_input_text("#create-image-image-select-typeahead", "quay.io/libpod/busybox:latest")
b.click('button.pf-c-toggle-group__button:contains("Local")')
b.click('button.pf-c-select__menu-item:contains("quay.io/libpod/busybox:latest")')
b.click('.pf-c-modal-box__footer button:contains("Create")')

container_sha = self.execute(auth, f"podman inspect --format '{{{{.Id}}}}' {container_name}").strip()
self.waitContainer(container_sha, auth, name=container_name, image='busybox:latest', cmd='sh',
state='running', owner="system" if auth else "admin", pod=podname)

def testCreateContainerInPodSystem(self):
self._testCreateContainerInPod(True)

def testCreateContainerInPodUser(self):
self._testCreateContainerInPod(False)


if __name__ == '__main__':
testlib.test_main()

0 comments on commit b22f4ae

Please sign in to comment.