Skip to content

Commit

Permalink
fixed wait when no pods exist, cleaned up info output
Browse files Browse the repository at this point in the history
  • Loading branch information
xadhatter committed Oct 20, 2023
1 parent e802cd3 commit b2b7289
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 71 deletions.
2 changes: 1 addition & 1 deletion cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ func addCommonBuildFlags(cmd *cobra.Command) {

func build(cmd *cobra.Command, args []string) {
r := repo.New(cfg)
r.BuildComp(args[0])
r.Build(args[0])
}
3 changes: 1 addition & 2 deletions cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var deployCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
PreRun: setup,
Run: runDeploy,
Short: "Deploy app using the version of the currently checked out Git commit",
Short: "Deploy KubeFox app using the version from the currently checked out Git commit",
Long: ``,
}

Expand Down Expand Up @@ -44,6 +44,5 @@ func runDeploy(cmd *cobra.Command, args []string) {
d := r.Deploy(name)
// Makes output less cluttered.
d.ManagedFields = nil
log.InfoNewline()
log.Marshal(d)
}
20 changes: 9 additions & 11 deletions cmd/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var publishCmd = &cobra.Command{
Args: cobra.MaximumNArgs(1),
PreRun: setup,
RunE: runPublish,
Short: "Builds, pushes, and deploys app using the version of the currently checked out Git commit",
Short: "Builds, pushes, and deploys KubeFox apps using the version of the currently checked out Git commit",
}

