<commit_before>package resource

import (
	"github.com/concourse/atc"
	"github.com/concourse/atc/worker"
	"github.com/concourse/baggageclaim"
	"github.com/pivotal-golang/lager"
)

type ResourceType string
type ContainerImage string

type Session struct {
	ID        worker.Identifier
	Ephemeral bool
}

//go:generate counterfeiter . Tracker

type Tracker interface {
	Init(lager.Logger, Metadata, Session, ResourceType, atc.Tags) (Resource, error)
	InitWithCache(lager.Logger, Metadata, Session, ResourceType, atc.Tags, CacheIdentifier) (Resource, Cache, error)
}

//go:generate counterfeiter . Cache

type Cache interface {
	IsInitialized() (bool, error)
	Initialize() error
}

type Metadata interface {
	Env() []string
}

type EmptyMetadata struct{}

func (m EmptyMetadata) Env() []string { return nil }

type tracker struct {
	workerClient worker.Client
}

type TrackerFactory struct{}

func (TrackerFactory) TrackerFor(client worker.Client) Tracker {
	return NewTracker(client)
}

func NewTracker(workerClient worker.Client) Tracker {
	return &tracker{
		workerClient: workerClient,
	}
}

type VolumeMount struct {
	Volume    baggageclaim.Volume
	MountPath string
}

func (tracker *tracker) Init(logger lager.Logger, metadata Metadata, session Session, typ ResourceType, tags atc.Tags) (Resource, error) {
	logger = logger.Session("init")

	logger.Debug("start")
	defer logger.Debug("done")

	container, found, err := tracker.workerClient.FindContainerForIdentifier(logger, session.ID)
	if err != nil {
		logger.Error("failed-to-look-for-existing-container", err)
		return nil, err
	}

	if found {
		logger.Info("found-existing", lager.Data{"container": container.Handle()})
		return NewResource(container), nil
	}

	logger.Info("creating-container", lager.Data{"identifier": session.ID})

	container, err = tracker.workerClient.CreateContainer(logger, session.ID, worker.ResourceTypeContainerSpec{
		Type:      string(typ),
		Ephemeral: session.Ephemeral,
		Tags:      tags,
		Env:       metadata.Env(),
	})
	if err != nil {
		return nil, err
	}

	logger.Info("created", lager.Data{"container": container.Handle()})

	return NewResource(container), nil
}

func (tracker *tracker) InitWithCache(logger lager.Logger, metadata Metadata, session Session, typ ResourceType, tags atc.Tags, cacheIdentifier CacheIdentifier) (Resource, Cache, error) {
	logger = logger.Session("init-with-cache")

	logger.Debug("start")
	defer logger.Debug("done")

	container, found, err := tracker.workerClient.FindContainerForIdentifier(logger, session.ID)
	if err != nil {
		logger.Error("failed-to-look-for-existing-container", err)
		return nil, nil, err
	}

	if found {
		logger.Info("found-existing", lager.Data{"container": container.Handle()})

		var cache Cache

		volumes := container.Volumes()
		switch len(volumes) {
		case 0:
			logger.Info("no-cache")
			cache = noopCache{}
		default:
			logger.Info("found-cache")
			cache = volumeCache{volumes[0]}
		}

		return NewResource(container), cache, nil
	}

	logger.Info("no-existing-container")

	resourceSpec := worker.WorkerSpec{
		ResourceType: string(typ),
		Tags:         tags,
	}

	chosenWorker, err := tracker.workerClient.Satisfying(resourceSpec)
	if err != nil {
		logger.Info("no-workers-satisfying-spec", lager.Data{
			"error": err.Error(),
		})
		return nil, nil, err
	}

	vm, hasVM := chosenWorker.VolumeManager()
	if !hasVM {
		logger.Info("creating-container-without-cache", lager.Data{"identifier": session.ID})

		container, err := chosenWorker.CreateContainer(logger, session.ID, worker.ResourceTypeContainerSpec{
			Type:      string(typ),
			Ephemeral: session.Ephemeral,
			Tags:      tags,
			Env:       metadata.Env(),
		})
		if err != nil {
			logger.Error("faild-to-create-container", err)
			return nil, nil, err
		}

		logger.Info("created", lager.Data{"container": container.Handle()})

		return NewResource(container), noopCache{}, nil
	}

	cachedVolume, cacheFound, err := cacheIdentifier.FindOn(logger, vm)
	if err != nil {
		logger.Error("failed-to-look-for-cache", err)
		return nil, nil, err
	}

	if cacheFound {
		logger.Info("found-cache", lager.Data{"volume": cachedVolume.Handle()})
	} else {
		logger.Info("no-cache-found")

		cachedVolume, err = cacheIdentifier.CreateOn(logger, vm)
		if err != nil {
			return nil, nil, err
		}

		logger.Info("new-cache", lager.Data{"volume": cachedVolume.Handle()})
	}

	defer cachedVolume.Release()

	logger.Info("creating-container-with-cache", lager.Data{"identifier": session.ID})

	container, err = chosenWorker.CreateContainer(logger, session.ID, worker.ResourceTypeContainerSpec{
		Type:      string(typ),
		Ephemeral: session.Ephemeral,
		Tags:      tags,
		Env:       metadata.Env(),
		Cache: worker.VolumeMount{
			Volume:    cachedVolume,
			MountPath: ResourcesDir("get"),
		},
	})
	if err != nil {
		logger.Error("failed-to-create-container", err)
		return nil, nil, err
	}

	logger.Info("created", lager.Data{"container": container.Handle()})

	return NewResource(container), volumeCache{cachedVolume}, nil
}
<commit_msg>don't log container identifier; too verbose<commit_after>package resource

import (
	"github.com/concourse/atc"
	"github.com/concourse/atc/worker"
	"github.com/concourse/baggageclaim"
	"github.com/pivotal-golang/lager"
)

type ResourceType string
type ContainerImage string

type Session struct {
	ID        worker.Identifier
	Ephemeral bool
}

//go:generate counterfeiter . Tracker

type Tracker interface {
	Init(lager.Logger, Metadata, Session, ResourceType, atc.Tags) (Resource, error)
	InitWithCache(lager.Logger, Metadata, Session, ResourceType, atc.Tags, CacheIdentifier) (Resource, Cache, error)
}

//go:generate counterfeiter . Cache

type Cache interface {
	IsInitialized() (bool, error)
	Initialize() error
}

type Metadata interface {
	Env() []string
}

type EmptyMetadata struct{}

func (m EmptyMetadata) Env() []string { return nil }

type tracker struct {
	workerClient worker.Client
}

type TrackerFactory struct{}

func (TrackerFactory) TrackerFor(client worker.Client) Tracker {
	return NewTracker(client)
}

func NewTracker(workerClient worker.Client) Tracker {
	return &tracker{
		workerClient: workerClient,
	}
}

type VolumeMount struct {
	Volume    baggageclaim.Volume
	MountPath string
}

func (tracker *tracker) Init(logger lager.Logger, metadata Metadata, session Session, typ ResourceType, tags atc.Tags) (Resource, error) {
	logger = logger.Session("init")

	logger.Debug("start")
	defer logger.Debug("done")

	container, found, err := tracker.workerClient.FindContainerForIdentifier(logger, session.ID)
	if err != nil {
		logger.Error("failed-to-look-for-existing-container", err)
		return nil, err
	}

	if found {
		logger.Info("found-existing", lager.Data{"container": container.Handle()})
		return NewResource(container), nil
	}

	logger.Info("creating-container")

	container, err = tracker.workerClient.CreateContainer(logger, session.ID, worker.ResourceTypeContainerSpec{
		Type:      string(typ),
		Ephemeral: session.Ephemeral,
		Tags:      tags,
		Env:       metadata.Env(),
	})
	if err != nil {
		return nil, err
	}

	logger.Info("created", lager.Data{"container": container.Handle()})

	return NewResource(container), nil
}

func (tracker *tracker) InitWithCache(logger lager.Logger, metadata Metadata, session Session, typ ResourceType, tags atc.Tags, cacheIdentifier CacheIdentifier) (Resource, Cache, error) {
	logger = logger.Session("init-with-cache")

	logger.Debug("start")
	defer logger.Debug("done")

	container, found, err := tracker.workerClient.FindContainerForIdentifier(logger, session.ID)
	if err != nil {
		logger.Error("failed-to-look-for-existing-container", err)
		return nil, nil, err
	}

	if found {
		logger.Info("found-existing", lager.Data{"container": container.Handle()})

		var cache Cache

		volumes := container.Volumes()
		switch len(volumes) {
		case 0:
			logger.Info("no-cache")
			cache = noopCache{}
		default:
			logger.Info("found-cache")
			cache = volumeCache{volumes[0]}
		}

		return NewResource(container), cache, nil
	}

	logger.Info("no-existing-container")

	resourceSpec := worker.WorkerSpec{
		ResourceType: string(typ),
		Tags:         tags,
	}

	chosenWorker, err := tracker.workerClient.Satisfying(resourceSpec)
	if err != nil {
		logger.Info("no-workers-satisfying-spec", lager.Data{
			"error": err.Error(),
		})
		return nil, nil, err
	}

	vm, hasVM := chosenWorker.VolumeManager()
	if !hasVM {
		logger.Info("creating-container-without-cache")

		container, err := chosenWorker.CreateContainer(logger, session.ID, worker.ResourceTypeContainerSpec{
			Type:      string(typ),
			Ephemeral: session.Ephemeral,
			Tags:      tags,
			Env:       metadata.Env(),
		})
		if err != nil {
			logger.Error("faild-to-create-container", err)
			return nil, nil, err
		}

		logger.Info("created", lager.Data{"container": container.Handle()})

		return NewResource(container), noopCache{}, nil
	}

	cachedVolume, cacheFound, err := cacheIdentifier.FindOn(logger, vm)
	if err != nil {
		logger.Error("failed-to-look-for-cache", err)
		return nil, nil, err
	}

	if cacheFound {
		logger.Info("found-cache", lager.Data{"volume": cachedVolume.Handle()})
	} else {
		logger.Info("no-cache-found")

		cachedVolume, err = cacheIdentifier.CreateOn(logger, vm)
		if err != nil {
			return nil, nil, err
		}

		logger.Info("new-cache", lager.Data{"volume": cachedVolume.Handle()})
	}

	defer cachedVolume.Release()

	logger.Info("creating-container-with-cache")

	container, err = chosenWorker.CreateContainer(logger, session.ID, worker.ResourceTypeContainerSpec{
		Type:      string(typ),
		Ephemeral: session.Ephemeral,
		Tags:      tags,
		Env:       metadata.Env(),
		Cache: worker.VolumeMount{
			Volume:    cachedVolume,
			MountPath: ResourcesDir("get"),
		},
	})
	if err != nil {
		logger.Error("failed-to-create-container", err)
		return nil, nil, err
	}

	logger.Info("created", lager.Data{"container": container.Handle()})

	return NewResource(container), volumeCache{cachedVolume}, nil
}
<|endoftext|>


<commit_before>package fix

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"strings"
	"time"
)

var entryFixes []EntryFix

func init() {
	entryFixes = []EntryFix{
		FixAddClosedAtTimestamp{},
		FixSplitCommitMessage{},
		FixCommitMessagePrefixWithTilde{},
	}
}

type EntryFix interface {
	// Parses io.Reader for the error that can be fixed
	CanFix(io.Reader) (bool, error)

	// Returns byte slice that has been fixed
	Execute(io.Reader) ([]byte, error)
}

// Parse the opened at timestamp and add 2 mins
// then append it to the end
type FixAddClosedAtTimestamp struct{}

func (FixAddClosedAtTimestamp) CanFix(r io.Reader) (bool, error) {
	data, err := ioutil.ReadAll(r)
	if err != nil {
		return false, err
	}

	return !lastLineIsTimestamp(data), nil
}

func lastLineIsTimestamp(data []byte) bool {
	scanner := bufio.NewScanner(bytes.NewReader(data))
	// Scan to the last line
	for scanner.Scan() {
	}
	_, err := time.Parse(time.UnixDate, scanner.Text())

	return err == nil
}

