import React, { useState } from 'react'; import { Button } from "@patternfly/react-core/dist/esm/components/Button"; import { Checkbox } from "@patternfly/react-core/dist/esm/components/Checkbox"; import { Form, FormGroup } from "@patternfly/react-core/dist/esm/components/Form"; import { Modal } from "@patternfly/react-core/dist/esm/components/Modal"; import { TextInput } from "@patternfly/react-core/dist/esm/components/TextInput"; import cockpit from 'cockpit'; import { FormHelper } from 'cockpit-components-form-helper.jsx'; import * as utils from './util.js'; import * as client from './client.js'; import { ErrorNotification } from './Notification.jsx'; import { fmt_to_fragments } from 'utils.jsx'; import { useDialogs } from "dialogs.jsx"; const _ = cockpit.gettext; const ContainerCommitModal = ({ container, localImages }) => { const Dialogs = useDialogs(); const [imageName, setImageName] = useState(""); const [tag, setTag] = useState(""); const [author, setAuthor] = useState(""); const [command, setCommand] = useState(utils.quote_cmdline(container.Config.Cmd)); const [pause, setPause] = useState(false); const [useDocker, setUseDocker] = useState(false); const [dialogError, setDialogError] = useState(""); const [dialogErrorDetail, setDialogErrorDetail] = useState(""); const [commitInProgress, setCommitInProgress] = useState(false); const [nameError, setNameError] = useState(""); const handleCommit = (force) => { if (!force && !imageName) { setNameError(_("Image name is required")); return; } let full_name = imageName + ":" + (tag !== "" ? tag : "latest"); if (full_name.indexOf("/") < 0) full_name = "localhost/" + full_name; if (!force && localImages.some(image => image.isSystem === container.isSystem && image.Name === full_name)) { setNameError(_("Image name is not unique")); return; } function quote(word) { word = word.replace(/"/g, '\\"'); return '"' + word + '"'; } const commitData = {}; commitData.container = container.Id; commitData.repo = imageName; commitData.author = author; commitData.pause = pause; if (useDocker) commitData.format = 'docker'; if (tag) commitData.tag = tag; commitData.changes = []; if (command.trim() !== "") { let cmdData = ""; const words = utils.unquote_cmdline(command.trim()); const cmdStr = words.map(quote).join(", "); cmdData = "CMD [" + cmdStr + "]"; commitData.changes.push(cmdData); } setCommitInProgress(true); setNameError(""); setDialogError(""); setDialogErrorDetail(""); client.commitContainer(container.isSystem, commitData) .then(() => Dialogs.close()) .catch(ex => { setDialogError(cockpit.format(_("Failed to commit container $0"), container.Name)); setDialogErrorDetail(cockpit.format("$0: $1", ex.message, ex.reason)); setCommitInProgress(false); }); }; const commitContent = (
{dialogError && setDialogError("")} />} { setNameError(""); setImageName(value) }} /> { setNameError(""); setTag(value) }} /> ")} value={author} onChange={(_, value) => setAuthor(value)} /> setCommand(value)} /> setPause(val)} label={_("Pause container when creating image")} /> setUseDocker(val)} description={_("Docker format is useful when sharing the image with Docker or Moby Engine")} label={_("Use legacy Docker format")} /> ); return ( {container.Name})} footer={<> {nameError && } } > {commitContent} ); }; export default ContainerCommitModal;