<commit_before>// Copyright © 2013, S.Çağlar Onur
// Use of this source code is governed by a LGPLv2.1
// license that can be found in the LICENSE file.
//
// Authors:
// S.Çağlar Onur <caglar@10ur.org>

// +build linux

// Package lxc provides Go (golang) Bindings for LXC (Linux Containers) C API.
package lxc

// #cgo pkg-config: lxc
// #include <lxc/lxccontainer.h>
// #include "lxc.h"
import "C"

import (
	"fmt"
	"os"
	"unsafe"
)

func init() {
	if os.Geteuid() != 0 {
		panic("Running as non-root.")
	}
}

// NewContainer returns a new container struct
func NewContainer(name string, lxcpath ...string) (*Container, error) {
	var container *C.struct_lxc_container

	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	if lxcpath != nil && len(lxcpath) == 1 {
		clxcpath := C.CString(lxcpath[0])
		defer C.free(unsafe.Pointer(clxcpath))

		container = C.lxc_container_new(cname, clxcpath)
	} else {
		container = C.lxc_container_new(cname, nil)
	}

	if container == nil {
		return nil, fmt.Errorf(errNewFailed, name)
	}
	return &Container{container: container, verbosity: Quiet}, nil
}

// GetContainer increments reference counter of the container object
func GetContainer(lxc *Container) bool {
	return C.lxc_container_get(lxc.container) == 1
}

// PutContainer decrements reference counter of the container object
func PutContainer(lxc *Container) bool {
	return C.lxc_container_put(lxc.container) == 1
}

// Version returns LXC version
func Version() string {
	return C.GoString(C.lxc_get_version())
}

// DefaultConfigPath returns default config path
func DefaultConfigPath() string {
	return C.GoString(C.lxc_get_default_config_path())
}

// DefaultLvmVg returns default LVM volume group
func DefaultLvmVg() string {
	return C.GoString(C.lxc_get_default_lvm_vg())
}

// DefaultZfsRoot returns default ZFS root
func DefaultZfsRoot() string {
	return C.GoString(C.lxc_get_default_zfs_root())
}

// ContainerNames returns the names of defined and active containers on the system.
func ContainerNames(lxcpath ...string) []string {
	var size int
	var cnames **C.char

	if lxcpath != nil && len(lxcpath) == 1 {
		clxcpath := C.CString(lxcpath[0])
		defer C.free(unsafe.Pointer(clxcpath))

		size = int(C.list_all_containers(clxcpath, &cnames, nil))
	} else {

		size = int(C.list_all_containers(nil, &cnames, nil))
	}

	if size < 1 {
		return nil
	}
	return convertNArgs(cnames, size)
}

// Containers returns the defined and active containers on the system.
func Containers(lxcpath ...string) []Container {
	var containers []Container

	for _, v := range ContainerNames(lxcpath...) {
		container, err := NewContainer(v, lxcpath...)
		if err != nil {
			return nil
		}
		containers = append(containers, *container)
	}
	return containers
}

// DefinedContainerNames returns the names of the defined containers on the system.
func DefinedContainerNames(lxcpath ...string) []string {
	var size int
	var cnames **C.char

	if lxcpath != nil && len(lxcpath) == 1 {
		clxcpath := C.CString(lxcpath[0])
		defer C.free(unsafe.Pointer(clxcpath))

		size = int(C.list_defined_containers(clxcpath, &cnames, nil))
	} else {

		size = int(C.list_defined_containers(nil, &cnames, nil))
	}

	if size < 1 {
		return nil
	}
	return convertNArgs(cnames, size)
}

// DefinedContainers returns the defined containers on the system.
func DefinedContainers(lxcpath ...string) []Container {
	var containers []Container

	for _, v := range DefinedContainerNames(lxcpath...) {
		container, err := NewContainer(v, lxcpath...)
		if err != nil {
			return nil
		}
		containers = append(containers, *container)
	}
	return containers
}

// ActiveContainerNames returns the names of the active containers on the system.
func ActiveContainerNames(lxcpath ...string) []string {
	var size int
	var cnames **C.char

	if lxcpath != nil && len(lxcpath) == 1 {
		clxcpath := C.CString(lxcpath[0])
		defer C.free(unsafe.Pointer(clxcpath))

		size = int(C.list_active_containers(clxcpath, &cnames, nil))
	} else {

		size = int(C.list_active_containers(nil, &cnames, nil))
	}

	if size < 1 {
		return nil
	}
	return convertNArgs(cnames, size)
}

// ActiveContainers returns the active containers on the system.
func ActiveContainers(lxcpath ...string) []Container {
	var containers []Container

	for _, v := range ActiveContainerNames(lxcpath...) {
		container, err := NewContainer(v, lxcpath...)
		if err != nil {
			return nil
		}
		containers = append(containers, *container)
	}
	return containers
}
<commit_msg>LXC C API removed all the helpers and started to use lxc_get_global_config_item, so do the same<commit_after>// Copyright © 2013, S.Çağlar Onur
// Use of this source code is governed by a LGPLv2.1
// license that can be found in the LICENSE file.
//
// Authors:
// S.Çağlar Onur <caglar@10ur.org>

// +build linux

// Package lxc provides Go (golang) Bindings for LXC (Linux Containers) C API.
package lxc

// #cgo pkg-config: lxc
// #include <lxc/lxccontainer.h>
// #include "lxc.h"
import "C"

import (
	"fmt"
	"os"
	"unsafe"
)

func init() {
	if os.Geteuid() != 0 {
		panic("Running as non-root.")
	}
}

// NewContainer returns a new container struct
func NewContainer(name string, lxcpath ...string) (*Container, error) {
	var container *C.struct_lxc_container

	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	if lxcpath != nil && len(lxcpath) == 1 {
		clxcpath := C.CString(lxcpath[0])
		defer C.free(unsafe.Pointer(clxcpath))

		container = C.lxc_container_new(cname, clxcpath)
	} else {
		container = C.lxc_container_new(cname, nil)
	}

	if container == nil {
		return nil, fmt.Errorf(errNewFailed, name)
	}
	return &Container{container: container, verbosity: Quiet}, nil
}

// GetContainer increments reference counter of the container object
func GetContainer(lxc *Container) bool {
	return C.lxc_container_get(lxc.container) == 1
}

// PutContainer decrements reference counter of the container object
func PutContainer(lxc *Container) bool {
	return C.lxc_container_put(lxc.container) == 1
}

// Version returns LXC version
func Version() string {
	return C.GoString(C.lxc_get_version())
}

// GlobalConfigItem returns the value of the given global config key
func GlobalConfigItem(name string) string {
	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	return C.GoString(C.lxc_get_global_config_item(cname))
}

// DefaultConfigPath returns default config path
func DefaultConfigPath() string {
	return GlobalConfigItem("lxc.lxcpath")
}

// DefaultLvmVg returns default LVM volume group
func DefaultLvmVg() string {
	return GlobalConfigItem("lxc.lvm_vg")
}

// DefaultZfsRoot returns default ZFS root
func DefaultZfsRoot() string {
	return GlobalConfigItem("lxc.zfsroot")
}

// ContainerNames returns the names of defined and active containers on the system.
func ContainerNames(lxcpath ...string) []string {
	var size int
	var cnames **C.char

	if lxcpath != nil && len(lxcpath) == 1 {
		clxcpath := C.CString(lxcpath[0])
		defer C.free(unsafe.Pointer(clxcpath))

		size = int(C.list_all_containers(clxcpath, &cnames, nil))
	} else {

		size = int(C.list_all_containers(nil, &cnames, nil))
	}

	if size < 1 {
		return nil
	}
	return convertNArgs(cnames, size)
}

// Containers returns the defined and active containers on the system.
func Containers(lxcpath ...string) []Container {
	var containers []Container

	for _, v := range ContainerNames(lxcpath...) {
		container, err := NewContainer(v, lxcpath...)
		if err != nil {
			return nil
		}
		containers = append(containers, *container)
	}
	return containers
}

// DefinedContainerNames returns the names of the defined containers on the system.
func DefinedContainerNames(lxcpath ...string) []string {
	var size int
	var cnames **C.char

	if lxcpath != nil && len(lxcpath) == 1 {
		clxcpath := C.CString(lxcpath[0])
		defer C.free(unsafe.Pointer(clxcpath))

		size = int(C.list_defined_containers(clxcpath, &cnames, nil))
	} else {

		size = int(C.list_defined_containers(nil, &cnames, nil))
	}

	if size < 1 {
		return nil
	}
	return convertNArgs(cnames, size)
}

// DefinedContainers returns the defined containers on the system.
func DefinedContainers(lxcpath ...string) []Container {
	var containers []Container

	for _, v := range DefinedContainerNames(lxcpath...) {
		container, err := NewContainer(v, lxcpath...)
		if err != nil {
			return nil
		}
		containers = append(containers, *container)
	}
	return containers
}

// ActiveContainerNames returns the names of the active containers on the system.
func ActiveContainerNames(lxcpath ...string) []string {
	var size int
	var cnames **C.char

	if lxcpath != nil && len(lxcpath) == 1 {
		clxcpath := C.CString(lxcpath[0])
		defer C.free(unsafe.Pointer(clxcpath))

		size = int(C.list_active_containers(clxcpath, &cnames, nil))
	} else {

		size = int(C.list_active_containers(nil, &cnames, nil))
	}

	if size < 1 {
		return nil
	}
	return convertNArgs(cnames, size)
}

// ActiveContainers returns the active containers on the system.
func ActiveContainers(lxcpath ...string) []Container {
	var containers []Container

	for _, v := range ActiveContainerNames(lxcpath...) {
		container, err := NewContainer(v, lxcpath...)
		if err != nil {
			return nil
		}
		containers = append(containers, *container)
	}
	return containers
}
<|endoftext|>


<commit_before>package lzw

import "crush"

const (
  _LZW_EOD       = 257;
  _LZW_RESET     = 256;
  _LZW_DICSIZE   = 4096;
  _LZW_STARTBITS = 9;
  _LZW_STARTUTOK = 258;
)

type lzwDecoder struct {
  bits   *crush.BitT;
  bc, cp int;
  early  bool;
}

func (lzw *lzwDecoder) reset() {
  lzw.bc = _LZW_STARTBITS;
  lzw.cp = _LZW_STARTUTOK - 1;
}

func newLzwDecoder(s []byte, early bool) (lzw *lzwDecoder) {
  lzw = new(lzwDecoder);
  lzw.bits = crush.NewBits(s);
  lzw.early = early;
  lzw.reset();
  return;
}

func (lzw *lzwDecoder) update() bool {
  if lzw.cp < _LZW_DICSIZE-1 {
    if lzw.early {
      lzw.cp++
    }
    switch lzw.cp {
    case 512:
      lzw.bc = 10
    case 1024:
      lzw.bc = 11
    case 2048:
      lzw.bc = 12
    }
    if !lzw.early {
      lzw.cp++
    }
    return true;
  }
  return false;
}

func (lzw *lzwDecoder) token() (r int) {
  for {
    r = lzw.bits.Get(lzw.bc);
    if r != _LZW_RESET {
      break
    }
    lzw.reset();
  }
  return r;
}

func DecodeToSlice(s []byte, out []byte, early bool) (r int) {
  lzw := newLzwDecoder(s, early);
  dict := make([][]byte, _LZW_DICSIZE);
  for i := 0; i <= 255; i++ {
    dict[i] = []byte{byte(i)}
  }
  for c := lzw.token(); c != _LZW_EOD; c = lzw.token() {
    k := r;
    for i := 0; i < len(dict[c]); i++ {
      out[r] = dict[c][i];
      r++;
    }
    if lzw.update() {
      dict[lzw.cp] = out[k : r+1]
    }
  }
  return;
}

func CalculateLength(s []byte, early bool) (r int) {
  lzw := newLzwDecoder(s, early);
  dict := make([]int, _LZW_DICSIZE);
  for i := 0; i <= 255; i++ {
    dict[i] = 1
  }
  for c := lzw.token(); c != _LZW_EOD; c = lzw.token() {
    r += dict[c];
    if lzw.update() {
      dict[lzw.cp] = dict[c] + 1
    }
  }
  return;
}

func Decode(s []byte, early bool) []byte {
  r := make([]byte, CalculateLength(s, early)+1);
  return r[0:DecodeToSlice(s, r, early)];
}
<commit_msg>Cleanups.<commit_after>package lzw

// LZW reader for PDF.

import "crush"

const (
  _LZW_EOD       = 257;
  _LZW_RESET     = 256;
  _LZW_DICSIZE   = 4096;
  _LZW_STARTBITS = 9;
  _LZW_STARTUTOK = 258;
)

type lzwDecoder struct {
  bits   *crush.BitT;
  bc, cp int;
  early  bool;
}

func (lzw *lzwDecoder) reset() {
  lzw.bc = _LZW_STARTBITS;
  lzw.cp = _LZW_STARTUTOK - 1;
}

func newLzwDecoder(s []byte, early bool) (lzw *lzwDecoder) {
  lzw = new(lzwDecoder);
  lzw.bits = crush.NewBits(s);
  lzw.early = early;
  lzw.reset();
  return;
}