func (FixAddClosedAtTimestamp) Execute(r io.Reader) ([]byte, error) {
	// For adding 2 mins and making the closed at timestamp
	var openedAt time.Time

	// For storing the fixed output
	b := bytes.NewBuffer(make([]byte, 0, 1024))

	scanner := bufio.NewScanner(r)

	// Scan in the opened at timestamp
	if scanner.Scan() {
		if time, err := time.Parse(time.UnixDate, scanner.Text()); err != nil {
			// First line wasn't a timestamp
			return nil, err
		} else {
			openedAt = time
			// Print the timestamp to the fixed buffer
			if _, err := fmt.Fprintln(b, scanner.Text()); err != nil {
				return nil, err
			}
		}
	} else {
		return nil, errors.New("error parsing opened at timestamp")
	}

	// Scan and copy lines into the fixed buffer
	for scanner.Scan() {
		if scanner.Err() != nil {
			return nil, scanner.Err()
		}

		if _, err := fmt.Fprintln(b, scanner.Text()); err != nil {
			return nil, err
		}
	}

	// Append the closed at timestamp to the end of the buffer
	closedAt := openedAt.Add(time.Minute * 2)
	if _, err := fmt.Fprintf(b, "\n%s\n", closedAt.Format(time.UnixDate)); err != nil {
		return nil, err
	}

	return b.Bytes(), nil
}

/*
	Fix a commit message with the format

		#~ Commit Msg
		# Additional Msg

	By turning it into this

		# Commit Msg | Additional Msg

*/
type FixSplitCommitMessage struct{}

func (FixSplitCommitMessage) CanFix(r io.Reader) (bool, error) {
	return hasSplitCommitMsg(r), nil
}

func hasSplitCommitMsg(r io.Reader) bool {
	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		if strings.HasPrefix(scanner.Text(), "#~ ") {
			if scanner.Scan() {
				if strings.HasPrefix(scanner.Text(), "# ") {
					return true
				}
			}
		}
	}
	return false
}

func (FixSplitCommitMessage) Execute(r io.Reader) ([]byte, error) {
	// For storing the fixed output
	b := bytes.NewBuffer(make([]byte, 0, 1024))

	scanner := bufio.NewScanner(r)

	for scanner.Scan() {
		line := scanner.Text()
		if !strings.HasPrefix(line, "#~ ") {
			fmt.Fprintln(b, line)
			continue
		}

		// We've found line 1 of the split commit message
		part1 := strings.TrimPrefix(line, "#~ ")

		if scanner.Scan() {
			// Trim line 2 of the message and put part1 and part2 together
			part2 := strings.TrimPrefix(scanner.Text(), "# ")
			fmt.Fprintf(b, "# %s | %s\n", part1, part2)
			continue

		} else {
			// Maybe this should be a panic
			return nil, errors.New("attempt to fix split commit message that doesn't exist")
		}
	}

	return b.Bytes(), nil
}

/*
	Fix a commit message line with the #~ format

		#~ Commit Msg

	to

		# Commit Msg

*/
type FixCommitMessagePrefixWithTilde struct{}

func (FixCommitMessagePrefixWithTilde) CanFix(r io.Reader) (bool, error) {
	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		if strings.HasPrefix(scanner.Text(), "#~ ") {
			if scanner.Scan() {
				// Make sure this isn't a split commit message
				if !strings.HasPrefix(scanner.Text(), "# ") {
					return true, nil
				}
			}
		}
	}
	return false, nil
}

func (FixCommitMessagePrefixWithTilde) Execute(r io.Reader) ([]byte, error) {
	// For storing the fixed output
	b := bytes.NewBuffer(make([]byte, 0, 1024))

	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		line := scanner.Text()

		if strings.HasPrefix(line, "#~ ") {
			// Trim out the ~ character and place in the buffer
			if _, err := fmt.Fprintln(b, strings.Replace(line, "#~", "#", 1)); err != nil {
				return nil, err
			}
			break
		}

		if _, err := fmt.Fprintln(b, line); err != nil {
			return nil, err
		}
	}

	// Copy the remaining bytes into the buffer
	for scanner.Scan() {
		if _, err := fmt.Fprintln(b, scanner.Text()); err != nil {
			return nil, err
		}
	}

	return b.Bytes(), nil
}
<commit_msg>Rearranged this fix for readability | Also check error returns from fmt.Fprint()<commit_after>package fix

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"strings"
	"time"
)

var entryFixes []EntryFix

func init() {
	entryFixes = []EntryFix{
		FixAddClosedAtTimestamp{},
		FixSplitCommitMessage{},
		FixCommitMessagePrefixWithTilde{},
	}
}

type EntryFix interface {
	// Parses io.Reader for the error that can be fixed
	CanFix(io.Reader) (bool, error)

	// Returns byte slice that has been fixed
	Execute(io.Reader) ([]byte, error)
}

// Parse the opened at timestamp and add 2 mins
// then append it to the end
type FixAddClosedAtTimestamp struct{}

func (FixAddClosedAtTimestamp) CanFix(r io.Reader) (bool, error) {
	data, err := ioutil.ReadAll(r)
	if err != nil {
		return false, err
	}

	return !lastLineIsTimestamp(data), nil
}

func lastLineIsTimestamp(data []byte) bool {
	scanner := bufio.NewScanner(bytes.NewReader(data))
	// Scan to the last line
	for scanner.Scan() {
	}
	_, err := time.Parse(time.UnixDate, scanner.Text())

	return err == nil
}

func (FixAddClosedAtTimestamp) Execute(r io.Reader) ([]byte, error) {
	// For adding 2 mins and making the closed at timestamp
	var openedAt time.Time

	// For storing the fixed output
	b := bytes.NewBuffer(make([]byte, 0, 1024))

	scanner := bufio.NewScanner(r)

	// Scan in the opened at timestamp
	if scanner.Scan() {
		if time, err := time.Parse(time.UnixDate, scanner.Text()); err != nil {
			// First line wasn't a timestamp
			return nil, err
		} else {
			openedAt = time
			// Print the timestamp to the fixed buffer
			if _, err := fmt.Fprintln(b, scanner.Text()); err != nil {
				return nil, err
			}
		}
	} else {
		return nil, errors.New("error parsing opened at timestamp")
	}

	// Scan and copy lines into the fixed buffer
	for scanner.Scan() {
		if scanner.Err() != nil {
			return nil, scanner.Err()
		}

		if _, err := fmt.Fprintln(b, scanner.Text()); err != nil {
			return nil, err
		}
	}

	// Append the closed at timestamp to the end of the buffer
	closedAt := openedAt.Add(time.Minute * 2)
	if _, err := fmt.Fprintf(b, "\n%s\n", closedAt.Format(time.UnixDate)); err != nil {
		return nil, err
	}

	return b.Bytes(), nil
}

/*
	Fix a commit message with the format

		#~ Commit Msg
		# Additional Msg

	By turning it into this

		# Commit Msg | Additional Msg

*/
type FixSplitCommitMessage struct{}

func (FixSplitCommitMessage) CanFix(r io.Reader) (bool, error) {
	return hasSplitCommitMsg(r), nil
}

func hasSplitCommitMsg(r io.Reader) bool {
	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		if strings.HasPrefix(scanner.Text(), "#~ ") {
			if scanner.Scan() {
				if strings.HasPrefix(scanner.Text(), "# ") {
					return true
				}
			}
		}
	}
	return false
}

func (FixSplitCommitMessage) Execute(r io.Reader) ([]byte, error) {
	// For storing the fixed output
	b := bytes.NewBuffer(make([]byte, 0, 1024))

	scanner := bufio.NewScanner(r)

	for scanner.Scan() {
		line := scanner.Text()

		if strings.HasPrefix(line, "#~ ") {
			// We've found line 1 of the split commit message
			part1 := strings.TrimPrefix(line, "#~ ")

			if scanner.Scan() {
				// Trim line 2 of the message and put part1 and part2 together
				part2 := strings.TrimPrefix(scanner.Text(), "# ")

				if _, err := fmt.Fprintf(b, "# %s | %s\n", part1, part2); err != nil {
					return nil, err
				}
			} else {
				// Maybe this should be a panic
				return nil, errors.New("attempt to fix split commit message that doesn't exist")
			}
			break
		}

		if _, err := fmt.Fprintln(b, line); err != nil {
			return nil, err
		}
	}

	// Copy the remaining bytes into the buffer
	for scanner.Scan() {
		if _, err := fmt.Fprintln(b, scanner.Text()); err != nil {
			return nil, err
		}
	}

	return b.Bytes(), nil
}

/*
	Fix a commit message line with the #~ format

		#~ Commit Msg

	to

		# Commit Msg

*/
type FixCommitMessagePrefixWithTilde struct{}

func (FixCommitMessagePrefixWithTilde) CanFix(r io.Reader) (bool, error) {
	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		if strings.HasPrefix(scanner.Text(), "#~ ") {
			if scanner.Scan() {
				// Make sure this isn't a split commit message
				if !strings.HasPrefix(scanner.Text(), "# ") {
					return true, nil
				}
			}
		}
	}
	return false, nil
}

func (FixCommitMessagePrefixWithTilde) Execute(r io.Reader) ([]byte, error) {
	// For storing the fixed output
	b := bytes.NewBuffer(make([]byte, 0, 1024))

	scanner := bufio.NewScanner(r)
	for scanner.Scan() {
		line := scanner.Text()

		if strings.HasPrefix(line, "#~ ") {
			// Trim out the ~ character and place in the buffer
			if _, err := fmt.Fprintln(b, strings.Replace(line, "#~", "#", 1)); err != nil {
				return nil, err
			}
			break
		}

		if _, err := fmt.Fprintln(b, line); err != nil {
			return nil, err
		}
	}

	// Copy the remaining bytes into the buffer
	for scanner.Scan() {
		if _, err := fmt.Fprintln(b, scanner.Text()); err != nil {
			return nil, err
		}
	}

	return b.Bytes(), nil
}
<|endoftext|>


<commit_before>package pusher

import (
	"encoding/json"
)

// Channel represents the information about a channel from the Pusher API.
type Channel struct {
	Name              string
	Occupied          bool `json:"occupied,omitempty"`
	UserCount         int  `json:"user_count,omitempty"`
	SubscriptionCount int  `json:"subscription_count,omitempty"`
}

// ChannelsList represents a list of channels received by the Pusher API.
type ChannelsList struct {
	Channels map[string]ChannelListItem `json:"channels"`
}

// ChannelListItem represents an item within ChannelsList
type ChannelListItem struct {
	UserCount int `json:"user_count"`
}

type TriggerChannelsList struct {
	Channels map[string]TriggerChannelListItem `json:"channels"`
}

type TriggerChannelListItem struct {
	UserCount         *int `json:"user_count,omitempty"`
	SubscriptionCount *int `json:"subscription_count,omitempty"`
}

// Users represents a list of users in a presence-channel
type Users struct {
	List []User `json:"users"`
}

// User represents a user and contains their ID.
type User struct {
	ID string `json:"id"`
}

/*
MemberData represents what to assign to a channel member, consisting of a
`UserID` and any custom `UserInfo`.
*/
type MemberData struct {
	UserID   string            `json:"user_id"`
	UserInfo map[string]string `json:"user_info,omitempty"`
}

func unmarshalledTriggerChannelsList(response []byte) (*TriggerChannelsList, error) {
	channels := &TriggerChannelsList{}
	err := json.Unmarshal(response, &channels)

	if err != nil {
		return nil, err
	}

	return channels, nil
}

func unmarshalledChannelsList(response []byte) (*ChannelsList, error) {
	channels := &ChannelsList{}
	err := json.Unmarshal(response, &channels)

	if err != nil {
		return nil, err
	}

	return channels, nil
}

func unmarshalledChannel(response []byte, name string) (*Channel, error) {
	channel := &Channel{Name: name}
	err := json.Unmarshal(response, &channel)

	if err != nil {
		return nil, err
	}

	return channel, nil
}

func unmarshalledChannelUsers(response []byte) (*Users, error) {
	users := &Users{}
	err := json.Unmarshal(response, &users)

	if err != nil {
		return nil, err
	}

	return users, nil
}
<commit_msg>Avoid two levels of pointer indirection when parsing responses<commit_after>package pusher

import (
	"encoding/json"
)

// Channel represents the information about a channel from the Pusher API.
type Channel struct {
	Name              string
	Occupied          bool `json:"occupied,omitempty"`
	UserCount         int  `json:"user_count,omitempty"`
	SubscriptionCount int  `json:"subscription_count,omitempty"`
}

// ChannelsList represents a list of channels received by the Pusher API.
type ChannelsList struct {
	Channels map[string]ChannelListItem `json:"channels"`
}

// ChannelListItem represents an item within ChannelsList
type ChannelListItem struct {
	UserCount int `json:"user_count"`
}

type TriggerChannelsList struct {
	Channels map[string]TriggerChannelListItem `json:"channels"`
}

type TriggerChannelListItem struct {
	UserCount         *int `json:"user_count,omitempty"`
	SubscriptionCount *int `json:"subscription_count,omitempty"`
}

