<commit_before>//
// command/run.go
//
// Copyright (c) 2016-2017 Junpei Kawamoto
//
// This software is released under the MIT License.
//
// http://opensource.org/licenses/mit-license.php
//

package command

import (
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/signal"
	"path"
	"path/filepath"
	"strings"
	"sync"
	"syscall"

	colorable "github.com/mattn/go-colorable"
	gitconfig "github.com/tcnksm/go-gitconfig"
	"github.com/ttacon/chalk"
	"github.com/urfave/cli"
)

// SourceArchive defines a name of source archive file.
const SourceArchive = "source.tar.gz"

// RunOpt defines a option parameter for run function.
type RunOpt struct {
	// Same options as DockerfileOpt.
	*DockerfileOpt
	// Travis configuration file.
	Filename string
	// Container name.
	Name string
	// Runtime version to which only versions matching will be run.
	Version string
	// Image tag.
	Tag string
	// Max processors to be used.
	Processors int
	// If true, logging information to be stored to files.
	OutputLog bool
	// If true, not using cache during buidling a docker image.
	NoCache bool
	// If true, omit printing color codes.
	NoColor bool
	// Printed on the header.
	Title string
}

// Run implements the action of this command.
func Run(c *cli.Context) error {

	opt := RunOpt{
		DockerfileOpt: &DockerfileOpt{
			BaseImage:  c.String("base"),
			AptProxy:   c.String("apt-proxy"),
			PypiProxy:  c.String("pypi-proxy"),
			HTTPProxy:  c.String("http-proxy"),
			HTTPSProxy: c.String("https-proxy"),
			NoProxy:    c.String("no-proxy"),
		},
		Filename:   c.Args().First(),
		Name:       c.String("name"),
		Version:    c.String("select"),
		Tag:        c.String("tag"),
		Processors: c.Int("max-processors"),
		OutputLog:  c.Bool("log"),
		NoCache:    c.Bool("no-cache"),
		NoColor:    c.Bool("no-color"),
		Title:      fmt.Sprintf("%v %v", c.App.Name, c.App.Version),
	}
	if err := run(&opt); err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	return nil
}