var (
Expand All @@ -39,20 +39,18 @@ func runPublish(cmd *cobra.Command, args []string) error {
if !cfg.Flags.SkipDeploy && len(args) == 0 {
return fmt.Errorf("accepts 1 arg(s), received 0")
}

var name string
if !cfg.Flags.SkipDeploy {
checkCommonDeployFlags(args[0])
name = args[0]
checkCommonDeployFlags(name)
}

r := repo.New(cfg)
r.Publish()

if !cfg.Flags.SkipDeploy {
d := r.Deploy(args[0])
// Makes output less cluttered.
d.ManagedFields = nil
log.InfoNewline()
log.Marshal(d)
}
d := r.Publish(name)
// Makes output less cluttered.
d.ManagedFields = nil
log.Marshal(d)

return nil
}
2 changes: 1 addition & 1 deletion cmd/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var releaseCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
PreRun: setup,
Run: release,
Short: "Release app using the version of the currently checked out Git commit",
Short: "Release app using the version from the currently checked out Git commit",
Long: `
The release command will ensure all components are deployed and then activate
their routes. This causes genesis events matching component's routes to be
Expand Down
21 changes: 10 additions & 11 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func (cfg *Config) Load() {
if errors.Is(err, fs.ErrNotExist) {
log.Info("It looks like this is the first time you are using 🦊 Fox. Welcome!")
log.InfoNewline()
log.Info("Fox needs some information from you to configure itself. The setup process only")
log.Info("🦊 Fox needs some information from you to configure itself. The setup process only")
log.Info("needs to be run once, but if you ever want change things you can use the")
log.Info("command 'fox config setup'.")
log.InfoNewline()
Expand Down Expand Up @@ -119,41 +119,40 @@ func (cfg *Config) Setup() {
log.Info("If you don't have a Kubernetes cluster you can run one locally with Kind (https://kind.sigs.k8s.io)")
log.Info("to experiment with KubeFox.")
log.InfoNewline()
log.Info("Fox needs a place to store the KubeFox Component images it will build, normally")
log.Info("this is a remote container registry. However, if you only want to use KubeFox")
log.Info("locally with Kind you can skip this step.")
log.Info("🦊 Fox needs a place to store the component images it will build, normally this is")
log.Info("a remote container registry. However, if you only want to use KubeFox locally")
log.Info("with Kind you can skip this step.")
kindOnly := utils.YesNoPrompt("Are you only using KubeFox with local Kind cluster?", false)
if kindOnly {
cfg.ContainerRegistry.Address = LocalRegistry
cfg.ContainerRegistry.Token = ""
cfg.Kind.ClusterName = utils.NamePrompt("Kind cluster name", "kind", true)
cfg.Kind.ClusterName = utils.NamePrompt("Kind cluster", "kind", true)
cfg.Kind.AlwaysLoad = true
log.InfoNewline()
cfg.done()
return
}

log.InfoNewline()
log.Info("Great! If you don't already have a container registry 🦊 Fox can help setup the")
log.Info("GitHub container registry (ghcr.io).")
useGH := utils.YesNoPrompt("Would you like to use ghcr.io?", true)
log.InfoNewline()
if useGH {
cfg.setupGitHub()

} else {
log.InfoNewline()
log.Info("No problem. 🦊 Fox just needs to know which container registry to use. Please be")
log.Info("sure you have permissions to pull and push images to the registry.")
cfg.ContainerRegistry.Address = utils.InputPrompt("Enter the container registry you'd like to use", "", true)
cfg.ContainerRegistry.Token = utils.InputPrompt("Enter the container registry access token", "", false)
}

log.InfoNewline()
cfg.done()
}

func (cfg *Config) done() {
cfg.Fresh = true
cfg.Write()

log.InfoNewline()
log.Info("Congrats, you are ready to use KubeFox!")
log.Info("Check out the quickstart for next steps (https://docs.kubefox.io/quickstart/).")
Expand All @@ -162,8 +161,7 @@ func (cfg *Config) done() {
}

func (cfg *Config) setupGitHub() {
log.InfoNewline()
log.Info("Fox needs to create two access tokens. The first is used by 🦊 Fox and is only")
log.Info("🦊 Fox needs to create two access tokens. The first is used by 🦊 Fox and is only")
log.Info("stored locally. It allows 🦊 Fox to read your GitHub user and organizations and to")
log.Info("push and pull container images to ghcr.io. This information never leaves your")
log.Info("workstation.")
Expand Down Expand Up @@ -193,6 +191,7 @@ func (cfg *Config) setupGitHub() {
cfg.GitHub.Org = *pickOrg(orgs)
}
cfg.ContainerRegistry.Address = fmt.Sprintf("ghcr.io/%s", cfg.GitHub.Org.Name)
log.InfoNewline()
}

func getToken(scopes []string) string {
Expand Down
9 changes: 5 additions & 4 deletions internal/repo/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ type DockerfileTar struct {
read int
}

func (r *repo) BuildComp(compDirName string) string {
img := r.GetContainerImage(compDirName)
func (r *repo) Build(compDirName string) string {
img := r.GetCompImageFromDir(compDirName)
compDir := filepath.Join(ComponentsDirName, compDirName)
compName := utils.Clean(compDirName)
gitCommit := r.GetCompCommit(compDirName)
Expand All @@ -48,12 +48,12 @@ func (r *repo) BuildComp(compDirName string) string {
if found, _ := r.ensureImageExists(img, false); found {
log.Info("Component image '%s' exists, skipping build.", img)
r.KindLoad(img)
log.InfoNewline()
return img
}
}

log.Info("Building component image '%s'.", img)

dfPath := filepath.Join(r.cfg.Flags.RepoPath, ComponentsDirName, compDirName, "Dockerfile")
df, err := os.ReadFile(dfPath)
if err != nil {
Expand Down Expand Up @@ -106,8 +106,9 @@ func (r *repo) BuildComp(compDirName string) string {
}
logResp(pushResp, true)
}
r.KindLoad(img)

r.KindLoad(img)
log.InfoNewline()
return img
}

Expand Down
43 changes: 25 additions & 18 deletions internal/repo/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func (r *repo) prepareDeployment() (*v1alpha1.Platform, *v1alpha1.DeploymentSpec
if apierrors.IsNotFound(err) {
platform = r.pickPlatform()
} else {
log.Fatal("Unable to get Platform: %v", err)
log.Fatal("Unable to get KubeFox platform: %v", err)
}
}
}
Expand All @@ -111,19 +111,22 @@ func (r *repo) prepareDeployment() (*v1alpha1.Platform, *v1alpha1.DeploymentSpec

allFound := true
for n, c := range spec.Components {
img := fmt.Sprintf("%s/%s:%s", spec.App.ContainerRegistry, n, c.Commit)
found, _ := r.ensureImageExists(img, false)
if !found {
img := r.GetCompImage(n, c.Commit)
if found, _ := r.ensureImageExists(img, false); found {
log.Info("Component image '%s' exists.", img)
} else {
log.Warn("Component image '%s' does not exist.", img)
allFound = false
break
}
}
log.InfoNewline()

if !allFound {
log.Info("There are one or more missing component images. 🦊 Fox will need to build and")
log.Info("push them to the container registry before continuing with the operation.")
if utils.YesNoPrompt("Missing component images, would you like to publish them?", true) {
r.Publish()
log.InfoNewline()
r.Publish("")
} else {
log.Fatal("There are one or more missing component images.")
}
Expand Down Expand Up @@ -181,14 +184,14 @@ func (r *repo) pickPlatform() *v1alpha1.Platform {
if !r.cfg.Flags.Info {
context := r.k8s.KubeConfig.CurrentContext
cluster := r.k8s.KubeConfig.Contexts[context].Cluster
log.Warn("No Platforms found on the current cluster '%s'.", cluster)
log.Warn("No KubeFox platforms found on the current cluster '%s'.", cluster)
}
log.Info("You need to have a KubeFox Platform instance running to deploy your components.")
log.Info("You need to have a KubeFox platform instance running to deploy your components.")
log.Info("Don't worry, 🦊 Fox can create one for you.")
if utils.YesNoPrompt("Would you like to create a Platform?", true) {
if utils.YesNoPrompt("Would you like to create a KubeFox platform?", true) {
return r.createPlatform()
} else {
log.Fatal("Error you must create a Platform before deploying Components.")
log.Fatal("Error you must create a KubeFox platform before deploying components.")
}
case 1:
return &pList[0]
Expand All @@ -199,7 +202,7 @@ func (r *repo) pickPlatform() *v1alpha1.Platform {
}

var input string
log.Printf("Select the KubeFox Platform to use: ")
log.Printf("Select the KubeFox platform to use: ")
fmt.Scanln(&input)
i, err := strconv.Atoi(input)
if err != nil {
Expand All @@ -212,20 +215,22 @@ func (r *repo) pickPlatform() *v1alpha1.Platform {

p := &pList[i]
if len(pList) > 1 {
if utils.YesNoPrompt("Remember selected Platform?", true) {
if utils.YesNoPrompt("Remember selected KubeFox platform?", true) {
r.cfg.KubeFox.Namespace = p.Namespace
r.cfg.KubeFox.Platform = p.Name
r.cfg.Write()
}
}
log.InfoNewline()

return p
}

func (r *repo) createPlatform() *v1alpha1.Platform {
name := utils.NamePrompt("Platform", "", true)
namespace := utils.InputPrompt("Enter the Kubernetes namespace of the Platform",
name := utils.NamePrompt("KubeFox platform", "", true)
namespace := utils.InputPrompt("Enter the Kubernetes namespace of the KubeFox platform",
fmt.Sprintf("kubefox-%s", name), true)
log.InfoNewline()

ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
Expand Down Expand Up @@ -268,7 +273,7 @@ func (r *repo) waitForReady(p *v1alpha1.Platform, spec *v1alpha1.DeploymentSpec)
ctx, cancel := context.WithTimeout(context.Background(), r.cfg.Flags.WaitTime)
defer cancel()

log.Info("Waiting for Platform '%s' to be ready.", p.Name)
log.Info("Waiting for KubeFox platform '%s' to be ready.", p.Name)
if err := r.checkAllPodsRdy(ctx, p, "nats", ""); err != nil {
log.Fatal("Error while waiting: %v", err)
}
Expand All @@ -277,15 +282,17 @@ func (r *repo) waitForReady(p *v1alpha1.Platform, spec *v1alpha1.DeploymentSpec)
}

for n, c := range spec.Components {
log.Info("Waiting for Component '%s' to be ready.", n)
log.Info("Waiting for component '%s' to be ready.", n)
if err := r.checkAllPodsRdy(ctx, p, n, c.Commit); err != nil {
log.Fatal("Error while waiting: %v", err)
}
}
log.InfoNewline()
}

func (r *repo) checkAllPodsRdy(ctx context.Context, p *v1alpha1.Platform, comp, commit string) error {
log.Verbose("Waiting for Component '%s' with commit '%s' to be ready.", comp, commit)
log.Verbose("Waiting for component '%s' with commit '%s' to be ready.", comp, commit)

hasLabels := client.MatchingLabels{
kubefox.LabelK8sComponent: comp,
kubefox.LabelK8sPlatform: p.Name,
Expand All @@ -299,7 +306,7 @@ func (r *repo) checkAllPodsRdy(ctx context.Context, p *v1alpha1.Platform, comp,
return fmt.Errorf("unable to list pods: %w", err)
}

ready := true
ready := len(l.Items) > 0
for _, p := range l.Items {
for _, c := range p.Status.ContainerStatuses {
if !c.Ready {
Expand Down
37 changes: 18 additions & 19 deletions internal/repo/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,38 +26,36 @@ func Init(cfg *config.Config) {

app, err := ReadApp(repoPath)
if err != nil && !errors.Is(err, fs.ErrNotExist) {
log.Error("An app definition already exists but appears to be invalid: %v.", err)
if !utils.YesNoPrompt("Would you like to reinitialize the repo?", true) {
log.Error("An KubeFox app definition already exists but appears to be invalid: %v.", err)
if !utils.YesNoPrompt("Would you like to reinitialize the app?", true) {
return
}
} else if !errors.Is(err, fs.ErrNotExist) {
log.VerboseMarshal(app, "App definition:")
log.Info("A valid app definition already exists.")
log.Info("A valid KubeFox app definition already exists.")
initGit(repoPath, app, cfg)
return
}

app = &App{}
log.Info("Let's initialize a KubeFox repo!")

log.Info("Let's initialize a KubeFox app!")
log.InfoNewline()
log.Info("To get things started quickly 🦊 Fox can create a hello-world app which includes")
log.Info("two components and example environments for testing.")
if utils.YesNoPrompt("Would you like to initialize the hello-world app?", false) {
log.Info("To get things started quickly 🦊 Fox can create a 'hello-world' KubeFox app which")
log.Info("includes two components and example environments for testing.")
if utils.YesNoPrompt("Would you like to initialize the 'hello-world' KubeFox app?", false) {
initDir(efs.HelloWorldPath, repoPath)
initGit(repoPath, app, cfg)
return
}

log.InfoNewline()
log.Info("Fox needs to create an app definition for the repo. The definition is stored in")
log.Info("the 'app.yaml' file in the root of the repo. The first thing it needs is a name")
log.Info("for the app. The name is used as part of Kubernetes resource names so it must")
log.Info("contain only lowercase alpha-numeric characters and dashes. But don't worry")
log.Info("you can enter a more human friendly title and description.")
app.Name = utils.NamePrompt("app", utils.Clean(repoPath), true)
app.Title = utils.InputPrompt("Enter the app's title", "", false)
app.Description = utils.InputPrompt("Enter the app's description", "", false)
log.Info("🦊 Fox needs to create an KubeFox app definition. The definition is stored in the")
log.Info("'app.yaml' file in the root of the repo. The first thing it needs is a name for")
log.Info("the app. The name is used as part of Kubernetes resource names so it must")
log.Info("contain only lowercase alpha-numeric characters and dashes. But don't worry you")
log.Info("can enter a more human friendly title and description.")
app.Name = utils.NamePrompt("KubeFox app", utils.Clean(repoPath), true)
app.Title = utils.InputPrompt("Enter the KubeFox app's title", "", false)
app.Description = utils.InputPrompt("Enter the KubeFox app's description", "", false)

WriteApp(repoPath, app)
utils.EnsureDir(filepath.Join(repoPath, ComponentsDirName))
Expand Down Expand Up @@ -88,7 +86,8 @@ func initGit(repoPath string, app *App, cfg *config.Config) {
}

log.InfoNewline()
log.Info("KubeFox repo initialization complete!")
log.Info("KubeFox app initialization complete!")
log.InfoNewline()
}

func initDir(in, out string) {
Expand All @@ -98,7 +97,7 @@ func initDir(in, out string) {
fs.WalkDir(efs.EFS, in,
func(efsPath string, d fs.DirEntry, err error) error {
if err != nil {
log.Fatal("Error initializing repo: %v", err)
log.Fatal("Error initializing app: %v", err)
}
if d.IsDir() {
return nil
Expand Down
Loading

0 comments on commit b2b7289

Please sign in to comment.