// Users represents a list of users in a presence-channel
type Users struct {
	List []User `json:"users"`
}

// User represents a user and contains their ID.
type User struct {
	ID string `json:"id"`
}

/*
MemberData represents what to assign to a channel member, consisting of a
`UserID` and any custom `UserInfo`.
*/
type MemberData struct {
	UserID   string            `json:"user_id"`
	UserInfo map[string]string `json:"user_info,omitempty"`
}

func unmarshalledTriggerChannelsList(response []byte) (*TriggerChannelsList, error) {
	channels := &TriggerChannelsList{}
	err := json.Unmarshal(response, channels)

	if err != nil {
		return nil, err
	}

	return channels, nil
}

func unmarshalledChannelsList(response []byte) (*ChannelsList, error) {
	channels := &ChannelsList{}
	err := json.Unmarshal(response, channels)

	if err != nil {
		return nil, err
	}

	return channels, nil
}

func unmarshalledChannel(response []byte, name string) (*Channel, error) {
	channel := &Channel{Name: name}
	err := json.Unmarshal(response, channel)

	if err != nil {
		return nil, err
	}

	return channel, nil
}

func unmarshalledChannelUsers(response []byte) (*Users, error) {
	users := &Users{}
	err := json.Unmarshal(response, users)

	if err != nil {
		return nil, err
	}

	return users, nil
}
<|endoftext|>


<commit_before>package server

import (
	"fmt"
	"io"
	"net/http"
	"sync"
)

var (
	srv *http.Server
	wg  sync.WaitGroup
)

// Address returns the http://$server:$port/ representation for clients to load
func Address() string {
	if srv == nil {
		return ""
	}
	return fmt.Sprintf("http://%s/", srv.Addr)
}

// TODO(adam): Make Register, Start, and Stop private? (defer to Launch()) ??

func Register() {
	if srv != nil {
		return // already initialized
	}

	srv = &http.Server{
		// TODO(adam): Can we pick a random port?
		Addr: "127.0.0.1:8888",
	}

	// http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	// 	io.WriteString(w, "hello world\n")
	// })
	http.HandleFunc("/done", func(w http.ResponseWriter, r *http.Request) {
		io.WriteString(w, "finished\n")
		wg.Done()
	})
}

// Start initializes the http server, binds and accepts connections
func Start() {
	if srv == nil {
		// TODO(adam): should we log here?
		return
	}

	wg.Add(1) // force callers to wait

	// spawn off http server
	go func() {
		if err := srv.ListenAndServe(); err != nil {
			fmt.Printf("ERROR: failed creating localhost server err=%s\n", err)
		}
	}()
}

// Stop calls for a shutdown of the http server, if it exists
func Stop() error {
	// hold on until the form has been filled out
	wg.Wait()

	if srv != nil {
		return srv.Shutdown(nil)
	}
	return nil
}
<commit_msg>ui/server: remove outdated todo<commit_after>package server

import (
	"fmt"
	"io"
	"net/http"
	"sync"
)

var (
	srv *http.Server
	wg  sync.WaitGroup
)

// Address returns the http://$server:$port/ representation for clients to load
func Address() string {
	if srv == nil {
		return ""
	}
	return fmt.Sprintf("http://%s/", srv.Addr)
}

func Register() {
	if srv != nil {
		return // already initialized
	}

	srv = &http.Server{
		// TODO(adam): Can we pick a random port?
		Addr: "127.0.0.1:8888",
	}

	// http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	// 	io.WriteString(w, "hello world\n")
	// })
	http.HandleFunc("/done", func(w http.ResponseWriter, r *http.Request) {
		io.WriteString(w, "finished\n")
		wg.Done()
	})
}

// Start initializes the http server, binds and accepts connections
func Start() {
	if srv == nil {
		// TODO(adam): should we log here?
		return
	}

	wg.Add(1) // force callers to wait

	// spawn off http server
	go func() {
		if err := srv.ListenAndServe(); err != nil {
			fmt.Printf("ERROR: failed creating localhost server err=%s\n", err)
		}
	}()
}

// Stop calls for a shutdown of the http server, if it exists
func Stop() error {
	// hold on until the form has been filled out
	wg.Wait()

	if srv != nil {
		return srv.Shutdown(nil)
	}
	return nil
}
<|endoftext|>


<commit_before>package sslcert

import (
	"fmt"

	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/service/iam"
)

type IAMManager struct {
	iam  *iam.IAM
	path string
}

func NewIAMManager(config *aws.Config, path string) *IAMManager {
	return &IAMManager{
		iam:  iam.New(config),
		path: path,
	}
}

func (m *IAMManager) Add(name string, cert string, key string) (string, error) {
	primary, chain := SplitCertChain(cert)
	input := &iam.UploadServerCertificateInput{
		CertificateBody:       aws.String(primary),
		PrivateKey:            aws.String(key),
		ServerCertificateName: certName(name),
		Path: aws.String(m.path),
	}

	if len(chain) > 0 {
		input.CertificateChain = aws.String(chain)
	}

	output, err := m.iam.UploadServerCertificate(input)
	if err != nil {
		return "", err
	}

	return *output.ServerCertificateMetadata.ServerCertificateID, nil
}

func (m *IAMManager) Remove(name string) error {
	_, err := m.iam.DeleteServerCertificate(&iam.DeleteServerCertificateInput{ServerCertificateName: certName(name)})
	return err
}

func (m *IAMManager) MetaData(name string) (map[string]string, error) {
	data := map[string]string{}
	out, err := m.iam.GetServerCertificate(&iam.GetServerCertificateInput{ServerCertificateName: certName(name)})
	if err != nil {
		return data, err
	}

	if out.ServerCertificate.ServerCertificateMetadata.ARN != nil {
		data["ARN"] = *out.ServerCertificate.ServerCertificateMetadata.ARN
	}

	return data, nil
}

func certName(name string) *string {
	return aws.String(fmt.Sprintf("%sCert", name))
}
<commit_msg>No errors if unable to remove a cert that does not exist<commit_after>package sslcert

import (
	"fmt"

	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/service/iam"
)

type IAMManager struct {
	iam  *iam.IAM
	path string
}

func NewIAMManager(config *aws.Config, path string) *IAMManager {
	return &IAMManager{
		iam:  iam.New(config),
		path: path,
	}
}

func (m *IAMManager) Add(name string, cert string, key string) (string, error) {
	primary, chain := SplitCertChain(cert)
	input := &iam.UploadServerCertificateInput{
		CertificateBody:       aws.String(primary),
		PrivateKey:            aws.String(key),
		ServerCertificateName: certName(name),
		Path: aws.String(m.path),
	}

	if len(chain) > 0 {
		input.CertificateChain = aws.String(chain)
	}

	output, err := m.iam.UploadServerCertificate(input)
	if err != nil {
		return "", err
	}

	return *output.ServerCertificateMetadata.ServerCertificateID, nil
}

func (m *IAMManager) Remove(name string) error {
	_, err := m.iam.DeleteServerCertificate(&iam.DeleteServerCertificateInput{ServerCertificateName: certName(name)})
	if noCertificate(err) {
		return nil
	}
	return err
}

func (m *IAMManager) MetaData(name string) (map[string]string, error) {
	data := map[string]string{}
	out, err := m.iam.GetServerCertificate(&iam.GetServerCertificateInput{ServerCertificateName: certName(name)})
	if err != nil {
		return data, err
	}

	if out.ServerCertificate.ServerCertificateMetadata.ARN != nil {
		data["ARN"] = *out.ServerCertificate.ServerCertificateMetadata.ARN
	}

	return data, nil
}

func certName(name string) *string {
	return aws.String(fmt.Sprintf("%sCert", name))
}

func noCertificate(err error) bool {
	if err, ok := err.(aws.APIError); ok {
		if err.Code == "NoSuchEntity" {
			return true
		}
	}

	return false
}
<|endoftext|>


<commit_before>package ebcdic

import (
	"bytes"
	"fmt"
	"strconv"
	_ "strings"
)

//an ebcdic to unicode mapper
//based on http://www-01.ibm.com/support/docview.wss?uid=swg21145758

//A unicode mapper is also available at http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT

/*
ASCII TO EBCDIC TRANSLATE TABLE

*                 0 1 2 3 4 5 6 7 8 9 A B C D E F
TOEBTABL DC    X'000102030405060708090A0B0C0D0E0F'  00-0F
         DC    X'101112131415161718191A1B1C1D1E1F'  10-1F
         DC    X'405A7F7B5B6C507D4D5D5C4E6B604B61'  20-2F
         DC    X'F0F1F2F3F4F5F6F7F8F97A5E4C7E6E6F'  30-3F
         DC    X'7CC1C2C3C4C5C6C7C8C9D1D2D3D4D5D6'  40-4F
         DC    X'D7D8D9E2E3E4E5E6E7E8E9ADE0BDB06D'  50-5F
         DC    X'79818283848586878889919293949596'  60-6F
         DC    X'979899A2A3A4A5A6A7A8A9C04FD0A17F'  70-7F
         DC    X'808182838485868788898A8B8C8D8E8F'  80-8F
         DC    X'909192939495969798999A9B9C9D9E9F'  90-9F
         DC    X'A0A1A2A3A4A5A6A7A8A9AAABACADAEAF'  A0-AF
         DC    X'B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF'  B0-BF
         DC    X'C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF'  C0-CF
         DC    X'D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF'  D0-DF
         DC    X'E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF'  E0-EF
         DC    X'F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF'  F0-FF

EBCDIC TO ASCII TRANSLATE TABLE

*                 0 1 2 3 4 5 6 7 8 9 A B C D E F
TOASTABL DC    X'000102030405060708090A0B0C0D0E0F'  00-0F
         DC    X'101112131415161718191A1B1C1D1E1F'  10-1F
         DC    X'202122232425262728292A2B2C2D2E2F'  20-2F
         DC    X'303132333435363738393A3B3C3D3E3F'  30-3F
         DC    X'202122232425262728292A2E3C282B6A'  40-4F
         DC    X'2651525354555657585921242A293B7E'  50-5F
         DC    X'2D2F62636465666768696A2C255F3E3F'  60-6F
         DC    X'707172737475767778603A2340273D22'  70-7F
         DC    X'806162636465666768698A8B8C8D8E8F'  80-8F
         DC    X'906A6B6C6D6E6F7071729A9B9C9D9E9F'  90-9F
         DC    X'A0A1737475767778797AAAABACADAEAF'  A0-AF
         DC    X'5EB1B2B3B4B5B6B7B8B9BABBBCBDBEBF'  B0-BF
         DC    X'7B414243444546474849CACBCCCDCECF'  C0-CF
         DC    X'7D4A4B4C4D4E4F505152DADBDCDDDEDF'  D0-DF
         DC    X'5CE1535455565758595AEAEBECEDEEEF'  E0-EF
         DC    X'30313233343536373839FAFBFCFDFEFF'  F0-FF

**/

var ebcdic_to_ascii =
    "000102030405060708090A0B0C0D0E0F" +
	"101112131415161718191A1B1C1D1E1F" +
	"202122232425262728292A2B2C2D2E2F" +
	"303132333435363738393A3B3C3D3E3F" +
	"202122232425262728292A2E3C282B6A" +
	"2651525354555657585921242A293B7E" +
	"2D2F62636465666768696A2C255F3E3F" +
	"707172737475767778603A2340273D22" +
	"806162636465666768698A8B8C8D8E8F" +
	"906A6B6C6D6E6F7071729A9B9C9D9E9F" +
	"A0A1737475767778797AAAABACADAEAF" +
	"5EB1B2B3B4B5B6B7B8B9BABBBCBDBEBF" +
	"7B414243444546474849CACBCCCDCECF" +
	"7D4A4B4C4D4E4F505152DADBDCDDDEDF" +
	"5CE1535455565758595AEAEBECEDEEEF" +
	"30313233343536373839FAFBFCFDFEFF"

var ascii_to_ebcdic = "000102030405060708090A0B0C0D0E0F" +
	"101112131415161718191A1B1C1D1E1F" +
	"405A7F7B5B6C507D4D5D5C4E6B604B61" +
	"F0F1F2F3F4F5F6F7F8F97A5E4C7E6E6F" +
	"7CC1C2C3C4C5C6C7C8C9D1D2D3D4D5D6" +
	"D7D8D9E2E3E4E5E6E7E8E9ADE0BDB06D" +
	"79818283848586878889919293949596" +
	"979899A2A3A4A5A6A7A8A9C04FD0A17F" +
	"808182838485868788898A8B8C8D8E8F" +
	"909192939495969798999A9B9C9D9E9F" +
	"A0A1A2A3A4A5A6A7A8A9AAABACADAEAF" +
	"B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF" +
	"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF" +
	"D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF" +
	"E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF" +
	"F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF"