func run(opt *RunOpt) (err error) {

	// Prepare to be canceled.
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	sig := make(chan os.Signal, 1)
	signal.Notify(sig, os.Interrupt, os.Kill, syscall.SIGQUIT)
	go func() {
		<-sig
		cancel()
	}()

	// Prepare interface.
	display, ctx, err := NewDisplay(ctx, opt.Title, opt.Processors)
	if err != nil {
		return
	}
	logger := display.Header.Logger

	var stdout io.Writer
	if opt.NoColor {
		stdout = colorable.NewNonColorable(os.Stdout)
		logger = colorable.NewNonColorable(logger)
		cli.ErrWriter = colorable.NewNonColorable(cli.ErrWriter)
	} else {
		stdout = colorable.NewColorableStdout()
	}

	// Load a Travis's script file.
	if opt.Filename == "" {
		opt.Filename = ".travis.yml"
	}
	fmt.Fprintln(logger, chalk.Yellow.Color("Loading .travis.yml"))

	travis, err := NewTravisFromFile(opt.Filename)
	if err != nil {
		return
	}

	// Get repository information.
	fmt.Fprintln(logger, chalk.Yellow.Color("Checking repository information"))
	origin, err := gitconfig.OriginURL()
	if err != nil {
		return
	}
	opt.Repository = getRepository(origin)

	// Set up the tag name of the container image.
	if opt.Tag == "" {
		opt.Tag = fmt.Sprintf("loci/%s", strings.ToLower(path.Base(opt.Repository)))
	}
	tempDir := filepath.Join(os.TempDir(), opt.Tag)
	if err = os.MkdirAll(tempDir, 0777); err != nil {
		return
	}
	defer os.RemoveAll(tempDir)

	// Prepare docker images.
	fmt.Fprintln(logger, chalk.Yellow.Color("Preparing docker images for sandbox containers"))
	err = PrepareBaseImage(ctx, opt.BaseImage, logger)
	if err != nil {
		return
	}

	// Archive source files.
	fmt.Fprintln(logger, chalk.Yellow.Color("Archiving source code"))
	pwd, err := os.Getwd()
	if err != nil {
		return
	}
	if err = Archive(ctx, pwd, filepath.Join(tempDir, SourceArchive), ioutil.Discard, os.Stderr); err != nil {
		// if err = Archive(ctx, pwd, filepath.Join(tempDir, SourceArchive), logger, os.Stderr); err != nil {
		return
	}

	// Create Dockerfile.
	fmt.Fprintln(logger, chalk.Yellow.Color("Creating Dockerfile"))
	docker, err := Dockerfile(travis, opt.DockerfileOpt, SourceArchive)
	if err != nil {
		return
	}
	if err = ioutil.WriteFile(filepath.Join(tempDir, "Dockerfile"), docker, 0644); err != nil {
		return
	}

	// Create entrypoint.sh.
	fmt.Fprintln(logger, chalk.Yellow.Color("Creating entrypoint.sh"))
	entry, err := Entrypoint(travis)
	if err != nil {
		return
	}
	if err = ioutil.WriteFile(filepath.Join(tempDir, "entrypoint.sh"), entry, 0644); err != nil {
		return
	}

	argset, err := travis.ArgumentSet(logger)
	if err != nil {
		return
	}

	// Start testing with goroutines.
	fmt.Fprintln(logger, chalk.Yellow.Color("Start testing"))
	var i int
	var wg sync.WaitGroup
	semaphore := make(chan struct{}, opt.Processors)
	errs := NewErrorSet()
	for version, set := range argset {

		if opt.Version != "" && version != opt.Version {
			continue
		}

		wg.Add(1)
		go func(version string, set [][]string) (err error) {
			semaphore <- struct{}{}
			defer func() {
				<-semaphore
				wg.Done()
			}()

			// Build a container image.
			sec := display.AddSection(fmt.Sprintf("Building a image for %v", version))
			defer display.DeleteSection(sec)

			var output io.Writer
			writer := sec.Writer()
			defer writer.Close()
			output = writer
			if opt.NoColor {
				output = colorable.NewNonColorable(output)
			}

			if opt.OutputLog {
				var fp *os.File
				fp, err = os.OpenFile(fmt.Sprintf("loci-build-%v.log", version), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
				if err != nil {
					errs.Add(version, err)
					return
				}
				defer fp.Close()
				output = io.MultiWriter(output, colorable.NewColorable(fp))
			}

			tag := fmt.Sprintf("%v/%v", opt.Tag, version)
			err = Build(ctx, tempDir, tag, version, opt.NoCache, output)
			if err == context.Canceled {
				errs.Add("", err)
				return
			} else if err != nil {
				msg := fmt.Sprintf(chalk.Red.Color("Faild to build a docker image for %v"), version)
				errs.Add(
					version,
					fmt.Errorf("%v\n%v", msg, err.Error()))
				fmt.Fprintln(logger, msg)
				return
			}
			fmt.Fprintln(logger, chalk.Green.Color(fmt.Sprintf("Built a image for %v", version)))

			for _, envs := range set {

				wg.Add(1)
				go func(envs []string) {
					semaphore <- struct{}{}
					defer func() {
						<-semaphore
						wg.Done()
					}()

					// Run tests in a sandbox.
					sec := display.AddSection(fmt.Sprintf("Running tests (%v: %v)", version, envs))
					defer display.DeleteSection(sec)

					var output io.Writer
					writer := sec.Writer()
					defer writer.Close()
					output = writer
					if opt.NoColor {
						output = colorable.NewNonColorable(output)
					}

					if opt.OutputLog {
						var fp *os.File
						fp, err = os.OpenFile(
							fmt.Sprintf("loci-%v.log", strings.Join(append([]string{version}, envs...), "-")),
							os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
						if err != nil {
							errs.Add(fmt.Sprintf("%v:%v", version, envs), err)
							return
						}
						defer fp.Close()
						output = io.MultiWriter(output, colorable.NewColorable(fp))
					}

					name := opt.Name
					if name != "" {
						i++
						name = fmt.Sprintf("%s-%d", name, i)
					}

					err = Start(ctx, tag, name, envs, output)
					if err == context.Canceled {
						errs.Add("", err)
					} else if err != nil {
						errs.Add(fmt.Sprintf("%v:%v", version, envs), fmt.Errorf("%s\n%s", chalk.Red.Color(err.Error()), sec.String()))
						fmt.Fprintln(logger, chalk.Red.Color(fmt.Sprintf("Failed tests (%v: %v) ", version, envs)))
					} else {
						fmt.Fprintln(logger, chalk.Green.Color(fmt.Sprintf("Passed tests (%v: %v) ", version, envs)))
					}
					return

				}(envs)

			}

			return

		}(version, set)

	}

	wg.Wait()
	display.Close()

	if errs.Size() == 0 {
		fmt.Fprintln(stdout, chalk.Green.Color("All tests have been passed."))
	} else {
		errList := errs.GetList()
		if errList[0] == context.Canceled {
			err = cli.NewExitError("canceled", 1)
		} else {
			err = cli.NewMultiError(errList...)
		}
	}
	return

}

// getRepository returns the repository path from a given remote URL of
// origin repository. The repository path consists of a URL without
// sheme, user name, password, and .git suffix.
func getRepository(origin string) (res string) {

	switch {
	case strings.Contains(origin, "@"):
		res = strings.Replace(strings.Split(origin, "@")[1], ":", "/", 1)
	case strings.HasPrefix(origin, "http://"):
		res = origin[len("http://"):]
	case strings.HasPrefix(origin, "https://"):
		res = origin[len("https://"):]
	default:
		res = strings.Replace(origin, ":", "/", 1)
	}
	if strings.HasSuffix(res, ".git") {
		res = res[:len(res)-len(".git")]
	}

	return

}
<commit_msg>Update colors of logging massages and print building logs when building images fails.<commit_after>//
// command/run.go
//
// Copyright (c) 2016-2017 Junpei Kawamoto
//
// This software is released under the MIT License.
//
// http://opensource.org/licenses/mit-license.php
//

package command

import (
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/signal"
	"path"
	"path/filepath"
	"strings"
	"sync"
	"syscall"

	colorable "github.com/mattn/go-colorable"
	gitconfig "github.com/tcnksm/go-gitconfig"
	"github.com/ttacon/chalk"
	"github.com/urfave/cli"
)

// SourceArchive defines a name of source archive file.
const SourceArchive = "source.tar.gz"

// RunOpt defines a option parameter for run function.
type RunOpt struct {
	// Same options as DockerfileOpt.
	*DockerfileOpt
	// Travis configuration file.
	Filename string
	// Container name.
	Name string
	// Runtime version to which only versions matching will be run.
	Version string
	// Image tag.
	Tag string
	// Max processors to be used.
	Processors int
	// If true, logging information to be stored to files.
	OutputLog bool
	// If true, not using cache during buidling a docker image.
	NoCache bool
	// If true, omit printing color codes.
	NoColor bool
	// Printed on the header.
	Title string
}

// Run implements the action of this command.
func Run(c *cli.Context) error {

	opt := RunOpt{
		DockerfileOpt: &DockerfileOpt{
			BaseImage:  c.String("base"),
			AptProxy:   c.String("apt-proxy"),
			PypiProxy:  c.String("pypi-proxy"),
			HTTPProxy:  c.String("http-proxy"),
			HTTPSProxy: c.String("https-proxy"),
			NoProxy:    c.String("no-proxy"),
		},
		Filename:   c.Args().First(),
		Name:       c.String("name"),
		Version:    c.String("select"),
		Tag:        c.String("tag"),
		Processors: c.Int("max-processors"),
		OutputLog:  c.Bool("log"),
		NoCache:    c.Bool("no-cache"),
		NoColor:    c.Bool("no-color"),
		Title:      fmt.Sprintf("%v %v", c.App.Name, c.App.Version),
	}
	if err := run(&opt); err != nil {
		return cli.NewExitError(err.Error(), 1)
	}
	return nil
}

func run(opt *RunOpt) (err error) {

	// Prepare to be canceled.
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	sig := make(chan os.Signal, 1)
	signal.Notify(sig, os.Interrupt, os.Kill, syscall.SIGQUIT)
	go func() {
		<-sig
		cancel()
	}()

	// Prepare interface.
	display, ctx, err := NewDisplay(ctx, opt.Title, opt.Processors)
	if err != nil {
		return
	}
	logger := display.Header.Logger

	var stdout io.Writer
	if opt.NoColor {
		stdout = colorable.NewNonColorable(os.Stdout)
		logger = colorable.NewNonColorable(logger)
		cli.ErrWriter = colorable.NewNonColorable(cli.ErrWriter)
	} else {
		stdout = colorable.NewColorableStdout()
	}

	// Load a Travis's script file.
	if opt.Filename == "" {
		opt.Filename = ".travis.yml"
	}
	fmt.Fprintln(logger, chalk.Cyan.Color("Loading .travis.yml"))

	travis, err := NewTravisFromFile(opt.Filename)
	if err != nil {
		return
	}

	// Get repository information.
	fmt.Fprintln(logger, chalk.Cyan.Color("Checking repository information"))
	origin, err := gitconfig.OriginURL()
	if err != nil {
		return
	}
	opt.Repository = getRepository(origin)

	// Set up the tag name of the container image.
	if opt.Tag == "" {
		opt.Tag = fmt.Sprintf("loci/%s", strings.ToLower(path.Base(opt.Repository)))
	}

	// Prepare docker images.
	fmt.Fprintln(logger, chalk.Cyan.Color("Preparing docker images for sandbox containers"))
	err = PrepareBaseImage(ctx, opt.BaseImage, logger)
	if err != nil {
		return
	}

	// Archive source files.
	fmt.Fprintln(logger, chalk.Cyan.Color("Archiving source code"))
	tempDir := filepath.Join(os.TempDir(), opt.Tag)
	if err = os.MkdirAll(tempDir, 0777); err != nil {
		return
	}
	defer os.RemoveAll(tempDir)
	pwd, err := os.Getwd()
	if err != nil {
		return
	}
	if err = Archive(ctx, pwd, filepath.Join(tempDir, SourceArchive), ioutil.Discard, os.Stderr); err != nil {
		// if err = Archive(ctx, pwd, filepath.Join(tempDir, SourceArchive), logger, os.Stderr); err != nil {
		return
	}

	// Create Dockerfile.
	fmt.Fprintln(logger, chalk.Cyan.Color("Creating Dockerfile"))
	docker, err := Dockerfile(travis, opt.DockerfileOpt, SourceArchive)
	if err != nil {
		return
	}
	if err = ioutil.WriteFile(filepath.Join(tempDir, "Dockerfile"), docker, 0644); err != nil {
		return
	}

	// Create entrypoint.sh.
	fmt.Fprintln(logger, chalk.Cyan.Color("Creating entrypoint.sh"))
	entry, err := Entrypoint(travis)
	if err != nil {
		return
	}
	if err = ioutil.WriteFile(filepath.Join(tempDir, "entrypoint.sh"), entry, 0644); err != nil {
		return
	}

	argset, err := travis.ArgumentSet(logger)
	if err != nil {
		return
	}

	// Start testing with goroutines.
	fmt.Fprintln(logger, chalk.Cyan.Color("Building sandbox images and running tests"))
	var i int
	var wg sync.WaitGroup
	semaphore := make(chan struct{}, opt.Processors)
	errs := NewErrorSet()
	for version, set := range argset {

		if opt.Version != "" && version != opt.Version {
			continue
		}

		wg.Add(1)
		go func(version string, set [][]string) (err error) {
			semaphore <- struct{}{}
			defer func() {
				<-semaphore
				wg.Done()
			}()

			// Build a container image.
			sec := display.AddSection(fmt.Sprintf("Building a image for %v", version))
			defer display.DeleteSection(sec)

			var output io.Writer
			writer := sec.Writer()
			defer writer.Close()
			output = writer
			if opt.NoColor {
				output = colorable.NewNonColorable(output)
			}

			if opt.OutputLog {
				var fp *os.File
				fp, err = os.OpenFile(fmt.Sprintf("loci-build-%v.log", version), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
				if err != nil {
					errs.Add(version, err)
					return
				}
				defer fp.Close()
				output = io.MultiWriter(output, colorable.NewColorable(fp))
			}

			tag := fmt.Sprintf("%v/%v", opt.Tag, version)
			err = Build(ctx, tempDir, tag, version, opt.NoCache, output)
			if err == context.Canceled {
				errs.Add("", err)
				return
			} else if err != nil {
				msg := fmt.Sprintf(chalk.Red.Color("Faild to build a docker image for %v"), version)
				errs.Add(
					version,
					fmt.Errorf("%v\n%v\n%v\n", msg, err.Error(), sec.String()))
				fmt.Fprintln(logger, msg)
				return
			}
			fmt.Fprintln(logger, chalk.Green.Color(fmt.Sprintf("Built a image for %v", version)))

			for _, envs := range set {

				wg.Add(1)
				go func(envs []string) {
					semaphore <- struct{}{}
					defer func() {
						<-semaphore
						wg.Done()
					}()

					// Run tests in a sandbox.
					sec := display.AddSection(fmt.Sprintf("Running tests (%v: %v)", version, envs))
					defer display.DeleteSection(sec)

					var output io.Writer
					writer := sec.Writer()
					defer writer.Close()
					output = writer
					if opt.NoColor {
						output = colorable.NewNonColorable(output)
					}

					if opt.OutputLog {
						var fp *os.File
						fp, err = os.OpenFile(
							fmt.Sprintf("loci-%v.log", strings.Join(append([]string{version}, envs...), "-")),
							os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
						if err != nil {
							errs.Add(fmt.Sprintf("%v:%v", version, envs), err)
							return
						}
						defer fp.Close()
						output = io.MultiWriter(output, colorable.NewColorable(fp))
					}

					name := opt.Name
					if name != "" {
						i++
						name = fmt.Sprintf("%s-%d", name, i)
					}

					err = Start(ctx, tag, name, envs, output)
					if err == context.Canceled {
						errs.Add("", err)
					} else if err != nil {
						errs.Add(fmt.Sprintf("%v:%v", version, envs), fmt.Errorf("%s\n%s", chalk.Red.Color(err.Error()), sec.String()))
						fmt.Fprintln(logger, chalk.Red.Color(fmt.Sprintf("Failed tests (%v: %v) ", version, envs)))
					} else {
						fmt.Fprintln(logger, chalk.Green.Color(fmt.Sprintf("Passed tests (%v: %v) ", version, envs)))
					}
					return

				}(envs)

			}

			return

		}(version, set)

	}

	wg.Wait()
	display.Close()

	if errs.Size() == 0 {
		fmt.Fprintln(stdout, chalk.Green.Color("All tests have been passed."))
	} else {
		errList := errs.GetList()
		if errList[0] == context.Canceled {
			err = cli.NewExitError("canceled", 1)
		} else {
			err = cli.NewMultiError(errList...)
		}
	}
	return

}

// getRepository returns the repository path from a given remote URL of
// origin repository. The repository path consists of a URL without
// sheme, user name, password, and .git suffix.
func getRepository(origin string) (res string) {

	switch {
	case strings.Contains(origin, "@"):
		res = strings.Replace(strings.Split(origin, "@")[1], ":", "/", 1)
	case strings.HasPrefix(origin, "http://"):
		res = origin[len("http://"):]
	case strings.HasPrefix(origin, "https://"):
		res = origin[len("https://"):]
	default:
		res = strings.Replace(origin, ":", "/", 1)
	}
	if strings.HasSuffix(res, ".git") {
		res = res[:len(res)-len(".git")]
	}

	return

}
<|endoftext|>


<commit_before>// This file contains version specific, and usage information for
// the wol application
package main

import (
    "fmt"
    "github.com/sabhiram/colorize"
)

// Version represents the current Semantic Version of this application
const Version = "1.0.0"

// List of options which chloe supports
var ValidOptions = [] struct {
    short, long, description string
} {
    { `v`, `version`, `prints the application version`   },
    { `h`, `help`,    `prints this help menu`            },
    { `p`, `port`,    `udp port to send bcast packet to` },
    { `b`, `bcast`,   `broadcast IP to send packet to`   },
}

// Usage string for wol
var UsageString = `Usage:

    <cyan>wol</cyan> [<options>] [mac address]

Options:

%s

Specifying MAC addresses:
-------------------------
The following MAC addresses are valid and will match:
01-23-45-56-67-89, 89:AB:CD:EF:00:12, 89:ab:cd:ef:00:12

The supported delimiters include ":" and "-"

Version:

    <white>%s</white>

`
// Returns a tuple of commands and options which we support
func getAllOptions() string {
    options := ""
    for _, o := range ValidOptions {
        options += fmt.Sprintf("    <yellow>-%s --%-8s</yellow>    %s\n", o.short, o.long, o.description)
    }
    return options
}

// Returns the Usage string for this application
func getAppUsageString() string {
    options := getAllOptions()
    return colorize.Colorize(fmt.Sprintf(UsageString, options, Version))
}

<commit_msg>Update import due to changed repo name (colorize -> go-colorize)<commit_after>// This file contains version specific, and usage information for
// the wol application
package main

import (
    "fmt"
    "github.com/sabhiram/go-colorize"
)

// Version represents the current Semantic Version of this application
const Version = "1.0.0"

// List of options which chloe supports
var ValidOptions = [] struct {
    short, long, description string
} {
    { `v`, `version`, `prints the application version`   },
    { `h`, `help`,    `prints this help menu`            },
    { `p`, `port`,    `udp port to send bcast packet to` },
    { `b`, `bcast`,   `broadcast IP to send packet to`   },
}

// Usage string for wol
var UsageString = `Usage:

    <cyan>wol</cyan> [<options>] [mac address]

Options:

%s

Specifying MAC addresses:
-------------------------
The following MAC addresses are valid and will match:
01-23-45-56-67-89, 89:AB:CD:EF:00:12, 89:ab:cd:ef:00:12

The supported delimiters include ":" and "-"

Version:

    <white>%s</white>

`
// Returns a tuple of commands and options which we support
func getAllOptions() string {
    options := ""
    for _, o := range ValidOptions {
        options += fmt.Sprintf("    <yellow>-%s --%-8s</yellow>    %s\n", o.short, o.long, o.description)
    }
    return options
}

// Returns the Usage string for this application
func getAppUsageString() string {
    options := getAllOptions()
    return colorize.Colorize(fmt.Sprintf(UsageString, options, Version))
}

<|endoftext|>


<commit_before>package appui

import (
	"github.com/docker/engine-api/types"
	termui "github.com/gizak/termui"
	"github.com/moncho/dry/docker"
)

//ContainerCommandList is a Bufferer holding the list of container commands
type ContainerCommandList struct {
	List     *termui.List
	Commands []string
}

//NewContainerCommands creates a Bufferer with the list of container commands
func NewContainerCommands(container types.Container, x, y, height, width int) *ContainerCommandList {
	l := termui.NewList()

	//shortID := docker.TruncateID(container.ID)
	commandsLen := len(docker.CommandDescriptions)
	commands := make([]string, commandsLen)
	l.Items = commands
	l.Border = false
	//l.BorderLabel =
	//	fmt.Sprintf(" %s - %s ", container.Names[0], shortID)
	l.BorderFg = termui.ColorBlue
	l.Height = len(commands) + 4 // 2 because of the top+bottom padding, 2 because of the borders
	l.Width = width / 2
	l.PaddingTop = 1
	l.PaddingBottom = 1
	l.PaddingLeft = 2
	l.X = x
	l.Y = y

	return &ContainerCommandList{l, commands}
}
<commit_msg>Minor<commit_after>package appui

import (
	"github.com/docker/engine-api/types"
	termui "github.com/gizak/termui"
	"github.com/moncho/dry/docker"
)

//ContainerCommandList is a Bufferer holding the list of container commands
type ContainerCommandList struct {
	List     *termui.List
	Commands []string
}

//NewContainerCommands creates a Bufferer with the list of container commands
func NewContainerCommands(container types.Container, x, y, height, width int) *ContainerCommandList {
	l := termui.NewList()

	commandsLen := len(docker.CommandDescriptions)
	commands := make([]string, commandsLen)
	l.Items = commands
	l.Border = false
	l.BorderFg = termui.ColorBlue
	l.Height = len(commands) + 4 // 2 because of the top+bottom padding, 2 because of the borders
	l.Width = width / 2
	l.PaddingTop = 1
	l.PaddingBottom = 1
	l.PaddingLeft = 2
	l.X = x
	l.Y = y

	return &ContainerCommandList{l, commands}
}
<|endoftext|>


<commit_before>package drivers

import (
	"text/template"
)

// Base config. This is common for all VMs and has no variables in it.
var qemuBase = template.Must(template.New("qemuBase").Parse(`
# Machine
[machine]
graphics = "off"
{{if eq .architecture "x86_64" -}}
type = "q35"
{{end -}}
{{if eq .architecture "aarch64" -}}
type = "virt"
{{end -}}
{{if eq .architecture "ppc64le" -}}
type = "pseries"
{{end -}}
accel = "kvm"
usb = "off"
graphics = "off"

{{if eq .architecture "x86_64" -}}
[global]
driver = "ICH9-LPC"
property = "disable_s3"
value = "1"

[global]
driver = "ICH9-LPC"
property = "disable_s4"
value = "1"
{{end -}}

[boot-opts]
strict = "on"

# LXD serial identifier
[device]
driver = "virtio-serial"

[device]
driver = "virtserialport"
name = "org.linuxcontainers.lxd"
chardev = "vserial"

[chardev "vserial"]
backend = "ringbuf"
size = "{{.ringbufSizeBytes}}B"

# SCSI controller
{{if ne .architecture "ppc64le" -}}
[device "qemu_pcie1"]
driver = "pcie-root-port"
port = "0x10"
chassis = "1"
bus = "pcie.0"
multifunction = "on"
addr = "0x2"
{{- end }}

[device "qemu_scsi"]
driver = "virtio-scsi-pci"
{{if eq .architecture "ppc64le" -}}
bus = "pci.0"
{{else -}}
bus = "qemu_pcie1"
addr = "0x0"
{{end -}}

# Balloon driver
{{if ne .architecture "ppc64le" -}}
[device "qemu_pcie2"]
driver = "pcie-root-port"
port = "0x11"
chassis = "2"
bus = "pcie.0"
addr = "0x2.0x1"
{{- end }}

[device "qemu_ballon"]
driver = "virtio-balloon-pci"
{{if eq .architecture "ppc64le" -}}
bus = "pci.0"
{{else -}}
bus = "qemu_pcie2"
addr = "0x0"
{{end -}}

# Random number generator
[object "qemu_rng"]
qom-type = "rng-random"
filename = "/dev/urandom"

{{if ne .architecture "ppc64le" -}}
[device "qemu_pcie3"]
driver = "pcie-root-port"
port = "0x12"
chassis = "3"
bus = "pcie.0"
addr = "0x2.0x2"
{{- end }}

[device "dev-qemu_rng"]
driver = "virtio-rng-pci"
rng = "qemu_rng"
{{if eq .architecture "ppc64le" -}}
bus = "pci.0"
{{else -}}
bus = "qemu_pcie3"
addr = "0x0"
{{end -}}

# Console
[chardev "console"]
backend = "pty"
`))

var qemuMemory = template.Must(template.New("qemuMemory").Parse(`
# Memory
[memory]
size = "{{.memSizeBytes}}B"
`))

var qemuVsock = template.Must(template.New("qemuVsock").Parse(`
# Vsock
{{if ne .architecture "ppc64le" -}}
[device "qemu_pcie4"]
driver = "pcie-root-port"
port = "0x13"
chassis = "4"
bus = "pcie.0"
addr = "0x2.0x3"
{{- end }}

[device]
driver = "vhost-vsock-pci"
guest-cid = "{{.vsockID}}"
{{if eq .architecture "ppc64le" -}}
bus = "pci.0"
{{else -}}
bus = "qemu_pcie4"
addr = "0x0"
{{end -}}
`))

var qemuCPU = template.Must(template.New("qemuCPU").Parse(`
# CPU
[smp-opts]
cpus = "{{.cpuCount}}"
sockets = "{{.cpuSockets}}"
cores = "{{.cpuCores}}"
threads = "{{.cpuThreads}}"
`))

var qemuControlSocket = template.Must(template.New("qemuControlSocket").Parse(`
# Qemu control
[chardev "monitor"]
backend = "socket"
path = "{{.path}}"
server = "on"
wait = "off"

[mon]
chardev = "monitor"
mode = "control"
`))

var qemuDriveFirmware = template.Must(template.New("qemuDriveFirmware").Parse(`
# Firmware (read only)
[drive]
file = "{{.roPath}}"
if = "pflash"
format = "raw"
unit = "0"
readonly = "on"

# Firmware settings (writable)
[drive]
file = "{{.nvramPath}}"
if = "pflash"
format = "raw"
unit = "1"
`))

// Devices use "qemu_" prefix indicating that this is a internally named device.
var qemuDriveConfig = template.Must(template.New("qemuDriveConfig").Parse(`
# Config drive
[fsdev "qemu_config"]
fsdriver = "local"
security_model = "none"
readonly = "on"
path = "{{.path}}"

[device "dev-qemu_config"]
driver = "virtio-9p-pci"
fsdev = "qemu_config"
mount_tag = "config"
`))

// Devices use "lxd_" prefix indicating that this is a internally named device.
var qemuDriveDir = template.Must(template.New("qemuDriveDir").Parse(`
# {{.devName}} drive
[fsdev "lxd_{{.devName}}"]
{{- if .readonly}}
readonly = "on"
fsdriver = "local"
security_model = "none"
path = "{{.path}}"
{{- else}}
readonly = "off"
fsdriver = "proxy"
sock_fd = "{{.proxyFD}}"
{{- end}}

[device "dev-lxd_{{.devName}}"]
driver = "virtio-9p-pci"
fsdev = "lxd_{{.devName}}"
mount_tag = "{{.mountTag}}"
`))

// Devices use "lxd_" prefix indicating that this is a user named device.
var qemuDrive = template.Must(template.New("qemuDrive").Parse(`
# {{.devName}} drive
[drive "lxd_{{.devName}}"]
file = "{{.devPath}}"
format = "raw"
if = "none"
cache = "{{.cacheMode}}"
aio = "{{.aioMode}}"
discard = "on"

[device "dev-lxd_{{.devName}}"]
driver = "scsi-hd"
bus = "qemu_scsi.0"
channel = "0"
scsi-id = "{{.bootIndex}}"
lun = "1"
drive = "lxd_{{.devName}}"
bootindex = "{{.bootIndex}}"
`))

// qemuDevTapCommon is common PCI device template for tap based netdevs.
var qemuDevTapCommon = template.Must(template.New("qemuDevTapCommon").Parse(`
{{if ne .architecture "ppc64le" -}}
[device "qemu_pcie{{.chassisIndex}}"]
driver = "pcie-root-port"
port = "0x{{.portIndex}}"
chassis = "{{.chassisIndex}}"
bus = "pcie.0"
addr = "0x2.0x{{.pcieAddr}}"
{{- end }}

[device "dev-lxd_{{.devName}}"]
driver = "virtio-net-pci"
netdev = "lxd_{{.devName}}"
mac = "{{.devHwaddr}}"
{{if eq .architecture "ppc64le" -}}
bus = "pci.0"
{{else -}}
bus = "qemu_pcie{{.chassisIndex}}"
addr = "0x0"
{{end -}}
bootindex = "{{.bootIndex}}"
`))

// Devices use "lxd_" prefix indicating that this is a user named device.
var qemuNetDevTapTun = template.Must(qemuDevTapCommon.New("qemuNetDevTapTun").Parse(`
# Network card ("{{.devName}}" device)
[netdev "lxd_{{.devName}}"]
type = "tap"
vhost = "on"
ifname = "{{.ifName}}"
script = "no"
downscript = "no"
{{ template "qemuDevTapCommon" . -}}
`))

// Devices use "lxd_" prefix indicating that this is a user named device.
var qemuNetdevTapFD = template.Must(qemuDevTapCommon.New("qemuNetdevTapFD").Parse(`
# Network card ("{{.devName}}" device)
[netdev "lxd_{{.devName}}"]
type = "tap"
vhost = "on"
fd = "{{.tapFD}}"
{{ template "qemuDevTapCommon" . -}}
`))

// Devices use "lxd_" prefix indicating that this is a user named device.
var qemuNetdevPhysical = template.Must(template.New("qemuNetdevPhysical").Parse(`
# Network card ("{{.devName}}" device)
[device "dev-lxd_{{.devName}}"]
driver = "vfio-pci"
host = "{{.pciSlotName}}"
bootindex = "{{.bootIndex}}"
`))
<commit_msg>lxd/instance/drivers/driver/qemu: Tweaks template whitespace removal to leave newline between sections<commit_after>package drivers

import (
	"text/template"
)

// Base config. This is common for all VMs and has no variables in it.
var qemuBase = template.Must(template.New("qemuBase").Parse(`
# Machine
[machine]
graphics = "off"
{{if eq .architecture "x86_64" -}}
type = "q35"
{{end -}}
{{if eq .architecture "aarch64" -}}
type = "virt"
{{end -}}
{{if eq .architecture "ppc64le" -}}
type = "pseries"
{{end -}}
accel = "kvm"
usb = "off"
graphics = "off"

{{if eq .architecture "x86_64" -}}
[global]
driver = "ICH9-LPC"
property = "disable_s3"
value = "1"

[global]
driver = "ICH9-LPC"
property = "disable_s4"
value = "1"
{{end -}}

[boot-opts]
strict = "on"

# LXD serial identifier
[device]
driver = "virtio-serial"

[device]
driver = "virtserialport"
name = "org.linuxcontainers.lxd"
chardev = "vserial"

[chardev "vserial"]
backend = "ringbuf"
size = "{{.ringbufSizeBytes}}B"

# SCSI controller
{{- if ne .architecture "ppc64le"}}
[device "qemu_pcie1"]
driver = "pcie-root-port"
port = "0x10"
chassis = "1"
bus = "pcie.0"
multifunction = "on"
addr = "0x2"
{{- end }}

[device "qemu_scsi"]
driver = "virtio-scsi-pci"
{{- if eq .architecture "ppc64le"}}
bus = "pci.0"
{{- else}}
bus = "qemu_pcie1"
addr = "0x0"
{{- end}}

# Balloon driver
{{- if ne .architecture "ppc64le"}}
[device "qemu_pcie2"]
driver = "pcie-root-port"
port = "0x11"
chassis = "2"
bus = "pcie.0"
addr = "0x2.0x1"
{{- end }}

[device "qemu_ballon"]
driver = "virtio-balloon-pci"
{{- if eq .architecture "ppc64le"}}
bus = "pci.0"
{{- else}}
bus = "qemu_pcie2"
addr = "0x0"
{{- end}}

# Random number generator
[object "qemu_rng"]
qom-type = "rng-random"
filename = "/dev/urandom"

{{if ne .architecture "ppc64le" -}}
[device "qemu_pcie3"]
driver = "pcie-root-port"
port = "0x12"
chassis = "3"
bus = "pcie.0"
addr = "0x2.0x2"
{{- end }}

[device "dev-qemu_rng"]
driver = "virtio-rng-pci"
rng = "qemu_rng"
{{- if eq .architecture "ppc64le"}}
bus = "pci.0"
{{- else}}
bus = "qemu_pcie3"
addr = "0x0"
{{- end}}

# Console
[chardev "console"]
backend = "pty"
`))

var qemuMemory = template.Must(template.New("qemuMemory").Parse(`
# Memory
[memory]
size = "{{.memSizeBytes}}B"
`))

var qemuVsock = template.Must(template.New("qemuVsock").Parse(`
# Vsock
{{if ne .architecture "ppc64le" -}}
[device "qemu_pcie4"]
driver = "pcie-root-port"
port = "0x13"
chassis = "4"
bus = "pcie.0"
addr = "0x2.0x3"
{{- end }}

[device]
driver = "vhost-vsock-pci"
guest-cid = "{{.vsockID}}"
{{if eq .architecture "ppc64le" -}}
bus = "pci.0"
{{else -}}
bus = "qemu_pcie4"
addr = "0x0"
{{end -}}
`))

var qemuCPU = template.Must(template.New("qemuCPU").Parse(`
# CPU
[smp-opts]
cpus = "{{.cpuCount}}"
sockets = "{{.cpuSockets}}"
cores = "{{.cpuCores}}"
threads = "{{.cpuThreads}}"
`))

var qemuControlSocket = template.Must(template.New("qemuControlSocket").Parse(`
# Qemu control
[chardev "monitor"]
backend = "socket"
path = "{{.path}}"
server = "on"
wait = "off"

[mon]
chardev = "monitor"
mode = "control"
`))

var qemuDriveFirmware = template.Must(template.New("qemuDriveFirmware").Parse(`
# Firmware (read only)
[drive]
file = "{{.roPath}}"
if = "pflash"
format = "raw"
unit = "0"
readonly = "on"

# Firmware settings (writable)
[drive]
file = "{{.nvramPath}}"
if = "pflash"
format = "raw"
unit = "1"
`))

// Devices use "qemu_" prefix indicating that this is a internally named device.
var qemuDriveConfig = template.Must(template.New("qemuDriveConfig").Parse(`
# Config drive
[fsdev "qemu_config"]
fsdriver = "local"
security_model = "none"
readonly = "on"
path = "{{.path}}"

[device "dev-qemu_config"]
driver = "virtio-9p-pci"
fsdev = "qemu_config"
mount_tag = "config"
`))

// Devices use "lxd_" prefix indicating that this is a internally named device.
var qemuDriveDir = template.Must(template.New("qemuDriveDir").Parse(`
# {{.devName}} drive
[fsdev "lxd_{{.devName}}"]
{{- if .readonly}}
readonly = "on"
fsdriver = "local"
security_model = "none"
path = "{{.path}}"
{{- else}}
readonly = "off"
fsdriver = "proxy"
sock_fd = "{{.proxyFD}}"
{{- end}}

[device "dev-lxd_{{.devName}}"]
driver = "virtio-9p-pci"
fsdev = "lxd_{{.devName}}"
mount_tag = "{{.mountTag}}"
`))

// Devices use "lxd_" prefix indicating that this is a user named device.
var qemuDrive = template.Must(template.New("qemuDrive").Parse(`
# {{.devName}} drive
[drive "lxd_{{.devName}}"]
file = "{{.devPath}}"
format = "raw"
if = "none"
cache = "{{.cacheMode}}"
aio = "{{.aioMode}}"
discard = "on"

[device "dev-lxd_{{.devName}}"]
driver = "scsi-hd"
bus = "qemu_scsi.0"
channel = "0"
scsi-id = "{{.bootIndex}}"
lun = "1"
drive = "lxd_{{.devName}}"
bootindex = "{{.bootIndex}}"
`))

// qemuDevTapCommon is common PCI device template for tap based netdevs.
var qemuDevTapCommon = template.Must(template.New("qemuDevTapCommon").Parse(`
{{if ne .architecture "ppc64le" -}}
[device "qemu_pcie{{.chassisIndex}}"]
driver = "pcie-root-port"
port = "0x{{.portIndex}}"
chassis = "{{.chassisIndex}}"
bus = "pcie.0"
addr = "0x2.0x{{.pcieAddr}}"
{{- end }}

[device "dev-lxd_{{.devName}}"]
driver = "virtio-net-pci"
netdev = "lxd_{{.devName}}"
mac = "{{.devHwaddr}}"
{{if eq .architecture "ppc64le" -}}
bus = "pci.0"
{{else -}}
bus = "qemu_pcie{{.chassisIndex}}"
addr = "0x0"
{{end -}}
bootindex = "{{.bootIndex}}"
`))

// Devices use "lxd_" prefix indicating that this is a user named device.
var qemuNetDevTapTun = template.Must(qemuDevTapCommon.New("qemuNetDevTapTun").Parse(`
# Network card ("{{.devName}}" device)
[netdev "lxd_{{.devName}}"]
type = "tap"
vhost = "on"
ifname = "{{.ifName}}"
script = "no"
downscript = "no"
{{ template "qemuDevTapCommon" . -}}
`))

// Devices use "lxd_" prefix indicating that this is a user named device.
var qemuNetdevTapFD = template.Must(qemuDevTapCommon.New("qemuNetdevTapFD").Parse(`
# Network card ("{{.devName}}" device)
[netdev "lxd_{{.devName}}"]
type = "tap"
vhost = "on"
fd = "{{.tapFD}}"
{{ template "qemuDevTapCommon" . -}}
`))

// Devices use "lxd_" prefix indicating that this is a user named device.
var qemuNetdevPhysical = template.Must(template.New("qemuNetdevPhysical").Parse(`
# Network card ("{{.devName}}" device)
[device "dev-lxd_{{.devName}}"]
driver = "vfio-pci"
host = "{{.pciSlotName}}"
bootindex = "{{.bootIndex}}"
`))
<|endoftext|>


<commit_before>package provider

import (
	"fmt"
	"regexp"
	"testing"

	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

type customLens struct {
	customLen int
}

func TestAccResourceString(t *testing.T) {
	resource.UnitTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
		Providers: testAccProviders,
		Steps: []resource.TestStep{
			{
				Config: testAccResourceStringConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccResourceStringCheck("random_string.foo", &customLens{
						customLen: 12,
					}),
					testAccResourceStringCheck("random_string.bar", &customLens{
						customLen: 32,
					}),
					testAccResourceStringCheck("random_string.three", &customLens{
						customLen: 4,
					}),
					patternMatch("random_string.three", "!!!!"),
					testAccResourceStringCheck("random_string.min", &customLens{
						customLen: 12,
					}),
					regexMatch("random_string.min", regexp.MustCompile(`([a-z])`), 2),
					regexMatch("random_string.min", regexp.MustCompile(`([A-Z])`), 3),
					regexMatch("random_string.min", regexp.MustCompile(`([0-9])`), 4),
					regexMatch("random_string.min", regexp.MustCompile(`([!#@])`), 1),
				),
			},
			{
				ResourceName:            "random_string.foo",
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"length", "lower", "number", "special", "upper", "min_lower", "min_numeric", "min_special", "min_upper", "override_special"},
			},
			{
				ResourceName:            "random_string.bar",
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"length", "lower", "number", "special", "upper", "min_lower", "min_numeric", "min_special", "min_upper", "override_special"},
			},
			{
				ResourceName:            "random_string.three",
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"length", "lower", "number", "special", "upper", "min_lower", "min_numeric", "min_special", "min_upper", "override_special"},
			},
			{
				ResourceName:            "random_string.min",
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"length", "lower", "number", "special", "upper", "min_lower", "min_numeric", "min_special", "min_upper", "override_special"},
			},
			{
				Config:      testAccResourceStringInvalidConfig,
				ExpectError: regexp.MustCompile("Error running apply: exit status 1"),
			},
			{
				Config:      testAccResourceStringLengthTooShortConfig,
				ExpectError: regexp.MustCompile("Error running apply: exit status 1"),
			},
		},
	})
}

