package start import ( "fmt" "io" "net" "os" "github.com/golang/glog" "github.com/spf13/cobra" kerrors "k8s.io/kubernetes/pkg/api/errors" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "github.com/openshift/origin/pkg/cmd/flagtypes" configapi "github.com/openshift/origin/pkg/cmd/server/api" "github.com/openshift/origin/pkg/cmd/templates" ) var apiLong = templates.LongDesc(` Start the master API This command starts the master API. Running %[1]s start master %[2]s will start the server listening for incoming API requests. The server will run in the foreground until you terminate the process.`) // NewCommandStartMasterAPI starts only the APIserver func NewCommandStartMasterAPI(name, basename string, out, errout io.Writer) (*cobra.Command, *MasterOptions) { options := &MasterOptions{Output: out} options.DefaultsFromName(basename) cmd := &cobra.Command{ Use: name, Short: "Launch master API", Long: fmt.Sprintf(apiLong, basename, name), Run: func(c *cobra.Command, args []string) { if err := options.Complete(); err != nil { fmt.Fprintln(errout, kcmdutil.UsageError(c, err.Error())) return } if len(options.ConfigFile) == 0 { fmt.Fprintln(errout, kcmdutil.UsageError(c, "--config is required for this command")) return } if err := options.Validate(args); err != nil { fmt.Fprintln(errout, kcmdutil.UsageError(c, err.Error())) return } startProfiler() if err := options.StartMaster(); err != nil { if kerrors.IsInvalid(err) { if details := err.(*kerrors.StatusError).ErrStatus.Details; details != nil { fmt.Fprintf(errout, "Invalid %s %s\n", details.Kind, details.Name) for _, cause := range details.Causes { fmt.Fprintf(errout, " %s: %s\n", cause.Field, cause.Message) } os.Exit(255) } } glog.Fatal(err) } }, } // allow the master IP address to be overridden on a per process basis masterAddr := flagtypes.Addr{ Value: "127.0.0.1:8443", DefaultScheme: "https", DefaultPort: 8443, AllowPrefix: true, }.Default() // allow the listen address to be overridden on a per process basis listenArg := &ListenArg{ ListenAddr: flagtypes.Addr{ Value: "127.0.0.1:8444", DefaultScheme: "https", DefaultPort: 8444, AllowPrefix: true, }.Default(), } options.MasterArgs = NewDefaultMasterArgs() options.MasterArgs.StartAPI = true options.MasterArgs.OverrideConfig = func(config *configapi.MasterConfig) error { // we do not currently enable multi host etcd for the cluster config.EtcdConfig = nil if config.KubernetesMasterConfig != nil { if masterAddr.Provided { if ip := net.ParseIP(masterAddr.Host); ip != nil { glog.V(2).Infof("Using a masterIP override %q", ip) config.KubernetesMasterConfig.MasterIP = ip.String() } } if listenArg.ListenAddr.Provided { addr := listenArg.ListenAddr.URL.Host glog.V(2).Infof("Using a listen address override %q", addr) applyBindAddressOverride(addr, config) } } return nil } flags := cmd.Flags() // This command only supports reading from config and the override master address flags.StringVar(&options.ConfigFile, "config", "", "Location of the master configuration file to run from. Required") cmd.MarkFlagFilename("config", "yaml", "yml") flags.Var(&masterAddr, "master", "The address the master should register for itself. Defaults to the master address from the config.") BindListenArg(listenArg, flags, "") return cmd, options } // applyBindAddressOverride takes a given address and overrides the relevant sections of a MasterConfig // TODO: move into helpers func applyBindAddressOverride(addr string, config *configapi.MasterConfig) { defaultHost, defaultPort, err := net.SplitHostPort(addr) if err != nil { // is just a host defaultHost = addr } config.ServingInfo.BindAddress = overrideAddress(config.ServingInfo.BindAddress, defaultHost, defaultPort) if config.EtcdConfig != nil { config.EtcdConfig.ServingInfo.BindAddress = overrideAddress(config.EtcdConfig.ServingInfo.BindAddress, defaultHost, "") config.EtcdConfig.PeerServingInfo.BindAddress = overrideAddress(config.EtcdConfig.PeerServingInfo.BindAddress, defaultHost, "") } if config.DNSConfig != nil { config.DNSConfig.BindAddress = overrideAddress(config.DNSConfig.BindAddress, defaultHost, "") } if config.AssetConfig != nil { config.AssetConfig.ServingInfo.BindAddress = overrideAddress(config.AssetConfig.ServingInfo.BindAddress, defaultHost, defaultPort) } } // overrideAddress applies an optional host or port override to a incoming addr. If host or port are empty they will // not override the existing addr values. func overrideAddress(addr, host, port string) string { existingHost, existingPort, err := net.SplitHostPort(addr) if err != nil { if len(host) > 0 { return host } return addr } if len(host) > 0 { existingHost = host } if len(port) > 0 { existingPort = port } if len(existingPort) == 0 { return existingHost } return net.JoinHostPort(existingHost, existingPort) }