//convert from ebcdic bytes to a ascii string
func EncodeToString(data []byte) string {

	buf := bytes.NewBufferString("")

	for _, b := range data {
		var x uint32 = uint32(b)
		fmt.Println("x",x);
		tmp := ebcdic_to_ascii[(x * 2) : (x*2)+2]
		i, _ := strconv.ParseUint(tmp, 16, 8)
		fmt.Println("i",i);
		buf.WriteString(string(i))

	}

	return buf.String()
}

//convert from a ascii encoded string to ebcdic bytes
func Decode(str string) []byte {

	data := make([]byte, len(str))

	for i := 0; i < len(str); i++ {
		b := uint32(str[i])
		b_val, _ := strconv.ParseUint(ascii_to_ebcdic[b*2:b*2+2], 16, 8)
		data[i] = byte(b_val)
	}

	return data
}
<commit_msg>removed debugs<commit_after>package ebcdic

import (
	"bytes"
	"strconv"
	_ "strings"
)

//an ebcdic to unicode mapper
//based on http://www-01.ibm.com/support/docview.wss?uid=swg21145758

//A unicode mapper is also available at http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT

/*
ASCII TO EBCDIC TRANSLATE TABLE

*                 0 1 2 3 4 5 6 7 8 9 A B C D E F
TOEBTABL DC    X'000102030405060708090A0B0C0D0E0F'  00-0F
         DC    X'101112131415161718191A1B1C1D1E1F'  10-1F
         DC    X'405A7F7B5B6C507D4D5D5C4E6B604B61'  20-2F
         DC    X'F0F1F2F3F4F5F6F7F8F97A5E4C7E6E6F'  30-3F
         DC    X'7CC1C2C3C4C5C6C7C8C9D1D2D3D4D5D6'  40-4F
         DC    X'D7D8D9E2E3E4E5E6E7E8E9ADE0BDB06D'  50-5F
         DC    X'79818283848586878889919293949596'  60-6F
         DC    X'979899A2A3A4A5A6A7A8A9C04FD0A17F'  70-7F
         DC    X'808182838485868788898A8B8C8D8E8F'  80-8F
         DC    X'909192939495969798999A9B9C9D9E9F'  90-9F
         DC    X'A0A1A2A3A4A5A6A7A8A9AAABACADAEAF'  A0-AF
         DC    X'B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF'  B0-BF
         DC    X'C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF'  C0-CF
         DC    X'D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF'  D0-DF
         DC    X'E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF'  E0-EF
         DC    X'F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF'  F0-FF

EBCDIC TO ASCII TRANSLATE TABLE

*                 0 1 2 3 4 5 6 7 8 9 A B C D E F
TOASTABL DC    X'000102030405060708090A0B0C0D0E0F'  00-0F
         DC    X'101112131415161718191A1B1C1D1E1F'  10-1F
         DC    X'202122232425262728292A2B2C2D2E2F'  20-2F
         DC    X'303132333435363738393A3B3C3D3E3F'  30-3F
         DC    X'202122232425262728292A2E3C282B6A'  40-4F
         DC    X'2651525354555657585921242A293B7E'  50-5F
         DC    X'2D2F62636465666768696A2C255F3E3F'  60-6F
         DC    X'707172737475767778603A2340273D22'  70-7F
         DC    X'806162636465666768698A8B8C8D8E8F'  80-8F
         DC    X'906A6B6C6D6E6F7071729A9B9C9D9E9F'  90-9F
         DC    X'A0A1737475767778797AAAABACADAEAF'  A0-AF
         DC    X'5EB1B2B3B4B5B6B7B8B9BABBBCBDBEBF'  B0-BF
         DC    X'7B414243444546474849CACBCCCDCECF'  C0-CF
         DC    X'7D4A4B4C4D4E4F505152DADBDCDDDEDF'  D0-DF
         DC    X'5CE1535455565758595AEAEBECEDEEEF'  E0-EF
         DC    X'30313233343536373839FAFBFCFDFEFF'  F0-FF

**/

var ebcdic_to_ascii = "000102030405060708090A0B0C0D0E0F" +
	"101112131415161718191A1B1C1D1E1F" +
	"202122232425262728292A2B2C2D2E2F" +
	"303132333435363738393A3B3C3D3E3F" +
	"202122232425262728292A2E3C282B6A" +
	"2651525354555657585921242A293B7E" +
	"2D2F62636465666768696A2C255F3E3F" +
	"707172737475767778603A2340273D22" +
	"806162636465666768698A8B8C8D8E8F" +
	"906A6B6C6D6E6F7071729A9B9C9D9E9F" +
	"A0A1737475767778797AAAABACADAEAF" +
	"5EB1B2B3B4B5B6B7B8B9BABBBCBDBEBF" +
	"7B414243444546474849CACBCCCDCECF" +
	"7D4A4B4C4D4E4F505152DADBDCDDDEDF" +
	"5CE1535455565758595AEAEBECEDEEEF" +
	"30313233343536373839FAFBFCFDFEFF"

var ascii_to_ebcdic = "000102030405060708090A0B0C0D0E0F" +
	"101112131415161718191A1B1C1D1E1F" +
	"405A7F7B5B6C507D4D5D5C4E6B604B61" +
	"F0F1F2F3F4F5F6F7F8F97A5E4C7E6E6F" +
	"7CC1C2C3C4C5C6C7C8C9D1D2D3D4D5D6" +
	"D7D8D9E2E3E4E5E6E7E8E9ADE0BDB06D" +
	"79818283848586878889919293949596" +
	"979899A2A3A4A5A6A7A8A9C04FD0A17F" +
	"808182838485868788898A8B8C8D8E8F" +
	"909192939495969798999A9B9C9D9E9F" +
	"A0A1A2A3A4A5A6A7A8A9AAABACADAEAF" +
	"B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF" +
	"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF" +
	"D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF" +
	"E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF" +
	"F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF"

//convert from ebcdic bytes to a ascii string
func EncodeToString(data []byte) string {

	buf := bytes.NewBufferString("")

	for _, b := range data {
		var x uint32 = uint32(b)
		tmp := ebcdic_to_ascii[(x * 2) : (x*2)+2]
		i, _ := strconv.ParseUint(tmp, 16, 8)
		buf.WriteString(string(i))

	}

	return buf.String()
}

//convert from a ascii encoded string to ebcdic bytes
func Decode(str string) []byte {

	data := make([]byte, len(str))

	for i := 0; i < len(str); i++ {
		b := uint32(str[i])
		b_val, _ := strconv.ParseUint(ascii_to_ebcdic[b*2:b*2+2], 16, 8)
		data[i] = byte(b_val)
	}

	return data
}
<|endoftext|>


<commit_before>package dht

import (
	"github.com/anacrolix/stm"
)

// Populates the node table.
func (s *Server) Bootstrap() (_ TraversalStats, err error) {
	t, err := s.newTraversal(s.id)
	if err != nil {
		return
	}
	t.reason = "dht bootstrap find_node"
	t.doneVar = stm.NewVar(false)
	t.stopTraversal = func(*stm.Tx, addrMaybeId) bool {
		return false
	}
	t.query = func(addr Addr) QueryResult {
		return s.FindNode(addr, s.id, QueryRateLimiting{NotFirst: true})
	}
	t.run()
	return t.stats, nil
}
<commit_msg>Add a stop condition for bootstraps<commit_after>package dht

import (
	"github.com/anacrolix/stm"
)

// Populates the node table.
func (s *Server) Bootstrap() (_ TraversalStats, err error) {
	t, err := s.newTraversal(s.id)
	if err != nil {
		return
	}
	t.reason = "dht bootstrap find_node"
	t.doneVar = stm.NewVar(false)
	// Track number of responses, for STM use. (It's available via atomic in TraversalStats but that
	// won't let wake up STM transactions that are observing the value.)
	numResponseStm := stm.NewBuiltinEqVar(0)
	t.stopTraversal = func(tx *stm.Tx, _ addrMaybeId) bool {
		return tx.Get(numResponseStm).(int) >= 100
	}
	t.query = func(addr Addr) QueryResult {
		res := s.FindNode(addr, s.id, QueryRateLimiting{NotFirst: true})
		if res.Err == nil {
			stm.Atomically(stm.VoidOperation(func(tx *stm.Tx) {
				tx.Set(numResponseStm, tx.Get(numResponseStm).(int)+1)
			}))
		}
		return res
	}
	t.run()
	return t.stats, nil
}
<|endoftext|>


<commit_before>package killswitch

import (
	"bytes"
	"errors"
	"fmt"
	"net"
)

// Network struct
type Network struct {
	Interfaces    []net.Interface
	UpInterfaces  map[string][]string
	P2PInterfaces map[string][]string
	PeerIP        string
	PFRules       bytes.Buffer
}

// New returns a Network struct
func New(peerIP string) (*Network, error) {
	var (
		ip  net.IP
		err error
	)
	if peerIP != "" {
		ip = net.ParseIP(peerIP)
	} else {
		if ip, err = UGSX(); err != nil {
			return nil, err
		}
	}
	ifaces, err := net.Interfaces()
	if err != nil {
		return nil, err
	}
	return &Network{
		Interfaces:    ifaces,
		UpInterfaces:  make(map[string][]string),
		P2PInterfaces: make(map[string][]string),
		PeerIP:        ip.String(),
	}, nil
}

// GetActive finds active interfaces
func (n *Network) GetActive() error {
	for _, i := range n.Interfaces {
		if i.Flags&net.FlagUp == 0 {
			continue // interface down
		}
		if i.Flags&net.FlagLoopback != 0 {
			continue // loopback interface
		}
		addrs, err := i.Addrs()
		if err != nil {
			return err
		}
		for _, addr := range addrs {
			var ip net.IP
			switch v := addr.(type) {
			case *net.IPNet:
				ip = v.IP
			case *net.IPAddr:
				ip = v.IP
			}
			if ip == nil || ip.IsLoopback() {
				continue
			}
			ip = ip.To4()
			if ip == nil {
				continue // not an ipv4 address
			}
			if i.Flags&net.FlagPointToPoint != 0 {
				n.P2PInterfaces[i.Name] = []string{i.HardwareAddr.String(), ip.String()}
			} else {
				n.UpInterfaces[i.Name] = []string{i.HardwareAddr.String(), ip.String()}
				fmt.Printf("ip.String() = %+v\n", ip.String())
				fmt.Printf("(%s)\n", ip.DefaultMask())
				mask := ip.DefaultMask()
				prefixSize, _ := mask.Size()
				fmt.Printf("prefixSize = %+v\n", prefixSize)
			}
		}
	}
	if n.UpInterfaces == nil {
		return errors.New("No active connections, verify you are connected to the network")
	}
	return nil
}
<commit_msg>sync Tue Oct  9 19:34:23 CEST 2018<commit_after>package killswitch

import (
	"bytes"
	"errors"
	"fmt"
	"net"
)

// Network struct
type Network struct {
	Interfaces    []net.Interface
	UpInterfaces  map[string][]string
	P2PInterfaces map[string][]string
	PeerIP        string
	PFRules       bytes.Buffer
}

// New returns a Network struct
func New(peerIP string) (*Network, error) {
	var (
		ip  net.IP
		err error
	)
	if peerIP != "" {
		ip = net.ParseIP(peerIP)
	} else {
		if ip, err = UGSX(); err != nil {
			return nil, err
		}
	}
	ifaces, err := net.Interfaces()
	if err != nil {
		return nil, err
	}
	return &Network{
		Interfaces:    ifaces,
		UpInterfaces:  make(map[string][]string),
		P2PInterfaces: make(map[string][]string),
		PeerIP:        ip.String(),
	}, nil
}

// GetActive finds active interfaces
func (n *Network) GetActive() error {
	for _, i := range n.Interfaces {
		if i.Flags&net.FlagUp == 0 {
			continue // interface down
		}
		if i.Flags&net.FlagLoopback != 0 {
			continue // loopback interface
		}
		addrs, err := i.Addrs()
		if err != nil {
			return err
		}
		for _, addr := range addrs {
			var ip net.IP
			switch v := addr.(type) {
			case *net.IPNet:
				ip = v.IP
			case *net.IPAddr:
				ip = v.IP
			}
			if ip == nil || ip.IsLoopback() {
				continue
			}
			ip = ip.To4()
			if ip == nil {
				continue // not an ipv4 address
			}
			if i.Flags&net.FlagPointToPoint != 0 {
				n.P2PInterfaces[i.Name] = []string{i.HardwareAddr.String(), ip.String()}
			} else {
				// get mask
				mask := ip.DefaultMask()
				prefixSize, _ := mask.Size()
				n.UpInterfaces[i.Name] = []string{i.HardwareAddr.String(), fmt.Sprintf("%s/%d", ip.String(), prefixSize)}

			}
		}
	}
	if n.UpInterfaces == nil {
		return errors.New("No active connections, verify you are connected to the network")
	}
	return nil
}
<|endoftext|>