func testAccResourceStringCheck(id string, want *customLens) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[id]
		if !ok {
			return fmt.Errorf("Not found: %s", id)
		}
		if rs.Primary.ID == "" {
			return fmt.Errorf("No ID is set")
		}

		customStr := rs.Primary.Attributes["result"]

		if got, want := len(customStr), want.customLen; got != want {
			return fmt.Errorf("custom string length is %d; want %d", got, want)
		}

		return nil
	}
}

func regexMatch(id string, exp *regexp.Regexp, requiredMatches int) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[id]
		if !ok {
			return fmt.Errorf("Not found: %s", id)
		}
		if rs.Primary.ID == "" {
			return fmt.Errorf("No ID is set")
		}

		customStr := rs.Primary.Attributes["result"]

		if matches := exp.FindAllStringSubmatchIndex(customStr, -1); len(matches) < requiredMatches {
			return fmt.Errorf("custom string is %s; did not match %s", customStr, exp)
		}

		return nil
	}
}
func patternMatch(id string, want string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[id]
		if !ok {
			return fmt.Errorf("Not found: %s", id)
		}
		if rs.Primary.ID == "" {
			return fmt.Errorf("No ID is set")
		}
		customStr := rs.Primary.Attributes["result"]

		if got, want := customStr, want; got != want {
			return fmt.Errorf("custom string is %s; want %s", got, want)
		}

		return nil
	}
}