func (lzw *lzwDecoder) update() bool {
  if lzw.cp < _LZW_DICSIZE-1 {
    if lzw.early {
      lzw.cp++
    }
    switch lzw.cp {
    case 512:
      lzw.bc = 10
    case 1024:
      lzw.bc = 11
    case 2048:
      lzw.bc = 12
    }
    if !lzw.early {
      lzw.cp++
    }
    return true;
  }
  return false;
}

func (lzw *lzwDecoder) token() (r int) {
  for {
    r = lzw.bits.Get(lzw.bc);
    if r != _LZW_RESET {
      break
    }
    lzw.reset();
  }
  return;
}

func DecodeToSlice(s []byte, out []byte, early bool) (r int) {
  lzw := newLzwDecoder(s, early);
  dict := make([][]byte, _LZW_DICSIZE);
  for i := 0; i <= 255; i++ {
    dict[i] = []byte{byte(i)}
  }
  for c := lzw.token(); c != _LZW_EOD; c = lzw.token() {
    k := r;
    for i := 0; i < len(dict[c]); i++ {
      out[r] = dict[c][i];
      r++;
    }
    if lzw.update() {
      dict[lzw.cp] = out[k : r+1]
    }
  }
  return;
}

func CalculateLength(s []byte, early bool) (r int) {
  lzw := newLzwDecoder(s, early);
  dict := make([]int, _LZW_DICSIZE);
  for i := 0; i <= 255; i++ {
    dict[i] = 1
  }
  for c := lzw.token(); c != _LZW_EOD; c = lzw.token() {
    r += dict[c];
    if lzw.update() {
      dict[lzw.cp] = dict[c] + 1
    }
  }
  return;
}

func Decode(s []byte, early bool) []byte {
  r := make([]byte, CalculateLength(s, early)+1);
  return r[0:DecodeToSlice(s, r, early)];
}
<|endoftext|>


<commit_before>package devices

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"syscall"
)

const (
	Wildcard = -1
)

var (
	ErrNotADeviceNode = errors.New("not a device node")
)

// Testing dependencies
var (
	osLstat       = os.Lstat
	ioutilReadDir = ioutil.ReadDir
)

type Device struct {
	Type              rune        `json:"type,omitempty"`
	Path              string      `json:"path,omitempty"`               // It is fine if this is an empty string in the case that you are using Wildcards
	MajorNumber       int64       `json:"major_number,omitempty"`       // Use the wildcard constant for wildcards.
	MinorNumber       int64       `json:"minor_number,omitempty"`       // Use the wildcard constant for wildcards.
	CgroupPermissions string      `json:"cgroup_permissions,omitempty"` // Typically just "rwm"
	FileMode          os.FileMode `json:"file_mode,omitempty"`          // The permission bits of the file's mode
	Uid               uint32      `json:"uid,omitempty"`
	Gid               uint32      `json:"gid,omitempty"`
}

func GetDeviceNumberString(deviceNumber int64) string {
	if deviceNumber == Wildcard {
		return "*"
	} else {
		return fmt.Sprintf("%d", deviceNumber)
	}
}

func (device *Device) GetCgroupAllowString() string {
	return fmt.Sprintf("%c %s:%s %s", device.Type, GetDeviceNumberString(device.MajorNumber), GetDeviceNumberString(device.MinorNumber), device.CgroupPermissions)
}

// Given the path to a device and it's cgroup_permissions(which cannot be easilly queried) look up the information about a linux device and return that information as a Device struct.
func GetDevice(path, cgroupPermissions string) (*Device, error) {
	fileInfo, err := osLstat(path)
	if err != nil {
		return nil, err
	}

	var (
		devType                rune
		mode                   = fileInfo.Mode()
		fileModePermissionBits = os.FileMode.Perm(mode)
	)

	switch {
	case mode&os.ModeDevice == 0:
		return nil, ErrNotADeviceNode
	case mode&os.ModeCharDevice != 0:
		fileModePermissionBits |= syscall.S_IFCHR
		devType = 'c'
	default:
		fileModePermissionBits |= syscall.S_IFBLK
		devType = 'b'
	}

	stat_t, ok := fileInfo.Sys().(*syscall.Stat_t)
	if !ok {
		return nil, fmt.Errorf("cannot determine the device number for device %s", path)
	}
	devNumber := int(stat_t.Rdev)

	return &Device{
		Type:              devType,
		Path:              path,
		MajorNumber:       Major(devNumber),
		MinorNumber:       Minor(devNumber),
		CgroupPermissions: cgroupPermissions,
		FileMode:          fileModePermissionBits,
		Uid:               stat_t.Uid,
		Gid:               stat_t.Gid,
	}, nil
}

func GetHostDeviceNodes() ([]*Device, error) {
	return getDeviceNodes("/dev")
}

func getDeviceNodes(path string) ([]*Device, error) {
	files, err := ioutilReadDir(path)
	if err != nil {
		return nil, err
	}

	out := []*Device{}
	for _, f := range files {
		if f.IsDir() {
			switch f.Name() {
			case "pts", "shm", "fd":
				continue
			default:
				sub, err := getDeviceNodes(filepath.Join(path, f.Name()))
				if err != nil {
					return nil, err
				}

				out = append(out, sub...)
				continue
			}
		}

		switch f.Name() {
		case "console":
			continue
		default:
			device, err := GetDevice(filepath.Join(path, f.Name()), "rwm")
			if err != nil {
				if err == ErrNotADeviceNode {
					continue
				}
				return nil, err
			}
			out = append(out, device)
		}
	}

	return out, nil
}
<commit_msg>modified devices: filter /dev/console out of...<commit_after>package devices

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"syscall"
)

const (
	Wildcard = -1
)

var (
	ErrNotADeviceNode = errors.New("not a device node")
)

// Testing dependencies
var (
	osLstat       = os.Lstat
	ioutilReadDir = ioutil.ReadDir
)

type Device struct {
	Type              rune        `json:"type,omitempty"`
	Path              string      `json:"path,omitempty"`               // It is fine if this is an empty string in the case that you are using Wildcards
	MajorNumber       int64       `json:"major_number,omitempty"`       // Use the wildcard constant for wildcards.
	MinorNumber       int64       `json:"minor_number,omitempty"`       // Use the wildcard constant for wildcards.
	CgroupPermissions string      `json:"cgroup_permissions,omitempty"` // Typically just "rwm"
	FileMode          os.FileMode `json:"file_mode,omitempty"`          // The permission bits of the file's mode
	Uid               uint32      `json:"uid,omitempty"`
	Gid               uint32      `json:"gid,omitempty"`
}

func GetDeviceNumberString(deviceNumber int64) string {
	if deviceNumber == Wildcard {
		return "*"
	} else {
		return fmt.Sprintf("%d", deviceNumber)
	}
}

func (device *Device) GetCgroupAllowString() string {
	return fmt.Sprintf("%c %s:%s %s", device.Type, GetDeviceNumberString(device.MajorNumber), GetDeviceNumberString(device.MinorNumber), device.CgroupPermissions)
}

// Given the path to a device and it's cgroup_permissions(which cannot be easilly queried) look up the information about a linux device and return that information as a Device struct.
func GetDevice(path, cgroupPermissions string) (*Device, error) {
	fileInfo, err := osLstat(path)
	if err != nil {
		return nil, err
	}

	var (
		devType                rune
		mode                   = fileInfo.Mode()
		fileModePermissionBits = os.FileMode.Perm(mode)
	)

	switch {
	case mode&os.ModeDevice == 0:
		return nil, ErrNotADeviceNode
	case mode&os.ModeCharDevice != 0:
		fileModePermissionBits |= syscall.S_IFCHR
		devType = 'c'
	default:
		fileModePermissionBits |= syscall.S_IFBLK
		devType = 'b'
	}

	stat_t, ok := fileInfo.Sys().(*syscall.Stat_t)
	if !ok {
		return nil, fmt.Errorf("cannot determine the device number for device %s", path)
	}
	devNumber := int(stat_t.Rdev)

	return &Device{
		Type:              devType,
		Path:              path,
		MajorNumber:       Major(devNumber),
		MinorNumber:       Minor(devNumber),
		CgroupPermissions: cgroupPermissions,
		FileMode:          fileModePermissionBits,
		Uid:               stat_t.Uid,
		Gid:               stat_t.Gid,
	}, nil
}

func GetHostDeviceNodes() ([]*Device, error) {
	return getDeviceNodes("/dev")
}

func getDeviceNodes(path string) ([]*Device, error) {
	files, err := ioutilReadDir(path)
	if err != nil {
		return nil, err
	}

	out := []*Device{}
	for _, f := range files {
		switch {
		case f.IsDir():
			switch f.Name() {
			case "pts", "shm", "fd":
				continue
			default:
				sub, err := getDeviceNodes(filepath.Join(path, f.Name()))
				if err != nil {
					return nil, err
				}

				out = append(out, sub...)
				continue
			}
		case f.Name() == "console":
			continue
		}

		device, err := GetDevice(filepath.Join(path, f.Name()), "rwm")
		if err != nil {
			if err == ErrNotADeviceNode {
				continue
			}
			return nil, err
		}
		out = append(out, device)
	}

	return out, nil
}
<|endoftext|>


<commit_before>package cli

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"time"

	"github.com/schollz/croc/v6/src/croc"
	"github.com/schollz/croc/v6/src/models"
	"github.com/schollz/croc/v6/src/tcp"
	"github.com/schollz/croc/v6/src/utils"
	log "github.com/schollz/logger"
	"github.com/urfave/cli"
)

var Version string

func Run() (err error) {
	// use all of the processors
	runtime.GOMAXPROCS(runtime.NumCPU())

	app := cli.NewApp()
	app.Name = "croc"
	if Version == "" {
		Version = "v6.0.12-fbbdd1b"
	}
	app.Version = Version
	app.Compiled = time.Now()
	app.Usage = "easily and securely transfer stuff from one computer to another"
	app.UsageText = "croc allows any two computers to directly and securely transfer files"
	// app.ArgsUsage = "[args and such]"
	app.Commands = []cli.Command{
		{
			Name:        "send",
			Usage:       "send a file",
			Description: "send a file over the relay",
			ArgsUsage:   "[filename]",
			Flags: []cli.Flag{
				cli.StringFlag{Name: "code, c", Usage: "codephrase used to connect to relay"},
				cli.BoolFlag{Name: "no-local", Usage: "disable local relay when sending"},
				cli.StringFlag{Name: "ports", Value: "9009,9010,9011,9012,9013", Usage: "ports of the local relay (optional)"},
			},
			HelpName: "croc send",
			Action: func(c *cli.Context) error {
				return send(c)
			},
		},
		{
			Name:        "relay",
			Description: "start relay",
			HelpName:    "croc relay",
			Action: func(c *cli.Context) error {
				return relay(c)
			},
			Flags: []cli.Flag{
				cli.StringFlag{Name: "ports", Value: "9009,9010,9011,9012,9013", Usage: "ports of the relay"},
			},
		},
	}
	app.Flags = []cli.Flag{
		cli.BoolFlag{Name: "remember", Usage: "save these settings to reuse next time"},
		cli.BoolFlag{Name: "debug", Usage: "increase verbosity (a lot)"},
		cli.BoolFlag{Name: "yes", Usage: "automatically agree to all prompts"},
		cli.BoolFlag{Name: "stdout", Usage: "redirect file to stdout"},
		cli.StringFlag{Name: "relay", Value: models.DEFAULT_RELAY, Usage: "address of the relay"},
		cli.StringFlag{Name: "out", Value: ".", Usage: "specify an output folder to receive the file"},
	}
	app.EnableBashCompletion = true
	app.HideHelp = false
	app.HideVersion = false
	app.BashComplete = func(c *cli.Context) {
		fmt.Fprintf(c.App.Writer, "send\nreceive\relay")
	}
	app.Action = func(c *cli.Context) error {
		// if trying to send but forgot send, let the user know
		if c.Args().First() != "" && utils.Exists(c.Args().First()) {
			_, fname := filepath.Split(c.Args().First())
			yn := utils.GetInput(fmt.Sprintf("Did you mean to send '%s'? (y/n) ", fname))
			if strings.ToLower(yn) == "y" {
				return send(c)
			}
		}
		return receive(c)
	}

	return app.Run(os.Args)
}

func getConfigDir() (homedir string, err error) {
	homedir, err = os.UserHomeDir()
	if err != nil {
		log.Error(err)
		return
	}
	homedir = path.Join(homedir, ".config", "croc")
	if _, err := os.Stat(homedir); os.IsNotExist(err) {
		log.Debugf("creating home directory %s", homedir)
		err = os.MkdirAll(homedir, 0700)
	}
	return
}