<commit_before>package jsoniter

import (
	"fmt"
	"io"
	"testing"

	"github.com/json-iterator/go/require"
)

var intConvertMap = map[string]int{
	"321.1":      321,
	"-321.1":     -321,
	`"1.1"`:      1,
	`"-1.1"`:     -1,
	"0.0":        0,
	"0":          0,
	`"0"`:        0,
	`"0.0"`:      0,
	"-1.1":       -1,
	"true":       1,
	"false":      0,
	`"true"`:     0,
	`"false"`:    0,
	`"true123"`:  0,
	`"123true"`:  123,
	`"1.2332e6"`: 1,
	`""`:         0,
}

func Test_read_any_to_int(t *testing.T) {
	should := require.New(t)

	// int
	for k, v := range intConvertMap {
		any := Get([]byte(k))
		should.Equal(v, any.ToInt(), fmt.Sprintf("origin val %v", k))
	}

	// int32
	for k, v := range intConvertMap {
		any := Get([]byte(k))
		should.Equal(int32(v), any.ToInt32(), fmt.Sprintf("original val is %v", k))
	}

	// int64
	for k, v := range intConvertMap {
		any := Get([]byte(k))
		should.Equal(int64(v), any.ToInt64(), fmt.Sprintf("original val is %v", k))
	}

}

var uintConvertMap = map[string]int{
	"321.1":      321,
	`"1.1"`:      1,
	`"-1.1"`:     1,
	"0.0":        0,
	"0":          0,
	`"0"`:        0,
	`"0.0"`:      0,
	"true":       1,
	"false":      0,
	`"true"`:     0,
	`"false"`:    0,
	`"true123"`:  0,
	`"123true"`:  123,
	`"1.2332e6"`: 1,
	`""`:         0,
	// TODO need to solve
	//"-1.1":       1,
	//"-321.1": 321,
}

func Test_read_any_to_uint(t *testing.T) {
	should := require.New(t)

	for k, v := range uintConvertMap {
		any := Get([]byte(k))
		should.Equal(uint64(v), any.ToUint64(), fmt.Sprintf("origin val %v", k))
	}

	for k, v := range uintConvertMap {
		any := Get([]byte(k))
		should.Equal(uint32(v), any.ToUint32(), fmt.Sprintf("origin val %v", k))
	}

	for k, v := range uintConvertMap {
		any := Get([]byte(k))
		should.Equal(uint32(v), any.ToUint32(), fmt.Sprintf("origin val %v", k))
	}

}

func Test_read_int64_as_any(t *testing.T) {
	should := require.New(t)
	any := Get([]byte("1234"))
	should.Equal(1234, any.ToInt())
	should.Equal(io.EOF, any.LastError())
	should.Equal("1234", any.ToString())
	should.True(any.ToBool())
}

func Test_int_lazy_any_get(t *testing.T) {
	should := require.New(t)
	any := Get([]byte("1234"))
	should.Equal(Invalid, any.Get(1, "2").ValueType())
}
<commit_msg>add array to int<commit_after>package jsoniter

import (
	"fmt"
	"io"
	"testing"

	"github.com/json-iterator/go/require"
)

var intConvertMap = map[string]int{
	"321.1":      321,
	"-321.1":     -321,
	`"1.1"`:      1,
	`"-1.1"`:     -1,
	"0.0":        0,
	"0":          0,
	`"0"`:        0,
	`"0.0"`:      0,
	"-1.1":       -1,
	"true":       1,
	"false":      0,
	`"true"`:     0,
	`"false"`:    0,
	`"true123"`:  0,
	`"123true"`:  123,
	`"1.2332e6"`: 1,
	`""`:         0,
	"+":          0,
	"-":          0,
	"[]":         0,
	"[1,2]":      1,
}

func Test_read_any_to_int(t *testing.T) {
	should := require.New(t)

	// int
	for k, v := range intConvertMap {
		any := Get([]byte(k))
		should.Equal(v, any.ToInt(), fmt.Sprintf("origin val %v", k))
	}

	// int32
	for k, v := range intConvertMap {
		any := Get([]byte(k))
		should.Equal(int32(v), any.ToInt32(), fmt.Sprintf("original val is %v", k))
	}

	// int64
	for k, v := range intConvertMap {
		any := Get([]byte(k))
		should.Equal(int64(v), any.ToInt64(), fmt.Sprintf("original val is %v", k))
	}

}

var uintConvertMap = map[string]int{
	"321.1":      321,
	`"1.1"`:      1,
	`"-1.1"`:     1,
	"0.0":        0,
	"0":          0,
	`"0"`:        0,
	`"0.0"`:      0,
	"true":       1,
	"false":      0,
	`"true"`:     0,
	`"false"`:    0,
	`"true123"`:  0,
	`"123true"`:  123,
	`"1.2332e6"`: 1,
	`""`:         0,
	"+":          0,
	"-":          0,
	"[]":         0,
	"[1,2]":      1,
	// TODO need to solve
	//"-1.1":       1,
	//"-321.1": 321,
}

func Test_read_any_to_uint(t *testing.T) {
	should := require.New(t)

	for k, v := range uintConvertMap {
		any := Get([]byte(k))
		should.Equal(uint64(v), any.ToUint64(), fmt.Sprintf("origin val %v", k))
	}

	for k, v := range uintConvertMap {
		any := Get([]byte(k))
		should.Equal(uint32(v), any.ToUint32(), fmt.Sprintf("origin val %v", k))
	}

	for k, v := range uintConvertMap {
		any := Get([]byte(k))
		should.Equal(uint32(v), any.ToUint32(), fmt.Sprintf("origin val %v", k))
	}

}

func Test_read_int64_as_any(t *testing.T) {
	should := require.New(t)
	any := Get([]byte("1234"))
	should.Equal(1234, any.ToInt())
	should.Equal(io.EOF, any.LastError())
	should.Equal("1234", any.ToString())
	should.True(any.ToBool())
}

func Test_int_lazy_any_get(t *testing.T) {
	should := require.New(t)
	any := Get([]byte("1234"))
	should.Equal(Invalid, any.Get(1, "2").ValueType())
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"strings"
	"time"

	"gopkg.in/yaml.v2"
	"k8s.io/apimachinery/pkg/api/errors"
	apiv1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/pkg/api/v1"
	v1batch "k8s.io/client-go/pkg/apis/batch/v1"
	"k8s.io/client-go/pkg/apis/extensions/v1beta1"
	"k8s.io/client-go/tools/clientcmd"
)

func loadKubernetesClient(config *appConfig) (*kubernetes.Clientset, error) {
	clientConfigLoader := &clientcmd.ClientConfigLoadingRules{
		ExplicitPath: config.configFile,
	}
	configOverrides := &clientcmd.ConfigOverrides{}
	if config.context != "" {
		configOverrides.CurrentContext = config.context
	}
	kubeConfig, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(clientConfigLoader, configOverrides).ClientConfig()
	if err != nil {
		return nil, err
	}
	return kubernetes.NewForConfig(kubeConfig)
}

type KubernetesResource struct {
	Kind     string `yaml:"kind"`
	Metadata struct {
		Name      string `yaml:"name"`
		Namespace string `yaml:"namespace"`
	} `yaml:"metadata"`
}

func loadKubernetesResource(data []byte) (*KubernetesResource, error) {
	r := &KubernetesResource{}
	err := yaml.Unmarshal(data, r)
	if err != nil {
		return nil, err
	}
	return r, nil
}

func createNamespace(kubeClient *kubernetes.Clientset, namespace string) error {
	_, err := kubeClient.Core().Namespaces().Get(namespace, apiv1.GetOptions{})
	if err == nil {
		return nil
	}
	if !isResourceNotExist(err) {
		return err
	}
	ns := &v1.Namespace{
		ObjectMeta: apiv1.ObjectMeta{
			Name: namespace,
		},
	}
	_, err = kubeClient.Core().Namespaces().Create(ns)
	return err
}

func deleteNamespace(kubeClient *kubernetes.Clientset, namespace string) error {
	if namespace == "default" {
		return nil
	}
	_, err := kubeClient.Core().Namespaces().Get(namespace, apiv1.GetOptions{})
	if err != nil {
		if isResourceNotExist(err) {
			return nil
		}
		return err
	}
	for i := 0; i < 10; i++ {
		err = kubeClient.Core().Namespaces().Delete(namespace, &apiv1.DeleteOptions{})
		if err == nil {
			return nil
		}
		time.Sleep(5 * time.Second)
	}
	if err != nil {
		return err
	}
	return nil
}

func checkResourceExist(kubeClient *kubernetes.Clientset, kind, name, namespace string) (bool, error) {
	var err error
	switch kind {
	case "pod":
		pod, err := kubeClient.Core().Pods(namespace).Get(name, apiv1.GetOptions{})
		if err != nil {
			if isResourceNotExist(err) {
				return false, nil
			}
			return false, err
		}
		switch pod.Status.Phase {
		case v1.PodUnknown:
			return false, fmt.Errorf("unknown pod status")
		case v1.PodSucceeded, v1.PodFailed:
			return false, nil
		default:
			return true, nil
		}
	case "deployment":
		_, err = kubeClient.Extensions().Deployments(namespace).Get(name, apiv1.GetOptions{})
	case "service":
		_, err = kubeClient.Core().Services(namespace).Get(name, apiv1.GetOptions{})
	case "job":
		_, err = kubeClient.Batch().Jobs(namespace).Get(name, apiv1.GetOptions{})
	case "persistentvolumeclaim":
		_, err = kubeClient.Core().PersistentVolumeClaims(namespace).Get(name, apiv1.GetOptions{})
	case "configmap":
		_, err = kubeClient.Core().ConfigMaps(namespace).Get(name, apiv1.GetOptions{})
	case "secret":
		_, err = kubeClient.Core().Secrets(namespace).Get(name, apiv1.GetOptions{})
	case "ingress":
		_, err = kubeClient.Extensions().Ingresses(namespace).Get(name, apiv1.GetOptions{})
	case "endpoints":
		_, err = kubeClient.Core().Endpoints(namespace).Get(name, apiv1.GetOptions{})
	case "daemonset":
		_, err = kubeClient.Extensions().DaemonSets(namespace).Get(name, apiv1.GetOptions{})
	default:
		return false, UnsupportedResource(kind)
	}
	if err == nil {
		return true, nil
	}
	if isResourceNotExist(err) {
		return false, nil
	}
	return false, err
}

func createResource(kubeClient *kubernetes.Clientset, kind, name, namespace string, resourceData interface{}) error {
	var err error
	retry := 0
	for {
		switch kind {
		case "pod":
			// Delete if possible
			deleteOptions := apiv1.NewDeleteOptions(0)
			kubeClient.Core().Pods(namespace).Delete(name, deleteOptions)
			_, err = kubeClient.Core().Pods(namespace).Create(resourceData.(*v1.Pod))
		case "deployment":
			_, err = kubeClient.Extensions().Deployments(namespace).Create(resourceData.(*v1beta1.Deployment))
		case "service":
			_, err = kubeClient.Core().Services(namespace).Create(resourceData.(*v1.Service))
		case "job":
			_, err = kubeClient.Batch().Jobs(namespace).Create(resourceData.(*v1batch.Job))
		case "persistentvolumeclaim":
			_, err = kubeClient.Core().PersistentVolumeClaims(namespace).Create(resourceData.(*v1.PersistentVolumeClaim))
		case "configmap":
			_, err = kubeClient.Core().ConfigMaps(namespace).Create(resourceData.(*v1.ConfigMap))
		case "secret":
			_, err = kubeClient.Core().Secrets(namespace).Create(resourceData.(*v1.Secret))
		case "ingress":
			_, err = kubeClient.Extensions().Ingresses(namespace).Create(resourceData.(*v1beta1.Ingress))
		case "endpoints":
			_, err = kubeClient.Core().Endpoints(namespace).Create(resourceData.(*v1.Endpoints))
		case "daemonset":
			_, err = kubeClient.Extensions().DaemonSets(namespace).Create(resourceData.(*v1beta1.DaemonSet))
		default:
			return UnsupportedResource(kind)
		}
		if err == nil {
			return nil
		}
		statusErr, ok := err.(*errors.StatusError)
		if !ok {
			return err
		}
		message := statusErr.Status().Message
		if strings.Contains(message, "unable to create new content in namespace") && strings.Contains(message, "being terminated") {
			retry++
			if retry > 10 {
				return err
			}
			time.Sleep(5 * time.Second)
			continue
		} else if strings.Contains(message, "namespaces") && strings.Contains(message, "not found") {
			err = createNamespace(kubeClient, namespace)
			if err != nil {
				return err
			}
		} else {
			return err
		}

	}
	return err
}