const (
	testAccResourceStringConfig = `
resource "random_string" "foo" {
  length = 12
}

resource "random_string" "bar" {
  length = 32
}

resource "random_string" "three" {
  length = 4
  override_special = "!"
  lower = false
  upper = false
  number = false
}

resource "random_string" "min" {
  length = 12
  override_special = "!#@"
  min_lower = 2
  min_upper = 3
  min_special = 1
  min_numeric = 4
}
`
	testAccResourceStringInvalidConfig = `
resource "random_string" "invalid_length" {
  length = 2
  min_lower = 3
}`
	testAccResourceStringLengthTooShortConfig = `
resource "random_string" "invalid_length" {
  length = 0
}`
)
<commit_msg>Modifying regex to match significant text in error message<commit_after>package provider

import (
	"fmt"
	"regexp"
	"testing"

	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

type customLens struct {
	customLen int
}

func TestAccResourceString(t *testing.T) {
	resource.UnitTest(t, resource.TestCase{
		PreCheck:  func() { testAccPreCheck(t) },
		Providers: testAccProviders,
		Steps: []resource.TestStep{
			{
				Config: testAccResourceStringConfig,
				Check: resource.ComposeTestCheckFunc(
					testAccResourceStringCheck("random_string.foo", &customLens{
						customLen: 12,
					}),
					testAccResourceStringCheck("random_string.bar", &customLens{
						customLen: 32,
					}),
					testAccResourceStringCheck("random_string.three", &customLens{
						customLen: 4,
					}),
					patternMatch("random_string.three", "!!!!"),
					testAccResourceStringCheck("random_string.min", &customLens{
						customLen: 12,
					}),
					regexMatch("random_string.min", regexp.MustCompile(`([a-z])`), 2),
					regexMatch("random_string.min", regexp.MustCompile(`([A-Z])`), 3),
					regexMatch("random_string.min", regexp.MustCompile(`([0-9])`), 4),
					regexMatch("random_string.min", regexp.MustCompile(`([!#@])`), 1),
				),
			},
			{
				ResourceName:            "random_string.foo",
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"length", "lower", "number", "special", "upper", "min_lower", "min_numeric", "min_special", "min_upper", "override_special"},
			},
			{
				ResourceName:            "random_string.bar",
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"length", "lower", "number", "special", "upper", "min_lower", "min_numeric", "min_special", "min_upper", "override_special"},
			},
			{
				ResourceName:            "random_string.three",
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"length", "lower", "number", "special", "upper", "min_lower", "min_numeric", "min_special", "min_upper", "override_special"},
			},
			{
				ResourceName:            "random_string.min",
				ImportState:             true,
				ImportStateVerify:       true,
				ImportStateVerifyIgnore: []string{"length", "lower", "number", "special", "upper", "min_lower", "min_numeric", "min_special", "min_upper", "override_special"},
			},
			{
				Config:      testAccResourceStringInvalidConfig,
				ExpectError: regexp.MustCompile(`.+?length \(2\) must be >= min_upper \+ min_lower \+ min_numeric \+ min_special \(3\)`),
			},
			{
				Config:      testAccResourceStringLengthTooShortConfig,
				ExpectError: regexp.MustCompile(`.+?length \(0\) must be >= 1`),
			},
		},
	})
}

