From dcc639e47ae6452d6ac5448e80cf83139bcd168d Mon Sep 17 00:00:00 2001 From: Ping-Lin Chang Date: Fri, 27 Oct 2023 16:49:52 +0100 Subject: [PATCH] chore(local): adopt new core launch logic --- pkg/cmd/local/deploy.go | 206 ++++++++++++++++++++------------------ pkg/cmd/local/local.go | 26 +++-- pkg/cmd/local/start.go | 38 ++++--- pkg/cmd/local/status.go | 26 +++-- pkg/cmd/local/stop.go | 38 ++++--- pkg/cmd/local/undeploy.go | 33 +++--- 6 files changed, 183 insertions(+), 184 deletions(-) diff --git a/pkg/cmd/local/deploy.go b/pkg/cmd/local/deploy.go index 66467ad..ecc8f10 100644 --- a/pkg/cmd/local/deploy.go +++ b/pkg/cmd/local/deploy.go @@ -5,6 +5,7 @@ import ( "os" "path" "path/filepath" + "strconv" "strings" "time" @@ -35,6 +36,8 @@ type DeployOptions struct { Interactive bool Force bool Upgrade bool + Latest bool + Build bool checkForUpdate func(ExecDep, string, string, string) (*releaseInfo, error) isDeployed func(ExecDep, string) error } @@ -74,8 +77,11 @@ func NewDeployCmd(f *cmdutil.Factory, runF func(*DeployOptions) error) *cobra.Co } cmd.Flags().BoolVarP(&opts.Force, "force", "f", false, "Force to deploy a new local Instill Core instance") - cmd.Flags().BoolVarP(&opts.Upgrade, "upgrade", "u", false, "Upgrade Instill Core instance to the latest version") + cmd.Flags().BoolVarP(&opts.Upgrade, "upgrade", "u", false, "Upgrade Instill Core instance to the latest release version") + cmd.Flags().BoolVarP(&opts.Latest, "latest", "l", false, "Deploy an Instill Core instance with the latest version (unstable)") + cmd.Flags().BoolVarP(&opts.Build, "build", "b", false, "Deploy an Instill Core instance and build the images at the local") cmd.MarkFlagsMutuallyExclusive("force", "upgrade") + cmd.MarkFlagsMutuallyExclusive("upgrade", "latest") return cmd } @@ -99,49 +105,82 @@ func runDeploy(opts *DeployOptions) error { } // download the latest version of the projects, if local repos are not present - for _, proj := range projs { - projDirPath := filepath.Join(LocalInstancePath, proj) - _, err = os.Stat(projDirPath) - if os.IsNotExist(err) { - if latestVersion, err := execCmd(opts.Exec, "bash", "-c", fmt.Sprintf("curl https://api.github.com/repos/instill-ai/%s/releases | jq -r 'map(select(.prerelease)) | first | .tag_name'", proj)); err == nil { - latestVersion = strings.Trim(latestVersion, "\n") + projDirPath := filepath.Join(LocalInstancePath, "core") + _, err = os.Stat(projDirPath) + if os.IsNotExist(err) { + if opts.Latest { + if out, err := execCmd(opts.Exec, "bash", "-c", + fmt.Sprintf("git clone --depth 1 https://github.com/instill-ai/core.git %s", projDirPath)); err != nil { + return fmt.Errorf("ERROR: cannot clone Instill Core repo, %w:\n%s", err, out) + } + } else { + if latestReleaseVersion, err := execCmd(opts.Exec, "bash", "-c", "curl https://api.github.com/repos/instill-ai/core/releases | jq -r 'map(select(.prerelease)) | first | .tag_name'"); err == nil { + latestReleaseVersion = strings.Trim(latestReleaseVersion, "\n") if out, err := execCmd(opts.Exec, "bash", "-c", - fmt.Sprintf("git clone --depth 1 -b %s -c advice.detachedHead=false https://github.com/instill-ai/%s.git %s", latestVersion, proj, projDirPath)); err != nil { - return fmt.Errorf("ERROR: cannot clone %s, %w:\n%s", proj, err, out) + fmt.Sprintf("git clone --depth 1 -b %s -c advice.detachedHead=false https://github.com/instill-ai/core.git %s", latestReleaseVersion, projDirPath)); err != nil { + return fmt.Errorf("ERROR: cannot clone core, %w:\n%s", err, out) } - if _, err := opts.checkForUpdate(opts.Exec, filepath.Join(config.StateDir(), fmt.Sprintf("%s.yml", proj)), fmt.Sprintf("instill-ai/%s", proj), latestVersion); err != nil { - return fmt.Errorf("ERROR: cannot check for update %s, %w:\n%s", proj, err, latestVersion) + if _, err := opts.checkForUpdate(opts.Exec, filepath.Join(config.StateDir(), "core.yml"), "instill-ai/core", latestReleaseVersion); err != nil { + return fmt.Errorf("ERROR: cannot check for the update of Instill Core, %w:\n%s", err, latestReleaseVersion) } } else { - return fmt.Errorf("ERROR: cannot find latest release version of %s, %w:\n%s", proj, err, latestVersion) + return fmt.Errorf("ERROR: cannot find latest release version of Instill Core, %w:\n%s", err, latestReleaseVersion) } } } if opts.Force { p(opts.IO, "Tear down Instill Core instance if existing...") - for _, proj := range projs { - projDirPath := filepath.Join(LocalInstancePath, proj) - _, err = os.Stat(projDirPath) - if !os.IsNotExist(err) { - if opts.OS != nil { - if err = opts.OS.Chdir(projDirPath); err != nil { - return err - } - } else { - if err = os.Chdir(projDirPath); err != nil { - return err - } + projDirPath := filepath.Join(LocalInstancePath, "core") + _, err = os.Stat(projDirPath) + if !os.IsNotExist(err) { + if opts.OS != nil { + if err = opts.OS.Chdir(projDirPath); err != nil { + return err } - if out, err := execCmd(opts.Exec, "bash", "-c", "make down"); err != nil { - return fmt.Errorf("ERROR: cannot force tearing down %s, %w:\n%s", proj, err, out) + } else { + if err = os.Chdir(projDirPath); err != nil { + return err } } + if out, err := execCmd(opts.Exec, "bash", "-c", "make down"); err != nil { + return fmt.Errorf("ERROR: cannot force tearing down Instill Core, %w:\n%s", err, out) + } } - } else if opts.Upgrade { + + } else if opts.Upgrade && !opts.Latest { hasNewVersion := false - for _, proj := range projs { - projDirPath := filepath.Join(LocalInstancePath, proj) + projDirPath := filepath.Join(LocalInstancePath, "core") + _, err = os.Stat(projDirPath) + if !os.IsNotExist(err) { + if opts.OS != nil { + if err = opts.OS.Chdir(projDirPath); err != nil { + return err + } + } else { + if err = os.Chdir(projDirPath); err != nil { + return err + } + } + if currentVersion, err := execCmd(opts.Exec, "bash", "-c", "git name-rev --tags --name-only $(git rev-parse HEAD)"); err == nil { + currentVersion = strings.Trim(currentVersion, "\n") + if currentVersion == "undefined" { + currentVersion = "latest" + } + if newRelease, err := opts.checkForUpdate(opts.Exec, filepath.Join(config.StateDir(), "core.yml"), "instill-ai/core", currentVersion); err != nil { + return fmt.Errorf("ERROR: cannot check for the update of Instill Core, %w:\n%s", err, currentVersion) + } else if newRelease != nil { + p(opts.IO, "Upgrade Instill Core to %s...", newRelease.Version) + hasNewVersion = true + } + } else { + return fmt.Errorf("ERROR: cannot find current release version of Instill Core, %w:\n%s", err, currentVersion) + } + } + + if hasNewVersion { + p(opts.IO, "Tear down Instill Core instance if existing...") + projDirPath := filepath.Join(LocalInstancePath, "core") _, err = os.Stat(projDirPath) if !os.IsNotExist(err) { if opts.OS != nil { @@ -153,59 +192,29 @@ func runDeploy(opts *DeployOptions) error { return err } } - if currentVersion, err := execCmd(opts.Exec, "bash", "-c", "git name-rev --tags --name-only $(git rev-parse HEAD)"); err == nil { - currentVersion = strings.Trim(currentVersion, "\n") - if newRelease, err := opts.checkForUpdate(opts.Exec, filepath.Join(config.StateDir(), fmt.Sprintf("%s.yml", proj)), fmt.Sprintf("instill-ai/%s", proj), currentVersion); err != nil { - return fmt.Errorf("ERROR: cannot check for update %s, %w:\n%s", proj, err, currentVersion) - } else if newRelease != nil { - p(opts.IO, "Upgrade %s to %s...", proj, newRelease.Version) - hasNewVersion = true - } - } else { - return fmt.Errorf("ERROR: cannot find current release version of %s, %w:\n%s", proj, err, currentVersion) + if out, err := execCmd(opts.Exec, "bash", "-c", "make down"); err != nil { + return fmt.Errorf("ERROR: cannot force tearing down Instill Core, %w:\n%s", err, out) } } - } - - if hasNewVersion { - p(opts.IO, "Tear down Instill Core instance if existing...") - for _, proj := range projs { - projDirPath := filepath.Join(LocalInstancePath, proj) - _, err = os.Stat(projDirPath) - if !os.IsNotExist(err) { - if opts.OS != nil { - if err = opts.OS.Chdir(projDirPath); err != nil { - return err - } - } else { - if err = os.Chdir(projDirPath); err != nil { - return err - } - } - if out, err := execCmd(opts.Exec, "bash", "-c", "make down"); err != nil { - return fmt.Errorf("ERROR: cannot force tearing down %s, %w:\n%s", proj, err, out) - } - } - if dir, err := os.ReadDir(projDirPath); err == nil { - for _, d := range dir { - if os.RemoveAll(path.Join([]string{projDirPath, d.Name()}...)); err != nil { - return fmt.Errorf("ERROR: cannot remove %s, %w", projDirPath, err) - } + if dir, err := os.ReadDir(projDirPath); err == nil { + for _, d := range dir { + if os.RemoveAll(path.Join([]string{projDirPath, d.Name()}...)); err != nil { + return fmt.Errorf("ERROR: cannot remove %s, %w", projDirPath, err) } - } else { - return fmt.Errorf("ERROR: cannot read %s, %w", projDirPath, err) } + } else { + return fmt.Errorf("ERROR: cannot read %s, %w", projDirPath, err) + } - if latestVersion, err := execCmd(opts.Exec, "bash", "-c", fmt.Sprintf("curl https://api.github.com/repos/instill-ai/%s/releases | jq -r 'map(select(.prerelease)) | first | .tag_name'", proj)); err == nil { - latestVersion = strings.Trim(latestVersion, "\n") - if out, err := execCmd(opts.Exec, "bash", "-c", - fmt.Sprintf("git clone --depth 1 -b %s -c advice.detachedHead=false https://github.com/instill-ai/%s.git %s", latestVersion, proj, projDirPath)); err != nil { - return fmt.Errorf("ERROR: cannot clone %s, %w:\n%s", proj, err, out) - } - } else { - return fmt.Errorf("ERROR: cannot find latest release version of %s, %w:\n%s", proj, err, latestVersion) + if latestVersion, err := execCmd(opts.Exec, "bash", "-c", fmt.Sprintf("curl https://api.github.com/repos/instill-ai/%s/releases | jq -r 'map(select(.prerelease)) | first | .tag_name'", "core")); err == nil { + latestVersion = strings.Trim(latestVersion, "\n") + if out, err := execCmd(opts.Exec, "bash", "-c", + fmt.Sprintf("git clone --depth 1 -b %s -c advice.detachedHead=false https://github.com/instill-ai/core.git %s", latestVersion, projDirPath)); err != nil { + return fmt.Errorf("ERROR: cannot clone Instill Core, %w:\n%s", err, out) } + } else { + return fmt.Errorf("ERROR: cannot find latest release version of Instill Core, %w:\n%s", err, latestVersion) } } else { p(opts.IO, "No upgrade available") @@ -213,37 +222,38 @@ func runDeploy(opts *DeployOptions) error { } } else { - for _, proj := range projs { - if err := opts.isDeployed(opts.Exec, proj); err == nil { - p(opts.IO, "A local Instill Core deployment detected") - return nil - } + if err := opts.isDeployed(opts.Exec, "core"); err == nil { + p(opts.IO, "A local Instill Core deployment detected") + return nil } } - p(opts.IO, "Launch Instill Core...") - for _, proj := range projs { - projDirPath := filepath.Join(LocalInstancePath, proj) - _, err = os.Stat(projDirPath) - if !os.IsNotExist(err) { - if opts.OS != nil { - err = opts.OS.Chdir(projDirPath) - } else { - err = os.Chdir(projDirPath) - } - if err != nil { - return fmt.Errorf("ERROR: cannot open the directory: %w", err) - } + _, err = os.Stat(projDirPath) + if !os.IsNotExist(err) { + if opts.OS != nil { + err = opts.OS.Chdir(projDirPath) + } else { + err = os.Chdir(projDirPath) + } + if err != nil { + return fmt.Errorf("ERROR: cannot open the directory: %w", err) } + } + if opts.Latest { + p(opts.IO, "Spin up latest Instill Core...") + if out, err := execCmd(opts.Exec, "bash", "-c", fmt.Sprintf("make latest BUILD=%s", strconv.FormatBool(opts.Build))); err != nil { + return fmt.Errorf("ERROR: Instill Core spin-up failed, %w\n%s", err, out) + } + } else { if currentVersion, err := execCmd(opts.Exec, "bash", "-c", "git name-rev --tags --name-only $(git rev-parse HEAD)"); err == nil { currentVersion = strings.Trim(currentVersion, "\n") - p(opts.IO, "Spin up %s %s...", proj, currentVersion) - if out, err := execCmd(opts.Exec, "bash", "-c", "make all"); err != nil { - return fmt.Errorf("ERROR: %s spin-up failed, %w\n%s", proj, err, out) - } + p(opts.IO, "Spin up Instill Core %s...", currentVersion) } else { - return fmt.Errorf("ERROR: cannot get current tag %s, %w:\n%s", proj, err, currentVersion) + return fmt.Errorf("ERROR: cannot get the current tag of Instill Core repo, %w:\n%s", err, currentVersion) + } + if out, err := execCmd(opts.Exec, "bash", "-c", fmt.Sprintf("make all BUILD=%s", strconv.FormatBool(opts.Build))); err != nil { + return fmt.Errorf("ERROR: Instill Core spin-up failed, %w\n%s", err, out) } } diff --git a/pkg/cmd/local/local.go b/pkg/cmd/local/local.go index 7123f58..31579fb 100644 --- a/pkg/cmd/local/local.go +++ b/pkg/cmd/local/local.go @@ -17,8 +17,6 @@ import ( "github.com/instill-ai/cli/pkg/cmdutil" ) -var projs = [3]string{"core", "vdp", "model"} - // ExecDep is an interface for executing commands type ExecDep interface { Command(name string, arg ...string) *exec.Cmd @@ -64,22 +62,22 @@ func New(f *cmdutil.Factory) *cobra.Command { // check for update if cmd.Flags().Lookup("upgrade") == nil || (cmd.Flags().Lookup("upgrade") != nil && !cmd.Flags().Lookup("upgrade").Changed) { - for _, proj := range projs { - projDirPath := filepath.Join(LocalInstancePath, proj) - _, err = os.Stat(projDirPath) - if !os.IsNotExist(err) { - if err = os.Chdir(projDirPath); err != nil { - return err - } - if currentVersion, err := execCmd(nil, "bash", "-c", "git name-rev --tags --name-only $(git rev-parse HEAD)"); err == nil { - currentVersion = strings.Trim(currentVersion, "\n") - if newRelease, err := checkForUpdate(nil, filepath.Join(config.StateDir(), fmt.Sprintf("%s.yml", proj)), fmt.Sprintf("instill-ai/%s", proj), currentVersion); err != nil { - return fmt.Errorf("ERROR: cannot check for update %s, %w:\n%s", proj, err, currentVersion) + projDirPath := filepath.Join(LocalInstancePath, "core") + _, err = os.Stat(projDirPath) + if !os.IsNotExist(err) { + if err = os.Chdir(projDirPath); err != nil { + return err + } + if currentVersion, err := execCmd(nil, "bash", "-c", "git name-rev --tags --name-only $(git rev-parse HEAD)"); err == nil { + currentVersion = strings.Trim(currentVersion, "\n") + if currentVersion != "undefined" { + if newRelease, err := checkForUpdate(nil, filepath.Join(config.StateDir(), "core.yml"), "instill-ai/core", currentVersion); err != nil { + return fmt.Errorf("ERROR: cannot check for the update Instill Core, %w:\n%s", err, currentVersion) } else if newRelease != nil { cmdFactory := factory.New(build.Version) stderr := cmdFactory.IOStreams.ErrOut fmt.Fprintf(stderr, "\n%s %s → %s\n", - ansi.Color(fmt.Sprintf("A new release of Instill %s is available:", proj), "yellow"), + ansi.Color("A new release of Instill Core is available:", "yellow"), ansi.Color(currentVersion, "cyan"), ansi.Color(newRelease.Version, "cyan")) fmt.Fprintf(stderr, "%s\n\n", diff --git a/pkg/cmd/local/start.go b/pkg/cmd/local/start.go index 0971a3b..3ee8b00 100644 --- a/pkg/cmd/local/start.go +++ b/pkg/cmd/local/start.go @@ -64,28 +64,26 @@ func runStart(opts *StartOptions) error { return nil } - for _, proj := range projs { - projDirPath := filepath.Join(LocalInstancePath, proj) - if err := isProjectDeployed(opts.Exec, proj); err == nil { - if opts.OS != nil { - err = opts.OS.Chdir(projDirPath) - } else { - err = os.Chdir(projDirPath) - } - if err != nil { - return fmt.Errorf("ERROR: cannot open the directory: %w", err) - } - p(opts.IO, fmt.Sprintf("Starting %s...", proj)) - out, err := execCmd(opts.Exec, "make", "start") - if err != nil { - return fmt.Errorf("ERROR: when starting, %w", err) - } - if err != nil { - return fmt.Errorf("ERROR: %s when starting, %w\n%s", proj, err, out) - } + projDirPath := filepath.Join(LocalInstancePath, "core") + if err := isProjectDeployed(opts.Exec, "core"); err == nil { + if opts.OS != nil { + err = opts.OS.Chdir(projDirPath) } else { - return fmt.Errorf("ERROR: %w", err) + err = os.Chdir(projDirPath) + } + if err != nil { + return fmt.Errorf("ERROR: cannot open the directory: %w", err) + } + p(opts.IO, "Starting Instill Core...") + out, err := execCmd(opts.Exec, "make", "start") + if err != nil { + return fmt.Errorf("ERROR: when starting, %w", err) + } + if err != nil { + return fmt.Errorf("ERROR: when starting Instill Core, %w\n%s", err, out) } + } else { + return fmt.Errorf("ERROR: %w", err) } p(opts.IO, "Instill Core started") diff --git a/pkg/cmd/local/status.go b/pkg/cmd/local/status.go index 86e0a15..c9f1e14 100644 --- a/pkg/cmd/local/status.go +++ b/pkg/cmd/local/status.go @@ -74,21 +74,19 @@ func runStatus(opts *StatusOptions) error { return nil } - for _, proj := range projs { - deployed := "NO" - started := "NO" - healthy := "NO" - if err := isProjectDeployed(opts.Exec, proj); err == nil { - deployed = "YES" - } - if err := isProjectStarted(opts.Exec, proj); err == nil { - started = "YES" - } - if err := isProjectHealthy(opts.Exec, proj); err == nil { - healthy = "YES" - } - fmt.Printf("%5s - Deployed: %s | Started: %s | Healthy: %s\n", proj, deployed, started, healthy) + deployed := "NO" + started := "NO" + healthy := "NO" + if err := isProjectDeployed(opts.Exec, "core"); err == nil { + deployed = "YES" + } + if err := isProjectStarted(opts.Exec, "core"); err == nil { + started = "YES" + } + if err := isProjectHealthy(opts.Exec, "core"); err == nil { + healthy = "YES" } + fmt.Printf("Instill Core - Deployed: %s | Started: %s | Healthy: %s\n", deployed, started, healthy) return nil } diff --git a/pkg/cmd/local/stop.go b/pkg/cmd/local/stop.go index 359e827..82e48d5 100644 --- a/pkg/cmd/local/stop.go +++ b/pkg/cmd/local/stop.go @@ -66,28 +66,26 @@ func runStop(opts *StopOptions) error { return nil } - for _, proj := range projs { - projDirPath := filepath.Join(LocalInstancePath, proj) - if err := isProjectDeployed(opts.Exec, proj); err == nil { - if opts.OS != nil { - err = opts.OS.Chdir(projDirPath) - } else { - err = os.Chdir(projDirPath) - } - if err != nil { - return fmt.Errorf("ERROR: cannot open the directory: %w", err) - } - p(opts.IO, fmt.Sprintf("Stopping %s...", proj)) - out, err := execCmd(opts.Exec, "make", "stop") - if err != nil { - return fmt.Errorf("ERROR: when stopping, %w", err) - } - if err != nil { - return fmt.Errorf("ERROR: %s when stopping, %w\n%s", proj, err, out) - } + projDirPath := filepath.Join(LocalInstancePath, "core") + if err := isProjectDeployed(opts.Exec, "core"); err == nil { + if opts.OS != nil { + err = opts.OS.Chdir(projDirPath) } else { - return fmt.Errorf("ERROR: %w", err) + err = os.Chdir(projDirPath) + } + if err != nil { + return fmt.Errorf("ERROR: cannot open the directory: %w", err) + } + p(opts.IO, "Stopping Instill Core...") + out, err := execCmd(opts.Exec, "make", "stop") + if err != nil { + return fmt.Errorf("ERROR: when stopping, %w", err) + } + if err != nil { + return fmt.Errorf("ERROR: when stopping Instill Core, %w\n%s", err, out) } + } else { + return fmt.Errorf("ERROR: %w", err) } p(opts.IO, "Instill Core stopped") diff --git a/pkg/cmd/local/undeploy.go b/pkg/cmd/local/undeploy.go index efbc5ac..d5df126 100644 --- a/pkg/cmd/local/undeploy.go +++ b/pkg/cmd/local/undeploy.go @@ -61,25 +61,22 @@ func NewUndeployCmd(f *cmdutil.Factory, runF func(*UndeployOptions) error) *cobr func runUndeploy(opts *UndeployOptions) error { var err error - for _, proj := range projs { - projDirPath := filepath.Join(LocalInstancePath, proj) - _, err = os.Stat(projDirPath) + projDirPath := filepath.Join(LocalInstancePath, "core") + _, err = os.Stat(projDirPath) + if !os.IsNotExist(err) { + if opts.OS != nil { + err = opts.OS.Chdir(projDirPath) + } else { + err = os.Chdir(projDirPath) + } + if err != nil { + return fmt.Errorf("ERROR: cannot open the directory: %w", err) + } + p(opts.IO, "Tearing down Instill Core...") + _, err = os.Stat(filepath.Join(projDirPath, "Makefile")) if !os.IsNotExist(err) { - if opts.OS != nil { - err = opts.OS.Chdir(projDirPath) - } else { - err = os.Chdir(projDirPath) - } - if err != nil { - return fmt.Errorf("ERROR: cannot open the directory: %w", err) - } - p(opts.IO, fmt.Sprintf("Tearing down %s...", proj)) - _, err = os.Stat(filepath.Join(projDirPath, "Makefile")) - if !os.IsNotExist(err) { - out, err := execCmd(opts.Exec, "bash", "-c", "make down") - if err != nil { - fmt.Println(fmt.Errorf("ERROR: when tearing down %s, %w\n%s, continue to tear down", proj, err, out)) - } + if out, err := execCmd(opts.Exec, "bash", "-c", "make down"); err != nil { + fmt.Println(fmt.Errorf("ERROR: when tearing down Instill Core, %w\n%s, continue to tear down", err, out)) } } }