func destroyResource(kubeClient *kubernetes.Clientset, kind, name, namespace string) error {
	var err error
	deleteOptions := apiv1.NewDeleteOptions(0)
	switch kind {
	case "pod":
		return destroyPod(kubeClient, name, namespace)
	case "deployment":
		return destroyDeployment(kubeClient, name, namespace)
	case "service":
		err = kubeClient.Core().Services(namespace).Delete(name, deleteOptions)
	case "job":
		return destroyJob(kubeClient, name, namespace)
	case "persistentvolumeclaim":
		err = kubeClient.Core().PersistentVolumeClaims(namespace).Delete(name, deleteOptions)
	case "configmap":
		err = kubeClient.Core().ConfigMaps(namespace).Delete(name, deleteOptions)
	case "secret":
		err = kubeClient.Core().Secrets(namespace).Delete(name, deleteOptions)
	case "ingress":
		err = kubeClient.Extensions().Ingresses(namespace).Delete(name, deleteOptions)
	case "endpoints":
		err = kubeClient.Core().Endpoints(namespace).Delete(name, deleteOptions)
	case "daemonset":
		err = kubeClient.Extensions().DaemonSets(namespace).Delete(name, deleteOptions)
	default:
		return UnsupportedResource(kind)
	}
	return err
}

func updateResource(kubeClient *kubernetes.Clientset, kind, name, namespace string, resourceData interface{}) error {
	var err error
	switch kind {
	case "pod":
		_, err = kubeClient.Core().Pods(namespace).Update(resourceData.(*v1.Pod))
	case "deployment":
		_, err = kubeClient.Extensions().Deployments(namespace).Update(resourceData.(*v1beta1.Deployment))
	case "service":
		return nil
	case "job":
		return nil
	case "persistentvolumeclaim":
		return nil
	case "configmap":
		_, err = kubeClient.Core().ConfigMaps(namespace).Update(resourceData.(*v1.ConfigMap))
	case "secret":
		_, err = kubeClient.Core().Secrets(namespace).Update(resourceData.(*v1.Secret))
	case "ingress":
		_, err = kubeClient.Extensions().Ingresses(namespace).Update(resourceData.(*v1beta1.Ingress))
	case "endpoints":
		_, err = kubeClient.Core().Endpoints(namespace).Update(resourceData.(*v1.Endpoints))
	case "daemonset":
		_, err = kubeClient.Extensions().DaemonSets(namespace).Update(resourceData.(*v1beta1.DaemonSet))
	default:
		return UnsupportedResource(kind)
	}
	return err
}

func getResourceImages(kind string, resourceData interface{}) ([]string, error) {
	var containers []v1.Container
	switch kind {
	case "pod":
		containers = resourceData.(*v1.Pod).Spec.Containers
	case "deployment":
		containers = resourceData.(*v1beta1.Deployment).Spec.Template.Spec.Containers
	case "job":
		containers = resourceData.(*v1batch.Job).Spec.Template.Spec.Containers
	case "service", "persistentvolumeclaim", "configmap", "secret", "ingress":
		return nil, nil
	default:
		return nil, UnsupportedResource(kind)
	}
	images := []string{}
	for _, container := range containers {
		images = append(images, container.Image)
	}
	return images, nil
}

func destroyPod(kubeClient *kubernetes.Clientset, name, namespace string) error {
	deleteOptions := apiv1.NewDeleteOptions(0)
	err := kubeClient.Core().Pods(namespace).Delete(name, deleteOptions)
	if err == nil {
		return nil
	}
	statusErr, ok := err.(*errors.StatusError)
	if !ok {
		return err
	}
	if statusErr.Status().Code == 404 {
		return nil
	}
	return err
}

func destroyDeployment(kubeClient *kubernetes.Clientset, name, namespace string) error {
	deleteOptions := apiv1.NewDeleteOptions(0)
	err := kubeClient.Extensions().Deployments(namespace).Delete(name, deleteOptions)
	if err != nil {
		return err
	}
	listOptions := apiv1.ListOptions{
		LabelSelector: "name=" + name,
	}
	err = kubeClient.Extensions().ReplicaSets(namespace).DeleteCollection(deleteOptions, listOptions)
	if err != nil {
		return err
	}
	return kubeClient.Core().Pods(namespace).DeleteCollection(deleteOptions, listOptions)
}

func destroyJob(kubeClient *kubernetes.Clientset, name, namespace string) error {
	deleteOptions := apiv1.NewDeleteOptions(0)
	err := kubeClient.Batch().Jobs(namespace).Delete(name, deleteOptions)
	if err != nil {
		return err
	}
	pods, err := kubeClient.Core().Pods(namespace).List(apiv1.ListOptions{
		LabelSelector: "job-name=" + name,
	})
	if err != nil {
		return err
	}
	for _, pod := range pods.Items {
		err = kubeClient.Core().Pods(namespace).Delete(pod.Name, deleteOptions)
		if err != nil {
			return err
		}
	}
	return nil
}

func getLogFromPod(kubeClient *kubernetes.Clientset, namespace, podName string, follow bool) (io.ReadCloser, error) {
	var stream io.ReadCloser
	var err error
	for {
		stream, err = kubeClient.Core().Pods(namespace).GetLogs(podName, &v1.PodLogOptions{
			Follow: follow,
		}).Stream()
		if err == nil {
			break
		}
		if strings.Contains(err.Error(), "ContainerCreating") {
			time.Sleep(time.Second)
		} else {
			return nil, err
		}
	}
	return stream, nil
}

func getEvents(kubeClient *kubernetes.Clientset, namespace, podName string) ([]v1.Event, error) {
	events, err := kubeClient.Core().Events(namespace).List(apiv1.ListOptions{
		FieldSelector: "involvedObject.name=" + podName,
	})
	if err != nil {
		return nil, err
	}
	return events.Items, err
}

func getLastEvent(kubeClient *kubernetes.Clientset, namespace, podName string) (*v1.Event, error) {
	events, err := getEvents(kubeClient, namespace, podName)
	if err != nil {
		return nil, err
	}
	if len(events) == 0 {
		return nil, fmt.Errorf("no event found")
	}
	return &events[len(events)-1], nil
}

func isResourceNotExist(err error) bool {
	switch err := err.(type) {
	case *errors.StatusError:
		if err.Status().Code == 404 {
			return true
		}
		return false
	default:
		return false
	}
}
<commit_msg>Fix image downloading bailing out when resources contain daemonset/endpoints<commit_after>package main

import (
	"fmt"
	"io"
	"strings"
	"time"

	"gopkg.in/yaml.v2"
	"k8s.io/apimachinery/pkg/api/errors"
	apiv1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/pkg/api/v1"
	v1batch "k8s.io/client-go/pkg/apis/batch/v1"
	"k8s.io/client-go/pkg/apis/extensions/v1beta1"
	"k8s.io/client-go/tools/clientcmd"
)

func loadKubernetesClient(config *appConfig) (*kubernetes.Clientset, error) {
	clientConfigLoader := &clientcmd.ClientConfigLoadingRules{
		ExplicitPath: config.configFile,
	}
	configOverrides := &clientcmd.ConfigOverrides{}
	if config.context != "" {
		configOverrides.CurrentContext = config.context
	}
	kubeConfig, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(clientConfigLoader, configOverrides).ClientConfig()
	if err != nil {
		return nil, err
	}
	return kubernetes.NewForConfig(kubeConfig)
}

type KubernetesResource struct {
	Kind     string `yaml:"kind"`
	Metadata struct {
		Name      string `yaml:"name"`
		Namespace string `yaml:"namespace"`
	} `yaml:"metadata"`
}

func loadKubernetesResource(data []byte) (*KubernetesResource, error) {
	r := &KubernetesResource{}
	err := yaml.Unmarshal(data, r)
	if err != nil {
		return nil, err
	}
	return r, nil
}

func createNamespace(kubeClient *kubernetes.Clientset, namespace string) error {
	_, err := kubeClient.Core().Namespaces().Get(namespace, apiv1.GetOptions{})
	if err == nil {
		return nil
	}
	if !isResourceNotExist(err) {
		return err
	}
	ns := &v1.Namespace{
		ObjectMeta: apiv1.ObjectMeta{
			Name: namespace,
		},
	}
	_, err = kubeClient.Core().Namespaces().Create(ns)
	return err
}

func deleteNamespace(kubeClient *kubernetes.Clientset, namespace string) error {
	if namespace == "default" {
		return nil
	}
	_, err := kubeClient.Core().Namespaces().Get(namespace, apiv1.GetOptions{})
	if err != nil {
		if isResourceNotExist(err) {
			return nil
		}
		return err
	}
	for i := 0; i < 10; i++ {
		err = kubeClient.Core().Namespaces().Delete(namespace, &apiv1.DeleteOptions{})
		if err == nil {
			return nil
		}
		time.Sleep(5 * time.Second)
	}
	if err != nil {
		return err
	}
	return nil
}

func checkResourceExist(kubeClient *kubernetes.Clientset, kind, name, namespace string) (bool, error) {
	var err error
	switch kind {
	case "pod":
		pod, err := kubeClient.Core().Pods(namespace).Get(name, apiv1.GetOptions{})
		if err != nil {
			if isResourceNotExist(err) {
				return false, nil
			}
			return false, err
		}
		switch pod.Status.Phase {
		case v1.PodUnknown:
			return false, fmt.Errorf("unknown pod status")
		case v1.PodSucceeded, v1.PodFailed:
			return false, nil
		default:
			return true, nil
		}
	case "deployment":
		_, err = kubeClient.Extensions().Deployments(namespace).Get(name, apiv1.GetOptions{})
	case "service":
		_, err = kubeClient.Core().Services(namespace).Get(name, apiv1.GetOptions{})
	case "job":
		_, err = kubeClient.Batch().Jobs(namespace).Get(name, apiv1.GetOptions{})
	case "persistentvolumeclaim":
		_, err = kubeClient.Core().PersistentVolumeClaims(namespace).Get(name, apiv1.GetOptions{})
	case "configmap":
		_, err = kubeClient.Core().ConfigMaps(namespace).Get(name, apiv1.GetOptions{})
	case "secret":
		_, err = kubeClient.Core().Secrets(namespace).Get(name, apiv1.GetOptions{})
	case "ingress":
		_, err = kubeClient.Extensions().Ingresses(namespace).Get(name, apiv1.GetOptions{})
	case "endpoints":
		_, err = kubeClient.Core().Endpoints(namespace).Get(name, apiv1.GetOptions{})
	case "daemonset":
		_, err = kubeClient.Extensions().DaemonSets(namespace).Get(name, apiv1.GetOptions{})
	default:
		return false, UnsupportedResource(kind)
	}
	if err == nil {
		return true, nil
	}
	if isResourceNotExist(err) {
		return false, nil
	}
	return false, err
}

func createResource(kubeClient *kubernetes.Clientset, kind, name, namespace string, resourceData interface{}) error {
	var err error
	retry := 0
	for {
		switch kind {
		case "pod":
			// Delete if possible
			deleteOptions := apiv1.NewDeleteOptions(0)
			kubeClient.Core().Pods(namespace).Delete(name, deleteOptions)
			_, err = kubeClient.Core().Pods(namespace).Create(resourceData.(*v1.Pod))
		case "deployment":
			_, err = kubeClient.Extensions().Deployments(namespace).Create(resourceData.(*v1beta1.Deployment))
		case "service":
			_, err = kubeClient.Core().Services(namespace).Create(resourceData.(*v1.Service))
		case "job":
			_, err = kubeClient.Batch().Jobs(namespace).Create(resourceData.(*v1batch.Job))
		case "persistentvolumeclaim":
			_, err = kubeClient.Core().PersistentVolumeClaims(namespace).Create(resourceData.(*v1.PersistentVolumeClaim))
		case "configmap":
			_, err = kubeClient.Core().ConfigMaps(namespace).Create(resourceData.(*v1.ConfigMap))
		case "secret":
			_, err = kubeClient.Core().Secrets(namespace).Create(resourceData.(*v1.Secret))
		case "ingress":
			_, err = kubeClient.Extensions().Ingresses(namespace).Create(resourceData.(*v1beta1.Ingress))
		case "endpoints":
			_, err = kubeClient.Core().Endpoints(namespace).Create(resourceData.(*v1.Endpoints))
		case "daemonset":
			_, err = kubeClient.Extensions().DaemonSets(namespace).Create(resourceData.(*v1beta1.DaemonSet))
		default:
			return UnsupportedResource(kind)
		}
		if err == nil {
			return nil
		}
		statusErr, ok := err.(*errors.StatusError)
		if !ok {
			return err
		}
		message := statusErr.Status().Message
		if strings.Contains(message, "unable to create new content in namespace") && strings.Contains(message, "being terminated") {
			retry++
			if retry > 10 {
				return err
			}
			time.Sleep(5 * time.Second)
			continue
		} else if strings.Contains(message, "namespaces") && strings.Contains(message, "not found") {
			err = createNamespace(kubeClient, namespace)
			if err != nil {
				return err
			}
		} else {
			return err
		}

	}
	return err
}