func testAccResourceStringCheck(id string, want *customLens) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[id]
		if !ok {
			return fmt.Errorf("Not found: %s", id)
		}
		if rs.Primary.ID == "" {
			return fmt.Errorf("No ID is set")
		}

		customStr := rs.Primary.Attributes["result"]

		if got, want := len(customStr), want.customLen; got != want {
			return fmt.Errorf("custom string length is %d; want %d", got, want)
		}

		return nil
	}
}

func regexMatch(id string, exp *regexp.Regexp, requiredMatches int) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[id]
		if !ok {
			return fmt.Errorf("Not found: %s", id)
		}
		if rs.Primary.ID == "" {
			return fmt.Errorf("No ID is set")
		}

		customStr := rs.Primary.Attributes["result"]

		if matches := exp.FindAllStringSubmatchIndex(customStr, -1); len(matches) < requiredMatches {
			return fmt.Errorf("custom string is %s; did not match %s", customStr, exp)
		}

		return nil
	}
}
func patternMatch(id string, want string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[id]
		if !ok {
			return fmt.Errorf("Not found: %s", id)
		}
		if rs.Primary.ID == "" {
			return fmt.Errorf("No ID is set")
		}
		customStr := rs.Primary.Attributes["result"]

		if got, want := customStr, want; got != want {
			return fmt.Errorf("custom string is %s; want %s", got, want)
		}

		return nil
	}
}

const (
	testAccResourceStringConfig = `
resource "random_string" "foo" {
  length = 12
}

resource "random_string" "bar" {
  length = 32
}

resource "random_string" "three" {
  length = 4
  override_special = "!"
  lower = false
  upper = false
  number = false
}

resource "random_string" "min" {
  length = 12
  override_special = "!#@"
  min_lower = 2
  min_upper = 3
  min_special = 1
  min_numeric = 4
}
`
	testAccResourceStringInvalidConfig = `
resource "random_string" "invalid_length" {
  length = 2
  min_lower = 3
}`
	testAccResourceStringLengthTooShortConfig = `
resource "random_string" "invalid_length" {
  length = 0
}`
)
<|endoftext|>


<commit_before>package request

// 4.5 Video Object
//
// The video object to be used for all video elements supported in the Native Ad.
// This corresponds to the Video object of OpenRTB.
// Exchange implementers can impose their own specific restrictions.
// Here are the required attributes of the Video Object.
// For optional attributes please refer to OpenRTB.
type Video struct {
	// Field:
	//   mimes
	// Scope:
	//   required
	// Type:
	//   array of string
	// Description:
	//   Content MIME types supported.
	//   Popular MIME types include,but are not limited to “video/x-mswmv” for Windows Media, and “video/x-flv” for Flash Video, or “video/mp4”.
	//   Note that native frequently does not support flash.
	MIMEs []string `json:"mimes"`

	// Field:
	//   minduration
	// Scope:
	//   required
	// Type:
	//   integer
	// Description:
	//   Minimum video ad duration in seconds.
	MinDuration int64 `json:"minduration"`

	// Field:
	//   maxduration
	// Scope:
	//   required
	// Type:
	//   integer
	// Description:
	//   Maximum video ad duration in seconds.
	MaxDuration int64 `json:"maxduration"`

	// Field:
	//   protocols
	// Scope:
	//   required
	// Type:
	//   array of integers
	// Description:
	//   An array of video protocols the publisher can accept in the bid response.
	//   See OpenRTB Table ‘Video Bid Response Protocols’ for a list of possible values.
	Protocols []int8 `json:"protocols"` // TODO!!!

	// Field:
	//   ext
	// Scope:
	//   optional
	// Type:
	//   object
	// Description:
	// This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
	Ext RawJSON `json:"ext,omitempty"`
}
<commit_msg>native/request: use copied request.Protocol for request.Video.Protocols<commit_after>package request

// 4.5 Video Object
//
// The video object to be used for all video elements supported in the Native Ad.
// This corresponds to the Video object of OpenRTB.
// Exchange implementers can impose their own specific restrictions.
// Here are the required attributes of the Video Object.
// For optional attributes please refer to OpenRTB.
type Video struct {
	// Field:
	//   mimes
	// Scope:
	//   required
	// Type:
	//   array of string
	// Description:
	//   Content MIME types supported.
	//   Popular MIME types include,but are not limited to “video/x-mswmv” for Windows Media, and “video/x-flv” for Flash Video, or “video/mp4”.
	//   Note that native frequently does not support flash.
	MIMEs []string `json:"mimes"`

	// Field:
	//   minduration
	// Scope:
	//   required
	// Type:
	//   integer
	// Description:
	//   Minimum video ad duration in seconds.
	MinDuration int64 `json:"minduration"`

	// Field:
	//   maxduration
	// Scope:
	//   required
	// Type:
	//   integer
	// Description:
	//   Maximum video ad duration in seconds.
	MaxDuration int64 `json:"maxduration"`

	// Field:
	//   protocols
	// Scope:
	//   required
	// Type:
	//   array of integers
	// Description:
	//   An array of video protocols the publisher can accept in the bid response.
	//   See OpenRTB Table ‘Video Bid Response Protocols’ for a list of possible values.
	Protocols []Protocol `json:"protocols"`

	// Field:
	//   ext
	// Scope:
	//   optional
	// Type:
	//   object
	// Description:
	// This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
	Ext RawJSON `json:"ext,omitempty"`
}
<|endoftext|>


<commit_before>package mgmt

const (
	ParentNodeManagerConfigKey = "PARENT_NODE_MANAGER_NAME"
	ChildNodeManagerConfigKey  = "CHILD_NODE_MANAGER_NAME"
	AppCycleManagerConfigKey   = "CHILD_APP_CYCLE_MANAGER_NAME"
)
<commit_msg>veyron/lib/modules: adding an option to pass Config to a child process<commit_after>package mgmt

const (
	ParentNameConfigKey      = "MGMT_PARENT_PROCESS_NAME"
	ChildNameConfigKey       = "MGMT_CHILD_PROCESS_NAME"
	AppCycleManagerConfigKey = "MGMT_APP_CYCLE_MANAGER_NAME"
	AddressConfigKey         = "MGMT_CHILD_PROCESS_ADDRESS"
	ProtocolConfigKey        = "MGMT_CHILD_PROCESS_PROTOCOL"
)
<|endoftext|>


<commit_before>package ghfs

import (
	"errors"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
	"syscall"
	"time"

	g "github.com/lemmi/git"
)

type ghfsDir struct {
	tree    *g.Tree
	fi      os.FileInfo
	scanner *g.TreeScanner
}

// Implement http.File on a git tree
func NewDir(tree *g.Tree, fi os.FileInfo) (http.File, error) {
	scanner, err := tree.Scanner()
	if err != nil {
		return nil, err
	}
	return &ghfsDir{tree: tree, fi: fi, scanner: scanner}, nil
}
func (d *ghfsDir) Read([]byte) (int, error) {
	return 0, io.EOF
}
func (d *ghfsDir) Close() error {
	return nil
}
func (d *ghfsDir) Readdir(count int) ([]os.FileInfo, error) {
	ret := []os.FileInfo{}
	for c := 0; c < count; c++ {
		if !d.scanner.Scan() {
			break
		}
		ret = append(ret, d.scanner.TreeEntry())
	}
	if err := d.scanner.Err(); err != nil {
		return ret, err
	}
	return ret, nil
}
func (d *ghfsDir) Seek(int64, int) (int64, error) {
	return 0, syscall.EISDIR
}
func (d *ghfsDir) Stat() (os.FileInfo, error) {
	return d.fi, nil
}

type rootFileInfo struct{}

func (r rootFileInfo) Name() string {
	return ""
}
func (r rootFileInfo) Size() int64 {
	return 0
}
func (r rootFileInfo) Mode() os.FileMode {
	return os.ModeDir | 0755
}
func (r rootFileInfo) ModTime() time.Time {
	return time.Now()
}
func (r rootFileInfo) IsDir() bool {
	return true
}
func (r rootFileInfo) Sys() interface{} {
	return nil
}

type modTimeFileInfo struct {
	os.FileInfo
	modTime time.Time
}

func (m modTimeFileInfo) ModTime() time.Time {
	return m.modTime
}

type ghfsFile struct {
	entry *g.TreeEntry
	fi    os.FileInfo
	rc    io.ReadCloser
	off   int64
	atEnd bool
}

