فهرست منبع

merge docker build context fix

Alexander Belanger 4 سال پیش
والد
کامیت
527dc6917f

+ 4 - 1
Makefile

@@ -11,4 +11,7 @@ setup-env-files:
 	bash ./scripts/dev-environment/CreateDefaultEnvFiles.sh
 	bash ./scripts/dev-environment/CreateDefaultEnvFiles.sh
 
 
 build-cli: 
 build-cli: 
-	go build -ldflags="-w -s -X 'github.com/porter-dev/porter/cli/cmd.Version=${VERSION}'" -a -tags cli -o $(BINDIR)/porter ./cli
+	go build -ldflags="-w -s -X 'github.com/porter-dev/porter/cli/cmd.Version=${VERSION}'" -a -tags cli -o $(BINDIR)/porter ./cli
+
+build-cli-dev:
+	go build -tags cli -o $(BINDIR)/porter ./cli

+ 1 - 1
cli/cmd/create.go

@@ -93,7 +93,7 @@ func init() {
 		&localPath,
 		&localPath,
 		"path",
 		"path",
 		"p",
 		"p",
-		".",
+		"",
 		"if local build, the path to the build directory",
 		"if local build, the path to the build directory",
 	)
 	)
 
 

+ 1 - 1
cli/cmd/deploy.go

@@ -235,7 +235,7 @@ func init() {
 		&localPath,
 		&localPath,
 		"path",
 		"path",
 		"p",
 		"p",
-		".",
+		"",
 		"If local build, the path to the build directory. If remote build, the relative path from the repository root to the build directory.",
 		"If local build, the path to the build directory. If remote build, the relative path from the repository root to the build directory.",
 	)
 	)
 
 

+ 1 - 1
cli/cmd/deploy/create.go

@@ -281,7 +281,7 @@ func (c *CreateAgent) CreateFromDocker(
 	}
 	}
 
 
 	if opts.Method == DeployBuildTypeDocker {
 	if opts.Method == DeployBuildTypeDocker {
-		err = buildAgent.BuildDocker(agent, opts.LocalPath, ".", opts.LocalDockerfile, "latest")
+		err = buildAgent.BuildDocker(agent, opts.LocalPath, opts.LocalPath, opts.LocalDockerfile, "latest")
 	} else {
 	} else {
 		err = buildAgent.BuildPack(agent, opts.LocalPath, "latest")
 		err = buildAgent.BuildPack(agent, opts.LocalPath, "latest")
 	}
 	}

+ 1 - 0
cli/cmd/deploy/deploy.go

@@ -132,6 +132,7 @@ func NewDeployAgent(client *client.Client, app string, opts *DeployOpts) (*Deplo
 		deployAgent.dockerfilePath = deployAgent.opts.LocalDockerfile
 		deployAgent.dockerfilePath = deployAgent.opts.LocalDockerfile
 	} else {
 	} else {
 		deployAgent.imageRepo = release.GitActionConfig.ImageRepoURI
 		deployAgent.imageRepo = release.GitActionConfig.ImageRepoURI
+		deployAgent.opts.LocalPath = release.GitActionConfig.FolderPath
 	}
 	}
 
 
 	deployAgent.tag = opts.OverrideTag
 	deployAgent.tag = opts.OverrideTag

+ 15 - 6
cli/cmd/pack/pack.go

