<commit_before>// Copyright 2016 The Upspin Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package flags defines command-line flags to make them consistent between binaries.
// Not all flags make sense for all binaries.
package flags // import "upspin.io/flags"

import (
	"flag"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"upspin.io/log"
)

// flagVar represents a flag in this package.
type flagVar struct {
	set  func()        // Set the value at parse time.
	arg  func() string // Return the argument to set the flag.
	arg2 func() string // Return the argument to set the second flag; usually nil.
}

const (
	defaultBlockSize  = 1024 * 1024 // Keep in sync with upspin.BlockSize.]
	defaultHTTPAddr   = ":80"
	defaultHTTPSAddr  = ":443"
	defaultLog        = "info"
	defaultServerKind = "inprocess"
)

var (
	// BlockSize is the block size used when writing large files. The default is 1MB.
	BlockSize = defaultBlockSize

	// CacheDir specifies the directory for the various file caches.
	defaultCacheDir = filepath.Join(os.Getenv("HOME"), "upspin")
	CacheDir        = defaultCacheDir

	// Config names the Upspin configuration file to use.
	defaultConfig = filepath.Join(os.Getenv("HOME"), "upspin", "config")
	Config        = defaultConfig

	// HTTPAddr is the network address on which to listen for incoming
	// insecure network connections.
	HTTPAddr = defaultHTTPAddr

	// HTTPSAddr is the network address on which to listen for incoming
	// secure network connections.
	HTTPSAddr = defaultHTTPSAddr

	// LetsEncryptCache is the location of a file in which the Let's
	// Encrypt certificates are stored. The containing directory should
	// be owner-accessible only (chmod 0700).
	LetsEncryptCache = ""

	// Log sets the level of logging (implements flag.Value).
	Log logFlag

	// NetAddr is the publicly accessible network address of this server.
	NetAddr = ""

	// Project is the project name on GCP; used by servers, upspin-deploy,
	// and cmd/upspin setupdomain.
	Project = ""

	// ServerConfig specifies configuration options ("key=value") for servers.
	ServerConfig []string

	// ServerKind is the implementation kind of this server.
	ServerKind = defaultServerKind

	// StoreServerName is the Upspin user name of the StoreServer.
	StoreServerUser = ""

	// TLSCertFile and TLSKeyFile specify the location of a TLS
	// certificate/key pair used for serving TLS (HTTPS).
	TLSCertFile = ""
	TLSKeyFile  = ""
)

// flags is a map of flag registration functions keyed by flag name,
// used by Parse to register specific (or all) flags.
var flags = map[string]*flagVar{
	"addr": &flagVar{
		set: func() {
			flag.StringVar(&NetAddr, "addr", "", "publicly accessible network address (`host:port`)")
		},
		arg: func() string { return strArg("addr", NetAddr, "") },
	},
	"blocksize": &flagVar{
		set: func() {
			flag.IntVar(&BlockSize, "blocksize", BlockSize, "`size` of blocks when writing larg:e files")
		},
		arg: func() string {
			if BlockSize == defaultBlockSize {
				return ""
			}
			return fmt.Sprintf("-blocksize=%d", BlockSize)
		},
	},
	"cachedir": &flagVar{
		set: func() {
			flag.StringVar(&CacheDir, "cachedir", CacheDir, "`directory` containing all file caches")
		},
		arg: func() string {
			return strArg("cachedir", CacheDir, defaultCacheDir)
		},
	},
	"config": &flagVar{
		set: func() {
			flag.StringVar(&Config, "config", Config, "user's configuration `file`")
		},
		arg: func() string { return strArg("config", Config, defaultConfig) },
	},
	"http": &flagVar{
		set: func() {
			flag.StringVar(&HTTPAddr, "http", HTTPAddr, "`address` for incoming insecure network connections")
		},
		arg: func() string { return strArg("http", HTTPAddr, defaultHTTPAddr) },
	},
	"https": &flagVar{
		set: func() {
			flag.StringVar(&HTTPSAddr, "https", HTTPSAddr, "`address` for incoming secure network connections")
		},
		arg: func() string { return strArg("https", HTTPSAddr, defaultHTTPSAddr) },
	},
	"kind": &flagVar{
		set: func() {
			flag.StringVar(&ServerKind, "kind", ServerKind, "server implementation `kind` (inprocess, gcp)")
		},
		arg: func() string { return strArg("kind", ServerKind, defaultServerKind) },
	},
	"letscache": &flagVar{
		set: func() {
			flag.StringVar(&LetsEncryptCache, "letscache", "", "Let's Encrypt cache `directory`")
		},
		arg: func() string { return strArg("letscache", LetsEncryptCache, "") },
	},
	"log": &flagVar{
		set: func() {
			Log.Set("info")
			flag.Var(&Log, "log", "`level` of logging: debug, info, error, disabled")
		},
		arg: func() string { return strArg("log", Log.String(), defaultLog) },
	},
	"project": &flagVar{
		set: func() {
			flag.StringVar(&Project, "project", Project, "GCP `project` name")
		},
		arg: func() string { return strArg("-project=", Project, "") },
	},
	"serverconfig": &flagVar{
		set: func() {
			flag.Var(configFlag{&ServerConfig}, "serverconfig", "comma-separated list of configuration options (key=value) for this server")
		},
		arg: func() string { return strArg("-serverconfig=", configFlag{&ServerConfig}.String(), "") },
	},
	"storeserveruser": &flagVar{
		set: func() {
			flag.StringVar(&StoreServerUser, "storeserveruser", "", "user name of the StoreServer")
		},
		arg: func() string { return strArg("storeserveruser", StoreServerUser, "") },
	},
	"tls": &flagVar{
		set: func() {
			flag.StringVar(&TLSCertFile, "tls_cert", "", "TLS Certificate `file` in PEM format")
			flag.StringVar(&TLSKeyFile, "tls_key", "", "TLS Key `file` in PEM format")
		},
		arg:  func() string { return strArg("tls_cert", TLSCertFile, "") },
		arg2: func() string { return strArg("tls_key", TLSKeyFile, "") },
	},
}

// Parse registers the command-line flags for the given flag names
// and calls flag.Parse. Passing zero names registers all flags.
// Passing an unknown name triggers a panic.
//
// For example:
// 	flags.Parse("config", "endpoint") // Register Config and Endpoint.
// or
// 	flags.Parse() // Register all flags.
func Parse(names ...string) {
	if len(names) == 0 {
		// Register all flags if no names provided.
		for _, flag := range flags {
			flag.set()
		}
	} else {
		for _, n := range names {
			flag, ok := flags[n]
			if !ok {
				panic(fmt.Sprintf("unknown flag %q", n))
			}
			flag.set()
		}
	}
	flag.Parse()
}

// Args returns a slice of -flag=value strings that will recreate
// the state of the flags. Flags set to their default value are elided.
func Args() []string {
	var args []string
	for _, flag := range flags {
		arg := flag.arg()
		if arg == "" {
			continue
		}
		args = append(args, arg)
		if flag.arg2 != nil {
			args = append(args, flag.arg2())
		}
	}
	return args
}

// strArg returns a command-line argument that will recreate the flag,
// or the empty string if the value is the default.
func strArg(name, value, _default string) string {
	if value == _default {
		return ""
	}
	return "-" + name + "=" + value
}

type logFlag string

// String implements flag.Value.
func (f logFlag) String() string {
	return string(f)
}

// Set implements flag.Value.
func (f *logFlag) Set(level string) error {
	err := log.SetLevel(level)
	if err != nil {
		return err
	}
	*f = logFlag(log.GetLevel())
	return nil
}

// Get implements flag.Getter.
func (logFlag) Get() interface{} {
	return log.GetLevel()
}

type configFlag struct {
	s *[]string
}

// String implements flag.Value.
func (f configFlag) String() string {
	if f.s == nil {
		return ""
	}
	return strings.Join(*f.s, ",")
}

// Set implements flag.Value.
func (f configFlag) Set(s string) error {
	ss := strings.Split(strings.TrimSpace(s), ",")
	// Drop empty elements.
	for i := 0; i < len(ss); i++ {
		if ss[i] == "" {
			ss = append(ss[:i], ss[i+1:]...)
		}
	}
	*f.s = ss
	return nil
}

// Get implements flag.Getter.
func (f configFlag) Get() interface{} {
	if f.s == nil {
		return ""
	}
	return *f.s
}
<commit_msg>flags: delete - and = from a few calls to setVar<commit_after>// Copyright 2016 The Upspin Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package flags defines command-line flags to make them consistent between binaries.
// Not all flags make sense for all binaries.
package flags // import "upspin.io/flags"

import (
	"flag"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"upspin.io/log"
)

// flagVar represents a flag in this package.
type flagVar struct {
	set  func()        // Set the value at parse time.
	arg  func() string // Return the argument to set the flag.
	arg2 func() string // Return the argument to set the second flag; usually nil.
}

const (
	defaultBlockSize  = 1024 * 1024 // Keep in sync with upspin.BlockSize.]
	defaultHTTPAddr   = ":80"
	defaultHTTPSAddr  = ":443"
	defaultLog        = "info"
	defaultServerKind = "inprocess"
)

var (
	// BlockSize is the block size used when writing large files. The default is 1MB.
	BlockSize = defaultBlockSize

	// CacheDir specifies the directory for the various file caches.
	defaultCacheDir = filepath.Join(os.Getenv("HOME"), "upspin")
	CacheDir        = defaultCacheDir

	// Config names the Upspin configuration file to use.
	defaultConfig = filepath.Join(os.Getenv("HOME"), "upspin", "config")
	Config        = defaultConfig

	// HTTPAddr is the network address on which to listen for incoming
	// insecure network connections.
	HTTPAddr = defaultHTTPAddr

	// HTTPSAddr is the network address on which to listen for incoming
	// secure network connections.
	HTTPSAddr = defaultHTTPSAddr

	// LetsEncryptCache is the location of a file in which the Let's
	// Encrypt certificates are stored. The containing directory should
	// be owner-accessible only (chmod 0700).
	LetsEncryptCache = ""

	// Log sets the level of logging (implements flag.Value).
	Log logFlag

	// NetAddr is the publicly accessible network address of this server.
	NetAddr = ""

	// Project is the project name on GCP; used by servers, upspin-deploy,
	// and cmd/upspin setupdomain.
	Project = ""

	// ServerConfig specifies configuration options ("key=value") for servers.
	ServerConfig []string

	// ServerKind is the implementation kind of this server.
	ServerKind = defaultServerKind

	// StoreServerName is the Upspin user name of the StoreServer.
	StoreServerUser = ""

	// TLSCertFile and TLSKeyFile specify the location of a TLS
	// certificate/key pair used for serving TLS (HTTPS).
	TLSCertFile = ""
	TLSKeyFile  = ""
)