// Implement http.File on a git blob
func NewFile(entry *g.TreeEntry, fi os.FileInfo) (http.File, error) {
	return &ghfsFile{entry: entry, fi: fi}, nil
}

func (f *ghfsFile) Read(buf []byte) (int, error) {
	var err error
	if f.rc == nil {
		f.rc, err = f.entry.Blob().Data()
		if err != nil {
			return 0, err
		}
	}

	if f.atEnd {
		return 0, io.EOF
	}

	n, err := f.rc.Read(buf)
	f.off += int64(n)
	return n, err
}
func (f *ghfsFile) Close() error {
	var ret error
	if f.rc != nil {
		ret = f.rc.Close()
		f.rc = nil
	}
	f.off = 0
	return ret
}
func (f *ghfsFile) Readdir(count int) ([]os.FileInfo, error) {
	return nil, os.ErrInvalid
}
func (f *ghfsFile) Seek(offset int64, whence int) (int64, error) {
	var noff int64

	if whence == os.SEEK_CUR && f.atEnd {
		whence = os.SEEK_END
	}

	switch whence {
	case os.SEEK_SET:
		noff = offset
	case os.SEEK_CUR:
		noff = f.off + offset
	case os.SEEK_END:
		if offset == 0 {
			f.atEnd = true
			return f.entry.Size(), nil
		}
		noff = f.entry.Size() + offset
	default:
		return 0, errors.New("Invalid argument for whence")
	}

	f.atEnd = false

	switch {
	case noff < 0:
		return 0, errors.New("Invalid offset")
	case noff < f.off:
		f.Close()
		return io.CopyN(ioutil.Discard, f, noff)
	case noff >= f.off:
		_, err := io.CopyN(ioutil.Discard, f, noff-f.off)
		return f.off, err
	default:
		panic("Unreachable")
	}
}
func (f *ghfsFile) Stat() (os.FileInfo, error) {
	return f.fi, nil
}

// Implement a http.Filesystem for a git Tree
type ghfs struct {
	commit *g.Commit
	tree   *g.Tree
}

// Serve git tree from commit. Optionally from subtree
func FromCommit(commit *g.Commit, tree ...*g.Tree) http.FileSystem {
	var t *g.Tree
	if len(tree) == 0 {
		t = &commit.Tree
	} else {
		t = tree[0]
	}
	return ghfs{commit, t}
}

func (fs ghfs) Open(name string) (http.File, error) {
	var entry *g.TreeEntry
	if strings.HasPrefix(name, "/") {
		name = name[1:]
	}
	if name == "" {
		return NewDir(fs.tree, rootFileInfo{})
	} else {
		var err error
		entry, err = fs.tree.GetTreeEntryByPath(name)
		if err != nil {
			return nil, err
		}
	}

	fi := modTimeFileInfo{entry, fs.commit.Author.When}

	switch entry.Type {
	case g.ObjectTree:
		stree, err := fs.tree.SubTree(name)
		if err != nil {
			return nil, err
		}
		return NewDir(stree, fi)
	case g.ObjectBlob:
		return NewFile(entry, fi)
	default:
		return nil, errors.New("Invalid type")
	}
}
<commit_msg>Fix Readdir(0) to return all entries<commit_after>package ghfs

import (
	"errors"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
	"syscall"
	"time"

	g "github.com/lemmi/git"
)

type ghfsDir struct {
	tree    *g.Tree
	fi      os.FileInfo
	scanner *g.TreeScanner
}

// Implement http.File on a git tree
func NewDir(tree *g.Tree, fi os.FileInfo) (http.File, error) {
	scanner, err := tree.Scanner()
	if err != nil {
		return nil, err
	}
	return &ghfsDir{tree: tree, fi: fi, scanner: scanner}, nil
}
func (d *ghfsDir) Read([]byte) (int, error) {
	return 0, io.EOF
}
func (d *ghfsDir) Close() error {
	return nil
}
func (d *ghfsDir) Readdir(count int) ([]os.FileInfo, error) {
	ret := []os.FileInfo{}
	for c := 0; count <= 0 || count > c; c++ {
		if !d.scanner.Scan() {
			break
		}
		ret = append(ret, d.scanner.TreeEntry())
	}
	if err := d.scanner.Err(); err != nil {
		return ret, err
	}
	return ret, nil
}
func (d *ghfsDir) Seek(int64, int) (int64, error) {
	return 0, syscall.EISDIR
}
func (d *ghfsDir) Stat() (os.FileInfo, error) {
	return d.fi, nil
}

type rootFileInfo struct{}

func (r rootFileInfo) Name() string {
	return ""
}
func (r rootFileInfo) Size() int64 {
	return 0
}
func (r rootFileInfo) Mode() os.FileMode {
	return os.ModeDir | 0755
}
func (r rootFileInfo) ModTime() time.Time {
	return time.Now()
}
func (r rootFileInfo) IsDir() bool {
	return true
}
func (r rootFileInfo) Sys() interface{} {
	return nil
}

type modTimeFileInfo struct {
	os.FileInfo
	modTime time.Time
}

func (m modTimeFileInfo) ModTime() time.Time {
	return m.modTime
}

type ghfsFile struct {
	entry *g.TreeEntry
	fi    os.FileInfo
	rc    io.ReadCloser
	off   int64
	atEnd bool
}

// Implement http.File on a git blob
func NewFile(entry *g.TreeEntry, fi os.FileInfo) (http.File, error) {
	return &ghfsFile{entry: entry, fi: fi}, nil
}

func (f *ghfsFile) Read(buf []byte) (int, error) {
	var err error
	if f.rc == nil {
		f.rc, err = f.entry.Blob().Data()
		if err != nil {
			return 0, err
		}
	}

	if f.atEnd {
		return 0, io.EOF
	}

	n, err := f.rc.Read(buf)
	f.off += int64(n)
	return n, err
}
func (f *ghfsFile) Close() error {
	var ret error
	if f.rc != nil {
		ret = f.rc.Close()
		f.rc = nil
	}
	f.off = 0
	return ret
}
func (f *ghfsFile) Readdir(count int) ([]os.FileInfo, error) {
	return nil, os.ErrInvalid
}
func (f *ghfsFile) Seek(offset int64, whence int) (int64, error) {
	var noff int64

	if whence == os.SEEK_CUR && f.atEnd {
		whence = os.SEEK_END
	}

	switch whence {
	case os.SEEK_SET:
		noff = offset
	case os.SEEK_CUR:
		noff = f.off + offset
	case os.SEEK_END:
		if offset == 0 {
			f.atEnd = true
			return f.entry.Size(), nil
		}
		noff = f.entry.Size() + offset
	default:
		return 0, errors.New("Invalid argument for whence")
	}

	f.atEnd = false

	switch {
	case noff < 0:
		return 0, errors.New("Invalid offset")
	case noff < f.off:
		f.Close()
		return io.CopyN(ioutil.Discard, f, noff)
	case noff >= f.off:
		_, err := io.CopyN(ioutil.Discard, f, noff-f.off)
		return f.off, err
	default:
		panic("Unreachable")
	}
}
func (f *ghfsFile) Stat() (os.FileInfo, error) {
	return f.fi, nil
}

// Implement a http.Filesystem for a git Tree
type ghfs struct {
	commit *g.Commit
	tree   *g.Tree
}

// Serve git tree from commit. Optionally from subtree
func FromCommit(commit *g.Commit, tree ...*g.Tree) http.FileSystem {
	var t *g.Tree
	if len(tree) == 0 {
		t = &commit.Tree
	} else {
		t = tree[0]
	}
	return ghfs{commit, t}
}

func (fs ghfs) Open(name string) (http.File, error) {
	var entry *g.TreeEntry
	if strings.HasPrefix(name, "/") {
		name = name[1:]
	}
	if name == "" {
		return NewDir(fs.tree, rootFileInfo{})
	} else {
		var err error
		entry, err = fs.tree.GetTreeEntryByPath(name)
		if err != nil {
			return nil, err
		}
	}

	fi := modTimeFileInfo{entry, fs.commit.Author.When}

	switch entry.Type {
	case g.ObjectTree:
		stree, err := fs.tree.SubTree(name)
		if err != nil {
			return nil, err
		}
		return NewDir(stree, fi)
	case g.ObjectBlob:
		return NewFile(entry, fi)
	default:
		return nil, errors.New("Invalid type")
	}
}
<|endoftext|>


<commit_before>package hrx

import "github.com/melias122/engine/engine"

type hkey struct {
	cislo   int16
	pozicia int16
	pocet   int32
}

type hCache struct {
	n, m  int
	cache map[hkey]float64
}

func newHCache(n, m int) *hCache {
	return &hCache{
		n:     n,
		m:     m,
		cache: make(map[hkey]float64, 1<<10),
	}
}

func (h *hCache) H(cislo, pozicia, pocet int) float64 {
	//	if cislo > (h.m/2)+h.m%2 {
	//		cislo = (cislo - (h.m + 1)) * (-1)
	//		pozicia = h.n - pozicia + 1
	//	}
	k := hkey{int16(cislo), int16(pozicia), int32(pocet)}
	v, ok := h.cache[k]
	if ok {
		return v
	}
	v = engine.H(cislo, pozicia, pocet, h.n, h.m)
	h.cache[k] = v
	return v
}
<commit_msg>hrx: remove unused code from hCache<commit_after>package hrx

import "github.com/melias122/engine/engine"

type hkey struct {
	cislo   int16
	pozicia int16
	pocet   int32
}

type hCache struct {
	n, m  int
	cache map[hkey]float64
}

func newHCache(n, m int) *hCache {
	return &hCache{
		n:     n,
		m:     m,
		cache: make(map[hkey]float64, 1<<10),
	}
}

func (h *hCache) H(cislo, pozicia, pocet int) float64 {
	k := hkey{int16(cislo), int16(pozicia), int32(pocet)}
	v, ok := h.cache[k]
	if ok {
		return v
	}
	v = engine.H(cislo, pozicia, pocet, h.n, h.m)
	h.cache[k] = v
	return v
}
<|endoftext|>


<commit_before>// Copyright 2016 Mender Software AS
//
//    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 main

import (
	"mime"
	"net/http"

	"github.com/ant0ine/go-json-rest/rest"
	"github.com/mendersoftware/deployments/config"
	"github.com/mendersoftware/go-lib-micro/accesslog"
	"github.com/mendersoftware/go-lib-micro/requestid"
	"github.com/mendersoftware/go-lib-micro/requestlog"
)

const (
	HttpHeaderContentType                 string = "Content-type"
	HttpHeaderOrigin                      string = "Origin"
	HttpHeaderAuthorization               string = "Authorization"
	HttpHeaderAcceptEncoding              string = "Accept-Encoding"
	HttpHeaderAccessControlRequestHeaders string = "Access-Control-Request-Headers"
	HttpHeaderAccessControlRequestMethod  string = "Access-Control-Request-Method"
	HttpHeaderLastModified                string = "Last-Modified"
	HttpHeaderExpires                     string = "Expires"
	HttpHeaderLocation                    string = "Location"
	HttpHeaderAllow                       string = "Allow"
	HttpHeaderAccept                      string = "Accept"

	EnvProd string = "prod"
	EnvDev  string = "dev"
)

