You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ma...@apache.org on 2023/05/04 01:50:34 UTC

[camel-karavan] 05/07: Run container prototype for #757

This is an automated email from the ASF dual-hosted git repository.

marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git

commit cd52a88c05e83bfe505f6e46aeee1da337d91df4
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Wed May 3 18:02:28 2023 -0400

    Run container prototype for #757
---
 .../camel/karavan/service/KubernetesService.java   |   4 +-
 karavan-app/src/main/webui/src/index.css           |  14 +-
 .../main/webui/src/projects/ProjectDevelopment.tsx |  35 ++--
 .../src/main/webui/src/projects/ProjectInfo.tsx    | 178 ---------------------
 .../src/main/webui/src/projects/ProjectPage.tsx    |   1 -
 .../src/main/webui/src/projects/ProjectRunner.tsx  |  23 +--
 .../webui/src/projects/ProjectRunnerToolbar.tsx    |  82 ++++++++++
 karavan-runner/Dockerfile                          |  13 +-
 karavan-runner/docker-entrypoint.sh                |  16 --
 9 files changed, 120 insertions(+), 246 deletions(-)

diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java
index ebdb649e..525f8738 100644
--- a/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java
+++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java
@@ -384,8 +384,8 @@ public class KubernetesService implements HealthCheck{
 
     public String tryCreatePod(String projectId) {
         String name = projectId + "-" + RUNNER_SUFFIX;
-        createPVC(name + JBANG_CACHE_SUFFIX);
-        createPVC(name + M2_CACHE_SUFFIX);
+        createPVC(name + "-" + JBANG_CACHE_SUFFIX);
+        createPVC(name + "-" + M2_CACHE_SUFFIX);
         Pod old = kubernetesClient().pods().inNamespace(getNamespace()).withName(name).get();
         if (old == null) {
             createPod(name);
diff --git a/karavan-app/src/main/webui/src/index.css b/karavan-app/src/main/webui/src/index.css
index 72cf3111..7fa80c96 100644
--- a/karavan-app/src/main/webui/src/index.css
+++ b/karavan-app/src/main/webui/src/index.css
@@ -145,10 +145,22 @@
   font-size: 15px;
 }
 
-.karavan .project-page .project-info {
+.karavan .project-page .project-development {
   margin-bottom: 16px;
 }
 
+.karavan .project-page .project-development .runner-toolbar {
+  line-height: 24px;
+  row-gap: 24px;
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-start;
+}
+.karavan .project-page .project-development .runner-toolbar .row {
+  line-height: 24px;
+  height: 30px;
+}
+
 .karavan .project-page .project-status {
   margin-bottom: 16px;
 }
diff --git a/karavan-app/src/main/webui/src/projects/ProjectDevelopment.tsx b/karavan-app/src/main/webui/src/projects/ProjectDevelopment.tsx
index fd1a6e1d..beb40c6d 100644
--- a/karavan-app/src/main/webui/src/projects/ProjectDevelopment.tsx
+++ b/karavan-app/src/main/webui/src/projects/ProjectDevelopment.tsx
@@ -5,45 +5,36 @@ import {
 } from '@patternfly/react-core';
 import '../designer/karavan.css';
 import {Project} from "./ProjectModels";
-import {ProjectInfo} from "./ProjectInfo";
+import {ProjectRunnerToolbar} from "./ProjectRunnerToolbar";
 import {ProjectRunner} from "./ProjectRunner";
 
 
 interface Props {
     project: Project,
     config: any,
-    needCommit: boolean,
 }
 
-interface State {
-    environment: string,
-}
-
-export class ProjectDevelopment extends React.Component<Props, State> {
-
-    public state: State = {
-        environment: this.props.config.environment
-    };
+export const ProjectDevelopment = (props: Props) => {
 
-    render() {
-        const {project, config, needCommit} = this.props;
-        return (
-            <Card className="project-info">
+    const {project, config} = props;
+    return (
+            <Card className="project-development">
                 <CardBody>
                     <Flex direction={{default: "row"}}
-                          // style={{height: "200px"}}
                           justifyContent={{default: "justifyContentSpaceBetween"}}>
-                        <FlexItem flex={{default: "flex_2"}}>
-                            <ProjectInfo project={project} config={config} needCommit={needCommit} />
+                        <FlexItem flex={{default: "flex_4"}}>
+                            <ProjectRunner project={project} config={config} />
+                        </FlexItem>
+                        <Divider orientation={{default: "vertical"}}/>
+                        <FlexItem flex={{default: "flex_4"}}>
+                            <ProjectRunner project={project} config={config} />
                         </FlexItem>
                         <Divider orientation={{default: "vertical"}}/>
-                        <FlexItem flex={{default: "flex_3"}}>
-                            <ProjectRunner project={project} config={config} needCommit={needCommit} />
+                        <FlexItem>
+                            <ProjectRunnerToolbar project={project} config={config} />
                         </FlexItem>
                     </Flex>
                 </CardBody>
-                {/*{this.state.showDeleteConfirmation && this.getDeleteConfirmation()}*/}
             </Card>
         )
-    }
 }
diff --git a/karavan-app/src/main/webui/src/projects/ProjectInfo.tsx b/karavan-app/src/main/webui/src/projects/ProjectInfo.tsx
deleted file mode 100644
index a7a6ed2d..00000000
--- a/karavan-app/src/main/webui/src/projects/ProjectInfo.tsx
+++ /dev/null
@@ -1,178 +0,0 @@
-import React from 'react';
-import {
-    DescriptionList,
-    DescriptionListTerm,
-    DescriptionListGroup,
-    DescriptionListDescription,
-    Tooltip,
-    Flex,
-    FlexItem,
-    Label,
-    Button,
-    Modal,
-    ModalVariant,
-    Form,
-    FormGroup,
-    TextInput,
-    FormHelperText
-} from '@patternfly/react-core';
-import '../designer/karavan.css';
-import {Project} from "./ProjectModels";
-import {KaravanApi} from "../api/KaravanApi";
-import PushIcon from "@patternfly/react-icons/dist/esm/icons/code-branch-icon";
-
-
-interface Props {
-    project: Project,
-    config: any,
-    needCommit: boolean,
-}
-
-interface State {
-    environment: string,
-    isPushing: boolean,
-    commitMessageIsOpen: boolean,
-    commitMessage: string
-}
-
-export class ProjectInfo extends React.Component<Props, State> {
-
-    public state: State = {
-        environment: this.props.config.environment,
-        isPushing: false,
-        commitMessageIsOpen: false,
-        commitMessage: ''
-    };
-
-    push = (after?: () => void) => {
-        this.setState({isPushing: true, commitMessageIsOpen: false});
-        const params = {
-            "projectId": this.props.project.projectId,
-            "message": this.state.commitMessage
-        };
-        KaravanApi.push(params, res => {
-            if (res.status === 200 || res.status === 201) {
-                this.setState({isPushing: false});
-                after?.call(this);
-                // this.props.onRefresh.call(this);
-            } else {
-                // Todo notification
-            }
-        });
-    }
-
-    getDate(lastUpdate: number): string {
-        if (lastUpdate) {
-            const date = new Date(lastUpdate);
-            return date.toISOString().slice(0, 19).replace('T',' ');
-        } else {
-            return "N/A"
-        }
-    }
-
-    getLastUpdatePanel() {
-        const {project, needCommit} = this.props;
-        const color = needCommit ? "grey" : "green";
-        return (
-            <Flex direction={{default: "row"}} justifyContent={{default: "justifyContentFlexStart"}}>
-                {project?.lastCommitTimestamp && project?.lastCommitTimestamp > 0 &&
-                    <FlexItem>
-                        <Label color={color}>{this.getDate(project?.lastCommitTimestamp)}</Label>
-                    </FlexItem>
-                }
-            </Flex>
-        )
-    }
-
-    getCommitPanel() {
-        const {isPushing, commitMessage} = this.state;
-        const {project, needCommit} = this.props;
-        const color = needCommit ? "grey" : "green";
-        return (
-            <Flex direction={{default: "row"}} justifyContent={{default: "justifyContentSpaceBetween"}}>
-                <FlexItem>
-                    <Tooltip content={project?.lastCommit} position={"right"}>
-                        <Label
-                            color={color}>{project?.lastCommit ? project?.lastCommit?.substr(0, 18) : "-"}</Label>
-                    </Tooltip>
-                </FlexItem>
-                <FlexItem>
-                    <Tooltip content="Commit and push to git" position={"bottom-end"}>
-                        <Button isLoading={isPushing ? true : undefined}
-                                isSmall
-                                variant={needCommit ? "primary" : "secondary"}
-                                className="project-button"
-                                icon={!isPushing ? <PushIcon/> : <div></div>}
-                                onClick={() => this.setState({
-                                    commitMessageIsOpen: true,
-                                    commitMessage : commitMessage === ''
-                                        ? new Date().toISOString().slice(0, 19).replace('T',' ')
-                                        : commitMessage
-                                })}>
-                            {isPushing ? "..." : "Push"}
-                        </Button>
-                    </Tooltip>
-                </FlexItem>
-            </Flex>
-        )
-    }
-
-    getCommitModal() {
-        let {commitMessage, commitMessageIsOpen} = this.state;
-        return (
-            <Modal
-                title="Commit"
-                variant={ModalVariant.small}
-                isOpen={commitMessageIsOpen}
-                onClose={() => this.setState({commitMessageIsOpen: false})}
-                actions={[
-                    <Button key="confirm" variant="primary" onClick={() => this.push()}>Save</Button>,
-                    <Button key="cancel" variant="secondary"
-                            onClick={() => this.setState({commitMessageIsOpen: false})}>Cancel</Button>
-                ]}
-            >
-                <Form autoComplete="off" isHorizontal className="create-file-form">
-                    <FormGroup label="Message" fieldId="name" isRequired>
-                        <TextInput value={commitMessage} onChange={value => this.setState({commitMessage: value})}/>
-                        <FormHelperText isHidden={false} component="div"/>
-                    </FormGroup>
-                </Form>
-            </Modal>
-        )
-    }
-
-    render() {
-        const {project} = this.props;
-        return (
-            <React.Fragment>
-                <DescriptionList isHorizontal>
-                    <DescriptionListGroup>
-                        <DescriptionListTerm>Project ID</DescriptionListTerm>
-                        <DescriptionListDescription>{project?.projectId}</DescriptionListDescription>
-                    </DescriptionListGroup>
-                    <DescriptionListGroup>
-                        <DescriptionListTerm>Name</DescriptionListTerm>
-                        <DescriptionListDescription>{project?.name}</DescriptionListDescription>
-                    </DescriptionListGroup>
-                    <DescriptionListGroup>
-                        <DescriptionListTerm>Description</DescriptionListTerm>
-                        <DescriptionListDescription>{project?.description}</DescriptionListDescription>
-                    </DescriptionListGroup>
-                    <DescriptionListGroup>
-                        <DescriptionListTerm>Updated</DescriptionListTerm>
-                        <DescriptionListDescription>
-                            {this.getLastUpdatePanel()}
-                        </DescriptionListDescription>
-                    </DescriptionListGroup>
-                    <DescriptionListGroup>
-                        <DescriptionListTerm>Commit</DescriptionListTerm>
-                        <DescriptionListDescription>
-                            {this.getCommitPanel()}
-                        </DescriptionListDescription>
-                    </DescriptionListGroup>
-                </DescriptionList>
-                {this.getCommitModal()}
-            </React.Fragment>
-        );
-    }
-}
diff --git a/karavan-app/src/main/webui/src/projects/ProjectPage.tsx b/karavan-app/src/main/webui/src/projects/ProjectPage.tsx
index e8f373db..88a28833 100644
--- a/karavan-app/src/main/webui/src/projects/ProjectPage.tsx
+++ b/karavan-app/src/main/webui/src/projects/ProjectPage.tsx
@@ -415,7 +415,6 @@ export class ProjectPage extends React.Component<Props, State> {
                 {!isBuildIn &&
                     <PageSection className="project-bottom" padding={{default: "padding"}}>
                         {tab === 'development' && project && <ProjectDevelopment project={project}
-                                                                                 needCommit={this.needCommit()}
                                                                                  config={this.props.config}/>}
                         {tab === 'development' && <ProjectFilesTable files={files}
                                                                      onOpenDeleteConfirmation={this.openDeleteConfirmation}
diff --git a/karavan-app/src/main/webui/src/projects/ProjectRunner.tsx b/karavan-app/src/main/webui/src/projects/ProjectRunner.tsx
index bb91a453..dcbd3112 100644
--- a/karavan-app/src/main/webui/src/projects/ProjectRunner.tsx
+++ b/karavan-app/src/main/webui/src/projects/ProjectRunner.tsx
@@ -25,7 +25,6 @@ import PushIcon from "@patternfly/react-icons/dist/esm/icons/code-branch-icon";
 interface Props {
     project: Project,
     config: any,
-    needCommit: boolean,
 }
 
 interface State {
@@ -71,8 +70,8 @@ export class ProjectRunner extends React.Component<Props, State> {
     }
 
     getLastUpdatePanel() {
-        const {project, needCommit} = this.props;
-        const color = needCommit ? "grey" : "green";
+        const {project} = this.props;
+        const color = true ? "grey" : "green";
         return (
             <Flex direction={{default: "row"}} justifyContent={{default: "justifyContentFlexStart"}}>
                 {project?.lastCommitTimestamp && project?.lastCommitTimestamp > 0 &&
@@ -86,8 +85,8 @@ export class ProjectRunner extends React.Component<Props, State> {
 
     getCommitPanel() {
         const {isPushing, commitMessage} = this.state;
-        const {project, needCommit} = this.props;
-        const color = needCommit ? "grey" : "green";
+        const {project} = this.props;
+        const color = true ? "grey" : "green";
         return (
             <Flex direction={{default: "row"}} justifyContent={{default: "justifyContentSpaceBetween"}}>
                 <FlexItem>
@@ -97,19 +96,7 @@ export class ProjectRunner extends React.Component<Props, State> {
                     </Tooltip>
                 </FlexItem>
                 <FlexItem>
-                    <Tooltip content="Commit and push to git" position={"bottom-end"}>
-                        <Button isLoading={isPushing ? true : undefined}
-                                isSmall
-                                variant={needCommit ? "primary" : "secondary"}
-                                className="project-button"
-                                icon={!isPushing ? <PushIcon/> : <div></div>}
-                                onClick={() => this.setState({
-                                    commitMessageIsOpen: true,
-                                    commitMessage : commitMessage === '' ? new Date().toLocaleString() : commitMessage
-                                })}>
-                            {isPushing ? "..." : "Push"}
-                        </Button>
-                    </Tooltip>
+
                 </FlexItem>
             </Flex>
         )
diff --git a/karavan-app/src/main/webui/src/projects/ProjectRunnerToolbar.tsx b/karavan-app/src/main/webui/src/projects/ProjectRunnerToolbar.tsx
new file mode 100644
index 00000000..f3850ecd
--- /dev/null
+++ b/karavan-app/src/main/webui/src/projects/ProjectRunnerToolbar.tsx
@@ -0,0 +1,82 @@
+import React, {useState} from 'react';
+import {
+    Button,
+    Tooltip,
+    TooltipPosition
+} from '@patternfly/react-core';
+import '../designer/karavan.css';
+import {Project} from "./ProjectModels";
+import RocketIcon from "@patternfly/react-icons/dist/esm/icons/rocket-icon";
+import PlayIcon from "@patternfly/react-icons/dist/esm/icons/play-icon";
+import DeleteIcon from "@patternfly/react-icons/dist/esm/icons/times-circle-icon";
+import {KaravanApi} from "../api/KaravanApi";
+import {ProjectEventBus} from "./ProjectEventBus";
+
+
+interface Props {
+    project: Project,
+    config: any,
+}
+
+export const ProjectRunnerToolbar = (props: Props) => {
+
+    const [isJbangRunning, setJbangIsRunning] = useState(false);
+    const [isRunning, setIsRunning] = useState(false);
+
+    function jbangRun () {
+        setJbangIsRunning(true);
+        KaravanApi.runProject(props.project, res => {
+            if (res.status === 200 || res.status === 201) {
+                setJbangIsRunning(false);
+                ProjectEventBus.showLog('container', res.data, props.config.environment)
+            } else {
+                // Todo notification
+                setJbangIsRunning(false);
+            }
+        });
+    }
+
+    return (
+        <React.Fragment>
+            <div className="runner-toolbar">
+                <div className="row">
+                    <Tooltip content="JBang run" position={TooltipPosition.left}>
+                        <Button isLoading={isJbangRunning ? true : undefined}
+                                isSmall
+                                variant={"primary"}
+                                className="project-button"
+                                icon={!isJbangRunning ? <RocketIcon/> : <div></div>}
+                                onClick={() => jbangRun()}>
+                            {isJbangRunning ? "..." : "Run"}
+                        </Button>
+                    </Tooltip>
+                </div>
+                <div className="row">
+                    <Tooltip content="Runtime run" position={TooltipPosition.left}>
+                        <Button isLoading={isRunning ? true : undefined}
+                                isSmall
+                                variant={"secondary"}
+                                className="project-button"
+                                icon={!isRunning ? <PlayIcon/> : <div></div>}
+                                onClick={() => {
+                                }}>
+                            {isRunning ? "..." : "Run"}
+                        </Button>
+                    </Tooltip>
+                </div>
+                <div className="row">
+                    <Tooltip content="Delete container" position={TooltipPosition.left}>
+                        <Button isSmall
+                                variant={"secondary"}
+                                className="project-button"
+                                icon={!isRunning ? <DeleteIcon/> : <div></div>}
+                                onClick={() => {
+                                }}>
+                            Delete
+                        </Button>
+                    </Tooltip>
+                </div>
+            </div>
+        </React.Fragment>
+    );
+}
diff --git a/karavan-runner/Dockerfile b/karavan-runner/Dockerfile
index 6ec1cd29..9d3febf7 100644
--- a/karavan-runner/Dockerfile
+++ b/karavan-runner/Dockerfile
@@ -1,18 +1,15 @@
 FROM jbangdev/jbang-action:0.106.1
 
 ENV CAMEL_VERSION=3.20.4
+ENV KAMELETS_DIR="/kamelets"
+RUN mkdir /kamelets
 
-# Install Git and Camel-JBang
-RUN apt-get update && apt-get install -y git 
+# Install Camel-JBang
 RUN jbang trust add -o --fresh --quiet https://github.com/apache/camel/blob/camel-$CAMEL_VERSION/dsl/camel-jbang/camel-jbang-main/dist/CamelJBang.java
 RUN jbang alias add --name camel https://github.com/apache/camel/blob/camel-$CAMEL_VERSION/dsl/camel-jbang/camel-jbang-main/dist/CamelJBang.java
 
-# Add scripts
-COPY docker-entrypoint.sh /scripts/docker-entrypoint.sh
-RUN chmod +x /scripts/docker-entrypoint.sh
-
 # Add demo routes
-COPY demo.camel.yaml /scripts/code/demo1/demo.camel.yaml
+COPY demo.camel.yaml /scripts/demo.camel.yaml
 
 WORKDIR /scripts
-ENTRYPOINT ["bash", "/scripts/docker-entrypoint.sh"]
+ENTRYPOINT jbang -Dcamel.jbang.version=$CAMEL_VERSION camel run * --console --local-kamelet-dir=$KAMELETS_DIR
\ No newline at end of file
diff --git a/karavan-runner/docker-entrypoint.sh b/karavan-runner/docker-entrypoint.sh
deleted file mode 100644
index ba0ab772..00000000
--- a/karavan-runner/docker-entrypoint.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-export CHECKOUT_DIR="/scripts/code"
-export KAMELETS_DIR="/scripts/code/kamelets"
-
-if  [[ $GIT_REPOSITORY == https* ]] ;
-then
-    replacer=https://$GIT_TOKEN@
-    prefix=https://
-    url="${GIT_REPOSITORY/$prefix/$replacer}"
-    git clone --depth 1 --branch $GIT_BRANCH $url $CHECKOUT_DIR
-else
-    git clone --depth 1 --branch $GIT_BRANCH $GIT_REPOSITORY $CHECKOUT_DIR
-fi
-
-cd $CHECKOUT_DIR/$PROJECT
-jbang -Dcamel.jbang.version=$CAMEL_VERSION camel run * --console --local-kamelet-dir=$KAMELETS_DIR
\ No newline at end of file