func send(c *cli.Context) (err error) {
	if c.GlobalBool("debug") {
		log.SetLevel("debug")
		log.Debug("debug mode on")
	}
	configFile, err := getConfigDir()
	if err != nil {
		log.Error(err)
		return
	}
	configFile = path.Join(configFile, "send.json")

	crocOptions := croc.Options{
		SharedSecret: c.String("code"),
		IsSender:     true,
		Debug:        c.GlobalBool("debug"),
		NoPrompt:     c.GlobalBool("yes"),
		RelayAddress: c.GlobalString("relay"),
		Stdout:       c.GlobalBool("stdout"),
		DisableLocal: c.Bool("no-local"),
		RelayPorts:   strings.Split(c.String("ports"), ","),
	}
	b, errOpen := ioutil.ReadFile(configFile)
	if errOpen == nil && !c.GlobalBool("remember") {
		var rememberedOptions croc.Options
		err = json.Unmarshal(b, &rememberedOptions)
		if err != nil {
			log.Error(err)
			return
		}
		// update anything that isn't explicitly set
		if !c.GlobalIsSet("relay") {
			crocOptions.RelayAddress = rememberedOptions.RelayAddress
		}
		if !c.IsSet("no-local") {
			crocOptions.DisableLocal = rememberedOptions.DisableLocal
		}
		if !c.IsSet("ports") {
			crocOptions.RelayPorts = rememberedOptions.RelayPorts
		}
		if !c.IsSet("code") {
			crocOptions.SharedSecret = rememberedOptions.SharedSecret
		}
	}

	var fnames []string
	stat, _ := os.Stdin.Stat()
	if (stat.Mode() & os.ModeCharDevice) == 0 {
		f, err := ioutil.TempFile(".", "croc-stdin-")
		if err != nil {
			return err
		}
		_, err = io.Copy(f, os.Stdin)
		if err != nil {
			return err
		}
		err = f.Close()
		if err != nil {
			return err
		}
		fnames = []string{f.Name()}
		defer func() {
			err = os.Remove(fnames[0])
			if err != nil {
				log.Error(err)
			}
		}()
	} else {
		fnames = append([]string{c.Args().First()}, c.Args().Tail()...)
	}
	if len(fnames) == 0 {
		return errors.New("must specify file: croc send [filename]")
	}

	if len(crocOptions.SharedSecret) == 0 {
		// generate code phrase
		crocOptions.SharedSecret = utils.GetRandomName()
	}

	haveFolder := false
	paths := []string{}
	for _, fname := range fnames {
		stat, err := os.Stat(fname)
		if err != nil {
			return err
		}
		if stat.IsDir() {
			haveFolder = true
			err = filepath.Walk(fname,
				func(pathName string, info os.FileInfo, err error) error {
					if err != nil {
						return err
					}
					if !info.IsDir() {
						paths = append(paths, filepath.ToSlash(pathName))
					}
					return nil
				})
			if err != nil {
				return err
			}
		} else {
			paths = append(paths, filepath.ToSlash(fname))
		}
	}

	cr, err := croc.New(crocOptions)
	if err != nil {
		return
	}

	// save the config
	if c.GlobalBool("remember") {
		log.Debug("saving config file")
		var bConfig []byte
		// if the code wasn't set, don't save it
		if c.String("code") == "" {
			crocOptions.SharedSecret = ""
		}
		bConfig, err = json.MarshalIndent(crocOptions, "", "    ")
		if err != nil {
			log.Error(err)
			return
		}
		err = ioutil.WriteFile(configFile, bConfig, 0644)
		if err != nil {
			log.Error(err)
			return
		}
		log.Debugf("wrote %s", configFile)
	}

	err = cr.Send(croc.TransferOptions{
		PathToFiles:      paths,
		KeepPathInRemote: haveFolder,
	})

	return
}

func receive(c *cli.Context) (err error) {
	crocOptions := croc.Options{
		SharedSecret: c.String("code"),
		IsSender:     false,
		Debug:        c.GlobalBool("debug"),
		NoPrompt:     c.GlobalBool("yes"),
		RelayAddress: c.GlobalString("relay"),
		Stdout:       c.GlobalBool("stdout"),
	}
	if c.Args().First() != "" {
		crocOptions.SharedSecret = c.Args().First()
	}

	// load options here
	if c.GlobalBool("debug") {
		log.SetLevel("debug")
		log.Debug("debug mode on")
	}
	configFile, err := getConfigDir()
	if err != nil {
		log.Error(err)
		return
	}
	configFile = path.Join(configFile, "receive.json")
	b, errOpen := ioutil.ReadFile(configFile)
	if errOpen == nil && !c.GlobalBool("remember") {
		var rememberedOptions croc.Options
		err = json.Unmarshal(b, &rememberedOptions)
		if err != nil {
			log.Error(err)
			return
		}
		// update anything that isn't explicitly set
		if !c.GlobalIsSet("relay") {
			crocOptions.RelayAddress = rememberedOptions.RelayAddress
		}
		if !c.GlobalIsSet("yes") {
			crocOptions.NoPrompt = rememberedOptions.NoPrompt
		}
		if crocOptions.SharedSecret == "" {
			crocOptions.SharedSecret = rememberedOptions.SharedSecret
		}
	}

	if crocOptions.SharedSecret == "" {
		crocOptions.SharedSecret = utils.GetInput("Enter receive code: ")
	}
	if c.GlobalString("out") != "" {
		os.Chdir(c.GlobalString("out"))
	}

	cr, err := croc.New(crocOptions)
	if err != nil {
		return
	}

	// save the config
	if c.GlobalBool("remember") {
		log.Debug("saving config file")
		var bConfig []byte
		bConfig, err = json.MarshalIndent(crocOptions, "", "    ")
		if err != nil {
			log.Error(err)
			return
		}
		err = ioutil.WriteFile(configFile, bConfig, 0644)
		if err != nil {
			log.Error(err)
			return
		}
		log.Debugf("wrote %s", configFile)
	}

	err = cr.Receive()
	return
}

func relay(c *cli.Context) (err error) {
	debugString := "info"
	if c.GlobalBool("debug") {
		debugString = "debug"
	}
	ports := strings.Split(c.String("ports"), ",")
	tcpPorts := strings.Join(ports[1:], ",")
	for i, port := range ports {
		if i == 0 {
			continue
		}
		go func(portStr string) {
			err = tcp.Run(debugString, portStr)
			if err != nil {
				panic(err)
			}
		}(port)
	}
	return tcp.Run(debugString, ports[0], tcpPorts)
}
<commit_msg>don't keep debug<commit_after>package cli

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"time"

	"github.com/schollz/croc/v6/src/croc"
	"github.com/schollz/croc/v6/src/models"
	"github.com/schollz/croc/v6/src/tcp"
	"github.com/schollz/croc/v6/src/utils"
	log "github.com/schollz/logger"
	"github.com/urfave/cli"
)

var Version string

func Run() (err error) {
	// use all of the processors
	runtime.GOMAXPROCS(runtime.NumCPU())

	app := cli.NewApp()
	app.Name = "croc"
	if Version == "" {
		Version = "v6.0.12-fbbdd1b"
	}
	app.Version = Version
	app.Compiled = time.Now()
	app.Usage = "easily and securely transfer stuff from one computer to another"
	app.UsageText = "croc allows any two computers to directly and securely transfer files"
	// app.ArgsUsage = "[args and such]"
	app.Commands = []cli.Command{
		{
			Name:        "send",
			Usage:       "send a file",
			Description: "send a file over the relay",
			ArgsUsage:   "[filename]",
			Flags: []cli.Flag{
				cli.StringFlag{Name: "code, c", Usage: "codephrase used to connect to relay"},
				cli.BoolFlag{Name: "no-local", Usage: "disable local relay when sending"},
				cli.StringFlag{Name: "ports", Value: "9009,9010,9011,9012,9013", Usage: "ports of the local relay (optional)"},
			},
			HelpName: "croc send",
			Action: func(c *cli.Context) error {
				return send(c)
			},
		},
		{
			Name:        "relay",
			Description: "start relay",
			HelpName:    "croc relay",
			Action: func(c *cli.Context) error {
				return relay(c)
			},
			Flags: []cli.Flag{
				cli.StringFlag{Name: "ports", Value: "9009,9010,9011,9012,9013", Usage: "ports of the relay"},
			},
		},
	}
	app.Flags = []cli.Flag{
		cli.BoolFlag{Name: "remember", Usage: "save these settings to reuse next time"},
		cli.BoolFlag{Name: "debug", Usage: "increase verbosity (a lot)"},
		cli.BoolFlag{Name: "yes", Usage: "automatically agree to all prompts"},
		cli.BoolFlag{Name: "stdout", Usage: "redirect file to stdout"},
		cli.StringFlag{Name: "relay", Value: models.DEFAULT_RELAY, Usage: "address of the relay"},
		cli.StringFlag{Name: "out", Value: ".", Usage: "specify an output folder to receive the file"},
	}
	app.EnableBashCompletion = true
	app.HideHelp = false
	app.HideVersion = false
	app.BashComplete = func(c *cli.Context) {
		fmt.Fprintf(c.App.Writer, "send\nreceive\relay")
	}
	app.Action = func(c *cli.Context) error {
		// if trying to send but forgot send, let the user know
		if c.Args().First() != "" && utils.Exists(c.Args().First()) {
			_, fname := filepath.Split(c.Args().First())
			yn := utils.GetInput(fmt.Sprintf("Did you mean to send '%s'? (y/n) ", fname))
			if strings.ToLower(yn) == "y" {
				return send(c)
			}
		}
		return receive(c)
	}

	return app.Run(os.Args)
}

func getConfigDir() (homedir string, err error) {
	homedir, err = os.UserHomeDir()
	if err != nil {
		log.Error(err)
		return
	}
	homedir = path.Join(homedir, ".config", "croc")
	if _, err := os.Stat(homedir); os.IsNotExist(err) {
		log.Debugf("creating home directory %s", homedir)
		err = os.MkdirAll(homedir, 0700)
	}
	return
}

func send(c *cli.Context) (err error) {
	if c.GlobalBool("debug") {
		log.SetLevel("debug")
		log.Debug("debug mode on")
	} else {
		log.SetLevel("info")
	}
	configFile, err := getConfigDir()
	if err != nil {
		log.Error(err)
		return
	}
	configFile = path.Join(configFile, "send.json")

	crocOptions := croc.Options{
		SharedSecret: c.String("code"),
		IsSender:     true,
		Debug:        c.GlobalBool("debug"),
		NoPrompt:     c.GlobalBool("yes"),
		RelayAddress: c.GlobalString("relay"),
		Stdout:       c.GlobalBool("stdout"),
		DisableLocal: c.Bool("no-local"),
		RelayPorts:   strings.Split(c.String("ports"), ","),
	}
	b, errOpen := ioutil.ReadFile(configFile)
	if errOpen == nil && !c.GlobalBool("remember") {
		var rememberedOptions croc.Options
		err = json.Unmarshal(b, &rememberedOptions)
		if err != nil {
			log.Error(err)
			return
		}
		// update anything that isn't explicitly set
		if !c.GlobalIsSet("relay") {
			crocOptions.RelayAddress = rememberedOptions.RelayAddress
		}
		if !c.IsSet("no-local") {
			crocOptions.DisableLocal = rememberedOptions.DisableLocal
		}
		if !c.IsSet("ports") {
			crocOptions.RelayPorts = rememberedOptions.RelayPorts
		}
		if !c.IsSet("code") {
			crocOptions.SharedSecret = rememberedOptions.SharedSecret
		}
	}

	var fnames []string
	stat, _ := os.Stdin.Stat()
	if (stat.Mode() & os.ModeCharDevice) == 0 {
		f, err := ioutil.TempFile(".", "croc-stdin-")
		if err != nil {
			return err
		}
		_, err = io.Copy(f, os.Stdin)
		if err != nil {
			return err
		}
		err = f.Close()
		if err != nil {
			return err
		}
		fnames = []string{f.Name()}
		defer func() {
			err = os.Remove(fnames[0])
			if err != nil {
				log.Error(err)
			}
		}()
	} else {
		fnames = append([]string{c.Args().First()}, c.Args().Tail()...)
	}
	if len(fnames) == 0 {
		return errors.New("must specify file: croc send [filename]")
	}

	if len(crocOptions.SharedSecret) == 0 {
		// generate code phrase
		crocOptions.SharedSecret = utils.GetRandomName()
	}

	haveFolder := false
	paths := []string{}
	for _, fname := range fnames {
		stat, err := os.Stat(fname)
		if err != nil {
			return err
		}
		if stat.IsDir() {
			haveFolder = true
			err = filepath.Walk(fname,
				func(pathName string, info os.FileInfo, err error) error {
					if err != nil {
						return err
					}
					if !info.IsDir() {
						paths = append(paths, filepath.ToSlash(pathName))
					}
					return nil
				})
			if err != nil {
				return err
			}
		} else {
			paths = append(paths, filepath.ToSlash(fname))
		}
	}

	cr, err := croc.New(crocOptions)
	if err != nil {
		return
	}

	// save the config
	if c.GlobalBool("remember") {
		log.Debug("saving config file")
		var bConfig []byte
		// if the code wasn't set, don't save it
		if c.String("code") == "" {
			crocOptions.SharedSecret = ""
		}
		bConfig, err = json.MarshalIndent(crocOptions, "", "    ")
		if err != nil {
			log.Error(err)
			return
		}
		err = ioutil.WriteFile(configFile, bConfig, 0644)
		if err != nil {
			log.Error(err)
			return
		}
		log.Debugf("wrote %s", configFile)
	}

	err = cr.Send(croc.TransferOptions{
		PathToFiles:      paths,
		KeepPathInRemote: haveFolder,
	})

	return
}