var DefaultDevStack = []rest.Middleware{

	// logging
	&requestlog.RequestLogMiddleware{},
	&accesslog.AccessLogMiddleware{Format: accesslog.SimpleLogFormat},
	&rest.TimerMiddleware{},
	&rest.RecorderMiddleware{},

	// catches the panic errors that occur with stack trace
	&rest.RecoverMiddleware{
		EnableResponseStackTrace: true,
	},

	// json pretty print
	&rest.JsonIndentMiddleware{},
	&requestid.RequestIdMiddleware{},
}

var DefaultProdStack = []rest.Middleware{

	// logging
	&requestlog.RequestLogMiddleware{},
	&accesslog.AccessLogMiddleware{Format: accesslog.SimpleLogFormat},
	&rest.TimerMiddleware{},
	&rest.RecorderMiddleware{},

	// catches the panic errorsx
	&rest.RecoverMiddleware{},

	// response compression
	&rest.GzipMiddleware{},
	&requestid.RequestIdMiddleware{},
}

func SetupMiddleware(c config.ConfigReader, api *rest.Api) {
	api.Use(DefaultDevStack...)

	// Verifies the request Content-Type header if the content is non-null.
	// For the POST /api/0.0.1/images request expected Content-Type is 'multipart/form-data'.
	// For the rest of the requests expected Content-Type is 'application/json'.
	api.Use(&rest.IfMiddleware{
		Condition: func(r *rest.Request) bool {
			if r.URL.Path == "/api/0.0.1/artifacts" && r.Method == http.MethodPost {
				return true
			} else {
				return false
			}
		},
		IfTrue: rest.MiddlewareSimple(func(handler rest.HandlerFunc) rest.HandlerFunc {
			return func(w rest.ResponseWriter, r *rest.Request) {
				mediatype, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
				if r.ContentLength > 0 && !(mediatype == "multipart/form-data") {
					rest.Error(w, "Bad Content-Type, expected 'multipart/form-data'", http.StatusUnsupportedMediaType)
					return
				}
				// call the wrapped handler
				handler(w, r)
			}
		}),
		IfFalse: &rest.ContentTypeCheckerMiddleware{},
	})

	api.Use(&rest.CorsMiddleware{
		RejectNonCorsRequests: false,

		// Should be tested with some list
		OriginValidator: func(origin string, request *rest.Request) bool {
			// Accept all requests
			return true
		},

		// Preflight request cache lenght
		AccessControlMaxAge: 60,

		// Allow authentication requests
		AccessControlAllowCredentials: true,

		// Allowed headers
		AllowedMethods: []string{
			http.MethodGet,
			http.MethodPost,
			http.MethodPut,
			http.MethodDelete,
			http.MethodOptions,
		},

		// Allowed heardes
		AllowedHeaders: []string{
			HttpHeaderAccept,
			HttpHeaderAllow,
			HttpHeaderContentType,
			HttpHeaderOrigin,
			HttpHeaderAuthorization,
			HttpHeaderAcceptEncoding,
			HttpHeaderAccessControlRequestHeaders,
			HttpHeaderAccessControlRequestMethod,
		},

		// Headers that can be exposed to JS
		AccessControlExposeHeaders: []string{
			HttpHeaderLocation,
		},
	})
}
<commit_msg>middleware: actually use the middleware setting<commit_after>// Copyright 2016 Mender Software AS
//
//    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 main

import (
	"mime"
	"net/http"

	"github.com/ant0ine/go-json-rest/rest"
	"github.com/mendersoftware/deployments/config"
	"github.com/mendersoftware/go-lib-micro/accesslog"
	"github.com/mendersoftware/go-lib-micro/requestid"
	"github.com/mendersoftware/go-lib-micro/requestlog"
)

const (
	HttpHeaderContentType                 string = "Content-type"
	HttpHeaderOrigin                      string = "Origin"
	HttpHeaderAuthorization               string = "Authorization"
	HttpHeaderAcceptEncoding              string = "Accept-Encoding"
	HttpHeaderAccessControlRequestHeaders string = "Access-Control-Request-Headers"
	HttpHeaderAccessControlRequestMethod  string = "Access-Control-Request-Method"
	HttpHeaderLastModified                string = "Last-Modified"
	HttpHeaderExpires                     string = "Expires"
	HttpHeaderLocation                    string = "Location"
	HttpHeaderAllow                       string = "Allow"
	HttpHeaderAccept                      string = "Accept"

	EnvProd string = "prod"
	EnvDev  string = "dev"
)

var DefaultDevStack = []rest.Middleware{

	// logging
	&requestlog.RequestLogMiddleware{},
	&accesslog.AccessLogMiddleware{Format: accesslog.SimpleLogFormat},
	&rest.TimerMiddleware{},
	&rest.RecorderMiddleware{},

	// catches the panic errors that occur with stack trace
	&rest.RecoverMiddleware{
		EnableResponseStackTrace: true,
	},

	// json pretty print
	&rest.JsonIndentMiddleware{},
	&requestid.RequestIdMiddleware{},
}

var DefaultProdStack = []rest.Middleware{

	// logging
	&requestlog.RequestLogMiddleware{},
	&accesslog.AccessLogMiddleware{Format: accesslog.SimpleLogFormat},
	&rest.TimerMiddleware{},
	&rest.RecorderMiddleware{},

	// catches the panic errorsx
	&rest.RecoverMiddleware{},

	// response compression
	&rest.GzipMiddleware{},
	&requestid.RequestIdMiddleware{},
}

func SetupMiddleware(c config.ConfigReader, api *rest.Api) {
	mwtype := c.GetString(SettingMiddleware)
	if mwtype == EnvDev {
		api.Use(DefaultDevStack...)
	} else {
		api.Use(DefaultProdStack...)
	}

	// Verifies the request Content-Type header if the content is non-null.
	// For the POST /api/0.0.1/images request expected Content-Type is 'multipart/form-data'.
	// For the rest of the requests expected Content-Type is 'application/json'.
	api.Use(&rest.IfMiddleware{
		Condition: func(r *rest.Request) bool {
			if r.URL.Path == "/api/0.0.1/artifacts" && r.Method == http.MethodPost {
				return true
			} else {
				return false
			}
		},
		IfTrue: rest.MiddlewareSimple(func(handler rest.HandlerFunc) rest.HandlerFunc {
			return func(w rest.ResponseWriter, r *rest.Request) {
				mediatype, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
				if r.ContentLength > 0 && !(mediatype == "multipart/form-data") {
					rest.Error(w, "Bad Content-Type, expected 'multipart/form-data'", http.StatusUnsupportedMediaType)
					return
				}
				// call the wrapped handler
				handler(w, r)
			}
		}),
		IfFalse: &rest.ContentTypeCheckerMiddleware{},
	})

	api.Use(&rest.CorsMiddleware{
		RejectNonCorsRequests: false,

		// Should be tested with some list
		OriginValidator: func(origin string, request *rest.Request) bool {
			// Accept all requests
			return true
		},

		// Preflight request cache lenght
		AccessControlMaxAge: 60,

		// Allow authentication requests
		AccessControlAllowCredentials: true,

		// Allowed headers
		AllowedMethods: []string{
			http.MethodGet,
			http.MethodPost,
			http.MethodPut,
			http.MethodDelete,
			http.MethodOptions,
		},

		// Allowed heardes
		AllowedHeaders: []string{
			HttpHeaderAccept,
			HttpHeaderAllow,
			HttpHeaderContentType,
			HttpHeaderOrigin,
			HttpHeaderAuthorization,
			HttpHeaderAcceptEncoding,
			HttpHeaderAccessControlRequestHeaders,
			HttpHeaderAccessControlRequestMethod,
		},

		// Headers that can be exposed to JS
		AccessControlExposeHeaders: []string{
			HttpHeaderLocation,
		},
	})
}
<|endoftext|>


<commit_before>package negronilogrus

import (
	"fmt"
	"github.com/Sirupsen/logrus"
	"github.com/codegangsta/negroni"
	"github.com/jabong/canonburst/conf"
	"github.com/jabong/canonburst/log"
	"net/http"
	"time"
)

// Middleware is a middleware handler that logs the request as it goes in and the response as it goes out.
type Middleware struct {
	// Logger is the log.Logger instance used to log messages with the Logger middleware
	Logger *logrus.Logger
	// Name is the name of the application as recorded in latency metrics
	Name string
}

// NewMiddleware returns a new *Middleware, yay!
func NewMiddleware() *Middleware {
	return NewCustomMiddleware(logrus.InfoLevel, &logrus.TextFormatter{}, "web")
}

// NewCustomMiddleware builds a *Middleware with the given level and formatter
func NewCustomMiddleware(level logrus.Level, formatter logrus.Formatter, name string) *Middleware {
	log := logrus.New()
	log.Level = level
	log.Formatter = formatter

	return &Middleware{Logger: log, Name: name}
}

func (l *Middleware) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	start := time.Now()
	config := conf.GetConfig()
	if config.Env == "dev" {
		l.Logger.WithFields(logrus.Fields{
			"method":         r.Method,
			"request":        r.RequestURI,
			"remote":         r.RemoteAddr,
			"X-Jabong-Reqid": r.Header.Get("X-Jabong-Reqid"),
			"X-Jabong-Tid":   r.Header.Get("X-Jabong-Tid"),
		}).Info("started handling request")
	}
	msg := fmt.Sprintf("started handling request: method=%s remote=%s request=%s X-Jabong-Reqid=%v X-Jabong-Tid=%v", r.Method, r.RemoteAddr, r.RequestURI, r.Header.Get("X-Jabong-Reqid"), r.Header.Get("X-Jabong-Tid"))

	if r.RequestURI != "/catalog/v1/healthcheck/" && r.RequestURI != "/catalog/v1/healthcheck" {
		log.Info(msg)
	}

	next(rw, r)
	latency := time.Since(start)
	res := rw.(negroni.ResponseWriter)
	if config.Env == "dev" {
		l.Logger.WithFields(logrus.Fields{
			"status":      res.Status(),
			"method":      r.Method,
			"request":     r.RequestURI,
			"remote":      r.RemoteAddr,
			"text_status": http.StatusText(res.Status()),
			"took":        latency,
			fmt.Sprintf("measure#%s.latency", l.Name): latency.Nanoseconds(),
			"X-Jabong-Reqid":                          r.Header.Get("X-Jabong-Reqid"),
			"X-Jabong-Tid":                            r.Header.Get("X-Jabong-Tid"),
		}).Info("completed handling request")
	}
	msg = fmt.Sprintf("completed handling request: measure#%s.latency=%d method=%s remote=%s request=%s status=%d text_status=%s took=%s X-Jabong-Reqid=%v X-Jabong-Tid=%v", l.Name, latency.Nanoseconds(), r.Method, r.RemoteAddr, r.RequestURI, res.Status(), http.StatusText(res.Status()), latency, r.Header.Get("X-Jabong-Reqid"), r.Header.Get("X-Jabong-Tid"))
	log.GetDAgent().Count(fmt.Sprintf("%d_requests", res.Status()), 1)

	if r.RequestURI == "/catalog/v1/healthcheck/" || r.RequestURI == "/catalog/v1/healthcheck" {
		return
	}

	if res.Status() == http.StatusOK {
		if latency > (time.Duration(config.LogLatencyLimit) * time.Millisecond) {
			log.Errf(msg, r.Header.Get("X-Jabong-Reqid"), r.Header.Get("X-Jabong-Tid"))
		}
	} else if res.Status() == http.StatusInternalServerError {
		log.Errf(msg, r.Header.Get("X-Jabong-Reqid"), r.Header.Get("X-Jabong-Tid"))
	} else {
		log.Alertf(msg, r.Header.Get("X-Jabong-Reqid"), r.Header.Get("X-Jabong-Tid"))
	}
}
<commit_msg>change errf to infof<commit_after>package negronilogrus

