<commit_before>package model

import (
	"encoding/json"

	"github.com/af83/edwig/logger"
)

type OperationnalStatus int

const (
	OPERATIONNAL_STATUS_UNKNOWN OperationnalStatus = iota
	OPERATIONNAL_STATUS_UP
	OPERATIONNAL_STATUS_DOWN
)

type PartnerId string

type Partners interface {
	UUIDInterface
	Startable

	New() *Partner
	Find(id PartnerId) *Partner
	FindAll() []*Partner
	Save(partner *Partner) bool
	Delete(partner *Partner) bool
}

type Partner struct {
	id                 PartnerId
	Name               string
	operationnalStatus OperationnalStatus

	checkStatusClient CheckStatusClient

	manager Partners
}

type PartnerManager struct {
	UUIDConsumer

	byId     map[PartnerId]*Partner
	guardian *PartnersGuardian
}

func (partner *Partner) Id() PartnerId {
	return partner.id
}

func (partner *Partner) OperationnalStatus() OperationnalStatus {
	return partner.operationnalStatus
}

func (partner *Partner) Save() (ok bool) {
	return partner.manager.Save(partner)
}

func (partner *Partner) MarshalJSON() ([]byte, error) {
	return json.Marshal(map[string]interface{}{
		"Id":   partner.id,
		"Name": partner.Name,
	})
}

// Refresh Connector instances according to connector type list
func (partner *Partner) RefreshConnectors() {
	// WIP
	if partner.checkStatusClient != nil {
		siriPartner := NewSIRIPartner(partner)
		partner.checkStatusClient = NewSIRICheckStatusClient(siriPartner)
	}
}

func (partner *Partner) CheckStatusClient() CheckStatusClient {
	// WIP
	return partner.checkStatusClient
}

func (partner *Partner) CheckStatus() {
	logger.Log.Debugf("Check '%s' partner status", partner.Name)

	partner.operationnalStatus, _ = partner.CheckStatusClient().Status()
}

func NewPartnerManager() *PartnerManager {
	manager := &PartnerManager{
		byId: make(map[PartnerId]*Partner),
	}
	manager.guardian = NewPartnersGuardian(manager)
	return manager
}

func (manager *PartnerManager) Start() {
	manager.guardian.Start()
}

func (manager *PartnerManager) New() *Partner {
	return &Partner{manager: manager}
}

func (manager *PartnerManager) Find(id PartnerId) *Partner {
	partner, _ := manager.byId[id]
	return partner
}

func (manager *PartnerManager) FindAll() (partners []*Partner) {
	for _, partner := range manager.byId {
		partners = append(partners, partner)
	}
	return partners
}

func (manager *PartnerManager) Save(partner *Partner) bool {
	if partner.id == "" {
		partner.id = PartnerId(manager.NewUUID())
	}
	partner.manager = manager
	manager.byId[partner.id] = partner
	return true
}

func (manager *PartnerManager) Delete(partner *Partner) bool {
	delete(manager.byId, partner.id)
	return true
}
<commit_msg>Add Partner.settings. Refs #1946<commit_after>package model

import (
	"encoding/json"

	"github.com/af83/edwig/logger"
)

type OperationnalStatus int

const (
	OPERATIONNAL_STATUS_UNKNOWN OperationnalStatus = iota
	OPERATIONNAL_STATUS_UP
	OPERATIONNAL_STATUS_DOWN
)

type PartnerId string

type Partners interface {
	UUIDInterface
	Startable

	New() *Partner
	Find(id PartnerId) *Partner
	FindAll() []*Partner
	Save(partner *Partner) bool
	Delete(partner *Partner) bool
}

type Partner struct {
	id                 PartnerId
	Name               string
	Settings           map[string]string
	operationnalStatus OperationnalStatus

	checkStatusClient CheckStatusClient

	manager Partners
}

type PartnerManager struct {
	UUIDConsumer

	byId     map[PartnerId]*Partner
	guardian *PartnersGuardian
}

func (partner *Partner) Id() PartnerId {
	return partner.id
}

func (partner *Partner) Setting(key string) string {
	return partner.Settings[key]
}

func (partner *Partner) OperationnalStatus() OperationnalStatus {
	return partner.operationnalStatus
}

func (partner *Partner) Save() (ok bool) {
	return partner.manager.Save(partner)
}

func (partner *Partner) MarshalJSON() ([]byte, error) {
	return json.Marshal(map[string]interface{}{
		"Id":   partner.id,
		"Name": partner.Name,
	})
}

// Refresh Connector instances according to connector type list
func (partner *Partner) RefreshConnectors() {
	// WIP
	if partner.checkStatusClient != nil {
		siriPartner := NewSIRIPartner(partner)
		partner.checkStatusClient = NewSIRICheckStatusClient(siriPartner)
	}
}

func (partner *Partner) CheckStatusClient() CheckStatusClient {
	// WIP
	return partner.checkStatusClient
}

func (partner *Partner) CheckStatus() {
	logger.Log.Debugf("Check '%s' partner status", partner.Name)

	partner.operationnalStatus, _ = partner.CheckStatusClient().Status()
}

func NewPartnerManager() *PartnerManager {
	manager := &PartnerManager{
		byId: make(map[PartnerId]*Partner),
	}
	manager.guardian = NewPartnersGuardian(manager)
	return manager
}

func (manager *PartnerManager) Start() {
	manager.guardian.Start()
}

func (manager *PartnerManager) New() *Partner {
	return &Partner{manager: manager}
}

func (manager *PartnerManager) Find(id PartnerId) *Partner {
	partner, _ := manager.byId[id]
	return partner
}

func (manager *PartnerManager) FindAll() (partners []*Partner) {
	for _, partner := range manager.byId {
		partners = append(partners, partner)
	}
	return partners
}

func (manager *PartnerManager) Save(partner *Partner) bool {
	if partner.id == "" {
		partner.id = PartnerId(manager.NewUUID())
	}
	partner.manager = manager
	manager.byId[partner.id] = partner
	return true
}

