Merge pull request #91 from andyxning/add_option_pkg

add options pkg
This commit is contained in:
Lantao Liu
2017-02-07 10:38:49 -08:00
committed by GitHub
4 changed files with 134 additions and 64 deletions
+18 -59
View File
@@ -17,11 +17,9 @@ limitations under the License.
package main
import (
"flag"
"net"
"net/http"
_ "net/http/pprof"
"net/url"
"os"
"strconv"
@@ -29,57 +27,13 @@ import (
"github.com/spf13/pflag"
"k8s.io/node-problem-detector/pkg/kernelmonitor"
"k8s.io/node-problem-detector/pkg/options"
"k8s.io/node-problem-detector/pkg/problemclient"
"k8s.io/node-problem-detector/pkg/problemdetector"
"k8s.io/node-problem-detector/pkg/version"
)
// TODO: Move flags to options directory.
var (
kernelMonitorConfigPath = pflag.String("kernel-monitor", "/config/kernel-monitor.json", "The path to the kernel monitor config file")
apiServerOverride = pflag.String("apiserver-override", "", "Custom URI used to connect to Kubernetes ApiServer")
printVersion = pflag.Bool("version", false, "Print version information and quit")
hostnameOverride = pflag.String("hostname-override", "", "Custom node name used to override hostname")
serverPort = pflag.Int("port", 10256, "The port to bind the node problem detector server. Use 0 to disable.")
serverAddress = pflag.String("address", "127.0.0.1", "The address to bind the node problem detector server.")
)
func validateCmdParams() {
if _, err := url.Parse(*apiServerOverride); err != nil {
glog.Fatalf("apiserver-override %q is not a valid HTTP URI: %v", *apiServerOverride, err)
}
}
func getNodeNameOrDie() string {
var nodeName string
// Check hostname override first for customized node name.
if *hostnameOverride != "" {
return *hostnameOverride
}
// Get node name from environment variable NODE_NAME
// By default, assume that the NODE_NAME env should have been set with
// downward api or user defined exported environment variable. We prefer it because sometimes
// the hostname returned by os.Hostname is not right because:
// 1. User may override the hostname.
// 2. For some cloud providers, os.Hostname is different from the real hostname.
nodeName = os.Getenv("NODE_NAME")
if nodeName != "" {
return nodeName
}
// For backward compatibility. If the env is not set, get the hostname
// from os.Hostname(). This may not work for all configurations and
// environments.
nodeName, err := os.Hostname()
if err != nil {
glog.Fatalf("Failed to get host name: %v", err)
}
return nodeName
}
func startHTTPServer(p problemdetector.ProblemDetector) {
func startHTTPServer(p problemdetector.ProblemDetector, npdo *options.NodeProblemDetectorOptions) {
// Add healthz http request handler. Always return ok now, add more health check
// logic in the future.
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
@@ -88,31 +42,36 @@ func startHTTPServer(p problemdetector.ProblemDetector) {
})
// Add the http handlers in problem detector.
p.RegisterHTTPHandlers()
err := http.ListenAndServe(net.JoinHostPort(*serverAddress, strconv.Itoa(*serverPort)), nil)
addr := net.JoinHostPort(npdo.ServerAddress, strconv.Itoa(npdo.ServerPort))
err := http.ListenAndServe(addr, nil)
if err != nil {
glog.Fatalf("Failed to start server: %v", err)
}
}
func main() {
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
npdo := options.NewNodeProblemDetectorOptions()
npdo.AddFlags(pflag.CommandLine)
pflag.Parse()
validateCmdParams()
npdo.SetNodeNameOrDie()
if *printVersion {
npdo.ValidOrDie()
if npdo.PrintVersion {
version.PrintVersion()
os.Exit(0)
}
nodeName := getNodeNameOrDie()
k := kernelmonitor.NewKernelMonitorOrDie(*kernelMonitorConfigPath)
p := problemdetector.NewProblemDetector(k, *apiServerOverride, nodeName)
k := kernelmonitor.NewKernelMonitorOrDie(npdo.KernelMonitorConfigPath)
c := problemclient.NewClientOrDie(npdo)
p := problemdetector.NewProblemDetector(k, c)
// Start http server.
if *serverPort > 0 {
startHTTPServer(p)
if npdo.ServerPort > 0 {
startHTTPServer(p, npdo)
}
if err := p.Run(); err != nil {
+111
View File
@@ -0,0 +1,111 @@
/*
Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package options
import (
"flag"
"fmt"
"os"
"net/url"
"github.com/spf13/pflag"
)
// NodeProblemDetectorOptions contains node problem detector command line and application options.
type NodeProblemDetectorOptions struct {
// command line options
// KernelMonitorConfigPath specifies the path to kernel monitor configuration file.
KernelMonitorConfigPath string
// ApiServerOverride is the custom URI used to connect to Kubernetes ApiServer.
ApiServerOverride string
// PrintVersion is the flag determining whether version information is printed.
PrintVersion bool
// HostnameOverride specifies custom node name used to override hostname.
HostnameOverride string
// ServerPort is the port to bind the node problem detector server. Use 0 to disable.
ServerPort int
// ServerAddress is the address to bind the node problem detector server.
ServerAddress string
// application options
// NodeName is the node name used to communicate with Kubernetes ApiServer.
NodeName string
}
func NewNodeProblemDetectorOptions() *NodeProblemDetectorOptions {
return &NodeProblemDetectorOptions{}
}
// AddFlags adds node problem detector command line options to pflag.
func (npdo *NodeProblemDetectorOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&npdo.KernelMonitorConfigPath, "kernel-monitor",
"/config/kernel-monitor.json", "The path to the kernel monitor config file")
fs.StringVar(&npdo.ApiServerOverride, "apiserver-override",
"", "Custom URI used to connect to Kubernetes ApiServer")
fs.BoolVar(&npdo.PrintVersion, "version", false, "Print version information and quit")
fs.StringVar(&npdo.HostnameOverride, "hostname-override",
"", "Custom node name used to override hostname")
fs.IntVar(&npdo.ServerPort, "port",
10256, "The port to bind the node problem detector server. Use 0 to disable.")
fs.StringVar(&npdo.ServerAddress, "address",
"127.0.0.1", "The address to bind the node problem detector server.")
}
// ValidOrDie validates node problem detector command line options.
func (npdo *NodeProblemDetectorOptions) ValidOrDie() {
if _, err := url.Parse(npdo.ApiServerOverride); err != nil {
panic(fmt.Sprintf("apiserver-override %q is not a valid HTTP URI: %v",
npdo.ApiServerOverride, err))
}
}
// SetNodeNameOrDie sets `NodeName` field with valid value.
func (npdo *NodeProblemDetectorOptions) SetNodeNameOrDie() {
// Check hostname override first for customized node name.
if npdo.HostnameOverride != "" {
npdo.NodeName = npdo.HostnameOverride
return
}
// Get node name from environment variable NODE_NAME
// By default, assume that the NODE_NAME env should have been set with
// downward api or user defined exported environment variable. We prefer it because sometimes
// the hostname returned by os.Hostname is not right because:
// 1. User may override the hostname.
// 2. For some cloud providers, os.Hostname is different from the real hostname.
npdo.NodeName = os.Getenv("NODE_NAME")
if npdo.NodeName != "" {
return
}
// For backward compatibility. If the env is not set, get the hostname
// from os.Hostname(). This may not work for all configurations and
// environments.
nodeName, err := os.Hostname()
if err != nil {
panic(fmt.Sprintf("Failed to get host name: %v", err))
}
npdo.NodeName = nodeName
}
func init() {
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
}
+4 -3
View File
@@ -29,6 +29,7 @@ import (
"k8s.io/kubernetes/pkg/util/clock"
"k8s.io/heapster/common/kubernetes"
"k8s.io/node-problem-detector/pkg/options"
)
// Client is the interface of problem client
@@ -50,11 +51,11 @@ type nodeProblemClient struct {
}
// NewClientOrDie creates a new problem client, panics if error occurs.
func NewClientOrDie(apiServerOverride, nodeName string) Client {
func NewClientOrDie(npdo *options.NodeProblemDetectorOptions) Client {
c := &nodeProblemClient{clock: clock.RealClock{}}
// we have checked it is a valid URI after command line argument is parsed.:)
uri, _ := url.Parse(apiServerOverride)
uri, _ := url.Parse(npdo.ApiServerOverride)
cfg, err := kubernetes.GetKubeClientConfig(uri)
if err != nil {
@@ -63,7 +64,7 @@ func NewClientOrDie(apiServerOverride, nodeName string) Client {
// TODO(random-liu): Set QPS Limit
c.client = client.NewOrDie(cfg)
c.nodeName = nodeName
c.nodeName = npdo.NodeName
c.nodeRef = getNodeRef(c.nodeName)
c.recorders = make(map[string]record.EventRecorder)
return c
+1 -2
View File
@@ -44,8 +44,7 @@ type problemDetector struct {
// NewProblemDetector creates the problem detector. Currently we just directly passed in the problem daemons, but
// in the future we may want to let the problem daemons register themselves.
func NewProblemDetector(monitor kernelmonitor.KernelMonitor, apiServerOverride, nodeName string) ProblemDetector {
client := problemclient.NewClientOrDie(apiServerOverride, nodeName)
func NewProblemDetector(monitor kernelmonitor.KernelMonitor, client problemclient.Client) ProblemDetector {
return &problemDetector{
client: client,
conditionManager: condition.NewConditionManager(client, clock.RealClock{}),