func destroyResource(kubeClient *kubernetes.Clientset, kind, name, namespace string) error {
	var err error
	deleteOptions := apiv1.NewDeleteOptions(0)
	switch kind {
	case "pod":
		return destroyPod(kubeClient, name, namespace)
	case "deployment":
		return destroyDeployment(kubeClient, name, namespace)
	case "service":
		err = kubeClient.Core().Services(namespace).Delete(name, deleteOptions)
	case "job":
		return destroyJob(kubeClient, name, namespace)
	case "persistentvolumeclaim":
		err = kubeClient.Core().PersistentVolumeClaims(namespace).Delete(name, deleteOptions)
	case "configmap":
		err = kubeClient.Core().ConfigMaps(namespace).Delete(name, deleteOptions)
	case "secret":
		err = kubeClient.Core().Secrets(namespace).Delete(name, deleteOptions)
	case "ingress":
		err = kubeClient.Extensions().Ingresses(namespace).Delete(name, deleteOptions)
	case "endpoints":
		err = kubeClient.Core().Endpoints(namespace).Delete(name, deleteOptions)
	case "daemonset":
		err = kubeClient.Extensions().DaemonSets(namespace).Delete(name, deleteOptions)
	default:
		return UnsupportedResource(kind)
	}
	return err
}

func updateResource(kubeClient *kubernetes.Clientset, kind, name, namespace string, resourceData interface{}) error {
	var err error
	switch kind {
	case "pod":
		_, err = kubeClient.Core().Pods(namespace).Update(resourceData.(*v1.Pod))
	case "deployment":
		_, err = kubeClient.Extensions().Deployments(namespace).Update(resourceData.(*v1beta1.Deployment))
	case "service":
		return nil
	case "job":
		return nil
	case "persistentvolumeclaim":
		return nil
	case "configmap":
		_, err = kubeClient.Core().ConfigMaps(namespace).Update(resourceData.(*v1.ConfigMap))
	case "secret":
		_, err = kubeClient.Core().Secrets(namespace).Update(resourceData.(*v1.Secret))
	case "ingress":
		_, err = kubeClient.Extensions().Ingresses(namespace).Update(resourceData.(*v1beta1.Ingress))
	case "endpoints":
		_, err = kubeClient.Core().Endpoints(namespace).Update(resourceData.(*v1.Endpoints))
	case "daemonset":
		_, err = kubeClient.Extensions().DaemonSets(namespace).Update(resourceData.(*v1beta1.DaemonSet))
	default:
		return UnsupportedResource(kind)
	}
	return err
}

func getResourceImages(kind string, resourceData interface{}) ([]string, error) {
	var containers []v1.Container
	switch kind {
	case "pod":
		containers = resourceData.(*v1.Pod).Spec.Containers
	case "deployment":
		containers = resourceData.(*v1beta1.Deployment).Spec.Template.Spec.Containers
	case "job":
		containers = resourceData.(*v1batch.Job).Spec.Template.Spec.Containers
	case "daemonset":
		containers = resourceData.(*v1beta1.DaemonSet).Spec.Template.Spec.Containers
	case "service", "persistentvolumeclaim", "configmap", "secret", "ingress", "endpoints":
		return nil, nil
	default:
		return nil, UnsupportedResource(kind)
	}
	images := []string{}
	for _, container := range containers {
		images = append(images, container.Image)
	}
	return images, nil
}

func destroyPod(kubeClient *kubernetes.Clientset, name, namespace string) error {
	deleteOptions := apiv1.NewDeleteOptions(0)
	err := kubeClient.Core().Pods(namespace).Delete(name, deleteOptions)
	if err == nil {
		return nil
	}
	statusErr, ok := err.(*errors.StatusError)
	if !ok {
		return err
	}
	if statusErr.Status().Code == 404 {
		return nil
	}
	return err
}

func destroyDeployment(kubeClient *kubernetes.Clientset, name, namespace string) error {
	deleteOptions := apiv1.NewDeleteOptions(0)
	err := kubeClient.Extensions().Deployments(namespace).Delete(name, deleteOptions)
	if err != nil {
		return err
	}
	listOptions := apiv1.ListOptions{
		LabelSelector: "name=" + name,
	}
	err = kubeClient.Extensions().ReplicaSets(namespace).DeleteCollection(deleteOptions, listOptions)
	if err != nil {
		return err
	}
	return kubeClient.Core().Pods(namespace).DeleteCollection(deleteOptions, listOptions)
}

func destroyJob(kubeClient *kubernetes.Clientset, name, namespace string) error {
	deleteOptions := apiv1.NewDeleteOptions(0)
	err := kubeClient.Batch().Jobs(namespace).Delete(name, deleteOptions)
	if err != nil {
		return err
	}
	pods, err := kubeClient.Core().Pods(namespace).List(apiv1.ListOptions{
		LabelSelector: "job-name=" + name,
	})
	if err != nil {
		return err
	}
	for _, pod := range pods.Items {
		err = kubeClient.Core().Pods(namespace).Delete(pod.Name, deleteOptions)
		if err != nil {
			return err
		}
	}
	return nil
}

func getLogFromPod(kubeClient *kubernetes.Clientset, namespace, podName string, follow bool) (io.ReadCloser, error) {
	var stream io.ReadCloser
	var err error
	for {
		stream, err = kubeClient.Core().Pods(namespace).GetLogs(podName, &v1.PodLogOptions{
			Follow: follow,
		}).Stream()
		if err == nil {
			break
		}
		if strings.Contains(err.Error(), "ContainerCreating") {
			time.Sleep(time.Second)
		} else {
			return nil, err
		}
	}
	return stream, nil
}

func getEvents(kubeClient *kubernetes.Clientset, namespace, podName string) ([]v1.Event, error) {
	events, err := kubeClient.Core().Events(namespace).List(apiv1.ListOptions{
		FieldSelector: "involvedObject.name=" + podName,
	})
	if err != nil {
		return nil, err
	}
	return events.Items, err
}

func getLastEvent(kubeClient *kubernetes.Clientset, namespace, podName string) (*v1.Event, error) {
	events, err := getEvents(kubeClient, namespace, podName)
	if err != nil {
		return nil, err
	}
	if len(events) == 0 {
		return nil, fmt.Errorf("no event found")
	}
	return &events[len(events)-1], nil
}

func isResourceNotExist(err error) bool {
	switch err := err.(type) {
	case *errors.StatusError:
		if err.Status().Code == 404 {
			return true
		}
		return false
	default:
		return false
	}
}
<|endoftext|>


<commit_before>package bot

import (
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/demisto/alfred/domain"
	"github.com/demisto/alfred/queue"
)

// Dedup is responsible for pulling messages from the queue and passing only relevant ones to work
type Dedup struct {
	handledMessages map[string]map[string]*time.Time // message map per team of messages we already handled
	q               queue.Queue
	cleanTime       time.Time
}

// NewDedup with the queue
func NewDedup(q queue.Queue) *Dedup {
	return &Dedup{
		q:               q,
		handledMessages: make(map[string]map[string]*time.Time),
		cleanTime:       time.Now(),
	}
}

// Start the dedup process. To stop, just close the queue.
func (d *Dedup) Start() {
	counter := 0
	for {
		msg, err := d.q.PopMessage(0)
		if err != nil || msg == nil {
			logrus.Info("Stoping DEDUP process - %v, %v", err, msg)
			return
		}
		logrus.Debugf("Deduping message %s\n", msg.MessageID)
		// Check time only every 1000 messages the messages we should clear
		if counter >= 1000 {
			counter = 0
			if time.Now().Sub(d.cleanTime) > 5*time.Minute {
				for _, v := range d.handledMessages {
					for k, t := range v {
						if time.Since(*t) > 5*time.Minute {
							delete(v, k)
						}
					}
				}
			}
		}
		if !d.alreadyHandled(msg) {
			logrus.Debugf("Pushing message %s to work\n", msg.MessageID)
			d.q.PushWork(msg)
		}
		counter++
	}
}

func (d *Dedup) alreadyHandled(data *domain.WorkRequest) bool {
	context, err := GetContext(data.Context)
	if err != nil {
		logrus.Warnf("Unknown context for message %+v\n", data)
		return true
	}
	handled := d.handledMessages[context.Team]
	if handled == nil {
		handled = make(map[string]*time.Time)
		d.handledMessages[context.Team] = handled
	}
	if data.MessageID == "" {
		// Ignore the message
		return true
	}
	if handled[data.MessageID] != nil {
		return true
	}
	now := time.Now()
	handled[data.MessageID] = &now
	return false
}
<commit_msg>Minor fix for dedup log<commit_after>package bot

import (
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/demisto/alfred/domain"
	"github.com/demisto/alfred/queue"
)

// Dedup is responsible for pulling messages from the queue and passing only relevant ones to work
type Dedup struct {
	handledMessages map[string]map[string]*time.Time // message map per team of messages we already handled
	q               queue.Queue
	cleanTime       time.Time
}

// NewDedup with the queue
func NewDedup(q queue.Queue) *Dedup {
	return &Dedup{
		q:               q,
		handledMessages: make(map[string]map[string]*time.Time),
		cleanTime:       time.Now(),
	}
}

// Start the dedup process. To stop, just close the queue.
func (d *Dedup) Start() {
	counter := 0
	for {
		msg, err := d.q.PopMessage(0)
		if err != nil || msg == nil {
			logrus.Infof("Stoping DEDUP process - %v, %v", err, msg)
			return
		}
		logrus.Debugf("Deduping message %s\n", msg.MessageID)
		// Check time only every 1000 messages the messages we should clear
		if counter >= 1000 {
			counter = 0
			if time.Now().Sub(d.cleanTime) > 5*time.Minute {
				for _, v := range d.handledMessages {
					for k, t := range v {
						if time.Since(*t) > 5*time.Minute {
							delete(v, k)
						}
					}
				}
			}
		}
		if !d.alreadyHandled(msg) {
			logrus.Debugf("Pushing message %s to work\n", msg.MessageID)
			d.q.PushWork(msg)
		}
		counter++
	}
}

func (d *Dedup) alreadyHandled(data *domain.WorkRequest) bool {
	context, err := GetContext(data.Context)
	if err != nil {
		logrus.Warnf("Unknown context for message %+v\n", data)
		return true
	}
	handled := d.handledMessages[context.Team]
	if handled == nil {
		handled = make(map[string]*time.Time)
		d.handledMessages[context.Team] = handled
	}
	if data.MessageID == "" {
		// Ignore the message
		return true
	}
	if handled[data.MessageID] != nil {
		return true
	}
	now := time.Now()
	handled[data.MessageID] = &now
	return false
}
<|endoftext|>


<commit_before>package tcpreuse

import (
	"context"
	"net"
	"syscall"

	reuseport "github.com/libp2p/go-reuseport"
)

var fallbackDialer net.Dialer

// reuseErrShouldRetry diagnoses whether to retry after a reuse error.
// if we failed to bind, we should retry. if bind worked and this is a
// real dial error (remote end didnt answer) then we should not retry.
func reuseErrShouldRetry(err error) bool {
	if err == nil {
		return false // hey, it worked! no need to retry.
	}

	// if it's a network timeout error, it's a legitimate failure.
	if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
		return false
	}

	errno, ok := err.(syscall.Errno)
	if !ok { // not an errno? who knows what this is. retry.
		return true
	}

	switch errno {
	case syscall.EADDRINUSE, syscall.EADDRNOTAVAIL:
		return true // failure to bind. retry.
	case syscall.ECONNREFUSED:
		return false // real dial error
	default:
		return true // optimistically default to retry.
	}
}