// flags is a map of flag registration functions keyed by flag name,
// used by Parse to register specific (or all) flags.
var flags = map[string]*flagVar{
	"addr": &flagVar{
		set: func() {
			flag.StringVar(&NetAddr, "addr", "", "publicly accessible network address (`host:port`)")
		},
		arg: func() string { return strArg("addr", NetAddr, "") },
	},
	"blocksize": &flagVar{
		set: func() {
			flag.IntVar(&BlockSize, "blocksize", BlockSize, "`size` of blocks when writing larg:e files")
		},
		arg: func() string {
			if BlockSize == defaultBlockSize {
				return ""
			}
			return fmt.Sprintf("-blocksize=%d", BlockSize)
		},
	},
	"cachedir": &flagVar{
		set: func() {
			flag.StringVar(&CacheDir, "cachedir", CacheDir, "`directory` containing all file caches")
		},
		arg: func() string {
			return strArg("cachedir", CacheDir, defaultCacheDir)
		},
	},
	"config": &flagVar{
		set: func() {
			flag.StringVar(&Config, "config", Config, "user's configuration `file`")
		},
		arg: func() string { return strArg("config", Config, defaultConfig) },
	},
	"http": &flagVar{
		set: func() {
			flag.StringVar(&HTTPAddr, "http", HTTPAddr, "`address` for incoming insecure network connections")
		},
		arg: func() string { return strArg("http", HTTPAddr, defaultHTTPAddr) },
	},
	"https": &flagVar{
		set: func() {
			flag.StringVar(&HTTPSAddr, "https", HTTPSAddr, "`address` for incoming secure network connections")
		},
		arg: func() string { return strArg("https", HTTPSAddr, defaultHTTPSAddr) },
	},
	"kind": &flagVar{
		set: func() {
			flag.StringVar(&ServerKind, "kind", ServerKind, "server implementation `kind` (inprocess, gcp)")
		},
		arg: func() string { return strArg("kind", ServerKind, defaultServerKind) },
	},
	"letscache": &flagVar{
		set: func() {
			flag.StringVar(&LetsEncryptCache, "letscache", "", "Let's Encrypt cache `directory`")
		},
		arg: func() string { return strArg("letscache", LetsEncryptCache, "") },
	},
	"log": &flagVar{
		set: func() {
			Log.Set("info")
			flag.Var(&Log, "log", "`level` of logging: debug, info, error, disabled")
		},
		arg: func() string { return strArg("log", Log.String(), defaultLog) },
	},
	"project": &flagVar{
		set: func() {
			flag.StringVar(&Project, "project", Project, "GCP `project` name")
		},
		arg: func() string { return strArg("project", Project, "") },
	},
	"serverconfig": &flagVar{
		set: func() {
			flag.Var(configFlag{&ServerConfig}, "serverconfig", "comma-separated list of configuration options (key=value) for this server")
		},
		arg: func() string { return strArg("serverconfig", configFlag{&ServerConfig}.String(), "") },
	},
	"storeserveruser": &flagVar{
		set: func() {
			flag.StringVar(&StoreServerUser, "storeserveruser", "", "user name of the StoreServer")
		},
		arg: func() string { return strArg("storeserveruser", StoreServerUser, "") },
	},
	"tls": &flagVar{
		set: func() {
			flag.StringVar(&TLSCertFile, "tls_cert", "", "TLS Certificate `file` in PEM format")
			flag.StringVar(&TLSKeyFile, "tls_key", "", "TLS Key `file` in PEM format")
		},
		arg:  func() string { return strArg("tls_cert", TLSCertFile, "") },
		arg2: func() string { return strArg("tls_key", TLSKeyFile, "") },
	},
}

// Parse registers the command-line flags for the given flag names
// and calls flag.Parse. Passing zero names registers all flags.
// Passing an unknown name triggers a panic.
//
// For example:
// 	flags.Parse("config", "endpoint") // Register Config and Endpoint.
// or
// 	flags.Parse() // Register all flags.
func Parse(names ...string) {
	if len(names) == 0 {
		// Register all flags if no names provided.
		for _, flag := range flags {
			flag.set()
		}
	} else {
		for _, n := range names {
			flag, ok := flags[n]
			if !ok {
				panic(fmt.Sprintf("unknown flag %q", n))
			}
			flag.set()
		}
	}
	flag.Parse()
}

// Args returns a slice of -flag=value strings that will recreate
// the state of the flags. Flags set to their default value are elided.
func Args() []string {
	var args []string
	for _, flag := range flags {
		arg := flag.arg()
		if arg == "" {
			continue
		}
		args = append(args, arg)
		if flag.arg2 != nil {
			args = append(args, flag.arg2())
		}
	}
	return args
}

// strArg returns a command-line argument that will recreate the flag,
// or the empty string if the value is the default.
func strArg(name, value, _default string) string {
	if value == _default {
		return ""
	}
	return "-" + name + "=" + value
}

type logFlag string

// String implements flag.Value.
func (f logFlag) String() string {
	return string(f)
}

// Set implements flag.Value.
func (f *logFlag) Set(level string) error {
	err := log.SetLevel(level)
	if err != nil {
		return err
	}
	*f = logFlag(log.GetLevel())
	return nil
}

// Get implements flag.Getter.
func (logFlag) Get() interface{} {
	return log.GetLevel()
}

type configFlag struct {
	s *[]string
}

// String implements flag.Value.
func (f configFlag) String() string {
	if f.s == nil {
		return ""
	}
	return strings.Join(*f.s, ",")
}

// Set implements flag.Value.
func (f configFlag) Set(s string) error {
	ss := strings.Split(strings.TrimSpace(s), ",")
	// Drop empty elements.
	for i := 0; i < len(ss); i++ {
		if ss[i] == "" {
			ss = append(ss[:i], ss[i+1:]...)
		}
	}
	*f.s = ss
	return nil
}

// Get implements flag.Getter.
func (f configFlag) Get() interface{} {
	if f.s == nil {
		return ""
	}
	return *f.s
}
<|endoftext|>


<commit_before>package libreofficekit

import (
	"testing"
)

const (
	DefaultLibreOfficePath  = "/usr/lib/libreoffice/program/"
	DocumentThatDoesntExist = "testdata/kittens.docx"
	SampleDocument          = "testdata/sample.docx"
)

func TestInvalidOfficePath(t *testing.T) {
	_, err := NewOffice("/etc/passwd")
	if err == nil {
		t.Fail()
	}
}

func TestValidOfficePath(t *testing.T) {
	_, err := NewOffice(DefaultLibreOfficePath)
	if err != nil {
		t.Fail()
	}
}

func TestGetOfficeErrorMessage(t *testing.T) {
	office, _ := NewOffice(DefaultLibreOfficePath)
	office.LoadDocument(DocumentThatDoesntExist)
	message := office.GetError()
	if len(message) == 0 {
		t.Fail()
	}
}

func TestLoadDocumentThatDoesntExist(t *testing.T) {
	office, _ := NewOffice(DefaultLibreOfficePath)
	_, err := office.LoadDocument(DocumentThatDoesntExist)
	if err == nil {
		t.Fail()
	}
}

func TestSuccessLoadDocument(t *testing.T) {
	office, _ := NewOffice(DefaultLibreOfficePath)
	_, err := office.LoadDocument(SampleDocument)
	if err != nil {
		t.Fail()
	}
}
<commit_msg>Moar tests<commit_after>package libreofficekit

import (
	"testing"
)

const (
	DefaultLibreOfficePath  = "/usr/lib/libreoffice/program/"
	DocumentThatDoesntExist = "testdata/kittens.docx"
	SampleDocument          = "testdata/sample.docx"
)

func TestInvalidOfficePath(t *testing.T) {
	_, err := NewOffice("/etc/passwd")
	if err == nil {
		t.Fail()
	}
}

func TestValidOfficePath(t *testing.T) {
	_, err := NewOffice(DefaultLibreOfficePath)
	if err != nil {
		t.Fail()
	}
}

func TestGetOfficeErrorMessage(t *testing.T) {
	office, _ := NewOffice(DefaultLibreOfficePath)
	office.LoadDocument(DocumentThatDoesntExist)
	message := office.GetError()
	if len(message) == 0 {
		t.Fail()
	}
}

func TestLoadDocumentThatDoesntExist(t *testing.T) {
	office, _ := NewOffice(DefaultLibreOfficePath)
	_, err := office.LoadDocument(DocumentThatDoesntExist)
	if err == nil {
		t.Fail()
	}
}

func TestSuccessLoadDocument(t *testing.T) {
	office, _ := NewOffice(DefaultLibreOfficePath)
	_, err := office.LoadDocument(SampleDocument)
	if err != nil {
		t.Fail()
	}
}

func TestGetPartPageRectangles(t *testing.T) {
	office, _ := NewOffice(DefaultLibreOfficePath)
	document, _ := office.LoadDocument(SampleDocument)
	rectangles := document.GetPartPageRectangles()
	if len(rectangles) != 2 {
		t.Fail()
	}
}

func TestGetParts(t *testing.T) {
	office, _ := NewOffice(DefaultLibreOfficePath)
	document, _ := office.LoadDocument(SampleDocument)
	parts := document.GetParts()
	if parts != 2 {
		t.Fail()
	}
}

func TestGetTileMode(t *testing.T) {
	office, _ := NewOffice(DefaultLibreOfficePath)
	document, _ := office.LoadDocument(SampleDocument)
	mode := document.GetTileMode()
	if mode != RGBATilemode && mode != BGRATilemode {
		t.Fail()
	}
}

func TestGetViews(t *testing.T) {
	office, _ := NewOffice(DefaultLibreOfficePath)
	document, _ := office.LoadDocument(SampleDocument)
	views := document.GetViews()
	if views != 1 {
		t.Fail()
	}
}