import (
	"fmt"
	"github.com/Sirupsen/logrus"
	"github.com/codegangsta/negroni"
	"github.com/jabong/canonburst/conf"
	"github.com/jabong/canonburst/log"
	"net/http"
	"time"
)

// Middleware is a middleware handler that logs the request as it goes in and the response as it goes out.
type Middleware struct {
	// Logger is the log.Logger instance used to log messages with the Logger middleware
	Logger *logrus.Logger
	// Name is the name of the application as recorded in latency metrics
	Name string
}

// NewMiddleware returns a new *Middleware, yay!
func NewMiddleware() *Middleware {
	return NewCustomMiddleware(logrus.InfoLevel, &logrus.TextFormatter{}, "web")
}

// NewCustomMiddleware builds a *Middleware with the given level and formatter
func NewCustomMiddleware(level logrus.Level, formatter logrus.Formatter, name string) *Middleware {
	log := logrus.New()
	log.Level = level
	log.Formatter = formatter

	return &Middleware{Logger: log, Name: name}
}

func (l *Middleware) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	start := time.Now()
	config := conf.GetConfig()
	if config.Env == "dev" {
		l.Logger.WithFields(logrus.Fields{
			"method":         r.Method,
			"request":        r.RequestURI,
			"remote":         r.RemoteAddr,
			"X-Jabong-Reqid": r.Header.Get("X-Jabong-Reqid"),
			"X-Jabong-Tid":   r.Header.Get("X-Jabong-Tid"),
		}).Info("started handling request")
	}
	msg := fmt.Sprintf("started handling request: method=%s remote=%s request=%s X-Jabong-Reqid=%v X-Jabong-Tid=%v", r.Method, r.RemoteAddr, r.RequestURI, r.Header.Get("X-Jabong-Reqid"), r.Header.Get("X-Jabong-Tid"))

	if r.RequestURI != "/catalog/v1/healthcheck/" && r.RequestURI != "/catalog/v1/healthcheck" {
		log.Info(msg)
	}

	next(rw, r)
	latency := time.Since(start)
	res := rw.(negroni.ResponseWriter)
	if config.Env == "dev" {
		l.Logger.WithFields(logrus.Fields{
			"status":      res.Status(),
			"method":      r.Method,
			"request":     r.RequestURI,
			"remote":      r.RemoteAddr,
			"text_status": http.StatusText(res.Status()),
			"took":        latency,
			fmt.Sprintf("measure#%s.latency", l.Name): latency.Nanoseconds(),
			"X-Jabong-Reqid":                          r.Header.Get("X-Jabong-Reqid"),
			"X-Jabong-Tid":                            r.Header.Get("X-Jabong-Tid"),
		}).Info("completed handling request")
	}
	msg = fmt.Sprintf("completed handling request: measure#%s.latency=%d method=%s remote=%s request=%s status=%d text_status=%s took=%s X-Jabong-Reqid=%v X-Jabong-Tid=%v", l.Name, latency.Nanoseconds(), r.Method, r.RemoteAddr, r.RequestURI, res.Status(), http.StatusText(res.Status()), latency, r.Header.Get("X-Jabong-Reqid"), r.Header.Get("X-Jabong-Tid"))
	log.GetDAgent().Count(fmt.Sprintf("%d_requests", res.Status()), 1)

	if r.RequestURI == "/catalog/v1/healthcheck/" || r.RequestURI == "/catalog/v1/healthcheck" {
		return
	}

	if res.Status() == http.StatusOK {
		if latency > (time.Duration(config.LogLatencyLimit) * time.Millisecond) {
			log.Infof(msg, r.Header.Get("X-Jabong-Reqid"), r.Header.Get("X-Jabong-Tid"))
		}
	} else if res.Status() == http.StatusInternalServerError {
		log.Errf(msg, r.Header.Get("X-Jabong-Reqid"), r.Header.Get("X-Jabong-Tid"))
	} else {
		log.Alertf(msg, r.Header.Get("X-Jabong-Reqid"), r.Header.Get("X-Jabong-Tid"))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"log"
	"net/url"
	"os"
	"strings"
)

var (
	EcAsics = []string{"http://www.asics.com/gb/en-gb", "http://www.asics.com/fr/fr-fr", "http://www.asics.com/es/es-es", "http://www.asics.com/it/it-it"}

	NoEcAsics = []string{"https://www.asics.co.za/", "https://www.asics.pl", "https://de.asics.ch"}
)

type ParseData struct {
	Locale string
	Header []Link
	Footer []Link
}

type Link struct {
	Title string
	Url   string
	Index int
	Img   string
	Items []ItemLink
}

type ItemLink struct {
	Title string
	Url   string
	Index int
	Img   string
}

func ParseECHtml(url_string string) {

	target_url, _ := url.Parse(url_string)
	doc, err := goquery.NewDocument(url_string)
	if err != nil {
		log.Fatal(err)
	}

	parsedata := ParseData{
		Locale: strings.Split(target_url.Path, "/")[2],
	}

	//parse the header
	// doc.Find("header #main-menu").Children().Each(func(i int, s *goquery.Selection) {

	//parse the footer
	doc.Find("footer").Children().Filter(".tiger-clearfix-toggle").Each(func(i int, s *goquery.Selection) {
		link := Link{
			Title: s.Children().Filter("h4").First().Text(),
			Url:   "#",
			Index: i + 1,
			img:   "",
		}

		s.Children().Filter("ul").Children().Each(func(i int, s *goquery.Selection) {
			itemlink := ItemLink{
				Title: s.Children().First().Text(),
				Url:   target_url.Scheme + "://" + target_url.Host + s.Children().First().AttrOr("href", "#"),
				Index: i + 1,
			}
			link.Items = append(link.Items, itemlink)
		})
		parsedata.Footer = append(parsedata.Footer, link)
	})

	jsondata, _ := json.Marshal(parsedata)

	file, _ := os.OpenFile(strings.Split(target_url.Path, "/")[2]+".json", os.O_WRONLY|os.O_CREATE, 0666)
	file.Write(jsondata)

	fmt.Println(string(jsondata))

}

func ParseNoECHtml(url_string string) {

	target_url, _ := url.Parse(url_string)
	doc, err := goquery.NewDocument(url_string)
	if err != nil {
		log.Fatal(err)
	}

	locale := strings.Split(target_url.Host, ".")[0] + "-" + strings.Split(target_url.Host, ".")[2]
	parsedata := ParseData{
		Locale: locale,
	}

	//parse the footer
	doc.Find(".footer section").Children().Each(func(i int, s *goquery.Selection) {
		link := Link{
			Title: s.Children().Filter("h4").First().Text(),
			Url:   "#",
			Index: i + 1,
			img:   "",
		}

		s.Children().Filter("ul").Children().Each(func(i int, s *goquery.Selection) {
			itemlink := ItemLink{
				Title: s.Children().First().Text(),
				Url:   target_url.Scheme + "://" + target_url.Host + s.Children().First().AttrOr("href", "#"),
				Index: i + 1,
			}
			link.Items = append(link.Items, itemlink)
		})
		parsedata.Footer = append(parsedata.Footer, link)
	})

	jsondata, _ := json.Marshal(parsedata)

	file, _ := os.OpenFile(locale, os.O_WRONLY|os.O_CREATE, 0666)
	file.Write(jsondata)

	fmt.Println(string(jsondata))

}

func main() {
	for _, url := range EcAsics {
		ParseECHtml(url)
	}
	for _, url := range NoEcAsics {
		ParseNoECHtml(url)
	}
}
<commit_msg>remove the img from Link struct<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"log"
	"net/url"
	"os"
	"strings"
)

var (
	EcAsics = []string{"http://www.asics.com/gb/en-gb", "http://www.asics.com/fr/fr-fr", "http://www.asics.com/es/es-es", "http://www.asics.com/it/it-it"}

	NoEcAsics = []string{"https://www.asics.co.za/", "https://www.asics.pl", "https://de.asics.ch"}
)

type ParseData struct {
	Locale string
	Header []Link
	Footer []Link
}

type Link struct {
	Title string
	Url   string
	Index int
	Img   string
	Items []ItemLink
}

type ItemLink struct {
	Title string
	Url   string
	Index int
	Img   string
}

func ParseECHtml(url_string string) {

	target_url, _ := url.Parse(url_string)
	doc, err := goquery.NewDocument(url_string)
	if err != nil {
		log.Fatal(err)
	}

	parsedata := ParseData{
		Locale: strings.Split(target_url.Path, "/")[2],
	}

	//parse the header
	// doc.Find("header #main-menu").Children().Each(func(i int, s *goquery.Selection) {

	//parse the footer
	doc.Find("footer").Children().Filter(".tiger-clearfix-toggle").Each(func(i int, s *goquery.Selection) {
		link := Link{
			Title: s.Children().Filter("h4").First().Text(),
			Url:   "#",
			Index: i + 1,
		}

		s.Children().Filter("ul").Children().Each(func(i int, s *goquery.Selection) {
			itemlink := ItemLink{
				Title: s.Children().First().Text(),
				Url:   target_url.Scheme + "://" + target_url.Host + s.Children().First().AttrOr("href", "#"),
				Index: i + 1,
			}
			link.Items = append(link.Items, itemlink)
		})
		parsedata.Footer = append(parsedata.Footer, link)
	})

	jsondata, _ := json.Marshal(parsedata)

	file, _ := os.OpenFile(strings.Split(target_url.Path, "/")[2]+".json", os.O_WRONLY|os.O_CREATE, 0666)
	file.Write(jsondata)

	fmt.Println(string(jsondata))

}

func ParseNoECHtml(url_string string) {

	target_url, _ := url.Parse(url_string)
	doc, err := goquery.NewDocument(url_string)
	if err != nil {
		log.Fatal(err)
	}

	locale := strings.Split(target_url.Host, ".")[0] + "-" + strings.Split(target_url.Host, ".")[2]
	parsedata := ParseData{
		Locale: locale,
	}

	//parse the footer
	doc.Find(".footer #tertiary section").Each(func(i int, s *goquery.Selection) {
		link := Link{
			Title: s.Children().First().Text(),
			Url:   "#",
			Index: i + 1,
		}
		fmt.Println(s)

		s.Children().Filter("ul").Children().Each(func(i int, s *goquery.Selection) {
			itemlink := ItemLink{
				Title: s.Children().First().Text(),
				Url:   s.Children().First().AttrOr("href", "#"),
				Index: i + 1,
			}
			link.Items = append(link.Items, itemlink)
		})
		parsedata.Footer = append(parsedata.Footer, link)
	})

	jsondata, _ := json.Marshal(parsedata)

	file, _ := os.OpenFile(locale, os.O_WRONLY|os.O_CREATE, 0666)
	file.Write(jsondata)

	fmt.Println(string(jsondata))

}

func main() {
	for _, url := range EcAsics {
		ParseECHtml(url)
	}
	for _, url := range NoEcAsics {
		ParseNoECHtml(url)
	}
}
<|endoftext|>