func (manager *PartnerManager) Delete(partner *Partner) bool {
	delete(manager.byId, partner.id)
	return true
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

package model

import (
	"strconv"
	"strings"
)

// This is a list of all the current viersions including any patches.
// It should be maitained in chronological order with most current
// release at the front of the list.
var versions = []string{
	"1.4.0",
	"1.3.0",
	"1.2.1",
	"1.2.0",
	"1.1.0",
	"1.0.0",
	"0.7.1",
	"0.7.0",
	"0.6.0",
	"0.5.0",
}

var CurrentVersion string = versions[0]
var BuildNumber = "_BUILD_NUMBER_"
var BuildDate = "_BUILD_DATE_"
var BuildHash = "_BUILD_HASH_"
var BuildEnterpriseReady = "false"

func SplitVersion(version string) (int64, int64, int64) {
	parts := strings.Split(version, ".")

	major := int64(0)
	minor := int64(0)
	patch := int64(0)

	if len(parts) > 0 {
		major, _ = strconv.ParseInt(parts[0], 10, 64)
	}

	if len(parts) > 1 {
		minor, _ = strconv.ParseInt(parts[1], 10, 64)
	}

	if len(parts) > 2 {
		patch, _ = strconv.ParseInt(parts[2], 10, 64)
	}

	return major, minor, patch
}

func GetPreviousVersion(currentVersion string) (int64, int64) {
	currentIndex := -1
	currentMajor, currentMinor, _ := SplitVersion(currentVersion)

	for index, version := range versions {
		major, minor, _ := SplitVersion(version)

		if currentMajor == major && currentMinor == minor {
			currentIndex = index
		}

		if currentIndex >= 0 {
			if currentMajor != major || currentMinor != minor {
				return major, minor
			}
		}
	}

	return 0, 0
}

func IsOfficalBuild() bool {
	return BuildNumber != "_BUILD_NUMBER_"
}

func IsCurrentVersion(versionToCheck string) bool {
	currentMajor, currentMinor, _ := SplitVersion(CurrentVersion)
	toCheckMajor, toCheckMinor, _ := SplitVersion(versionToCheck)

	if toCheckMajor == currentMajor && toCheckMinor == currentMinor {
		return true
	} else {
		return false
	}
}

func IsPreviousVersion(versionToCheck string) bool {
	toCheckMajor, toCheckMinor, _ := SplitVersion(versionToCheck)
	prevMajor, prevMinor := GetPreviousVersion(CurrentVersion)

	if toCheckMajor == prevMajor && toCheckMinor == prevMinor {
		return true
	} else {
		return false
	}
}
<commit_msg>Fxing version<commit_after>// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

package model

import (
	"strconv"
	"strings"
)

// This is a list of all the current viersions including any patches.
// It should be maitained in chronological order with most current
// release at the front of the list.
var versions = []string{
	"1.4.0",
	"1.3.0",
	"1.2.1",
	"1.2.0",
	"1.1.0",
	"1.0.0",
	"0.7.1",
	"0.7.0",
	"0.6.0",
	"0.5.0",
}

var CurrentVersion string = versions[0]
var BuildNumber = "_BUILD_NUMBER_"
var BuildDate = "_BUILD_DATE_"
var BuildHash = "_BUILD_HASH_"
var BuildEnterpriseReady = "_BUILD_ENTERPRISE_READY_"

func SplitVersion(version string) (int64, int64, int64) {
	parts := strings.Split(version, ".")

	major := int64(0)
	minor := int64(0)
	patch := int64(0)

	if len(parts) > 0 {
		major, _ = strconv.ParseInt(parts[0], 10, 64)
	}

	if len(parts) > 1 {
		minor, _ = strconv.ParseInt(parts[1], 10, 64)
	}

	if len(parts) > 2 {
		patch, _ = strconv.ParseInt(parts[2], 10, 64)
	}

	return major, minor, patch
}

func GetPreviousVersion(currentVersion string) (int64, int64) {
	currentIndex := -1
	currentMajor, currentMinor, _ := SplitVersion(currentVersion)

	for index, version := range versions {
		major, minor, _ := SplitVersion(version)

		if currentMajor == major && currentMinor == minor {
			currentIndex = index
		}

		if currentIndex >= 0 {
			if currentMajor != major || currentMinor != minor {
				return major, minor
			}
		}
	}

	return 0, 0
}

func IsOfficalBuild() bool {
	return BuildNumber != "_BUILD_NUMBER_"
}

func IsCurrentVersion(versionToCheck string) bool {
	currentMajor, currentMinor, _ := SplitVersion(CurrentVersion)
	toCheckMajor, toCheckMinor, _ := SplitVersion(versionToCheck)

	if toCheckMajor == currentMajor && toCheckMinor == currentMinor {
		return true
	} else {
		return false
	}
}

func IsPreviousVersion(versionToCheck string) bool {
	toCheckMajor, toCheckMinor, _ := SplitVersion(versionToCheck)
	prevMajor, prevMinor := GetPreviousVersion(CurrentVersion)

	if toCheckMajor == prevMajor && toCheckMinor == prevMinor {
		return true
	} else {
		return false
	}
}
<|endoftext|>


<commit_before>package models

import (
	"database/sql"

	e "github.com/techjanitor/pram-post/errors"
	u "github.com/techjanitor/pram-post/utils"
)

type AddTagModel struct {
	Uid   uint
	Ib    uint
	Tag   uint
	Image uint
	Ip    string
}

// ValidateInput will make sure all the parameters are valid
func (i *AddTagModel) ValidateInput() (err error) {
	if i.Ib == 0 {
		return e.ErrInvalidParam
	}

	if i.Tag == 0 {
		return e.ErrInvalidParam
	}

	if i.Image == 0 {
		return e.ErrInvalidParam
	}

	return

}

// Status will return info about the thread
func (i *AddTagModel) Status() (err error) {

	// Get Database handle
	db, err := u.GetDb()
	if err != nil {
		return
	}

	var check bool

	// check to see if this image is in the right ib
	err = db.QueryRow(`SELECT count(1) FROM images
	LEFT JOIN posts on images.post_id = posts.post_id
	LEFT JOIN threads on posts.thread_id = threads.thread_id
	WHERE image_id = ? AND ib_id = ?`, i.Image, i.Ib)
	if err == sql.ErrNoRows {
		return e.ErrNotFound
	} else if err != nil {
		return
	}

	// Check if tag is already there
	err = db.QueryRow("select count(1) from tagmap where tag_id = ? AND image_id = ?", i.Tag, i.Image).Scan(&check)
	if err != nil {
		return
	}

	// return if it does
	if check {
		return e.ErrDuplicateTag
	}

	return

}

// Post will add the reply to the database with a transaction
func (i *AddTagModel) Post() (err error) {

	// Get Database handle
	db, err := u.GetDb()
	if err != nil {
		return
	}

	ps1, err := db.Prepare("INSERT into tagmap (image_id, tag_id, tagmap_ip) VALUES (?,?,?)")
	if err != nil {
		return
	}
	defer ps1.Close()

	_, err = ps1.Exec(i.Image, i.Tag, i.Ip)
	if err != nil {
		return
	}

	return

}
<commit_msg>check tag add for right image ib<commit_after>package models

import (
	"database/sql"

	e "github.com/techjanitor/pram-post/errors"
	u "github.com/techjanitor/pram-post/utils"
)

type AddTagModel struct {
	Uid   uint
	Ib    uint
	Tag   uint
	Image uint
	Ip    string
}

// ValidateInput will make sure all the parameters are valid
func (i *AddTagModel) ValidateInput() (err error) {
	if i.Ib == 0 {
		return e.ErrInvalidParam
	}

	if i.Tag == 0 {
		return e.ErrInvalidParam
	}

	if i.Image == 0 {
		return e.ErrInvalidParam
	}

	return

}

// Status will return info about the thread
func (i *AddTagModel) Status() (err error) {

	// Get Database handle
	db, err := u.GetDb()
	if err != nil {
		return
	}

	var check bool

	// check to see if this image is in the right ib
	err = db.QueryRow(`SELECT count(1) FROM images
	LEFT JOIN posts on images.post_id = posts.post_id
	LEFT JOIN threads on posts.thread_id = threads.thread_id
	WHERE image_id = ? AND ib_id = ?`, i.Image, i.Ib).Scan(&check)
	if err != nil {
		return
	}

	// return if zero
	if !check {
		return e.ErrNotFound
	}

	// Check if tag is already there
	err = db.QueryRow("select count(1) from tagmap where tag_id = ? AND image_id = ?", i.Tag, i.Image).Scan(&check)
	if err != nil {
		return
	}

	// return if it does
	if check {
		return e.ErrDuplicateTag
	}

	return

}

// Post will add the reply to the database with a transaction
func (i *AddTagModel) Post() (err error) {

	// Get Database handle
	db, err := u.GetDb()
	if err != nil {
		return
	}

	ps1, err := db.Prepare("INSERT into tagmap (image_id, tag_id, tagmap_ip) VALUES (?,?,?)")
	if err != nil {
		return
	}
	defer ps1.Close()

	_, err = ps1.Exec(i.Image, i.Tag, i.Ip)
	if err != nil {
		return
	}

	return

}
<|endoftext|>


<commit_before>package models

import (
	"time"

	envmanModels "github.com/bitrise-io/envman/models"
)

// GlobalStepInfoModel ...
type GlobalStepInfoModel struct {
	RemovalDate    string `json:"removal_date,omitempty" yaml:"removal_date,omitempty"`
	DeprecateNotes string `json:"deprecate_notes,omitempty" yaml:"deprecate_notes,omitempty"`
}

// StepSourceModel ...
type StepSourceModel struct {
	Git    string `json:"git,omitempty" yaml:"git,omitempty"`
	Commit string `json:"commit,omitempty" yaml:"commit,omitempty"`
}

// DependencyModel ...
type DependencyModel struct {
	Manager string `json:"manager,omitempty" yaml:"manager,omitempty"`
	Name    string `json:"name,omitempty" yaml:"name,omitempty"`
}

// BrewDepModel ...
type BrewDepModel struct {
	Name string `json:"name,omitempty" yaml:"name,omitempty"`
}

// AptGetDepModel ...
type AptGetDepModel struct {
	Name string `json:"name,omitempty" yaml:"name,omitempty"`
}

// CheckOnlyDepModel ...
type CheckOnlyDepModel struct {
	Name string `json:"name,omitempty" yaml:"name,omitempty"`
}

// DepsModel ...
type DepsModel struct {
	Brew      []BrewDepModel      `json:"brew,omitempty" yaml:"brew,omitempty"`
	AptGet    []AptGetDepModel    `json:"apt_get,omitempty" yaml:"apt_get,omitempty"`
	CheckOnly []CheckOnlyDepModel `json:"check_only,omitempty" yaml:"check_only,omitempty"`
}

// BashStepToolkitModel ...
type BashStepToolkitModel struct {
	EntryFile string `json:"entry_file,omitempty" yaml:"entry_file,omitempty"`
}

// GoStepToolkitModel ...
type GoStepToolkitModel struct {
	// PackageName - required
	PackageName string `json:"package_name" yaml:"package_name"`
}

// StepToolkitModel ...
type StepToolkitModel struct {
	Bash BashStepToolkitModel `json:"bash,omitempty" yaml:"bash,omitempty"`
	Go   GoStepToolkitModel   `json:"go,omitempty" yaml:"go,omitempty"`
}

// StepModel ...
type StepModel struct {
	Title       *string `json:"title,omitempty" yaml:"title,omitempty"`
	Summary     *string `json:"summary,omitempty" yaml:"summary,omitempty"`
	Description *string `json:"description,omitempty" yaml:"description,omitempty"`
	//
	Website       *string `json:"website,omitempty" yaml:"website,omitempty"`
	SourceCodeURL *string `json:"source_code_url,omitempty" yaml:"source_code_url,omitempty"`
	SupportURL    *string `json:"support_url,omitempty" yaml:"support_url,omitempty"`
	// auto-generated at share
	PublishedAt *time.Time        `json:"published_at,omitempty" yaml:"published_at,omitempty"`
	Source      StepSourceModel   `json:"source,omitempty" yaml:"source,omitempty"`
	AssetURLs   map[string]string `json:"asset_urls,omitempty" yaml:"asset_urls,omitempty"`
	//
	HostOsTags          []string          `json:"host_os_tags,omitempty" yaml:"host_os_tags,omitempty"`
	ProjectTypeTags     []string          `json:"project_type_tags,omitempty" yaml:"project_type_tags,omitempty"`
	TypeTags            []string          `json:"type_tags,omitempty" yaml:"type_tags,omitempty"`
	Dependencies        []DependencyModel `json:"dependencies,omitempty" yaml:"dependencies,omitempty"`
	Toolkit             StepToolkitModel  `json:"toolkit,omitempty" yaml:"toolkit,omitempty"`
	Deps                DepsModel         `json:"deps,omitempty" yaml:"deps,omitempty"`
	IsRequiresAdminUser *bool             `json:"is_requires_admin_user,omitempty" yaml:"is_requires_admin_user,omitempty"`
	// IsAlwaysRun : if true then this step will always run,
	//  even if a previous step fails.
	IsAlwaysRun *bool `json:"is_always_run,omitempty" yaml:"is_always_run,omitempty"`
	// IsSkippable : if true and this step fails the build will still continue.
	//  If false then the build will be marked as failed and only those
	//  steps will run which are marked with IsAlwaysRun.
	IsSkippable *bool `json:"is_skippable,omitempty" yaml:"is_skippable,omitempty"`
	// RunIf : only run the step if the template example evaluates to true
	RunIf *string `json:"run_if,omitempty" yaml:"run_if,omitempty"`
	//
	Inputs  []envmanModels.EnvironmentItemModel `json:"inputs,omitempty" yaml:"inputs,omitempty"`
	Outputs []envmanModels.EnvironmentItemModel `json:"outputs,omitempty" yaml:"outputs,omitempty"`
}

// StepGroupInfoModel ...
type StepGroupInfoModel struct {
	RemovalDate    string            `json:"removal_date,omitempty" yaml:"removal_date,omitempty"`
	DeprecateNotes string            `json:"deprecate_notes,omitempty" yaml:"deprecate_notes,omitempty"`
	AssetURLs      map[string]string `json:"asset_urls,omitempty" yaml:"asset_urls,omitempty"`
}

// StepGroupModel ...
type StepGroupModel struct {
	Info                StepGroupInfoModel   `json:"info,omitempty" yaml:"info,omitempty"`
	LatestVersionNumber string               `json:"latest_version_number,omitempty" yaml:"latest_version_number,omitempty"`
	Versions            map[string]StepModel `json:"versions,omitempty" yaml:"versions,omitempty"`
}

// StepHash ...
type StepHash map[string]StepGroupModel

// DownloadLocationModel ...
type DownloadLocationModel struct {
	Type string `json:"type"`
	Src  string `json:"src"`
}

// StepCollectionModel ...
type StepCollectionModel struct {
	FormatVersion         string                  `json:"format_version" yaml:"format_version"`
	GeneratedAtTimeStamp  int64                   `json:"generated_at_timestamp" yaml:"generated_at_timestamp"`
	SteplibSource         string                  `json:"steplib_source" yaml:"steplib_source"`
	DownloadLocations     []DownloadLocationModel `json:"download_locations" yaml:"download_locations"`
	AssetsDownloadBaseURI string                  `json:"assets_download_base_uri" yaml:"assets_download_base_uri"`
	Steps                 StepHash                `json:"steps" yaml:"steps"`
}

// EnvInfoModel ...
type EnvInfoModel struct {
	Key          string   `json:"key,omitempty" yaml:"key,omitempty"`
	Title        string   `json:"title,omitempty" yaml:"title,omitempty"`
	Description  string   `json:"description,omitempty" yaml:"description,omitempty"`
	ValueOptions []string `json:"value_options,omitempty" yaml:"value_options,omitempty"`
	DefaultValue string   `json:"default_value,omitempty" yaml:"default_value,omitempty"`
	IsExpand     bool     `json:"is_expand" yaml:"is_expand"`
}

// StepInfoModel ...
type StepInfoModel struct {
	ID            string              `json:"step_id,omitempty" yaml:"step_id,omitempty"`
	Title         string              `json:"step_title,omitempty" yaml:"step_title,omitempty"`
	Version       string              `json:"step_version,omitempty" yaml:"step_version,omitempty"`
	Latest        string              `json:"latest_version,omitempty" yaml:"latest_version,omitempty"`
	Description   string              `json:"description,omitempty" yaml:"description,omitempty"`
	Source        string              `json:"source,omitempty" yaml:"source,omitempty"`
	StepLib       string              `json:"steplib,omitempty" yaml:"steplib,omitempty"`
	SupportURL    string              `json:"support_url,omitempty" yaml:"support_url,omitempty"`
	SourceCodeURL string              `json:"source_code_url,omitempty" yaml:"source_code_url,omitempty"`
	Inputs        []EnvInfoModel      `json:"inputs,omitempty" yaml:"inputs,omitempty"`
	Outputs       []EnvInfoModel      `json:"outputs,omitempty" yaml:"outputs,omitempty"`
	GlobalInfo    GlobalStepInfoModel `json:"global_info,omitempty" yaml:"global_info,omitempty"`
}

// StepListModel ...
type StepListModel struct {
	StepLib string   `json:"steplib,omitempty" yaml:"steplib,omitempty"`
	Steps   []string `json:"steps,omitempty" yaml:"steps,omitempty"`
}

// StepLibURIModel ...
type StepLibURIModel struct {
	URI string `json:"uri,omitempty" yaml:"uri,omitempty"`
}

// StepLibURIsModel ...
type StepLibURIsModel struct {
	StepLibURIs []StepLibURIModel `json:"steplibs,omitempty" yaml:"steplibs,omitempty"`
}
<commit_msg>toolkits - pointers<commit_after>package models

import (
	"time"

	envmanModels "github.com/bitrise-io/envman/models"
)

// GlobalStepInfoModel ...
type GlobalStepInfoModel struct {
	RemovalDate    string `json:"removal_date,omitempty" yaml:"removal_date,omitempty"`
	DeprecateNotes string `json:"deprecate_notes,omitempty" yaml:"deprecate_notes,omitempty"`
}

// StepSourceModel ...
type StepSourceModel struct {
	Git    string `json:"git,omitempty" yaml:"git,omitempty"`
	Commit string `json:"commit,omitempty" yaml:"commit,omitempty"`
}

// DependencyModel ...
type DependencyModel struct {
	Manager string `json:"manager,omitempty" yaml:"manager,omitempty"`
	Name    string `json:"name,omitempty" yaml:"name,omitempty"`
}

// BrewDepModel ...
type BrewDepModel struct {
	Name string `json:"name,omitempty" yaml:"name,omitempty"`
}

// AptGetDepModel ...
type AptGetDepModel struct {
	Name string `json:"name,omitempty" yaml:"name,omitempty"`
}

// CheckOnlyDepModel ...
type CheckOnlyDepModel struct {
	Name string `json:"name,omitempty" yaml:"name,omitempty"`
}

// DepsModel ...
type DepsModel struct {
	Brew      []BrewDepModel      `json:"brew,omitempty" yaml:"brew,omitempty"`
	AptGet    []AptGetDepModel    `json:"apt_get,omitempty" yaml:"apt_get,omitempty"`
	CheckOnly []CheckOnlyDepModel `json:"check_only,omitempty" yaml:"check_only,omitempty"`
}

// BashStepToolkitModel ...
type BashStepToolkitModel struct {
	EntryFile string `json:"entry_file,omitempty" yaml:"entry_file,omitempty"`
}

// GoStepToolkitModel ...
type GoStepToolkitModel struct {
	// PackageName - required
	PackageName string `json:"package_name" yaml:"package_name"`
}

// StepToolkitModel ...
type StepToolkitModel struct {
	Bash *BashStepToolkitModel `json:"bash,omitempty" yaml:"bash,omitempty"`
	Go   *GoStepToolkitModel   `json:"go,omitempty" yaml:"go,omitempty"`
}

// StepModel ...
type StepModel struct {
	Title       *string `json:"title,omitempty" yaml:"title,omitempty"`
	Summary     *string `json:"summary,omitempty" yaml:"summary,omitempty"`
	Description *string `json:"description,omitempty" yaml:"description,omitempty"`
	//
	Website       *string `json:"website,omitempty" yaml:"website,omitempty"`
	SourceCodeURL *string `json:"source_code_url,omitempty" yaml:"source_code_url,omitempty"`
	SupportURL    *string `json:"support_url,omitempty" yaml:"support_url,omitempty"`
	// auto-generated at share
	PublishedAt *time.Time        `json:"published_at,omitempty" yaml:"published_at,omitempty"`
	Source      StepSourceModel   `json:"source,omitempty" yaml:"source,omitempty"`
	AssetURLs   map[string]string `json:"asset_urls,omitempty" yaml:"asset_urls,omitempty"`
	//
	HostOsTags          []string          `json:"host_os_tags,omitempty" yaml:"host_os_tags,omitempty"`
	ProjectTypeTags     []string          `json:"project_type_tags,omitempty" yaml:"project_type_tags,omitempty"`
	TypeTags            []string          `json:"type_tags,omitempty" yaml:"type_tags,omitempty"`
	Dependencies        []DependencyModel `json:"dependencies,omitempty" yaml:"dependencies,omitempty"`
	Toolkit             *StepToolkitModel `json:"toolkit,omitempty" yaml:"toolkit,omitempty"`
	Deps                DepsModel         `json:"deps,omitempty" yaml:"deps,omitempty"`
	IsRequiresAdminUser *bool             `json:"is_requires_admin_user,omitempty" yaml:"is_requires_admin_user,omitempty"`
	// IsAlwaysRun : if true then this step will always run,
	//  even if a previous step fails.
	IsAlwaysRun *bool `json:"is_always_run,omitempty" yaml:"is_always_run,omitempty"`
	// IsSkippable : if true and this step fails the build will still continue.
	//  If false then the build will be marked as failed and only those
	//  steps will run which are marked with IsAlwaysRun.
	IsSkippable *bool `json:"is_skippable,omitempty" yaml:"is_skippable,omitempty"`
	// RunIf : only run the step if the template example evaluates to true
	RunIf *string `json:"run_if,omitempty" yaml:"run_if,omitempty"`
	//
	Inputs  []envmanModels.EnvironmentItemModel `json:"inputs,omitempty" yaml:"inputs,omitempty"`
	Outputs []envmanModels.EnvironmentItemModel `json:"outputs,omitempty" yaml:"outputs,omitempty"`
}

// StepGroupInfoModel ...
type StepGroupInfoModel struct {
	RemovalDate    string            `json:"removal_date,omitempty" yaml:"removal_date,omitempty"`
	DeprecateNotes string            `json:"deprecate_notes,omitempty" yaml:"deprecate_notes,omitempty"`
	AssetURLs      map[string]string `json:"asset_urls,omitempty" yaml:"asset_urls,omitempty"`
}

// StepGroupModel ...
type StepGroupModel struct {
	Info                StepGroupInfoModel   `json:"info,omitempty" yaml:"info,omitempty"`
	LatestVersionNumber string               `json:"latest_version_number,omitempty" yaml:"latest_version_number,omitempty"`
	Versions            map[string]StepModel `json:"versions,omitempty" yaml:"versions,omitempty"`
}

// StepHash ...
type StepHash map[string]StepGroupModel

// DownloadLocationModel ...
type DownloadLocationModel struct {
	Type string `json:"type"`
	Src  string `json:"src"`
}

// StepCollectionModel ...
type StepCollectionModel struct {
	FormatVersion         string                  `json:"format_version" yaml:"format_version"`
	GeneratedAtTimeStamp  int64                   `json:"generated_at_timestamp" yaml:"generated_at_timestamp"`
	SteplibSource         string                  `json:"steplib_source" yaml:"steplib_source"`
	DownloadLocations     []DownloadLocationModel `json:"download_locations" yaml:"download_locations"`
	AssetsDownloadBaseURI string                  `json:"assets_download_base_uri" yaml:"assets_download_base_uri"`
	Steps                 StepHash                `json:"steps" yaml:"steps"`
}

// EnvInfoModel ...
type EnvInfoModel struct {
	Key          string   `json:"key,omitempty" yaml:"key,omitempty"`
	Title        string   `json:"title,omitempty" yaml:"title,omitempty"`
	Description  string   `json:"description,omitempty" yaml:"description,omitempty"`
	ValueOptions []string `json:"value_options,omitempty" yaml:"value_options,omitempty"`
	DefaultValue string   `json:"default_value,omitempty" yaml:"default_value,omitempty"`
	IsExpand     bool     `json:"is_expand" yaml:"is_expand"`
}

// StepInfoModel ...
type StepInfoModel struct {
	ID            string              `json:"step_id,omitempty" yaml:"step_id,omitempty"`
	Title         string              `json:"step_title,omitempty" yaml:"step_title,omitempty"`
	Version       string              `json:"step_version,omitempty" yaml:"step_version,omitempty"`
	Latest        string              `json:"latest_version,omitempty" yaml:"latest_version,omitempty"`
	Description   string              `json:"description,omitempty" yaml:"description,omitempty"`
	Source        string              `json:"source,omitempty" yaml:"source,omitempty"`
	StepLib       string              `json:"steplib,omitempty" yaml:"steplib,omitempty"`
	SupportURL    string              `json:"support_url,omitempty" yaml:"support_url,omitempty"`
	SourceCodeURL string              `json:"source_code_url,omitempty" yaml:"source_code_url,omitempty"`
	Inputs        []EnvInfoModel      `json:"inputs,omitempty" yaml:"inputs,omitempty"`
	Outputs       []EnvInfoModel      `json:"outputs,omitempty" yaml:"outputs,omitempty"`
	GlobalInfo    GlobalStepInfoModel `json:"global_info,omitempty" yaml:"global_info,omitempty"`
}

// StepListModel ...
type StepListModel struct {
	StepLib string   `json:"steplib,omitempty" yaml:"steplib,omitempty"`
	Steps   []string `json:"steps,omitempty" yaml:"steps,omitempty"`
}

// StepLibURIModel ...
type StepLibURIModel struct {
	URI string `json:"uri,omitempty" yaml:"uri,omitempty"`
}

// StepLibURIsModel ...
type StepLibURIsModel struct {
	StepLibURIs []StepLibURIModel `json:"steplibs,omitempty" yaml:"steplibs,omitempty"`
}
<|endoftext|>


<commit_before>package models

// Action describes an action that the ScanBadge client performs, based on the result of the specified condition.
type Action struct {
	ID          int64      `db:"action_id" json:"action_id"`
	UserID      int64      `db:"user_id" json:"user_id"`
	DeviceID    int64      `db:"device_id" json:"device_id"`
	Name        string     `db:"action_name" json:"action_name" form:"name"`
	Description string     `db:"action_description" json:"action_description" form:"description"`
	Value       string     `db:"action_value" json:"action_value" form:"value"`
	Device      Device     `db:"-" json:"device"`
	Type        ActionType `db:"-" json:"action_type"`
}

// ActionType describes an action type. The action type can be used to determine what driver to use when the action is performed.
type ActionType struct {
	ID          int64  `db:"action_type_id" json:"id"`
	Name        string `db:"action_type_name" json:"name" form:"name"`
	Description string `db:"action_type_gdescription" json:"description" form:"description"`
}

// Condition describes a condition. When a condition evaluates to TRUE, the related action should be performed.
type Condition struct {
	ID          int64         `db:"condition_id" json:"id"`
	UserID      int64         `db:"user_id" json:"user_id"`
	DeviceID    int64         `db:"device_id" json:"device_id"`
	Name        string        `db:"condition_name" json:"name" form:"name"`
	Description string        `db:"condition_description" json:"description" form:"description"`
	Value       string        `db:"condition_value" json:"value" form:"value"`
	Action      Action        `db:"-" json:"action"`
	Device      Device        `db:"-" json:"device"`
	Type        ConditionType `db:"-" json:"condition_type"`
}

// ConditionType describes a condition type.
type ConditionType struct {
	ID          int64  `db:"condition_type_id" json:"id"`
	Name        string `db:"condition_type_name" json:"name" form:"name"`
	Description string `db:"condition_type_description" json:"description" form:"description"`
	ExecuteArgs string `db:"condition_type_execute_args" json:"execute_args" form:"execute_args"`
}

type Count struct {
	Endpoint string `json:"endpoint"`
	Count    int64  `json:"count"`
}

// Device describes a device.
// When adding a device, only name, description and key fields can be entered.
type Device struct {
	ID          int64  `db:"device_id" json:"device_id"`
	UserID      int64  `db:"user_id"`
	Name        string `db:"device_name" json:"name" form:"name"`
	Description string `db:"device_description" json:"description" form:"description"`
	Key         string `db:"device_key" json:"key" form:"key"`
	User        User   `db:"-" json:"user"`
}

// Log describes a log entry.
type Log struct {
	ID          int64  `db:"log_id" json:"id"`
	Date        int64  `db:"log_date" json:"date"`
	UserID      int64  `db:"user_id"`
	Type        string `db:"log_type" json:"type" form:"type"`
	Description string `db:"log_message" json:"message" form:"message"`
	Origin      string `db:"log_origin" json:"origin" form:"origin"`
	Object      string `db:"log_object" json:"object" form:"object"`
	User        User   `db:"-" json:"user"`
}

// User describes a user.
type User struct {
	ID        int64  `db:"user_id" json:"id"`
	Username  string `db:"user_username" json:"username" form:"username"`
	Email     string `db:"user_email" json:"email" form:"email"`
	Password  string `db:"user_password" json:"password,omitempty" form:"password"`
	FirstName string `db:"user_first_name" json:"first_name" form:"first_name"`
	LastName  string `db:"user_last_name" json:"last_name" form:"last_name"`
	Roles     Role   `db:"-" json:"roles,omitempty"`
}

// Role describes a user role.
type Role struct {
	ID          int64  `db:"role_id" json:"id"`
	Level       int64  `db:"role_Level" json:"level"`
	Name        string `db:"role_name" json:"name"`
	Description string `db:"role_description" json:"description"`
}
<commit_msg>Fixed typo of typo... Lmao.<commit_after>package models

// Action describes an action that the ScanBadge client performs, based on the result of the specified condition.
type Action struct {
	ID          int64      `db:"action_id" json:"action_id"`
	UserID      int64      `db:"user_id" json:"user_id"`
	DeviceID    int64      `db:"device_id" json:"device_id"`
	Name        string     `db:"action_name" json:"action_name" form:"name"`
	Description string     `db:"action_description" json:"action_description" form:"description"`
	Value       string     `db:"action_value" json:"action_value" form:"value"`
	Device      Device     `db:"-" json:"device"`
	Type        ActionType `db:"-" json:"action_type"`
}

// ActionType describes an action type. The action type can be used to determine what driver to use when the action is performed.
type ActionType struct {
	ID          int64  `db:"action_type_id" json:"id"`
	Name        string `db:"action_type_name" json:"name" form:"name"`
	Description string `db:"action_type_description" json:"description" form:"description"`
}

// Condition describes a condition. When a condition evaluates to TRUE, the related action should be performed.
type Condition struct {
	ID          int64         `db:"condition_id" json:"id"`
	UserID      int64         `db:"user_id" json:"user_id"`
	DeviceID    int64         `db:"device_id" json:"device_id"`
	Name        string        `db:"condition_name" json:"name" form:"name"`
	Description string        `db:"condition_description" json:"description" form:"description"`
	Value       string        `db:"condition_value" json:"value" form:"value"`
	Action      Action        `db:"-" json:"action"`
	Device      Device        `db:"-" json:"device"`
	Type        ConditionType `db:"-" json:"condition_type"`
}

// ConditionType describes a condition type.
type ConditionType struct {
	ID          int64  `db:"condition_type_id" json:"id"`
	Name        string `db:"condition_type_name" json:"name" form:"name"`
	Description string `db:"condition_type_description" json:"description" form:"description"`
	ExecuteArgs string `db:"condition_type_execute_args" json:"execute_args" form:"execute_args"`
}

type Count struct {
	Endpoint string `json:"endpoint"`
	Count    int64  `json:"count"`
}

// Device describes a device.
// When adding a device, only name, description and key fields can be entered.
type Device struct {
	ID          int64  `db:"device_id" json:"device_id"`
	UserID      int64  `db:"user_id"`
	Name        string `db:"device_name" json:"name" form:"name"`
	Description string `db:"device_description" json:"description" form:"description"`
	Key         string `db:"device_key" json:"key" form:"key"`
	User        User   `db:"-" json:"user"`
}

// Log describes a log entry.
type Log struct {
	ID          int64  `db:"log_id" json:"id"`
	Date        int64  `db:"log_date" json:"date"`
	UserID      int64  `db:"user_id"`
	Type        string `db:"log_type" json:"type" form:"type"`
	Description string `db:"log_message" json:"message" form:"message"`
	Origin      string `db:"log_origin" json:"origin" form:"origin"`
	Object      string `db:"log_object" json:"object" form:"object"`
	User        User   `db:"-" json:"user"`
}

// User describes a user.
type User struct {
	ID        int64  `db:"user_id" json:"id"`
	Username  string `db:"user_username" json:"username" form:"username"`
	Email     string `db:"user_email" json:"email" form:"email"`
	Password  string `db:"user_password" json:"password,omitempty" form:"password"`
	FirstName string `db:"user_first_name" json:"first_name" form:"first_name"`
	LastName  string `db:"user_last_name" json:"last_name" form:"last_name"`
	Roles     Role   `db:"-" json:"roles,omitempty"`
}

// Role describes a user role.
type Role struct {
	ID          int64  `db:"role_id" json:"id"`
	Level       int64  `db:"role_Level" json:"level"`
	Name        string `db:"role_name" json:"name"`
	Description string `db:"role_description" json:"description"`
}
<|endoftext|>


<commit_before>package indexer

import (
	"bytes"
	"io"
	"strings"

	"code.google.com/p/go.net/html"
	"code.google.com/p/go.net/html/atom"
)

type htmlParser struct {
	title string
	b     bytes.Buffer
	z     *html.Tokenizer
}

func (p *htmlParser) parseMeta(n *html.Node) {
	indexable := false
	for _, a := range n.Attr {
		if a.Key == "name" {
			v := strings.ToLower(a.Val)
			if v == "keywords" || v == "description" {
				indexable = true
			}
		}
	}
	if !indexable {
		return
	}
	for _, a := range n.Attr {
		if a.Key == "content" {
			p.consumeString(a.Val)
		}
	}
}

func (p *htmlParser) parseImg(n *html.Node) {
	for _, a := range n.Attr {
		if a.Key == "alt" {
			p.consumeString(a.Val)
			return
		}
	}
}

func (p *htmlParser) parseTitle(n *html.Node) {
	if c := n.FirstChild; c != nil && c.Type == html.TextNode {
		p.title = c.Data
	}
}

func (p *htmlParser) consumeString(s string) {
	p.b.WriteString(s)
	p.b.WriteByte('\n')
}

func (p *htmlParser) parseNoscript(n *html.Node) {
	c := n.FirstChild
	if c == nil {
		return
	}
	nodes, err := html.ParseFragment(strings.NewReader(c.Data), nil)
	if err != nil {
		return // ignore error
	}
	for _, v := range nodes {
		p.parseNode(v)
	}
}

func (p *htmlParser) parseNode(n *html.Node) {
	switch n.Type {
	case html.DocumentNode:
		// Parse children
		if c := n.FirstChild; c != nil {
			p.parseNode(c)
		}
	case html.ElementNode:
		switch n.DataAtom {
		case atom.Title:
			p.parseTitle(n)
		case atom.Meta:
			p.parseMeta(n)
		case atom.Img:
			p.parseImg(n)
		case atom.Noscript:
			// Parse insides of noscript as HTML.
			p.parseNoscript(n)
		case atom.Script, atom.Style:
			// skip children
		default:
			// Parse children
			if c := n.FirstChild; c != nil {
				p.parseNode(c)
			}
		}
	case html.TextNode:
		p.consumeString(n.Data)
	}
	// Parse sibling.
	if c := n.NextSibling; c != nil {
		p.parseNode(c)
	}
}

func (p *htmlParser) Parse(r io.Reader) error {
	doc, err := html.Parse(r)
	if err != nil {
		return err
	}
	p.parseNode(doc)
	return nil
}

func (p *htmlParser) Content() string {
	return p.b.String()
}

func (p *htmlParser) Title() string {
	return p.title
}

func parseHTML(r io.Reader) (title, content string, err error) {
	var p htmlParser
	err = p.Parse(r)
	if err != nil {
		return
	}
	return p.Title(), p.Content(), nil
}
<commit_msg>Update go.net import path.<commit_after>package indexer

import (
	"bytes"
	"io"
	"strings"

	"golang.org/x/net/html"
	"golang.org/x/net/html/atom"
)

type htmlParser struct {
	title string
	b     bytes.Buffer
	z     *html.Tokenizer
}

func (p *htmlParser) parseMeta(n *html.Node) {
	indexable := false
	for _, a := range n.Attr {
		if a.Key == "name" {
			v := strings.ToLower(a.Val)
			if v == "keywords" || v == "description" {
				indexable = true
			}
		}
	}
	if !indexable {
		return
	}
	for _, a := range n.Attr {
		if a.Key == "content" {
			p.consumeString(a.Val)
		}
	}
}

func (p *htmlParser) parseImg(n *html.Node) {
	for _, a := range n.Attr {
		if a.Key == "alt" {
			p.consumeString(a.Val)
			return
		}
	}
}

func (p *htmlParser) parseTitle(n *html.Node) {
	if c := n.FirstChild; c != nil && c.Type == html.TextNode {
		p.title = c.Data
	}
}

func (p *htmlParser) consumeString(s string) {
	p.b.WriteString(s)
	p.b.WriteByte('\n')
}

func (p *htmlParser) parseNoscript(n *html.Node) {
	c := n.FirstChild
	if c == nil {
		return
	}
	nodes, err := html.ParseFragment(strings.NewReader(c.Data), nil)
	if err != nil {
		return // ignore error
	}
	for _, v := range nodes {
		p.parseNode(v)
	}
}

func (p *htmlParser) parseNode(n *html.Node) {
	switch n.Type {
	case html.DocumentNode:
		// Parse children
		if c := n.FirstChild; c != nil {
			p.parseNode(c)
		}
	case html.ElementNode:
		switch n.DataAtom {
		case atom.Title:
			p.parseTitle(n)
		case atom.Meta:
			p.parseMeta(n)
		case atom.Img:
			p.parseImg(n)
		case atom.Noscript:
			// Parse insides of noscript as HTML.
			p.parseNoscript(n)
		case atom.Script, atom.Style:
			// skip children
		default:
			// Parse children
			if c := n.FirstChild; c != nil {
				p.parseNode(c)
			}
		}
	case html.TextNode:
		p.consumeString(n.Data)
	}
	// Parse sibling.
	if c := n.NextSibling; c != nil {
		p.parseNode(c)
	}
}

func (p *htmlParser) Parse(r io.Reader) error {
	doc, err := html.Parse(r)
	if err != nil {
		return err
	}
	p.parseNode(doc)
	return nil
}

func (p *htmlParser) Content() string {
	return p.b.String()
}

func (p *htmlParser) Title() string {
	return p.title
}

func parseHTML(r io.Reader) (title, content string, err error) {
	var p htmlParser
	err = p.Parse(r)
	if err != nil {
		return
	}
	return p.Title(), p.Content(), nil
}
<|endoftext|>


<commit_before>package hypervisor

import (
	"net"
	"time"

	"github.com/Symantec/Dominator/lib/tags"
)

const (
	StateStarting      = 0
	StateRunning       = 1
	StateFailedToStart = 2
	StateStopping      = 3
	StateStopped       = 4
	StateDestroying    = 5
	StateMigrating     = 6

	VolumeFormatRaw   = 0
	VolumeFormatQCOW2 = 1
)

type AcknowledgeVmRequest struct {
	IpAddress net.IP
}

type AcknowledgeVmResponse struct {
	Error string
}

type Address struct {
	IpAddress  net.IP `json:",omitempty"`
	MacAddress string
}

type BecomePrimaryVmOwnerRequest struct {
	IpAddress net.IP
}

type BecomePrimaryVmOwnerResponse struct {
	Error string
}

type ChangeAddressPoolRequest struct {
	AddressesToAdd       []Address       // Will be added to free pool.
	AddressesToRemove    []Address       // Will be removed from free pool.
	MaximumFreeAddresses map[string]uint // Key: subnet ID.
}

type ChangeAddressPoolResponse struct {
	Error string
}

type ChangeOwnersRequest struct {
	OwnerGroups []string `json:",omitempty"`
	OwnerUsers  []string `json:",omitempty"`
}

type ChangeOwnersResponse struct {
	Error string
}

type ChangeVmDestroyProtectionRequest struct {
	DestroyProtection bool
	IpAddress         net.IP
}

type ChangeVmDestroyProtectionResponse struct {
	Error string
}

type ChangeVmOwnerUsersRequest struct {
	IpAddress  net.IP
	OwnerUsers []string
}

type ChangeVmOwnerUsersResponse struct {
	Error string
}

type ChangeVmTagsRequest struct {
	IpAddress net.IP
	Tags      tags.Tags
}

type ChangeVmTagsResponse struct {
	Error string
}

type CommitImportedVmRequest struct {
	IpAddress net.IP
}

type CommitImportedVmResponse struct {
	Error string
}

type CopyVmRequest struct {
	AccessToken      []byte
	DhcpTimeout      time.Duration
	IpAddress        net.IP
	SourceHypervisor string
}

type CopyVmResponse struct { // Multiple responses are sent.
	DhcpTimedOut    bool
	Error           string
	Final           bool // If true, this is the final response.
	IpAddress       net.IP
	ProgressMessage string
}

type CreateVmRequest struct {
	DhcpTimeout      time.Duration
	ImageDataSize    uint64
	ImageTimeout     time.Duration
	MinimumFreeBytes uint64
	RoundupPower     uint64
	SecondaryVolumes []Volume
	SkipBootloader   bool
	UserDataSize     uint64
	VmInfo
} // RAW image data (length=ImageDataSize) and user data (length=UserDataSize)
// are streamed afterwards.

type CreateVmResponse struct { // Multiple responses are sent.
	DhcpTimedOut    bool
	Final           bool // If true, this is the final response.
	IpAddress       net.IP
	ProgressMessage string
	Error           string
}

type DeleteVmVolumeRequest struct {
	AccessToken []byte
	IpAddress   net.IP
	VolumeIndex uint
}

type DeleteVmVolumeResponse struct {
	Error string
}

type DestroyVmRequest struct {
	AccessToken []byte
	IpAddress   net.IP
}

type DestroyVmResponse struct {
	Error string
}

type DiscardVmAccessTokenRequest struct {
	AccessToken []byte
	IpAddress   net.IP
}

type DiscardVmAccessTokenResponse struct {
	Error string
}

type DiscardVmOldImageRequest struct {
	IpAddress net.IP
}

type DiscardVmOldImageResponse struct {
	Error string
}

type DiscardVmOldUserDataRequest struct {
	IpAddress net.IP
}

type DiscardVmOldUserDataResponse struct {
	Error string
}

type DiscardVmSnapshotRequest struct {
	IpAddress net.IP
}

type DiscardVmSnapshotResponse struct {
	Error string
}

// The GetUpdates() RPC is fully streamed.
// The client may or may not send GetUpdateRequest messages to the server.
// The server sends a stream of Update messages.

type GetUpdateRequest struct{}

type Update struct {
	HaveAddressPool  bool               `json:",omitempty"`
	AddressPool      []Address          `json:",omitempty"` // Used & free.
	NumFreeAddresses map[string]uint    `json:",omitempty"` // Key: subnet ID.
	HealthStatus     string             `json:",omitempty"`
	HaveSerialNumber bool               `json:",omitempty"`
	SerialNumber     string             `json:",omitempty"`
	HaveSubnets      bool               `json:",omitempty"`
	Subnets          []Subnet           `json:",omitempty"`
	HaveVMs          bool               `json:",omitempty"`
	VMs              map[string]*VmInfo `json:",omitempty"` // Key: IP address.
}

type GetVmAccessTokenRequest struct {
	IpAddress net.IP
	Lifetime  time.Duration
}

type GetVmAccessTokenResponse struct {
	Token []byte `json:",omitempty"`
	Error string
}

type GetVmInfoRequest struct {
	IpAddress net.IP
}

type GetVmInfoResponse struct {
	VmInfo VmInfo
	Error  string
}

type GetVmUserDataRequest struct {
	AccessToken []byte
	IpAddress   net.IP
}

type GetVmUserDataResponse struct {
	Error  string
	Length uint64
} // Data (length=Length) are streamed afterwards.

// The GetVmVolume() RPC is followed by the proto/rsync.GetBlocks message.

type GetVmVolumeRequest struct {
	AccessToken []byte
	IpAddress   net.IP
	VolumeIndex uint
}

type GetVmVolumeResponse struct {
	Error string
}

type ImportLocalVmRequest struct {
	VerificationCookie []byte `json:",omitempty"`
	VmInfo
	VolumeFilenames []string
}

type ImportLocalVmResponse struct {
	Error string
}

type ListVMsRequest struct {
	Sort bool
}

type ListVMsResponse struct {
	IpAddresses []net.IP
}

type ListVolumeDirectoriesRequest struct{}

type ListVolumeDirectoriesResponse struct {
	Directories []string
	Error       string
}

type MigrateVmRequest struct {
	AccessToken      []byte
	DhcpTimeout      time.Duration
	IpAddress        net.IP
	SourceHypervisor string
}

type MigrateVmResponse struct { // Multiple responses are sent.
	Error           string
	Final           bool // If true, this is the final response.
	ProgressMessage string
	RequestCommit   bool
}

type MigrateVmResponseResponse struct {
	Commit bool
}

type NetbootMachineRequest struct {
	Address                      Address
	Files                        map[string][]byte
	FilesExpiration              time.Duration
	Hostname                     string
	NumAcknowledgementsToWaitFor uint
	OfferExpiration              time.Duration
	Subnet                       *Subnet
	WaitTimeout                  time.Duration
}

type NetbootMachineResponse struct {
	Error string
}

type PrepareVmForMigrationRequest struct {
	AccessToken []byte
	Enable      bool
	IpAddress   net.IP
}

type PrepareVmForMigrationResponse struct {
	Error string
}

type ProbeVmPortRequest struct {
	IpAddress  net.IP
	PortNumber uint
	Timeout    time.Duration
}

type ProbeVmPortResponse struct {
	PortIsOpen bool
	Error      string
}

type ReplaceVmImageRequest struct {
	DhcpTimeout      time.Duration
	ImageDataSize    uint64
	ImageName        string `json:",omitempty"`
	ImageTimeout     time.Duration
	ImageURL         string `json:",omitempty"`
	IpAddress        net.IP
	MinimumFreeBytes uint64
	RoundupPower     uint64
	SkipBootloader   bool
} // RAW image data (length=ImageDataSize) is streamed afterwards.

type ReplaceVmImageResponse struct { // Multiple responses are sent.
	DhcpTimedOut    bool
	Final           bool // If true, this is the final response.
	ProgressMessage string
	Error           string
}

type ReplaceVmUserDataRequest struct {
	IpAddress net.IP
	Size      uint64
} // User data (length=Size) are streamed afterwards.

type ReplaceVmUserDataResponse struct {
	Error string
}

type RestoreVmFromSnapshotRequest struct {
	IpAddress         net.IP
	ForceIfNotStopped bool
}

type RestoreVmFromSnapshotResponse struct {
	Error string
}

type RestoreVmImageRequest struct {
	IpAddress net.IP
}

type RestoreVmImageResponse struct {
	Error string
}

type RestoreVmUserDataRequest struct {
	IpAddress net.IP
}

type RestoreVmUserDataResponse struct {
	Error string
}

type SnapshotVmRequest struct {
	IpAddress         net.IP
	ForceIfNotStopped bool
	RootOnly          bool
}

type SnapshotVmResponse struct {
	Error string
}

type StartVmRequest struct {
	AccessToken []byte
	DhcpTimeout time.Duration
	IpAddress   net.IP
}

type StartVmResponse struct {
	DhcpTimedOut bool
	Error        string
}

type StopVmRequest struct {
	AccessToken []byte
	IpAddress   net.IP
}

type StopVmResponse struct {
	Error string
}

type State uint

type Subnet struct {
	Id                string
	IpGateway         net.IP
	IpMask            net.IP // net.IPMask can't be JSON {en,de}coded.
	DomainName        string `json:",omitempty"`
	DomainNameServers []net.IP
	Manage            bool     `json:",omitempty"`
	VlanId            uint     `json:",omitempty"`
	AllowedGroups     []string `json:",omitempty"`
	AllowedUsers      []string `json:",omitempty"`
}

type TraceVmMetadataRequest struct {
	IpAddress net.IP
}

type TraceVmMetadataResponse struct {
	Error string
} // A stream of strings (trace paths) follow.

type UpdateSubnetsRequest struct {
	Add    []Subnet
	Change []Subnet
	Delete []string
}

type UpdateSubnetsResponse struct {
	Error string
}

type VmInfo struct {
	Address            Address
	DestroyProtection  bool   `json:",omitempty"`
	Hostname           string `json:",omitempty"`
	ImageName          string `json:",omitempty"`
	ImageURL           string `json:",omitempty"`
	MemoryInMiB        uint64
	MilliCPUs          uint
	OwnerGroups        []string `json:",omitempty"`
	OwnerUsers         []string `json:",omitempty"`
	SpreadVolumes      bool     `json:",omitempty"`
	State              State
	Tags               tags.Tags `json:",omitempty"`
	SecondaryAddresses []Address `json:",omitempty"`
	SecondarySubnetIDs []string  `json:",omitempty"`
	SubnetId           string    `json:",omitempty"`
	Uncommitted        bool      `json:",omitempty"`
	Volumes            []Volume  `json:",omitempty"`
}

type Volume struct {
	Size   uint64
	Format VolumeFormat
}

type VolumeFormat uint
<commit_msg>Remove obsolete DHCP-related fields in proto/hypervisor.CopyVm messages.<commit_after>package hypervisor

import (
	"net"
	"time"

	"github.com/Symantec/Dominator/lib/tags"
)

const (
	StateStarting      = 0
	StateRunning       = 1
	StateFailedToStart = 2
	StateStopping      = 3
	StateStopped       = 4
	StateDestroying    = 5
	StateMigrating     = 6

	VolumeFormatRaw   = 0
	VolumeFormatQCOW2 = 1
)

type AcknowledgeVmRequest struct {
	IpAddress net.IP
}

type AcknowledgeVmResponse struct {
	Error string
}

type Address struct {
	IpAddress  net.IP `json:",omitempty"`
	MacAddress string
}

type BecomePrimaryVmOwnerRequest struct {
	IpAddress net.IP
}

type BecomePrimaryVmOwnerResponse struct {
	Error string
}

type ChangeAddressPoolRequest struct {
	AddressesToAdd       []Address       // Will be added to free pool.
	AddressesToRemove    []Address       // Will be removed from free pool.
	MaximumFreeAddresses map[string]uint // Key: subnet ID.
}

type ChangeAddressPoolResponse struct {
	Error string
}

type ChangeOwnersRequest struct {
	OwnerGroups []string `json:",omitempty"`
	OwnerUsers  []string `json:",omitempty"`
}

type ChangeOwnersResponse struct {
	Error string
}

type ChangeVmDestroyProtectionRequest struct {
	DestroyProtection bool
	IpAddress         net.IP
}

type ChangeVmDestroyProtectionResponse struct {
	Error string
}

type ChangeVmOwnerUsersRequest struct {
	IpAddress  net.IP
	OwnerUsers []string
}

type ChangeVmOwnerUsersResponse struct {
	Error string
}

type ChangeVmTagsRequest struct {
	IpAddress net.IP
	Tags      tags.Tags
}

type ChangeVmTagsResponse struct {
	Error string
}

type CommitImportedVmRequest struct {
	IpAddress net.IP
}

type CommitImportedVmResponse struct {
	Error string
}

type CopyVmRequest struct {
	AccessToken      []byte
	IpAddress        net.IP
	SourceHypervisor string
}

type CopyVmResponse struct { // Multiple responses are sent.
	Error           string
	Final           bool // If true, this is the final response.
	IpAddress       net.IP
	ProgressMessage string
}

type CreateVmRequest struct {
	DhcpTimeout      time.Duration
	ImageDataSize    uint64
	ImageTimeout     time.Duration
	MinimumFreeBytes uint64
	RoundupPower     uint64
	SecondaryVolumes []Volume
	SkipBootloader   bool
	UserDataSize     uint64
	VmInfo
} // RAW image data (length=ImageDataSize) and user data (length=UserDataSize)
// are streamed afterwards.

type CreateVmResponse struct { // Multiple responses are sent.
	DhcpTimedOut    bool
	Final           bool // If true, this is the final response.
	IpAddress       net.IP
	ProgressMessage string
	Error           string
}

type DeleteVmVolumeRequest struct {
	AccessToken []byte
	IpAddress   net.IP
	VolumeIndex uint
}

type DeleteVmVolumeResponse struct {
	Error string
}

type DestroyVmRequest struct {
	AccessToken []byte
	IpAddress   net.IP
}

type DestroyVmResponse struct {
	Error string
}

type DiscardVmAccessTokenRequest struct {
	AccessToken []byte
	IpAddress   net.IP
}

type DiscardVmAccessTokenResponse struct {
	Error string
}

type DiscardVmOldImageRequest struct {
	IpAddress net.IP
}

type DiscardVmOldImageResponse struct {
	Error string
}

type DiscardVmOldUserDataRequest struct {
	IpAddress net.IP
}

type DiscardVmOldUserDataResponse struct {
	Error string
}

type DiscardVmSnapshotRequest struct {
	IpAddress net.IP
}

type DiscardVmSnapshotResponse struct {
	Error string
}

// The GetUpdates() RPC is fully streamed.
// The client may or may not send GetUpdateRequest messages to the server.
// The server sends a stream of Update messages.

type GetUpdateRequest struct{}

type Update struct {
	HaveAddressPool  bool               `json:",omitempty"`
	AddressPool      []Address          `json:",omitempty"` // Used & free.
	NumFreeAddresses map[string]uint    `json:",omitempty"` // Key: subnet ID.
	HealthStatus     string             `json:",omitempty"`
	HaveSerialNumber bool               `json:",omitempty"`
	SerialNumber     string             `json:",omitempty"`
	HaveSubnets      bool               `json:",omitempty"`
	Subnets          []Subnet           `json:",omitempty"`
	HaveVMs          bool               `json:",omitempty"`
	VMs              map[string]*VmInfo `json:",omitempty"` // Key: IP address.
}

type GetVmAccessTokenRequest struct {
	IpAddress net.IP
	Lifetime  time.Duration
}

type GetVmAccessTokenResponse struct {
	Token []byte `json:",omitempty"`
	Error string
}

type GetVmInfoRequest struct {
	IpAddress net.IP
}

type GetVmInfoResponse struct {
	VmInfo VmInfo
	Error  string
}

type GetVmUserDataRequest struct {
	AccessToken []byte
	IpAddress   net.IP
}

type GetVmUserDataResponse struct {
	Error  string
	Length uint64
} // Data (length=Length) are streamed afterwards.

// The GetVmVolume() RPC is followed by the proto/rsync.GetBlocks message.

type GetVmVolumeRequest struct {
	AccessToken []byte
	IpAddress   net.IP
	VolumeIndex uint
}

type GetVmVolumeResponse struct {
	Error string
}

type ImportLocalVmRequest struct {
	VerificationCookie []byte `json:",omitempty"`
	VmInfo
	VolumeFilenames []string
}

type ImportLocalVmResponse struct {
	Error string
}

type ListVMsRequest struct {
	Sort bool
}

type ListVMsResponse struct {
	IpAddresses []net.IP
}

type ListVolumeDirectoriesRequest struct{}

type ListVolumeDirectoriesResponse struct {
	Directories []string
	Error       string
}

type MigrateVmRequest struct {
	AccessToken      []byte
	DhcpTimeout      time.Duration
	IpAddress        net.IP
	SourceHypervisor string
}

type MigrateVmResponse struct { // Multiple responses are sent.
	Error           string
	Final           bool // If true, this is the final response.
	ProgressMessage string
	RequestCommit   bool
}

type MigrateVmResponseResponse struct {
	Commit bool
}

type NetbootMachineRequest struct {
	Address                      Address
	Files                        map[string][]byte
	FilesExpiration              time.Duration
	Hostname                     string
	NumAcknowledgementsToWaitFor uint
	OfferExpiration              time.Duration
	Subnet                       *Subnet
	WaitTimeout                  time.Duration
}

type NetbootMachineResponse struct {
	Error string
}

type PrepareVmForMigrationRequest struct {
	AccessToken []byte
	Enable      bool
	IpAddress   net.IP
}

type PrepareVmForMigrationResponse struct {
	Error string
}

type ProbeVmPortRequest struct {
	IpAddress  net.IP
	PortNumber uint
	Timeout    time.Duration
}

type ProbeVmPortResponse struct {
	PortIsOpen bool
	Error      string
}

type ReplaceVmImageRequest struct {
	DhcpTimeout      time.Duration
	ImageDataSize    uint64
	ImageName        string `json:",omitempty"`
	ImageTimeout     time.Duration
	ImageURL         string `json:",omitempty"`
	IpAddress        net.IP
	MinimumFreeBytes uint64
	RoundupPower     uint64
	SkipBootloader   bool
} // RAW image data (length=ImageDataSize) is streamed afterwards.

type ReplaceVmImageResponse struct { // Multiple responses are sent.
	DhcpTimedOut    bool
	Final           bool // If true, this is the final response.
	ProgressMessage string
	Error           string
}

type ReplaceVmUserDataRequest struct {
	IpAddress net.IP
	Size      uint64
} // User data (length=Size) are streamed afterwards.

type ReplaceVmUserDataResponse struct {
	Error string
}

type RestoreVmFromSnapshotRequest struct {
	IpAddress         net.IP
	ForceIfNotStopped bool
}

type RestoreVmFromSnapshotResponse struct {
	Error string
}

type RestoreVmImageRequest struct {
	IpAddress net.IP
}

type RestoreVmImageResponse struct {
	Error string
}

type RestoreVmUserDataRequest struct {
	IpAddress net.IP
}

type RestoreVmUserDataResponse struct {
	Error string
}

type SnapshotVmRequest struct {
	IpAddress         net.IP
	ForceIfNotStopped bool
	RootOnly          bool
}

type SnapshotVmResponse struct {
	Error string
}

type StartVmRequest struct {
	AccessToken []byte
	DhcpTimeout time.Duration
	IpAddress   net.IP
}

type StartVmResponse struct {
	DhcpTimedOut bool
	Error        string
}

type StopVmRequest struct {
	AccessToken []byte
	IpAddress   net.IP
}

type StopVmResponse struct {
	Error string
}

type State uint

type Subnet struct {
	Id                string
	IpGateway         net.IP
	IpMask            net.IP // net.IPMask can't be JSON {en,de}coded.
	DomainName        string `json:",omitempty"`
	DomainNameServers []net.IP
	Manage            bool     `json:",omitempty"`
	VlanId            uint     `json:",omitempty"`
	AllowedGroups     []string `json:",omitempty"`
	AllowedUsers      []string `json:",omitempty"`
}

type TraceVmMetadataRequest struct {
	IpAddress net.IP
}

type TraceVmMetadataResponse struct {
	Error string
} // A stream of strings (trace paths) follow.

type UpdateSubnetsRequest struct {
	Add    []Subnet
	Change []Subnet
	Delete []string
}

type UpdateSubnetsResponse struct {
	Error string
}

type VmInfo struct {
	Address            Address
	DestroyProtection  bool   `json:",omitempty"`
	Hostname           string `json:",omitempty"`
	ImageName          string `json:",omitempty"`
	ImageURL           string `json:",omitempty"`
	MemoryInMiB        uint64
	MilliCPUs          uint
	OwnerGroups        []string `json:",omitempty"`
	OwnerUsers         []string `json:",omitempty"`
	SpreadVolumes      bool     `json:",omitempty"`
	State              State
	Tags               tags.Tags `json:",omitempty"`
	SecondaryAddresses []Address `json:",omitempty"`
	SecondarySubnetIDs []string  `json:",omitempty"`
	SubnetId           string    `json:",omitempty"`
	Uncommitted        bool      `json:",omitempty"`
	Volumes            []Volume  `json:",omitempty"`
}

type Volume struct {
	Size   uint64
	Format VolumeFormat
}

type VolumeFormat uint
<|endoftext|>


<commit_before>/*
Copyright 2014 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package dockertools

import (
	"fmt"
	"math/rand"
	"net/http"
	"os"
	"strconv"
	"strings"

	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider"
	kubecontainer "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/container"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/leaky"
	kubeletTypes "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/types"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
	utilerrors "github.com/GoogleCloudPlatform/kubernetes/pkg/util/errors"
	"github.com/docker/docker/pkg/jsonmessage"
	"github.com/docker/docker/pkg/parsers"
	docker "github.com/fsouza/go-dockerclient"
	"github.com/golang/glog"
)

const (
	PodInfraContainerName  = leaky.PodInfraContainerName
	DockerPrefix           = "docker://"
	PodInfraContainerImage = "gcr.io/google_containers/pause:0.8.0"
)

const (
	// Taken from lmctfy https://github.com/google/lmctfy/blob/master/lmctfy/controllers/cpu_controller.cc
	minShares     = 2
	sharesPerCPU  = 1024
	milliCPUToCPU = 1000
)

// DockerInterface is an abstract interface for testability.  It abstracts the interface of docker.Client.
type DockerInterface interface {
	ListContainers(options docker.ListContainersOptions) ([]docker.APIContainers, error)
	InspectContainer(id string) (*docker.Container, error)
	CreateContainer(docker.CreateContainerOptions) (*docker.Container, error)
	StartContainer(id string, hostConfig *docker.HostConfig) error
	StopContainer(id string, timeout uint) error
	RemoveContainer(opts docker.RemoveContainerOptions) error
	InspectImage(image string) (*docker.Image, error)
	ListImages(opts docker.ListImagesOptions) ([]docker.APIImages, error)
	PullImage(opts docker.PullImageOptions, auth docker.AuthConfiguration) error
	RemoveImage(image string) error
	Logs(opts docker.LogsOptions) error
	Version() (*docker.Env, error)
	Info() (*docker.Env, error)
	CreateExec(docker.CreateExecOptions) (*docker.Exec, error)
	StartExec(string, docker.StartExecOptions) error
	InspectExec(id string) (*docker.ExecInspect, error)
}

// KubeletContainerName encapsulates a pod name and a Kubernetes container name.
type KubeletContainerName struct {
	PodFullName   string
	PodUID        types.UID
	ContainerName string
}

// DockerPuller is an abstract interface for testability.  It abstracts image pull operations.
type DockerPuller interface {
	Pull(image string, secrets []api.Secret) error
	IsImagePresent(image string) (bool, error)
}

// dockerPuller is the default implementation of DockerPuller.
type dockerPuller struct {
	client  DockerInterface
	keyring credentialprovider.DockerKeyring
}

type throttledDockerPuller struct {
	puller  dockerPuller
	limiter util.RateLimiter
}

// newDockerPuller creates a new instance of the default implementation of DockerPuller.
func newDockerPuller(client DockerInterface, qps float32, burst int) DockerPuller {
	dp := dockerPuller{
		client:  client,
		keyring: credentialprovider.NewDockerKeyring(),
	}

	if qps == 0.0 {
		return dp
	}
	return &throttledDockerPuller{
		puller:  dp,
		limiter: util.NewTokenBucketRateLimiter(qps, burst),
	}
}

func parseImageName(image string) (string, string) {
	return parsers.ParseRepositoryTag(image)
}

func filterHTTPError(err error, image string) error {
	// docker/docker/pull/11314 prints detailed error info for docker pull.
	// When it hits 502, it returns a verbose html output including an inline svg,
	// which makes the output of kubectl get pods much harder to parse.
	// Here converts such verbose output to a concise one.
	jerr, ok := err.(*jsonmessage.JSONError)
	if ok && (jerr.Code == http.StatusBadGateway ||
		jerr.Code == http.StatusServiceUnavailable ||
		jerr.Code == http.StatusGatewayTimeout) {
		glog.V(2).Infof("Pulling image %q failed: %v", image, err)
		return fmt.Errorf("image pull failed for %s because the registry is temporarily unavailbe.", image)
	} else {
		return err
	}
}

func (p dockerPuller) Pull(image string, secrets []api.Secret) error {
	repoToPull, tag := parseImageName(image)

	// If no tag was specified, use the default "latest".
	if len(tag) == 0 {
		tag = "latest"
	}

	opts := docker.PullImageOptions{
		Repository: repoToPull,
		Tag:        tag,
	}

	keyring, err := credentialprovider.MakeDockerKeyring(secrets, p.keyring)
	if err != nil {
		return err
	}

	creds, haveCredentials := keyring.Lookup(repoToPull)
	if !haveCredentials {
		glog.V(1).Infof("Pulling image %s without credentials", image)

		err := p.client.PullImage(opts, docker.AuthConfiguration{})
		if err == nil {
			return nil
		}

		// Image spec: [<registry>/]<repository>/<image>[:<version] so we count '/'
		explicitRegistry := (strings.Count(image, "/") == 2)
		// Hack, look for a private registry, and decorate the error with the lack of
		// credentials.  This is heuristic, and really probably could be done better
		// by talking to the registry API directly from the kubelet here.
		if explicitRegistry {
			return fmt.Errorf("image pull failed for %s, this may be because there are no credentials on this request.  details: (%v)", image, err)
		}

		return filterHTTPError(err, image)
	}

	var pullErrs []error
	for _, currentCreds := range creds {
		err := p.client.PullImage(opts, currentCreds)
		// If there was no error, return success
		if err == nil {
			return nil
		}

		pullErrs = append(pullErrs, filterHTTPError(err, image))
	}

	return utilerrors.NewAggregate(pullErrs)
}

func (p throttledDockerPuller) Pull(image string, secrets []api.Secret) error {
	if p.limiter.CanAccept() {
		return p.puller.Pull(image, secrets)
	}
	return fmt.Errorf("pull QPS exceeded.")
}

func (p dockerPuller) IsImagePresent(image string) (bool, error) {
	_, err := p.client.InspectImage(image)
	if err == nil {
		return true, nil
	}
	if err == docker.ErrNoSuchImage {
		return false, nil
	}
	return false, err
}

func (p throttledDockerPuller) IsImagePresent(name string) (bool, error) {
	return p.puller.IsImagePresent(name)
}

// DockerContainers is a map of containers
type DockerContainers map[kubeletTypes.DockerID]*docker.APIContainers

func (c DockerContainers) FindPodContainer(podFullName string, uid types.UID, containerName string) (*docker.APIContainers, bool, uint64) {
	for _, dockerContainer := range c {
		if len(dockerContainer.Names) == 0 {
			continue
		}
		// TODO(proppy): build the docker container name and do a map lookup instead?
		dockerName, hash, err := ParseDockerName(dockerContainer.Names[0])
		if err != nil {
			continue
		}
		if dockerName.PodFullName == podFullName &&
			(uid == "" || dockerName.PodUID == uid) &&
			dockerName.ContainerName == containerName {
			return dockerContainer, true, hash
		}
	}
	return nil, false, 0
}

const containerNamePrefix = "k8s"

// Creates a name which can be reversed to identify both full pod name and container name.
func BuildDockerName(dockerName KubeletContainerName, container *api.Container) string {
	containerName := dockerName.ContainerName + "." + strconv.FormatUint(kubecontainer.HashContainer(container), 16)
	return fmt.Sprintf("%s_%s_%s_%s_%08x",
		containerNamePrefix,
		containerName,
		dockerName.PodFullName,
		dockerName.PodUID,
		rand.Uint32())
}

// Unpacks a container name, returning the pod full name and container name we would have used to
// construct the docker name. If we are unable to parse the name, an error is returned.
func ParseDockerName(name string) (dockerName *KubeletContainerName, hash uint64, err error) {
	// For some reason docker appears to be appending '/' to names.
	// If it's there, strip it.
	name = strings.TrimPrefix(name, "/")
	parts := strings.Split(name, "_")
	if len(parts) == 0 || parts[0] != containerNamePrefix {
		err = fmt.Errorf("failed to parse Docker container name %q into parts", name)
		return nil, 0, err
	}
	if len(parts) < 6 {
		// We have at least 5 fields.  We may have more in the future.
		// Anything with less fields than this is not something we can
		// manage.
		glog.Warningf("found a container with the %q prefix, but too few fields (%d): %q", containerNamePrefix, len(parts), name)
		err = fmt.Errorf("Docker container name %q has less parts than expected %v", name, parts)
		return nil, 0, err
	}

	nameParts := strings.Split(parts[1], ".")
	containerName := nameParts[0]
	if len(nameParts) > 1 {
		hash, err = strconv.ParseUint(nameParts[1], 16, 32)
		if err != nil {
			glog.Warningf("invalid container hash %q in container %q", nameParts[1], name)
		}
	}

	podFullName := parts[2] + "_" + parts[3]
	podUID := types.UID(parts[4])

	return &KubeletContainerName{podFullName, podUID, containerName}, hash, nil
}

// Get a docker endpoint, either from the string passed in, or $DOCKER_HOST environment variables
func getDockerEndpoint(dockerEndpoint string) string {
	var endpoint string
	if len(dockerEndpoint) > 0 {
		endpoint = dockerEndpoint
	} else if len(os.Getenv("DOCKER_HOST")) > 0 {
		endpoint = os.Getenv("DOCKER_HOST")
	} else {
		endpoint = "unix:///var/run/docker.sock"
	}
	glog.Infof("Connecting to docker on %s", endpoint)

	return endpoint
}

func ConnectToDockerOrDie(dockerEndpoint string) DockerInterface {
	if dockerEndpoint == "fake://" {
		return &FakeDockerClient{
			VersionInfo: docker.Env{"ApiVersion=1.18"},
		}
	}
	client, err := docker.NewClient(getDockerEndpoint(dockerEndpoint))
	if err != nil {
		glog.Fatalf("Couldn't connect to docker: %v", err)
	}
	return client
}

func milliCPUToShares(milliCPU int64) int64 {
	if milliCPU == 0 {
		// zero milliCPU means unset. Use kernel default.
		return 0
	}
	// Conceptually (milliCPU / milliCPUToCPU) * sharesPerCPU, but factored to improve rounding.
	shares := (milliCPU * sharesPerCPU) / milliCPUToCPU
	if shares < minShares {
		return minShares
	}
	return shares
}

// GetKubeletDockerContainers lists all container or just the running ones.
// Returns a map of docker containers that we manage, keyed by container ID.
// TODO: Move this function with dockerCache to DockerManager.
func GetKubeletDockerContainers(client DockerInterface, allContainers bool) (DockerContainers, error) {
	result := make(DockerContainers)
	containers, err := client.ListContainers(docker.ListContainersOptions{All: allContainers})
	if err != nil {
		return nil, err
	}
	for i := range containers {
		container := &containers[i]
		if len(container.Names) == 0 {
			continue
		}
		// Skip containers that we didn't create to allow users to manually
		// spin up their own containers if they want.
		// TODO(dchen1107): Remove the old separator "--" by end of Oct
		if !strings.HasPrefix(container.Names[0], "/"+containerNamePrefix+"_") &&
			!strings.HasPrefix(container.Names[0], "/"+containerNamePrefix+"--") {
			glog.V(3).Infof("Docker Container: %s is not managed by kubelet.", container.Names[0])
			continue
		}
		result[kubeletTypes.DockerID(container.ID)] = container
	}
	return result, nil
}
<commit_msg>Set minimal shares for containers with no cpu specified<commit_after>/*
Copyright 2014 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package dockertools

import (
	"fmt"
	"math/rand"
	"net/http"
	"os"
	"strconv"
	"strings"

	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider"
	kubecontainer "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/container"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/leaky"
	kubeletTypes "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/types"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
	utilerrors "github.com/GoogleCloudPlatform/kubernetes/pkg/util/errors"
	"github.com/docker/docker/pkg/jsonmessage"
	"github.com/docker/docker/pkg/parsers"
	docker "github.com/fsouza/go-dockerclient"
	"github.com/golang/glog"
)

const (
	PodInfraContainerName  = leaky.PodInfraContainerName
	DockerPrefix           = "docker://"
	PodInfraContainerImage = "gcr.io/google_containers/pause:0.8.0"
)

const (
	// Taken from lmctfy https://github.com/google/lmctfy/blob/master/lmctfy/controllers/cpu_controller.cc
	minShares     = 2
	sharesPerCPU  = 1024
	milliCPUToCPU = 1000
)

// DockerInterface is an abstract interface for testability.  It abstracts the interface of docker.Client.
type DockerInterface interface {
	ListContainers(options docker.ListContainersOptions) ([]docker.APIContainers, error)
	InspectContainer(id string) (*docker.Container, error)
	CreateContainer(docker.CreateContainerOptions) (*docker.Container, error)
	StartContainer(id string, hostConfig *docker.HostConfig) error
	StopContainer(id string, timeout uint) error
	RemoveContainer(opts docker.RemoveContainerOptions) error
	InspectImage(image string) (*docker.Image, error)
	ListImages(opts docker.ListImagesOptions) ([]docker.APIImages, error)
	PullImage(opts docker.PullImageOptions, auth docker.AuthConfiguration) error
	RemoveImage(image string) error
	Logs(opts docker.LogsOptions) error
	Version() (*docker.Env, error)
	Info() (*docker.Env, error)
	CreateExec(docker.CreateExecOptions) (*docker.Exec, error)
	StartExec(string, docker.StartExecOptions) error
	InspectExec(id string) (*docker.ExecInspect, error)
}

// KubeletContainerName encapsulates a pod name and a Kubernetes container name.
type KubeletContainerName struct {
	PodFullName   string
	PodUID        types.UID
	ContainerName string
}

// DockerPuller is an abstract interface for testability.  It abstracts image pull operations.
type DockerPuller interface {
	Pull(image string, secrets []api.Secret) error
	IsImagePresent(image string) (bool, error)
}

// dockerPuller is the default implementation of DockerPuller.
type dockerPuller struct {
	client  DockerInterface
	keyring credentialprovider.DockerKeyring
}

type throttledDockerPuller struct {
	puller  dockerPuller
	limiter util.RateLimiter
}

// newDockerPuller creates a new instance of the default implementation of DockerPuller.
func newDockerPuller(client DockerInterface, qps float32, burst int) DockerPuller {
	dp := dockerPuller{
		client:  client,
		keyring: credentialprovider.NewDockerKeyring(),
	}

	if qps == 0.0 {
		return dp
	}
	return &throttledDockerPuller{
		puller:  dp,
		limiter: util.NewTokenBucketRateLimiter(qps, burst),
	}
}

func parseImageName(image string) (string, string) {
	return parsers.ParseRepositoryTag(image)
}

func filterHTTPError(err error, image string) error {
	// docker/docker/pull/11314 prints detailed error info for docker pull.
	// When it hits 502, it returns a verbose html output including an inline svg,
	// which makes the output of kubectl get pods much harder to parse.
	// Here converts such verbose output to a concise one.
	jerr, ok := err.(*jsonmessage.JSONError)
	if ok && (jerr.Code == http.StatusBadGateway ||
		jerr.Code == http.StatusServiceUnavailable ||
		jerr.Code == http.StatusGatewayTimeout) {
		glog.V(2).Infof("Pulling image %q failed: %v", image, err)
		return fmt.Errorf("image pull failed for %s because the registry is temporarily unavailbe.", image)
	} else {
		return err
	}
}

func (p dockerPuller) Pull(image string, secrets []api.Secret) error {
	repoToPull, tag := parseImageName(image)

	// If no tag was specified, use the default "latest".
	if len(tag) == 0 {
		tag = "latest"
	}

	opts := docker.PullImageOptions{
		Repository: repoToPull,
		Tag:        tag,
	}

	keyring, err := credentialprovider.MakeDockerKeyring(secrets, p.keyring)
	if err != nil {
		return err
	}

	creds, haveCredentials := keyring.Lookup(repoToPull)
	if !haveCredentials {
		glog.V(1).Infof("Pulling image %s without credentials", image)

		err := p.client.PullImage(opts, docker.AuthConfiguration{})
		if err == nil {
			return nil
		}

		// Image spec: [<registry>/]<repository>/<image>[:<version] so we count '/'
		explicitRegistry := (strings.Count(image, "/") == 2)
		// Hack, look for a private registry, and decorate the error with the lack of
		// credentials.  This is heuristic, and really probably could be done better
		// by talking to the registry API directly from the kubelet here.
		if explicitRegistry {
			return fmt.Errorf("image pull failed for %s, this may be because there are no credentials on this request.  details: (%v)", image, err)
		}

		return filterHTTPError(err, image)
	}

	var pullErrs []error
	for _, currentCreds := range creds {
		err := p.client.PullImage(opts, currentCreds)
		// If there was no error, return success
		if err == nil {
			return nil
		}

		pullErrs = append(pullErrs, filterHTTPError(err, image))
	}

	return utilerrors.NewAggregate(pullErrs)
}

func (p throttledDockerPuller) Pull(image string, secrets []api.Secret) error {
	if p.limiter.CanAccept() {
		return p.puller.Pull(image, secrets)
	}
	return fmt.Errorf("pull QPS exceeded.")
}

func (p dockerPuller) IsImagePresent(image string) (bool, error) {
	_, err := p.client.InspectImage(image)
	if err == nil {
		return true, nil
	}
	if err == docker.ErrNoSuchImage {
		return false, nil
	}
	return false, err
}

func (p throttledDockerPuller) IsImagePresent(name string) (bool, error) {
	return p.puller.IsImagePresent(name)
}

// DockerContainers is a map of containers
type DockerContainers map[kubeletTypes.DockerID]*docker.APIContainers

func (c DockerContainers) FindPodContainer(podFullName string, uid types.UID, containerName string) (*docker.APIContainers, bool, uint64) {
	for _, dockerContainer := range c {
		if len(dockerContainer.Names) == 0 {
			continue
		}
		// TODO(proppy): build the docker container name and do a map lookup instead?
		dockerName, hash, err := ParseDockerName(dockerContainer.Names[0])
		if err != nil {
			continue
		}
		if dockerName.PodFullName == podFullName &&
			(uid == "" || dockerName.PodUID == uid) &&
			dockerName.ContainerName == containerName {
			return dockerContainer, true, hash
		}
	}
	return nil, false, 0
}

const containerNamePrefix = "k8s"

// Creates a name which can be reversed to identify both full pod name and container name.
func BuildDockerName(dockerName KubeletContainerName, container *api.Container) string {
	containerName := dockerName.ContainerName + "." + strconv.FormatUint(kubecontainer.HashContainer(container), 16)
	return fmt.Sprintf("%s_%s_%s_%s_%08x",
		containerNamePrefix,
		containerName,
		dockerName.PodFullName,
		dockerName.PodUID,
		rand.Uint32())
}

// Unpacks a container name, returning the pod full name and container name we would have used to
// construct the docker name. If we are unable to parse the name, an error is returned.
func ParseDockerName(name string) (dockerName *KubeletContainerName, hash uint64, err error) {
	// For some reason docker appears to be appending '/' to names.
	// If it's there, strip it.
	name = strings.TrimPrefix(name, "/")
	parts := strings.Split(name, "_")
	if len(parts) == 0 || parts[0] != containerNamePrefix {
		err = fmt.Errorf("failed to parse Docker container name %q into parts", name)
		return nil, 0, err
	}
	if len(parts) < 6 {
		// We have at least 5 fields.  We may have more in the future.
		// Anything with less fields than this is not something we can
		// manage.
		glog.Warningf("found a container with the %q prefix, but too few fields (%d): %q", containerNamePrefix, len(parts), name)
		err = fmt.Errorf("Docker container name %q has less parts than expected %v", name, parts)
		return nil, 0, err
	}

	nameParts := strings.Split(parts[1], ".")
	containerName := nameParts[0]
	if len(nameParts) > 1 {
		hash, err = strconv.ParseUint(nameParts[1], 16, 32)
		if err != nil {
			glog.Warningf("invalid container hash %q in container %q", nameParts[1], name)
		}
	}

	podFullName := parts[2] + "_" + parts[3]
	podUID := types.UID(parts[4])

	return &KubeletContainerName{podFullName, podUID, containerName}, hash, nil
}

// Get a docker endpoint, either from the string passed in, or $DOCKER_HOST environment variables
func getDockerEndpoint(dockerEndpoint string) string {
	var endpoint string
	if len(dockerEndpoint) > 0 {
		endpoint = dockerEndpoint
	} else if len(os.Getenv("DOCKER_HOST")) > 0 {
		endpoint = os.Getenv("DOCKER_HOST")
	} else {
		endpoint = "unix:///var/run/docker.sock"
	}
	glog.Infof("Connecting to docker on %s", endpoint)

	return endpoint
}

func ConnectToDockerOrDie(dockerEndpoint string) DockerInterface {
	if dockerEndpoint == "fake://" {
		return &FakeDockerClient{
			VersionInfo: docker.Env{"ApiVersion=1.18"},
		}
	}
	client, err := docker.NewClient(getDockerEndpoint(dockerEndpoint))
	if err != nil {
		glog.Fatalf("Couldn't connect to docker: %v", err)
	}
	return client
}

func milliCPUToShares(milliCPU int64) int64 {
	if milliCPU == 0 {
		// Docker converts zero milliCPU to unset, which maps to kernel default
		// for unset: 1024. Return 2 here to really match kernel default for
		// zero milliCPU.
		return 2
	}
	// Conceptually (milliCPU / milliCPUToCPU) * sharesPerCPU, but factored to improve rounding.
	shares := (milliCPU * sharesPerCPU) / milliCPUToCPU
	if shares < minShares {
		return minShares
	}
	return shares
}

// GetKubeletDockerContainers lists all container or just the running ones.
// Returns a map of docker containers that we manage, keyed by container ID.
// TODO: Move this function with dockerCache to DockerManager.
func GetKubeletDockerContainers(client DockerInterface, allContainers bool) (DockerContainers, error) {
	result := make(DockerContainers)
	containers, err := client.ListContainers(docker.ListContainersOptions{All: allContainers})
	if err != nil {
		return nil, err
	}
	for i := range containers {
		container := &containers[i]
		if len(container.Names) == 0 {
			continue
		}
		// Skip containers that we didn't create to allow users to manually
		// spin up their own containers if they want.
		// TODO(dchen1107): Remove the old separator "--" by end of Oct
		if !strings.HasPrefix(container.Names[0], "/"+containerNamePrefix+"_") &&
			!strings.HasPrefix(container.Names[0], "/"+containerNamePrefix+"--") {
			glog.V(3).Infof("Docker Container: %s is not managed by kubelet.", container.Names[0])
			continue
		}
		result[kubeletTypes.DockerID(container.ID)] = container
	}
	return result, nil
}
<|endoftext|>


<commit_before>// 8 february 2014
package ui

import (
	"fmt"
//	"syscall"
	"unsafe"
)

var (
	hInstance		_HANDLE
	nCmdShow	int
	// TODO font
)

// TODO is this trick documented in MSDN?
func getWinMainhInstance() (err error) {
	r1, _, err := kernel32.NewProc("GetModuleHandleW").Call(uintptr(_NULL))
	if r1 == 0 {		// failure
		return err
	}
	hInstance = _HANDLE(r1)
	return nil
}

// TODO this is what MinGW-w64's crt (svn revision TODO) does; is it best? is any of this documented anywhere on MSDN?
func getWinMainnCmdShow() {
	var info struct {
		cb				uint32
		lpReserved		*uint16
		lpDesktop			*uint16
		lpTitle			*uint16
		dwX				uint32
		dwY				uint32
		dwXSize			uint32
		dwYSzie			uint32
		dwXCountChars	uint32
		dwYCountChars	uint32
		dwFillAttribute		uint32
		dwFlags			uint32
		wShowWindow		uint16
		cbReserved2		uint16
		lpReserved2		*byte
		hStdInput			_HANDLE
		hStdOutput		_HANDLE
		hStdError			_HANDLE
	}
	const _STARTF_USESHOWWINDOW = 0x00000001

	// does not fail according to MSDN
	kernel32.NewProc("GetStartupInfoW").Call(uintptr(unsafe.Pointer(&info)))
	if info.dwFlags & _STARTF_USESHOWWINDOW != 0 {
		nCmdShow = int(info.wShowWindow)
	} else {
		nCmdShow = _SW_SHOWDEFAULT
	}
}

func doWindowsInit() (err error) {
	err = getWinMainhInstance()
	if err != nil {
		return fmt.Errorf("error getting WinMain hInstance: %v", err)
	}
	getWinMainnCmdShow()
	err = initWndClassInfo()
	if err != nil {
		return fmt.Errorf("error initializing standard window class auxiliary info: %v", err)
	}
	err = getStandardWindowFonts()
	if err != nil {
		return fmt.Errorf("error getting standard window fonts: %v", err)
	}
	err = initCommonControls()
	if err != nil {
		return fmt.Errorf("error initializing Common Controls (comctl32.dll): %v", err)
	}
	// TODO others
	return nil		// all ready to go
}
<commit_msg>More TODO reduction.<commit_after>// 8 february 2014
package ui

import (
	"fmt"
//	"syscall"
	"unsafe"
)

var (
	hInstance		_HANDLE
	nCmdShow	int
)

// TODO is this trick documented in MSDN?
func getWinMainhInstance() (err error) {
	r1, _, err := kernel32.NewProc("GetModuleHandleW").Call(uintptr(_NULL))
	if r1 == 0 {		// failure
		return err
	}
	hInstance = _HANDLE(r1)
	return nil
}

// TODO this is what MinGW-w64's crt (svn revision TODO) does; is it best? is any of this documented anywhere on MSDN?
func getWinMainnCmdShow() {
	var info struct {
		cb				uint32
		lpReserved		*uint16
		lpDesktop			*uint16
		lpTitle			*uint16
		dwX				uint32
		dwY				uint32
		dwXSize			uint32
		dwYSzie			uint32
		dwXCountChars	uint32
		dwYCountChars	uint32
		dwFillAttribute		uint32
		dwFlags			uint32
		wShowWindow		uint16
		cbReserved2		uint16
		lpReserved2		*byte
		hStdInput			_HANDLE
		hStdOutput		_HANDLE
		hStdError			_HANDLE
	}
	const _STARTF_USESHOWWINDOW = 0x00000001

	// does not fail according to MSDN
	kernel32.NewProc("GetStartupInfoW").Call(uintptr(unsafe.Pointer(&info)))
	if info.dwFlags & _STARTF_USESHOWWINDOW != 0 {
		nCmdShow = int(info.wShowWindow)
	} else {
		nCmdShow = _SW_SHOWDEFAULT
	}
}

func doWindowsInit() (err error) {
	err = getWinMainhInstance()
	if err != nil {
		return fmt.Errorf("error getting WinMain hInstance: %v", err)
	}
	getWinMainnCmdShow()
	err = initWndClassInfo()
	if err != nil {
		return fmt.Errorf("error initializing standard window class auxiliary info: %v", err)
	}
	err = getStandardWindowFonts()
	if err != nil {
		return fmt.Errorf("error getting standard window fonts: %v", err)
	}
	err = initCommonControls()
	if err != nil {
		return fmt.Errorf("error initializing Common Controls (comctl32.dll): %v", err)
	}
	// TODO others
	return nil		// all ready to go
}
<|endoftext|>