<commit_before>package controllers

import (
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"gopkg.in/olivere/elastic.v3"
	"log"
	"net/http"
	"os"
)

var elasticsearch, _ = prepareElasticsearch()

func prepareElasticsearch() (*elastic.Client, error) {
	errorlog := log.New(os.Stdout, "Wave ", log.LstdFlags)
	client, err := elastic.NewClient(elastic.SetErrorLog(errorlog))
	if err != nil {
		log.Println(err)
		return client, err
	}
	exists, err := client.IndexExists("frames").Do()
	if err != nil {
		log.Println(err)
		return client, err
	}
	if exists {
		client.DeleteIndex("frames").Do()
	}
	return client, nil
}

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		// make sure the client presents proper TLS client cert
		return true
	},
}

func elasticache(frame []byte) {
	_, err := elasticsearch.Index().
		Index("frames").
		Type("frame").
		BodyString(string(frame)).
		Do()
	if err != nil {
		log.Println(err)
	}

	// parse ID, go delete in 30 seconds
	//go func() {
	//	time.Sleep(30 * time.Second)
	//	make a delete request for that frame
	//	client.Do(reqQ)
	//}()

	//resp.Body.Close()
}

func PollCollector(c *gin.Context) {
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err == nil {
		defer conn.Close()
		for {
			_, frame_bytes, err := conn.ReadMessage()
			if err != nil {
				break
			}
			//frame := string(frame_bytes)
			elasticache(frame_bytes)
			// update visualizer
		}
	}
}
<commit_msg>go delete in 30s because ttl was depricated in es<commit_after>package controllers

import (
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"gopkg.in/olivere/elastic.v3"
	"log"
	"net/http"
	"os"
	"time"
)

var elasticsearch, _ = prepareElasticsearch()

func prepareElasticsearch() (*elastic.Client, error) {
	errorlog := log.New(os.Stdout, "Wave ", log.LstdFlags)
	client, err := elastic.NewClient(elastic.SetErrorLog(errorlog))
	if err != nil {
		log.Println(err)
		return client, err
	}
	exists, err := client.IndexExists("frames").Do()
	if err != nil {
		log.Println(err)
		return client, err
	}
	if exists {
		client.DeleteIndex("frames").Do()
	}
	return client, nil
}

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		// make sure the client presents proper TLS client cert
		return true
	},
}

func elasticache(frame []byte) {
	record, err := elasticsearch.Index().
		Index("frames").
		Type("frame").
		BodyString(string(frame)).
		Do()
	if err != nil {
		log.Println(err)
	}
	go func() {
		time.Sleep(30 * time.Second)
		elasticsearch.Delete().
			Index("frames").
			Type("frame").
			Id(record.Id).
			Do()
	}()
}

