func addServiceAccount(c *k8sclient.Client, f *cmdutil.Factory, name string) (Result, error) { ns, _, e := f.DefaultNamespace() if e != nil { util.Fatal("No default namespace") return Failure, e } sas := c.ServiceAccounts(ns) _, err := sas.Get(name) if err != nil { sa := kapi.ServiceAccount{ ObjectMeta: kapi.ObjectMeta{ Name: name, Labels: map[string]string{ "provider": "fabric8.io", }, }, } _, err = sas.Create(&sa) } r := Success if err != nil { r = Failure } return r, err }
func installTemplates(kc *k8sclient.Client, c *oclient.Client, fac *cmdutil.Factory, v string, templateUrl string, dockerRegistry string, arch string, domain string) error { ns, _, err := fac.DefaultNamespace() if err != nil { util.Fatal("No default namespace") return err } templates := c.Templates(ns) uri := fmt.Sprintf(templateUrl, v) util.Infof("Downloading apps from: %v\n", uri) resp, err := http.Get(uri) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) } defer resp.Body.Close() tmpFileName := path.Join(os.TempDir(), "fabric8-template-distros.tar.gz") t, err := os.OpenFile(tmpFileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777) if err != nil { return err } defer t.Close() _, err = io.Copy(t, resp.Body) if err != nil { return err } r, err := zip.OpenReader(tmpFileName) if err != nil { return err } defer r.Close() typeOfMaster := util.TypeOfMaster(kc) for _, f := range r.File { mode := f.FileHeader.Mode() if mode.IsDir() { continue } rc, err := f.Open() if err != nil { return err } defer rc.Close() jsonData, err := ioutil.ReadAll(rc) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) } jsonData, err = adaptFabric8ImagesInResourceDescriptor(jsonData, dockerRegistry, arch) if err != nil { util.Fatalf("Cannot append docker registry: %v", err) } jsonData = replaceDomain(jsonData, domain, ns, typeOfMaster) var v1tmpl tapiv1.Template lowerName := strings.ToLower(f.Name) // if the folder starts with kubernetes/ or openshift/ then lets filter based on the cluster: if strings.HasPrefix(lowerName, "kubernetes/") && typeOfMaster != util.Kubernetes { //util.Info("Ignoring as on openshift!") continue } if strings.HasPrefix(lowerName, "openshift/") && typeOfMaster == util.Kubernetes { //util.Info("Ignoring as on kubernetes!") continue } configMapKeySuffix := ".json" if strings.HasSuffix(lowerName, ".yml") || strings.HasSuffix(lowerName, ".yaml") { configMapKeySuffix = ".yml" err = yaml.Unmarshal(jsonData, &v1tmpl) } else if strings.HasSuffix(lowerName, ".json") { err = json.Unmarshal(jsonData, &v1tmpl) } else { continue } if err != nil { util.Fatalf("Cannot unmarshall the fabric8 template %s to deploy: %v", f.Name, err) } util.Infof("Loading template %s\n", f.Name) var tmpl tapi.Template err = api.Scheme.Convert(&v1tmpl, &tmpl) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) return err } name := tmpl.ObjectMeta.Name template := true if len(name) <= 0 { template = false name = f.Name idx := strings.LastIndex(name, "/") if idx > 0 { name = name[idx+1:] } idx = strings.Index(name, ".") if idx > 0 { name = name[0:idx] } } if typeOfMaster == util.Kubernetes { appName := name name = "catalog-" + appName // lets install ConfigMaps for the templates // TODO should the name have a prefix? configmap := api.ConfigMap{ ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, Labels: map[string]string{ "name": appName, "provider": "fabric8.io", "kind": "catalog", }, }, Data: map[string]string{ name + configMapKeySuffix: string(jsonData), }, } configmaps := kc.ConfigMaps(ns) _, err = configmaps.Get(name) if err == nil { err = configmaps.Delete(name) if err != nil { util.Errorf("Could not delete configmap %s due to: %v\n", name, err) } } _, err = configmaps.Create(&configmap) if err != nil { util.Fatalf("Failed to create configmap %v", err) return err } } else { if !template { templateName := name var v1List v1.List if configMapKeySuffix == ".json" { err = json.Unmarshal(jsonData, &v1List) } else { err = yaml.Unmarshal(jsonData, &v1List) } if err != nil { util.Fatalf("Cannot unmarshal List %s to deploy. error: %v\ntemplate: %s", templateName, err, string(jsonData)) } if len(v1List.Items) == 0 { // lets check if its an RC / ReplicaSet or something _, groupVersionKind, err := api.Codecs.UniversalDeserializer().Decode(jsonData, nil, nil) if err != nil { printResult(templateName, Failure, err) } else { kind := groupVersionKind.Kind util.Infof("Processing resource of kind: %s version: %s\n", kind, groupVersionKind.Version) if len(kind) <= 0 { printResult(templateName, Failure, fmt.Errorf("Could not find kind from json %s", string(jsonData))) } else { util.Warnf("Cannot yet process kind %s, kind for %s\n", kind, templateName) continue } } } else { var kubeList api.List err = api.Scheme.Convert(&v1List, &kubeList) if err != nil { util.Fatalf("Cannot convert %s List to deploy: %v", templateName, err) } tmpl = tapi.Template{ ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, Labels: map[string]string{ "name": name, "provider": "fabric8.io", }, }, Objects: kubeList.Items, } } } // remove newlines from description to avoid breaking `oc get template` description := tmpl.ObjectMeta.Annotations["description"] if len(description) > 0 { tmpl.ObjectMeta.Annotations["description"] = strings.Replace(description, "\n", " ", -1) } // lets install the OpenShift templates _, err = templates.Get(name) if err == nil { err = templates.Delete(name) if err != nil { util.Errorf("Could not delete template %s due to: %v\n", name, err) } } _, err = templates.Create(&tmpl) if err != nil { util.Warnf("Failed to create template %v", err) return err } } } return nil }
func NewCmdCopyEndpoints(f *cmdutil.Factory) *cobra.Command { cmd := &cobra.Command{ Use: "copy-endpoints", Short: "Copies endpoints from the current namespace to a target namespace", Long: `Copies endpoints from the current namespace to a target namespace`, PreRun: func(cmd *cobra.Command, args []string) { showBanner() }, Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 { util.Info("Please specify one or more endpoint names to copy as arguments!\n") return } c, cfg := client.NewClient(f) oc, _ := client.NewOpenShiftClient(cfg) initSchema() toNamespace := cmd.Flags().Lookup(toNamespaceFlag).Value.String() fromNamespace := cmd.Flags().Lookup(fromNamespaceFlag).Value.String() if len(fromNamespace) == 0 { ns, _, err := f.DefaultNamespace() if err != nil { util.Fatal("No default namespace") } fromNamespace = ns } if len(toNamespace) == 0 { util.Fatal("No target namespace specified!") } util.Infof("Copying endpoints from namespace: %s to namespace: %s\n", fromNamespace, toNamespace) err := ensureNamespaceExists(c, oc, toNamespace) if err != nil { util.Fatalf("Failed to copy endpoints %v", err) } err = copyEndpoints(c, fromNamespace, toNamespace, args) if err != nil { util.Fatalf("Failed to copy endpoints %v", err) } }, } cmd.PersistentFlags().StringP(fromNamespaceFlag, "f", "", "the source namespace or uses the default namespace") cmd.PersistentFlags().StringP(toNamespaceFlag, "t", "", "the destination namespace") return cmd }
func NewCmdVolumes(f *cmdutil.Factory) *cobra.Command { cmd := &cobra.Command{ Use: "volumes", Short: "Creates a persisent volume for any pending persistance volume claims", Long: `Creates a persisent volume for any pending persistance volume claims`, PreRun: func(cmd *cobra.Command, args []string) { showBanner() }, Run: func(cmd *cobra.Command, args []string) { c, _ := client.NewClient(f) ns, _, err := f.DefaultNamespace() if err != nil { util.Fatal("No default namespace") } else { found, pendingClaimNames := findPendingPVS(c, ns) if found { createPV(c, ns, pendingClaimNames, cmd) } } }, } cmd.PersistentFlags().String(sshCommandFlag, "", "the ssh command to run commands inside the VM of the single node cluster") return cmd }
func NewCmdIngress(f *cmdutil.Factory) *cobra.Command { cmd := &cobra.Command{ Use: "ingress", Short: "Creates any missing Ingress resources for services", Long: `Creates any missing Ingress resources for Services which are of type LoadBalancer`, PreRun: func(cmd *cobra.Command, args []string) { showBanner() }, Run: func(cmd *cobra.Command, args []string) { c, cfg := client.NewClient(f) ns, _, err := f.DefaultNamespace() if err != nil { util.Fatal("No default namespace") printResult("Get default namespace", Failure, err) } else { domain := cmd.Flags().Lookup(domainFlag).Value.String() util.Info("Setting up ingress on your ") util.Success(string(util.TypeOfMaster(c))) util.Info(" installation at ") util.Success(cfg.Host) util.Info(" in namespace ") util.Successf("%s at domain %s\n\n", ns, domain) err := createIngressForDomain(ns, domain, c, f) printError("Create Ingress", err) } }, } cmd.PersistentFlags().StringP(domainFlag, "", defaultDomain(), "The domain to put the created routes inside") return cmd }
func NewCmdRoutes(f *cmdutil.Factory) *cobra.Command { cmd := &cobra.Command{ Use: "routes", Short: "Creates any missing Routes for services", Long: `Creates any missing Route resources for Services which need to be exposed remotely`, PreRun: func(cmd *cobra.Command, args []string) { showBanner() }, Run: func(cmd *cobra.Command, args []string) { c, cfg := client.NewClient(f) oc, _ := client.NewOpenShiftClient(cfg) ns, _, err := f.DefaultNamespace() if err != nil { util.Fatal("No default namespace") printResult("Get default namespace", Failure, err) } else { util.Info("Creating a persistent volume for your ") util.Success(string(util.TypeOfMaster(c))) util.Info(" installation at ") util.Success(cfg.Host) util.Info(" in namespace ") util.Successf("%s\n\n", ns) domain := cmd.Flags().Lookup(domainFlag).Value.String() err := createRoutesForDomain(ns, domain, c, oc, f) printError("Create Routes", err) } }, } cmd.PersistentFlags().StringP(domainFlag, "", defaultDomain(), "The domain to put the created routes inside") return cmd }
func NewCmdVolume(f *cmdutil.Factory) *cobra.Command { cmd := &cobra.Command{ Use: "volume", Short: "Creates a persisent volume for fabric8 apps needing persistent disk", Long: `Creates a persisent volume so that the PersistentVolumeClaims in fabric8 apps can be satisfied when creating fabric8 apps`, PreRun: func(cmd *cobra.Command, args []string) { showBanner() }, Run: func(cmd *cobra.Command, args []string) { c, cfg := client.NewClient(f) ns, _, err := f.DefaultNamespace() if err != nil { util.Fatal("No default namespace") printResult("Get default namespace", Failure, err) } else { util.Info("Creating a persistent volume for your ") util.Success(string(util.TypeOfMaster(c))) util.Info(" installation at ") util.Success(cfg.Host) util.Info(" in namespace ") util.Successf("%s\n\n", ns) r, err := createPersistentVolume(cmd, ns, c, f) printResult("Create PersistentVolume", r, err) } }, } cmd.PersistentFlags().StringP(hostPathFlag, "", "", "Defines the host folder on which to define a persisent volume for single node setups") cmd.PersistentFlags().StringP(nameFlag, "", "fabric8", "The name of the PersistentVolume to create") return cmd }
func NewCmdPull(f *cmdutil.Factory) *cobra.Command { cmd := &cobra.Command{ Use: "pull [templateNames]", Short: "Pulls the docker images for the given templates", Long: `Performs a docker pull on all the docker images referenced in the given templates to preload the local docker registry with images`, PreRun: func(cmd *cobra.Command, args []string) { showBanner() }, Run: func(cmd *cobra.Command, args []string) { if len(args) < 1 { util.Error("No template names specified!") cmd.Usage() } else { _, cfg := client.NewClient(f) oc, _ := client.NewOpenShiftClient(cfg) ns, _, err := f.DefaultNamespace() if err != nil { util.Fatal("No default namespace") } else { for _, template := range args { util.Info("Downloading docker images for template ") util.Success(template) util.Info("\n\n") r, err := downloadTemplateDockerImages(cmd, ns, oc, f, template) printResult("Download Docker images", r, err) } } } }, } return cmd }
func NewCmdVolumes(f *cmdutil.Factory) *cobra.Command { cmd := &cobra.Command{ Use: "volumes", Short: "Creates a persisent volume for any pending persistance volume claims", Long: `Creates a persisent volume for any pending persistance volume claims`, PreRun: func(cmd *cobra.Command, args []string) { showBanner() }, Run: func(cmd *cobra.Command, args []string) { c, _ := client.NewClient(f) ns, _, err := f.DefaultNamespace() if err != nil { util.Fatal("No default namespace") } else { found, pvcs, pendingClaimNames := findPendingPVs(c, ns) if found { sshCommand := cmd.Flags().Lookup(sshCommandFlag).Value.String() createPV(c, ns, pendingClaimNames, sshCommand) items := pvcs.Items for _, item := range items { name := item.ObjectMeta.Name status := item.Status.Phase if status == api.ClaimPending || status == api.ClaimLost { err = c.PersistentVolumeClaims(ns).Delete(name) if err != nil { util.Infof("Error deleting PVC %s\n", name) } else { util.Infof("Recreating PVC %s\n", name) c.PersistentVolumeClaims(ns).Create(&api.PersistentVolumeClaim{ ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, }, Spec: api.PersistentVolumeClaimSpec{ VolumeName: ns + "-" + name, AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce}, Resources: api.ResourceRequirements{ Requests: api.ResourceList{ api.ResourceName(api.ResourceStorage): resource.MustParse("1Gi"), }, }, }, }) } } } } } }, } cmd.PersistentFlags().String(sshCommandFlag, "", "the ssh command to run commands inside the VM of the single node cluster") return cmd }
func NewCmdSecrets(f *cmdutil.Factory) *cobra.Command { cmd := &cobra.Command{ Use: "secrets", Short: "Set up Secrets on your Kubernetes or OpenShift environment", Long: `set up Secrets on your Kubernetes or OpenShift environment`, PreRun: func(cmd *cobra.Command, args []string) { showBanner() }, Run: func(cmd *cobra.Command, args []string) { c, cfg := client.NewClient(f) ns, _, _ := f.DefaultNamespace() util.Info("Setting up secrets on your ") util.Success(string(util.TypeOfMaster(c))) util.Info(" installation at ") util.Success(cfg.Host) util.Info(" in namespace ") util.Successf("%s\n\n", ns) if confirmAction(cmd.Flags()) { typeOfMaster := util.TypeOfMaster(c) if typeOfMaster == util.Kubernetes { util.Fatal("Support for Kubernetes not yet available...\n") } else { oc, _ := client.NewOpenShiftClient(cfg) t := getTemplates(oc, ns) count := 0 // get all the Templates and find the annotations on any Pods for _, i := range t.Items { // convert TemplateList.Objects to Kubernetes resources _ = runtime.DecodeList(i.Objects, api.Scheme, runtime.UnstructuredJSONScheme) for _, rc := range i.Objects { switch rc := rc.(type) { case *api.ReplicationController: for secretType, secretDataIdentifiers := range rc.Spec.Template.Annotations { count += createAndPrintSecrets(secretDataIdentifiers, secretType, c, f, cmd.Flags()) } } } } if count == 0 { util.Info("No secrets created as no fabric8 secrets annotations found in the templates\n") util.Info("For more details see: https://github.com/fabric8io/fabric8/blob/master/docs/secretAnnotations.md\n") } } } }, } cmd.PersistentFlags().BoolP("print-import-folder-structure", "", true, "Prints the folder structures that are being used by the template annotations to import secrets") cmd.PersistentFlags().BoolP("write-generated-keys", "", false, "Write generated secrets to the local filesystem") cmd.PersistentFlags().BoolP("generate-secrets-data", "g", true, "Generate secrets data if secrets cannot be found to import from the local filesystem") return cmd }
func confirmAction(flags *pflag.FlagSet) bool { if flags.Lookup(yesFlag).Value.String() == "false" { util.Info("Continue? [Y/n] ") cont := util.AskForConfirmation(true) if !cont { util.Fatal("Cancelled...\n") return false } } return true }
func createRoutes(c *k8sclient.Client, oc *oclient.Client, fac *cmdutil.Factory) error { ns, _, err := fac.DefaultNamespace() if err != nil { util.Fatal("No default namespace") return err } domain := os.Getenv("KUBERNETES_DOMAIN") if domain == "" { domain = DefaultDomain } return createRoutesForDomain(ns, domain, c, oc, fac) }
// Ensure that the `restricted` SecurityContextConstraints has the RunAsUser set to RunAsAny // // if `restricted does not exist lets create it // otherwise if needed lets modify the RunAsUser func verifyRestrictedSecurityContextConstraints(c *k8sclient.Client, f *cmdutil.Factory) (Result, error) { name := RestrictedSCC ns, _, e := f.DefaultNamespace() if e != nil { util.Fatal("No default namespace") return Failure, e } rc, err := c.SecurityContextConstraints().Get(name) if err != nil { scc := kapi.SecurityContextConstraints{ ObjectMeta: kapi.ObjectMeta{ Name: RestrictedSCC, }, SELinuxContext: kapi.SELinuxContextStrategyOptions{ Type: kapi.SELinuxStrategyMustRunAs, }, RunAsUser: kapi.RunAsUserStrategyOptions{ Type: kapi.RunAsUserStrategyRunAsAny, }, Groups: []string{bootstrappolicy.AuthenticatedGroup}, } _, err = c.SecurityContextConstraints().Create(&scc) if err != nil { return Failure, err } else { util.Infof("SecurityContextConstraints %s created\n", name) return Success, err } } // lets check that the restricted is configured correctly if kapi.RunAsUserStrategyRunAsAny != rc.RunAsUser.Type { rc.RunAsUser.Type = kapi.RunAsUserStrategyRunAsAny _, err = c.SecurityContextConstraints().Update(rc) if err != nil { util.Fatalf("Failed to update SecurityContextConstraints %v in namespace %s: %v\n", rc, ns, err) return Failure, err } util.Infof("SecurityContextConstraints %s is updated to enable fabric8\n", name) } else { util.Infof("SecurityContextConstraints %s is configured correctly\n", name) } return Success, err }
func deployFabric8SecurityContextConstraints(c *k8sclient.Client, f *cmdutil.Factory) (Result, error) { name := Fabric8SCC scc := kapi.SecurityContextConstraints{ ObjectMeta: kapi.ObjectMeta{ Name: name, }, AllowPrivilegedContainer: true, AllowHostNetwork: true, AllowHostPorts: true, AllowHostDirVolumePlugin: true, SELinuxContext: kapi.SELinuxContextStrategyOptions{ Type: kapi.SELinuxStrategyRunAsAny, }, RunAsUser: kapi.RunAsUserStrategyOptions{ Type: kapi.RunAsUserStrategyRunAsAny, }, Users: []string{"system:serviceaccount:openshift-infra:build-controller", "system:serviceaccount:default:default", "system:serviceaccount:default:fabric8", "system:serviceaccount:default:gerrit", "system:serviceaccount:default:jenkins", "system:serviceaccount:default:router"}, Groups: []string{bootstrappolicy.ClusterAdminGroup, bootstrappolicy.NodesGroup}, } ns, _, err := f.DefaultNamespace() if err != nil { util.Fatal("No default namespace") return Failure, err } _, err = c.SecurityContextConstraints().Get(name) if err == nil { err = c.SecurityContextConstraints().Delete(name) if err != nil { return Failure, err } } _, err = c.SecurityContextConstraints().Create(&scc) if err != nil { util.Fatalf("Cannot create SecurityContextConstraints: %v\n", err) util.Fatalf("Failed to create SecurityContextConstraints %v in namespace %s: %v\n", scc, ns, err) return Failure, err } util.Infof("SecurityContextConstraints %s is setup correctly\n", name) return Success, err }
func installTemplates(kc *k8sclient.Client, c *oclient.Client, fac *cmdutil.Factory, v string, templateUrl string, dockerRegistry string, arch string, domain string) error { ns, _, err := fac.DefaultNamespace() if err != nil { util.Fatal("No default namespace") return err } templates := c.Templates(ns) util.Infof("Downloading templates for version %v\n", v) uri := fmt.Sprintf(templateUrl, v) resp, err := http.Get(uri) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) } defer resp.Body.Close() tmpFileName := "/tmp/fabric8-template-distros.tar.gz" t, err := os.OpenFile(tmpFileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777) if err != nil { return err } defer t.Close() _, err = io.Copy(t, resp.Body) if err != nil { return err } r, err := zip.OpenReader(tmpFileName) if err != nil { return err } defer r.Close() typeOfMaster := util.TypeOfMaster(kc) for _, f := range r.File { mode := f.FileHeader.Mode() if mode.IsDir() { continue } rc, err := f.Open() if err != nil { return err } defer rc.Close() util.Infof("Loading template %s\n", f.Name) jsonData, err := ioutil.ReadAll(rc) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) } jsonData, err = adaptFabric8ImagesInResourceDescriptor(jsonData, dockerRegistry, arch) if err != nil { util.Fatalf("Cannot append docker registry: %v", err) } jsonData = replaceDomain(jsonData, domain, ns, typeOfMaster) var v1tmpl tapiv1.Template err = json.Unmarshal(jsonData, &v1tmpl) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) } var tmpl tapi.Template err = api.Scheme.Convert(&v1tmpl, &tmpl) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) return err } name := tmpl.ObjectMeta.Name if typeOfMaster == util.Kubernetes { appName := name name = "catalog-" + appName // lets install ConfigMaps for the templates // TODO should the name have a prefix? configmap := api.ConfigMap{ ObjectMeta: api.ObjectMeta{ Name: name, Namespace: ns, Labels: map[string]string{ "name": appName, "provider": "fabric8.io", "kind": "catalog", }, }, Data: map[string]string{ name + ".json": string(jsonData), }, } configmaps := kc.ConfigMaps(ns) _, err = configmaps.Get(name) if err == nil { err = configmaps.Delete(name) if err != nil { util.Errorf("Could not delete configmap %s due to: %v\n", name, err) } } _, err = configmaps.Create(&configmap) if err != nil { util.Fatalf("Failed to create configmap %v", err) return err } } else { // lets install the OpenShift templates _, err = templates.Get(name) if err == nil { err = templates.Delete(name) if err != nil { util.Errorf("Could not delete template %s due to: %v\n", name, err) } } _, err = templates.Create(&tmpl) if err != nil { util.Fatalf("Failed to create template %v", err) return err } } } return nil }
func NewCmdWaitFor(f *cmdutil.Factory) *cobra.Command { cmd := &cobra.Command{ Use: "wait-for", Short: "Waits for the listed deployments to be ready - useful for automation and testing", Long: `Waits for the listed deployments to be ready - useful for automation and testing`, PreRun: func(cmd *cobra.Command, args []string) { showBanner() }, Run: func(cmd *cobra.Command, args []string) { waitAll := cmd.Flags().Lookup(allFlag).Value.String() == "true" durationText := cmd.Flags().Lookup(timeoutFlag).Value.String() maxDuration, err := time.ParseDuration(durationText) if err != nil { util.Fatalf("Could not parse duration `%s` from flag --%s. Error %v\n", durationText, timeoutFlag, err) } durationText = cmd.Flags().Lookup(sleepPeriodFlag).Value.String() sleepMillis, err := time.ParseDuration(durationText) if err != nil { util.Fatalf("Could not parse duration `%s` from flag --%s. Error %v\n", durationText, sleepPeriodFlag, err) } if !waitAll && len(args) == 0 { util.Infof("Please specify one or more names of Deployment or DeploymentConfig resources or use the --%s flag to match all Deployments and DeploymentConfigs\n", allFlag) return } c, cfg := client.NewClient(f) oc, _ := client.NewOpenShiftClient(cfg) initSchema() fromNamespace := cmd.Flags().Lookup(namespaceFlag).Value.String() if len(fromNamespace) == 0 { ns, _, err := f.DefaultNamespace() if err != nil { util.Fatal("No default namespace") } fromNamespace = ns } timer := time.NewTimer(maxDuration) go func() { <-timer.C util.Fatalf("Timed out waiting for Deployments. Waited: %v\n", maxDuration) }() util.Infof("Waiting for Deployments to be ready in namespace %s\n", fromNamespace) typeOfMaster := util.TypeOfMaster(c) for i := 0; i < 2; i++ { if typeOfMaster == util.OpenShift { handleError(waitForDeploymentConfigs(oc, fromNamespace, waitAll, args, sleepMillis)) } handleError(waitForDeployments(c, fromNamespace, waitAll, args, sleepMillis)) } timer.Stop() util.Infof("Deployments are ready now!\n") }, } cmd.PersistentFlags().Bool(allFlag, false, "waits for all the Deployments or DeploymentConfigs to be ready") cmd.PersistentFlags().StringP(namespaceFlag, "n", "", "the namespace to watch - if ommitted then the default namespace is used") cmd.PersistentFlags().String(timeoutFlag, "60m", "the maximum amount of time to wait for the Deployemnts to be ready before failing. e.g. an expression like: 1.5h, 12m, 10s") cmd.PersistentFlags().String(sleepPeriodFlag, "1s", "the sleep period while polling for Deployment status (e.g. 1s)") return cmd }
func installTemplates(c *oclient.Client, fac *cmdutil.Factory, v string, templateUrl string) error { ns, _, err := fac.DefaultNamespace() if err != nil { util.Fatal("No default namespace") return err } templates := c.Templates(ns) util.Infof("Downloading templates for version %v\n", v) uri := fmt.Sprintf(templateUrl, v) resp, err := http.Get(uri) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) } defer resp.Body.Close() tmpFileName := "/tmp/fabric8-template-distros.tar.gz" t, err := os.OpenFile(tmpFileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777) if err != nil { return err } defer t.Close() _, err = io.Copy(t, resp.Body) if err != nil { return err } r, err := zip.OpenReader(tmpFileName) if err != nil { return err } defer r.Close() for _, f := range r.File { mode := f.FileHeader.Mode() if mode.IsDir() { continue } rc, err := f.Open() if err != nil { return err } defer rc.Close() util.Infof("Loading template %s\n", f.Name) jsonData, err := ioutil.ReadAll(rc) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) } var v1tmpl tapiv1.Template err = json.Unmarshal(jsonData, &v1tmpl) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) } var tmpl tapi.Template err = api.Scheme.Convert(&v1tmpl, &tmpl) if err != nil { util.Fatalf("Cannot get fabric8 template to deploy: %v", err) return err } name := tmpl.ObjectMeta.Name _, err = templates.Get(name) if err == nil { err = templates.Delete(name) if err != nil { util.Errorf("Could not delete template %s due to: %v\n", name, err) } } _, err = templates.Create(&tmpl) if err != nil { util.Fatalf("Failed to create template %v", err) return err } } return nil }