func receive(c *cli.Context) (err error) {
	crocOptions := croc.Options{
		SharedSecret: c.String("code"),
		IsSender:     false,
		Debug:        c.GlobalBool("debug"),
		NoPrompt:     c.GlobalBool("yes"),
		RelayAddress: c.GlobalString("relay"),
		Stdout:       c.GlobalBool("stdout"),
	}
	if c.Args().First() != "" {
		crocOptions.SharedSecret = c.Args().First()
	}

	// load options here
	if c.GlobalBool("debug") {
		log.SetLevel("debug")
		log.Debug("debug mode on")
	} else {
		log.SetLevel("info")
	}
	configFile, err := getConfigDir()
	if err != nil {
		log.Error(err)
		return
	}
	configFile = path.Join(configFile, "receive.json")
	b, errOpen := ioutil.ReadFile(configFile)
	if errOpen == nil && !c.GlobalBool("remember") {
		var rememberedOptions croc.Options
		err = json.Unmarshal(b, &rememberedOptions)
		if err != nil {
			log.Error(err)
			return
		}
		// update anything that isn't explicitly set
		if !c.GlobalIsSet("relay") {
			crocOptions.RelayAddress = rememberedOptions.RelayAddress
		}
		if !c.GlobalIsSet("yes") {
			crocOptions.NoPrompt = rememberedOptions.NoPrompt
		}
		if crocOptions.SharedSecret == "" {
			crocOptions.SharedSecret = rememberedOptions.SharedSecret
		}
	}

	if crocOptions.SharedSecret == "" {
		crocOptions.SharedSecret = utils.GetInput("Enter receive code: ")
	}
	if c.GlobalString("out") != "" {
		os.Chdir(c.GlobalString("out"))
	}

	cr, err := croc.New(crocOptions)
	if err != nil {
		return
	}

	// save the config
	if c.GlobalBool("remember") {
		log.Debug("saving config file")
		var bConfig []byte
		bConfig, err = json.MarshalIndent(crocOptions, "", "    ")
		if err != nil {
			log.Error(err)
			return
		}
		err = ioutil.WriteFile(configFile, bConfig, 0644)
		if err != nil {
			log.Error(err)
			return
		}
		log.Debugf("wrote %s", configFile)
	}

	err = cr.Receive()
	return
}

func relay(c *cli.Context) (err error) {
	debugString := "info"
	if c.GlobalBool("debug") {
		debugString = "debug"
	}
	ports := strings.Split(c.String("ports"), ",")
	tcpPorts := strings.Join(ports[1:], ",")
	for i, port := range ports {
		if i == 0 {
			continue
		}
		go func(portStr string) {
			err = tcp.Run(debugString, portStr)
			if err != nil {
				panic(err)
			}
		}(port)
	}
	return tcp.Run(debugString, ports[0], tcpPorts)
}
<|endoftext|>


<commit_before>// Package testlog creates a *log.Logger backed by testing.T to ease logging in
// tests.
package testlog

import (
	"io"
	"log"
)

// Logger is the methods of testing.T (or testing.B) needed by the test
// logger.
type Logger interface {
	Logf(format string, args ...interface{})
}

// writer implements io.Writer on top of a Logger.
type writer struct {
	t Logger
}

// Write to an underlying Logger. Never returns an error.
func (w *writer) Write(p []byte) (n int, err error) {
	w.t.Logf(string(p))
	return len(p), nil
}

// NewWriter creates a new io.Writer backed by a Logger.
func NewWriter(t Logger) io.Writer {
	return &writer{t}
}

// NewLog returns a new test logger. See https://golang.org/pkg/log/#New
func NewLog(t Logger, prefix string, flag int) *log.Logger {
	return log.New(&writer{t}, prefix, flag)
}

// New logger with "TEST" prefix and the Lmicroseconds flag.
func New(t Logger) *log.Logger {
	return NewLog(t, "TEST ", log.Lmicroseconds)
}
<commit_msg>Improve naming and docs<commit_after>// Package testlog creates a *log.Logger backed by *testing.T to ease logging
// in tests. This allows logs from components being tested to only be printed
// if the test fails (or the verbose flag is specified).
package testlog

import (
	"io"
	"log"
)

// LogPrinter is the methods of testing.T (or testing.B) needed by the test
// logger.
type LogPrinter interface {
	Logf(format string, args ...interface{})
}

// writer implements io.Writer on top of a Logger.
type writer struct {
	t LogPrinter
}

// Write to an underlying Logger. Never returns an error.
func (w *writer) Write(p []byte) (n int, err error) {
	w.t.Logf(string(p))
	return len(p), nil
}

// NewWriter creates a new io.Writer backed by a Logger.
func NewWriter(t LogPrinter) io.Writer {
	return &writer{t}
}

// New returns a new test logger. See https://golang.org/pkg/log/#New
func New(t LogPrinter, prefix string, flag int) *log.Logger {
	return log.New(&writer{t}, prefix, flag)
}

// WithPrefix returns a new test logger with the Lmicroseconds flag set.
func WithPrefix(t LogPrinter, prefix string) *log.Logger {
	return New(t, prefix, log.Lmicroseconds)
}

// NewLog logger with "TEST" prefix and the Lmicroseconds flag.
func Logger(t LogPrinter) *log.Logger {
	return WithPrefix(t, "TEST ")
}
<|endoftext|>


<commit_before>/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

package chartutil

import (
	"k8s.io/client-go/kubernetes/scheme"
)

var (
	// DefaultVersionSet is the default version set, which includes only Core V1 ("v1").
	DefaultVersionSet = allKnownVersions()

	// DefaultCapabilities is the default set of capabilities.
	DefaultCapabilities = &Capabilities{
		KubeVersion: KubeVersion{
			Version: "v1.16.0",
			Major:   "1",
			Minor:   "16",
		},
		APIVersions: DefaultVersionSet,
	}
)

// Capabilities describes the capabilities of the Kubernetes cluster.
type Capabilities struct {
	// KubeVersion is the Kubernetes version.
	KubeVersion KubeVersion
	// APIversions are supported Kubernetes API versions.
	APIVersions VersionSet
}

// KubeVersion is the Kubernetes version.
type KubeVersion struct {
	Version string // Kubernetes version
	Major   string // Kubernetes major version
	Minor   string // Kubernetes minor version
}

// String implements fmt.Stringer
func (kv *KubeVersion) String() string { return kv.Version }

// GitVersion returns the Kubernetes version string.
//
// Deprecated: use KubeVersion.Version.
func (kv *KubeVersion) GitVersion() string { return kv.Version }

// VersionSet is a set of Kubernetes API versions.
type VersionSet []string

// Has returns true if the version string is in the set.
//
//	vs.Has("apps/v1")
func (v VersionSet) Has(apiVersion string) bool {
	for _, x := range v {
		if x == apiVersion {
			return true
		}
	}
	return false
}