func PollCollector(c *gin.Context) {
	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err == nil {
		defer conn.Close()
		for {
			_, frame_bytes, err := conn.ReadMessage()
			if err != nil {
				break
			}
			//frame := string(frame_bytes)
			elasticache(frame_bytes)
			// update visualizer
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/labstack/echo"
	"github.com/texttheater/golang-levenshtein/levenshtein"
	"net/http"
	"sort"
)

type ViewData struct {
	Failed  bool
	Message string
	Query   string
	Backend string
	Data    interface{}
}

// So that we can sort
var query string

func setupRoutes(e *echo.Echo) {
	e.GET("/", route_main)
	e.GET("/search/:query", route_search)
	e.GET("/manga/:backend/:id", route_manga)
	e.GET("/chapter/:backend/:id", route_chapter)
}

func route_main(c echo.Context) error {
	return c.Render(http.StatusOK, "index", nil)
}

type ByLevenshteinDistance []SearchResult

func (r ByLevenshteinDistance) Len() int {
	return len(r)
}

func (r ByLevenshteinDistance) Swap(i int, j int) {
	r[i], r[j] = r[j], r[i]
}

func (r ByLevenshteinDistance) Less(i int, j int) bool {
	return levenshtein.DistanceForStrings([]rune(query), []rune(r[i].Title), levenshtein.DefaultOptions) < levenshtein.DistanceForStrings([]rune(query), []rune(r[j].Title), levenshtein.DefaultOptions)
}

func route_search(c echo.Context) error {
	allResults := make(map[string][]SearchResult)
	query = c.Param("query")

	if len(query) < 5 {
		data := ViewData{
			Failed:  true,
			Message: "Search query is too short",
		}

		return c.Render(http.StatusBadRequest, "search", data)
	}

	for _, b := range BACKENDS {
		results, err := b.Search(query)
		if err != nil {
			log.Error(err)
			continue
		}

		sort.Sort(ByLevenshteinDistance(results))

		allResults[b.Name()] = results
	}

	data := ViewData{
		Failed: false,
		Query:  query,
		Data:   allResults,
	}

	return c.Render(http.StatusOK, "search", data)
}

func route_manga(c echo.Context) error {
	requestedBackend := c.Param("backend")
	requestedID := c.Param("id")

	for _, backend := range BACKENDS {
		if requestedBackend == backend.Name() {
			result, err := backend.Manga(requestedID)
			if err != nil {
				data := ViewData{
					Failed:  true,
					Message: err.Error(),
					Backend: requestedBackend,
				}
				return c.Render(http.StatusInternalServerError, "manga", data)
			}

			data := ViewData{
				Failed:  false,
				Data:    result,
				Backend: requestedBackend,
			}
			return c.Render(http.StatusOK, "manga", data)
		}
	}

	data := ViewData{
		Failed:  true,
		Message: "Backend not found",
	}
	return c.Render(http.StatusNotFound, "manga", data)
}

func route_chapter(c echo.Context) error {
	requestedBackend := c.Param("backend")
	requestedID := c.Param("id")

	for _, backend := range BACKENDS {
		if requestedBackend == backend.Name() {
			result, err := backend.Chapter(requestedID)
			if err != nil {
				return c.String(http.StatusInternalServerError, "")
			}

			return c.JSON(http.StatusOK, result)
		}
	}

	return c.String(http.StatusNotFound, "Backend not found")
}
<commit_msg>Use parameter searching instead of url searching<commit_after>package main

import (
	"github.com/labstack/echo"
	"github.com/texttheater/golang-levenshtein/levenshtein"
	"net/http"
	"sort"
)

type ViewData struct {
	Failed  bool
	Message string
	Query   string
	Backend string
	Data    interface{}
}

// So that we can sort
var query string

func setupRoutes(e *echo.Echo) {
	e.GET("/", route_main)
	e.GET("/search", route_search)
	e.GET("/manga/:backend/:id", route_manga)
	e.GET("/chapter/:backend/:id", route_chapter)
}

func route_main(c echo.Context) error {
	return c.Render(http.StatusOK, "index", nil)
}

type ByLevenshteinDistance []SearchResult

func (r ByLevenshteinDistance) Len() int {
	return len(r)
}

func (r ByLevenshteinDistance) Swap(i int, j int) {
	r[i], r[j] = r[j], r[i]
}

func (r ByLevenshteinDistance) Less(i int, j int) bool {
	return levenshtein.DistanceForStrings([]rune(query), []rune(r[i].Title), levenshtein.DefaultOptions) < levenshtein.DistanceForStrings([]rune(query), []rune(r[j].Title), levenshtein.DefaultOptions)
}

func route_search(c echo.Context) error {
	allResults := make(map[string][]SearchResult)
	query = c.QueryParam("q")

	if len(query) < 5 {
		data := ViewData{
			Failed:  true,
			Message: "Search query is too short",
		}

		return c.Render(http.StatusBadRequest, "search", data)
	}

	for _, b := range BACKENDS {
		results, err := b.Search(query)
		if err != nil {
			log.Error(err)
			continue
		}

		sort.Sort(ByLevenshteinDistance(results))

		allResults[b.Name()] = results
	}

	data := ViewData{
		Failed: false,
		Query:  query,
		Data:   allResults,
	}

	return c.Render(http.StatusOK, "search", data)
}

func route_manga(c echo.Context) error {
	requestedBackend := c.Param("backend")
	requestedID := c.Param("id")

	for _, backend := range BACKENDS {
		if requestedBackend == backend.Name() {
			result, err := backend.Manga(requestedID)
			if err != nil {
				data := ViewData{
					Failed:  true,
					Message: err.Error(),
					Backend: requestedBackend,
				}
				return c.Render(http.StatusInternalServerError, "manga", data)
			}

			data := ViewData{
				Failed:  false,
				Data:    result,
				Backend: requestedBackend,
			}
			return c.Render(http.StatusOK, "manga", data)
		}
	}

	data := ViewData{
		Failed:  true,
		Message: "Backend not found",
	}
	return c.Render(http.StatusNotFound, "manga", data)
}

func route_chapter(c echo.Context) error {
	requestedBackend := c.Param("backend")
	requestedID := c.Param("id")

	for _, backend := range BACKENDS {
		if requestedBackend == backend.Name() {
			result, err := backend.Chapter(requestedID)
			if err != nil {
				return c.String(http.StatusInternalServerError, "")
			}

			return c.JSON(http.StatusOK, result)
		}
	}

	return c.String(http.StatusNotFound, "Backend not found")
}
<|endoftext|>


<commit_before>/*
 * Copyright 2020 Arm Limited.
 * SPDX-License-Identifier: Apache-2.0
 *
 * 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 core

// Support for building libraries and binaries via soong's cc_library
// modules.

import (
	"fmt"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"

	"github.com/ARM-software/bob-build/internal/bpwriter"
	"github.com/ARM-software/bob-build/internal/ccflags"
	"github.com/ARM-software/bob-build/internal/utils"
)

// Convert between Bob module names, and the name we will give the generated
// cc_library module. This is required when a module supports being built on
// host and target; we cannot create two modules with the same name, so
// instead, we use the `shortName()` (which may include a `__host` or
// `__target` suffix) to disambiguate, and use the `stem` property to fix up
// the output filename.
func ccModuleName(mctx blueprint.BaseModuleContext, name string) string {
	var dep blueprint.Module

	mctx.VisitDirectDeps(func(m blueprint.Module) {
		if m.Name() == name {
			dep = m
		}
	})

	if dep == nil {
		panic(fmt.Errorf("%s has no dependency '%s'", mctx.ModuleName(), name))
	}

	if l, ok := getLibrary(dep); ok {
		return l.shortName()
	}

	// Most cases should match the getLibrary() check above, but generated libraries,
	// etc, do not, and they also do not require using shortName() (because of not
	// being target-specific), so just use the original build.bp name.
	return dep.Name()
}

func ccModuleNames(mctx blueprint.BaseModuleContext, nameLists ...[]string) []string {
	ccModules := []string{}
	for _, nameList := range nameLists {
		for _, name := range nameList {
			ccModules = append(ccModules, ccModuleName(mctx, name))
		}
	}
	return ccModules
}

func (l *library) getGeneratedSourceModules(mctx blueprint.BaseModuleContext) (srcs []string) {
	mctx.VisitDirectDepsIf(
		func(dep blueprint.Module) bool {
			return mctx.OtherModuleDependencyTag(dep) == generatedSourceTag
		},
		func(dep blueprint.Module) {
			switch dep.(type) {
			case *generateSource:
			case *transformSource:
			default:
				panic(fmt.Errorf("Dependency %s of %s is not a generated source",
					dep.Name(), l.Name()))
			}

			srcs = append(srcs, dep.Name())
		})
	return
}

func (l *library) getGeneratedHeaderModules(mctx blueprint.BaseModuleContext) (headers []string) {
	mctx.VisitDirectDepsIf(
		func(dep blueprint.Module) bool {
			return mctx.OtherModuleDependencyTag(dep) == generatedHeaderTag
		},
		func(dep blueprint.Module) {
			switch dep.(type) {
			case *generateSource:
			case *transformSource:
			default:
				panic(fmt.Errorf("Dependency %s of %s is not a generated source",
					dep.Name(), l.Name()))
			}

			headers = append(headers, dep.Name())
		})
	return
}

func addProvenanceProps(m bpwriter.Module, props AndroidProps) {
	if props.Owner != "" {
		m.AddString("owner", props.Owner)
		m.AddBool("vendor", true)
		m.AddBool("proprietary", true)
		m.AddBool("soc_specific", true)
	}
}

func addCFlags(m bpwriter.Module, cflags []string, conlyFlags []string, cxxFlags []string) error {
	if std := ccflags.GetCompilerStandard(cflags, conlyFlags); std != "" {
		m.AddString("c_std", std)
	}

	if std := ccflags.GetCompilerStandard(cflags, cxxFlags); std != "" {
		m.AddString("cpp_std", std)
	}

	armMode, err := ccflags.GetArmMode(cflags, conlyFlags, cxxFlags)
	if err != nil {
		return err
	}

	if armMode != "" {
		m.AddString("instruction_set", armMode)
	}

	m.AddStringList("cflags", utils.Filter(ccflags.AndroidCompileFlags, cflags))
	m.AddStringList("conlyflags", utils.Filter(ccflags.AndroidCompileFlags, conlyFlags))
	m.AddStringList("cppflags", utils.Filter(ccflags.AndroidCompileFlags, cxxFlags))
	return nil
}

func addCcLibraryProps(m bpwriter.Module, l library, mctx blueprint.ModuleContext) {
	if len(l.Properties.Export_include_dirs) > 0 {
		panic(fmt.Errorf("Module %s exports non-local include dirs %v - this is not supported",
			mctx.ModuleName(), l.Properties.Export_include_dirs))
	}

	// Soong deals with exported include directories between library
	// modules, but it doesn't export cflags.
	_, _, exported_cflags := l.GetExportedVariables(mctx)

	cflags := utils.NewStringSlice(l.Properties.Cflags, l.Properties.Export_cflags, exported_cflags)

	sharedLibs := ccModuleNames(mctx, l.Properties.Shared_libs)
	staticLibs := ccModuleNames(mctx, l.Properties.ResolvedStaticLibs)
	// Exported header libraries must be mentioned in both header_libs
	// *and* export_header_lib_headers - i.e., we can't export a header
	// library which isn't actually being used.
	headerLibs := ccModuleNames(mctx, l.Properties.Header_libs, l.Properties.Export_header_libs)

	reexportShared := []string{}
	reexportStatic := []string{}
	reexportHeaders := ccModuleNames(mctx, l.Properties.Export_header_libs)
	for _, lib := range ccModuleNames(mctx, l.Properties.Reexport_libs) {
		if utils.Contains(sharedLibs, lib) {
			reexportShared = append(reexportShared, lib)
		} else if utils.Contains(staticLibs, lib) {
			reexportStatic = append(reexportStatic, lib)
		} else if utils.Contains(headerLibs, lib) {
			reexportHeaders = append(reexportHeaders, lib)
		}
	}

	if l.shortName() != l.outputName() {
		m.AddString("stem", l.outputName())
	}
	m.AddStringList("srcs", utils.Filter(utils.IsCompilableSource, l.Properties.Srcs))
	m.AddStringList("generated_sources", l.getGeneratedSourceModules(mctx))
	m.AddStringList("generated_headers", l.getGeneratedHeaderModules(mctx))
	m.AddStringList("exclude_srcs", l.Properties.Exclude_srcs)
	err := addCFlags(m, cflags, l.Properties.Conlyflags, l.Properties.Cxxflags)
	if err != nil {
		panic(fmt.Errorf("Module %s: %s", mctx.ModuleName(), err.Error()))
	}
	m.AddStringList("include_dirs", l.Properties.Include_dirs)
	m.AddStringList("local_include_dirs", l.Properties.Local_include_dirs)
	m.AddStringList("shared_libs", ccModuleNames(mctx, l.Properties.Shared_libs))
	m.AddStringList("static_libs", staticLibs)
	m.AddStringList("whole_static_libs", ccModuleNames(mctx, l.Properties.Whole_static_libs))
	m.AddStringList("header_libs", headerLibs)
	m.AddStringList("export_shared_lib_headers", reexportShared)
	m.AddStringList("export_static_lib_headers", reexportStatic)
	m.AddStringList("export_header_lib_headers", reexportHeaders)
	m.AddStringList("ldflags", l.Properties.Ldflags)
	if l.getInstallableProps().Relative_install_path != nil {
		m.AddString("relative_install_path", proptools.String(l.getInstallableProps().Relative_install_path))
	}

	addProvenanceProps(m, l.Properties.Build.AndroidProps)
}

func addStaticOrSharedLibraryProps(m bpwriter.Module, l library, mctx blueprint.ModuleContext) {
	// Soong's `export_include_dirs` field is relative to the module
	// dir. The Android.bp backend writes the file into the project
	// root, so we can use the Export_local_include_dirs property
	// unchanged.
	m.AddStringList("export_include_dirs", l.Properties.Export_local_include_dirs)
}

func addStripProp(m bpwriter.Module) {
	g := m.NewGroup("strip")
	g.AddBool("all", true)
}

func (g *androidBpGenerator) binaryActions(l *binary, mctx blueprint.ModuleContext) {
	if !enabledAndRequired(l) {
		return
	}

	// Calculate and record outputs
	l.outs = []string{l.outputName()}

	var modType string
	switch l.Properties.TargetType {
	case tgtTypeHost:
		modType = "cc_binary_host"
	case tgtTypeTarget:
		modType = "cc_binary"
	}

	m, err := AndroidBpFile().NewModule(modType, l.shortName())
	if err != nil {
		panic(err.Error())
	}

	addCcLibraryProps(m, l.library, mctx)
	if l.strip() {
		addStripProp(m)
	}
}

func (g *androidBpGenerator) sharedActions(l *sharedLibrary, mctx blueprint.ModuleContext) {
	if !enabledAndRequired(l) {
		return
	}

	// Calculate and record outputs
	l.outs = []string{l.outputName() + l.fileNameExtension}

	var modType string
	switch l.Properties.TargetType {
	case tgtTypeHost:
		modType = "cc_library_host_shared"
	case tgtTypeTarget:
		modType = "cc_library_shared"
	}

	m, err := AndroidBpFile().NewModule(modType, l.shortName())
	if err != nil {
		panic(err.Error())
	}

	addCcLibraryProps(m, l.library, mctx)
	addStaticOrSharedLibraryProps(m, l.library, mctx)
	if l.strip() {
		addStripProp(m)
	}
}

func (g *androidBpGenerator) staticActions(l *staticLibrary, mctx blueprint.ModuleContext) {
	if !enabledAndRequired(l) {
		return
	}

	// Calculate and record outputs
	l.outs = []string{l.outputName()}

	var modType string
	switch l.Properties.TargetType {
	case tgtTypeHost:
		modType = "cc_library_host_static"
	case tgtTypeTarget:
		modType = "cc_library_static"
	}

	m, err := AndroidBpFile().NewModule(modType, l.shortName())
	if err != nil {
		panic(err.Error())
	}

	addCcLibraryProps(m, l.library, mctx)
	addStaticOrSharedLibraryProps(m, l.library, mctx)
}
<commit_msg>Export generated include dirs on Soong<commit_after>/*
 * Copyright 2020 Arm Limited.
 * SPDX-License-Identifier: Apache-2.0
 *
 * 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 core

// Support for building libraries and binaries via soong's cc_library
// modules.

import (
	"fmt"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"

	"github.com/ARM-software/bob-build/internal/bpwriter"
	"github.com/ARM-software/bob-build/internal/ccflags"
	"github.com/ARM-software/bob-build/internal/utils"
)

// Convert between Bob module names, and the name we will give the generated
// cc_library module. This is required when a module supports being built on
// host and target; we cannot create two modules with the same name, so
// instead, we use the `shortName()` (which may include a `__host` or
// `__target` suffix) to disambiguate, and use the `stem` property to fix up
// the output filename.
func ccModuleName(mctx blueprint.BaseModuleContext, name string) string {
	var dep blueprint.Module

	mctx.VisitDirectDeps(func(m blueprint.Module) {
		if m.Name() == name {
			dep = m
		}
	})

	if dep == nil {
		panic(fmt.Errorf("%s has no dependency '%s'", mctx.ModuleName(), name))
	}

	if l, ok := getLibrary(dep); ok {
		return l.shortName()
	}

	// Most cases should match the getLibrary() check above, but generated libraries,
	// etc, do not, and they also do not require using shortName() (because of not
	// being target-specific), so just use the original build.bp name.
	return dep.Name()
}

func ccModuleNames(mctx blueprint.BaseModuleContext, nameLists ...[]string) []string {
	ccModules := []string{}
	for _, nameList := range nameLists {
		for _, name := range nameList {
			ccModules = append(ccModules, ccModuleName(mctx, name))
		}
	}
	return ccModules
}

func (l *library) getGeneratedSourceModules(mctx blueprint.BaseModuleContext) (srcs []string) {
	mctx.VisitDirectDepsIf(
		func(dep blueprint.Module) bool {
			return mctx.OtherModuleDependencyTag(dep) == generatedSourceTag
		},
		func(dep blueprint.Module) {
			switch dep.(type) {
			case *generateSource:
			case *transformSource:
			default:
				panic(fmt.Errorf("Dependency %s of %s is not a generated source",
					dep.Name(), l.Name()))
			}

			srcs = append(srcs, dep.Name())
		})
	return
}

func (l *library) getGeneratedHeaderModules(mctx blueprint.BaseModuleContext) (headers []string) {
	mctx.VisitDirectDepsIf(
		func(dep blueprint.Module) bool {
			return mctx.OtherModuleDependencyTag(dep) == generatedHeaderTag
		},
		func(dep blueprint.Module) {
			switch dep.(type) {
			case *generateSource:
			case *transformSource:
			default:
				panic(fmt.Errorf("Dependency %s of %s is not a generated source",
					dep.Name(), l.Name()))
			}

			headers = append(headers, dep.Name())
		})
	return
}

func addProvenanceProps(m bpwriter.Module, props AndroidProps) {
	if props.Owner != "" {
		m.AddString("owner", props.Owner)
		m.AddBool("vendor", true)
		m.AddBool("proprietary", true)
		m.AddBool("soc_specific", true)
	}
}

func addCFlags(m bpwriter.Module, cflags []string, conlyFlags []string, cxxFlags []string) error {
	if std := ccflags.GetCompilerStandard(cflags, conlyFlags); std != "" {
		m.AddString("c_std", std)
	}

	if std := ccflags.GetCompilerStandard(cflags, cxxFlags); std != "" {
		m.AddString("cpp_std", std)
	}

	armMode, err := ccflags.GetArmMode(cflags, conlyFlags, cxxFlags)
	if err != nil {
		return err
	}

	if armMode != "" {
		m.AddString("instruction_set", armMode)
	}

	m.AddStringList("cflags", utils.Filter(ccflags.AndroidCompileFlags, cflags))
	m.AddStringList("conlyflags", utils.Filter(ccflags.AndroidCompileFlags, conlyFlags))
	m.AddStringList("cppflags", utils.Filter(ccflags.AndroidCompileFlags, cxxFlags))
	return nil
}

func addCcLibraryProps(m bpwriter.Module, l library, mctx blueprint.ModuleContext) {
	if len(l.Properties.Export_include_dirs) > 0 {
		panic(fmt.Errorf("Module %s exports non-local include dirs %v - this is not supported",
			mctx.ModuleName(), l.Properties.Export_include_dirs))
	}

	// Soong deals with exported include directories between library
	// modules, but it doesn't export cflags.
	_, _, exported_cflags := l.GetExportedVariables(mctx)

	cflags := utils.NewStringSlice(l.Properties.Cflags, l.Properties.Export_cflags, exported_cflags)

	sharedLibs := ccModuleNames(mctx, l.Properties.Shared_libs)
	staticLibs := ccModuleNames(mctx, l.Properties.ResolvedStaticLibs)
	// Exported header libraries must be mentioned in both header_libs
	// *and* export_header_lib_headers - i.e., we can't export a header
	// library which isn't actually being used.
	headerLibs := ccModuleNames(mctx, l.Properties.Header_libs, l.Properties.Export_header_libs)

	reexportShared := []string{}
	reexportStatic := []string{}
	reexportHeaders := ccModuleNames(mctx, l.Properties.Export_header_libs)
	for _, lib := range ccModuleNames(mctx, l.Properties.Reexport_libs) {
		if utils.Contains(sharedLibs, lib) {
			reexportShared = append(reexportShared, lib)
		} else if utils.Contains(staticLibs, lib) {
			reexportStatic = append(reexportStatic, lib)
		} else if utils.Contains(headerLibs, lib) {
			reexportHeaders = append(reexportHeaders, lib)
		}
	}

	if l.shortName() != l.outputName() {
		m.AddString("stem", l.outputName())
	}
	m.AddStringList("srcs", utils.Filter(utils.IsCompilableSource, l.Properties.Srcs))
	m.AddStringList("generated_sources", l.getGeneratedSourceModules(mctx))
	genHeaderModules := l.getGeneratedHeaderModules(mctx)
	m.AddStringList("generated_headers", genHeaderModules)
	m.AddStringList("export_generated_headers", genHeaderModules)
	m.AddStringList("exclude_srcs", l.Properties.Exclude_srcs)
	err := addCFlags(m, cflags, l.Properties.Conlyflags, l.Properties.Cxxflags)
	if err != nil {
		panic(fmt.Errorf("Module %s: %s", mctx.ModuleName(), err.Error()))
	}
	m.AddStringList("include_dirs", l.Properties.Include_dirs)
	m.AddStringList("local_include_dirs", l.Properties.Local_include_dirs)
	m.AddStringList("shared_libs", ccModuleNames(mctx, l.Properties.Shared_libs))
	m.AddStringList("static_libs", staticLibs)
	m.AddStringList("whole_static_libs", ccModuleNames(mctx, l.Properties.Whole_static_libs))
	m.AddStringList("header_libs", headerLibs)
	m.AddStringList("export_shared_lib_headers", reexportShared)
	m.AddStringList("export_static_lib_headers", reexportStatic)
	m.AddStringList("export_header_lib_headers", reexportHeaders)
	m.AddStringList("ldflags", l.Properties.Ldflags)
	if l.getInstallableProps().Relative_install_path != nil {
		m.AddString("relative_install_path", proptools.String(l.getInstallableProps().Relative_install_path))
	}

	addProvenanceProps(m, l.Properties.Build.AndroidProps)
}

func addStaticOrSharedLibraryProps(m bpwriter.Module, l library, mctx blueprint.ModuleContext) {
	// Soong's `export_include_dirs` field is relative to the module
	// dir. The Android.bp backend writes the file into the project
	// root, so we can use the Export_local_include_dirs property
	// unchanged.
	m.AddStringList("export_include_dirs", l.Properties.Export_local_include_dirs)
}

func addStripProp(m bpwriter.Module) {
	g := m.NewGroup("strip")
	g.AddBool("all", true)
}

func (g *androidBpGenerator) binaryActions(l *binary, mctx blueprint.ModuleContext) {
	if !enabledAndRequired(l) {
		return
	}

	// Calculate and record outputs
	l.outs = []string{l.outputName()}

	var modType string
	switch l.Properties.TargetType {
	case tgtTypeHost:
		modType = "cc_binary_host"
	case tgtTypeTarget:
		modType = "cc_binary"
	}

	m, err := AndroidBpFile().NewModule(modType, l.shortName())
	if err != nil {
		panic(err.Error())
	}

	addCcLibraryProps(m, l.library, mctx)
	if l.strip() {
		addStripProp(m)
	}
}

func (g *androidBpGenerator) sharedActions(l *sharedLibrary, mctx blueprint.ModuleContext) {
	if !enabledAndRequired(l) {
		return
	}

	// Calculate and record outputs
	l.outs = []string{l.outputName() + l.fileNameExtension}

	var modType string
	switch l.Properties.TargetType {
	case tgtTypeHost:
		modType = "cc_library_host_shared"
	case tgtTypeTarget:
		modType = "cc_library_shared"
	}

	m, err := AndroidBpFile().NewModule(modType, l.shortName())
	if err != nil {
		panic(err.Error())
	}

	addCcLibraryProps(m, l.library, mctx)
	addStaticOrSharedLibraryProps(m, l.library, mctx)
	if l.strip() {
		addStripProp(m)
	}
}

func (g *androidBpGenerator) staticActions(l *staticLibrary, mctx blueprint.ModuleContext) {
	if !enabledAndRequired(l) {
		return
	}

	// Calculate and record outputs
	l.outs = []string{l.outputName()}

	var modType string
	switch l.Properties.TargetType {
	case tgtTypeHost:
		modType = "cc_library_host_static"
	case tgtTypeTarget:
		modType = "cc_library_static"
	}

	m, err := AndroidBpFile().NewModule(modType, l.shortName())
	if err != nil {
		panic(err.Error())
	}

	addCcLibraryProps(m, l.library, mctx)
	addStaticOrSharedLibraryProps(m, l.library, mctx)
}
<|endoftext|>


<commit_before>// +build linux,!no_oci_worker

package main

import (
	"os/exec"

	ctdsnapshot "github.com/containerd/containerd/snapshots"
	"github.com/containerd/containerd/snapshots/native"
	"github.com/containerd/containerd/snapshots/overlay"
	"github.com/moby/buildkit/worker"
	"github.com/moby/buildkit/worker/base"
	"github.com/moby/buildkit/worker/runc"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"github.com/urfave/cli"
)

func init() {
	flags := []cli.Flag{
		cli.StringFlag{
			Name:  "oci-worker",
			Usage: "enable oci workers (true/false/auto)",
			Value: "auto",
		},
		cli.StringSliceFlag{
			Name:  "oci-worker-labels",
			Usage: "user-specific annotation labels (com.example.foo=bar)",
		},
		cli.StringFlag{
			Name:  "oci-worker-snapshotter",
			Usage: "name of snapshotter (overlayfs or native)",
			Value: "auto",
		},
	}
	n := "oci-worker-rootless"
	u := "enable rootless mode"
	if runningAsUnprivilegedUser() {
		flags = append(flags, cli.BoolTFlag{
			Name:  n,
			Usage: u,
		})
	} else {
		flags = append(flags, cli.BoolFlag{
			Name:  n,
			Usage: u,
		})
	}
	registerWorkerInitializer(
		workerInitializer{
			fn:       ociWorkerInitializer,
			priority: 0,
		},
		flags...,
	)
	// TODO: allow multiple oci runtimes
}

func ociWorkerInitializer(c *cli.Context, common workerInitializerOpt) ([]worker.Worker, error) {
	boolOrAuto, err := parseBoolOrAuto(c.GlobalString("oci-worker"))
	if err != nil {
		return nil, err
	}
	if (boolOrAuto == nil && !validOCIBinary()) || (boolOrAuto != nil && !*boolOrAuto) {
		return nil, nil
	}
	labels, err := attrMap(c.GlobalStringSlice("oci-worker-labels"))
	if err != nil {
		return nil, err
	}
	snFactory, err := snapshotterFactory(c.GlobalString("oci-worker-snapshotter"))
	if err != nil {
		return nil, err
	}
	// GlobalBool works for BoolT as well
	rootless := c.GlobalBool("oci-worker-rootless") || c.GlobalBool("rootless")
	if rootless {
		logrus.Debugf("running in rootless mode")
	}
	opt, err := runc.NewWorkerOpt(common.root, snFactory, rootless, labels)
	if err != nil {
		return nil, err
	}
	opt.SessionManager = common.sessionManager
	w, err := base.NewWorker(opt)
	if err != nil {
		return nil, err
	}
	return []worker.Worker{w}, nil
}

func snapshotterFactory(name string) (runc.SnapshotterFactory, error) {
	snFactory := runc.SnapshotterFactory{
		Name: name,
	}
	var err error
	switch name {
	case "auto":
		snFactory.New = func(root string) (ctdsnapshot.Snapshotter, error) {
			err := overlay.Supported(root)
			if err == nil {
				logrus.Debug("auto snapshotter: using overlayfs")
				return overlay.NewSnapshotter(root)
			}
			logrus.Debugf("auto snapshotter: using native for %s: %v", root, err)
			return native.NewSnapshotter(root)
		}
	case "native":
		snFactory.New = native.NewSnapshotter
	case "overlayfs": // not "overlay", for consistency with containerd snapshotter plugin ID.
		snFactory.New = func(root string) (ctdsnapshot.Snapshotter, error) {
			return overlay.NewSnapshotter(root)
		}
	default:
		err = errors.Errorf("unknown snapshotter name: %q", name)
	}
	return snFactory, err
}

func validOCIBinary() bool {
	_, err := exec.LookPath("runc")
	if err != nil {
		logrus.Warnf("skipping oci worker, as runc does not exist")
		return false
	}
	return true
}
<commit_msg>oci-worker: resolve snapshotter label to real name<commit_after>// +build linux,!no_oci_worker

package main

import (
	"os/exec"

	ctdsnapshot "github.com/containerd/containerd/snapshots"
	"github.com/containerd/containerd/snapshots/native"
	"github.com/containerd/containerd/snapshots/overlay"
	"github.com/moby/buildkit/worker"
	"github.com/moby/buildkit/worker/base"
	"github.com/moby/buildkit/worker/runc"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"github.com/urfave/cli"
)

func init() {
	flags := []cli.Flag{
		cli.StringFlag{
			Name:  "oci-worker",
			Usage: "enable oci workers (true/false/auto)",
			Value: "auto",
		},
		cli.StringSliceFlag{
			Name:  "oci-worker-labels",
			Usage: "user-specific annotation labels (com.example.foo=bar)",
		},
		cli.StringFlag{
			Name:  "oci-worker-snapshotter",
			Usage: "name of snapshotter (overlayfs or native)",
			Value: "auto",
		},
	}
	n := "oci-worker-rootless"
	u := "enable rootless mode"
	if runningAsUnprivilegedUser() {
		flags = append(flags, cli.BoolTFlag{
			Name:  n,
			Usage: u,
		})
	} else {
		flags = append(flags, cli.BoolFlag{
			Name:  n,
			Usage: u,
		})
	}
	registerWorkerInitializer(
		workerInitializer{
			fn:       ociWorkerInitializer,
			priority: 0,
		},
		flags...,
	)
	// TODO: allow multiple oci runtimes
}

func ociWorkerInitializer(c *cli.Context, common workerInitializerOpt) ([]worker.Worker, error) {
	boolOrAuto, err := parseBoolOrAuto(c.GlobalString("oci-worker"))
	if err != nil {
		return nil, err
	}
	if (boolOrAuto == nil && !validOCIBinary()) || (boolOrAuto != nil && !*boolOrAuto) {
		return nil, nil
	}
	labels, err := attrMap(c.GlobalStringSlice("oci-worker-labels"))
	if err != nil {
		return nil, err
	}
	snFactory, err := snapshotterFactory(common.root, c.GlobalString("oci-worker-snapshotter"))
	if err != nil {
		return nil, err
	}
	// GlobalBool works for BoolT as well
	rootless := c.GlobalBool("oci-worker-rootless") || c.GlobalBool("rootless")
	if rootless {
		logrus.Debugf("running in rootless mode")
	}
	opt, err := runc.NewWorkerOpt(common.root, snFactory, rootless, labels)
	if err != nil {
		return nil, err
	}
	opt.SessionManager = common.sessionManager
	w, err := base.NewWorker(opt)
	if err != nil {
		return nil, err
	}
	return []worker.Worker{w}, nil
}

func snapshotterFactory(commonRoot, name string) (runc.SnapshotterFactory, error) {
	if name == "auto" {
		if err := overlay.Supported(commonRoot); err == nil {
			logrus.Debug("auto snapshotter: using overlayfs")
			name = "overlayfs"
		} else {
			logrus.Debugf("auto snapshotter: using native, because overlayfs is not available for %s: %v", commonRoot, err)
			name = "native"
		}
	}
	snFactory := runc.SnapshotterFactory{
		Name: name,
	}
	switch name {
	case "native":
		snFactory.New = native.NewSnapshotter
	case "overlayfs": // not "overlay", for consistency with containerd snapshotter plugin ID.
		snFactory.New = func(root string) (ctdsnapshot.Snapshotter, error) {
			return overlay.NewSnapshotter(root)
		}
	default:
		return snFactory, errors.Errorf("unknown snapshotter name: %q", name)
	}
	return snFactory, nil
}

func validOCIBinary() bool {
	_, err := exec.LookPath("runc")
	if err != nil {
		logrus.Warnf("skipping oci worker, as runc does not exist")
		return false
	}
	return true
}
<|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 images

import (
	"fmt"

	"k8s.io/klog/v2"

	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
	kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
	"k8s.io/kubernetes/cmd/kubeadm/app/constants"
	kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
)

// GetGenericImage generates and returns a platform agnostic image (backed by manifest list)
func GetGenericImage(prefix, image, tag string) string {
	return fmt.Sprintf("%s/%s:%s", prefix, image, tag)
}

// GetKubernetesImage generates and returns the image for the components managed in the Kubernetes main repository,
// including the control-plane components and kube-proxy.
func GetKubernetesImage(image string, cfg *kubeadmapi.ClusterConfiguration) string {
	repoPrefix := cfg.GetControlPlaneImageRepository()
	kubernetesImageTag := kubeadmutil.KubernetesVersionToImageTag(cfg.KubernetesVersion)
	return GetGenericImage(repoPrefix, image, kubernetesImageTag)
}

// GetDNSImage generates and returns the image for CoreDNS.
func GetDNSImage(cfg *kubeadmapi.ClusterConfiguration) string {
	// DNS uses default image repository by default
	dnsImageRepository := cfg.ImageRepository
	// unless an override is specified
	if cfg.DNS.ImageRepository != "" {
		dnsImageRepository = cfg.DNS.ImageRepository
	}
	// Handle the renaming of the official image from "registry.k8s.io/coredns" to "registry.k8s.io/coredns/coredns
	if dnsImageRepository == kubeadmapiv1beta2.DefaultImageRepository {
		dnsImageRepository = fmt.Sprintf("%s/coredns", dnsImageRepository)
	}
	// DNS uses an imageTag that corresponds to the DNS version matching the Kubernetes version
	dnsImageTag := constants.CoreDNSVersion

	// unless an override is specified
	if cfg.DNS.ImageTag != "" {
		dnsImageTag = cfg.DNS.ImageTag
	}
	return GetGenericImage(dnsImageRepository, constants.CoreDNSImageName, dnsImageTag)
}

// GetEtcdImage generates and returns the image for etcd
func GetEtcdImage(cfg *kubeadmapi.ClusterConfiguration) string {
	// Etcd uses default image repository by default
	etcdImageRepository := cfg.ImageRepository
	// unless an override is specified
	if cfg.Etcd.Local != nil && cfg.Etcd.Local.ImageRepository != "" {
		etcdImageRepository = cfg.Etcd.Local.ImageRepository
	}
	// Etcd uses an imageTag that corresponds to the etcd version matching the Kubernetes version
	etcdImageTag := constants.DefaultEtcdVersion
	etcdVersion, warning, err := constants.EtcdSupportedVersion(constants.SupportedEtcdVersion, cfg.KubernetesVersion)
	if err == nil {
		etcdImageTag = etcdVersion.String()
	}
	if warning != nil {
		klog.Warningln(warning)
	}
	// unless an override is specified
	if cfg.Etcd.Local != nil && cfg.Etcd.Local.ImageTag != "" {
		etcdImageTag = cfg.Etcd.Local.ImageTag
	}
	return GetGenericImage(etcdImageRepository, constants.Etcd, etcdImageTag)
}

// GetControlPlaneImages returns a list of container images kubeadm expects to use on a control plane node
func GetControlPlaneImages(cfg *kubeadmapi.ClusterConfiguration) []string {
	imgs := []string{}

	// start with core kubernetes images
	imgs = append(imgs, GetKubernetesImage(constants.KubeAPIServer, cfg))
	imgs = append(imgs, GetKubernetesImage(constants.KubeControllerManager, cfg))
	imgs = append(imgs, GetKubernetesImage(constants.KubeScheduler, cfg))
	imgs = append(imgs, GetKubernetesImage(constants.KubeProxy, cfg))

	// pause is not available on the ci image repository so use the default image repository.
	imgs = append(imgs, GetPauseImage(cfg))

	// if etcd is not external then add the image as it will be required
	if cfg.Etcd.Local != nil {
		imgs = append(imgs, GetEtcdImage(cfg))
	}

	// Append the appropriate DNS images
	imgs = append(imgs, GetDNSImage(cfg))

	return imgs
}

// GetPauseImage returns the image for the "pause" container
func GetPauseImage(cfg *kubeadmapi.ClusterConfiguration) string {
	return GetGenericImage(cfg.ImageRepository, "pause", constants.PauseVersion)
}
<commit_msg>Optimize name rules<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 images

import (
	"fmt"

	"k8s.io/klog/v2"

	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
	kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
	"k8s.io/kubernetes/cmd/kubeadm/app/constants"
	kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
)

// GetGenericImage generates and returns a platform agnostic image (backed by manifest list)
func GetGenericImage(prefix, image, tag string) string {
	return fmt.Sprintf("%s/%s:%s", prefix, image, tag)
}

// GetKubernetesImage generates and returns the image for the components managed in the Kubernetes main repository,
// including the control-plane components and kube-proxy.
func GetKubernetesImage(image string, cfg *kubeadmapi.ClusterConfiguration) string {
	repoPrefix := cfg.GetControlPlaneImageRepository()
	kubernetesImageTag := kubeadmutil.KubernetesVersionToImageTag(cfg.KubernetesVersion)
	return GetGenericImage(repoPrefix, image, kubernetesImageTag)
}

// GetDNSImage generates and returns the image for CoreDNS.
func GetDNSImage(cfg *kubeadmapi.ClusterConfiguration) string {
	// DNS uses default image repository by default
	dnsImageRepository := cfg.ImageRepository
	// unless an override is specified
	if cfg.DNS.ImageRepository != "" {
		dnsImageRepository = cfg.DNS.ImageRepository
	}
	// Handle the renaming of the official image from "registry.k8s.io/coredns" to "registry.k8s.io/coredns/coredns
	if dnsImageRepository == kubeadmapiv1beta2.DefaultImageRepository {
		dnsImageRepository = fmt.Sprintf("%s/coredns", dnsImageRepository)
	}
	// DNS uses an imageTag that corresponds to the DNS version matching the Kubernetes version
	dnsImageTag := constants.CoreDNSVersion

	// unless an override is specified
	if cfg.DNS.ImageTag != "" {
		dnsImageTag = cfg.DNS.ImageTag
	}
	return GetGenericImage(dnsImageRepository, constants.CoreDNSImageName, dnsImageTag)
}

// GetEtcdImage generates and returns the image for etcd
func GetEtcdImage(cfg *kubeadmapi.ClusterConfiguration) string {
	// Etcd uses default image repository by default
	etcdImageRepository := cfg.ImageRepository
	// unless an override is specified
	if cfg.Etcd.Local != nil && cfg.Etcd.Local.ImageRepository != "" {
		etcdImageRepository = cfg.Etcd.Local.ImageRepository
	}
	// Etcd uses an imageTag that corresponds to the etcd version matching the Kubernetes version
	etcdImageTag := constants.DefaultEtcdVersion
	etcdVersion, warning, err := constants.EtcdSupportedVersion(constants.SupportedEtcdVersion, cfg.KubernetesVersion)
	if err == nil {
		etcdImageTag = etcdVersion.String()
	}
	if warning != nil {
		klog.Warningln(warning)
	}
	// unless an override is specified
	if cfg.Etcd.Local != nil && cfg.Etcd.Local.ImageTag != "" {
		etcdImageTag = cfg.Etcd.Local.ImageTag
	}
	return GetGenericImage(etcdImageRepository, constants.Etcd, etcdImageTag)
}

// GetControlPlaneImages returns a list of container images kubeadm expects to use on a control plane node
func GetControlPlaneImages(cfg *kubeadmapi.ClusterConfiguration) []string {
	images := make([]string, 0)

	// start with core kubernetes images
	images = append(images, GetKubernetesImage(constants.KubeAPIServer, cfg))
	images = append(images, GetKubernetesImage(constants.KubeControllerManager, cfg))
	images = append(images, GetKubernetesImage(constants.KubeScheduler, cfg))
	images = append(images, GetKubernetesImage(constants.KubeProxy, cfg))

	// pause is not available on the ci image repository so use the default image repository.
	images = append(images, GetPauseImage(cfg))

	// if etcd is not external then add the image as it will be required
	if cfg.Etcd.Local != nil {
		images = append(images, GetEtcdImage(cfg))
	}

	// Append the appropriate DNS images
	images = append(images, GetDNSImage(cfg))

	return images
}

// GetPauseImage returns the image for the "pause" container
func GetPauseImage(cfg *kubeadmapi.ClusterConfiguration) string {
	return GetGenericImage(cfg.ImageRepository, "pause", constants.PauseVersion)
}
<|endoftext|>


<commit_before>/*
   PulseHA - HA Cluster Daemon
   Copyright (C) 2017  Andrew Zak <andrew@pulseha.com>

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published
   by the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package main

import (
	"encoding/json"
	"errors"
	p "github.com/Syleron/PulseHA/proto"
	"github.com/Syleron/PulseHA/src/utils"
	log "github.com/Sirupsen/logrus"
	"google.golang.org/grpc/connectivity"
	"sync"
	"time"
)

/**
 * Memberlist struct type
 */
type Memberlist struct {
	Members []*Member
	sync.Mutex
}

/**

 */
func (m *Memberlist) Lock() {
	//_, _, no, _ := runtime.Caller(1)
	//log.Debugf("Memberlist:Lock() Lock set line: %d by %s", no, MyCaller())
	m.Mutex.Lock()
}

/**

 */
func (m *Memberlist) Unlock() {
	//_, _, no, _ := runtime.Caller(1)
	//log.Debugf("Memberlist:Unlock() Unlock set line: %d by %s", no, MyCaller())
	m.Mutex.Unlock()
}

/**
 * Add a member to the client list
 */
func (m *Memberlist) AddMember(hostname string, client *Client) {
	if !m.MemberExists(hostname) {
		log.Debug("Memberlist:MemberAdd() " + hostname + " added to memberlist")
		m.Lock()
		newMember := &Member{}
		newMember.setHostname(hostname)
		newMember.setStatus(p.MemberStatus_UNAVAILABLE)
		newMember.setClient(*client)
		m.Members = append(m.Members, newMember)
		m.Unlock()
	} else {
		log.Debug("Memberlist:MemberAdd() Member " + hostname + " already exists. Skipping.")
	}
}

/**
 * Remove a member from the client list by hostname
 */
func (m *Memberlist) MemberRemoveByName(hostname string) {
	log.Debug("Memberlist:MemberRemoveByName() " + hostname + " removed from the memberlist")
	m.Lock()
	defer m.Unlock()
	for i, member := range m.Members {
		if member.getHostname() == hostname {
			m.Members = append(m.Members[:i], m.Members[i+1:]...)
		}
	}
}

/**
 * Return Member by hostname
 */
func (m *Memberlist) GetMemberByHostname(hostname string) *Member {
	m.Lock()
	defer m.Unlock()
	if hostname == "" {
		log.Warning("Memberlist:GetMemberByHostname() Unable to get get member by hostname as hostname is empty!")
	}
	for _, member := range m.Members {
		if member.getHostname() == hostname {
			return member
		}
	}
	return nil
}

/**
 * Return true/false whether a member exists or not.
 */
func (m *Memberlist) MemberExists(hostname string) bool {
	m.Lock()
	defer m.Unlock()
	for _, member := range m.Members {
		if member.getHostname() == hostname {
			return true
		}
	}
	return false
}

/**
 * Attempt to broadcast a client function to other nodes (clients) within the memberlist
 */
func (m *Memberlist) Broadcast(funcName protoFunction, data interface{}) {
	log.Debug("Memberlist:Broadcast() Broadcasting " + funcName.String())
	m.Lock()
	defer m.Unlock()
	for _, member := range m.Members {
		// We don't want to broadcast to our self!
		if member.getHostname() == utils.GetHostname() {
			continue
		}
		log.Debugf("Broadcast: %s to member %s", funcName.String(), member.getHostname())
		member.Connect()
		member.Send(funcName, data)
	}
}

/**
Setup process for the memberlist
*/
func (m *Memberlist) Setup() {
	// Load members into our memberlist slice
	m.LoadMembers()
	// Check to see if we are in a cluster
	if gconf.ClusterCheck() {
		// Are we the only member in the cluster?
		if gconf.ClusterTotal() == 1 {
			// We are the only member in the cluster so
			// we are assume that we are now the active appliance.
			m.PromoteMember(gconf.getLocalNode())
		} else {
			// come up passive and monitoring health checks
			localMember := m.GetMemberByHostname(gconf.getLocalNode())
			//localMember.setLastHCResponse(time.Now().Add(time.Duration(10) * time.Second))
			localMember.setLastHCResponse(time.Now())
			localMember.setStatus(p.MemberStatus_PASSIVE)
			log.Debug("Memberlist:Setup() - starting the monitor received health checks scheduler")
			go utils.Scheduler(localMember.monitorReceivedHCs, 2000*time.Millisecond)
		}
	}
}

/**
load the nodes in our config into our memberlist
*/
func (m *Memberlist) LoadMembers() {
	config := gconf.GetConfig()
	for key := range config.Nodes {
		newClient := &Client{}
		m.AddMember(key, newClient)
	}
}

/**

 */
func (m *Memberlist) Reload() {
	log.Debug("Memberlist:ReloadMembers() Reloading member nodes")
	// Do a config reload
	gconf.Reload()
	// clear local members
	m.LoadMembers()
}

/**
Get status of a specific member by hostname
*/
func (m *Memberlist) MemberGetStatus(hostname string) (p.MemberStatus_Status, error) {
	m.Lock()
	defer m.Unlock()
	for _, member := range m.Members {
		if member.getHostname() == hostname {
			return member.getStatus(), nil
		}
	}
	return p.MemberStatus_UNAVAILABLE, errors.New("unable to find member with hostname " + hostname)
}

/*
	Return the hostname of the active member
	or empty string if non are active
*/
func (m *Memberlist) getActiveMember() (string, *Member) {
	for _, member := range m.Members {
		if member.getStatus() == p.MemberStatus_ACTIVE {
			return member.getHostname(), member
		}
	}
	return "", nil
}

/**
Promote a member within the memberlist to become the active
node
*/
func (m *Memberlist) PromoteMember(hostname string) error {
	log.Debug("Memberlist:PromoteMember() Memberlist promoting " + hostname + " as active member..")
	// Inform everyone in the cluster that a specific node is now the new active
	// Demote if old active is no longer active. promote if the passive is the new active.
	// get host is it active?
	// Make sure the hostname member exists
	member := m.GetMemberByHostname(hostname)
	if member == nil {
		log.Errorf("Unknown hostname %s give in call to promoteMember", hostname)
		return errors.New("the specified host does not exist in the configured cluster")
	}
	// if unavailable check it works or do nothing?
	switch member.getStatus() {
	case p.MemberStatus_UNAVAILABLE:
		//If we are the only node and just configured we will be unavailable
		if gconf.nodeCount() > 1 {
			log.Errorf("Unable to promote member %s because it is unavailable", member.getHostname())
			return errors.New("unable to promote member as it is unavailable")
		}
	case p.MemberStatus_ACTIVE:
		log.Errorf("Unable to promote member %s as it is active", member.getHostname())
		return errors.New("unable to promote member as it is already active")
	}
	// get the current active member
	_, activeMember := m.getActiveMember()
	// handle if we do not have an active member
	if activeMember != nil {
		// Make the current Active appliance passive
		success := activeMember.makePassive()
		if !success {
			log.Errorf("Failed to make %s passive, continuing", activeMember.getHostname())
		}
		// TODO: Note: Do we need this?
		// Update our local value for the active member
		activeMember.setStatus(p.MemberStatus_PASSIVE)
	}
	// make the hostname the new active
	success := member.makeActive()
	// make new node active
	if !success {
		log.Errorf("Failed to promote %s to active. Falling back to %s", member.getHostname(), activeMember.getHostname())
		// Somethings gone wrong.. attempt to make the previous active - active again.
		success := activeMember.makeActive()
		if !success {
			log.Error("Failed to make reinstate the active node. Something is really wrong")
		}
		// Note: we don't need to update the active status as we should recieve an updated memberlist from the active
	}
	return nil
}

/**
	Function is only to be run on the active appliance
	Note: THis is not the final function name.. or not sure if this is
          where this logic will stay.. just playing around at this point.
	monitors the connections states for each member
*/
func (m *Memberlist) monitorClientConns() bool {
	// make sure we are still the active appliance
	member, err := m.getLocalMember()
	if err != nil {
		log.Debug("Memberlist:monitorClientConns() Client monitoring has stopped as it seems we are no longer in a cluster")
		return true
	}
	if member.getStatus() == p.MemberStatus_PASSIVE {
		log.Debug("Memberlist:monitorClientConns() Client monitoring has stopped as we are no longer active")
		return true
	}
	for _, member := range m.Members {
		if member.getHostname() == gconf.getLocalNode() {
			continue
		}
		member.Connect()
		log.Debug(member.Hostname + " connection status is " + member.Connection.GetState().String())
		switch member.Connection.GetState() {
		case connectivity.Idle:
		case connectivity.Ready:
			member.setStatus(p.MemberStatus_PASSIVE)
		default:
			member.setStatus(p.MemberStatus_UNAVAILABLE)
		}
	}
	return false
}

/**
Send health checks to users who have a healthy connection
*/
func (m *Memberlist) addHealthCheckHandler() bool{
	// make sure we are still the active appliance
	member, err := m.getLocalMember()
	if err != nil {
		log.Debug("Memberlist:addHealthCheckhandler() Health check handler has stopped as it seems we are no longer in a cluster")
		return true
	}
	if member.getStatus() == p.MemberStatus_PASSIVE {
		log.Debug("Memberlist:addHealthCheckHandler() Health check handler has stopped as it seems we are no longer active")
		return true
	}
	for _, member := range m.Members {
		if member.getHostname() == gconf.getLocalNode() {
			continue
		}
		if !member.getHCBusy() && member.getStatus() == p.MemberStatus_PASSIVE {
			memberlist := new(p.PulseHealthCheck)
			for _, member := range m.Members {
				newMember := &p.MemberlistMember{
					Hostname: member.getHostname(),
					Status:   member.getStatus(),
					Latency: member.getLatency(),
					LastReceived: member.getLastHCResponse().Format(time.RFC1123),
				}
				memberlist.Memberlist = append(memberlist.Memberlist, newMember)
			}
			go member.routineHC(memberlist)
		}
	}
	return false
}

/**
Sync local config with each member in the cluster.
*/
func (m *Memberlist) SyncConfig() error {
	log.Debug("Memberlist:SyncConfig Syncing config with peers..")
	// Return with our new updated config
	buf, err := json.Marshal(gconf.GetConfig())
	// Handle failure to marshal config
	if err != nil {
		return errors.New("unable to sync config " + err.Error())
	}
	m.Broadcast(SendConfigSync, &p.PulseConfigSync{
		Replicated: true,
		Config:     buf,
	})
	return nil
}

/**
Update the local memberlist statuses based on the proto memberlist message
*/
func (m *Memberlist) update(memberlist []*p.MemberlistMember) {
	log.Debug("Memberlist:update() Updating memberlist")
	m.Lock()
	defer m.Unlock()
	 //do not update the memberlist if we are active
	for _, member := range memberlist {
		for _, localMember := range m.Members {
			if member.GetHostname() == localMember.getHostname() {
				localMember.setStatus(member.Status)
				localMember.setLatency(member.Latency)
				// our local last received has priority
				if member.GetHostname() != gconf.getLocalNode() {
					tym, _ := time.Parse(time.RFC1123, member.LastReceived)
					localMember.setLastHCResponse(tym)
				}
				break
			}
		}
	}
}

/**
Calculate who's next to become active in the memberlist
*/
func (m *Memberlist) getNextActiveMember() (*Member, error) {
	for hostname, _ := range gconf.Nodes {
		member := m.GetMemberByHostname(hostname)
		if member == nil {
			panic("Memberlist:getNextActiveMember() Cannot get member by hostname " + hostname)
		}
		if member.getStatus() == p.MemberStatus_PASSIVE {
			log.Debug("Memberlist:getNextActiveMember() " + member.getHostname() + " is the new active appliance")
			return member, nil
		}
	}
	return &Member{}, errors.New("Memberlist:getNextActiveMember() No new active member found")
}

/**

*/
func (m *Memberlist) getLocalMember() (*Member, error) {
	for _, member := range m.Members {
		if member.getHostname() == gconf.getLocalNode() {
			return member, nil
		}
	}
	return &Member{}, errors.New("cannot get local member. Perhaps we are no longer in a cluster")
}

/**
Reset the memberlist when we are no longer in a cluster.
 */
func (m *Memberlist) reset() {
	m.Lock()
	defer m.Unlock()
	m.Members = []*Member{}
}<commit_msg>updated memberlist log message types<commit_after>/*
   PulseHA - HA Cluster Daemon
   Copyright (C) 2017  Andrew Zak <andrew@pulseha.com>

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published
   by the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package main

import (
	"encoding/json"
	"errors"
	p "github.com/Syleron/PulseHA/proto"
	"github.com/Syleron/PulseHA/src/utils"
	log "github.com/Sirupsen/logrus"
	"google.golang.org/grpc/connectivity"
	"sync"
	"time"
)

/**
 * Memberlist struct type
 */
type Memberlist struct {
	Members []*Member
	sync.Mutex
}

/**

 */
func (m *Memberlist) Lock() {
	//_, _, no, _ := runtime.Caller(1)
	//log.Debugf("Memberlist:Lock() Lock set line: %d by %s", no, MyCaller())
	m.Mutex.Lock()
}

/**

 */
func (m *Memberlist) Unlock() {
	//_, _, no, _ := runtime.Caller(1)
	//log.Debugf("Memberlist:Unlock() Unlock set line: %d by %s", no, MyCaller())
	m.Mutex.Unlock()
}

/**
 * Add a member to the client list
 */
func (m *Memberlist) AddMember(hostname string, client *Client) {
	if !m.MemberExists(hostname) {
		log.Debug("Memberlist:MemberAdd() " + hostname + " added to memberlist")
		m.Lock()
		newMember := &Member{}
		newMember.setHostname(hostname)
		newMember.setStatus(p.MemberStatus_UNAVAILABLE)
		newMember.setClient(*client)
		m.Members = append(m.Members, newMember)
		m.Unlock()
	} else {
		log.Debug("Memberlist:MemberAdd() Member " + hostname + " already exists. Skipping.")
	}
}

/**
 * Remove a member from the client list by hostname
 */
func (m *Memberlist) MemberRemoveByName(hostname string) {
	log.Debug("Memberlist:MemberRemoveByName() " + hostname + " removed from the memberlist")
	m.Lock()
	defer m.Unlock()
	for i, member := range m.Members {
		if member.getHostname() == hostname {
			m.Members = append(m.Members[:i], m.Members[i+1:]...)
		}
	}
}

/**
 * Return Member by hostname
 */
func (m *Memberlist) GetMemberByHostname(hostname string) *Member {
	m.Lock()
	defer m.Unlock()
	if hostname == "" {
		log.Warning("Memberlist:GetMemberByHostname() Unable to get get member by hostname as hostname is empty!")
	}
	for _, member := range m.Members {
		if member.getHostname() == hostname {
			return member
		}
	}
	return nil
}

/**
 * Return true/false whether a member exists or not.
 */
func (m *Memberlist) MemberExists(hostname string) bool {
	m.Lock()
	defer m.Unlock()
	for _, member := range m.Members {
		if member.getHostname() == hostname {
			return true
		}
	}
	return false
}

/**
 * Attempt to broadcast a client function to other nodes (clients) within the memberlist
 */
func (m *Memberlist) Broadcast(funcName protoFunction, data interface{}) {
	log.Debug("Memberlist:Broadcast() Broadcasting " + funcName.String())
	m.Lock()
	defer m.Unlock()
	for _, member := range m.Members {
		// We don't want to broadcast to our self!
		if member.getHostname() == utils.GetHostname() {
			continue
		}
		log.Debugf("Broadcast: %s to member %s", funcName.String(), member.getHostname())
		member.Connect()
		member.Send(funcName, data)
	}
}

/**
Setup process for the memberlist
*/
func (m *Memberlist) Setup() {
	// Load members into our memberlist slice
	m.LoadMembers()
	// Check to see if we are in a cluster
	if gconf.ClusterCheck() {
		// Are we the only member in the cluster?
		if gconf.ClusterTotal() == 1 {
			// We are the only member in the cluster so
			// we are assume that we are now the active appliance.
			m.PromoteMember(gconf.getLocalNode())
		} else {
			// come up passive and monitoring health checks
			localMember := m.GetMemberByHostname(gconf.getLocalNode())
			//localMember.setLastHCResponse(time.Now().Add(time.Duration(10) * time.Second))
			localMember.setLastHCResponse(time.Now())
			localMember.setStatus(p.MemberStatus_PASSIVE)
			log.Debug("Memberlist:Setup() - starting the monitor received health checks scheduler")
			go utils.Scheduler(localMember.monitorReceivedHCs, 2000*time.Millisecond)
		}
	}
}

/**
load the nodes in our config into our memberlist
*/
func (m *Memberlist) LoadMembers() {
	config := gconf.GetConfig()
	for key := range config.Nodes {
		newClient := &Client{}
		m.AddMember(key, newClient)
	}
}

/**

 */
func (m *Memberlist) Reload() {
	log.Debug("Memberlist:ReloadMembers() Reloading member nodes")
	// Do a config reload
	gconf.Reload()
	// clear local members
	m.LoadMembers()
}

/**
Get status of a specific member by hostname
*/
func (m *Memberlist) MemberGetStatus(hostname string) (p.MemberStatus_Status, error) {
	m.Lock()
	defer m.Unlock()
	for _, member := range m.Members {
		if member.getHostname() == hostname {
			return member.getStatus(), nil
		}
	}
	return p.MemberStatus_UNAVAILABLE, errors.New("unable to find member with hostname " + hostname)
}

/*
	Return the hostname of the active member
	or empty string if non are active
*/
func (m *Memberlist) getActiveMember() (string, *Member) {
	for _, member := range m.Members {
		if member.getStatus() == p.MemberStatus_ACTIVE {
			return member.getHostname(), member
		}
	}
	return "", nil
}

/**
Promote a member within the memberlist to become the active
node
*/
func (m *Memberlist) PromoteMember(hostname string) error {
	log.Debug("Memberlist:PromoteMember() Memberlist promoting " + hostname + " as active member..")
	// Inform everyone in the cluster that a specific node is now the new active
	// Demote if old active is no longer active. promote if the passive is the new active.
	// get host is it active?
	// Make sure the hostname member exists
	member := m.GetMemberByHostname(hostname)
	if member == nil {
		log.Warningf("Unknown hostname %s give in call to promoteMember", hostname)
		return errors.New("the specified host does not exist in the configured cluster")
	}
	// if unavailable check it works or do nothing?
	switch member.getStatus() {
	case p.MemberStatus_UNAVAILABLE:
		//If we are the only node and just configured we will be unavailable
		if gconf.nodeCount() > 1 {
			log.Warningf("Unable to promote member %s because it is unavailable", member.getHostname())
			return errors.New("unable to promote member as it is unavailable")
		}
	case p.MemberStatus_ACTIVE:
		log.Warningf("Unable to promote member %s as it is active", member.getHostname())
		return errors.New("unable to promote member as it is already active")
	}
	// get the current active member
	_, activeMember := m.getActiveMember()
	// handle if we do not have an active member
	if activeMember != nil {
		// Make the current Active appliance passive
		success := activeMember.makePassive()
		if !success {
			log.Warningf("Failed to make %s passive, continuing", activeMember.getHostname())
		}
		// TODO: Note: Do we need this?
		// Update our local value for the active member
		activeMember.setStatus(p.MemberStatus_PASSIVE)
	}
	// make the hostname the new active
	success := member.makeActive()
	// make new node active
	if !success {
		log.Warningf("Failed to promote %s to active. Falling back to %s", member.getHostname(), activeMember.getHostname())
		// Somethings gone wrong.. attempt to make the previous active - active again.
		success := activeMember.makeActive()
		if !success {
			log.Error("Failed to make reinstate the active node. Something is really wrong")
		}
		// Note: we don't need to update the active status as we should recieve an updated memberlist from the active
	}
	return nil
}

/**
	Function is only to be run on the active appliance
	Note: THis is not the final function name.. or not sure if this is
          where this logic will stay.. just playing around at this point.
	monitors the connections states for each member
*/
func (m *Memberlist) monitorClientConns() bool {
	// make sure we are still the active appliance
	member, err := m.getLocalMember()
	if err != nil {
		log.Debug("Memberlist:monitorClientConns() Client monitoring has stopped as it seems we are no longer in a cluster")
		return true
	}
	if member.getStatus() == p.MemberStatus_PASSIVE {
		log.Debug("Memberlist:monitorClientConns() Client monitoring has stopped as we are no longer active")
		return true
	}
	for _, member := range m.Members {
		if member.getHostname() == gconf.getLocalNode() {
			continue
		}
		member.Connect()
		log.Debug(member.Hostname + " connection status is " + member.Connection.GetState().String())
		switch member.Connection.GetState() {
		case connectivity.Idle:
		case connectivity.Ready:
			member.setStatus(p.MemberStatus_PASSIVE)
		default:
			member.setStatus(p.MemberStatus_UNAVAILABLE)
		}
	}
	return false
}

/**
Send health checks to users who have a healthy connection
*/
func (m *Memberlist) addHealthCheckHandler() bool{
	// make sure we are still the active appliance
	member, err := m.getLocalMember()
	if err != nil {
		log.Debug("Memberlist:addHealthCheckhandler() Health check handler has stopped as it seems we are no longer in a cluster")
		return true
	}
	if member.getStatus() == p.MemberStatus_PASSIVE {
		log.Debug("Memberlist:addHealthCheckHandler() Health check handler has stopped as it seems we are no longer active")
		return true
	}
	for _, member := range m.Members {
		if member.getHostname() == gconf.getLocalNode() {
			continue
		}
		if !member.getHCBusy() && member.getStatus() == p.MemberStatus_PASSIVE {
			memberlist := new(p.PulseHealthCheck)
			for _, member := range m.Members {
				newMember := &p.MemberlistMember{
					Hostname: member.getHostname(),
					Status:   member.getStatus(),
					Latency: member.getLatency(),
					LastReceived: member.getLastHCResponse().Format(time.RFC1123),
				}
				memberlist.Memberlist = append(memberlist.Memberlist, newMember)
			}
			go member.routineHC(memberlist)
		}
	}
	return false
}

/**
Sync local config with each member in the cluster.
*/
func (m *Memberlist) SyncConfig() error {
	log.Debug("Memberlist:SyncConfig Syncing config with peers..")
	// Return with our new updated config
	buf, err := json.Marshal(gconf.GetConfig())
	// Handle failure to marshal config
	if err != nil {
		return errors.New("unable to sync config " + err.Error())
	}
	m.Broadcast(SendConfigSync, &p.PulseConfigSync{
		Replicated: true,
		Config:     buf,
	})
	return nil
}

/**
Update the local memberlist statuses based on the proto memberlist message
*/
func (m *Memberlist) update(memberlist []*p.MemberlistMember) {
	log.Debug("Memberlist:update() Updating memberlist")
	m.Lock()
	defer m.Unlock()
	 //do not update the memberlist if we are active
	for _, member := range memberlist {
		for _, localMember := range m.Members {
			if member.GetHostname() == localMember.getHostname() {
				localMember.setStatus(member.Status)
				localMember.setLatency(member.Latency)
				// our local last received has priority
				if member.GetHostname() != gconf.getLocalNode() {
					tym, _ := time.Parse(time.RFC1123, member.LastReceived)
					localMember.setLastHCResponse(tym)
				}
				break
			}
		}
	}
}

/**
Calculate who's next to become active in the memberlist
*/
func (m *Memberlist) getNextActiveMember() (*Member, error) {
	for hostname, _ := range gconf.Nodes {
		member := m.GetMemberByHostname(hostname)
		if member == nil {
			panic("Memberlist:getNextActiveMember() Cannot get member by hostname " + hostname)
		}
		if member.getStatus() == p.MemberStatus_PASSIVE {
			log.Debug("Memberlist:getNextActiveMember() " + member.getHostname() + " is the new active appliance")
			return member, nil
		}
	}
	return &Member{}, errors.New("Memberlist:getNextActiveMember() No new active member found")
}

/**

*/
func (m *Memberlist) getLocalMember() (*Member, error) {
	for _, member := range m.Members {
		if member.getHostname() == gconf.getLocalNode() {
			return member, nil
		}
	}
	return &Member{}, errors.New("cannot get local member. Perhaps we are no longer in a cluster")
}

/**
Reset the memberlist when we are no longer in a cluster.
 */
func (m *Memberlist) reset() {
	m.Lock()
	defer m.Unlock()
	m.Members = []*Member{}
}<|endoftext|>


<commit_before>package commands

import (
	"os"

	"github.com/docker/docker/cli/command"
	"github.com/docker/docker/cli/command/checkpoint"
	"github.com/docker/docker/cli/command/container"
	"github.com/docker/docker/cli/command/image"
	"github.com/docker/docker/cli/command/network"
	"github.com/docker/docker/cli/command/node"
	"github.com/docker/docker/cli/command/plugin"
	"github.com/docker/docker/cli/command/registry"
	"github.com/docker/docker/cli/command/secret"
	"github.com/docker/docker/cli/command/service"
	"github.com/docker/docker/cli/command/stack"
	"github.com/docker/docker/cli/command/swarm"
	"github.com/docker/docker/cli/command/system"
	"github.com/docker/docker/cli/command/volume"
	"github.com/spf13/cobra"
)

// AddCommands adds all the commands from cli/command to the root command
func AddCommands(cmd *cobra.Command, dockerCli *command.DockerCli) {
	cmd.AddCommand(
		node.NewNodeCommand(dockerCli),
		service.NewServiceCommand(dockerCli),
		swarm.NewSwarmCommand(dockerCli),
		secret.NewSecretCommand(dockerCli),
		container.NewContainerCommand(dockerCli),
		image.NewImageCommand(dockerCli),
		system.NewSystemCommand(dockerCli),
		container.NewRunCommand(dockerCli),
		image.NewBuildCommand(dockerCli),
		network.NewNetworkCommand(dockerCli),
		hide(system.NewEventsCommand(dockerCli)),
		registry.NewLoginCommand(dockerCli),
		registry.NewLogoutCommand(dockerCli),
		registry.NewSearchCommand(dockerCli),
		system.NewVersionCommand(dockerCli),
		volume.NewVolumeCommand(dockerCli),
		hide(system.NewInfoCommand(dockerCli)),
		hide(container.NewAttachCommand(dockerCli)),
		hide(container.NewCommitCommand(dockerCli)),
		hide(container.NewCopyCommand(dockerCli)),
		hide(container.NewCreateCommand(dockerCli)),
		hide(container.NewDiffCommand(dockerCli)),
		hide(container.NewExecCommand(dockerCli)),
		hide(container.NewExportCommand(dockerCli)),
		hide(container.NewKillCommand(dockerCli)),
		hide(container.NewLogsCommand(dockerCli)),
		hide(container.NewPauseCommand(dockerCli)),
		hide(container.NewPortCommand(dockerCli)),
		hide(container.NewPsCommand(dockerCli)),
		hide(container.NewRenameCommand(dockerCli)),
		hide(container.NewRestartCommand(dockerCli)),
		hide(container.NewRmCommand(dockerCli)),
		hide(container.NewStartCommand(dockerCli)),
		hide(container.NewStatsCommand(dockerCli)),
		hide(container.NewStopCommand(dockerCli)),
		hide(container.NewTopCommand(dockerCli)),
		hide(container.NewUnpauseCommand(dockerCli)),
		hide(container.NewUpdateCommand(dockerCli)),
		hide(container.NewWaitCommand(dockerCli)),
		hide(image.NewHistoryCommand(dockerCli)),
		hide(image.NewImagesCommand(dockerCli)),
		hide(image.NewImportCommand(dockerCli)),
		hide(image.NewLoadCommand(dockerCli)),
		hide(image.NewPullCommand(dockerCli)),
		hide(image.NewPushCommand(dockerCli)),
		hide(image.NewRemoveCommand(dockerCli)),
		hide(image.NewSaveCommand(dockerCli)),
		hide(image.NewTagCommand(dockerCli)),
		hide(system.NewInspectCommand(dockerCli)),
		stack.NewStackCommand(dockerCli),
		stack.NewTopLevelDeployCommand(dockerCli),
		checkpoint.NewCheckpointCommand(dockerCli),
		plugin.NewPluginCommand(dockerCli),
	)

}

func hide(cmd *cobra.Command) *cobra.Command {
	if os.Getenv("DOCKER_HIDE_LEGACY_COMMANDS") == "" {
		return cmd
	}
	cmdCopy := *cmd
	cmdCopy.Hidden = true
	cmdCopy.Aliases = []string{}
	return &cmdCopy
}
<commit_msg>Give a order to AddCommands, for easy read and maintenance.<commit_after>package commands

import (
	"os"

	"github.com/docker/docker/cli/command"
	"github.com/docker/docker/cli/command/checkpoint"
	"github.com/docker/docker/cli/command/container"
	"github.com/docker/docker/cli/command/image"
	"github.com/docker/docker/cli/command/network"
	"github.com/docker/docker/cli/command/node"
	"github.com/docker/docker/cli/command/plugin"
	"github.com/docker/docker/cli/command/registry"
	"github.com/docker/docker/cli/command/secret"
	"github.com/docker/docker/cli/command/service"
	"github.com/docker/docker/cli/command/stack"
	"github.com/docker/docker/cli/command/swarm"
	"github.com/docker/docker/cli/command/system"
	"github.com/docker/docker/cli/command/volume"
	"github.com/spf13/cobra"
)

// AddCommands adds all the commands from cli/command to the root command
func AddCommands(cmd *cobra.Command, dockerCli *command.DockerCli) {
	cmd.AddCommand(
		// checkpoint
		checkpoint.NewCheckpointCommand(dockerCli),

		// container
		container.NewContainerCommand(dockerCli),
		container.NewRunCommand(dockerCli),

		// image
		image.NewImageCommand(dockerCli),
		image.NewBuildCommand(dockerCli),

		// node
		node.NewNodeCommand(dockerCli),

		// network
		network.NewNetworkCommand(dockerCli),

		// plugin
		plugin.NewPluginCommand(dockerCli),

		// registry
		registry.NewLoginCommand(dockerCli),
		registry.NewLogoutCommand(dockerCli),
		registry.NewSearchCommand(dockerCli),

		// secret
		secret.NewSecretCommand(dockerCli),

		// service
		service.NewServiceCommand(dockerCli),

		// system
		system.NewSystemCommand(dockerCli),
		system.NewVersionCommand(dockerCli),

		// stack
		stack.NewStackCommand(dockerCli),
		stack.NewTopLevelDeployCommand(dockerCli),

		// swarm
		swarm.NewSwarmCommand(dockerCli),

		// volume
		volume.NewVolumeCommand(dockerCli),

		// legacy commands may be hidden
		hide(system.NewEventsCommand(dockerCli)),
		hide(system.NewInfoCommand(dockerCli)),
		hide(system.NewInspectCommand(dockerCli)),
		hide(container.NewAttachCommand(dockerCli)),
		hide(container.NewCommitCommand(dockerCli)),
		hide(container.NewCopyCommand(dockerCli)),
		hide(container.NewCreateCommand(dockerCli)),
		hide(container.NewDiffCommand(dockerCli)),
		hide(container.NewExecCommand(dockerCli)),
		hide(container.NewExportCommand(dockerCli)),
		hide(container.NewKillCommand(dockerCli)),
		hide(container.NewLogsCommand(dockerCli)),
		hide(container.NewPauseCommand(dockerCli)),
		hide(container.NewPortCommand(dockerCli)),
		hide(container.NewPsCommand(dockerCli)),
		hide(container.NewRenameCommand(dockerCli)),
		hide(container.NewRestartCommand(dockerCli)),
		hide(container.NewRmCommand(dockerCli)),
		hide(container.NewStartCommand(dockerCli)),
		hide(container.NewStatsCommand(dockerCli)),
		hide(container.NewStopCommand(dockerCli)),
		hide(container.NewTopCommand(dockerCli)),
		hide(container.NewUnpauseCommand(dockerCli)),
		hide(container.NewUpdateCommand(dockerCli)),
		hide(container.NewWaitCommand(dockerCli)),
		hide(image.NewHistoryCommand(dockerCli)),
		hide(image.NewImagesCommand(dockerCli)),
		hide(image.NewImportCommand(dockerCli)),
		hide(image.NewLoadCommand(dockerCli)),
		hide(image.NewPullCommand(dockerCli)),
		hide(image.NewPushCommand(dockerCli)),
		hide(image.NewRemoveCommand(dockerCli)),
		hide(image.NewSaveCommand(dockerCli)),
		hide(image.NewTagCommand(dockerCli)),
	)

}

func hide(cmd *cobra.Command) *cobra.Command {
	// If the environment variable with name "DOCKER_HIDE_LEGACY_COMMANDS" is not empty,
	// these legacy commands (such as `docker ps`, `docker exec`, etc)
	// will not be shown in output console.
	if os.Getenv("DOCKER_HIDE_LEGACY_COMMANDS") == "" {
		return cmd
	}
	cmdCopy := *cmd
	cmdCopy.Hidden = true
	cmdCopy.Aliases = []string{}
	return &cmdCopy
}
<|endoftext|>


<commit_before>package zk

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
)

type ErrMissingServerConfigField string

func (e ErrMissingServerConfigField) Error() string {
	return fmt.Sprintf("zk: missing server config field '%s'", string(e))
}

const (
	DefaultServerTickTime                 = 2000
	DefaultServerInitLimit                = 10
	DefaultServerSyncLimit                = 5
	DefaultServerAutoPurgeSnapRetainCount = 3
	DefaultPeerPort                       = 2888
	DefaultLeaderElectionPort             = 3888
)

type ServerConfigServer struct {
	Id                 int
	Host               string
	PeerPort           int
	LeaderElectionPort int
}

type ServerConfig struct {
	TickTime                 int    // Number of milliseconds of each tick
	InitLimit                int    // Number of ticks that the initial synchronization phase can take
	SyncLimit                int    // Number of ticks that can pass between sending a request and getting an acknowledgement
	DataDir                  string // Direcrory where the snapshot is stored
	ClientPort               int    // Port at which clients will connect
	AutoPurgeSnapRetainCount int    // Number of snapshots to retain in dataDir
	AutoPurgePurgeInterval   int    // Purge task internal in hours (0 to disable auto purge)
	Servers                  []ServerConfigServer
}

func (sc ServerConfig) Marshall(w io.Writer) error {
	if sc.DataDir == "" {
		return ErrMissingServerConfigField("dataDir")
	}
	fmt.Fprintf(w, "dataDir=%s\n", sc.DataDir)
	if sc.TickTime <= 0 {
		sc.TickTime = DefaultServerTickTime
	}
	fmt.Fprintf(w, "tickTime=%d\n", sc.TickTime)
	if sc.InitLimit <= 0 {
		sc.InitLimit = DefaultServerInitLimit
	}
	fmt.Fprintf(w, "initLimit=%d\n", sc.InitLimit)
	if sc.SyncLimit <= 0 {
		sc.SyncLimit = DefaultServerSyncLimit
	}
	fmt.Fprintf(w, "syncLimit=%d\n", sc.SyncLimit)
	if sc.ClientPort <= 0 {
		sc.ClientPort = DefaultPort
	}
	fmt.Fprintf(w, "clientPort=%d\n", sc.ClientPort)
	if sc.AutoPurgePurgeInterval > 0 {
		if sc.AutoPurgeSnapRetainCount <= 0 {
			sc.AutoPurgeSnapRetainCount = DefaultServerAutoPurgeSnapRetainCount
		}
		fmt.Fprintf(w, "autopurge.snapRetainCount=%d\n", sc.AutoPurgeSnapRetainCount)
		fmt.Fprintf(w, "autopurge.purgeInterval=%d\n", sc.AutoPurgePurgeInterval)
	}
	if len(sc.Servers) > 0 {
		for _, srv := range sc.Servers {
			if srv.PeerPort <= 0 {
				srv.PeerPort = DefaultPeerPort
			}
			if srv.LeaderElectionPort <= 0 {
				srv.LeaderElectionPort = DefaultLeaderElectionPort
			}
			fmt.Fprintf(w, "server.%d=%s:%d:%d\n", srv.Id, srv.Host, srv.PeerPort, srv.LeaderElectionPort)
		}
	}
	return nil
}

var jarSearchPaths = []string{
	"zookeeper-*/contrib/fatjar/zookeeper-*-fatjar.jar",
	"/usr/local/zookeeper-*/contrib/fatjar/zookeeper-*-fatjar.jar",
	"/usr/local/Cellar/zookeeper/*/libexec/contrib/fatjar/zookeeper-*-fatjar.jar",
}

func findZookeeperFatJar() string {
	for _, path := range jarSearchPaths {
		matches, _ := filepath.Glob(path)
		// TODO: could sort by version and pick latest
		if len(matches) > 0 {
			return matches[0]
		}
	}
	return ""
}

type Server struct {
	JarPath    string
	ConfigPath string

	cmd *exec.Cmd
}

func (srv *Server) Start() error {
	if srv.JarPath == "" {
		srv.JarPath = findZookeeperFatJar()
		if srv.JarPath == "" {
			return fmt.Errorf("zk: unable to find server jar")
		}
	}
	srv.cmd = exec.Command("java", "-jar", srv.JarPath, "server", srv.ConfigPath)
	// srv.cmd.Stdout = os.Stdout
	// srv.cmd.Stderr = os.Stderr
	return srv.cmd.Start()
}

func (srv *Server) Stop() error {
	srv.cmd.Process.Signal(os.Kill)
	return srv.cmd.Wait()
}
<commit_msg>Update jar search path to work with travis-ci<commit_after>package zk

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
)