func TestGetType(t *testing.T) {
	office, _ := NewOffice(DefaultLibreOfficePath)
	document, _ := office.LoadDocument(SampleDocument)
	documentType := document.GetType()
	if documentType != TextDocument {
		t.Fail()
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2018 The Kubernetes Authors.

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 kubelet

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/pkg/errors"

	"k8s.io/klog/v2"
	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
	"k8s.io/kubernetes/cmd/kubeadm/app/constants"
	"k8s.io/kubernetes/cmd/kubeadm/app/images"
	kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
)

type kubeletFlagsOpts struct {
	nodeRegOpts              *kubeadmapi.NodeRegistrationOptions
	pauseImage               string
	registerTaintsUsingFlags bool
}

// GetNodeNameAndHostname obtains the name for this Node using the following precedence
// (from lower to higher):
// - actual hostname
// - NodeRegistrationOptions.Name (same as "--node-name" passed to "kubeadm init/join")
// - "hostname-overide" flag in NodeRegistrationOptions.KubeletExtraArgs
// It also returns the hostname or an error if getting the hostname failed.
func GetNodeNameAndHostname(cfg *kubeadmapi.NodeRegistrationOptions) (string, string, error) {
	hostname, err := kubeadmutil.GetHostname("")
	nodeName := hostname
	if cfg.Name != "" {
		nodeName = cfg.Name
	}
	if name, ok := cfg.KubeletExtraArgs["hostname-override"]; ok {
		nodeName = name
	}
	return nodeName, hostname, err
}

// WriteKubeletDynamicEnvFile writes an environment file with dynamic flags to the kubelet.
// Used at "kubeadm init" and "kubeadm join" time.
func WriteKubeletDynamicEnvFile(cfg *kubeadmapi.ClusterConfiguration, nodeReg *kubeadmapi.NodeRegistrationOptions, registerTaintsUsingFlags bool, kubeletDir string) error {
	flagOpts := kubeletFlagsOpts{
		nodeRegOpts:              nodeReg,
		pauseImage:               images.GetPauseImage(cfg),
		registerTaintsUsingFlags: registerTaintsUsingFlags,
	}
	stringMap := buildKubeletArgMap(flagOpts)
	argList := kubeadmutil.BuildArgumentListFromMap(stringMap, nodeReg.KubeletExtraArgs)
	envFileContent := fmt.Sprintf("%s=%q\n", constants.KubeletEnvFileVariableName, strings.Join(argList, " "))

	return writeKubeletFlagBytesToDisk([]byte(envFileContent), kubeletDir)
}

//buildKubeletArgMapCommon takes a kubeletFlagsOpts object and builds based on that a string-string map with flags
//that are common to both Linux and Windows
func buildKubeletArgMapCommon(opts kubeletFlagsOpts) map[string]string {
	kubeletFlags := map[string]string{}

	if opts.nodeRegOpts.CRISocket == constants.DefaultDockerCRISocket {
		// These flags should only be set when running docker
		kubeletFlags["network-plugin"] = "cni"
		if opts.pauseImage != "" {
			kubeletFlags["pod-infra-container-image"] = opts.pauseImage
		}
	} else {
		kubeletFlags["container-runtime"] = "remote"
		kubeletFlags["container-runtime-endpoint"] = opts.nodeRegOpts.CRISocket
	}

	if opts.registerTaintsUsingFlags && opts.nodeRegOpts.Taints != nil && len(opts.nodeRegOpts.Taints) > 0 {
		taintStrs := []string{}
		for _, taint := range opts.nodeRegOpts.Taints {
			taintStrs = append(taintStrs, taint.ToString())
		}

		kubeletFlags["register-with-taints"] = strings.Join(taintStrs, ",")
	}

	// Pass the "--hostname-override" flag to the kubelet only if it's different from the hostname
	nodeName, hostname, err := GetNodeNameAndHostname(opts.nodeRegOpts)
	if err != nil {
		klog.Warning(err)
	}
	if nodeName != hostname {
		klog.V(1).Infof("setting kubelet hostname-override to %q", nodeName)
		kubeletFlags["hostname-override"] = nodeName
	}

	return kubeletFlags
}

// writeKubeletFlagBytesToDisk writes a byte slice down to disk at the specific location of the kubelet flag overrides file
func writeKubeletFlagBytesToDisk(b []byte, kubeletDir string) error {
	kubeletEnvFilePath := filepath.Join(kubeletDir, constants.KubeletEnvFileName)
	fmt.Printf("[kubelet-start] Writing kubelet environment file with flags to file %q\n", kubeletEnvFilePath)

	// creates target folder if not already exists
	if err := os.MkdirAll(kubeletDir, 0700); err != nil {
		return errors.Wrapf(err, "failed to create directory %q", kubeletDir)
	}
	if err := ioutil.WriteFile(kubeletEnvFilePath, b, 0644); err != nil {
		return errors.Wrapf(err, "failed to write kubelet configuration to the file %q", kubeletEnvFilePath)
	}
	return nil
}

// buildKubeletArgMap takes a kubeletFlagsOpts object and builds based on that a string-string map with flags
// that should be given to the local kubelet daemon.
func buildKubeletArgMap(opts kubeletFlagsOpts) map[string]string {
	return buildKubeletArgMapCommon(opts)
}
<commit_msg>kubeadm: pass pod-infra-container-image for all CRs<commit_after>/*
Copyright 2018 The Kubernetes Authors.

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 kubelet

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/pkg/errors"

	"k8s.io/klog/v2"
	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
	"k8s.io/kubernetes/cmd/kubeadm/app/constants"
	"k8s.io/kubernetes/cmd/kubeadm/app/images"
	kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
)

type kubeletFlagsOpts struct {
	nodeRegOpts              *kubeadmapi.NodeRegistrationOptions
	pauseImage               string
	registerTaintsUsingFlags bool
}

// GetNodeNameAndHostname obtains the name for this Node using the following precedence
// (from lower to higher):
// - actual hostname
// - NodeRegistrationOptions.Name (same as "--node-name" passed to "kubeadm init/join")
// - "hostname-overide" flag in NodeRegistrationOptions.KubeletExtraArgs
// It also returns the hostname or an error if getting the hostname failed.
func GetNodeNameAndHostname(cfg *kubeadmapi.NodeRegistrationOptions) (string, string, error) {
	hostname, err := kubeadmutil.GetHostname("")
	nodeName := hostname
	if cfg.Name != "" {
		nodeName = cfg.Name
	}
	if name, ok := cfg.KubeletExtraArgs["hostname-override"]; ok {
		nodeName = name
	}
	return nodeName, hostname, err
}

// WriteKubeletDynamicEnvFile writes an environment file with dynamic flags to the kubelet.
// Used at "kubeadm init" and "kubeadm join" time.
func WriteKubeletDynamicEnvFile(cfg *kubeadmapi.ClusterConfiguration, nodeReg *kubeadmapi.NodeRegistrationOptions, registerTaintsUsingFlags bool, kubeletDir string) error {
	flagOpts := kubeletFlagsOpts{
		nodeRegOpts:              nodeReg,
		pauseImage:               images.GetPauseImage(cfg),
		registerTaintsUsingFlags: registerTaintsUsingFlags,
	}
	stringMap := buildKubeletArgMap(flagOpts)
	argList := kubeadmutil.BuildArgumentListFromMap(stringMap, nodeReg.KubeletExtraArgs)
	envFileContent := fmt.Sprintf("%s=%q\n", constants.KubeletEnvFileVariableName, strings.Join(argList, " "))

	return writeKubeletFlagBytesToDisk([]byte(envFileContent), kubeletDir)
}

//buildKubeletArgMapCommon takes a kubeletFlagsOpts object and builds based on that a string-string map with flags
//that are common to both Linux and Windows
func buildKubeletArgMapCommon(opts kubeletFlagsOpts) map[string]string {
	kubeletFlags := map[string]string{}

	if opts.nodeRegOpts.CRISocket == constants.DefaultDockerCRISocket {
		// These flags should only be set when running docker
		kubeletFlags["network-plugin"] = "cni"
	} else {
		kubeletFlags["container-runtime"] = "remote"
		kubeletFlags["container-runtime-endpoint"] = opts.nodeRegOpts.CRISocket
	}

	// This flag passes the pod infra container image (e.g. "pause" image) to the kubelet
	// and prevents its garbage collection
	if opts.pauseImage != "" {
		kubeletFlags["pod-infra-container-image"] = opts.pauseImage
	}

	if opts.registerTaintsUsingFlags && opts.nodeRegOpts.Taints != nil && len(opts.nodeRegOpts.Taints) > 0 {
		taintStrs := []string{}
		for _, taint := range opts.nodeRegOpts.Taints {
			taintStrs = append(taintStrs, taint.ToString())
		}

		kubeletFlags["register-with-taints"] = strings.Join(taintStrs, ",")
	}

	// Pass the "--hostname-override" flag to the kubelet only if it's different from the hostname
	nodeName, hostname, err := GetNodeNameAndHostname(opts.nodeRegOpts)
	if err != nil {
		klog.Warning(err)
	}
	if nodeName != hostname {
		klog.V(1).Infof("setting kubelet hostname-override to %q", nodeName)
		kubeletFlags["hostname-override"] = nodeName
	}

	return kubeletFlags
}

// writeKubeletFlagBytesToDisk writes a byte slice down to disk at the specific location of the kubelet flag overrides file
func writeKubeletFlagBytesToDisk(b []byte, kubeletDir string) error {
	kubeletEnvFilePath := filepath.Join(kubeletDir, constants.KubeletEnvFileName)
	fmt.Printf("[kubelet-start] Writing kubelet environment file with flags to file %q\n", kubeletEnvFilePath)

	// creates target folder if not already exists
	if err := os.MkdirAll(kubeletDir, 0700); err != nil {
		return errors.Wrapf(err, "failed to create directory %q", kubeletDir)
	}
	if err := ioutil.WriteFile(kubeletEnvFilePath, b, 0644); err != nil {
		return errors.Wrapf(err, "failed to write kubelet configuration to the file %q", kubeletEnvFilePath)
	}
	return nil
}

// buildKubeletArgMap takes a kubeletFlagsOpts object and builds based on that a string-string map with flags
// that should be given to the local kubelet daemon.
func buildKubeletArgMap(opts kubeletFlagsOpts) map[string]string {
	return buildKubeletArgMapCommon(opts)
}
<|endoftext|>


<commit_before>package extract_strings

import (
	"fmt"
	"os"
	"regexp"
	"strconv"
	"strings"

	"go/ast"
	"go/build"
	"go/parser"
	"go/token"

	"path/filepath"

	"encoding/json"
	"io/ioutil"

	"github.com/maximilien/i18n4cf/cmds"
	"github.com/maximilien/i18n4cf/common"
)

type extractStrings struct {
	options cmds.Options

	i18nFilename string
	poFilename   string

	Filename      string
	OutputDirname string

	ExtractedStrings map[string]common.StringInfo
	FilteredStrings  map[string]string
	FilteredRegexps  []*regexp.Regexp

	TotalStringsDir int
	TotalStrings    int
	TotalFiles      int

	IgnoreRegexp *regexp.Regexp
}

func NewExtractStrings(options cmds.Options) extractStrings {
	var compiledRegexp *regexp.Regexp
	if options.IgnoreRegexpFlag != "" {
		compiledReg, err := regexp.Compile(options.IgnoreRegexpFlag)
		if err != nil {
			fmt.Println("WARNING compiling ignore-regexp:", err)
		}
		compiledRegexp = compiledReg
	}

	return extractStrings{options: options,
		Filename:         "extracted_strings.json",
		OutputDirname:    options.OutputDirFlag,
		ExtractedStrings: nil,
		FilteredStrings:  nil,
		FilteredRegexps:  nil,
		TotalStringsDir:  0,
		TotalStrings:     0,
		TotalFiles:       0,
		IgnoreRegexp:     compiledRegexp}
}

func (es *extractStrings) Options() cmds.Options {
	return es.options
}

func (es *extractStrings) Println(a ...interface{}) (int, error) {
	if es.options.VerboseFlag {
		return fmt.Println(a...)
	}

	return 0, nil
}

func (es *extractStrings) Printf(msg string, a ...interface{}) (int, error) {
	if es.options.VerboseFlag {
		return fmt.Printf(msg, a...)
	}

	return 0, nil
}

func (es *extractStrings) Run() error {
	if es.options.FilenameFlag != "" {
		return es.InspectFile(es.options.FilenameFlag)
	} else {
		err := es.InspectDir(es.options.DirnameFlag, es.options.RecurseFlag)
		if err != nil {
			es.Println("gi18n: could not extract strings from directory:", es.options.DirnameFlag)
			return err
		}
		es.Println()
		es.Println("Total files parsed:", es.TotalFiles)
		es.Println("Total extracted strings:", es.TotalStrings)
	}
	return nil
}

func (es *extractStrings) InspectFile(filename string) error {
	es.Println("gi18n: extracting strings from file:", filename)
	if es.options.DryRunFlag {
		es.Println("WARNING running in -dry-run mode")
	}

	es.ExtractedStrings = make(map[string]common.StringInfo)
	es.FilteredStrings = make(map[string]string)
	es.FilteredRegexps = []*regexp.Regexp{}

	es.setFilename(filename)
	es.setI18nFilename(filename)
	es.setPoFilename(filename)

	fset := token.NewFileSet()

	var absFilePath = filename
	if !filepath.IsAbs(absFilePath) {
		absFilePath = filepath.Join(os.Getenv("PWD"), absFilePath)
	}

	fileInfo, err := common.GetAbsFileInfo(absFilePath)
	if err != nil {
		es.Println(err)
	}

	if strings.HasPrefix(fileInfo.Name(), ".") {
		es.Println("WARNING ignoring file:", absFilePath)
		return nil
	}

	astFile, err := parser.ParseFile(fset, absFilePath, nil, parser.ParseComments|parser.AllErrors)
	if err != nil {
		es.Println(err)
		return err
	}

	err = es.loadExcludedStrings()
	if err != nil {
		es.Println(err)
		return err
	}
	es.Println(fmt.Sprintf("Loaded %d excluded strings", len(es.FilteredStrings)))

	err = es.loadExcludedRegexps()
	if err != nil {
		es.Println(err)
		return err
	}
	es.Println(fmt.Sprintf("Loaded %d excluded regexps", len(es.FilteredRegexps)))

	es.excludeImports(astFile)

	es.extractString(astFile, fset)
	es.TotalStringsDir += len(es.ExtractedStrings)
	es.TotalStrings += len(es.ExtractedStrings)
	es.TotalFiles += 1

	es.Printf("Extracted %d strings from file: %s\n", len(es.ExtractedStrings), absFilePath)

	var outputDirname = es.OutputDirname
	if es.options.OutputDirFlag != "" {
		if es.options.OutputMatchImportFlag {
			outputDirname, err = es.findImportPath(absFilePath)
			if err != nil {
				es.Println(err)
				return err
			}
		} else if es.options.OutputMatchPackageFlag {
			outputDirname, err = es.findPackagePath(absFilePath)
			if err != nil {
				es.Println(err)
				return err
			}
		}
	} else {
		outputDirname, err = common.FindFilePath(absFilePath)
		if err != nil {
			es.Println(err)
			return err
		}
	}

	if es.options.MetaFlag {
		err = es.saveExtractedStrings(outputDirname)
		if err != nil {
			es.Println(err)
			return err
		}
	}

	err = common.SaveStrings(es, es.ExtractedStrings, outputDirname, es.i18nFilename)
	if err != nil {
		es.Println(err)
		return err
	}

	if es.options.PoFlag {
		err = common.SaveStringsInPo(es, es.ExtractedStrings, outputDirname, es.poFilename)
		if err != nil {
			es.Println(err)
			return err
		}
	}

	return nil
}

func (es *extractStrings) InspectDir(dirName string, recursive bool) error {
	es.Printf("gi18n: inspecting dir %s, recursive: %t\n", dirName, recursive)
	es.Println()

	fset := token.NewFileSet()
	es.TotalStringsDir = 0

	packages, err := parser.ParseDir(fset, dirName, nil, parser.ParseComments)
	if err != nil {
		es.Println(err)
		return err
	}

	for k, pkg := range packages {
		es.Println("Extracting strings in package:", k)
		for fileName, _ := range pkg.Files {
			if es.IgnoreRegexp != nil && es.IgnoreRegexp.MatchString(fileName) {
				es.Println("Using ignore-regexp:", es.options.IgnoreRegexpFlag)
				continue
			} else {
				es.Println("No match for ignore-regexp:", es.options.IgnoreRegexpFlag)
			}

			if strings.HasSuffix(fileName, ".go") {
				err = es.InspectFile(fileName)
				if err != nil {
					es.Println(err)
				}
			}
		}
	}
	es.Printf("Extracted total of %d strings\n\n", es.TotalStringsDir)

	if recursive {
		fileInfos, _ := ioutil.ReadDir(dirName)
		for _, fileInfo := range fileInfos {
			if fileInfo.IsDir() && !strings.HasPrefix(fileInfo.Name(), ".") {
				err = es.InspectDir(filepath.Join(dirName, fileInfo.Name()), recursive)
				if err != nil {
					es.Println(err)
				}
			}
		}
	}

	return nil
}

func (es *extractStrings) findImportPath(filename string) (string, error) {
	path := es.OutputDirname

	filePath, err := common.FindFilePath(filename)
	if err != nil {
		fmt.Println("ERROR opening file", err)
		return "", err
	}

	pkg, err := build.ImportDir(filePath, 0)
	srcPath := "src" + string(os.PathSeparator)
	if strings.HasPrefix(pkg.Dir, srcPath) {
		path = filepath.Join(path, pkg.Dir[len(srcPath):len(pkg.Dir)])
	}

	return path, nil
}

func (es *extractStrings) findPackagePath(filename string) (string, error) {
	path := es.OutputDirname

	filePath, err := common.FindFilePath(filename)
	if err != nil {
		fmt.Println("ERROR opening file", err)
		return "", err
	}

	pkg, err := build.ImportDir(filePath, 0)
	if err != nil {
		fmt.Println("ERROR opening file", err)
		return "", err
	}

	return filepath.Join(path, pkg.Name), nil
}

func (es *extractStrings) saveExtractedStrings(outputDirname string) error {
	if len(es.ExtractedStrings) != 0 {
		es.Println("Saving extracted strings to file:", es.Filename)
	}

	if !es.options.DryRunFlag {
		err := common.CreateOutputDirsIfNeeded(outputDirname)
		if err != nil {
			es.Println(err)
			return err
		}
	}

	stringInfos := make([]common.StringInfo, 0)
	for _, stringInfo := range es.ExtractedStrings {
		stringInfo.Filename = strings.Split(es.Filename, ".extracted.json")[0]

		stringInfos = append(stringInfos, stringInfo)
	}

	jsonData, err := json.MarshalIndent(stringInfos, "", "   ")
	if err != nil {
		es.Println(err)
		return err
	}

	if !es.options.DryRunFlag && len(stringInfos) != 0 {
		file, err := os.Create(filepath.Join(outputDirname, es.Filename[strings.LastIndex(es.Filename, string(os.PathSeparator))+1:len(es.Filename)]))
		defer file.Close()
		if err != nil {
			es.Println(err)
			return err
		}

		file.Write(jsonData)
	}

	return nil
}

func (es *extractStrings) setFilename(filename string) {
	es.Filename = filename + ".extracted.json"
}

func (es *extractStrings) setI18nFilename(filename string) {
	es.i18nFilename = filename + ".en.json"
}

func (es *extractStrings) setPoFilename(filename string) {
	es.poFilename = filename + ".en.po"
}

func (es *extractStrings) loadExcludedStrings() error {
	_, err := os.Stat(es.options.ExcludedFilenameFlag)
	if os.IsNotExist(err) {
		es.Println("Could not find:", es.options.ExcludedFilenameFlag)
		return nil
	}

	es.Println("Excluding strings in file:", es.options.ExcludedFilenameFlag)

	content, err := ioutil.ReadFile(es.options.ExcludedFilenameFlag)
	if err != nil {
		fmt.Print(err)
		return err
	}

	var excludedStrings common.ExcludedStrings
	err = json.Unmarshal(content, &excludedStrings)
	if err != nil {
		fmt.Print(err)
		return err
	}

	for i := range excludedStrings.ExcludedStrings {
		es.FilteredStrings[excludedStrings.ExcludedStrings[i]] = excludedStrings.ExcludedStrings[i]
	}

	return nil
}

func (es *extractStrings) loadExcludedRegexps() error {
	_, err := os.Stat(es.options.ExcludedFilenameFlag)
	if os.IsNotExist(err) {
		es.Println("Could not find:", es.options.ExcludedFilenameFlag)
		return nil
	}

	es.Println("Excluding regexps in file:", es.options.ExcludedFilenameFlag)

	content, err := ioutil.ReadFile(es.options.ExcludedFilenameFlag)
	if err != nil {
		fmt.Print(err)
		return err
	}

	var excludedRegexps common.ExcludedStrings
	err = json.Unmarshal(content, &excludedRegexps)
	if err != nil {
		fmt.Print(err)
		return err
	}

	for _, regexpString := range excludedRegexps.ExcludedRegexps {
		compiledRegexp, err := regexp.Compile(regexpString)
		if err != nil {
			fmt.Println("WARNING error compiling regexp:", regexpString)
		}

		es.FilteredRegexps = append(es.FilteredRegexps, compiledRegexp)
	}

	return nil
}

func (es *extractStrings) extractString(f *ast.File, fset *token.FileSet) error {
	ast.Inspect(f, func(n ast.Node) bool {
		var s string
		switch x := n.(type) {
		case *ast.BasicLit:
			s, _ = strconv.Unquote(x.Value)
			if len(s) > 0 && x.Kind == token.STRING && s != "\t" && s != "\n" && s != " " && !es.filter(s) { //TODO: fix to remove these: s != "\\t" && s != "\\n" && s != " "
				position := fset.Position(n.Pos())
				stringInfo := common.StringInfo{Value: s,
					Filename: position.Filename,
					Offset:   position.Offset,
					Line:     position.Line,
					Column:   position.Column}
				es.ExtractedStrings[s] = stringInfo
			}
		}
		return true
	})

	return nil
}

func (es *extractStrings) excludeImports(astFile *ast.File) {
	for i := range astFile.Imports {
		importString, _ := strconv.Unquote(astFile.Imports[i].Path.Value)
		es.FilteredStrings[importString] = importString
	}

}

func (es *extractStrings) filter(aString string) bool {
	for i := range common.BLANKS {
		if aString == common.BLANKS[i] {
			return true
		}
	}

	if es.FilteredStrings[aString] != "" {
		return true
	}

	for _, compiledRegexp := range es.FilteredRegexps {
		if compiledRegexp.MatchString(aString) {
			return true
		}
	}

	return false
}
<commit_msg>More idiomatic way of checking for a key in a map<commit_after>package extract_strings

import (
	"fmt"
	"os"
	"regexp"
	"strconv"
	"strings"

	"go/ast"
	"go/build"
	"go/parser"
	"go/token"

	"path/filepath"

	"encoding/json"
	"io/ioutil"

	"github.com/maximilien/i18n4cf/cmds"
	"github.com/maximilien/i18n4cf/common"
)

type extractStrings struct {
	options cmds.Options

	i18nFilename string
	poFilename   string

	Filename      string
	OutputDirname string

	ExtractedStrings map[string]common.StringInfo
	FilteredStrings  map[string]string
	FilteredRegexps  []*regexp.Regexp

	TotalStringsDir int
	TotalStrings    int
	TotalFiles      int

	IgnoreRegexp *regexp.Regexp
}

func NewExtractStrings(options cmds.Options) extractStrings {
	var compiledRegexp *regexp.Regexp
	if options.IgnoreRegexpFlag != "" {
		compiledReg, err := regexp.Compile(options.IgnoreRegexpFlag)
		if err != nil {
			fmt.Println("WARNING compiling ignore-regexp:", err)
		}
		compiledRegexp = compiledReg
	}

	return extractStrings{options: options,
		Filename:         "extracted_strings.json",
		OutputDirname:    options.OutputDirFlag,
		ExtractedStrings: nil,
		FilteredStrings:  nil,
		FilteredRegexps:  nil,
		TotalStringsDir:  0,
		TotalStrings:     0,
		TotalFiles:       0,
		IgnoreRegexp:     compiledRegexp}
}

func (es *extractStrings) Options() cmds.Options {
	return es.options
}

func (es *extractStrings) Println(a ...interface{}) (int, error) {
	if es.options.VerboseFlag {
		return fmt.Println(a...)
	}

	return 0, nil
}

func (es *extractStrings) Printf(msg string, a ...interface{}) (int, error) {
	if es.options.VerboseFlag {
		return fmt.Printf(msg, a...)
	}

	return 0, nil
}

func (es *extractStrings) Run() error {
	if es.options.FilenameFlag != "" {
		return es.InspectFile(es.options.FilenameFlag)
	} else {
		err := es.InspectDir(es.options.DirnameFlag, es.options.RecurseFlag)
		if err != nil {
			es.Println("gi18n: could not extract strings from directory:", es.options.DirnameFlag)
			return err
		}
		es.Println()
		es.Println("Total files parsed:", es.TotalFiles)
		es.Println("Total extracted strings:", es.TotalStrings)
	}
	return nil
}

func (es *extractStrings) InspectFile(filename string) error {
	es.Println("gi18n: extracting strings from file:", filename)
	if es.options.DryRunFlag {
		es.Println("WARNING running in -dry-run mode")
	}

	es.ExtractedStrings = make(map[string]common.StringInfo)
	es.FilteredStrings = make(map[string]string)
	es.FilteredRegexps = []*regexp.Regexp{}

	es.setFilename(filename)
	es.setI18nFilename(filename)
	es.setPoFilename(filename)

	fset := token.NewFileSet()

	var absFilePath = filename
	if !filepath.IsAbs(absFilePath) {
		absFilePath = filepath.Join(os.Getenv("PWD"), absFilePath)
	}

	fileInfo, err := common.GetAbsFileInfo(absFilePath)
	if err != nil {
		es.Println(err)
	}

	if strings.HasPrefix(fileInfo.Name(), ".") {
		es.Println("WARNING ignoring file:", absFilePath)
		return nil
	}

	astFile, err := parser.ParseFile(fset, absFilePath, nil, parser.ParseComments|parser.AllErrors)
	if err != nil {
		es.Println(err)
		return err
	}

	err = es.loadExcludedStrings()
	if err != nil {
		es.Println(err)
		return err
	}
	es.Println(fmt.Sprintf("Loaded %d excluded strings", len(es.FilteredStrings)))

	err = es.loadExcludedRegexps()
	if err != nil {
		es.Println(err)
		return err
	}
	es.Println(fmt.Sprintf("Loaded %d excluded regexps", len(es.FilteredRegexps)))

	es.excludeImports(astFile)

	es.extractString(astFile, fset)
	es.TotalStringsDir += len(es.ExtractedStrings)
	es.TotalStrings += len(es.ExtractedStrings)
	es.TotalFiles += 1

	es.Printf("Extracted %d strings from file: %s\n", len(es.ExtractedStrings), absFilePath)

	var outputDirname = es.OutputDirname
	if es.options.OutputDirFlag != "" {
		if es.options.OutputMatchImportFlag {
			outputDirname, err = es.findImportPath(absFilePath)
			if err != nil {
				es.Println(err)
				return err
			}
		} else if es.options.OutputMatchPackageFlag {
			outputDirname, err = es.findPackagePath(absFilePath)
			if err != nil {
				es.Println(err)
				return err
			}
		}
	} else {
		outputDirname, err = common.FindFilePath(absFilePath)
		if err != nil {
			es.Println(err)
			return err
		}
	}

	if es.options.MetaFlag {
		err = es.saveExtractedStrings(outputDirname)
		if err != nil {
			es.Println(err)
			return err
		}
	}

	err = common.SaveStrings(es, es.ExtractedStrings, outputDirname, es.i18nFilename)
	if err != nil {
		es.Println(err)
		return err
	}

	if es.options.PoFlag {
		err = common.SaveStringsInPo(es, es.ExtractedStrings, outputDirname, es.poFilename)
		if err != nil {
			es.Println(err)
			return err
		}
	}

	return nil
}

func (es *extractStrings) InspectDir(dirName string, recursive bool) error {
	es.Printf("gi18n: inspecting dir %s, recursive: %t\n", dirName, recursive)
	es.Println()

	fset := token.NewFileSet()
	es.TotalStringsDir = 0

	packages, err := parser.ParseDir(fset, dirName, nil, parser.ParseComments)
	if err != nil {
		es.Println(err)
		return err
	}

	for k, pkg := range packages {
		es.Println("Extracting strings in package:", k)
		for fileName, _ := range pkg.Files {
			if es.IgnoreRegexp != nil && es.IgnoreRegexp.MatchString(fileName) {
				es.Println("Using ignore-regexp:", es.options.IgnoreRegexpFlag)
				continue
			} else {
				es.Println("No match for ignore-regexp:", es.options.IgnoreRegexpFlag)
			}

			if strings.HasSuffix(fileName, ".go") {
				err = es.InspectFile(fileName)
				if err != nil {
					es.Println(err)
				}
			}
		}
	}
	es.Printf("Extracted total of %d strings\n\n", es.TotalStringsDir)

	if recursive {
		fileInfos, _ := ioutil.ReadDir(dirName)
		for _, fileInfo := range fileInfos {
			if fileInfo.IsDir() && !strings.HasPrefix(fileInfo.Name(), ".") {
				err = es.InspectDir(filepath.Join(dirName, fileInfo.Name()), recursive)
				if err != nil {
					es.Println(err)
				}
			}
		}
	}

	return nil
}

func (es *extractStrings) findImportPath(filename string) (string, error) {
	path := es.OutputDirname

	filePath, err := common.FindFilePath(filename)
	if err != nil {
		fmt.Println("ERROR opening file", err)
		return "", err
	}

	pkg, err := build.ImportDir(filePath, 0)
	srcPath := "src" + string(os.PathSeparator)
	if strings.HasPrefix(pkg.Dir, srcPath) {
		path = filepath.Join(path, pkg.Dir[len(srcPath):len(pkg.Dir)])
	}

	return path, nil
}

func (es *extractStrings) findPackagePath(filename string) (string, error) {
	path := es.OutputDirname

	filePath, err := common.FindFilePath(filename)
	if err != nil {
		fmt.Println("ERROR opening file", err)
		return "", err
	}

	pkg, err := build.ImportDir(filePath, 0)
	if err != nil {
		fmt.Println("ERROR opening file", err)
		return "", err
	}

	return filepath.Join(path, pkg.Name), nil
}

func (es *extractStrings) saveExtractedStrings(outputDirname string) error {
	if len(es.ExtractedStrings) != 0 {
		es.Println("Saving extracted strings to file:", es.Filename)
	}

	if !es.options.DryRunFlag {
		err := common.CreateOutputDirsIfNeeded(outputDirname)
		if err != nil {
			es.Println(err)
			return err
		}
	}

	stringInfos := make([]common.StringInfo, 0)
	for _, stringInfo := range es.ExtractedStrings {
		stringInfo.Filename = strings.Split(es.Filename, ".extracted.json")[0]

		stringInfos = append(stringInfos, stringInfo)
	}

	jsonData, err := json.MarshalIndent(stringInfos, "", "   ")
	if err != nil {
		es.Println(err)
		return err
	}

	if !es.options.DryRunFlag && len(stringInfos) != 0 {
		file, err := os.Create(filepath.Join(outputDirname, es.Filename[strings.LastIndex(es.Filename, string(os.PathSeparator))+1:len(es.Filename)]))
		defer file.Close()
		if err != nil {
			es.Println(err)
			return err
		}

		file.Write(jsonData)
	}

	return nil
}

func (es *extractStrings) setFilename(filename string) {
	es.Filename = filename + ".extracted.json"
}

func (es *extractStrings) setI18nFilename(filename string) {
	es.i18nFilename = filename + ".en.json"
}

func (es *extractStrings) setPoFilename(filename string) {
	es.poFilename = filename + ".en.po"
}

func (es *extractStrings) loadExcludedStrings() error {
	_, err := os.Stat(es.options.ExcludedFilenameFlag)
	if os.IsNotExist(err) {
		es.Println("Could not find:", es.options.ExcludedFilenameFlag)
		return nil
	}

	es.Println("Excluding strings in file:", es.options.ExcludedFilenameFlag)

	content, err := ioutil.ReadFile(es.options.ExcludedFilenameFlag)
	if err != nil {
		fmt.Print(err)
		return err
	}

	var excludedStrings common.ExcludedStrings
	err = json.Unmarshal(content, &excludedStrings)
	if err != nil {
		fmt.Print(err)
		return err
	}

	for i := range excludedStrings.ExcludedStrings {
		es.FilteredStrings[excludedStrings.ExcludedStrings[i]] = excludedStrings.ExcludedStrings[i]
	}

	return nil
}

func (es *extractStrings) loadExcludedRegexps() error {
	_, err := os.Stat(es.options.ExcludedFilenameFlag)
	if os.IsNotExist(err) {
		es.Println("Could not find:", es.options.ExcludedFilenameFlag)
		return nil
	}

	es.Println("Excluding regexps in file:", es.options.ExcludedFilenameFlag)

	content, err := ioutil.ReadFile(es.options.ExcludedFilenameFlag)
	if err != nil {
		fmt.Print(err)
		return err
	}

	var excludedRegexps common.ExcludedStrings
	err = json.Unmarshal(content, &excludedRegexps)
	if err != nil {
		fmt.Print(err)
		return err
	}

	for _, regexpString := range excludedRegexps.ExcludedRegexps {
		compiledRegexp, err := regexp.Compile(regexpString)
		if err != nil {
			fmt.Println("WARNING error compiling regexp:", regexpString)
		}

		es.FilteredRegexps = append(es.FilteredRegexps, compiledRegexp)
	}

	return nil
}

func (es *extractStrings) extractString(f *ast.File, fset *token.FileSet) error {
	ast.Inspect(f, func(n ast.Node) bool {
		var s string
		switch x := n.(type) {
		case *ast.BasicLit:
			s, _ = strconv.Unquote(x.Value)
			if len(s) > 0 && x.Kind == token.STRING && s != "\t" && s != "\n" && s != " " && !es.filter(s) { //TODO: fix to remove these: s != "\\t" && s != "\\n" && s != " "
				position := fset.Position(n.Pos())
				stringInfo := common.StringInfo{Value: s,
					Filename: position.Filename,
					Offset:   position.Offset,
					Line:     position.Line,
					Column:   position.Column}
				es.ExtractedStrings[s] = stringInfo
			}
		}
		return true
	})

	return nil
}

func (es *extractStrings) excludeImports(astFile *ast.File) {
	for i := range astFile.Imports {
		importString, _ := strconv.Unquote(astFile.Imports[i].Path.Value)
		es.FilteredStrings[importString] = importString
	}

}

func (es *extractStrings) filter(aString string) bool {
	for i := range common.BLANKS {
		if aString == common.BLANKS[i] {
			return true
		}
	}

	if _, ok := es.FilteredStrings[aString]; ok {
		return true
	}

	for _, compiledRegexp := range es.FilteredRegexps {
		if compiledRegexp.MatchString(aString) {
			return true
		}
	}

	return false
}
<|endoftext|>


<commit_before>// Package http provides a http server with features; acme, cors, etc
package http

import (
	"crypto/tls"
	"net"
	"net/http"
	"os"
	"sync"

	"github.com/gorilla/handlers"
	"github.com/micro/go-micro/api/server"
	"github.com/micro/go-micro/util/log"
)

type httpServer struct {
	mux  *http.ServeMux
	opts server.Options

	mtx     sync.RWMutex
	address string
	exit    chan chan error
}

func NewServer(address string) server.Server {
	return &httpServer{
		opts:    server.Options{},
		mux:     http.NewServeMux(),
		address: address,
		exit:    make(chan chan error),
	}
}

func (s *httpServer) Address() string {
	s.mtx.RLock()
	defer s.mtx.RUnlock()
	return s.address
}

func (s *httpServer) Init(opts ...server.Option) error {
	for _, o := range opts {
		o(&s.opts)
	}
	return nil
}

func (s *httpServer) Handle(path string, handler http.Handler) {
	s.mux.Handle(path, handlers.CombinedLoggingHandler(os.Stdout, handler))
}

func (s *httpServer) Start() error {
	var l net.Listener
	var err error

	if s.opts.EnableACME {
		// should we check the address to make sure its using :443?
		l, err = s.opts.ACMEProvider.NewListener(s.opts.ACMEHosts...)
	} else if s.opts.EnableTLS && s.opts.TLSConfig != nil {
		l, err = tls.Listen("tcp", s.address, s.opts.TLSConfig)
	} else {
		// otherwise plain listen
		l, err = net.Listen("tcp", s.address)
	}
	if err != nil {
		return err
	}

	log.Logf("HTTP API Listening on %s", l.Addr().String())

	s.mtx.Lock()
	s.address = l.Addr().String()
	s.mtx.Unlock()

	go func() {
		if err := http.Serve(l, s.mux); err != nil {
			// temporary fix
			//log.Fatal(err)
		}
	}()

	go func() {
		ch := <-s.exit
		ch <- l.Close()
	}()

	return nil
}

func (s *httpServer) Stop() error {
	ch := make(chan error)
	s.exit <- ch
	return <-ch
}

func (s *httpServer) String() string {
	return "http"
}
<commit_msg>Add nil check for acme provider<commit_after>// Package http provides a http server with features; acme, cors, etc
package http

import (
	"crypto/tls"
	"net"
	"net/http"
	"os"
	"sync"

	"github.com/gorilla/handlers"
	"github.com/micro/go-micro/api/server"
	"github.com/micro/go-micro/util/log"
)

type httpServer struct {
	mux  *http.ServeMux
	opts server.Options

	mtx     sync.RWMutex
	address string
	exit    chan chan error
}

func NewServer(address string) server.Server {
	return &httpServer{
		opts:    server.Options{},
		mux:     http.NewServeMux(),
		address: address,
		exit:    make(chan chan error),
	}
}

func (s *httpServer) Address() string {
	s.mtx.RLock()
	defer s.mtx.RUnlock()
	return s.address
}

func (s *httpServer) Init(opts ...server.Option) error {
	for _, o := range opts {
		o(&s.opts)
	}
	return nil
}

func (s *httpServer) Handle(path string, handler http.Handler) {
	s.mux.Handle(path, handlers.CombinedLoggingHandler(os.Stdout, handler))
}

func (s *httpServer) Start() error {
	var l net.Listener
	var err error

	if s.opts.EnableACME && s.opts.ACMEProvider != nil {
		// should we check the address to make sure its using :443?
		l, err = s.opts.ACMEProvider.NewListener(s.opts.ACMEHosts...)
	} else if s.opts.EnableTLS && s.opts.TLSConfig != nil {
		l, err = tls.Listen("tcp", s.address, s.opts.TLSConfig)
	} else {
		// otherwise plain listen
		l, err = net.Listen("tcp", s.address)
	}
	if err != nil {
		return err
	}

	log.Logf("HTTP API Listening on %s", l.Addr().String())

	s.mtx.Lock()
	s.address = l.Addr().String()
	s.mtx.Unlock()

	go func() {
		if err := http.Serve(l, s.mux); err != nil {
			// temporary fix
			//log.Fatal(err)
		}
	}()

	go func() {
		ch := <-s.exit
		ch <- l.Close()
	}()

	return nil
}

func (s *httpServer) Stop() error {
	ch := make(chan error)
	s.exit <- ch
	return <-ch
}

func (s *httpServer) String() string {
	return "http"
}
<|endoftext|>


<commit_before>package knsq

import (
	"github.com/bitly/nsq/nsq"
)

// MustReader calls nsq.NewReader and panics if nsq.NewReader
// returned an error. nsq.NewReader only fails on invalid
// topic and channel names.
func MustReader(topic, channel string) *nsq.Reader {
	r, err := nsq.NewReader(topic, channel)
	if err != nil {
		panic(err)
	}
	return r
}

// HandlerFunc is a type that makes a single function
// implement to the nsq.Handler interface which consists
// of only one function (just like http.HandlerFunc and http.Handler).
type HandlerFunc func(message *nsq.Message) error

func (f HandlerFunc) HandleMessage(message *nsq.Message) error {
	return f(message)
}

// AttachHandler creates a new nsq.Reader for a topic and attaches the
// given handler to it.
func AttachHandler(topic, channel string, lookupd string, handler nsq.Handler) error {
	mountReader, err := nsq.NewReader(topic, channel)
	if err != nil {
		return err
	}
	mountReader.AddHandler(handler)
	return mountReader.ConnectToLookupd(lookupd)
}

// AttachEphemeralHandler create a new nsq.Reader for a topic and attaches the
// given handler to it. The nsq channel to which the handler gets attached
// will be ephemeral. Ephemeral channels will not be buffered to disk and may
// drop messages. Ephemeral channels will also not be persisted after its
// last client disconnects.
func AttachEphemeralHandler(topic, channel, lookupd string, handler nsq.Handler) error {
	return AttachHandler(topic, channel + "#ephemeral", lookupd, handler)
}
<commit_msg>reduce name for ephemeral channels in length if it's too long.<commit_after>package knsq

import (
	"github.com/bitly/nsq/nsq"
)

// MustReader calls nsq.NewReader and panics if nsq.NewReader
// returned an error. nsq.NewReader only fails on invalid
// topic and channel names.
func MustReader(topic, channel string) *nsq.Reader {
	r, err := nsq.NewReader(topic, channel)
	if err != nil {
		panic(err)
	}
	return r
}

// HandlerFunc is a type that makes a single function
// implement to the nsq.Handler interface which consists
// of only one function (just like http.HandlerFunc and http.Handler).
type HandlerFunc func(message *nsq.Message) error

func (f HandlerFunc) HandleMessage(message *nsq.Message) error {
	return f(message)
}

// AttachHandler creates a new nsq.Reader for a topic and attaches the
// given handler to it.
func AttachHandler(topic, channel string, lookupd string, handler nsq.Handler) error {
	mountReader, err := nsq.NewReader(topic, channel)
	if err != nil {
		return err
	}
	mountReader.AddHandler(handler)
	return mountReader.ConnectToLookupd(lookupd)
}

// AttachEphemeralHandler create a new nsq.Reader for a topic and attaches the
// given handler to it. The nsq channel to which the handler gets attached
// will be ephemeral. Ephemeral channels will not be buffered to disk and may
// drop messages. Ephemeral channels will also not be persisted after its
// last client disconnects.
func AttachEphemeralHandler(topic, channel, lookupd string, handler nsq.Handler) error {
	ephSuffix := "#ephemeral"
	if (len(channel) + len(ephSuffix) > 32) {
		channel = channel[:32 - len(ephSuffix)]
	}
	return AttachHandler(topic, channel + ephSuffix, lookupd, handler)
}
<|endoftext|>


<commit_before>package force

import (
	"fmt"
)

// Custom Error to handle salesforce api responses.
type ApiErrors []*ApiError

type ApiError struct {
	Fields           []string `json:"fields,omitempty" force:"fields,omitempty"`
	Message          string   `json:"message,omitempty" force:"message,omitempty"`
	ErrorCode        string   `json:"errorCode,omitempty" force:"errorCode,omitempty"`
	ErrorName        string   `json:"error,omitempty" force:"error,omitempty"`
	ErrorDescription string   `json:"error_description,omitempty" force:"error_description,omitempty"`
}

func (e ApiErrors) Error() string {
	return fmt.Sprintf("%#v", e)
}

func (e ApiErrors) Validate() bool {
	if len(e) != 0 {
		return true
	}

	return false
}

func (e ApiError) Error() string {
	return fmt.Sprintf("%#v", e)
}

func (e ApiError) Validate() bool {
	if len(e.Fields) != 0 || len(e.Message) != 0 || len(e.ErrorCode) != 0 || len(e.ErrorName) != 0 || len(e.ErrorDescription) != 0 {
		return true
	}

	return false
}
<commit_msg>Fixed the Error method for ApiErrors so that it prints each error.<commit_after>package force

import (
	"fmt"
)

// Custom Error to handle salesforce api responses.
type ApiErrors []*ApiError

type ApiError struct {
	Fields           []string `json:"fields,omitempty" force:"fields,omitempty"`
	Message          string   `json:"message,omitempty" force:"message,omitempty"`
	ErrorCode        string   `json:"errorCode,omitempty" force:"errorCode,omitempty"`
	ErrorName        string   `json:"error,omitempty" force:"error,omitempty"`
	ErrorDescription string   `json:"error_description,omitempty" force:"error_description,omitempty"`
}

func (e ApiErrors) Error() string {
	return fmt.Sprintf("%#v", e.Errors)
}

func (e ApiErrors) Errors() []string {
	eArr := make([]string, len(e))
	for i, err := range e {
		eArr[i] = err.Error()
	}
	return eArr
}

func (e ApiErrors) Validate() bool {
	if len(e) != 0 {
		return true
	}

	return false
}

func (e ApiError) Error() string {
	return fmt.Sprintf("%#v", e)
}

func (e ApiError) Validate() bool {
	if len(e.Fields) != 0 || len(e.Message) != 0 || len(e.ErrorCode) != 0 || len(e.ErrorName) != 0 || len(e.ErrorDescription) != 0 {
		return true
	}

	return false
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"math"
	"os"
	"time"

	"github.com/coreos/locksmith/third_party/github.com/coreos/go-systemd/dbus"
	"github.com/coreos/locksmith/third_party/github.com/coreos/go-systemd/login1"

	"github.com/coreos/locksmith/lock"
	"github.com/coreos/locksmith/pkg/machineid"
	"github.com/coreos/locksmith/updateengine"
)

var (
	cmdDaemon = &Command{
		Name:        "daemon",
		Summary:     "Daemon for reboot needed signal and if reboot able.",
		Description: `Daemon waits for the reboot needed signal coming out of update engine and attempts to acquire the reboot lock. If the reboot lock is acquired then the machine will reboot.`,
		Run:         runDaemon,
	}
)

const (
	initialTimeout = time.Second * 5
	maxTimeout     = time.Minute * 5
)

const (
	StrategyReboot     = "reboot"
	StrategyEtcdLock   = "etcd-lock"
	StrategyBestEffort = "best-effort"
)

func expBackoff(try int) time.Duration {
	sleep := time.Duration(math.Pow(2, float64(try))) * initialTimeout
	if sleep > maxTimeout {
		sleep = maxTimeout
	}

	return sleep
}

func rebootAndSleep(lgn *login1.Conn) {
	lgn.Reboot(false)
	fmt.Println("Reboot sent. Going to sleep.")

	// Wait a really long time for the reboot to occur.
	time.Sleep(time.Hour * 24 * 7)
}

// lockAndReboot attempts to acquire the lock and reboot the machine in an
// infinite loop. Returns if the reboot failed.
func lockAndReboot(lck *lock.Lock, lgn *login1.Conn) {
	tries := 0
	for {
		err := lck.Lock()
		if err != nil && err != lock.ErrExist {
			sleep := expBackoff(tries)
			fmt.Printf("Retrying in %v. Error locking: %v\n", sleep, err)
			time.Sleep(sleep)
			tries = tries + 1

			continue
		}

		rebootAndSleep(lgn)

		return
	}
}

func unlockIfHeld(lck *lock.Lock) {
	tries := 0
	for {
		err := lck.Unlock()
		if err == nil {
			fmt.Println("Unlocked existing lock for this machine")
			return
		} else if err == lock.ErrNotExist {
			return
		}

		sleep := expBackoff(tries)
		fmt.Println("Retrying in %v. Error unlocking: %v", sleep, err)
		time.Sleep(sleep)
		tries = tries + 1
	}
}

func setupLock() (lck *lock.Lock, err error) {
	elc, err := lock.NewEtcdLockClient(nil)
	if err != nil {
		return nil, fmt.Errorf("Error initializing etcd client: %v", err)
	}

	mID := machineid.MachineID("/")
	if mID == "" {
		return nil, fmt.Errorf("Cannot read machine-id")
	}

	lck = lock.New(mID, elc)

	unlockIfHeld(lck)

	return lck, nil
}

// etcdActive returns true if etcd is not in an inactive state according to systemd.
func etcdActive() (running bool, err error) {
	sys, err := dbus.New()
	if err != nil {
		return false, err
	}

	prop, err := sys.GetUnitProperty("etcd.service", "ActiveState")
	if err != nil {
		return false, fmt.Errorf("Error getting etcd.service ActiveState: %v", err)
	}

	if prop.Value.Value().(string) == "inactive" {
		return false, nil
	}

	return true, nil
}

func reboot(useLock bool, lck *lock.Lock, lgn *login1.Conn) {
	if useLock {
		lockAndReboot(lck, lgn)
	}

	rebootAndSleep(lgn)
	fmt.Println("Error: reboot attempt never finished")
}

func runDaemon(args []string) int {
	var lck *lock.Lock

	useLock := false
	switch s := os.ExpandEnv("${LOCKSMITH_STRATEGY}"); {
	case s == "":
		fallthrough
	case s == StrategyBestEffort:
		running, err := etcdActive()
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			return 1
		}
		if running {
			fmt.Println("etcd.service is active")
			useLock = true
		} else {
			fmt.Println("etcd.service is inactive")
			useLock = false
		}
	case s == StrategyEtcdLock:
		useLock = true
	case s == StrategyReboot:
		useLock = false
	default:
		fmt.Fprintln(os.Stderr, "Unknown strategy:", s)
		return 1
	}

	ue, err := updateengine.New()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error initializing update1 client:", err)
		return 1
	}

	lgn, err := login1.New()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error initializing login1 client:", err)
		return 1
	}

	if useLock {
		lck, err = setupLock()
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			return 1
		}
	}

	ch := make(chan updateengine.Status, 1)
	go ue.RebootNeededSignal(ch)

	result, err := ue.GetStatus()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Cannot get update engine status:", err)
		return 1
	}

	if result.CurrentOperation == updateengine.UpdateStatusUpdatedNeedReboot {
		reboot(useLock, lck, lgn)
		return 1
	}

	fmt.Printf("locksmithd starting currentOperation=%q strategy=%q useLock=%t\n",
		result.CurrentOperation,
		os.ExpandEnv("${LOCKSMITH_STRATEGY}"),
		useLock,
	)

	// Wait for a reboot needed signal
	<-ch
	reboot(useLock, lck, lgn)

	return 1
}
<commit_msg>feat(daemon): wait until you get a signal to check for etcd<commit_after>package main

import (
	"fmt"
	"math"
	"os"
	"time"

	"github.com/coreos/locksmith/third_party/github.com/coreos/go-systemd/dbus"
	"github.com/coreos/locksmith/third_party/github.com/coreos/go-systemd/login1"

	"github.com/coreos/locksmith/lock"
	"github.com/coreos/locksmith/pkg/machineid"
	"github.com/coreos/locksmith/updateengine"
)

var (
	cmdDaemon = &Command{
		Name:        "daemon",
		Summary:     "Daemon for reboot needed signal and if reboot able.",
		Description: `Daemon waits for the reboot needed signal coming out of update engine and attempts to acquire the reboot lock. If the reboot lock is acquired then the machine will reboot.`,
		Run:         runDaemon,
	}
)

const (
	initialTimeout = time.Second * 5
	maxTimeout     = time.Minute * 5
)

const (
	StrategyReboot     = "reboot"
	StrategyEtcdLock   = "etcd-lock"
	StrategyBestEffort = "best-effort"
)

func expBackoff(try int) time.Duration {
	sleep := time.Duration(math.Pow(2, float64(try))) * initialTimeout
	if sleep > maxTimeout {
		sleep = maxTimeout
	}

	return sleep
}

func rebootAndSleep(lgn *login1.Conn) {
	lgn.Reboot(false)
	fmt.Println("Reboot sent. Going to sleep.")

	// Wait a really long time for the reboot to occur.
	time.Sleep(time.Hour * 24 * 7)
}

// lockAndReboot attempts to acquire the lock and reboot the machine in an
// infinite loop. Returns if the reboot failed.
func (r rebooter) lockAndReboot(lck *lock.Lock) {
	tries := 0
	for {
		err := lck.Lock()
		if err != nil && err != lock.ErrExist {
			sleep := expBackoff(tries)
			fmt.Printf("Retrying in %v. Error locking: %v\n", sleep, err)
			time.Sleep(sleep)
			tries = tries + 1

			continue
		}

		rebootAndSleep(r.lgn)

		return
	}
}

func unlockIfHeld(lck *lock.Lock) {
	tries := 0
	for {
		err := lck.Unlock()
		if err == nil {
			fmt.Println("Unlocked existing lock for this machine")
			return
		} else if err == lock.ErrNotExist {
			return
		}

		sleep := expBackoff(tries)
		fmt.Println("Retrying in %v. Error unlocking: %v", sleep, err)
		time.Sleep(sleep)
		tries = tries + 1
	}
}

func setupLock() (lck *lock.Lock, err error) {
	elc, err := lock.NewEtcdLockClient(nil)
	if err != nil {
		return nil, fmt.Errorf("Error initializing etcd client: %v", err)
	}

	mID := machineid.MachineID("/")
	if mID == "" {
		return nil, fmt.Errorf("Cannot read machine-id")
	}

	lck = lock.New(mID, elc)

	unlockIfHeld(lck)

	return lck, nil
}

// etcdActive returns true if etcd is not in an inactive state according to systemd.
func etcdActive() (running bool, err error) {
	sys, err := dbus.New()
	if err != nil {
		return false, err
	}

	prop, err := sys.GetUnitProperty("etcd.service", "ActiveState")
	if err != nil {
		return false, fmt.Errorf("Error getting etcd.service ActiveState: %v", err)
	}

	if prop.Value.Value().(string) == "inactive" {
		return false, nil
	}

	return true, nil
}

type rebooter struct {
	strategy string
	lgn *login1.Conn
}

func (r rebooter) useLock() (useLock bool, err error) {
	switch r.strategy {
	case "":
		fallthrough
	case StrategyBestEffort:
		running, err := etcdActive()
		if err != nil {
			return false, err
		}
		if running {
			fmt.Println("etcd.service is active")
			useLock = true
		} else {
			fmt.Println("etcd.service is inactive")
			useLock = false
		}
	case StrategyEtcdLock:
		useLock = true
	case StrategyReboot:
		useLock = false
	default:
		return false, fmt.Errorf("Unknown strategy: %s", r.strategy)
	}

	return useLock, nil
}

func (r rebooter) reboot() int {
	useLock, err := r.useLock()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return 1
	}

	if useLock {
		lck, err := setupLock()
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			return 1
		}

		r.lockAndReboot(lck)
	}

	rebootAndSleep(r.lgn)
	fmt.Println("Error: reboot attempt never finished")
	return 1
}

func runDaemon(args []string) int {
	strategy := os.ExpandEnv("${LOCKSMITH_STRATEGY}")

	ue, err := updateengine.New()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error initializing update1 client:", err)
		return 1
	}

	lgn, err := login1.New()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error initializing login1 client:", err)
		return 1
	}

	ch := make(chan updateengine.Status, 1)
	go ue.RebootNeededSignal(ch)

	r := rebooter{strategy, lgn}

	result, err := ue.GetStatus()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Cannot get update engine status:", err)
		return 1
	}

	if result.CurrentOperation == updateengine.UpdateStatusUpdatedNeedReboot {
		return r.reboot()
	}

	fmt.Printf("locksmithd starting currentOperation=%q strategy=%q\n",
		result.CurrentOperation,
		os.ExpandEnv("${LOCKSMITH_STRATEGY}"),
	)

	// Wait for a reboot needed signal
	<-ch
	return r.reboot()
}
<|endoftext|>


<commit_before>package profile

import (
	"github.com/godbus/dbus"
	"github.com/muka/go-bluetooth/bluez"
)

// NewAdapter1 create a new Adapter1 client
func NewAdapter1(hostID string) *Adapter1 {
	a := new(Adapter1)
	a.client = bluez.NewClient(
		&bluez.Config{
			Name:  "org.bluez",
			Iface: bluez.Adapter1Interface,
			Path:  "/org/bluez/" + hostID,
			Bus:   bluez.SystemBus,
		},
	)
	a.Properties = new(Adapter1Properties)
	a.GetProperties()
	return a
}

// Adapter1 client
type Adapter1 struct {
	client     *bluez.Client
	Properties *Adapter1Properties
}

//Adapter1Properties contains the exposed properties of an interface
type Adapter1Properties struct {
	UUIDs               []string
	Discoverable        bool
	Discovering         bool
	Pairable            bool
	Powered             bool
	Address             string
	Alias               string
	Modalias            string
	Name                string
	Class               uint32
	DiscoverableTimeout uint32
	PairableTimeout     uint32
}

// Close the connection
func (a *Adapter1) Close() {
	a.client.Disconnect()
}

//GetProperties load all available properties
func (a *Adapter1) GetProperties() (*Adapter1Properties, error) {
	err := a.client.GetProperties(a.Properties)
	return a.Properties, err
}

//SetProperty set a property
func (a *Adapter1) SetProperty(name string, value interface{}) error {
	return a.client.SetProperty(name, value)
}

//StartDiscovery on the adapter
func (a *Adapter1) StartDiscovery() error {
	return a.client.Call("StartDiscovery", 0).Store()
}

//StopDiscovery on the adapter
func (a *Adapter1) StopDiscovery() error {
	return a.client.Call("StopDiscovery", 0).Store()
}

//RemoveDevice from the list
func (a *Adapter1) RemoveDevice(device string) error {
	return a.client.Call("RemoveDevice", 0, dbus.ObjectPath(device)).Store()
}
<commit_msg>add support for setting discovery filters<commit_after>package profile

import (
	"github.com/godbus/dbus"
	"github.com/muka/go-bluetooth/bluez"
)

// NewAdapter1 create a new Adapter1 client
func NewAdapter1(hostID string) *Adapter1 {
	a := new(Adapter1)
	a.client = bluez.NewClient(
		&bluez.Config{
			Name:  "org.bluez",
			Iface: bluez.Adapter1Interface,
			Path:  "/org/bluez/" + hostID,
			Bus:   bluez.SystemBus,
		},
	)
	a.Properties = new(Adapter1Properties)
	a.GetProperties()
	return a
}

// Adapter1 client
type Adapter1 struct {
	client     *bluez.Client
	Properties *Adapter1Properties
}

//Adapter1Properties contains the exposed properties of an interface
type Adapter1Properties struct {
	UUIDs               []string
	Discoverable        bool
	Discovering         bool
	Pairable            bool
	Powered             bool
	Address             string
	Alias               string
	Modalias            string
	Name                string
	Class               uint32
	DiscoverableTimeout uint32
	PairableTimeout     uint32
}

// Close the connection
func (a *Adapter1) Close() {
	a.client.Disconnect()
}

//GetProperties load all available properties
func (a *Adapter1) GetProperties() (*Adapter1Properties, error) {
	err := a.client.GetProperties(a.Properties)
	return a.Properties, err
}

//SetProperty set a property
func (a *Adapter1) SetProperty(name string, value interface{}) error {
	return a.client.SetProperty(name, value)
}

//StartDiscovery on the adapter
func (a *Adapter1) StartDiscovery() error {
	return a.client.Call("StartDiscovery", 0).Store()
}

//StopDiscovery on the adapter
func (a *Adapter1) StopDiscovery() error {
	return a.client.Call("StopDiscovery", 0).Store()
}

//RemoveDevice from the list
func (a *Adapter1) RemoveDevice(device string) error {
	return a.client.Call("RemoveDevice", 0, dbus.ObjectPath(device)).Store()
}

//GetDiscoveryFilters - get supported discovery filters
func (a *Adapter1) GetDiscoveryFilters() ([]string, error) {
	var f []string
	err := a.client.Call("GetDiscoveryFilters", 0).Store(&f)
	return f, err
}

//SetDiscoveryFilters - set discovery filters.
//
// Example:
// 	filters := map[string]interface{} {
//		"RSSI": int16(-127),
//		"Transport": "le",
//		"DuplicateData": true,
//		"UUIDs": []string{"0x180a", "0x1400"},
//	}
//  adapter.SetDiscoveryFilter(filter)
func (a *Adapter1) SetDiscoveryFilter(f map[string]interface{}) error {
	return a.client.Call("SetDiscoveryFilter", 0, f).Store()
}
<|endoftext|>


<commit_before>// Copyright 2013 Apcera Inc. All rights reserved.

package graft

import (
	"time"
)

const (
	VERSION = "0.1"

	// Election timeout MIN and MAX per RAFT spec suggestion.
	MIN_ELECTION_TIMEOUT = 500 * time.Millisecond
	MAX_ELECTION_TIMEOUT = 2 * MIN_ELECTION_TIMEOUT

	// Heartbeat tick for LEADERS.
	// Should be << MIN_ELECTION_TIMEOUT per RAFT spec.
	HEARTBEAT_INTERVAL = 100 * time.Millisecond

	NO_LEADER = ""
	NO_VOTE   = ""

	// Use buffer channels.
	CHAN_SIZE = 8
)
<commit_msg>Removed channel buffer size<commit_after>// Copyright 2013 Apcera Inc. All rights reserved.

package graft

import (
	"time"
)

const (
	VERSION = "0.1"

	// Election timeout MIN and MAX per RAFT spec suggestion.
	MIN_ELECTION_TIMEOUT = 500 * time.Millisecond
	MAX_ELECTION_TIMEOUT = 2 * MIN_ELECTION_TIMEOUT

	// Heartbeat tick for LEADERS.
	// Should be << MIN_ELECTION_TIMEOUT per RAFT spec.
	HEARTBEAT_INTERVAL = 100 * time.Millisecond

	NO_LEADER = ""
	NO_VOTE   = ""
)
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors.

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 node

import (
	"crypto/tls"
	"fmt"
	"net/http"
	"regexp"
	"strconv"
	"time"

	"k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/util/uuid"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/apimachinery/pkg/watch"
	"k8s.io/kubernetes/test/e2e/framework"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	imageutils "k8s.io/kubernetes/test/utils/image"
)

var _ = SIGDescribe("Pods Extended", func() {
	f := framework.NewDefaultFramework("pods")

	framework.KubeDescribe("Delete Grace Period", func() {
		var podClient *framework.PodClient
		BeforeEach(func() {
			podClient = f.PodClient()
		})
		// Flaky issue #36821.
		framework.ConformanceIt("should be submitted and removed  [Flaky]", func() {
			By("creating the pod")
			name := "pod-submit-remove-" + string(uuid.NewUUID())
			value := strconv.Itoa(time.Now().Nanosecond())
			pod := &v1.Pod{
				ObjectMeta: metav1.ObjectMeta{
					Name: name,
					Labels: map[string]string{
						"name": "foo",
						"time": value,
					},
				},
				Spec: v1.PodSpec{
					Containers: []v1.Container{
						{
							Name:  "nginx",
							Image: imageutils.GetE2EImage(imageutils.NginxSlim),
						},
					},
				},
			}

			By("setting up watch")
			selector := labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))
			options := metav1.ListOptions{LabelSelector: selector.String()}
			pods, err := podClient.List(options)
			Expect(err).NotTo(HaveOccurred(), "failed to query for pod")
			Expect(len(pods.Items)).To(Equal(0))
			options = metav1.ListOptions{
				LabelSelector:   selector.String(),
				ResourceVersion: pods.ListMeta.ResourceVersion,
			}
			w, err := podClient.Watch(options)
			Expect(err).NotTo(HaveOccurred(), "failed to set up watch")

			By("submitting the pod to kubernetes")
			podClient.Create(pod)

			By("verifying the pod is in kubernetes")
			selector = labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))
			options = metav1.ListOptions{LabelSelector: selector.String()}
			pods, err = podClient.List(options)
			Expect(err).NotTo(HaveOccurred(), "failed to query for pod")
			Expect(len(pods.Items)).To(Equal(1))

			By("verifying pod creation was observed")
			select {
			case event, _ := <-w.ResultChan():
				if event.Type != watch.Added {
					framework.Failf("Failed to observe pod creation: %v", event)
				}
			case <-time.After(framework.PodStartTimeout):
				framework.Failf("Timeout while waiting for pod creation")
			}

			// We need to wait for the pod to be running, otherwise the deletion
			// may be carried out immediately rather than gracefully.
			framework.ExpectNoError(f.WaitForPodRunning(pod.Name))
			// save the running pod
			pod, err = podClient.Get(pod.Name, metav1.GetOptions{})
			Expect(err).NotTo(HaveOccurred(), "failed to GET scheduled pod")

			// start local proxy, so we can send graceful deletion over query string, rather than body parameter
			cmd := framework.KubectlCmd("proxy", "-p", "0")
			stdout, stderr, err := framework.StartCmdAndStreamOutput(cmd)
			Expect(err).NotTo(HaveOccurred(), "failed to start up proxy")
			defer stdout.Close()
			defer stderr.Close()
			defer framework.TryKill(cmd)
			buf := make([]byte, 128)
			var n int
			n, err = stdout.Read(buf)
			Expect(err).NotTo(HaveOccurred(), "failed to read from kubectl proxy stdout")
			output := string(buf[:n])
			proxyRegexp := regexp.MustCompile("Starting to serve on 127.0.0.1:([0-9]+)")
			match := proxyRegexp.FindStringSubmatch(output)
			Expect(len(match)).To(Equal(2))
			port, err := strconv.Atoi(match[1])
			Expect(err).NotTo(HaveOccurred(), "failed to convert port into string")

			endpoint := fmt.Sprintf("http://localhost:%d/api/v1/namespaces/%s/pods/%s?gracePeriodSeconds=30", port, pod.Namespace, pod.Name)
			tr := &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
			}
			client := &http.Client{Transport: tr}
			req, err := http.NewRequest("DELETE", endpoint, nil)
			Expect(err).NotTo(HaveOccurred(), "failed to create http request")

			By("deleting the pod gracefully")
			rsp, err := client.Do(req)
			Expect(err).NotTo(HaveOccurred(), "failed to use http client to send delete")

			defer rsp.Body.Close()

			By("verifying the kubelet observed the termination notice")
			Expect(wait.Poll(time.Second*5, time.Second*30, func() (bool, error) {
				podList, err := framework.GetKubeletPods(f.ClientSet, pod.Spec.NodeName)
				if err != nil {
					framework.Logf("Unable to retrieve kubelet pods for node %v: %v", pod.Spec.NodeName, err)
					return false, nil
				}
				for _, kubeletPod := range podList.Items {
					if pod.Name != kubeletPod.Name {
						continue
					}
					if kubeletPod.ObjectMeta.DeletionTimestamp == nil {
						framework.Logf("deletion has not yet been observed")
						return false, nil
					}
					return true, nil
				}
				framework.Logf("no pod exists with the name we were looking for, assuming the termination request was observed and completed")
				return true, nil
			})).NotTo(HaveOccurred(), "kubelet never observed the termination notice")

			By("verifying pod deletion was observed")
			deleted := false
			timeout := false
			var lastPod *v1.Pod
			timer := time.After(1 * time.Minute)
			for !deleted && !timeout {
				select {
				case event, _ := <-w.ResultChan():
					if event.Type == watch.Deleted {
						lastPod = event.Object.(*v1.Pod)
						deleted = true
					}
				case <-timer:
					timeout = true
				}
			}
			if !deleted {
				framework.Failf("Failed to observe pod deletion")
			}

			Expect(lastPod.DeletionTimestamp).ToNot(BeNil())
			Expect(lastPod.Spec.TerminationGracePeriodSeconds).ToNot(BeZero())

			selector = labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))
			options = metav1.ListOptions{LabelSelector: selector.String()}
			pods, err = podClient.List(options)
			Expect(err).NotTo(HaveOccurred(), "failed to query for pods")
			Expect(len(pods.Items)).To(Equal(0))

		})
	})

	framework.KubeDescribe("Pods Set QOS Class", func() {
		var podClient *framework.PodClient
		BeforeEach(func() {
			podClient = f.PodClient()
		})
		framework.ConformanceIt("should be submitted and removed ", func() {
			By("creating the pod")
			name := "pod-qos-class-" + string(uuid.NewUUID())
			pod := &v1.Pod{
				ObjectMeta: metav1.ObjectMeta{
					Name: name,
					Labels: map[string]string{
						"name": name,
					},
				},
				Spec: v1.PodSpec{
					Containers: []v1.Container{
						{
							Name:  "nginx",
							Image: imageutils.GetE2EImage(imageutils.NginxSlim),
							Resources: v1.ResourceRequirements{
								Limits: v1.ResourceList{
									v1.ResourceCPU:    resource.MustParse("100m"),
									v1.ResourceMemory: resource.MustParse("100Mi"),
								},
								Requests: v1.ResourceList{
									v1.ResourceCPU:    resource.MustParse("100m"),
									v1.ResourceMemory: resource.MustParse("100Mi"),
								},
							},
						},
					},
				},
			}

			By("submitting the pod to kubernetes")
			podClient.Create(pod)

			By("verifying QOS class is set on the pod")
			pod, err := podClient.Get(name, metav1.GetOptions{})
			Expect(err).NotTo(HaveOccurred(), "failed to query for pod")
			Expect(pod.Status.QOSClass == v1.PodQOSGuaranteed)
		})
	})
})
<commit_msg>Pod deletion can be contended, causing test failure<commit_after>/*
Copyright 2016 The Kubernetes Authors.

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 node

import (
	"crypto/tls"
	"fmt"
	"net/http"
	"regexp"
	"strconv"
	"time"

	"k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/util/uuid"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/apimachinery/pkg/watch"
	"k8s.io/kubernetes/test/e2e/framework"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	imageutils "k8s.io/kubernetes/test/utils/image"
)

var _ = SIGDescribe("Pods Extended", func() {
	f := framework.NewDefaultFramework("pods")

	framework.KubeDescribe("Delete Grace Period", func() {
		var podClient *framework.PodClient
		BeforeEach(func() {
			podClient = f.PodClient()
		})
		// Flaky issue #36821.
		framework.ConformanceIt("should be submitted and removed  [Flaky]", func() {
			By("creating the pod")
			name := "pod-submit-remove-" + string(uuid.NewUUID())
			value := strconv.Itoa(time.Now().Nanosecond())
			pod := &v1.Pod{
				ObjectMeta: metav1.ObjectMeta{
					Name: name,
					Labels: map[string]string{
						"name": "foo",
						"time": value,
					},
				},
				Spec: v1.PodSpec{
					Containers: []v1.Container{
						{
							Name:  "nginx",
							Image: imageutils.GetE2EImage(imageutils.NginxSlim),
						},
					},
				},
			}

			By("setting up watch")
			selector := labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))
			options := metav1.ListOptions{LabelSelector: selector.String()}
			pods, err := podClient.List(options)
			Expect(err).NotTo(HaveOccurred(), "failed to query for pod")
			Expect(len(pods.Items)).To(Equal(0))
			options = metav1.ListOptions{
				LabelSelector:   selector.String(),
				ResourceVersion: pods.ListMeta.ResourceVersion,
			}
			w, err := podClient.Watch(options)
			Expect(err).NotTo(HaveOccurred(), "failed to set up watch")

			By("submitting the pod to kubernetes")
			podClient.Create(pod)

			By("verifying the pod is in kubernetes")
			selector = labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))
			options = metav1.ListOptions{LabelSelector: selector.String()}
			pods, err = podClient.List(options)
			Expect(err).NotTo(HaveOccurred(), "failed to query for pod")
			Expect(len(pods.Items)).To(Equal(1))

			By("verifying pod creation was observed")
			select {
			case event, _ := <-w.ResultChan():
				if event.Type != watch.Added {
					framework.Failf("Failed to observe pod creation: %v", event)
				}
			case <-time.After(framework.PodStartTimeout):
				framework.Failf("Timeout while waiting for pod creation")
			}

			// We need to wait for the pod to be running, otherwise the deletion
			// may be carried out immediately rather than gracefully.
			framework.ExpectNoError(f.WaitForPodRunning(pod.Name))
			// save the running pod
			pod, err = podClient.Get(pod.Name, metav1.GetOptions{})
			Expect(err).NotTo(HaveOccurred(), "failed to GET scheduled pod")

			// start local proxy, so we can send graceful deletion over query string, rather than body parameter
			cmd := framework.KubectlCmd("proxy", "-p", "0")
			stdout, stderr, err := framework.StartCmdAndStreamOutput(cmd)
			Expect(err).NotTo(HaveOccurred(), "failed to start up proxy")
			defer stdout.Close()
			defer stderr.Close()
			defer framework.TryKill(cmd)
			buf := make([]byte, 128)
			var n int
			n, err = stdout.Read(buf)
			Expect(err).NotTo(HaveOccurred(), "failed to read from kubectl proxy stdout")
			output := string(buf[:n])
			proxyRegexp := regexp.MustCompile("Starting to serve on 127.0.0.1:([0-9]+)")
			match := proxyRegexp.FindStringSubmatch(output)
			Expect(len(match)).To(Equal(2))
			port, err := strconv.Atoi(match[1])
			Expect(err).NotTo(HaveOccurred(), "failed to convert port into string")

			endpoint := fmt.Sprintf("http://localhost:%d/api/v1/namespaces/%s/pods/%s?gracePeriodSeconds=30", port, pod.Namespace, pod.Name)
			tr := &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
			}
			client := &http.Client{Transport: tr}
			req, err := http.NewRequest("DELETE", endpoint, nil)
			Expect(err).NotTo(HaveOccurred(), "failed to create http request")

			By("deleting the pod gracefully")
			rsp, err := client.Do(req)
			Expect(err).NotTo(HaveOccurred(), "failed to use http client to send delete")

			defer rsp.Body.Close()

			By("verifying the kubelet observed the termination notice")
			Expect(wait.Poll(time.Second*5, time.Second*30, func() (bool, error) {
				podList, err := framework.GetKubeletPods(f.ClientSet, pod.Spec.NodeName)
				if err != nil {
					framework.Logf("Unable to retrieve kubelet pods for node %v: %v", pod.Spec.NodeName, err)
					return false, nil
				}
				for _, kubeletPod := range podList.Items {
					if pod.Name != kubeletPod.Name {
						continue
					}
					if kubeletPod.ObjectMeta.DeletionTimestamp == nil {
						framework.Logf("deletion has not yet been observed")
						return false, nil
					}
					return true, nil
				}
				framework.Logf("no pod exists with the name we were looking for, assuming the termination request was observed and completed")
				return true, nil
			})).NotTo(HaveOccurred(), "kubelet never observed the termination notice")

			By("verifying pod deletion was observed")
			deleted := false
			timeout := false
			var lastPod *v1.Pod
			timer := time.After(2 * time.Minute)
			for !deleted && !timeout {
				select {
				case event, _ := <-w.ResultChan():
					if event.Type == watch.Deleted {
						lastPod = event.Object.(*v1.Pod)
						deleted = true
					}
				case <-timer:
					timeout = true
				}
			}
			if !deleted {
				framework.Failf("Failed to observe pod deletion")
			}

			Expect(lastPod.DeletionTimestamp).ToNot(BeNil())
			Expect(lastPod.Spec.TerminationGracePeriodSeconds).ToNot(BeZero())

			selector = labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))
			options = metav1.ListOptions{LabelSelector: selector.String()}
			pods, err = podClient.List(options)
			Expect(err).NotTo(HaveOccurred(), "failed to query for pods")
			Expect(len(pods.Items)).To(Equal(0))

		})
	})

	framework.KubeDescribe("Pods Set QOS Class", func() {
		var podClient *framework.PodClient
		BeforeEach(func() {
			podClient = f.PodClient()
		})
		framework.ConformanceIt("should be submitted and removed ", func() {
			By("creating the pod")
			name := "pod-qos-class-" + string(uuid.NewUUID())
			pod := &v1.Pod{
				ObjectMeta: metav1.ObjectMeta{
					Name: name,
					Labels: map[string]string{
						"name": name,
					},
				},
				Spec: v1.PodSpec{
					Containers: []v1.Container{
						{
							Name:  "nginx",
							Image: imageutils.GetE2EImage(imageutils.NginxSlim),
							Resources: v1.ResourceRequirements{
								Limits: v1.ResourceList{
									v1.ResourceCPU:    resource.MustParse("100m"),
									v1.ResourceMemory: resource.MustParse("100Mi"),
								},
								Requests: v1.ResourceList{
									v1.ResourceCPU:    resource.MustParse("100m"),
									v1.ResourceMemory: resource.MustParse("100Mi"),
								},
							},
						},
					},
				},
			}

			By("submitting the pod to kubernetes")
			podClient.Create(pod)

			By("verifying QOS class is set on the pod")
			pod, err := podClient.Get(name, metav1.GetOptions{})
			Expect(err).NotTo(HaveOccurred(), "failed to query for pod")
			Expect(pod.Status.QOSClass == v1.PodQOSGuaranteed)
		})
	})
})
<|endoftext|>


<commit_before><commit_msg>This is not done yet<commit_after><|endoftext|>


<commit_before>package main

import (
	"github.com/xiaonanln/goworld"
)

var (
	_SERVICE_NAMES = []string{
		"OnlineService",
		"SpaceService",
	}
)

func main() {
	goworld.RegisterSpace(&MySpace{}) // 注册自定义的Space类型

	goworld.RegisterEntity("OnlineService", &OnlineService{})
	goworld.RegisterEntity("SpaceService", &SpaceService{})
	// 注册Account类型
	goworld.RegisterEntity("Account", &Account{})
	// 注册Monster类型
	goworld.RegisterEntity("Monster", &Monster{})
	// 注册Avatar类型，并定义属性
	goworld.RegisterEntity("Player", &Player{})
	// 运行游戏服务器
	goworld.Run()
}
<commit_msg>fix unity demo<commit_after>package main

import (
	"github.com/xiaonanln/goworld"
)

var (
	_SERVICE_NAMES = []string{
		"OnlineService",
		"SpaceService",
	}
)

func main() {
	goworld.RegisterSpace(&MySpace{}) // 注册自定义的Space类型

	goworld.RegisterService("OnlineService", &OnlineService{})
	goworld.RegisterService("SpaceService", &SpaceService{})
	// 注册Account类型
	goworld.RegisterEntity("Account", &Account{})
	// 注册Monster类型
	goworld.RegisterEntity("Monster", &Monster{})
	// 注册Avatar类型，并定义属性
	goworld.RegisterEntity("Player", &Player{})
	// 运行游戏服务器
	goworld.Run()
}
<|endoftext|>