@@ -3,6 +3,7 @@ package pack
 import (
 import (
 	"context"
 	"context"
 	"fmt"
 	"fmt"
+	"path/filepath"
 
 
 	"github.com/buildpacks/pack"
 	"github.com/buildpacks/pack"
 	"github.com/porter-dev/porter/cli/cmd/docker"
 	"github.com/porter-dev/porter/cli/cmd/docker"
@@ -16,16 +17,24 @@ func (a *Agent) Build(opts *docker.BuildOpts) error {
 
 
 	//initialize a pack client
 	//initialize a pack client
 	client, err := pack.NewClient()
 	client, err := pack.NewClient()
+
+	if err != nil {
+		return err
+	}
+
+	absPath, err := filepath.Abs(opts.BuildContext)
+
 	if err != nil {
 	if err != nil {
-		panic(err)
+		return err
 	}
 	}
 
 
 	buildOpts := pack.BuildOptions{
 	buildOpts := pack.BuildOptions{
-		Image:        fmt.Sprintf("%s:%s", opts.ImageRepo, opts.Tag),
-		Builder:      "heroku/buildpacks:18",
-		AppPath:      opts.BuildContext,
-		TrustBuilder: true,
-		Env:          opts.Env,
+		RelativeBaseDir: filepath.Dir(absPath),
+		Image:           fmt.Sprintf("%s:%s", opts.ImageRepo, opts.Tag),
+		Builder:         "heroku/buildpacks:18",
+		AppPath:         opts.BuildContext,
+		TrustBuilder:    true,
+		Env:             opts.Env,
 	}
 	}
 
 
 	return client.Build(context, buildOpts)
 	return client.Build(context, buildOpts)

+ 17 - 10
dashboard/src/components/porter-form/field-components/KeyValueArray.tsx

@@ -12,6 +12,7 @@ import Modal from "../../../main/home/modals/Modal";
 import LoadEnvGroupModal from "../../../main/home/modals/LoadEnvGroupModal";
 import LoadEnvGroupModal from "../../../main/home/modals/LoadEnvGroupModal";
 import EnvEditorModal from "../../../main/home/modals/EnvEditorModal";
 import EnvEditorModal from "../../../main/home/modals/EnvEditorModal";
 import { hasSetValue } from "../utils";
 import { hasSetValue } from "../utils";
+import _ from "lodash";
 
 
 interface Props extends KeyValueArrayField {
 interface Props extends KeyValueArrayField {
   id: string;
   id: string;
@@ -166,17 +167,23 @@ const KeyValueArray: React.FC<Props> = (props) => {
             }
             }
             setValues={(values) => {
             setValues={(values) => {
               setState((prev) => {
               setState((prev) => {
+                // Transform array to object similar on what we receive from setValues
+                const prevValues = prev.values.reduce((acc, currentValue) => {
+                  acc[currentValue.key] = currentValue.value;
+                  return acc;
+                }, {} as Record<string, string>)
+
+                // Deconstruct the two records/objects inside one to merge their values (this will override the old duped vars too)
+                // and convert the new object back to an array usable for the component
+                const newValues = Object.entries({...prevValues, ...values})?.map(([k, v]) => {
+                  return {
+                    key: k,
+                    value: v,
+                  };
+                });
+
                 return {
                 return {
-                  // might be broken
-                  values: [
-                    ...prev.values,
-                    ...Object.entries(values)?.map(([k, v]) => {
-                      return {
-                        key: k,
-                        value: v,
-                      };
-                    }),
-                  ],
+                  values: [...newValues]
                 };
                 };
               });
               });
             }}
             }}

+ 14 - 31
dashboard/src/components/repo-selector/ActionConfEditor.tsx

@@ -67,44 +67,26 @@ const ActionConfEditor: React.FC<Props> = (props) => {
         </BackButton>
         </BackButton>
       </>
       </>
     );
     );
-  } else if (!props.dockerfilePath && !props.folderPath) {
-    return (
-      <>
-        <ContentsList
-          actionConfig={actionConfig}
-          branch={branch}
-          setActionConfig={setActionConfig}
-          setDockerfilePath={(x: string) => props.setDockerfilePath(x)}
-          setProcfilePath={(x: string) => props.setProcfilePath(x)}
-          setFolderPath={(x: string) => props.setFolderPath(x)}
-        />
-        <Br />
-        <BackButton
-          width="145px"
-          onClick={() => {
-            setBranch("");
-          }}
-        >
-          <i className="material-icons">keyboard_backspace</i>
-          Select Branch
-        </BackButton>
-      </>
-    );
-  }
-
-  if (
-    props.procfilePath &&
-    props.folderPath &&
-    !props.dockerfilePath &&
-    !props.procfileProcess
+  } else if (
+    // select dockerfile or buildpack build context
+    (!props.dockerfilePath && !props.folderPath) ||
+    // select procfile process
+    (props.procfilePath &&
+      props.folderPath &&
+      !props.dockerfilePath &&
+      !props.procfileProcess) ||
+    // select docker build context
+    (props.dockerfilePath && !props.folderPath)
   ) {
   ) {
     return (
     return (
       <>
       <>
         <ContentsList
         <ContentsList
           actionConfig={actionConfig}
           actionConfig={actionConfig}
           branch={branch}
           branch={branch}
-          setActionConfig={setActionConfig}
+          dockerfilePath={props.dockerfilePath}
           procfilePath={props.procfilePath}
           procfilePath={props.procfilePath}
+          folderPath={props.folderPath}
+          setActionConfig={setActionConfig}
           setDockerfilePath={(x: string) => props.setDockerfilePath(x)}
           setDockerfilePath={(x: string) => props.setDockerfilePath(x)}
           setProcfilePath={(x: string) => props.setProcfilePath(x)}
           setProcfilePath={(x: string) => props.setProcfilePath(x)}
           setProcfileProcess={(x: string) => props.setProcfileProcess(x)}
           setProcfileProcess={(x: string) => props.setProcfileProcess(x)}
@@ -115,6 +97,7 @@ const ActionConfEditor: React.FC<Props> = (props) => {
           width="145px"
           width="145px"
           onClick={() => {
           onClick={() => {
             setBranch("");
             setBranch("");
+            props.setDockerfilePath("");
           }}
           }}
         >
         >
           <i className="material-icons">keyboard_backspace</i>
           <i className="material-icons">keyboard_backspace</i>

+ 12 - 9
dashboard/src/components/repo-selector/ActionDetails.tsx

@@ -124,7 +124,7 @@ export default class ActionDetails extends Component<PropsType, StateType> {
           width="100%"
           width="100%"
           value={this.props.branch}
           value={this.props.branch}
         />
         />
-        {this.props.dockerfilePath ? (
+        {this.props.dockerfilePath && (
           <InputRow
           <InputRow
             disabled={true}
             disabled={true}
             label="Dockerfile Path"
             label="Dockerfile Path"
@@ -132,15 +132,18 @@ export default class ActionDetails extends Component<PropsType, StateType> {
             width="100%"
             width="100%"
             value={this.props.dockerfilePath}
             value={this.props.dockerfilePath}
           />
           />
-        ) : (
-          <InputRow
-            disabled={true}
-            label="Folder Path"
-            type="text"
-            width="100%"
-            value={this.props.folderPath}
-          />
         )}
         )}
+        <InputRow
+          disabled={true}
+          label={
+            this.props.dockerfilePath
+              ? "Docker Build Context"
+              : "Application Folder"
+          }
+          type="text"
+          width="100%"
+          value={this.props.folderPath}
+        />
         {this.renderRegistrySection()}
         {this.renderRegistrySection()}
         <Br />
         <Br />
 
 

+ 61 - 4
dashboard/src/components/repo-selector/ContentsList.tsx

@@ -19,6 +19,8 @@ interface AutoBuildpack {
 type PropsType = {
 type PropsType = {
   actionConfig: ActionConfigType | null;
   actionConfig: ActionConfigType | null;
   branch: string;
   branch: string;
+  dockerfilePath?: string;
+  folderPath: string;
   procfilePath?: string;
   procfilePath?: string;
   setActionConfig: (x: ActionConfigType) => void;
   setActionConfig: (x: ActionConfigType) => void;
   setProcfileProcess?: (x: string) => void;
   setProcfileProcess?: (x: string) => void;
@@ -35,6 +37,7 @@ type StateType = {
   dockerfiles: string[];
   dockerfiles: string[];
   processes: Record<string, string>;
   processes: Record<string, string>;
   autoBuildpack: AutoBuildpack;
   autoBuildpack: AutoBuildpack;
+  showingBuildContextPrompt: boolean;
 };
 };
 
 
 export default class ContentsList extends Component<PropsType, StateType> {
 export default class ContentsList extends Component<PropsType, StateType> {
@@ -49,6 +52,7 @@ export default class ContentsList extends Component<PropsType, StateType> {
       valid: false,
       valid: false,
       name: "",
       name: "",
     },
     },
+    showingBuildContextPrompt: true,
   };
   };
 
 
   componentDidMount() {
   componentDidMount() {
@@ -183,7 +187,7 @@ export default class ContentsList extends Component<PropsType, StateType> {
         );
         );
       }
       }
 
 
-      if (fileName.includes("Dockerfile")) {
+      if (fileName.includes("Dockerfile") && !this.props.dockerfilePath) {
         return (
         return (
           <FileItem
           <FileItem
             key={i}
             key={i}
@@ -227,12 +231,20 @@ export default class ContentsList extends Component<PropsType, StateType> {
     return (
     return (
       <FileItem lastItem={false}>
       <FileItem lastItem={false}>
         <img src={info} />
         <img src={info} />
-        Select Application Folder
+        Select{" "}
+        {this.props.dockerfilePath
+          ? "Docker Build Context"
+          : "Application Folder"}
       </FileItem>
       </FileItem>
     );
     );
   };
   };
 
 
   handleContinue = () => {
   handleContinue = () => {
+    if (this.props.dockerfilePath) {
+      this.props.setFolderPath(this.state.currentDir || "./");
+      return;
+    }
+
     let dockerfiles = [] as string[];
     let dockerfiles = [] as string[];
     this.state.contents.forEach((item: FileType, i: number) => {
     this.state.contents.forEach((item: FileType, i: number) => {
       let splits = item.path.split("/");
       let splits = item.path.split("/");
@@ -318,7 +330,7 @@ export default class ContentsList extends Component<PropsType, StateType> {
         </Overlay>
         </Overlay>
       );
       );
     }
     }
-    if (this.state.dockerfiles.length > 0) {
+    if (this.state.dockerfiles.length > 0 && !this.props.dockerfilePath) {
       return (
       return (
         <Overlay>
         <Overlay>
           <BgOverlay onClick={() => this.setState({ dockerfiles: [] })} />
           <BgOverlay onClick={() => this.setState({ dockerfiles: [] })} />
@@ -363,6 +375,45 @@ export default class ContentsList extends Component<PropsType, StateType> {
         </Overlay>
         </Overlay>
       );
       );
     }
     }
+    if (
+      this.props.dockerfilePath &&
+      !this.props.folderPath &&
+      this.state.showingBuildContextPrompt
+    ) {
+      return (
+        <Overlay>
+          <BgOverlay onClick={() => this.props.setDockerfilePath("")} />
+          <CloseButton
+            onClick={() =>
+              this.props.setFolderPath(this.state.currentDir || "./")
+            }
+          >
+            <CloseButtonImg src={close} />
+          </CloseButton>
+          <Label>
+            Would you like to set the Docker build context to a different
+            directory?
+          </Label>
+          <MultiSelectRow>
+            <ConfirmButton
+              onClick={() => {
+                this.setState({ showingBuildContextPrompt: false });
+                this.setSubdirectory("");
+              }}
+            >
+              Yes
+            </ConfirmButton>
+            <ConfirmButton
+              onClick={() =>
+                this.props.setFolderPath(this.state.currentDir || "./")
+              }
+            >
+              No
+            </ConfirmButton>
+          </MultiSelectRow>
+        </Overlay>
+      );
+    }
   };
   };
 
 
   render() {
   render() {
@@ -476,12 +527,18 @@ const Indicator = styled.div<{ selected: boolean }>`
 `;
 `;
 
 
 const Label = styled.div`
 const Label = styled.div`
-  max-width: 420px;
+  max-width: 500px;
   line-height: 1.5em;
   line-height: 1.5em;
   text-align: center;
   text-align: center;
   font-size: 14px;
   font-size: 14px;
 `;
 `;
 
 
+const MultiSelectRow = styled.div`
+  display: flex;
+  min-width: 150px;
+  justify-content: space-between;
+`;
+
 const DockerfileList = styled.div`
 const DockerfileList = styled.div`
   border-radius: 3px;
   border-radius: 3px;
   margin-top: 20px;
   margin-top: 20px;

+ 14 - 1
dashboard/src/main/home/cluster-dashboard/expanded-chart/SettingsSection.tsx

@@ -287,6 +287,19 @@ const SettingsSection: React.FC<PropsType> = ({
     return false;
     return false;
   };
   };
 
 
+  const canBeCloned = () => {
+    if(chartWasDeployedWithGithub()) {
+      return false;
+    }
+
+    // If its not web worker or job it means is an addon, and for now it's not supported
+    if (!["web", "worker", "job"].includes(currentChart?.chart?.metadata?.name)) {
+      return false
+    }
+
+    return true
+  }
+
   return (
   return (
     <Wrapper>
     <Wrapper>
       {!loadingWebhookToken ? (
       {!loadingWebhookToken ? (
@@ -294,7 +307,7 @@ const SettingsSection: React.FC<PropsType> = ({
           {renderWebhookSection()}
           {renderWebhookSection()}
           <NotificationSettingsSection currentChart={currentChart} />
           <NotificationSettingsSection currentChart={currentChart} />
           {/* Prevent the clone button to be rendered in github deployed charts */}
           {/* Prevent the clone button to be rendered in github deployed charts */}
-          {!chartWasDeployedWithGithub() && (
+          {canBeCloned() && (
             <>
             <>
               <Heading>Clone deployment</Heading>
               <Heading>Clone deployment</Heading>
               <Helper>
               <Helper>

+ 8 - 0
dashboard/src/main/home/launch/Launch.tsx

@@ -125,6 +125,14 @@ class Templates extends Component<PropsType, StateType> {
           this.props.history.push("/dashboard");
           this.props.history.push("/dashboard");
           return;
           return;
         }
         }
+        // If its not web worker or job it means is an addon, and for now it's not supported
+        if (!["web", "worker", "job"].includes(release?.chart?.metadata?.name)) {
+          this.context.setCurrentError(
+            "Addons don't support cloning yet!"
+          );
+          this.props.history.push("/dashboard");
+          return;
+        }
       }
       }
 
 
       this.setState(
       this.setState(

+ 1 - 1
dashboard/src/main/home/launch/launch-flow/LaunchFlow.tsx

@@ -335,7 +335,7 @@ const LaunchFlow: React.FC<PropsType> = (props) => {
       );
       );
     }
     }
 
 
-    if (!templateName && !props.isCloning) {
+    if (!templateName && !props.isCloning && currentTab === "porter") {
       const newTemplateName = generateRandomName();
       const newTemplateName = generateRandomName();
       setTemplateName(newTemplateName);
       setTemplateName(newTemplateName);
     }
     }

+ 9 - 1
dashboard/src/main/home/launch/launch-flow/SourcePage.tsx

@@ -147,7 +147,15 @@ class SourcePage extends Component<PropsType, StateType> {
     } = this.props;
     } = this.props;
     return (
     return (
       <StyledSourceBox>
       <StyledSourceBox>
-        <CloseButton onClick={() => setSourceType("")}>
+        <CloseButton
+          onClick={() => {
+            setSourceType("");
+            setDockerfilePath("");
+            setFolderPath("");
+            setProcfilePath("");
+            setProcfileProcess("");
+          }}
+        >
           <CloseButtonImg src={close} />
           <CloseButtonImg src={close} />
         </CloseButton>
         </CloseButton>
         <Subtitle>
         <Subtitle>