type ErrMissingServerConfigField string

func (e ErrMissingServerConfigField) Error() string {
	return fmt.Sprintf("zk: missing server config field '%s'", string(e))
}

const (
	DefaultServerTickTime                 = 2000
	DefaultServerInitLimit                = 10
	DefaultServerSyncLimit                = 5
	DefaultServerAutoPurgeSnapRetainCount = 3
	DefaultPeerPort                       = 2888
	DefaultLeaderElectionPort             = 3888
)

type ServerConfigServer struct {
	Id                 int
	Host               string
	PeerPort           int
	LeaderElectionPort int
}

type ServerConfig struct {
	TickTime                 int    // Number of milliseconds of each tick
	InitLimit                int    // Number of ticks that the initial synchronization phase can take
	SyncLimit                int    // Number of ticks that can pass between sending a request and getting an acknowledgement
	DataDir                  string // Direcrory where the snapshot is stored
	ClientPort               int    // Port at which clients will connect
	AutoPurgeSnapRetainCount int    // Number of snapshots to retain in dataDir
	AutoPurgePurgeInterval   int    // Purge task internal in hours (0 to disable auto purge)
	Servers                  []ServerConfigServer
}

func (sc ServerConfig) Marshall(w io.Writer) error {
	if sc.DataDir == "" {
		return ErrMissingServerConfigField("dataDir")
	}
	fmt.Fprintf(w, "dataDir=%s\n", sc.DataDir)
	if sc.TickTime <= 0 {
		sc.TickTime = DefaultServerTickTime
	}
	fmt.Fprintf(w, "tickTime=%d\n", sc.TickTime)
	if sc.InitLimit <= 0 {
		sc.InitLimit = DefaultServerInitLimit
	}
	fmt.Fprintf(w, "initLimit=%d\n", sc.InitLimit)
	if sc.SyncLimit <= 0 {
		sc.SyncLimit = DefaultServerSyncLimit
	}
	fmt.Fprintf(w, "syncLimit=%d\n", sc.SyncLimit)
	if sc.ClientPort <= 0 {
		sc.ClientPort = DefaultPort
	}
	fmt.Fprintf(w, "clientPort=%d\n", sc.ClientPort)
	if sc.AutoPurgePurgeInterval > 0 {
		if sc.AutoPurgeSnapRetainCount <= 0 {
			sc.AutoPurgeSnapRetainCount = DefaultServerAutoPurgeSnapRetainCount
		}
		fmt.Fprintf(w, "autopurge.snapRetainCount=%d\n", sc.AutoPurgeSnapRetainCount)
		fmt.Fprintf(w, "autopurge.purgeInterval=%d\n", sc.AutoPurgePurgeInterval)
	}
	if len(sc.Servers) > 0 {
		for _, srv := range sc.Servers {
			if srv.PeerPort <= 0 {
				srv.PeerPort = DefaultPeerPort
			}
			if srv.LeaderElectionPort <= 0 {
				srv.LeaderElectionPort = DefaultLeaderElectionPort
			}
			fmt.Fprintf(w, "server.%d=%s:%d:%d\n", srv.Id, srv.Host, srv.PeerPort, srv.LeaderElectionPort)
		}
	}
	return nil
}