// Dials using reuseport and then redials normally if that fails.
func reuseDial(ctx context.Context, laddr *net.TCPAddr, network, raddr string) (con net.Conn, err error) {
	if laddr == nil {
		return fallbackDialer.DialContext(ctx, network, raddr)
	}

	d := net.Dialer{
		LocalAddr: laddr,
		Control:   reuseport.Control,
	}

	con, err = d.DialContext(ctx, network, raddr)
	if err == nil {
		return con, nil
	}

	if reuseErrShouldRetry(err) && ctx.Err() == nil {
		// We could have an existing socket open or we could have one
		// stuck in TIME-WAIT.
		log.Debugf("failed to reuse port, dialing with a random port: %s", err)
		con, err = fallbackDialer.DialContext(ctx, network, raddr)
	}
	return con, err
}
<commit_msg>fix: less confusing log message<commit_after>package tcpreuse

import (
	"context"
	"net"
	"syscall"

	reuseport "github.com/libp2p/go-reuseport"
)

var fallbackDialer net.Dialer

// reuseErrShouldRetry diagnoses whether to retry after a reuse error.
// if we failed to bind, we should retry. if bind worked and this is a
// real dial error (remote end didnt answer) then we should not retry.
func reuseErrShouldRetry(err error) bool {
	if err == nil {
		return false // hey, it worked! no need to retry.
	}

	// if it's a network timeout error, it's a legitimate failure.
	if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
		return false
	}

	errno, ok := err.(syscall.Errno)
	if !ok { // not an errno? who knows what this is. retry.
		return true
	}

	switch errno {
	case syscall.EADDRINUSE, syscall.EADDRNOTAVAIL:
		return true // failure to bind. retry.
	case syscall.ECONNREFUSED:
		return false // real dial error
	default:
		return true // optimistically default to retry.
	}
}

// Dials using reuseport and then redials normally if that fails.
func reuseDial(ctx context.Context, laddr *net.TCPAddr, network, raddr string) (con net.Conn, err error) {
	if laddr == nil {
		return fallbackDialer.DialContext(ctx, network, raddr)
	}

	d := net.Dialer{
		LocalAddr: laddr,
		Control:   reuseport.Control,
	}

	con, err = d.DialContext(ctx, network, raddr)
	if err == nil {
		return con, nil
	}

	if reuseErrShouldRetry(err) && ctx.Err() == nil {
		// We could have an existing socket open or we could have one
		// stuck in TIME-WAIT.
		log.Debugf("failed to reuse port, will try again with a random port: %s", err)
		con, err = fallbackDialer.DialContext(ctx, network, raddr)
	}
	return con, err
}
<|endoftext|>


<commit_before>package uncertainty

import (
	"errors"
	"math"

	"github.com/ready-steady/linear/matrix"
	"github.com/ready-steady/probability"
	"github.com/ready-steady/statistics/correlation"
	"github.com/turing-complete/laboratory/src/internal/config"
	"github.com/turing-complete/laboratory/src/internal/distribution"
	"github.com/turing-complete/laboratory/src/internal/system"

	icorrelation "github.com/turing-complete/laboratory/src/internal/correlation"
)

var (
	standardGaussian = probability.NewGaussian(0.0, 1.0)
	nInfinity        = math.Inf(-1.0)
	pInfinity        = math.Inf(1.0)
)

type aleatory struct {
	base

	correlator   []float64
	decorrelator []float64
	marginals    []probability.Distribution

	nz uint
}

func newAleatory(system *system.System, reference []float64,
	config *config.Parameter) (*aleatory, error) {

	base, err := newBase(reference, config)
	if err != nil {
		return nil, err
	}

	if base.nu == 0 {
		return &aleatory{base: base}, nil
	}

	correlator, decorrelator, err := correlate(system, config, base.tasks)
	if err != nil {
		return nil, err
	}

	marginalizer, err := distribution.Parse(config.Distribution)
	if err != nil {
		return nil, err
	}

	marginals := make([]probability.Distribution, base.nu)
	for i, tid := range base.tasks {
		marginals[i] = marginalizer(base.lower[tid], base.upper[tid])
	}

	return &aleatory{
		base: base,

		correlator:   correlator,
		decorrelator: decorrelator,
		marginals:    marginals,

		nz: uint(len(correlator)) / base.nu,
	}, nil
}

func (self *aleatory) Mapping() (uint, uint) {
	return self.nz, self.nt
}

func (self *aleatory) Forward(ω []float64) []float64 {
	nu, nz := self.nu, self.nz

	z := make([]float64, nz)
	if nz == 0 {
		return z
	}

	u := make([]float64, nu)
	n := make([]float64, nz)

	// Dependent desired to dependent uniform
	for i, tid := range self.tasks {
		u[i] = self.marginals[i].Cumulate(ω[tid])
	}

	// Dependent uniform to dependent Gaussian
	for i := range u {
		u[i] = standardGaussian.Decumulate(u[i])
	}

	// Dependent Gaussian to independent Gaussian
	multiply(self.decorrelator, u, n, nz, nu)

	// Independent Gaussian to independent uniform
	for i := range n {
		z[i] = standardGaussian.Cumulate(n[i])
	}

	return z
}

func (self *aleatory) Inverse(z []float64) []float64 {
	nt, nu, nz := self.nt, self.nu, self.nz

	ω := make([]float64, nt)
	copy(ω, self.lower)
	if nu == 0 {
		return ω
	}

	n := make([]float64, nz)
	u := make([]float64, nu)

	// Independent uniform to independent Gaussian
	for i := range n {
		n[i] = standardGaussian.Decumulate(z[i])
	}

	// Independent Gaussian to dependent Gaussian
	multiply(self.correlator, n, u, nu, nz)

	// Dependent Gaussian to dependent uniform
	for i := range u {
		u[i] = standardGaussian.Cumulate(u[i])
	}

	// Dependent uniform to dependent desired
	for i, tid := range self.tasks {
		ω[tid] = self.marginals[i].Decumulate(u[i])
	}

	return ω
}

func correlate(system *system.System, config *config.Parameter,
	tasks []uint) ([]float64, []float64, error) {

	if config.Correlation == 0.0 {
		identity := matrix.Identity(uint(len(tasks)))
		return identity, append(([]float64)(nil), identity...), nil
	}
	if config.Correlation < 0.0 {
		return nil, nil, errors.New("the correlation length should be nonnegative")
	}
	if config.Variance <= 0.0 {
		return nil, nil, errors.New("the variance threshold should be positive")
	}

	C := icorrelation.Compute(system.Application, tasks, config.Correlation)
	correlator, decorrelator, _, err := correlation.Decompose(C, uint(len(tasks)), config.Variance)
	if err != nil {
		return nil, nil, err
	}

	return correlator, decorrelator, nil
}

func multiply(A, x, y []float64, m, n uint) {
	infinite, z := false, make([]float64, n)

	for i := range x {
		switch x[i] {
		case nInfinity:
			infinite, z[i] = true, -1.0
		case pInfinity:
			infinite, z[i] = true, 1.0
		}
	}

	if !infinite {
		matrix.Multiply(A, x, y, m, n, 1)
		return
	}

	for i := uint(0); i < m; i++ {
		Σ1, Σ2 := 0.0, 0.0
		for j := uint(0); j < n; j++ {
			a := A[j*m+i]
			if a == 0.0 {
				continue
			}
			if z[j] == 0.0 {
				Σ1 += a * x[j]
			} else {
				Σ2 += a * z[j]
			}
		}
		if Σ2 < 0.0 {
			y[i] = nInfinity
		} else if Σ2 > 0.0 {
			y[i] = pInfinity
		} else {
			y[i] = Σ1
		}
	}
}
<commit_msg>i/uncertainty: make a cosmetic adjustment<commit_after>package uncertainty

import (
	"errors"
	"math"

	"github.com/ready-steady/linear/matrix"
	"github.com/ready-steady/probability"
	"github.com/ready-steady/statistics/correlation"
	"github.com/turing-complete/laboratory/src/internal/config"
	"github.com/turing-complete/laboratory/src/internal/distribution"
	"github.com/turing-complete/laboratory/src/internal/system"

	icorrelation "github.com/turing-complete/laboratory/src/internal/correlation"
)

var (
	standardGaussian = probability.NewGaussian(0.0, 1.0)
	nInfinity        = math.Inf(-1.0)
	pInfinity        = math.Inf(1.0)
)

type aleatory struct {
	base

	correlator   []float64
	decorrelator []float64
	marginals    []probability.Distribution

	nz uint
}

func newAleatory(system *system.System, reference []float64,
	config *config.Parameter) (*aleatory, error) {

	base, err := newBase(reference, config)
	if err != nil {
		return nil, err
	}

	if base.nu == 0 {
		return &aleatory{base: base}, nil
	}

	correlator, decorrelator, err := correlate(system, config, base.tasks)
	if err != nil {
		return nil, err
	}

	marginalizer, err := distribution.Parse(config.Distribution)
	if err != nil {
		return nil, err
	}

	marginals := make([]probability.Distribution, base.nu)
	for i, tid := range base.tasks {
		marginals[i] = marginalizer(base.lower[tid], base.upper[tid])
	}

	return &aleatory{
		base: base,

		correlator:   correlator,
		decorrelator: decorrelator,
		marginals:    marginals,

		nz: uint(len(correlator)) / base.nu,
	}, nil
}

func (self *aleatory) Mapping() (uint, uint) {
	return self.nz, self.nt
}

func (self *aleatory) Forward(ω []float64) []float64 {
	nu, nz := self.nu, self.nz

	z := make([]float64, nz)
	if nz == 0 {
		return z
	}

	u := make([]float64, nu)
	n := make([]float64, nz)

	// Dependent desired to dependent uniform
	for i, tid := range self.tasks {
		u[i] = self.marginals[i].Cumulate(ω[tid])
	}

	// Dependent uniform to dependent Gaussian
	for i := range u {
		u[i] = standardGaussian.Decumulate(u[i])
	}

	// Dependent Gaussian to independent Gaussian
	multiply(self.decorrelator, u, n, nz, nu)

	// Independent Gaussian to independent uniform
	for i := range n {
		z[i] = standardGaussian.Cumulate(n[i])
	}

	return z
}

func (self *aleatory) Inverse(z []float64) []float64 {
	nu, nz := self.nu, self.nz

	ω := append(([]float64)(nil), self.lower...)
	if nu == 0 {
		return ω
	}

	n := make([]float64, nz)
	u := make([]float64, nu)

	// Independent uniform to independent Gaussian
	for i := range n {
		n[i] = standardGaussian.Decumulate(z[i])
	}

	// Independent Gaussian to dependent Gaussian
	multiply(self.correlator, n, u, nu, nz)

	// Dependent Gaussian to dependent uniform
	for i := range u {
		u[i] = standardGaussian.Cumulate(u[i])
	}

	// Dependent uniform to dependent desired
	for i, tid := range self.tasks {
		ω[tid] = self.marginals[i].Decumulate(u[i])
	}

	return ω
}

func correlate(system *system.System, config *config.Parameter,
	tasks []uint) ([]float64, []float64, error) {

	if config.Correlation == 0.0 {
		identity := matrix.Identity(uint(len(tasks)))
		return identity, append(([]float64)(nil), identity...), nil
	}
	if config.Correlation < 0.0 {
		return nil, nil, errors.New("the correlation length should be nonnegative")
	}
	if config.Variance <= 0.0 {
		return nil, nil, errors.New("the variance threshold should be positive")
	}

	C := icorrelation.Compute(system.Application, tasks, config.Correlation)
	correlator, decorrelator, _, err := correlation.Decompose(C, uint(len(tasks)), config.Variance)
	if err != nil {
		return nil, nil, err
	}

	return correlator, decorrelator, nil
}

func multiply(A, x, y []float64, m, n uint) {
	infinite, z := false, make([]float64, n)

	for i := range x {
		switch x[i] {
		case nInfinity:
			infinite, z[i] = true, -1.0
		case pInfinity:
			infinite, z[i] = true, 1.0
		}
	}

	if !infinite {
		matrix.Multiply(A, x, y, m, n, 1)
		return
	}

	for i := uint(0); i < m; i++ {
		Σ1, Σ2 := 0.0, 0.0
		for j := uint(0); j < n; j++ {
			a := A[j*m+i]
			if a == 0.0 {
				continue
			}
			if z[j] == 0.0 {
				Σ1 += a * x[j]
			} else {
				Σ2 += a * z[j]
			}
		}
		if Σ2 < 0.0 {
			y[i] = nInfinity
		} else if Σ2 > 0.0 {
			y[i] = pInfinity
		} else {
			y[i] = Σ1
		}
	}
}
<|endoftext|>