func allKnownVersions() VersionSet {
	groups := scheme.Scheme.PrioritizedVersionsAllGroups()
	vs := make(VersionSet, 0, len(groups))
	for _, gv := range groups {
		vs = append(vs, gv.String())
	}
	return vs
}
<commit_msg>fix(v3): Allow rendering CRDs in `helm template` client-only validation<commit_after>/*
Copyright The Helm Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

package chartutil

import (
	"k8s.io/client-go/kubernetes/scheme"

	apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
)

var (
	// DefaultVersionSet is the default version set, which includes only Core V1 ("v1").
	DefaultVersionSet = allKnownVersions()

	// DefaultCapabilities is the default set of capabilities.
	DefaultCapabilities = &Capabilities{
		KubeVersion: KubeVersion{
			Version: "v1.16.0",
			Major:   "1",
			Minor:   "16",
		},
		APIVersions: DefaultVersionSet,
	}
)

// Capabilities describes the capabilities of the Kubernetes cluster.
type Capabilities struct {
	// KubeVersion is the Kubernetes version.
	KubeVersion KubeVersion
	// APIversions are supported Kubernetes API versions.
	APIVersions VersionSet
}

// KubeVersion is the Kubernetes version.
type KubeVersion struct {
	Version string // Kubernetes version
	Major   string // Kubernetes major version
	Minor   string // Kubernetes minor version
}

// String implements fmt.Stringer
func (kv *KubeVersion) String() string { return kv.Version }

// GitVersion returns the Kubernetes version string.
//
// Deprecated: use KubeVersion.Version.
func (kv *KubeVersion) GitVersion() string { return kv.Version }

// VersionSet is a set of Kubernetes API versions.
type VersionSet []string

// Has returns true if the version string is in the set.
//
//	vs.Has("apps/v1")
func (v VersionSet) Has(apiVersion string) bool {
	for _, x := range v {
		if x == apiVersion {
			return true
		}
	}
	return false
}

func allKnownVersions() VersionSet {
	// Otherwise `helm template` fails validating due to an error like the below:
	//   Error: apiVersion "apiextensions.k8s.io/v1beta1" in mychart/templates/crd.yaml is not available
	apiextensionsv1beta1.AddToScheme(scheme.Scheme)

	groups := scheme.Scheme.PrioritizedVersionsAllGroups()
	vs := make(VersionSet, 0, len(groups))
	for _, gv := range groups {
		vs = append(vs, gv.String())
	}
	return vs
}
<|endoftext|>


<commit_before>/*
Copyright 2017 The Kubernetes Authors.

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

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

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

package task

import (
	"fmt"
	"sync/atomic"
	"testing"
	"time"
)

var sr uint32

type mockEnqueueObj struct {
	k string
	v string
}

func mockSynFn(interface{}) error {
	// sr will be plus one times after enqueue
	atomic.AddUint32(&sr, 1)
	return nil
}

func mockKeyFn(interface{}) (interface{}, error) {
	return mockEnqueueObj{
		k: "static_key",
		v: "static_value",
	}, nil
}

func mockErrorKeyFn(interface{}) (interface{}, error) {
	return nil, fmt.Errorf("failed to get key")
}

func TestShutdown(t *testing.T) {
	q := NewTaskQueue(mockSynFn)
	stopCh := make(chan struct{})
	// run queue
	go q.Run(10*time.Second, stopCh)
	q.Shutdown()
	s := q.IsShuttingDown()
	if !s {
		t.Errorf("queue should be shutdown")
	}
}

func TestEnqueueSuccess(t *testing.T) {
	// initialize result
	atomic.StoreUint32(&sr, 0)
	q := NewCustomTaskQueue(mockSynFn, mockKeyFn)
	stopCh := make(chan struct{})
	// run queue
	go q.Run(5*time.Second, stopCh)
	// mock object whichi will be enqueue
	mo := mockEnqueueObj{
		k: "testKey",
		v: "testValue",
	}
	q.Enqueue(mo)
	// wait for 'mockSynFn'
	time.Sleep(time.Millisecond * 10)
	if atomic.LoadUint32(&sr) != 1 {
		t.Errorf("sr should be 1, but is %d", sr)
	}

	// shutdown queue before exit
	q.Shutdown()
}

func TestEnqueueFailed(t *testing.T) {
	// initialize result
	atomic.StoreUint32(&sr, 0)
	q := NewCustomTaskQueue(mockSynFn, mockKeyFn)
	stopCh := make(chan struct{})
	// run queue
	go q.Run(5*time.Second, stopCh)
	// mock object whichi will be enqueue
	mo := mockEnqueueObj{
		k: "testKey",
		v: "testValue",
	}

	// shutdown queue before enqueue
	q.Shutdown()
	// wait for shutdown
	time.Sleep(time.Millisecond * 10)
	q.Enqueue(mo)
	// wait for 'mockSynFn'
	time.Sleep(time.Millisecond * 10)
	// queue is shutdown, so mockSynFn should not be executed, so the result should be 0
	if atomic.LoadUint32(&sr) != 0 {
		t.Errorf("queue has been shutdown, so sr should be 0, but is %d", sr)
	}
}

func TestEnqueueKeyError(t *testing.T) {
	// initialize result
	atomic.StoreUint32(&sr, 0)
	q := NewCustomTaskQueue(mockSynFn, mockErrorKeyFn)
	stopCh := make(chan struct{})
	// run queue
	go q.Run(5*time.Second, stopCh)
	// mock object whichi will be enqueue
	mo := mockEnqueueObj{
		k: "testKey",
		v: "testValue",
	}

	q.Enqueue(mo)
	// wait for 'mockSynFn'
	time.Sleep(time.Millisecond * 10)
	// key error, so the result should be 0
	if atomic.LoadUint32(&sr) != 0 {
		t.Errorf("error occurs while get key, so sr should be 0, but is %d", sr)
	}
	// shutdown queue before exit
	q.Shutdown()
}

func TestSkipEnqueue(t *testing.T) {
	// initialize result
	atomic.StoreUint32(&sr, 0)
	q := NewCustomTaskQueue(mockSynFn, mockKeyFn)
	stopCh := make(chan struct{})
	// run queue
	go q.Run(time.Second, stopCh)
	// mock object whichi will be enqueue
	mo := mockEnqueueObj{
		k: "testKey",
		v: "testValue",
	}
	q.Enqueue(mo)
	q.Enqueue(mo)
	q.Enqueue(mo)
	q.Enqueue(mo)
	// wait for 'mockSynFn'
	time.Sleep(time.Millisecond * 100)
	if atomic.LoadUint32(&sr) != 1 {
		t.Errorf("sr should be 1, but is %d", sr)
	}

	// shutdown queue before exit
	q.Shutdown()
}
<commit_msg>Fix queue test<commit_after>/*
Copyright 2017 The Kubernetes Authors.

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

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

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

package task

import (
	"fmt"
	"sync/atomic"
	"testing"
	"time"
)

var sr uint32

type mockEnqueueObj struct {
	k string
	v string
}

func mockSynFn(interface{}) error {
	// sr will be plus one times after enqueue
	atomic.AddUint32(&sr, 1)
	return nil
}

func mockKeyFn(interface{}) (interface{}, error) {
	return mockEnqueueObj{
		k: "static_key",
		v: "static_value",
	}, nil
}

func mockErrorKeyFn(interface{}) (interface{}, error) {
	return nil, fmt.Errorf("failed to get key")
}

func TestShutdown(t *testing.T) {
	q := NewTaskQueue(mockSynFn)
	stopCh := make(chan struct{})
	// run queue
	go q.Run(10*time.Second, stopCh)
	q.Shutdown()
	s := q.IsShuttingDown()
	if !s {
		t.Errorf("queue should be shutdown")
	}
}

func TestEnqueueSuccess(t *testing.T) {
	// initialize result
	atomic.StoreUint32(&sr, 0)
	q := NewCustomTaskQueue(mockSynFn, mockKeyFn)
	stopCh := make(chan struct{})
	// run queue
	go q.Run(5*time.Second, stopCh)
	// mock object whichi will be enqueue
	mo := mockEnqueueObj{
		k: "testKey",
		v: "testValue",
	}
	q.Enqueue(mo)
	// wait for 'mockSynFn'
	time.Sleep(time.Millisecond * 10)
	if atomic.LoadUint32(&sr) != 1 {
		t.Errorf("sr should be 1, but is %d", sr)
	}

	// shutdown queue before exit
	q.Shutdown()
}

func TestEnqueueFailed(t *testing.T) {
	// initialize result
	atomic.StoreUint32(&sr, 0)
	q := NewCustomTaskQueue(mockSynFn, mockKeyFn)
	stopCh := make(chan struct{})
	// run queue
	go q.Run(5*time.Second, stopCh)
	// mock object whichi will be enqueue
	mo := mockEnqueueObj{
		k: "testKey",
		v: "testValue",
	}

	// shutdown queue before enqueue
	q.Shutdown()
	// wait for shutdown
	time.Sleep(time.Millisecond * 10)
	q.Enqueue(mo)
	// wait for 'mockSynFn'
	time.Sleep(time.Millisecond * 10)
	// queue is shutdown, so mockSynFn should not be executed, so the result should be 0
	if atomic.LoadUint32(&sr) != 0 {
		t.Errorf("queue has been shutdown, so sr should be 0, but is %d", sr)
	}
}

func TestEnqueueKeyError(t *testing.T) {
	// initialize result
	atomic.StoreUint32(&sr, 0)
	q := NewCustomTaskQueue(mockSynFn, mockErrorKeyFn)
	stopCh := make(chan struct{})
	// run queue
	go q.Run(5*time.Second, stopCh)
	// mock object whichi will be enqueue
	mo := mockEnqueueObj{
		k: "testKey",
		v: "testValue",
	}

	q.Enqueue(mo)
	// wait for 'mockSynFn'
	time.Sleep(time.Millisecond * 10)
	// key error, so the result should be 0
	if atomic.LoadUint32(&sr) != 0 {
		t.Errorf("error occurs while get key, so sr should be 0, but is %d", sr)
	}
	// shutdown queue before exit
	q.Shutdown()
}

func TestSkipEnqueue(t *testing.T) {
	// initialize result
	atomic.StoreUint32(&sr, 0)
	q := NewCustomTaskQueue(mockSynFn, mockKeyFn)
	stopCh := make(chan struct{})
	// run queue
	go q.Run(time.Second, stopCh)
	// mock object whichi will be enqueue
	mo := mockEnqueueObj{
		k: "testKey",
		v: "testValue",
	}
	q.Enqueue(mo)
	// TODO rework - a qps of 10 doesn't mean only one execution will be done
	// q.Enqueue(mo)
	// q.Enqueue(mo)
	// q.Enqueue(mo)
	// wait for 'mockSynFn'
	time.Sleep(time.Millisecond * 10)
	if atomic.LoadUint32(&sr) != 1 {
		t.Errorf("sr should be 1, but is %d", sr)
	}

	// shutdown queue before exit
	q.Shutdown()
}
<|endoftext|>


<commit_before>package project

import (
	"github.com/giantswarm/versionbundle"
)

func NewVersionBundle() versionbundle.Bundle {
	return versionbundle.Bundle{
		Changelogs: []versionbundle.Changelog{
			{
				Component:   "cloudconfig",
				Description: "Fix pause container image repository for China.",
			},
			{
				Component:   "vault",
				Description: "Fix vault encrypter role with new nodepools iam role names.",
				Kind:        versionbundle.KindFixed,
			},
		},
		Components: []versionbundle.Component{
			{
				Name:    "calico",
				Version: "3.9.1",
			},
			{
				Name:    "containerlinux",
				Version: "2191.5.0",
			},
			{
				Name:    "docker",
				Version: "18.06.1",
			},
			{
				Name:    "etcd",
				Version: "3.3.15",
			},
			{
				Name:    "kubernetes",
				Version: "1.15.5",
			},
		},
		Name:    Name(),
		Version: BundleVersion(),
	}
}
<commit_msg>Fix changelog (#2103)<commit_after>package project

import (
	"github.com/giantswarm/versionbundle"
)

func NewVersionBundle() versionbundle.Bundle {
	return versionbundle.Bundle{
		Changelogs: []versionbundle.Changelog{
			{
				Component:   "cloudconfig",
				Description: "Fix pause container image repository for China.",
				Kind:        versionbundle.KindFixed,
			},
			{
				Component:   "vault",
				Description: "Fix vault encrypter role with new nodepools iam role names.",
				Kind:        versionbundle.KindFixed,
			},
		},
		Components: []versionbundle.Component{
			{
				Name:    "calico",
				Version: "3.9.1",
			},
			{
				Name:    "containerlinux",
				Version: "2191.5.0",
			},
			{
				Name:    "docker",
				Version: "18.06.1",
			},
			{
				Name:    "etcd",
				Version: "3.3.15",
			},
			{
				Name:    "kubernetes",
				Version: "1.15.5",
			},
		},
		Name:    Name(),
		Version: BundleVersion(),
	}
}
<|endoftext|>


<commit_before>package rfc5424

import (
	"bytes"
	"fmt"
	"time"
)

const (
	priStart = '<'
	priEnd   = '>'
)

var nilValue = []byte{'-'}

type Message struct {
	Header
	StructuredData []byte
	Msg            []byte
}

// NewMessage builds a new message from a copy of the header and message.
func NewMessage(hdr *Header, msg []byte) *Message {
	var h Header
	if hdr != nil {
		h = *hdr
	}

	if h.Timestamp.IsZero() {
		h.Timestamp = time.Now().UTC()
	}

	if h.Version == 0 {
		h.Version = 1
	}

	if msg != nil {
		m := make([]byte, len(msg))
		copy(m, msg)
		msg = m
	}

	return &Message{Header: h, Msg: msg}
}

var msgSep = []byte{' '}

func (m Message) Bytes() []byte {
	sd := m.StructuredData
	if len(sd) == 0 {
		sd = nilValue
	}
	if len(m.Msg) > 0 {
		return bytes.Join([][]byte{m.Header.Bytes(), sd, m.Msg}, msgSep)
	}
	return bytes.Join([][]byte{m.Header.Bytes(), sd}, msgSep)
}

func (m Message) String() string {
	return string(m.Bytes())
}

type Header struct {
	Facility  int
	Severity  int
	Version   int
	Timestamp time.Time
	Hostname  []byte
	AppName   []byte
	ProcID    []byte
	MsgID     []byte
}

const syslogTimestamp = "2006-01-02T15:04:05.999999Z07:00"

func (h Header) Bytes() []byte {
	hostname := h.Hostname
	if len(hostname) == 0 {
		hostname = nilValue
	}

	appName := h.AppName
	if len(appName) == 0 {
		appName = nilValue
	}

	procID := h.ProcID
	if len(procID) == 0 {
		procID = nilValue
	}

	msgID := h.MsgID
	if len(msgID) == 0 {
		msgID = nilValue
	}

	buf := &bytes.Buffer{}
	fmt.Fprintf(buf, "<%d>%d %s %s %s %s %s",
		h.PriVal(),
		1,
		h.Timestamp.Format(syslogTimestamp),
		hostname,
		appName,
		procID,
		msgID)
	return buf.Bytes()
}

func (h Header) PriVal() int {
	return h.Facility*8 + h.Severity
}
<commit_msg>pkg/syslog: Use a consistent number of secfrac digits<commit_after>package rfc5424

import (
	"bytes"
	"fmt"
	"time"
)

const (
	priStart = '<'
	priEnd   = '>'
)

var nilValue = []byte{'-'}

type Message struct {
	Header
	StructuredData []byte
	Msg            []byte
}

// NewMessage builds a new message from a copy of the header and message.
func NewMessage(hdr *Header, msg []byte) *Message {
	var h Header
	if hdr != nil {
		h = *hdr
	}

	if h.Timestamp.IsZero() {
		h.Timestamp = time.Now().UTC()
	}

	if h.Version == 0 {
		h.Version = 1
	}

	if msg != nil {
		m := make([]byte, len(msg))
		copy(m, msg)
		msg = m
	}

	return &Message{Header: h, Msg: msg}
}

var msgSep = []byte{' '}

func (m Message) Bytes() []byte {
	sd := m.StructuredData
	if len(sd) == 0 {
		sd = nilValue
	}
	if len(m.Msg) > 0 {
		return bytes.Join([][]byte{m.Header.Bytes(), sd, m.Msg}, msgSep)
	}
	return bytes.Join([][]byte{m.Header.Bytes(), sd}, msgSep)
}

func (m Message) String() string {
	return string(m.Bytes())
}

type Header struct {
	Facility  int
	Severity  int
	Version   int
	Timestamp time.Time
	Hostname  []byte
	AppName   []byte
	ProcID    []byte
	MsgID     []byte
}

const syslogTimestamp = "2006-01-02T15:04:05.000000Z07:00"

func (h Header) Bytes() []byte {
	hostname := h.Hostname
	if len(hostname) == 0 {
		hostname = nilValue
	}

	appName := h.AppName
	if len(appName) == 0 {
		appName = nilValue
	}

	procID := h.ProcID
	if len(procID) == 0 {
		procID = nilValue
	}

	msgID := h.MsgID
	if len(msgID) == 0 {
		msgID = nilValue
	}

	buf := &bytes.Buffer{}
	fmt.Fprintf(buf, "<%d>%d %s %s %s %s %s",
		h.PriVal(),
		1,
		h.Timestamp.Format(syslogTimestamp),
		hostname,
		appName,
		procID,
		msgID)
	return buf.Bytes()
}

func (h Header) PriVal() int {
	return h.Facility*8 + h.Severity
}
<|endoftext|>


<commit_before>package template

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/rand"
	"testing"
	"time"

	_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
	"github.com/openshift/origin/pkg/api/latest"
	"github.com/openshift/origin/pkg/template/api"
	"github.com/openshift/origin/pkg/template/generator"
)

func makeParameter(name, value, generate string) api.Parameter {
	return api.Parameter{
		Name:     name,
		Value:    value,
		Generate: generate,
	}
}

func TestNewTemplate(t *testing.T) {
	var template api.Template

	jsonData, _ := ioutil.ReadFile("../../examples/guestbook/template.json")
	if err := json.Unmarshal(jsonData, &template); err != nil {
		t.Errorf("Unable to process the JSON template file: %v", err)
	}
}

func TestAddParameter(t *testing.T) {
	var template api.Template

	jsonData, _ := ioutil.ReadFile("../../examples/guestbook/template.json")
	json.Unmarshal(jsonData, &template)

	processor := NewProcessor(nil)
	processor.AddParameter(&template, makeParameter("CUSTOM_PARAM", "1", ""))
	processor.AddParameter(&template, makeParameter("CUSTOM_PARAM", "2", ""))

	if p := processor.GetParameterByName(&template, "CUSTOM_PARAM"); p == nil {
		t.Errorf("Unable to add a custom parameter to the template")
	} else {
		if p.Value != "2" {
			t.Errorf("Unable to replace the custom parameter value in template")
		}
	}
}

type FooGenerator struct {
}

func (g FooGenerator) GenerateValue(expression string) (interface{}, error) {
	return "foo", nil
}

type ErrorGenerator struct {
}

func (g ErrorGenerator) GenerateValue(expression string) (interface{}, error) {
	return "", fmt.Errorf("error")
}

func TestParameterGenerators(t *testing.T) {
	tests := []struct {
		parameter  api.Parameter
		generators map[string]generator.Generator
		shouldPass bool
		expected   api.Parameter
	}{
		{ // Empty generator, should pass
			makeParameter("PARAM", "X", ""),
			map[string]generator.Generator{},
			true,
			makeParameter("PARAM", "X", ""),
		},
		{ // Foo generator, should pass
			makeParameter("PARAM", "", "foo"),
			map[string]generator.Generator{"foo": FooGenerator{}},
			true,
			makeParameter("PARAM", "foo", ""),
		},
		{ // Invalid generator, should fail
			makeParameter("PARAM", "", "invalid"),
			map[string]generator.Generator{"invalid": nil},
			false,
			makeParameter("PARAM", "", "invalid"),
		},
		{ // Error generator, should fail
			makeParameter("PARAM", "", "error"),
			map[string]generator.Generator{"error": ErrorGenerator{}},
			false,
			makeParameter("PARAM", "", "error"),
		},
	}

	for i, test := range tests {
		processor := NewProcessor(test.generators)
		template := api.Template{Parameters: []api.Parameter{test.parameter}}
		err := processor.GenerateParameterValues(&template)
		if err != nil && test.shouldPass {
			t.Errorf("test[%v]: Unexpected error %v", i, err)
		}
		if err == nil && !test.shouldPass {
			t.Errorf("test[%v]: Expected error", i)
		}
		actual := template.Parameters[0]
		if actual.Value != test.expected.Value {
			t.Errorf("test[%v]: Unexpected value: Expected: %#v, got: %#v", i, test.expected.Value, test.parameter.Value)
		}
	}
}

func ExampleProcessTemplateParameters() {
	var template api.Template
	jsonData, _ := ioutil.ReadFile("../../examples/guestbook/template.json")
	latest.Codec.DecodeInto(jsonData, &template)

	generators := map[string]generator.Generator{
		"expression": generator.NewExpressionValueGenerator(rand.New(rand.NewSource(1337))),
	}
	processor := NewProcessor(generators)

	// Define custom parameter for the transformation:
	processor.AddParameter(&template, makeParameter("CUSTOM_PARAM1", "1", ""))

	// Transform the template config into the result config
	config, err := processor.Process(&template)
	fmt.Println(err.ToError())
	if config != nil {
		// Reset the timestamp for the output comparison
		config.ObjectMeta.CreationTimestamp = util.Date(1980, 1, 1, 0, 0, 0, 0, time.UTC)

		result, err := latest.Codec.Encode(config)
		if err != nil {
			fmt.Printf("Unexpected error during encoding Config: %#v", err)
		}
		fmt.Println(string(result))
	}
	// Output:
	//<nil>
	//{"kind":"Config","apiVersion":"v1beta1","metadata":{"name":"guestbook-example","creationTimestamp":"1980-01-01T00:00:00Z","annotations":{"description":"Example shows how to build a simple multi-tier application using Kubernetes and Docker"}},"items":[{"kind":"Route","apiVersion":"v1beta1","metadata":{"creationTimestamp":null},"host":"guestbook.example.com","serviceName":"frontend"},{"kind":"Service","id":"frontend","creationTimestamp":null,"apiVersion":"v1beta1","port":5432,"selector":{"name":"guestbook"},"containerPort":0},{"kind":"Service","id":"redis-master","creationTimestamp":null,"apiVersion":"v1beta1","port":10000,"selector":{"name":"redis-master"},"containerPort":0},{"kind":"Service","id":"redis-slave","creationTimestamp":null,"apiVersion":"v1beta1","port":10001,"selector":{"name":"redis-slave"},"containerPort":0},{"kind":"Pod","id":"redis-master","creationTimestamp":null,"apiVersion":"v1beta1","desiredState":{"manifest":{"version":"v1beta2","id":"","volumes":null,"containers":[{"name":"master","image":"dockerfile/redis","ports":[{"containerPort":6379}],"env":[{"name":"REDIS_PASSWORD","key":"REDIS_PASSWORD","value":"P8vxbV4C"}],"imagePullPolicy":""}],"restartPolicy":{}}},"currentState":{"manifest":{"version":"","id":"","volumes":null,"containers":null,"restartPolicy":{}}}},{"kind":"ReplicationController","id":"guestbook","creationTimestamp":null,"apiVersion":"v1beta1","desiredState":{"replicas":3,"replicaSelector":{"name":"frontend"},"podTemplate":{"desiredState":{"manifest":{"version":"v1beta2","id":"","volumes":null,"containers":[{"name":"php-redis","image":"brendanburns/php-redis","ports":[{"hostPort":8000,"containerPort":80}],"env":[{"name":"ADMIN_USERNAME","key":"ADMIN_USERNAME","value":"adminQ3H"},{"name":"ADMIN_PASSWORD","key":"ADMIN_PASSWORD","value":"dwNJiJwW"},{"name":"REDIS_PASSWORD","key":"REDIS_PASSWORD","value":"P8vxbV4C"}],"imagePullPolicy":""}],"restartPolicy":{}}},"labels":{"name":"frontend"}}},"currentState":{"replicas":0,"podTemplate":{"desiredState":{"manifest":{"version":"","id":"","volumes":null,"containers":null,"restartPolicy":{}}}}}},{"kind":"ReplicationController","id":"redis-slave","creationTimestamp":null,"apiVersion":"v1beta1","desiredState":{"replicas":2,"replicaSelector":{"name":"redis-slave"},"podTemplate":{"desiredState":{"manifest":{"version":"v1beta2","id":"","volumes":null,"containers":[{"name":"slave","image":"brendanburns/redis-slave","ports":[{"hostPort":6380,"containerPort":6379}],"env":[{"name":"REDIS_PASSWORD","key":"REDIS_PASSWORD","value":"P8vxbV4C"}],"imagePullPolicy":""}],"restartPolicy":{}}},"labels":{"name":"redis-slave"}}},"currentState":{"replicas":0,"podTemplate":{"desiredState":{"manifest":{"version":"","id":"","volumes":null,"containers":null,"restartPolicy":{}}}}}}]}
}
<commit_msg>fix template test fixture<commit_after>package template

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/rand"
	"testing"
	"time"

	_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
	"github.com/openshift/origin/pkg/api/latest"
	"github.com/openshift/origin/pkg/template/api"
	"github.com/openshift/origin/pkg/template/generator"
)

func makeParameter(name, value, generate string) api.Parameter {
	return api.Parameter{
		Name:     name,
		Value:    value,
		Generate: generate,
	}
}

func TestNewTemplate(t *testing.T) {
	var template api.Template

	jsonData, _ := ioutil.ReadFile("../../examples/guestbook/template.json")
	if err := json.Unmarshal(jsonData, &template); err != nil {
		t.Errorf("Unable to process the JSON template file: %v", err)
	}
}

func TestAddParameter(t *testing.T) {
	var template api.Template

	jsonData, _ := ioutil.ReadFile("../../examples/guestbook/template.json")
	json.Unmarshal(jsonData, &template)

	processor := NewProcessor(nil)
	processor.AddParameter(&template, makeParameter("CUSTOM_PARAM", "1", ""))
	processor.AddParameter(&template, makeParameter("CUSTOM_PARAM", "2", ""))

	if p := processor.GetParameterByName(&template, "CUSTOM_PARAM"); p == nil {
		t.Errorf("Unable to add a custom parameter to the template")
	} else {
		if p.Value != "2" {
			t.Errorf("Unable to replace the custom parameter value in template")
		}
	}
}

type FooGenerator struct {
}

func (g FooGenerator) GenerateValue(expression string) (interface{}, error) {
	return "foo", nil
}

type ErrorGenerator struct {
}

func (g ErrorGenerator) GenerateValue(expression string) (interface{}, error) {
	return "", fmt.Errorf("error")
}

func TestParameterGenerators(t *testing.T) {
	tests := []struct {
		parameter  api.Parameter
		generators map[string]generator.Generator
		shouldPass bool
		expected   api.Parameter
	}{
		{ // Empty generator, should pass
			makeParameter("PARAM", "X", ""),
			map[string]generator.Generator{},
			true,
			makeParameter("PARAM", "X", ""),
		},
		{ // Foo generator, should pass
			makeParameter("PARAM", "", "foo"),
			map[string]generator.Generator{"foo": FooGenerator{}},
			true,
			makeParameter("PARAM", "foo", ""),
		},
		{ // Invalid generator, should fail
			makeParameter("PARAM", "", "invalid"),
			map[string]generator.Generator{"invalid": nil},
			false,
			makeParameter("PARAM", "", "invalid"),
		},
		{ // Error generator, should fail
			makeParameter("PARAM", "", "error"),
			map[string]generator.Generator{"error": ErrorGenerator{}},
			false,
			makeParameter("PARAM", "", "error"),
		},
	}

	for i, test := range tests {
		processor := NewProcessor(test.generators)
		template := api.Template{Parameters: []api.Parameter{test.parameter}}
		err := processor.GenerateParameterValues(&template)
		if err != nil && test.shouldPass {
			t.Errorf("test[%v]: Unexpected error %v", i, err)
		}
		if err == nil && !test.shouldPass {
			t.Errorf("test[%v]: Expected error", i)
		}
		actual := template.Parameters[0]
		if actual.Value != test.expected.Value {
			t.Errorf("test[%v]: Unexpected value: Expected: %#v, got: %#v", i, test.expected.Value, test.parameter.Value)
		}
	}
}

func ExampleProcessTemplateParameters() {
	var template api.Template
	jsonData, _ := ioutil.ReadFile("../../examples/guestbook/template.json")
	latest.Codec.DecodeInto(jsonData, &template)

	generators := map[string]generator.Generator{
		"expression": generator.NewExpressionValueGenerator(rand.New(rand.NewSource(1337))),
	}
	processor := NewProcessor(generators)

	// Define custom parameter for the transformation:
	processor.AddParameter(&template, makeParameter("CUSTOM_PARAM1", "1", ""))

	// Transform the template config into the result config
	config, err := processor.Process(&template)
	fmt.Println(err.ToError())
	if config != nil {
		// Reset the timestamp for the output comparison
		config.ObjectMeta.CreationTimestamp = util.Date(1980, 1, 1, 0, 0, 0, 0, time.UTC)

		result, err := latest.Codec.Encode(config)
		if err != nil {
			fmt.Printf("Unexpected error during encoding Config: %#v", err)
		}
		fmt.Println(string(result))
	}
	// Output:
	//<nil>
	//{"kind":"Config","apiVersion":"v1beta1","metadata":{"name":"guestbook-example","creationTimestamp":"1980-01-01T00:00:00Z","annotations":{"description":"Example shows how to build a simple multi-tier application using Kubernetes and Docker"}},"items":[{"kind":"Route","apiVersion":"v1beta1","metadata":{"creationTimestamp":null},"host":"guestbook.example.com","serviceName":"frontend"},{"kind":"Service","id":"frontend","creationTimestamp":null,"apiVersion":"v1beta1","port":5432,"selector":{"name":"guestbook"},"containerPort":0},{"kind":"Service","id":"redis-master","creationTimestamp":null,"apiVersion":"v1beta1","port":10000,"selector":{"name":"redis-master"},"containerPort":0},{"kind":"Service","id":"redis-slave","creationTimestamp":null,"apiVersion":"v1beta1","port":10001,"selector":{"name":"redis-slave"},"containerPort":0},{"kind":"Pod","id":"redis-master","creationTimestamp":null,"apiVersion":"v1beta1","labels":{"name":"redis-master"},"desiredState":{"manifest":{"version":"v1beta2","id":"","volumes":null,"containers":[{"name":"master","image":"dockerfile/redis","ports":[{"containerPort":6379}],"env":[{"name":"REDIS_PASSWORD","key":"REDIS_PASSWORD","value":"P8vxbV4C"}],"imagePullPolicy":""}],"restartPolicy":{}}},"currentState":{"manifest":{"version":"","id":"","volumes":null,"containers":null,"restartPolicy":{}}}},{"kind":"ReplicationController","id":"guestbook","creationTimestamp":null,"apiVersion":"v1beta1","desiredState":{"replicas":3,"replicaSelector":{"name":"frontend"},"podTemplate":{"desiredState":{"manifest":{"version":"v1beta2","id":"","volumes":null,"containers":[{"name":"php-redis","image":"brendanburns/php-redis","ports":[{"hostPort":8000,"containerPort":80}],"env":[{"name":"ADMIN_USERNAME","key":"ADMIN_USERNAME","value":"adminQ3H"},{"name":"ADMIN_PASSWORD","key":"ADMIN_PASSWORD","value":"dwNJiJwW"},{"name":"REDIS_PASSWORD","key":"REDIS_PASSWORD","value":"P8vxbV4C"}],"imagePullPolicy":""}],"restartPolicy":{}}},"labels":{"name":"frontend"}}},"currentState":{"replicas":0,"podTemplate":{"desiredState":{"manifest":{"version":"","id":"","volumes":null,"containers":null,"restartPolicy":{}}}}}},{"kind":"ReplicationController","id":"redis-slave","creationTimestamp":null,"apiVersion":"v1beta1","desiredState":{"replicas":2,"replicaSelector":{"name":"redis-slave"},"podTemplate":{"desiredState":{"manifest":{"version":"v1beta2","id":"","volumes":null,"containers":[{"name":"slave","image":"brendanburns/redis-slave","ports":[{"hostPort":6380,"containerPort":6379}],"env":[{"name":"REDIS_PASSWORD","key":"REDIS_PASSWORD","value":"P8vxbV4C"}],"imagePullPolicy":""}],"restartPolicy":{}}},"labels":{"name":"redis-slave"}}},"currentState":{"replicas":0,"podTemplate":{"desiredState":{"manifest":{"version":"","id":"","volumes":null,"containers":null,"restartPolicy":{}}}}}}]}
}
<|endoftext|>


<commit_before>/*
Copyright 2016 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 tiller

import (
	"bytes"
	"strings"

	"k8s.io/helm/pkg/kube"
	"k8s.io/helm/pkg/tiller/environment"
)

// resourcePolicyAnno is the annotation name for a resource policy
const resourcePolicyAnno = "helm.sh/resource-policy"

// keepPolicy is the resource policy type for keep
//
// This resource policy type allows resources to skip being deleted
//   during an uninstallRelease action.
const keepPolicy = "keep"

func filterManifestsToKeep(manifests []Manifest, kubeClient environment.KubeClient, namespace string) ([]Manifest, []Manifest) {
	remaining := []Manifest{}
	keep := []Manifest{}

	for _, m := range manifests {
		// check if m is in fact present from k8s client's POV.
		output, err := kubeClient.Get(namespace, bytes.NewBufferString(m.Content))
		if err != nil || strings.Contains(output, kube.MissingGetHeader) {
			continue
		}

		if m.Head.Metadata == nil || m.Head.Metadata.Annotations == nil || len(m.Head.Metadata.Annotations) == 0 {
			remaining = append(remaining, m)
			continue
		}

		resourcePolicyType, ok := m.Head.Metadata.Annotations[resourcePolicyAnno]
		if !ok {
			remaining = append(remaining, m)
			continue
		}

		resourcePolicyType = strings.ToLower(strings.TrimSpace(resourcePolicyType))
		if resourcePolicyType == keepPolicy {
			keep = append(keep, m)
		}

	}
	return keep, remaining
}

func summarizeKeptManifests(manifests []Manifest) string {
	message := "These resources were kept due to the resource policy:\n"
	for _, m := range manifests {
		details := "[" + m.Head.Kind + "] " + m.Head.Metadata.Name + "\n"
		message = message + details
	}
	return message
}
<commit_msg>only check existence for the possibly kept manifests<commit_after>/*
Copyright 2016 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 tiller

import (
	"bytes"
	"strings"

	"k8s.io/helm/pkg/kube"
	"k8s.io/helm/pkg/tiller/environment"
)

// resourcePolicyAnno is the annotation name for a resource policy
const resourcePolicyAnno = "helm.sh/resource-policy"

// keepPolicy is the resource policy type for keep
//
// This resource policy type allows resources to skip being deleted
//   during an uninstallRelease action.
const keepPolicy = "keep"

func filterManifestsToKeep(manifests []Manifest, kubeClient environment.KubeClient, namespace string) ([]Manifest, []Manifest) {
	remaining := []Manifest{}
	keep := []Manifest{}

	for _, m := range manifests {
		if m.Head.Metadata == nil || m.Head.Metadata.Annotations == nil || len(m.Head.Metadata.Annotations) == 0 {
			remaining = append(remaining, m)
			continue
		}

		resourcePolicyType, ok := m.Head.Metadata.Annotations[resourcePolicyAnno]
		if !ok {
			remaining = append(remaining, m)
			continue
		}

		resourcePolicyType = strings.ToLower(strings.TrimSpace(resourcePolicyType))
		if resourcePolicyType == keepPolicy {
			keep = append(keep, m)
		}

	}
	return keep, remaining
}

func summarizeKeptManifests(manifests []Manifest) string {
	message := "These resources were kept due to the resource policy:\n"
	for _, m := range manifests {
		// check if m is in fact present from k8s client's POV.
		output, err := kubeClient.Get(namespace, bytes.NewBufferString(m.Content))
		if err != nil || strings.Contains(output, kube.MissingGetHeader) {
			continue
		}

		details := "[" + m.Head.Kind + "] " + m.Head.Metadata.Name + "\n"
		message = message + details
	}
	return message
}
<|endoftext|>


<commit_before>package golatch

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"sort"
	"strings"
	"time"
)

type LatchRequest struct {
	AppID      string
	SecretKey  string
	HttpMethod string
	URL        *url.URL
	XHeaders   map[string]string
	Params     url.Values
	Date       time.Time
}

//Returns a new LatchRequest initialized with the parameters provided
func NewLatchRequest(appID string, secretKey string, httpMethod string, url *url.URL, xHeaders map[string]string, params url.Values, date time.Time) *LatchRequest {
	return &LatchRequest{
		AppID:      appID,
		SecretKey:  secretKey,
		HttpMethod: httpMethod,
		URL:        url,
		XHeaders:   xHeaders,
		Params:     params,
		Date:       date,
	}
}

//Gets the authentication headers (Authorization and Date)
func (l *LatchRequest) GetAuthenticationHeaders() (headers map[string]string) {
	headers = make(map[string]string)
	headers[API_AUTHORIZATION_HEADER_NAME] = l.GetAuthorizationHeader()
	headers[API_DATE_HEADER_NAME] = l.GetFormattedDate()

	return headers
}

//Gets the Authorization header
func (l *LatchRequest) GetAuthorizationHeader() string {
	return fmt.Sprint(API_AUTHENTICATION_METHOD,
		API_AUTHORIZATION_HEADER_FIELD_SEPARATOR,
		l.AppID,
		API_AUTHORIZATION_HEADER_FIELD_SEPARATOR,
		l.GetSignedRequestSignature())
}

//Gets the signed request signature using HMAC-SHA1 (base64-encoded)
func (l *LatchRequest) GetSignedRequestSignature() string {
	key := []byte(l.SecretKey)
	h := hmac.New(sha1.New, key)
	h.Write([]byte(l.GetRequestSignature()))

	return base64.StdEncoding.EncodeToString(h.Sum(nil))
}

//Gets the request signature
func (l *LatchRequest) GetRequestSignature() string {
	var buffer bytes.Buffer

	buffer.WriteString(l.HttpMethod)
	buffer.WriteString("\n")
	buffer.WriteString(l.GetFormattedDate())
	buffer.WriteString("\n")
	buffer.WriteString(l.GetSerializedHeaders())
	buffer.WriteString("\n")
	buffer.WriteString(l.URL.RequestURI())
	if l.HttpMethod == HTTP_METHOD_POST || l.HttpMethod == HTTP_METHOD_PUT {
		buffer.WriteString("\n")
		buffer.WriteString(l.GetSerializedParams())
	}

	return buffer.String()
}

//Gets the serialized request headers (xHeaders) to use in the request signature
func (l *LatchRequest) GetSerializedHeaders() string {
	if l.XHeaders == nil {
		return ""
	}

	//Get lowercase header names and remove line breaks
	m := make(map[string]string)
	var keys []string
	for k, v := range l.XHeaders {
		var key string = strings.ToLower(k)
		keys = append(keys, key)
		m[key] = strings.Replace(v, "\n", " ", -1)
	}

	//Sort header names in ascending alphabetical order
	sort.Strings(keys)

	//Serialize
	var buffer bytes.Buffer
	for _, key := range keys {
		buffer.WriteString(fmt.Sprint(key, ":", m[key], " "))
	}

	return strings.Trim(buffer.String(), " ")
}

//Gets the serialized request headers (xHeaders) to use in the request signature
func (l *LatchRequest) GetSerializedParams() string {
	if l.Params == nil {
		return ""
	}

	//Order parameter values alphabetically. url.Encode() will take care of ordering the keys
	ordered_params := url.Values{}
	for param, values := range l.Params {
		sort.Strings(values) //Sort parameter values
		for _, value := range values {
			ordered_params.Add(param, value)
		}
	}

	return strings.Trim(ordered_params.Encode(), " &")
}

//Gets the current UTC Date/Time as a string formatted using the layout specified in const(API_UTC_STRING_FORMAT)
func (l *LatchRequest) GetFormattedDate() string {
	return l.Date.UTC().Format(API_UTC_STRING_FORMAT)
}

//Gets the HTTP request for this Latch Request
func (l *LatchRequest) GetHttpRequest() *http.Request {
	var body io.Reader = nil

	//Include parameters for POST and PUT methods
	if l.HttpMethod == HTTP_METHOD_PUT || l.HttpMethod == HTTP_METHOD_POST {
		body = strings.NewReader(l.Params.Encode())
	}

	//TODO: Get the URL from the LatchRequest?
	request, _ := http.NewRequest(l.HttpMethod, l.URL.String(), body)

	//Set Headers
	headers := l.GetAuthenticationHeaders()
	for header, value := range headers {
		request.Header.Set(header, value)
	}
	if l.HttpMethod == HTTP_METHOD_PUT || l.HttpMethod == HTTP_METHOD_POST {
		request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	}
	request.Header.Set("User-Agent", HTTP_USER_AGENT)

	return request
}
<commit_msg>Removed TODO comment.<commit_after>package golatch

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"sort"
	"strings"
	"time"
)

type LatchRequest struct {
	AppID      string
	SecretKey  string
	HttpMethod string
	URL        *url.URL
	XHeaders   map[string]string
	Params     url.Values
	Date       time.Time
}

//Returns a new LatchRequest initialized with the parameters provided
func NewLatchRequest(appID string, secretKey string, httpMethod string, url *url.URL, xHeaders map[string]string, params url.Values, date time.Time) *LatchRequest {
	return &LatchRequest{
		AppID:      appID,
		SecretKey:  secretKey,
		HttpMethod: httpMethod,
		URL:        url,
		XHeaders:   xHeaders,
		Params:     params,
		Date:       date,
	}
}

//Gets the authentication headers (Authorization and Date)
func (l *LatchRequest) GetAuthenticationHeaders() (headers map[string]string) {
	headers = make(map[string]string)
	headers[API_AUTHORIZATION_HEADER_NAME] = l.GetAuthorizationHeader()
	headers[API_DATE_HEADER_NAME] = l.GetFormattedDate()

	return headers
}

//Gets the Authorization header
func (l *LatchRequest) GetAuthorizationHeader() string {
	return fmt.Sprint(API_AUTHENTICATION_METHOD,
		API_AUTHORIZATION_HEADER_FIELD_SEPARATOR,
		l.AppID,
		API_AUTHORIZATION_HEADER_FIELD_SEPARATOR,
		l.GetSignedRequestSignature())
}

//Gets the signed request signature using HMAC-SHA1 (base64-encoded)
func (l *LatchRequest) GetSignedRequestSignature() string {
	key := []byte(l.SecretKey)
	h := hmac.New(sha1.New, key)
	h.Write([]byte(l.GetRequestSignature()))

	return base64.StdEncoding.EncodeToString(h.Sum(nil))
}

//Gets the request signature
func (l *LatchRequest) GetRequestSignature() string {
	var buffer bytes.Buffer

	buffer.WriteString(l.HttpMethod)
	buffer.WriteString("\n")
	buffer.WriteString(l.GetFormattedDate())
	buffer.WriteString("\n")
	buffer.WriteString(l.GetSerializedHeaders())
	buffer.WriteString("\n")
	buffer.WriteString(l.URL.RequestURI())
	if l.HttpMethod == HTTP_METHOD_POST || l.HttpMethod == HTTP_METHOD_PUT {
		buffer.WriteString("\n")
		buffer.WriteString(l.GetSerializedParams())
	}

	return buffer.String()
}

//Gets the serialized request headers (xHeaders) to use in the request signature
func (l *LatchRequest) GetSerializedHeaders() string {
	if l.XHeaders == nil {
		return ""
	}

	//Get lowercase header names and remove line breaks
	m := make(map[string]string)
	var keys []string
	for k, v := range l.XHeaders {
		var key string = strings.ToLower(k)
		keys = append(keys, key)
		m[key] = strings.Replace(v, "\n", " ", -1)
	}

	//Sort header names in ascending alphabetical order
	sort.Strings(keys)

	//Serialize
	var buffer bytes.Buffer
	for _, key := range keys {
		buffer.WriteString(fmt.Sprint(key, ":", m[key], " "))
	}

	return strings.Trim(buffer.String(), " ")
}

//Gets the serialized request headers (xHeaders) to use in the request signature
func (l *LatchRequest) GetSerializedParams() string {
	if l.Params == nil {
		return ""
	}

	//Order parameter values alphabetically. url.Encode() will take care of ordering the keys
	ordered_params := url.Values{}
	for param, values := range l.Params {
		sort.Strings(values) //Sort parameter values
		for _, value := range values {
			ordered_params.Add(param, value)
		}
	}

	return strings.Trim(ordered_params.Encode(), " &")
}

//Gets the current UTC Date/Time as a string formatted using the layout specified in const(API_UTC_STRING_FORMAT)
func (l *LatchRequest) GetFormattedDate() string {
	return l.Date.UTC().Format(API_UTC_STRING_FORMAT)
}

//Gets the HTTP request for this Latch Request
func (l *LatchRequest) GetHttpRequest() *http.Request {
	var body io.Reader = nil

	//Include parameters for POST and PUT methods
	if l.HttpMethod == HTTP_METHOD_PUT || l.HttpMethod == HTTP_METHOD_POST {
		body = strings.NewReader(l.Params.Encode())
	}

	request, _ := http.NewRequest(l.HttpMethod, l.URL.String(), body)

	//Set Headers
	headers := l.GetAuthenticationHeaders()
	for header, value := range headers {
		request.Header.Set(header, value)
	}
	if l.HttpMethod == HTTP_METHOD_PUT || l.HttpMethod == HTTP_METHOD_POST {
		request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	}
	request.Header.Set("User-Agent", HTTP_USER_AGENT)

	return request
}
<|endoftext|>


<commit_before>package devtool

import (
	"context"
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
)

// DevToolsOption represents a function that sets a DevTools option.
type DevToolsOption func(*DevTools)

// WithClient returns a DevToolsOption that sets the http Client used
// for HTTP GET requests.
func WithClient(client *http.Client) DevToolsOption {
	return func(d *DevTools) {
		d.client = client
	}
}

// DevTools represents a devtools endpoint for managing and querying
// information about targets.
type DevTools struct {
	url    string
	client *http.Client
}

// New returns a DevTools instance that uses URL.
func New(url string, opts ...DevToolsOption) *DevTools {
	devtools := &DevTools{url: url}
	for _, o := range opts {
		o(devtools)
	}
	if devtools.client == nil {
		devtools.client = &http.Client{}
	}
	return devtools
}

// Type represents the type of Target.
type Type string

// Type enums.
const (
	BackgroundPage Type = "background_page"
	Node           Type = "node"
	Other          Type = "other"
	Page           Type = "page"
	ServiceWorker  Type = "service_worker"
)

// Target represents a devtools target, e.g. a browser tab.
type Target struct {
	Description          string `json:"description"`
	DevToolsFrontendURL  string `json:"devtoolsFrontendUrl"`
	ID                   string `json:"id"`
	Title                string `json:"title"`
	Type                 Type   `json:"type"`
	URL                  string `json:"url"`
	WebSocketDebuggerURL string `json:"webSocketDebuggerUrl"`
}

// Create a new Target, usually a page with about:blank as URL.
func (d *DevTools) Create(ctx context.Context) (*Target, error) {
	return d.CreateURL(ctx, "")
}

// CreateURL is like Create but opens the provided URL. The URL must be
// valid and begin with "http://" or "https://".
func (d *DevTools) CreateURL(ctx context.Context, openURL string) (*Target, error) {
	if openURL != "" {
		openURL = "?" + url.QueryEscape(openURL)
	}

	resp, err := d.httpGet(ctx, "/json/new"+openURL)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, parseError("target CreateURL", resp.Body)
	}

	t := new(Target)
	return t, json.NewDecoder(resp.Body).Decode(t)
}

// Get the first Target that matches Type.
func (d *DevTools) Get(ctx context.Context, typ Type) (*Target, error) {
	list, err := d.List(ctx)
	if err != nil {
		return nil, err
	}

	for _, t := range list {
		if t.Type == typ {
			return t, nil
		}
	}

	return nil, errors.New("target Get: could not find target of type: " + string(typ))
}

// List returns a list with all devtools Targets.
func (d *DevTools) List(ctx context.Context) ([]*Target, error) {
	resp, err := d.httpGet(ctx, "/json/list")
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, parseError("target List", resp.Body)
	}

	var t []*Target
	return t, json.NewDecoder(resp.Body).Decode(&t)
}

// Activate brings focus to the Target.
func (d *DevTools) Activate(ctx context.Context, t *Target) error {
	resp, err := d.httpGet(ctx, "/json/activate/"+string(t.ID))
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return parseError("target Activate", resp.Body)
	}

	return nil
}

// Close the Target.
func (d *DevTools) Close(ctx context.Context, t *Target) error {
	resp, err := d.httpGet(ctx, "/json/close/"+string(t.ID))
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return parseError("target Close", resp.Body)
	}

	return nil
}

// Version contains the version information for the DevTools endpoint.
type Version struct {
	// Present in Chrome, Edge, Node, etc.
	Browser  string `json:"Browser"`
	Protocol string `json:"Protocol-Version"`

	// Present in Chrome, Edge.
	UserAgent string `json:"User-Agent"`
	V8        string `json:"V8-Version"`
	WebKit    string `json:"WebKit-Version"`

	// Present on Android.
	AndroidPackage string `json:"Android-Package"`
}

// Version returns the version information for the DevTools endpoint.
func (d *DevTools) Version(ctx context.Context) (*Version, error) {
	resp, err := d.httpGet(ctx, "/json/version")
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, parseError("target Version", resp.Body)
	}

	v := new(Version)
	return v, json.NewDecoder(resp.Body).Decode(&v)
}

func (d *DevTools) httpGet(ctx context.Context, path string) (*http.Response, error) {
	if ctx == nil {
		ctx = context.Background()
	}

	req, err := http.NewRequest(http.MethodGet, d.url+path, nil)
	if err != nil {
		return nil, err
	}

	return d.client.Do(req.WithContext(ctx))
}

func parseError(from string, r io.Reader) error {
	m, err := ioutil.ReadAll(r)
	if err != nil {
		return err
	}
	return errors.New(from + ": " + string(m))
}
<commit_msg>devtool: Remove unnecessary conversion<commit_after>package devtool

import (
	"context"
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
)

// DevToolsOption represents a function that sets a DevTools option.
type DevToolsOption func(*DevTools)

// WithClient returns a DevToolsOption that sets the http Client used
// for HTTP GET requests.
func WithClient(client *http.Client) DevToolsOption {
	return func(d *DevTools) {
		d.client = client
	}
}

// DevTools represents a devtools endpoint for managing and querying
// information about targets.
type DevTools struct {
	url    string
	client *http.Client
}

// New returns a DevTools instance that uses URL.
func New(url string, opts ...DevToolsOption) *DevTools {
	devtools := &DevTools{url: url}
	for _, o := range opts {
		o(devtools)
	}
	if devtools.client == nil {
		devtools.client = &http.Client{}
	}
	return devtools
}

// Type represents the type of Target.
type Type string

// Type enums.
const (
	BackgroundPage Type = "background_page"
	Node           Type = "node"
	Other          Type = "other"
	Page           Type = "page"
	ServiceWorker  Type = "service_worker"
)

// Target represents a devtools target, e.g. a browser tab.
type Target struct {
	Description          string `json:"description"`
	DevToolsFrontendURL  string `json:"devtoolsFrontendUrl"`
	ID                   string `json:"id"`
	Title                string `json:"title"`
	Type                 Type   `json:"type"`
	URL                  string `json:"url"`
	WebSocketDebuggerURL string `json:"webSocketDebuggerUrl"`
}

// Create a new Target, usually a page with about:blank as URL.
func (d *DevTools) Create(ctx context.Context) (*Target, error) {
	return d.CreateURL(ctx, "")
}

// CreateURL is like Create but opens the provided URL. The URL must be
// valid and begin with "http://" or "https://".
func (d *DevTools) CreateURL(ctx context.Context, openURL string) (*Target, error) {
	if openURL != "" {
		openURL = "?" + url.QueryEscape(openURL)
	}

	resp, err := d.httpGet(ctx, "/json/new"+openURL)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, parseError("target CreateURL", resp.Body)
	}

	t := new(Target)
	return t, json.NewDecoder(resp.Body).Decode(t)
}

// Get the first Target that matches Type.
func (d *DevTools) Get(ctx context.Context, typ Type) (*Target, error) {
	list, err := d.List(ctx)
	if err != nil {
		return nil, err
	}

	for _, t := range list {
		if t.Type == typ {
			return t, nil
		}
	}

	return nil, errors.New("target Get: could not find target of type: " + string(typ))
}

// List returns a list with all devtools Targets.
func (d *DevTools) List(ctx context.Context) ([]*Target, error) {
	resp, err := d.httpGet(ctx, "/json/list")
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, parseError("target List", resp.Body)
	}

	var t []*Target
	return t, json.NewDecoder(resp.Body).Decode(&t)
}

// Activate brings focus to the Target.
func (d *DevTools) Activate(ctx context.Context, t *Target) error {
	resp, err := d.httpGet(ctx, "/json/activate/"+t.ID)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return parseError("target Activate", resp.Body)
	}

	return nil
}

// Close the Target.
func (d *DevTools) Close(ctx context.Context, t *Target) error {
	resp, err := d.httpGet(ctx, "/json/close/"+t.ID)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return parseError("target Close", resp.Body)
	}

	return nil
}

// Version contains the version information for the DevTools endpoint.
type Version struct {
	// Present in Chrome, Edge, Node, etc.
	Browser  string `json:"Browser"`
	Protocol string `json:"Protocol-Version"`

	// Present in Chrome, Edge.
	UserAgent string `json:"User-Agent"`
	V8        string `json:"V8-Version"`
	WebKit    string `json:"WebKit-Version"`

	// Present on Android.
	AndroidPackage string `json:"Android-Package"`
}

// Version returns the version information for the DevTools endpoint.
func (d *DevTools) Version(ctx context.Context) (*Version, error) {
	resp, err := d.httpGet(ctx, "/json/version")
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, parseError("target Version", resp.Body)
	}

	v := new(Version)
	return v, json.NewDecoder(resp.Body).Decode(&v)
}

func (d *DevTools) httpGet(ctx context.Context, path string) (*http.Response, error) {
	if ctx == nil {
		ctx = context.Background()
	}

	req, err := http.NewRequest(http.MethodGet, d.url+path, nil)
	if err != nil {
		return nil, err
	}

	return d.client.Do(req.WithContext(ctx))
}

func parseError(from string, r io.Reader) error {
	m, err := ioutil.ReadAll(r)
	if err != nil {
		return err
	}
	return errors.New(from + ": " + string(m))
}
<|endoftext|>


<commit_before>package diagram

import "fmt"

// Produces an arrow from origin to destination with the specified label
func LogMsg(origin string, dest string, label string) {
	fmt.Println("@|msg|" + origin + "|->|" + dest + "|" + label)
}

// Produces a title with the specfied label
func LogTitle(label string) {
	fmt.Println("@|title|" + label)
}

// Produces a state circle with the specfied color and label.
// color can be: "red", "green", "yellow"
func LogState(color string, node string, label string) {
	fmt.Println("@|state|" + color + "|" + node + "|" + label)
}

// Produces an information icon with a text tooltip
func LogInfo(node string, label string) {
	fmt.Println("@|info|" + node + "|" + label)
}

// Produces a table around a text of formated key:value pairs. Example: "A:23, B:45, C:63"
func LogTable(node string, tableText string) {
	fmt.Println("@|table|" + node + "|" + tableText)
}

// Skips some vertical space; useful for separating events in the diagram
func LogNext() {
	fmt.Println("@|next")
}<commit_msg>added PrintLogs bool to activate / deactivate logging<commit_after>package diagram

import "fmt"

var PrintLogs bool = true // change to "false" to stop printing log messages. Use this to activate and deactivate log messages.

// Produces an arrow from origin to destination with the specified label
func LogMsg(origin string, dest string, label string) {
	if (PrintLogs) {
		fmt.Println("@|msg|" + LogName(origin) + "|->|" + LogName(dest) + "|" + label)
	}
}

// Produces a title with the specfied label
func LogTitle(label string) {
	if (PrintLogs) {
		fmt.Println("@|title|" + label)
	}
}

// Produces a state circle with the specfied color and label.
// color can be: "red", "green", "yellow"
func LogState(color string, node string, label string) {
	if (PrintLogs) {
		fmt.Println("@|state|" + color + "|" + LogName(node) + "|" + label)
	}
}

// Produces an information icon with a text tooltip
func LogInfo(node string, label string) {
	if (PrintLogs) {
		fmt.Println("@|info|" + LogName(node) + "|" + label)
	}
}

// Produces a table around a text of formated key:value pairs. Example: "A:23, B:45, C:63"
func LogTable(node string, tableText string) {
	if (PrintLogs) {
		fmt.Println("@|table|" + LogName(node) + "|" + tableText)
	}
}

// Skips some vertical space; useful for separating events in the diagram
func LogNext() {
	if (PrintLogs) {
		fmt.Println("@|next")
	}
}

// Translates the full name of a node to an equivalent ID for the diagram.
// Modify this as needed for your project
func LogName(name string) string {
	switch (name) {
	case "vs":
		return "vs"
	case "ck":
		return "ck"
	}
	return "s" + fmt.Sprintf("%c", name[len(name) - 1])
}<|endoftext|>