var jarSearchPaths = []string{
	"zookeeper-*/contrib/fatjar/zookeeper-*-fatjar.jar",
	"../zookeeper-*/contrib/fatjar/zookeeper-*-fatjar.jar",
	"/usr/local/zookeeper-*/contrib/fatjar/zookeeper-*-fatjar.jar",
	"/usr/local/Cellar/zookeeper/*/libexec/contrib/fatjar/zookeeper-*-fatjar.jar",
}

func findZookeeperFatJar() string {
	for _, path := range jarSearchPaths {
		matches, _ := filepath.Glob(path)
		// TODO: could sort by version and pick latest
		if len(matches) > 0 {
			return matches[0]
		}
	}
	return ""
}

type Server struct {
	JarPath    string
	ConfigPath string

	cmd *exec.Cmd
}

func (srv *Server) Start() error {
	if srv.JarPath == "" {
		srv.JarPath = findZookeeperFatJar()
		if srv.JarPath == "" {
			return fmt.Errorf("zk: unable to find server jar")
		}
	}
	srv.cmd = exec.Command("java", "-jar", srv.JarPath, "server", srv.ConfigPath)
	// srv.cmd.Stdout = os.Stdout
	// srv.cmd.Stderr = os.Stderr
	return srv.cmd.Start()
}

func (srv *Server) Stop() error {
	srv.cmd.Process.Signal(os.Kill)
	return srv.cmd.Wait()
}
<|endoftext|>