Upgrade to Beats v5.0.0-beta1 - Added comments

--- config/config.go
+++ config/config.go
@@ -12,10 +12,16 @@
 	DefaultDocumentType string        = "httpbeat"
 )

+/*
+ Configuration for Httpbeat
+ */
 type HttpbeatConfig struct {
 	Urls []UrlConfig
 }

+/*
+ Configuration for single URL
+ */
 type UrlConfig struct {
 	Cron         string
 	Url          string
@@ -31,6 +37,9 @@
 	JsonDotMode  string `config:"json_dot_mode"`
 }

+/*
+ Configuration for Basic authentication
+ */
 type BasicAuthenticationConfig struct {
 	Username string
 	Password string

<|original_code|>
package config

import (
	"github.com/elastic/beats/libbeat/outputs"
	"time"
)

// Defaults for config variables which are not set
const (
	DefaultCron         string        = "@every 1m"
	DefaultTimeout      time.Duration = 60 * time.Second
	DefaultDocumentType string        = "httpbeat"
)

type HttpbeatConfig struct {
	Urls []UrlConfig
}

type UrlConfig struct {
	Cron         string
	Url          string
	BasicAuth    BasicAuthenticationConfig `config:"basic_auth"`
	Method       string
	Body         string
	Headers      map[string]string
	ProxyUrl     string `config:"proxy_url"`
	Timeout      *int64
	DocumentType string            `config:"document_type"`
	Fields       map[string]string `config:"fields"`
	SSL          *outputs.TLSConfig
	JsonDotMode  string `config:"json_dot_mode"`
}

type BasicAuthenticationConfig struct {
	Username string
	Password string
}

type ConfigSettings struct {
	Httpbeat HttpbeatConfig
}

<|edits_diff|>
--- config/config.go
+++ config/config.go
@@ -12,10 +12,16 @@
 	DefaultDocumentType string        = "httpbeat"
 )

+/*
+ Configuration for Httpbeat
+ */
 type HttpbeatConfig struct {
 	Urls []UrlConfig
 }

+/*
+ Configuration for single URL
+ */
 type UrlConfig struct {
 	Cron         string
 	Url          string
<|current_version|>
package config

import (
	"github.com/elastic/beats/libbeat/outputs"
	"time"
)

// Defaults for config variables which are not set
const (
	DefaultCron         string        = "@every 1m"
	DefaultTimeout      time.Duration = 60 * time.Second
	DefaultDocumentType string        = "httpbeat"
)

/*
 Configuration for Httpbeat
 */
type HttpbeatConfig struct {
	Urls []UrlConfig
}

/*
 Configuration for single URL
 */
type UrlConfig struct {
	Cron         string
	Url          string
	BasicAuth    BasicAuthenticationConfig `config:"basic_auth"`
	Method       string
	Body         string
	Headers      map[string]string
	ProxyUrl     string `config:"proxy_url"`
	Timeout      *int64
	DocumentType string            `config:"document_type"`
	Fields       map[string]string `config:"fields"`
	SSL          *outputs.TLSConfig
	JsonDotMode  string `config:"json_dot_mode"`
}

type BasicAuthenticationConfig struct {
	Username string
	Password string
}

type ConfigSettings struct {
	Httpbeat HttpbeatConfig
}

<|next_version|>
package config

import (
	"github.com/elastic/beats/libbeat/outputs"
	"time"
)

// Defaults for config variables which are not set
const (
	DefaultCron         string        = "@every 1m"
	DefaultTimeout      time.Duration = 60 * time.Second
	DefaultDocumentType string        = "httpbeat"
)

/*
 Configuration for Httpbeat
 */
type HttpbeatConfig struct {
	Urls []UrlConfig
}

/*
 Configuration for single URL
 */
type UrlConfig struct {
	Cron         string
	Url          string
	BasicAuth    BasicAuthenticationConfig `config:"basic_auth"`
	Method       string
	Body         string
	Headers      map[string]string
	ProxyUrl     string `config:"proxy_url"`
	Timeout      *int64
	DocumentType string            `config:"document_type"`
	Fields       map[string]string `config:"fields"`
	SSL          *outputs.TLSConfig
	JsonDotMode  string `config:"json_dot_mode"`
}

/*
 Configuration for Basic authentication
 */
type BasicAuthenticationConfig struct {
	Username string
	Password string
}

type ConfigSettings struct {
	Httpbeat HttpbeatConfig
}


Fix golint errors when generating informer code

Kubernetes-commit: acf78cd6133de6faea9221d8c53b02ca6009b0bb

--- pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go
+++ pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go
@@ -27,6 +27,7 @@
 	versioned "k8s.io/csi-api/pkg/client/clientset/versioned"
 )

+// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer.
 type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer

 // SharedInformerFactory a small interface to allow for adding an informer without an import cycle
@@ -35,4 +36,5 @@
 	InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
 }

+// TweakListOptionsFunc is a function that transforms a v1.ListOptions.
 type TweakListOptionsFunc func(*v1.ListOptions)

<|original_code|>
/*
Copyright 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.
*/

// Code generated by informer-gen. DO NOT EDIT.

package internalinterfaces

import (
	time "time"

	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	runtime "k8s.io/apimachinery/pkg/runtime"
	cache "k8s.io/client-go/tools/cache"
	versioned "k8s.io/csi-api/pkg/client/clientset/versioned"
)

type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer

// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
type SharedInformerFactory interface {
	Start(stopCh <-chan struct{})
	InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
}

type TweakListOptionsFunc func(*v1.ListOptions)

<|edits_diff|>
--- pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go
+++ pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go
@@ -27,6 +27,7 @@
 	versioned "k8s.io/csi-api/pkg/client/clientset/versioned"
 )

+// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer.
 type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer

 // SharedInformerFactory a small interface to allow for adding an informer without an import cycle
<|current_version|>
/*
Copyright 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.
*/

// Code generated by informer-gen. DO NOT EDIT.

package internalinterfaces

import (
	time "time"

	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	runtime "k8s.io/apimachinery/pkg/runtime"
	cache "k8s.io/client-go/tools/cache"
	versioned "k8s.io/csi-api/pkg/client/clientset/versioned"
)

// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer.
type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer

// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
type SharedInformerFactory interface {
	Start(stopCh <-chan struct{})
	InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
}

type TweakListOptionsFunc func(*v1.ListOptions)

<|next_version|>
/*
Copyright 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.
*/

// Code generated by informer-gen. DO NOT EDIT.

package internalinterfaces

import (
	time "time"

	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	runtime "k8s.io/apimachinery/pkg/runtime"
	cache "k8s.io/client-go/tools/cache"
	versioned "k8s.io/csi-api/pkg/client/clientset/versioned"
)

// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer.
type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer

// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
type SharedInformerFactory interface {
	Start(stopCh <-chan struct{})
	InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
}

// TweakListOptionsFunc is a function that transforms a v1.ListOptions.
type TweakListOptionsFunc func(*v1.ListOptions)


Make GetFilesJSON return after sending on channel

--- goat/apiFiles.go
+++ goat/apiFiles.go
@@ -17,11 +17,14 @@
 		if err != nil {
 			log.Println(err.Error())
 			resChan <- nil
+			return
 		}

 		// Return status
 		resChan <- res
+		return
 	}

 	resChan <- nil
+	return
 }

<|original_code|>
package goat

import (
	"encoding/json"
	"log"
)

// GetFilesJSON returns a JSON representation of one or more FileRecords
func GetFilesJSON(ID int, resChan chan []byte) {
	// Check for a valid integer ID
	if ID > 0 {
		// Load file
		file := new(FileRecord).Load(ID, "id")

		// Marshal into JSON
		res, err := json.Marshal(file)
		if err != nil {
			log.Println(err.Error())
			resChan <- nil
		}

		// Return status
		resChan <- res
	}

	resChan <- nil
}

<|edits_diff|>
--- goat/apiFiles.go
+++ goat/apiFiles.go
@@ -17,10 +17,12 @@
 		if err != nil {
 			log.Println(err.Error())
 			resChan <- nil
+			return
 		}

 		// Return status
 		resChan <- res
+		return
 	}

 	resChan <- nil
<|current_version|>
package goat

import (
	"encoding/json"
	"log"
)

// GetFilesJSON returns a JSON representation of one or more FileRecords
func GetFilesJSON(ID int, resChan chan []byte) {
	// Check for a valid integer ID
	if ID > 0 {
		// Load file
		file := new(FileRecord).Load(ID, "id")

		// Marshal into JSON
		res, err := json.Marshal(file)
		if err != nil {
			log.Println(err.Error())
			resChan <- nil
			return
		}

		// Return status
		resChan <- res
		return
	}

	resChan <- nil
}

<|next_version|>
package goat

import (
	"encoding/json"
	"log"
)

// GetFilesJSON returns a JSON representation of one or more FileRecords
func GetFilesJSON(ID int, resChan chan []byte) {
	// Check for a valid integer ID
	if ID > 0 {
		// Load file
		file := new(FileRecord).Load(ID, "id")

		// Marshal into JSON
		res, err := json.Marshal(file)
		if err != nil {
			log.Println(err.Error())
			resChan <- nil
			return
		}

		// Return status
		resChan <- res
		return
	}

	resChan <- nil
	return
}


Add a Entry.String method for debugging

Add a Entry.String method for debugging

println ftw.

--- scoring/entry.go
+++ scoring/entry.go
@@ -1,4 +1,6 @@
 package scoring
+
+import "fmt"

 // An entry represents a path and a score.
 type Entry struct {
@@ -16,6 +18,10 @@
 	return e.Score.Calculate()
 }

+func (e *Entry) String() string {
+	return fmt.Sprintf("{%s %s}", e.Path, e.Score)
+}
+
 // Create a new entry with the specified path. The score is created with
 // NewScore.
 func NewEntry(path string) *Entry {

<|original_code|>
package scoring

// An entry represents a path and a score.
type Entry struct {
	Path  string
	Score *Score
}

// Update the score for an entry.
func (e *Entry) UpdateScore() {
	e.Score.Update()
}

// Calculates the score for an entry.
func (e *Entry) CalculateScore() float64 {
	return e.Score.Calculate()
}

// Create a new entry with the specified path. The score is created with
// NewScore.
func NewEntry(path string) *Entry {
	return &Entry{path, NewScore()}
}

<|edits_diff|>
--- scoring/entry.go
+++ scoring/entry.go
@@ -1,4 +1,6 @@
 package scoring
+
+import "fmt"

 // An entry represents a path and a score.
 type Entry struct {
<|current_version|>
package scoring

import "fmt"

// An entry represents a path and a score.
type Entry struct {
	Path  string
	Score *Score
}

// Update the score for an entry.
func (e *Entry) UpdateScore() {
	e.Score.Update()
}

// Calculates the score for an entry.
func (e *Entry) CalculateScore() float64 {
	return e.Score.Calculate()
}

// Create a new entry with the specified path. The score is created with
// NewScore.
func NewEntry(path string) *Entry {
	return &Entry{path, NewScore()}
}

<|next_version|>
package scoring

import "fmt"

// An entry represents a path and a score.
type Entry struct {
	Path  string
	Score *Score
}

// Update the score for an entry.
func (e *Entry) UpdateScore() {
	e.Score.Update()
}

// Calculates the score for an entry.
func (e *Entry) CalculateScore() float64 {
	return e.Score.Calculate()
}

func (e *Entry) String() string {
	return fmt.Sprintf("{%s %s}", e.Path, e.Score)
}

// Create a new entry with the specified path. The score is created with
// NewScore.
func NewEntry(path string) *Entry {
	return &Entry{path, NewScore()}
}


Add more necessary methods to Transcoder interface

--- transcode/transcode.go
+++ transcode/transcode.go
@@ -2,6 +2,8 @@

 import (
 	"errors"
+
+	"github.com/mdlayher/wavepipe/data"
 )

 var (
@@ -21,6 +23,9 @@
 // for a transcoder
 type Transcoder interface {
 	Codec() string
+	FFmpeg() *FFmpeg
+	MIMEType() string
+	SetSong(*data.Song)
 	Quality() string
 }

<|original_code|>
package transcode

import (
	"errors"
)

var (
	// ErrInvalidCodec is returned when an invalid transcoder codec is selected
	ErrInvalidCodec = errors.New("transcode: no such transcoder codec")
	// ErrInvalidQuality is returned when an invalid quality is selected for a given codec
	ErrInvalidQuality = errors.New("transcode: invalid quality for transcoder codec")
)

// Enabled determines whether transcoding is available and enabled for wavepipe
var Enabled bool

// FFmpegPath is the path to the ffmpeg binary detected by the transcode manager
var FFmpegPath string

// Transcoder represents a transcoding operation, and the methods which must be defined
// for a transcoder
type Transcoder interface {
	Codec() string
	Quality() string
}

// Factory generates a new Transcoder depending on the input parameters
func Factory(codec string, quality string) (Transcoder, error) {
	// Check for a valid codec
	switch codec {
	// MP3
	case "mp3", "MP3":
		return NewMP3Transcoder(quality)
	// Invalid choice
	default:
		return nil, ErrInvalidCodec
	}
}

<|edits_diff|>
--- transcode/transcode.go
+++ transcode/transcode.go
@@ -2,6 +2,8 @@

 import (
 	"errors"
+
+	"github.com/mdlayher/wavepipe/data"
 )

 var (
<|current_version|>
package transcode

import (
	"errors"

	"github.com/mdlayher/wavepipe/data"
)

var (
	// ErrInvalidCodec is returned when an invalid transcoder codec is selected
	ErrInvalidCodec = errors.New("transcode: no such transcoder codec")
	// ErrInvalidQuality is returned when an invalid quality is selected for a given codec
	ErrInvalidQuality = errors.New("transcode: invalid quality for transcoder codec")
)

// Enabled determines whether transcoding is available and enabled for wavepipe
var Enabled bool

// FFmpegPath is the path to the ffmpeg binary detected by the transcode manager
var FFmpegPath string

// Transcoder represents a transcoding operation, and the methods which must be defined
// for a transcoder
type Transcoder interface {
	Codec() string
	Quality() string
}

// Factory generates a new Transcoder depending on the input parameters
func Factory(codec string, quality string) (Transcoder, error) {
	// Check for a valid codec
	switch codec {
	// MP3
	case "mp3", "MP3":
		return NewMP3Transcoder(quality)
	// Invalid choice
	default:
		return nil, ErrInvalidCodec
	}
}

<|next_version|>
package transcode

import (
	"errors"

	"github.com/mdlayher/wavepipe/data"
)

var (
	// ErrInvalidCodec is returned when an invalid transcoder codec is selected
	ErrInvalidCodec = errors.New("transcode: no such transcoder codec")
	// ErrInvalidQuality is returned when an invalid quality is selected for a given codec
	ErrInvalidQuality = errors.New("transcode: invalid quality for transcoder codec")
)

// Enabled determines whether transcoding is available and enabled for wavepipe
var Enabled bool

// FFmpegPath is the path to the ffmpeg binary detected by the transcode manager
var FFmpegPath string

// Transcoder represents a transcoding operation, and the methods which must be defined
// for a transcoder
type Transcoder interface {
	Codec() string
	FFmpeg() *FFmpeg
	MIMEType() string
	SetSong(*data.Song)
	Quality() string
}

// Factory generates a new Transcoder depending on the input parameters
func Factory(codec string, quality string) (Transcoder, error) {
	// Check for a valid codec
	switch codec {
	// MP3
	case "mp3", "MP3":
		return NewMP3Transcoder(quality)
	// Invalid choice
	default:
		return nil, ErrInvalidCodec
	}
}


Add pixel diff to list of recognized tasks

BUG=skia:6778

Change-Id: I61a9562930516f88e1f6308d9a36eda4978f129a
Reviewed-on: https://skia-review.googlesource.com/20600
Reviewed-by: Ravi Mistry <9fa2e7438b8cb730f96b74865492597170561628@google.com>
Commit-Queue: Ravi Mistry <9fa2e7438b8cb730f96b74865492597170561628@google.com>

--- ct/go/ctfe/task_types/task_types.go
+++ ct/go/ctfe/task_types/task_types.go
@@ -11,6 +11,7 @@
 	"go.skia.org/infra/ct/go/ctfe/chromium_builds"
 	"go.skia.org/infra/ct/go/ctfe/chromium_perf"
 	"go.skia.org/infra/ct/go/ctfe/lua_scripts"
+	"go.skia.org/infra/ct/go/ctfe/pixel_diff"
 	"go.skia.org/infra/ct/go/ctfe/task_common"
 )

@@ -19,6 +20,7 @@
 	return []task_common.Task{
 		&chromium_analysis.DBTask{},
 		&chromium_perf.DBTask{},
+		&pixel_diff.DBTask{},
 		&capture_skps.DBTask{},
 		&lua_scripts.DBTask{},
 		&chromium_builds.DBTask{},

<|original_code|>
/*
	List of all task types.
*/

package task_types

import (
	"go.skia.org/infra/ct/go/ctfe/admin_tasks"
	"go.skia.org/infra/ct/go/ctfe/capture_skps"
	"go.skia.org/infra/ct/go/ctfe/chromium_analysis"
	"go.skia.org/infra/ct/go/ctfe/chromium_builds"
	"go.skia.org/infra/ct/go/ctfe/chromium_perf"
	"go.skia.org/infra/ct/go/ctfe/lua_scripts"
	"go.skia.org/infra/ct/go/ctfe/task_common"
)

// Slice of all tasks supported by CTFE.
func Prototypes() []task_common.Task {
	return []task_common.Task{
		&chromium_analysis.DBTask{},
		&chromium_perf.DBTask{},
		&capture_skps.DBTask{},
		&lua_scripts.DBTask{},
		&chromium_builds.DBTask{},
		&admin_tasks.RecreatePageSetsDBTask{},
		&admin_tasks.RecreateWebpageArchivesDBTask{},
	}
}

<|edits_diff|>
--- ct/go/ctfe/task_types/task_types.go
+++ ct/go/ctfe/task_types/task_types.go
@@ -11,6 +11,7 @@
 	"go.skia.org/infra/ct/go/ctfe/chromium_builds"
 	"go.skia.org/infra/ct/go/ctfe/chromium_perf"
 	"go.skia.org/infra/ct/go/ctfe/lua_scripts"
+	"go.skia.org/infra/ct/go/ctfe/pixel_diff"
 	"go.skia.org/infra/ct/go/ctfe/task_common"
 )

<|current_version|>
/*
	List of all task types.
*/

package task_types

import (
	"go.skia.org/infra/ct/go/ctfe/admin_tasks"
	"go.skia.org/infra/ct/go/ctfe/capture_skps"
	"go.skia.org/infra/ct/go/ctfe/chromium_analysis"
	"go.skia.org/infra/ct/go/ctfe/chromium_builds"
	"go.skia.org/infra/ct/go/ctfe/chromium_perf"
	"go.skia.org/infra/ct/go/ctfe/lua_scripts"
	"go.skia.org/infra/ct/go/ctfe/pixel_diff"
	"go.skia.org/infra/ct/go/ctfe/task_common"
)

// Slice of all tasks supported by CTFE.
func Prototypes() []task_common.Task {
	return []task_common.Task{
		&chromium_analysis.DBTask{},
		&chromium_perf.DBTask{},
		&capture_skps.DBTask{},
		&lua_scripts.DBTask{},
		&chromium_builds.DBTask{},
		&admin_tasks.RecreatePageSetsDBTask{},
		&admin_tasks.RecreateWebpageArchivesDBTask{},
	}
}

<|next_version|>
/*
	List of all task types.
*/

package task_types

import (
	"go.skia.org/infra/ct/go/ctfe/admin_tasks"
	"go.skia.org/infra/ct/go/ctfe/capture_skps"
	"go.skia.org/infra/ct/go/ctfe/chromium_analysis"
	"go.skia.org/infra/ct/go/ctfe/chromium_builds"
	"go.skia.org/infra/ct/go/ctfe/chromium_perf"
	"go.skia.org/infra/ct/go/ctfe/lua_scripts"
	"go.skia.org/infra/ct/go/ctfe/pixel_diff"
	"go.skia.org/infra/ct/go/ctfe/task_common"
)

// Slice of all tasks supported by CTFE.
func Prototypes() []task_common.Task {
	return []task_common.Task{
		&chromium_analysis.DBTask{},
		&chromium_perf.DBTask{},
		&pixel_diff.DBTask{},
		&capture_skps.DBTask{},
		&lua_scripts.DBTask{},
		&chromium_builds.DBTask{},
		&admin_tasks.RecreatePageSetsDBTask{},
		&admin_tasks.RecreateWebpageArchivesDBTask{},
	}
}


Add messages around synchronizing clients

--- main.go
+++ main.go
@@ -1,6 +1,7 @@
 package main

 import (
+	"fmt"
 	"os"
 	"strings"
 	"time"
@@ -18,8 +19,10 @@
 		Behaviors: behaviors,
 	}

+	fmt.Println("Waiting 1 second for test clients to come online")
 	time.Sleep(1 * time.Second)

+	fmt.Println("Begining matrix of tests")
 	results := BeginMatrixTest(matrix)

 	OutputResults(results)

<|original_code|>
package main

import (
	"os"
	"strings"
	"time"
)

func main() {

	clients := strings.Split(os.Getenv("XLANG_CLIENTS"), ",")
	servers := strings.Split(os.Getenv("XLANG_SERVERS"), ",")
	behaviors := strings.Split(os.Getenv("XLANG_BEHAVIORS"), ",")

	matrix := Matrix{
		Clients:   clients,
		Servers:   servers,
		Behaviors: behaviors,
	}

	time.Sleep(1 * time.Second)

	results := BeginMatrixTest(matrix)

	OutputResults(results)
}

<|edits_diff|>
--- main.go
+++ main.go
@@ -1,6 +1,7 @@
 package main

 import (
+	"fmt"
 	"os"
 	"strings"
 	"time"
@@ -18,6 +19,7 @@
 		Behaviors: behaviors,
 	}

+	fmt.Println("Waiting 1 second for test clients to come online")
 	time.Sleep(1 * time.Second)

 	results := BeginMatrixTest(matrix)
<|current_version|>
package main

import (
	"fmt"
	"os"
	"strings"
	"time"
)

func main() {

	clients := strings.Split(os.Getenv("XLANG_CLIENTS"), ",")
	servers := strings.Split(os.Getenv("XLANG_SERVERS"), ",")
	behaviors := strings.Split(os.Getenv("XLANG_BEHAVIORS"), ",")

	matrix := Matrix{
		Clients:   clients,
		Servers:   servers,
		Behaviors: behaviors,
	}

	fmt.Println("Waiting 1 second for test clients to come online")
	time.Sleep(1 * time.Second)

	results := BeginMatrixTest(matrix)

	OutputResults(results)
}

<|next_version|>
package main

import (
	"fmt"
	"os"
	"strings"
	"time"
)

func main() {

	clients := strings.Split(os.Getenv("XLANG_CLIENTS"), ",")
	servers := strings.Split(os.Getenv("XLANG_SERVERS"), ",")
	behaviors := strings.Split(os.Getenv("XLANG_BEHAVIORS"), ",")

	matrix := Matrix{
		Clients:   clients,
		Servers:   servers,
		Behaviors: behaviors,
	}

	fmt.Println("Waiting 1 second for test clients to come online")
	time.Sleep(1 * time.Second)

	fmt.Println("Begining matrix of tests")
	results := BeginMatrixTest(matrix)

	OutputResults(results)
}


Add TicksPerSecond constant obtained from sysconf(_SC_CLK_TCK) call

--- utils.go
+++ utils.go
@@ -6,11 +6,20 @@
 	"strings"
 )

+// #include <unistd.h>
+import "C"
+
 var (
+	TicksPerSecond uint64
+
 	ErrUserNotFound      = errors.New("user not found")
 	ErrGroupNotFound     = errors.New("group not found")
 	ErrInvalidFileFormat = errors.New("invalid file format")
 )
+
+func init() {
+	TicksPerSecond = uint64(C.sysconf(C._SC_CLK_TCK))
+}

 func readSingleValueFile(path string) (string, error) {
 	content, err := ioutil.ReadFile(path)

<|original_code|>
package sysinfo

import (
	"errors"
	"io/ioutil"
	"strings"
)

var (
	ErrUserNotFound      = errors.New("user not found")
	ErrGroupNotFound     = errors.New("group not found")
	ErrInvalidFileFormat = errors.New("invalid file format")
)

func readSingleValueFile(path string) (string, error) {
	content, err := ioutil.ReadFile(path)
	if err != nil {
		return "", err
	}

	return strings.TrimSpace(string(content)), nil
}

<|edits_diff|>
--- utils.go
+++ utils.go
@@ -6,7 +6,12 @@
 	"strings"
 )

+// #include <unistd.h>
+import "C"
+
 var (
+	TicksPerSecond uint64
+
 	ErrUserNotFound      = errors.New("user not found")
 	ErrGroupNotFound     = errors.New("group not found")
 	ErrInvalidFileFormat = errors.New("invalid file format")
<|current_version|>
package sysinfo

import (
	"errors"
	"io/ioutil"
	"strings"
)

// #include <unistd.h>
import "C"

var (
	TicksPerSecond uint64

	ErrUserNotFound      = errors.New("user not found")
	ErrGroupNotFound     = errors.New("group not found")
	ErrInvalidFileFormat = errors.New("invalid file format")
)

func readSingleValueFile(path string) (string, error) {
	content, err := ioutil.ReadFile(path)
	if err != nil {
		return "", err
	}

	return strings.TrimSpace(string(content)), nil
}

<|next_version|>
package sysinfo

import (
	"errors"
	"io/ioutil"
	"strings"
)

// #include <unistd.h>
import "C"

var (
	TicksPerSecond uint64

	ErrUserNotFound      = errors.New("user not found")
	ErrGroupNotFound     = errors.New("group not found")
	ErrInvalidFileFormat = errors.New("invalid file format")
)

func init() {
	TicksPerSecond = uint64(C.sysconf(C._SC_CLK_TCK))
}

func readSingleValueFile(path string) (string, error) {
	content, err := ioutil.ReadFile(path)
	if err != nil {
		return "", err
	}

	return strings.TrimSpace(string(content)), nil
}


Print usage when incorrect parameters passed

If the incorrect number of parameters are passed the print the usage
string.

--- main.go
+++ main.go
@@ -10,6 +10,8 @@
 	"syscall"
 )

+var usage string = "setuidgid: usage: setuidgid username program [arg...]"
+
 func checkError(err error) {
 	if err != nil {
 		fmt.Println(err)
@@ -18,6 +20,11 @@
 }

 func main() {
+
+	if len(os.Args) <= 2 {
+		fmt.Print(usage)
+		os.Exit(100)
+	}

 	username := os.Args[1]
 	program := os.Args[2]

<|original_code|>
package main

import (
	"fmt"
	"os"
	"os/user"
	"path"
	"strconv"
	"strings"
	"syscall"
)

func checkError(err error) {
	if err != nil {
		fmt.Println(err)
		os.Exit(111)
	}
}

func main() {

	username := os.Args[1]
	program := os.Args[2]
	pargv := os.Args[2:]

	user, err := user.Lookup(username)
	checkError(err)

	uid, err := strconv.Atoi(user.Uid)
	checkError(err)
	gid, err := strconv.Atoi(user.Gid)
	checkError(err)

	err = syscall.Setgid(gid)
	checkError(err)
	err = syscall.Setuid(uid)
	checkError(err)

	if path.IsAbs(program) {
		err := syscall.Exec(program, pargv, os.Environ())
		checkError(err)
	}

	for _, p := range strings.Split(os.Getenv("PATH"), ":") {
		absPath := path.Join(p, program)
		err = syscall.Exec(absPath, pargv, os.Environ())
	}

	checkError(err)
}

<|edits_diff|>
--- main.go
+++ main.go
@@ -9,6 +9,8 @@
 	"strings"
 	"syscall"
 )
+
+var usage string = "setuidgid: usage: setuidgid username program [arg...]"

 func checkError(err error) {
 	if err != nil {
<|current_version|>
package main

import (
	"fmt"
	"os"
	"os/user"
	"path"
	"strconv"
	"strings"
	"syscall"
)

var usage string = "setuidgid: usage: setuidgid username program [arg...]"

func checkError(err error) {
	if err != nil {
		fmt.Println(err)
		os.Exit(111)
	}
}

func main() {

	username := os.Args[1]
	program := os.Args[2]
	pargv := os.Args[2:]

	user, err := user.Lookup(username)
	checkError(err)

	uid, err := strconv.Atoi(user.Uid)
	checkError(err)
	gid, err := strconv.Atoi(user.Gid)
	checkError(err)

	err = syscall.Setgid(gid)
	checkError(err)
	err = syscall.Setuid(uid)
	checkError(err)

	if path.IsAbs(program) {
		err := syscall.Exec(program, pargv, os.Environ())
		checkError(err)
	}

	for _, p := range strings.Split(os.Getenv("PATH"), ":") {
		absPath := path.Join(p, program)
		err = syscall.Exec(absPath, pargv, os.Environ())
	}

	checkError(err)
}

<|next_version|>
package main

import (
	"fmt"
	"os"
	"os/user"
	"path"
	"strconv"
	"strings"
	"syscall"
)

var usage string = "setuidgid: usage: setuidgid username program [arg...]"

func checkError(err error) {
	if err != nil {
		fmt.Println(err)
		os.Exit(111)
	}
}

func main() {

	if len(os.Args) <= 2 {
		fmt.Print(usage)
		os.Exit(100)
	}

	username := os.Args[1]
	program := os.Args[2]
	pargv := os.Args[2:]

	user, err := user.Lookup(username)
	checkError(err)

	uid, err := strconv.Atoi(user.Uid)
	checkError(err)
	gid, err := strconv.Atoi(user.Gid)
	checkError(err)

	err = syscall.Setgid(gid)
	checkError(err)
	err = syscall.Setuid(uid)
	checkError(err)

	if path.IsAbs(program) {
		err := syscall.Exec(program, pargv, os.Environ())
		checkError(err)
	}

	for _, p := range strings.Split(os.Getenv("PATH"), ":") {
		absPath := path.Join(p, program)
		err = syscall.Exec(absPath, pargv, os.Environ())
	}

	checkError(err)
}


Fix support for minus value

Fix support for minus value

--- gondom.go
+++ gondom.go
@@ -10,6 +10,9 @@
 )

 func Make(n int, seed int64) string {
+	if n < 0 {
+		n = n * -1
+	}
 	b := make([]byte, n)
 	rand.Seed(seed)
 	for i := range b {
@@ -19,6 +22,9 @@
 }

 func MakeURL(n int, seed int64) string {
+	if n < 0 {
+		n = n * -1
+	}
 	b := make([]byte, n)
 	rand.Seed(seed)
 	for i := range b {

<|original_code|>
package gondom

import (
	"math/rand"
)

const (
	_rawURLLetters = "abcdefghijklmnopqrstuvwxyz0123456789"
	_rawLetters    = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
)

func Make(n int, seed int64) string {
	b := make([]byte, n)
	rand.Seed(seed)
	for i := range b {
		b[i] = _rawLetters[rand.Intn(62)]
	}
	return string(b)
}

func MakeURL(n int, seed int64) string {
	b := make([]byte, n)
	rand.Seed(seed)
	for i := range b {
		b[i] = _rawURLLetters[rand.Intn(36)]
	}
	return string(b)
}

<|edits_diff|>
--- gondom.go
+++ gondom.go
@@ -10,6 +10,9 @@
 )

 func Make(n int, seed int64) string {
+	if n < 0 {
+		n = n * -1
+	}
 	b := make([]byte, n)
 	rand.Seed(seed)
 	for i := range b {
<|current_version|>
package gondom

import (
	"math/rand"
)

const (
	_rawURLLetters = "abcdefghijklmnopqrstuvwxyz0123456789"
	_rawLetters    = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
)

func Make(n int, seed int64) string {
	if n < 0 {
		n = n * -1
	}
	b := make([]byte, n)
	rand.Seed(seed)
	for i := range b {
		b[i] = _rawLetters[rand.Intn(62)]
	}
	return string(b)
}

func MakeURL(n int, seed int64) string {
	b := make([]byte, n)
	rand.Seed(seed)
	for i := range b {
		b[i] = _rawURLLetters[rand.Intn(36)]
	}
	return string(b)
}

<|next_version|>
package gondom

import (
	"math/rand"
)

const (
	_rawURLLetters = "abcdefghijklmnopqrstuvwxyz0123456789"
	_rawLetters    = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
)

func Make(n int, seed int64) string {
	if n < 0 {
		n = n * -1
	}
	b := make([]byte, n)
	rand.Seed(seed)
	for i := range b {
		b[i] = _rawLetters[rand.Intn(62)]
	}
	return string(b)
}

func MakeURL(n int, seed int64) string {
	if n < 0 {
		n = n * -1
	}
	b := make([]byte, n)
	rand.Seed(seed)
	for i := range b {
		b[i] = _rawURLLetters[rand.Intn(36)]
	}
	return string(b)
}


Add valid cases for later

Add valid cases for later

--- subvert_test.go
+++ subvert_test.go
@@ -11,10 +11,16 @@
 	dst *regexp.Regexp
 }{
 	{"abc", regexp.MustCompile(`(abc)`)},
+	{"abcdef", regexp.MustCompile(`(abcdef)`)},

 	{"a,b", regexp.MustCompile(`(a|b)`)},
+	{"a,bc,def", regexp.MustCompile(`(a|bc|def)`)},

 	{"a\\,b", regexp.MustCompile(`(a,b)`)},
+	{"a\\,bc\\,def", regexp.MustCompile(`(a,bc,def)`)},
+
+	{"a\\,b,c", regexp.MustCompile(`(a,b|c)`)},
+	{"a,bc\\,def", regexp.MustCompile(`(a|bc,def)`)},
 }

 func TestGenMatcher(t *testing.T) {

<|original_code|>
package main

import (
	"reflect"
	"regexp"
	"testing"
)

var genMatcherTests = []struct {
	src string
	dst *regexp.Regexp
}{
	{"abc", regexp.MustCompile(`(abc)`)},

	{"a,b", regexp.MustCompile(`(a|b)`)},

	{"a\\,b", regexp.MustCompile(`(a,b)`)},
}

func TestGenMatcher(t *testing.T) {
	for _, test := range genMatcherTests {
		expect := test.dst
		actual, err := newMatcher(test.src)
		if err != nil {
			t.Errorf("NewSubvert(%q) returns %q, want nil",
				test.src, err)
		}
		if !reflect.DeepEqual(actual, expect) {
			t.Errorf("%q: got %q, want %q",
				test.src, actual, expect)
		}
	}
}

<|edits_diff|>
--- subvert_test.go
+++ subvert_test.go
@@ -11,8 +11,10 @@
 	dst *regexp.Regexp
 }{
 	{"abc", regexp.MustCompile(`(abc)`)},
+	{"abcdef", regexp.MustCompile(`(abcdef)`)},

 	{"a,b", regexp.MustCompile(`(a|b)`)},
+	{"a,bc,def", regexp.MustCompile(`(a|bc|def)`)},

 	{"a\\,b", regexp.MustCompile(`(a,b)`)},
 }
<|current_version|>
package main

import (
	"reflect"
	"regexp"
	"testing"
)

var genMatcherTests = []struct {
	src string
	dst *regexp.Regexp
}{
	{"abc", regexp.MustCompile(`(abc)`)},
	{"abcdef", regexp.MustCompile(`(abcdef)`)},

	{"a,b", regexp.MustCompile(`(a|b)`)},
	{"a,bc,def", regexp.MustCompile(`(a|bc|def)`)},

	{"a\\,b", regexp.MustCompile(`(a,b)`)},
}

func TestGenMatcher(t *testing.T) {
	for _, test := range genMatcherTests {
		expect := test.dst
		actual, err := newMatcher(test.src)
		if err != nil {
			t.Errorf("NewSubvert(%q) returns %q, want nil",
				test.src, err)
		}
		if !reflect.DeepEqual(actual, expect) {
			t.Errorf("%q: got %q, want %q",
				test.src, actual, expect)
		}
	}
}

<|next_version|>
package main

import (
	"reflect"
	"regexp"
	"testing"
)

var genMatcherTests = []struct {
	src string
	dst *regexp.Regexp
}{
	{"abc", regexp.MustCompile(`(abc)`)},
	{"abcdef", regexp.MustCompile(`(abcdef)`)},

	{"a,b", regexp.MustCompile(`(a|b)`)},
	{"a,bc,def", regexp.MustCompile(`(a|bc|def)`)},

	{"a\\,b", regexp.MustCompile(`(a,b)`)},
	{"a\\,bc\\,def", regexp.MustCompile(`(a,bc,def)`)},

	{"a\\,b,c", regexp.MustCompile(`(a,b|c)`)},
	{"a,bc\\,def", regexp.MustCompile(`(a|bc,def)`)},
}

func TestGenMatcher(t *testing.T) {
	for _, test := range genMatcherTests {
		expect := test.dst
		actual, err := newMatcher(test.src)
		if err != nil {
			t.Errorf("NewSubvert(%q) returns %q, want nil",
				test.src, err)
		}
		if !reflect.DeepEqual(actual, expect) {
			t.Errorf("%q: got %q, want %q",
				test.src, actual, expect)
		}
	}
}


Add check for multiplication overflow in ptypes.ReverseInt function

--- ptypes/reverseint.go
+++ ptypes/reverseint.go
@@ -11,6 +11,7 @@
 // The time complexity is O(n), where n is the number of digits in x.
 // The space complexity is O(1).
 func ReverseInt(x int64) (r int64, ok bool) {
+	const cutoff = math.MaxInt64/10 + 1 // The first smallest number such that cutoff*10 > MaxInt64.
 	var n uint64

 	neg := x < 0
@@ -20,6 +21,9 @@
 	}

 	for u > 0 {
+		if n >= cutoff { // Check if n*10 overflows.
+			return 0, false // TODO: cover this in tests!
+		}
 		n = n*10 + u%10
 		if neg && n > -math.MinInt64 || !neg && n > math.MaxInt64 { // -n < math.MinInt64 || n > math.MaxInt64
 			return 0, false

<|original_code|>
// Copyright (c) 2015, Peter Mrekaj. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE.txt file.

package ptypes

import "math"

// ReverseInt returns reversed x digits.
// 0, false is returned if x cannot be reversed because of int64 overflow.
// The time complexity is O(n), where n is the number of digits in x.
// The space complexity is O(1).
func ReverseInt(x int64) (r int64, ok bool) {
	var n uint64

	neg := x < 0
	u := uint64(x)
	if neg {
		u = -u
	}

	for u > 0 {
		n = n*10 + u%10
		if neg && n > -math.MinInt64 || !neg && n > math.MaxInt64 { // -n < math.MinInt64 || n > math.MaxInt64
			return 0, false
		}
		u /= 10
	}

	r = int64(n)
	if neg {
		r = -r
	}
	return r, true
}

<|edits_diff|>
--- ptypes/reverseint.go
+++ ptypes/reverseint.go
@@ -11,6 +11,7 @@
 // The time complexity is O(n), where n is the number of digits in x.
 // The space complexity is O(1).
 func ReverseInt(x int64) (r int64, ok bool) {
+	const cutoff = math.MaxInt64/10 + 1 // The first smallest number such that cutoff*10 > MaxInt64.
 	var n uint64

 	neg := x < 0
<|current_version|>
// Copyright (c) 2015, Peter Mrekaj. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE.txt file.

package ptypes

import "math"

// ReverseInt returns reversed x digits.
// 0, false is returned if x cannot be reversed because of int64 overflow.
// The time complexity is O(n), where n is the number of digits in x.
// The space complexity is O(1).
func ReverseInt(x int64) (r int64, ok bool) {
	const cutoff = math.MaxInt64/10 + 1 // The first smallest number such that cutoff*10 > MaxInt64.
	var n uint64

	neg := x < 0
	u := uint64(x)
	if neg {
		u = -u
	}

	for u > 0 {
		n = n*10 + u%10
		if neg && n > -math.MinInt64 || !neg && n > math.MaxInt64 { // -n < math.MinInt64 || n > math.MaxInt64
			return 0, false
		}
		u /= 10
	}

	r = int64(n)
	if neg {
		r = -r
	}
	return r, true
}

<|next_version|>
// Copyright (c) 2015, Peter Mrekaj. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE.txt file.

package ptypes

import "math"

// ReverseInt returns reversed x digits.
// 0, false is returned if x cannot be reversed because of int64 overflow.
// The time complexity is O(n), where n is the number of digits in x.
// The space complexity is O(1).
func ReverseInt(x int64) (r int64, ok bool) {
	const cutoff = math.MaxInt64/10 + 1 // The first smallest number such that cutoff*10 > MaxInt64.
	var n uint64

	neg := x < 0
	u := uint64(x)
	if neg {
		u = -u
	}

	for u > 0 {
		if n >= cutoff { // Check if n*10 overflows.
			return 0, false // TODO: cover this in tests!
		}
		n = n*10 + u%10
		if neg && n > -math.MinInt64 || !neg && n > math.MaxInt64 { // -n < math.MinInt64 || n > math.MaxInt64
			return 0, false
		}
		u /= 10
	}

	r = int64(n)
	if neg {
		r = -r
	}
	return r, true
}


Add missing documentation to exported types

--- lib/writer.go
+++ lib/writer.go
@@ -7,12 +7,15 @@
 	"os"
 )

+// ASTWriter writes the ast.File to the provided filename
 type ASTWriter interface {
 	Write(file *ast.File, filename string) error
 }

+// DiskASTWriter saves an AST to disk
 type DiskASTWriter struct{}

+// Write outputs the ast.File to a file on disk specified by filename
 func (d *DiskASTWriter) Write(file *ast.File, filename string) error {
 	spyFile, err := os.Create(filename)
 	if err != nil {

<|original_code|>
package fm

import (
	"go/ast"
	"go/format"
	"go/token"
	"os"
)

type ASTWriter interface {
	Write(file *ast.File, filename string) error
}

type DiskASTWriter struct{}

func (d *DiskASTWriter) Write(file *ast.File, filename string) error {
	spyFile, err := os.Create(filename)
	if err != nil {
		return err
	}

	return format.Node(spyFile, token.NewFileSet(), file)
}

<|edits_diff|>
--- lib/writer.go
+++ lib/writer.go
@@ -7,10 +7,12 @@
 	"os"
 )

+// ASTWriter writes the ast.File to the provided filename
 type ASTWriter interface {
 	Write(file *ast.File, filename string) error
 }

+// DiskASTWriter saves an AST to disk
 type DiskASTWriter struct{}

 func (d *DiskASTWriter) Write(file *ast.File, filename string) error {
<|current_version|>
package fm

import (
	"go/ast"
	"go/format"
	"go/token"
	"os"
)

// ASTWriter writes the ast.File to the provided filename
type ASTWriter interface {
	Write(file *ast.File, filename string) error
}

// DiskASTWriter saves an AST to disk
type DiskASTWriter struct{}

func (d *DiskASTWriter) Write(file *ast.File, filename string) error {
	spyFile, err := os.Create(filename)
	if err != nil {
		return err
	}

	return format.Node(spyFile, token.NewFileSet(), file)
}

<|next_version|>
package fm

import (
	"go/ast"
	"go/format"
	"go/token"
	"os"
)

// ASTWriter writes the ast.File to the provided filename
type ASTWriter interface {
	Write(file *ast.File, filename string) error
}

// DiskASTWriter saves an AST to disk
type DiskASTWriter struct{}

// Write outputs the ast.File to a file on disk specified by filename
func (d *DiskASTWriter) Write(file *ast.File, filename string) error {
	spyFile, err := os.Create(filename)
	if err != nil {
		return err
	}

	return format.Node(spyFile, token.NewFileSet(), file)
}


Load JsonPermission in LoadGameRules func. Currently using the working path for loading of users.json and groups.json

--- src/chunkymonkey/gamerules/gamerules.go
+++ src/chunkymonkey/gamerules/gamerules.go
@@ -4,6 +4,7 @@
 	"os"

 	"chunkymonkey/command"
+	"chunkymonkey/permission"
 )

 // GameRules is a container type for block, item and recipe definitions.
@@ -13,6 +14,7 @@
 	Recipes          *RecipeSet
 	FurnaceReactions FurnaceData
 	CommandFramework *command.CommandFramework
+	Permissions      permission.IPermissions
 )

 func LoadGameRules(blocksDefFile, itemsDefFile, recipesDefFile, furnaceDefFile string) (err os.Error) {
@@ -41,5 +43,10 @@
 	// TODO: Load the prefix from a config file
 	CommandFramework = command.NewCommandFramework("/")

+	Permissions, err = permission.LoadJsonPermission("./")
+	if err != nil {
+		return
+	}
+
 	return
 }

<|original_code|>
package gamerules

import (
	"os"

	"chunkymonkey/command"
)

// GameRules is a container type for block, item and recipe definitions.
var (
	Blocks           BlockTypeList
	Items            ItemTypeMap
	Recipes          *RecipeSet
	FurnaceReactions FurnaceData
	CommandFramework *command.CommandFramework
)

func LoadGameRules(blocksDefFile, itemsDefFile, recipesDefFile, furnaceDefFile string) (err os.Error) {
	Blocks, err = LoadBlocksFromFile(blocksDefFile)
	if err != nil {
		return
	}

	Items, err = LoadItemTypesFromFile(itemsDefFile)
	if err != nil {
		return
	}

	Blocks.CreateBlockItemTypes(Items)

	Recipes, err = LoadRecipesFromFile(recipesDefFile, Items)
	if err != nil {
		return
	}

	FurnaceReactions, err = LoadFurnaceDataFromFile(furnaceDefFile)
	if err != nil {
		return
	}

	// TODO: Load the prefix from a config file
	CommandFramework = command.NewCommandFramework("/")

	return
}

<|edits_diff|>
--- src/chunkymonkey/gamerules/gamerules.go
+++ src/chunkymonkey/gamerules/gamerules.go
@@ -4,6 +4,7 @@
 	"os"

 	"chunkymonkey/command"
+	"chunkymonkey/permission"
 )

 // GameRules is a container type for block, item and recipe definitions.
@@ -13,6 +14,7 @@
 	Recipes          *RecipeSet
 	FurnaceReactions FurnaceData
 	CommandFramework *command.CommandFramework
+	Permissions      permission.IPermissions
 )

 func LoadGameRules(blocksDefFile, itemsDefFile, recipesDefFile, furnaceDefFile string) (err os.Error) {
<|current_version|>
package gamerules

import (
	"os"

	"chunkymonkey/command"
	"chunkymonkey/permission"
)

// GameRules is a container type for block, item and recipe definitions.
var (
	Blocks           BlockTypeList
	Items            ItemTypeMap
	Recipes          *RecipeSet
	FurnaceReactions FurnaceData
	CommandFramework *command.CommandFramework
	Permissions      permission.IPermissions
)

func LoadGameRules(blocksDefFile, itemsDefFile, recipesDefFile, furnaceDefFile string) (err os.Error) {
	Blocks, err = LoadBlocksFromFile(blocksDefFile)
	if err != nil {
		return
	}

	Items, err = LoadItemTypesFromFile(itemsDefFile)
	if err != nil {
		return
	}

	Blocks.CreateBlockItemTypes(Items)

	Recipes, err = LoadRecipesFromFile(recipesDefFile, Items)
	if err != nil {
		return
	}

	FurnaceReactions, err = LoadFurnaceDataFromFile(furnaceDefFile)
	if err != nil {
		return
	}

	// TODO: Load the prefix from a config file
	CommandFramework = command.NewCommandFramework("/")

	return
}

<|next_version|>
package gamerules

import (
	"os"

	"chunkymonkey/command"
	"chunkymonkey/permission"
)

// GameRules is a container type for block, item and recipe definitions.
var (
	Blocks           BlockTypeList
	Items            ItemTypeMap
	Recipes          *RecipeSet
	FurnaceReactions FurnaceData
	CommandFramework *command.CommandFramework
	Permissions      permission.IPermissions
)

func LoadGameRules(blocksDefFile, itemsDefFile, recipesDefFile, furnaceDefFile string) (err os.Error) {
	Blocks, err = LoadBlocksFromFile(blocksDefFile)
	if err != nil {
		return
	}

	Items, err = LoadItemTypesFromFile(itemsDefFile)
	if err != nil {
		return
	}

	Blocks.CreateBlockItemTypes(Items)

	Recipes, err = LoadRecipesFromFile(recipesDefFile, Items)
	if err != nil {
		return
	}

	FurnaceReactions, err = LoadFurnaceDataFromFile(furnaceDefFile)
	if err != nil {
		return
	}

	// TODO: Load the prefix from a config file
	CommandFramework = command.NewCommandFramework("/")

	Permissions, err = permission.LoadJsonPermission("./")
	if err != nil {
		return
	}

	return
}


Exit on failure to listen over HTTP

Exit on failure to listen over HTTP

--- goat/listener.go
+++ goat/listener.go
@@ -3,6 +3,7 @@
 import (
 	"log"
 	"net"
+	"os"
 	"strconv"
 )

@@ -21,6 +22,8 @@
 	l, err := net.Listen("tcp", ":"+strconv.Itoa(Static.Config.Port))
 	if err != nil {
 		log.Println(err.Error())
+		log.Println("Cannot start HTTP server, exiting now.")
+		os.Exit(1)
 	}

 	// Send listener to HttpConnHandler

<|original_code|>
package goat

import (
	"log"
	"net"
	"strconv"
)

// Listener interface method Listen defines a network listener which accepts connections
type Listener interface {
	Listen(chan bool)
}

// HTTPListener listens for HTTP (TCP) connections
type HTTPListener struct {
}

// Listen and handle HTTP (TCP) connections
func (h HTTPListener) Listen(httpDoneChan chan bool) {
	// Listen on specified TCP port
	l, err := net.Listen("tcp", ":"+strconv.Itoa(Static.Config.Port))
	if err != nil {
		log.Println(err.Error())
	}

	// Send listener to HttpConnHandler
	go new(HTTPConnHandler).Handle(l, httpDoneChan)
}

// UDPListener listens for UDP connections
type UDPListener struct {
}

// Listen on specified UDP port, accept and handle connections
func (u UDPListener) Listen(udpDoneChan chan bool) {
	// Listen on specified UDP port
	addr, err := net.ResolveUDPAddr("udp", ":"+strconv.Itoa(Static.Config.Port))
	l, err := net.ListenUDP("udp", addr)
	if err != nil {
		log.Println(err.Error())
	}

	// Send listener to UdpConnHandler
	go new(UDPConnHandler).Handle(l, udpDoneChan)
}

<|edits_diff|>
--- goat/listener.go
+++ goat/listener.go
@@ -3,6 +3,7 @@
 import (
 	"log"
 	"net"
+	"os"
 	"strconv"
 )

<|current_version|>
package goat

import (
	"log"
	"net"
	"os"
	"strconv"
)

// Listener interface method Listen defines a network listener which accepts connections
type Listener interface {
	Listen(chan bool)
}

// HTTPListener listens for HTTP (TCP) connections
type HTTPListener struct {
}

// Listen and handle HTTP (TCP) connections
func (h HTTPListener) Listen(httpDoneChan chan bool) {
	// Listen on specified TCP port
	l, err := net.Listen("tcp", ":"+strconv.Itoa(Static.Config.Port))
	if err != nil {
		log.Println(err.Error())
	}

	// Send listener to HttpConnHandler
	go new(HTTPConnHandler).Handle(l, httpDoneChan)
}

// UDPListener listens for UDP connections
type UDPListener struct {
}

// Listen on specified UDP port, accept and handle connections
func (u UDPListener) Listen(udpDoneChan chan bool) {
	// Listen on specified UDP port
	addr, err := net.ResolveUDPAddr("udp", ":"+strconv.Itoa(Static.Config.Port))
	l, err := net.ListenUDP("udp", addr)
	if err != nil {
		log.Println(err.Error())
	}

	// Send listener to UdpConnHandler
	go new(UDPConnHandler).Handle(l, udpDoneChan)
}

<|next_version|>
package goat

import (
	"log"
	"net"
	"os"
	"strconv"
)

// Listener interface method Listen defines a network listener which accepts connections
type Listener interface {
	Listen(chan bool)
}

// HTTPListener listens for HTTP (TCP) connections
type HTTPListener struct {
}

// Listen and handle HTTP (TCP) connections
func (h HTTPListener) Listen(httpDoneChan chan bool) {
	// Listen on specified TCP port
	l, err := net.Listen("tcp", ":"+strconv.Itoa(Static.Config.Port))
	if err != nil {
		log.Println(err.Error())
		log.Println("Cannot start HTTP server, exiting now.")
		os.Exit(1)
	}

	// Send listener to HttpConnHandler
	go new(HTTPConnHandler).Handle(l, httpDoneChan)
}

// UDPListener listens for UDP connections
type UDPListener struct {
}

// Listen on specified UDP port, accept and handle connections
func (u UDPListener) Listen(udpDoneChan chan bool) {
	// Listen on specified UDP port
	addr, err := net.ResolveUDPAddr("udp", ":"+strconv.Itoa(Static.Config.Port))
	l, err := net.ListenUDP("udp", addr)
	if err != nil {
		log.Println(err.Error())
	}

	// Send listener to UdpConnHandler
	go new(UDPConnHandler).Handle(l, udpDoneChan)
}


Add debug flag for logger

Add debug flag for logger

--- citadel/main.go
+++ citadel/main.go
@@ -22,12 +22,16 @@

 	app.Before = func(context *cli.Context) error {
 		registry = citadel.NewRegistry(context.GlobalStringSlice("etcd-machines"))
+		if context.GlobalBool("debug") {
+			logger.Level = logrus.Debug
+		}

 		return nil
 	}

 	app.Flags = []cli.Flag{
 		cli.StringSliceFlag{"etcd-machines", &cli.StringSlice{"http://127.0.0.1:4001"}, "etcd hosts"},
+		cli.BoolFlag{"debug", "run the logger at the debug level"},
 	}

 	app.Commands = []cli.Command{

<|original_code|>
package main

import (
	"os"

	"github.com/Sirupsen/logrus"
	"github.com/citadel/citadel"
	"github.com/codegangsta/cli"
)

var (
	logger   = logrus.New()
	registry citadel.Registry
)

func main() {
	app := cli.NewApp()
	app.Usage = "mangage your docker containers across hosts"
	app.Name = "citadel"
	app.Version = "0.1"
	app.Author = "citadel team"

	app.Before = func(context *cli.Context) error {
		registry = citadel.NewRegistry(context.GlobalStringSlice("etcd-machines"))

		return nil
	}

	app.Flags = []cli.Flag{
		cli.StringSliceFlag{"etcd-machines", &cli.StringSlice{"http://127.0.0.1:4001"}, "etcd hosts"},
	}

	app.Commands = []cli.Command{
		appCommand,
		deleteCommand,
		startCommand,
		stopCommand,
		loadCommand,
		liveCommand,
		containerCommand,
		hostCommand,
		hostsCommand,
		managementCommand,
	}

	if err := app.Run(os.Args); err != nil {
		logger.Fatal(err)
	}
}

<|edits_diff|>
--- citadel/main.go
+++ citadel/main.go
@@ -22,6 +22,9 @@

 	app.Before = func(context *cli.Context) error {
 		registry = citadel.NewRegistry(context.GlobalStringSlice("etcd-machines"))
+		if context.GlobalBool("debug") {
+			logger.Level = logrus.Debug
+		}

 		return nil
 	}
<|current_version|>
package main

import (
	"os"

	"github.com/Sirupsen/logrus"
	"github.com/citadel/citadel"
	"github.com/codegangsta/cli"
)

var (
	logger   = logrus.New()
	registry citadel.Registry
)

func main() {
	app := cli.NewApp()
	app.Usage = "mangage your docker containers across hosts"
	app.Name = "citadel"
	app.Version = "0.1"
	app.Author = "citadel team"

	app.Before = func(context *cli.Context) error {
		registry = citadel.NewRegistry(context.GlobalStringSlice("etcd-machines"))
		if context.GlobalBool("debug") {
			logger.Level = logrus.Debug
		}

		return nil
	}

	app.Flags = []cli.Flag{
		cli.StringSliceFlag{"etcd-machines", &cli.StringSlice{"http://127.0.0.1:4001"}, "etcd hosts"},
	}

	app.Commands = []cli.Command{
		appCommand,
		deleteCommand,
		startCommand,
		stopCommand,
		loadCommand,
		liveCommand,
		containerCommand,
		hostCommand,
		hostsCommand,
		managementCommand,
	}

	if err := app.Run(os.Args); err != nil {
		logger.Fatal(err)
	}
}

<|next_version|>
package main

import (
	"os"

	"github.com/Sirupsen/logrus"
	"github.com/citadel/citadel"
	"github.com/codegangsta/cli"
)

var (
	logger   = logrus.New()
	registry citadel.Registry
)

func main() {
	app := cli.NewApp()
	app.Usage = "mangage your docker containers across hosts"
	app.Name = "citadel"
	app.Version = "0.1"
	app.Author = "citadel team"

	app.Before = func(context *cli.Context) error {
		registry = citadel.NewRegistry(context.GlobalStringSlice("etcd-machines"))
		if context.GlobalBool("debug") {
			logger.Level = logrus.Debug
		}

		return nil
	}

	app.Flags = []cli.Flag{
		cli.StringSliceFlag{"etcd-machines", &cli.StringSlice{"http://127.0.0.1:4001"}, "etcd hosts"},
		cli.BoolFlag{"debug", "run the logger at the debug level"},
	}

	app.Commands = []cli.Command{
		appCommand,
		deleteCommand,
		startCommand,
		stopCommand,
		loadCommand,
		liveCommand,
		containerCommand,
		hostCommand,
		hostsCommand,
		managementCommand,
	}

	if err := app.Run(os.Args); err != nil {
		logger.Fatal(err)
	}
}


Add warning banner to imageserver if in insecure mode.

--- imageserver/httpd/status.go
+++ imageserver/httpd/status.go
@@ -4,6 +4,7 @@
 	"bufio"
 	"fmt"
 	"github.com/Symantec/Dominator/lib/html"
+	"github.com/Symantec/Dominator/lib/srpc"
 	"net/http"
 )

@@ -14,6 +15,10 @@
 	fmt.Fprintln(writer, "")
 	fmt.Fprintln(writer, "")
 	fmt.Fprintln(writer, "
imageserver status page
")
+	if !srpc.CheckTlsRequired() {
+		fmt.Fprintln(writer,
+			`<h1><font color="red">Running in insecure mode. Your images can be pwned!!!</font></h1>`)
+	}
 	fmt.Fprintln(writer, "")
 	html.WriteHeaderWithRequest(writer, req)
 	fmt.Fprintln(writer, "
")

<|original_code|>
package httpd

import (
	"bufio"
	"fmt"
	"github.com/Symantec/Dominator/lib/html"
	"net/http"
)

func statusHandler(w http.ResponseWriter, req *http.Request) {
	writer := bufio.NewWriter(w)
	defer writer.Flush()
	fmt.Fprintln(writer, "<title>imageserver status page</title>")
	fmt.Fprintln(writer, "")
	fmt.Fprintln(writer, "")
	fmt.Fprintln(writer, "
imageserver status page
")
	fmt.Fprintln(writer, "")
	html.WriteHeaderWithRequest(writer, req)
	fmt.Fprintln(writer, "
")
	for _, htmlWriter := range htmlWriters {
		htmlWriter.WriteHtml(writer)
	}
	fmt.Fprintln(writer, "
")
	fmt.Fprintln(writer, "
")
	html.WriteFooter(writer)
	fmt.Fprintln(writer, "")
}

<|edits_diff|>
--- imageserver/httpd/status.go
+++ imageserver/httpd/status.go
@@ -4,6 +4,7 @@
 	"bufio"
 	"fmt"
 	"github.com/Symantec/Dominator/lib/html"
+	"github.com/Symantec/Dominator/lib/srpc"
 	"net/http"
 )

<|current_version|>
package httpd

import (
	"bufio"
	"fmt"
	"github.com/Symantec/Dominator/lib/html"
	"github.com/Symantec/Dominator/lib/srpc"
	"net/http"
)

func statusHandler(w http.ResponseWriter, req *http.Request) {
	writer := bufio.NewWriter(w)
	defer writer.Flush()
	fmt.Fprintln(writer, "<title>imageserver status page</title>")
	fmt.Fprintln(writer, "")
	fmt.Fprintln(writer, "")
	fmt.Fprintln(writer, "
imageserver status page
")
	fmt.Fprintln(writer, "")
	html.WriteHeaderWithRequest(writer, req)
	fmt.Fprintln(writer, "
")
	for _, htmlWriter := range htmlWriters {
		htmlWriter.WriteHtml(writer)
	}
	fmt.Fprintln(writer, "
")
	fmt.Fprintln(writer, "
")
	html.WriteFooter(writer)
	fmt.Fprintln(writer, "")
}

<|next_version|>
package httpd

import (
	"bufio"
	"fmt"
	"github.com/Symantec/Dominator/lib/html"
	"github.com/Symantec/Dominator/lib/srpc"
	"net/http"
)

func statusHandler(w http.ResponseWriter, req *http.Request) {
	writer := bufio.NewWriter(w)
	defer writer.Flush()
	fmt.Fprintln(writer, "<title>imageserver status page</title>")
	fmt.Fprintln(writer, "")
	fmt.Fprintln(writer, "")
	fmt.Fprintln(writer, "
imageserver status page
")
	if !srpc.CheckTlsRequired() {
		fmt.Fprintln(writer,
			`<h1><font color="red">Running in insecure mode. Your images can be pwned!!!</font></h1>`)
	}
	fmt.Fprintln(writer, "")
	html.WriteHeaderWithRequest(writer, req)
	fmt.Fprintln(writer, "
")
	for _, htmlWriter := range htmlWriters {
		htmlWriter.WriteHtml(writer)
	}
	fmt.Fprintln(writer, "
")
	fmt.Fprintln(writer, "
")
	html.WriteFooter(writer)
	fmt.Fprintln(writer, "")
}


Fix ScheduleBackups and UnscheduleBackups not defaulting correctly

--- lib/backup_schedule_calls.go
+++ lib/backup_schedule_calls.go
@@ -7,6 +7,10 @@

 // CreateBackupSchedule creates a new backup schedule starting at the given date, with backups occuring every interval seconds
 func (c *bytemarkClient) CreateBackupSchedule(server VirtualMachineName, discLabel string, startDate string, interval int) (sched brain.BackupSchedule, err error) {
+	err = c.validateVirtualMachineName(&server)
+	if err != nil {
+		return
+	}
 	r, err := c.BuildRequest("POST", BrainEndpoint, "/accounts/%s/groups/%s/virtual_machines/%s/discs/%s/backup_schedules", server.Account, server.Group, server.VirtualMachine, discLabel)
 	if err != nil {
 		return
@@ -21,6 +25,10 @@

 // DeleteBackupSchedule deletes the given backup schedule
 func (c *bytemarkClient) DeleteBackupSchedule(server VirtualMachineName, discLabel string, id int) (err error) {
+	err = c.validateVirtualMachineName(&server)
+	if err != nil {
+		return
+	}
 	r, err := c.BuildRequest("DELETE", BrainEndpoint, "/accounts/%s/groups/%s/virtual_machines/%s/discs/%s/backup_schedules/%s", server.Account, server.Group, server.VirtualMachine, discLabel, strconv.Itoa(id))
 	if err != nil {
 		return

<|original_code|>
package lib

import (
	"github.com/BytemarkHosting/bytemark-client/lib/brain"
	"strconv"
)

// CreateBackupSchedule creates a new backup schedule starting at the given date, with backups occuring every interval seconds
func (c *bytemarkClient) CreateBackupSchedule(server VirtualMachineName, discLabel string, startDate string, interval int) (sched brain.BackupSchedule, err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/accounts/%s/groups/%s/virtual_machines/%s/discs/%s/backup_schedules", server.Account, server.Group, server.VirtualMachine, discLabel)
	if err != nil {
		return
	}
	inputSchedule := brain.BackupSchedule{
		StartDate: startDate,
		Interval:  interval,
	}
	_, _, err = r.MarshalAndRun(inputSchedule, &sched)
	return
}

// DeleteBackupSchedule deletes the given backup schedule
func (c *bytemarkClient) DeleteBackupSchedule(server VirtualMachineName, discLabel string, id int) (err error) {
	r, err := c.BuildRequest("DELETE", BrainEndpoint, "/accounts/%s/groups/%s/virtual_machines/%s/discs/%s/backup_schedules/%s", server.Account, server.Group, server.VirtualMachine, discLabel, strconv.Itoa(id))
	if err != nil {
		return
	}
	_, _, err = r.Run(nil, nil)
	return
}

<|edits_diff|>
--- lib/backup_schedule_calls.go
+++ lib/backup_schedule_calls.go
@@ -7,6 +7,10 @@

 // CreateBackupSchedule creates a new backup schedule starting at the given date, with backups occuring every interval seconds
 func (c *bytemarkClient) CreateBackupSchedule(server VirtualMachineName, discLabel string, startDate string, interval int) (sched brain.BackupSchedule, err error) {
+	err = c.validateVirtualMachineName(&server)
+	if err != nil {
+		return
+	}
 	r, err := c.BuildRequest("POST", BrainEndpoint, "/accounts/%s/groups/%s/virtual_machines/%s/discs/%s/backup_schedules", server.Account, server.Group, server.VirtualMachine, discLabel)
 	if err != nil {
 		return
<|current_version|>
package lib

import (
	"github.com/BytemarkHosting/bytemark-client/lib/brain"
	"strconv"
)

// CreateBackupSchedule creates a new backup schedule starting at the given date, with backups occuring every interval seconds
func (c *bytemarkClient) CreateBackupSchedule(server VirtualMachineName, discLabel string, startDate string, interval int) (sched brain.BackupSchedule, err error) {
	err = c.validateVirtualMachineName(&server)
	if err != nil {
		return
	}
	r, err := c.BuildRequest("POST", BrainEndpoint, "/accounts/%s/groups/%s/virtual_machines/%s/discs/%s/backup_schedules", server.Account, server.Group, server.VirtualMachine, discLabel)
	if err != nil {
		return
	}
	inputSchedule := brain.BackupSchedule{
		StartDate: startDate,
		Interval:  interval,
	}
	_, _, err = r.MarshalAndRun(inputSchedule, &sched)
	return
}

// DeleteBackupSchedule deletes the given backup schedule
func (c *bytemarkClient) DeleteBackupSchedule(server VirtualMachineName, discLabel string, id int) (err error) {
	r, err := c.BuildRequest("DELETE", BrainEndpoint, "/accounts/%s/groups/%s/virtual_machines/%s/discs/%s/backup_schedules/%s", server.Account, server.Group, server.VirtualMachine, discLabel, strconv.Itoa(id))
	if err != nil {
		return
	}
	_, _, err = r.Run(nil, nil)
	return
}

<|next_version|>
package lib

import (
	"github.com/BytemarkHosting/bytemark-client/lib/brain"
	"strconv"
)

// CreateBackupSchedule creates a new backup schedule starting at the given date, with backups occuring every interval seconds
func (c *bytemarkClient) CreateBackupSchedule(server VirtualMachineName, discLabel string, startDate string, interval int) (sched brain.BackupSchedule, err error) {
	err = c.validateVirtualMachineName(&server)
	if err != nil {
		return
	}
	r, err := c.BuildRequest("POST", BrainEndpoint, "/accounts/%s/groups/%s/virtual_machines/%s/discs/%s/backup_schedules", server.Account, server.Group, server.VirtualMachine, discLabel)
	if err != nil {
		return
	}
	inputSchedule := brain.BackupSchedule{
		StartDate: startDate,
		Interval:  interval,
	}
	_, _, err = r.MarshalAndRun(inputSchedule, &sched)
	return
}

// DeleteBackupSchedule deletes the given backup schedule
func (c *bytemarkClient) DeleteBackupSchedule(server VirtualMachineName, discLabel string, id int) (err error) {
	err = c.validateVirtualMachineName(&server)
	if err != nil {
		return
	}
	r, err := c.BuildRequest("DELETE", BrainEndpoint, "/accounts/%s/groups/%s/virtual_machines/%s/discs/%s/backup_schedules/%s", server.Account, server.Group, server.VirtualMachine, discLabel, strconv.Itoa(id))
	if err != nil {
		return
	}
	_, _, err = r.Run(nil, nil)
	return
}


Add regular expression for object names in 'refs'

it will be used in 'image-tools' or other project for checking regular
expression of 'refs', which writes as "Object names in the refs
subdirectories MUST NOT include characters outside of the set of "A" to
"Z", "a" to "z", "0" to "9", the hyphen -, the dot ., and the underscore
_." at https://github.com/opencontainers/image-spec/blob/master/image-layout.md

Signed-off-by: Ling FaKe <25fffa53a086899a13ee0dcbe820593f9964b232@huawei.com>

--- specs-go/v1/layout.go
+++ specs-go/v1/layout.go
@@ -14,8 +14,15 @@

 package v1

+import "regexp"
+
 // ImageLayout is the structure in the "oci-layout" file, found in the root
 // of an OCI Image-layout directory.
 type ImageLayout struct {
 	Version string `json:"imageLayoutVersion"`
 }
+
+var (
+	// RefsRegexp matches requirement of image-layout 'refs' charset.
+	RefsRegexp = regexp.MustCompile(`^[a-zA-Z0-9-._]+$`)
+)

<|original_code|>
// Copyright 2016 The Linux Foundation
//
// 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 v1

// ImageLayout is the structure in the "oci-layout" file, found in the root
// of an OCI Image-layout directory.
type ImageLayout struct {
	Version string `json:"imageLayoutVersion"`
}

<|edits_diff|>
--- specs-go/v1/layout.go
+++ specs-go/v1/layout.go
@@ -14,6 +14,8 @@

 package v1

+import "regexp"
+
 // ImageLayout is the structure in the "oci-layout" file, found in the root
 // of an OCI Image-layout directory.
 type ImageLayout struct {
<|current_version|>
// Copyright 2016 The Linux Foundation
//
// 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 v1

import "regexp"

// ImageLayout is the structure in the "oci-layout" file, found in the root
// of an OCI Image-layout directory.
type ImageLayout struct {
	Version string `json:"imageLayoutVersion"`
}

<|next_version|>
// Copyright 2016 The Linux Foundation
//
// 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 v1

import "regexp"

// ImageLayout is the structure in the "oci-layout" file, found in the root
// of an OCI Image-layout directory.
type ImageLayout struct {
	Version string `json:"imageLayoutVersion"`
}

var (
	// RefsRegexp matches requirement of image-layout 'refs' charset.
	RefsRegexp = regexp.MustCompile(`^[a-zA-Z0-9-._]+$`)
)


Enable KeepAlives and set timeout in http transport.

--- http_client.go
+++ http_client.go
@@ -33,9 +33,14 @@
 			if err != nil {
 				return nil, err
 			}
+			if tc, ok := c.(*net.TCPConn); ok {
+				tc.SetKeepAlive(true)
+				tc.SetKeepAlivePeriod(timeout)
+			}
 			return &deadlineConn{timeout, c}, nil
 		},
 		ResponseHeaderTimeout: timeout,
+		MaxIdleConnsPerHost:   20,
 	}
 	return &http.Client{Transport: transport}
 }

<|original_code|>
package s3gof3r

import (
	"net"
	"net/http"
	"time"
)

type deadlineConn struct {
	Timeout time.Duration
	net.Conn
}

func (c *deadlineConn) Read(b []byte) (n int, err error) {
	if err = c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return
	}
	return c.Conn.Read(b)
}

func (c *deadlineConn) Write(b []byte) (n int, err error) {
	if err = c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return
	}
	return c.Conn.Write(b)
}

func ClientWithTimeout(timeout time.Duration) *http.Client {
	transport := &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: func(netw, addr string) (net.Conn, error) {
			c, err := net.DialTimeout(netw, addr, timeout)
			if err != nil {
				return nil, err
			}
			return &deadlineConn{timeout, c}, nil
		},
		ResponseHeaderTimeout: timeout,
	}
	return &http.Client{Transport: transport}
}

<|edits_diff|>
--- http_client.go
+++ http_client.go
@@ -33,6 +33,10 @@
 			if err != nil {
 				return nil, err
 			}
+			if tc, ok := c.(*net.TCPConn); ok {
+				tc.SetKeepAlive(true)
+				tc.SetKeepAlivePeriod(timeout)
+			}
 			return &deadlineConn{timeout, c}, nil
 		},
 		ResponseHeaderTimeout: timeout,
<|current_version|>
package s3gof3r

import (
	"net"
	"net/http"
	"time"
)

type deadlineConn struct {
	Timeout time.Duration
	net.Conn
}

func (c *deadlineConn) Read(b []byte) (n int, err error) {
	if err = c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return
	}
	return c.Conn.Read(b)
}

func (c *deadlineConn) Write(b []byte) (n int, err error) {
	if err = c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return
	}
	return c.Conn.Write(b)
}

func ClientWithTimeout(timeout time.Duration) *http.Client {
	transport := &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: func(netw, addr string) (net.Conn, error) {
			c, err := net.DialTimeout(netw, addr, timeout)
			if err != nil {
				return nil, err
			}
			if tc, ok := c.(*net.TCPConn); ok {
				tc.SetKeepAlive(true)
				tc.SetKeepAlivePeriod(timeout)
			}
			return &deadlineConn{timeout, c}, nil
		},
		ResponseHeaderTimeout: timeout,
	}
	return &http.Client{Transport: transport}
}

<|next_version|>
package s3gof3r

import (
	"net"
	"net/http"
	"time"
)

type deadlineConn struct {
	Timeout time.Duration
	net.Conn
}

func (c *deadlineConn) Read(b []byte) (n int, err error) {
	if err = c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return
	}
	return c.Conn.Read(b)
}

func (c *deadlineConn) Write(b []byte) (n int, err error) {
	if err = c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return
	}
	return c.Conn.Write(b)
}

func ClientWithTimeout(timeout time.Duration) *http.Client {
	transport := &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: func(netw, addr string) (net.Conn, error) {
			c, err := net.DialTimeout(netw, addr, timeout)
			if err != nil {
				return nil, err
			}
			if tc, ok := c.(*net.TCPConn); ok {
				tc.SetKeepAlive(true)
				tc.SetKeepAlivePeriod(timeout)
			}
			return &deadlineConn{timeout, c}, nil
		},
		ResponseHeaderTimeout: timeout,
		MaxIdleConnsPerHost:   20,
	}
	return &http.Client{Transport: transport}
}


Add stackdriver format support via TV4/logrus-stackdriver-formatter. Simply set format in config to stackdriver

--- internal/logging/helper.go
+++ internal/logging/helper.go
@@ -1,6 +1,7 @@
 package logging

 import (
+	stackdriver "github.com/TV4/logrus-stackdriver-formatter"
 	"github.com/sirupsen/logrus"
 	"github.com/spf13/viper"
 )
@@ -11,6 +12,8 @@
 //  - include source file and line number for every event (false [default], true)
 func ConfigureLogging(cfg *viper.Viper) {
 	switch cfg.GetString("logging.format") {
+	case "stackdriver":
+		logrus.SetFormatter(stackdriver.NewFormatter())
 	case "json":
 		logrus.SetFormatter(&logrus.JSONFormatter{})
 	case "text":

<|original_code|>
package logging

import (
	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
)

// ConfigureLogging sets up open match logrus instance using the logging section of the matchmaker_config.json
//  - log line format (text[default] or json)
//  - min log level to include (debug, info [default], warn, error, fatal, panic)
//  - include source file and line number for every event (false [default], true)
func ConfigureLogging(cfg *viper.Viper) {
	switch cfg.GetString("logging.format") {
	case "json":
		logrus.SetFormatter(&logrus.JSONFormatter{})
	case "text":
	default:
		logrus.SetFormatter(&logrus.TextFormatter{})
	}

	switch cfg.GetString("logging.level") {
	case "debug":
		logrus.SetLevel(logrus.DebugLevel)
		logrus.Warn("Debug logging level configured. Not recommended for production!")
	case "warn":
		logrus.SetLevel(logrus.WarnLevel)
	case "error":
		logrus.SetLevel(logrus.ErrorLevel)
	case "fatal":
		logrus.SetLevel(logrus.FatalLevel)
	case "panic":
		logrus.SetLevel(logrus.PanicLevel)
	case "info":
	default:
		logrus.SetLevel(logrus.InfoLevel)
	}

	switch cfg.GetBool("logging.source") {
	case true:
		logrus.SetReportCaller(true)
	}

}

<|edits_diff|>
--- internal/logging/helper.go
+++ internal/logging/helper.go
@@ -1,6 +1,7 @@
 package logging

 import (
+	stackdriver "github.com/TV4/logrus-stackdriver-formatter"
 	"github.com/sirupsen/logrus"
 	"github.com/spf13/viper"
 )
<|current_version|>
package logging

import (
	stackdriver "github.com/TV4/logrus-stackdriver-formatter"
	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
)

// ConfigureLogging sets up open match logrus instance using the logging section of the matchmaker_config.json
//  - log line format (text[default] or json)
//  - min log level to include (debug, info [default], warn, error, fatal, panic)
//  - include source file and line number for every event (false [default], true)
func ConfigureLogging(cfg *viper.Viper) {
	switch cfg.GetString("logging.format") {
	case "json":
		logrus.SetFormatter(&logrus.JSONFormatter{})
	case "text":
	default:
		logrus.SetFormatter(&logrus.TextFormatter{})
	}

	switch cfg.GetString("logging.level") {
	case "debug":
		logrus.SetLevel(logrus.DebugLevel)
		logrus.Warn("Debug logging level configured. Not recommended for production!")
	case "warn":
		logrus.SetLevel(logrus.WarnLevel)
	case "error":
		logrus.SetLevel(logrus.ErrorLevel)
	case "fatal":
		logrus.SetLevel(logrus.FatalLevel)
	case "panic":
		logrus.SetLevel(logrus.PanicLevel)
	case "info":
	default:
		logrus.SetLevel(logrus.InfoLevel)
	}

	switch cfg.GetBool("logging.source") {
	case true:
		logrus.SetReportCaller(true)
	}

}

<|next_version|>
package logging

import (
	stackdriver "github.com/TV4/logrus-stackdriver-formatter"
	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
)

// ConfigureLogging sets up open match logrus instance using the logging section of the matchmaker_config.json
//  - log line format (text[default] or json)
//  - min log level to include (debug, info [default], warn, error, fatal, panic)
//  - include source file and line number for every event (false [default], true)
func ConfigureLogging(cfg *viper.Viper) {
	switch cfg.GetString("logging.format") {
	case "stackdriver":
		logrus.SetFormatter(stackdriver.NewFormatter())
	case "json":
		logrus.SetFormatter(&logrus.JSONFormatter{})
	case "text":
	default:
		logrus.SetFormatter(&logrus.TextFormatter{})
	}

	switch cfg.GetString("logging.level") {
	case "debug":
		logrus.SetLevel(logrus.DebugLevel)
		logrus.Warn("Debug logging level configured. Not recommended for production!")
	case "warn":
		logrus.SetLevel(logrus.WarnLevel)
	case "error":
		logrus.SetLevel(logrus.ErrorLevel)
	case "fatal":
		logrus.SetLevel(logrus.FatalLevel)
	case "panic":
		logrus.SetLevel(logrus.PanicLevel)
	case "info":
	default:
		logrus.SetLevel(logrus.InfoLevel)
	}

	switch cfg.GetBool("logging.source") {
	case true:
		logrus.SetReportCaller(true)
	}

}


Add support for hooking retryablehttp request logs

--- azure/client.go
+++ azure/client.go
@@ -5,6 +5,7 @@
 	"log"

 	"github.com/hashicorp/go-retryablehttp"
+	"net/http"
 )

 type Client struct {
@@ -34,6 +35,10 @@
 	}, nil
 }

+func (c *Client) SetRequestLoggingHook(hook func (*log.Logger, *http.Request, int)) {
+	c.httpClient.RequestLogHook = hook
+}
+
 func (c *Client) SetLogger(newLogger *log.Logger) {
 	c.logger = newLogger
 	c.httpClient.Logger = newLogger

<|original_code|>
package azure

import (
	"io/ioutil"
	"log"

	"github.com/hashicorp/go-retryablehttp"
)

type Client struct {
	logger *log.Logger

	BaseURL        string
	subscriptionID string

	tokenRequester *tokenRequester
	httpClient     *retryablehttp.Client
}

func NewClient(creds *AzureResourceManagerCredentials) (*Client, error) {
	defaultLogger := log.New(ioutil.Discard, "", 0)

	httpClient := retryablehttp.NewClient()
	httpClient.Logger = defaultLogger

	tr := newTokenRequester(httpClient, creds.ClientID, creds.ClientSecret, creds.TenantID)

	return &Client{
		BaseURL:        "https://management.azure.com",
		subscriptionID: creds.SubscriptionID,
		httpClient:     httpClient,
		tokenRequester: tr,
		logger:         defaultLogger,
	}, nil
}

func (c *Client) SetLogger(newLogger *log.Logger) {
	c.logger = newLogger
	c.httpClient.Logger = newLogger
}

func (c *Client) NewRequest() *Request {
	return &Request{
		client: c,
	}
}

func (c *Client) NewRequestForURI(resourceURI string) *Request {
	return &Request{
		URI:    &resourceURI,
		client: c,
	}
}

<|edits_diff|>
--- azure/client.go
+++ azure/client.go
@@ -5,6 +5,7 @@
 	"log"

 	"github.com/hashicorp/go-retryablehttp"
+	"net/http"
 )

 type Client struct {
<|current_version|>
package azure

import (
	"io/ioutil"
	"log"

	"github.com/hashicorp/go-retryablehttp"
	"net/http"
)

type Client struct {
	logger *log.Logger

	BaseURL        string
	subscriptionID string

	tokenRequester *tokenRequester
	httpClient     *retryablehttp.Client
}

func NewClient(creds *AzureResourceManagerCredentials) (*Client, error) {
	defaultLogger := log.New(ioutil.Discard, "", 0)

	httpClient := retryablehttp.NewClient()
	httpClient.Logger = defaultLogger

	tr := newTokenRequester(httpClient, creds.ClientID, creds.ClientSecret, creds.TenantID)

	return &Client{
		BaseURL:        "https://management.azure.com",
		subscriptionID: creds.SubscriptionID,
		httpClient:     httpClient,
		tokenRequester: tr,
		logger:         defaultLogger,
	}, nil
}

func (c *Client) SetLogger(newLogger *log.Logger) {
	c.logger = newLogger
	c.httpClient.Logger = newLogger
}

func (c *Client) NewRequest() *Request {
	return &Request{
		client: c,
	}
}

func (c *Client) NewRequestForURI(resourceURI string) *Request {
	return &Request{
		URI:    &resourceURI,
		client: c,
	}
}

<|next_version|>
package azure

import (
	"io/ioutil"
	"log"

	"github.com/hashicorp/go-retryablehttp"
	"net/http"
)

type Client struct {
	logger *log.Logger

	BaseURL        string
	subscriptionID string

	tokenRequester *tokenRequester
	httpClient     *retryablehttp.Client
}

func NewClient(creds *AzureResourceManagerCredentials) (*Client, error) {
	defaultLogger := log.New(ioutil.Discard, "", 0)

	httpClient := retryablehttp.NewClient()
	httpClient.Logger = defaultLogger

	tr := newTokenRequester(httpClient, creds.ClientID, creds.ClientSecret, creds.TenantID)

	return &Client{
		BaseURL:        "https://management.azure.com",
		subscriptionID: creds.SubscriptionID,
		httpClient:     httpClient,
		tokenRequester: tr,
		logger:         defaultLogger,
	}, nil
}

func (c *Client) SetRequestLoggingHook(hook func (*log.Logger, *http.Request, int)) {
	c.httpClient.RequestLogHook = hook
}

func (c *Client) SetLogger(newLogger *log.Logger) {
	c.logger = newLogger
	c.httpClient.Logger = newLogger
}

func (c *Client) NewRequest() *Request {
	return &Request{
		client: c,
	}
}

func (c *Client) NewRequestForURI(resourceURI string) *Request {
	return &Request{
		URI:    &resourceURI,
		client: c,
	}
}


Put a time limit on smart shutdown.

Put a time limit on smart shutdown.

--- smart_shutdown.go
+++ smart_shutdown.go
@@ -7,6 +7,7 @@
 	"os/signal"
 	"sync"
 	"syscall"
+	"time"
 )

 var listenerChan = make(chan net.Listener)
@@ -35,6 +36,11 @@
 			if *pidfile != "" {
 				os.Remove(*pidfile)
 			}
+			go func() {
+				// Stop after 24 hours even if the connections aren't closed.
+				time.Sleep(24 * time.Hour)
+				os.Exit(0)
+			}()
 			activeConnections.Wait()
 			os.Exit(0)
 		}

<|original_code|>
package main

import (
	"log"
	"net"
	"os"
	"os/signal"
	"sync"
	"syscall"
)

var listenerChan = make(chan net.Listener)

var activeConnections sync.WaitGroup

func init() {
	go watchForSIGTERM()
}

func watchForSIGTERM() {
	var listeners []net.Listener
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGTERM)

	for {
		select {
		case l := <-listenerChan:
			listeners = append(listeners, l)

		case <-sigChan:
			log.Println("Received SIGTERM")
			for _, ln := range listeners {
				ln.Close()
			}
			if *pidfile != "" {
				os.Remove(*pidfile)
			}
			activeConnections.Wait()
			os.Exit(0)
		}
	}
}

<|edits_diff|>
--- smart_shutdown.go
+++ smart_shutdown.go
@@ -7,6 +7,7 @@
 	"os/signal"
 	"sync"
 	"syscall"
+	"time"
 )

 var listenerChan = make(chan net.Listener)
<|current_version|>
package main

import (
	"log"
	"net"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"
)

var listenerChan = make(chan net.Listener)

var activeConnections sync.WaitGroup

func init() {
	go watchForSIGTERM()
}

func watchForSIGTERM() {
	var listeners []net.Listener
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGTERM)

	for {
		select {
		case l := <-listenerChan:
			listeners = append(listeners, l)

		case <-sigChan:
			log.Println("Received SIGTERM")
			for _, ln := range listeners {
				ln.Close()
			}
			if *pidfile != "" {
				os.Remove(*pidfile)
			}
			activeConnections.Wait()
			os.Exit(0)
		}
	}
}

<|next_version|>
package main

import (
	"log"
	"net"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"
)

var listenerChan = make(chan net.Listener)

var activeConnections sync.WaitGroup

func init() {
	go watchForSIGTERM()
}

func watchForSIGTERM() {
	var listeners []net.Listener
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGTERM)

	for {
		select {
		case l := <-listenerChan:
			listeners = append(listeners, l)

		case <-sigChan:
			log.Println("Received SIGTERM")
			for _, ln := range listeners {
				ln.Close()
			}
			if *pidfile != "" {
				os.Remove(*pidfile)
			}
			go func() {
				// Stop after 24 hours even if the connections aren't closed.
				time.Sleep(24 * time.Hour)
				os.Exit(0)
			}()
			activeConnections.Wait()
			os.Exit(0)
		}
	}
}


Add ID and timestamp for notifs from CB

Add ID and timestamp for notifs from CB

--- src/iotrules/engine/notifcb.go
+++ src/iotrules/engine/notifcb.go
@@ -2,6 +2,10 @@

 import (
 	"encoding/json"
+	"time"
+
+	"code.google.com/p/go-uuid/uuid"
+
 	"iotrules/mylog"
 )

@@ -27,6 +31,8 @@
 	defer func() { mylog.Debugf("exit NewNotifFromCB (%+v,%v)\n", n, err) }()

 	n = &Notif{Data: map[string]interface{}{}}
+	n.ID = uuid.New()
+	n.Received = time.Now()

 	var ncr NotifyContextRequest
 	err = json.Unmarshal(ngsi, &ncr)

<|original_code|>
package engine

import (
	"encoding/json"
	"iotrules/mylog"
)

type NotifyContextRequest struct {
	SubscriptionId   string
	Originator       string
	ContextResponses []struct{ ContextElement ContextElement }
}
type ContextElement struct {
	Id         string
	IsPattern  string
	Type       string
	Attributes []Attribute
}
type Attribute struct {
	Name  string
	Type  string
	Value string
}

func NewNotifFromCB(ngsi []byte, service int) (n *Notif, err error) {
	mylog.Debugf("enter NewNotifFromCB(%s,%d)\n", ngsi, service)
	defer func() { mylog.Debugf("exit NewNotifFromCB (%+v,%v)\n", n, err) }()

	n = &Notif{Data: map[string]interface{}{}}

	var ncr NotifyContextRequest
	err = json.Unmarshal(ngsi, &ncr)
	if err != nil {
		return nil, err
	}
	mylog.Debugf("in NewNotifFromCB NotifyContextRequest: %+v\n", ncr)

	n.Data["id"] = ncr.ContextResponses[0].ContextElement.Id
	n.Data["type"] = ncr.ContextResponses[0].ContextElement.Type
	for _, attr := range ncr.ContextResponses[0].ContextElement.Attributes {
		n.Data[attr.Name] = attr.Value
	}

	return n, nil
}

<|edits_diff|>
--- src/iotrules/engine/notifcb.go
+++ src/iotrules/engine/notifcb.go
@@ -2,6 +2,10 @@

 import (
 	"encoding/json"
+	"time"
+
+	"code.google.com/p/go-uuid/uuid"
+
 	"iotrules/mylog"
 )

<|current_version|>
package engine

import (
	"encoding/json"
	"time"

	"code.google.com/p/go-uuid/uuid"

	"iotrules/mylog"
)

type NotifyContextRequest struct {
	SubscriptionId   string
	Originator       string
	ContextResponses []struct{ ContextElement ContextElement }
}
type ContextElement struct {
	Id         string
	IsPattern  string
	Type       string
	Attributes []Attribute
}
type Attribute struct {
	Name  string
	Type  string
	Value string
}

func NewNotifFromCB(ngsi []byte, service int) (n *Notif, err error) {
	mylog.Debugf("enter NewNotifFromCB(%s,%d)\n", ngsi, service)
	defer func() { mylog.Debugf("exit NewNotifFromCB (%+v,%v)\n", n, err) }()

	n = &Notif{Data: map[string]interface{}{}}

	var ncr NotifyContextRequest
	err = json.Unmarshal(ngsi, &ncr)
	if err != nil {
		return nil, err
	}
	mylog.Debugf("in NewNotifFromCB NotifyContextRequest: %+v\n", ncr)

	n.Data["id"] = ncr.ContextResponses[0].ContextElement.Id
	n.Data["type"] = ncr.ContextResponses[0].ContextElement.Type
	for _, attr := range ncr.ContextResponses[0].ContextElement.Attributes {
		n.Data[attr.Name] = attr.Value
	}

	return n, nil
}

<|next_version|>
package engine

import (
	"encoding/json"
	"time"

	"code.google.com/p/go-uuid/uuid"

	"iotrules/mylog"
)

type NotifyContextRequest struct {
	SubscriptionId   string
	Originator       string
	ContextResponses []struct{ ContextElement ContextElement }
}
type ContextElement struct {
	Id         string
	IsPattern  string
	Type       string
	Attributes []Attribute
}
type Attribute struct {
	Name  string
	Type  string
	Value string
}

func NewNotifFromCB(ngsi []byte, service int) (n *Notif, err error) {
	mylog.Debugf("enter NewNotifFromCB(%s,%d)\n", ngsi, service)
	defer func() { mylog.Debugf("exit NewNotifFromCB (%+v,%v)\n", n, err) }()

	n = &Notif{Data: map[string]interface{}{}}
	n.ID = uuid.New()
	n.Received = time.Now()

	var ncr NotifyContextRequest
	err = json.Unmarshal(ngsi, &ncr)
	if err != nil {
		return nil, err
	}
	mylog.Debugf("in NewNotifFromCB NotifyContextRequest: %+v\n", ncr)

	n.Data["id"] = ncr.ContextResponses[0].ContextElement.Id
	n.Data["type"] = ncr.ContextResponses[0].ContextElement.Type
	for _, attr := range ncr.ContextResponses[0].ContextElement.Attributes {
		n.Data[attr.Name] = attr.Value
	}

	return n, nil
}


Validate required env vars existence

Validate required env vars existence

--- config/config.go
+++ config/config.go
@@ -2,6 +2,8 @@

 import (
 	"bytes"
+	"errors"
+	"fmt"

 	"github.com/eyecuelab/kit/assets"
 	"github.com/spf13/viper"
@@ -30,6 +32,9 @@
 		if err := viper.BindEnv(envVar); err != nil {
 			return err
 		}
+		if !viper.IsSet(envVar) {
+			return errors.New(fmt.Sprintf("Env var is not set: %s", envVar))
+		}
 	}

 	return nil

<|original_code|>
package config

import (
	"bytes"

	"github.com/eyecuelab/kit/assets"
	"github.com/spf13/viper"
)

func Load(envPrefix string, configPath string) error {
	viper.SetConfigType("yaml")

	if len(configPath) > 0 {
		viper.SetConfigFile(configPath)
		if err := viper.ReadInConfig(); err != nil {
			return err
		}
	} else {
		if data, err := assets.Get("data/bin/config.yaml"); err != nil {
			return err
		} else {
			viper.ReadConfig(bytes.NewBuffer(data))
		}
	}

	viper.SetEnvPrefix(envPrefix)
	viper.AutomaticEnv()

	for _, envVar := range viper.GetStringSlice("env") {
		if err := viper.BindEnv(envVar); err != nil {
			return err
		}
	}

	return nil
}

<|edits_diff|>
--- config/config.go
+++ config/config.go
@@ -2,6 +2,8 @@

 import (
 	"bytes"
+	"errors"
+	"fmt"

 	"github.com/eyecuelab/kit/assets"
 	"github.com/spf13/viper"
<|current_version|>
package config

import (
	"bytes"
	"errors"
	"fmt"

	"github.com/eyecuelab/kit/assets"
	"github.com/spf13/viper"
)

func Load(envPrefix string, configPath string) error {
	viper.SetConfigType("yaml")

	if len(configPath) > 0 {
		viper.SetConfigFile(configPath)
		if err := viper.ReadInConfig(); err != nil {
			return err
		}
	} else {
		if data, err := assets.Get("data/bin/config.yaml"); err != nil {
			return err
		} else {
			viper.ReadConfig(bytes.NewBuffer(data))
		}
	}

	viper.SetEnvPrefix(envPrefix)
	viper.AutomaticEnv()

	for _, envVar := range viper.GetStringSlice("env") {
		if err := viper.BindEnv(envVar); err != nil {
			return err
		}
	}

	return nil
}

<|next_version|>
package config

import (
	"bytes"
	"errors"
	"fmt"

	"github.com/eyecuelab/kit/assets"
	"github.com/spf13/viper"
)

func Load(envPrefix string, configPath string) error {
	viper.SetConfigType("yaml")

	if len(configPath) > 0 {
		viper.SetConfigFile(configPath)
		if err := viper.ReadInConfig(); err != nil {
			return err
		}
	} else {
		if data, err := assets.Get("data/bin/config.yaml"); err != nil {
			return err
		} else {
			viper.ReadConfig(bytes.NewBuffer(data))
		}
	}

	viper.SetEnvPrefix(envPrefix)
	viper.AutomaticEnv()

	for _, envVar := range viper.GetStringSlice("env") {
		if err := viper.BindEnv(envVar); err != nil {
			return err
		}
		if !viper.IsSet(envVar) {
			return errors.New(fmt.Sprintf("Env var is not set: %s", envVar))
		}
	}

	return nil
}


Exclude interfaces bound to a VLAN in lib/net/GetMyIP().

--- lib/net/util/getMyIP.go
+++ lib/net/util/getMyIP.go
@@ -3,7 +3,11 @@
 import (
 	"errors"
 	"net"
+	"os"
+	"path/filepath"
 )
+
+const procNetVlan = "/proc/net/vlan"

 func getMyIP() (net.IP, error) {
 	var myIP net.IP
@@ -17,6 +21,9 @@
 			continue
 		}
 		if iface.Flags&net.FlagBroadcast == 0 {
+			continue
+		}
+		if _, e := os.Stat(filepath.Join(procNetVlan, iface.Name)); e == nil {
 			continue
 		}
 		interfaceAddrs, err := iface.Addrs()

<|original_code|>
package util

import (
	"errors"
	"net"
)

func getMyIP() (net.IP, error) {
	var myIP net.IP
	mostOnesInMask := 0
	interfaces, err := net.Interfaces()
	if err != nil {
		return nil, err
	}
	for _, iface := range interfaces {
		if iface.Flags&net.FlagUp == 0 {
			continue
		}
		if iface.Flags&net.FlagBroadcast == 0 {
			continue
		}
		interfaceAddrs, err := iface.Addrs()
		if err != nil {
			return nil, err
		}
		for _, addr := range interfaceAddrs {
			IP, IPNet, err := net.ParseCIDR(addr.String())
			if err != nil {
				return nil, err
			}
			if IP = IP.To4(); IP == nil {
				continue
			}
			if onesInMask, _ := IPNet.Mask.Size(); onesInMask > mostOnesInMask {
				myIP = IP
				mostOnesInMask = onesInMask
			}
		}
	}
	if myIP == nil {
		return nil, errors.New("no IP address found")
	}
	return myIP, nil
}

<|edits_diff|>
--- lib/net/util/getMyIP.go
+++ lib/net/util/getMyIP.go
@@ -3,7 +3,11 @@
 import (
 	"errors"
 	"net"
+	"os"
+	"path/filepath"
 )
+
+const procNetVlan = "/proc/net/vlan"

 func getMyIP() (net.IP, error) {
 	var myIP net.IP
<|current_version|>
package util

import (
	"errors"
	"net"
	"os"
	"path/filepath"
)

const procNetVlan = "/proc/net/vlan"

func getMyIP() (net.IP, error) {
	var myIP net.IP
	mostOnesInMask := 0
	interfaces, err := net.Interfaces()
	if err != nil {
		return nil, err
	}
	for _, iface := range interfaces {
		if iface.Flags&net.FlagUp == 0 {
			continue
		}
		if iface.Flags&net.FlagBroadcast == 0 {
			continue
		}
		interfaceAddrs, err := iface.Addrs()
		if err != nil {
			return nil, err
		}
		for _, addr := range interfaceAddrs {
			IP, IPNet, err := net.ParseCIDR(addr.String())
			if err != nil {
				return nil, err
			}
			if IP = IP.To4(); IP == nil {
				continue
			}
			if onesInMask, _ := IPNet.Mask.Size(); onesInMask > mostOnesInMask {
				myIP = IP
				mostOnesInMask = onesInMask
			}
		}
	}
	if myIP == nil {
		return nil, errors.New("no IP address found")
	}
	return myIP, nil
}

<|next_version|>
package util

import (
	"errors"
	"net"
	"os"
	"path/filepath"
)

const procNetVlan = "/proc/net/vlan"

func getMyIP() (net.IP, error) {
	var myIP net.IP
	mostOnesInMask := 0
	interfaces, err := net.Interfaces()
	if err != nil {
		return nil, err
	}
	for _, iface := range interfaces {
		if iface.Flags&net.FlagUp == 0 {
			continue
		}
		if iface.Flags&net.FlagBroadcast == 0 {
			continue
		}
		if _, e := os.Stat(filepath.Join(procNetVlan, iface.Name)); e == nil {
			continue
		}
		interfaceAddrs, err := iface.Addrs()
		if err != nil {
			return nil, err
		}
		for _, addr := range interfaceAddrs {
			IP, IPNet, err := net.ParseCIDR(addr.String())
			if err != nil {
				return nil, err
			}
			if IP = IP.To4(); IP == nil {
				continue
			}
			if onesInMask, _ := IPNet.Mask.Size(); onesInMask > mostOnesInMask {
				myIP = IP
				mostOnesInMask = onesInMask
			}
		}
	}
	if myIP == nil {
		return nil, errors.New("no IP address found")
	}
	return myIP, nil
}


Set stack when deploying for integration tests

--- src/binary/integration/deploy_a_binary_app_test.go
+++ src/binary/integration/deploy_a_binary_app_test.go
@@ -6,6 +6,7 @@
 	"github.com/cloudfoundry/libbuildpack/cutlass"
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
+	"os"
 )

 var _ = Describe("CF Binary Buildpack", func() {
@@ -21,6 +22,7 @@
 	Describe("deploying a Ruby script", func() {
 		BeforeEach(func() {
 			app = cutlass.New(filepath.Join(bpDir, "fixtures", "webrick_app"))
+			app.Stack = os.Getenv("CF_STACK")
 		})

 		Context("when specifying a buildpack", func() {

<|original_code|>
package integration_test

import (
	"path/filepath"

	"github.com/cloudfoundry/libbuildpack/cutlass"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("CF Binary Buildpack", func() {
	var app *cutlass.App

	AfterEach(func() {
		if app != nil {
			app.Destroy()
		}
		app = nil
	})

	Describe("deploying a Ruby script", func() {
		BeforeEach(func() {
			app = cutlass.New(filepath.Join(bpDir, "fixtures", "webrick_app"))
		})

		Context("when specifying a buildpack", func() {
			BeforeEach(func() {
				app.Buildpacks = []string{"binary_buildpack"}
			})

			It("deploys successfully", func() {
				PushAppAndConfirm(app)

				Expect(app.GetBody("/")).To(ContainSubstring("Hello, world!"))
			})
		})

		Context("without specifying a buildpack", func() {
			BeforeEach(func() {
				app.Buildpacks = []string{}
			})

			It("fails to stage", func() {
				Expect(app.Push()).ToNot(Succeed())

				Eventually(app.Stdout.String).Should(ContainSubstring("None of the buildpacks detected a compatible application"))
			})
		})
	})
})

<|edits_diff|>
--- src/binary/integration/deploy_a_binary_app_test.go
+++ src/binary/integration/deploy_a_binary_app_test.go
@@ -6,6 +6,7 @@
 	"github.com/cloudfoundry/libbuildpack/cutlass"
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
+	"os"
 )

 var _ = Describe("CF Binary Buildpack", func() {
<|current_version|>
package integration_test

import (
	"path/filepath"

	"github.com/cloudfoundry/libbuildpack/cutlass"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"os"
)

var _ = Describe("CF Binary Buildpack", func() {
	var app *cutlass.App

	AfterEach(func() {
		if app != nil {
			app.Destroy()
		}
		app = nil
	})

	Describe("deploying a Ruby script", func() {
		BeforeEach(func() {
			app = cutlass.New(filepath.Join(bpDir, "fixtures", "webrick_app"))
		})

		Context("when specifying a buildpack", func() {
			BeforeEach(func() {
				app.Buildpacks = []string{"binary_buildpack"}
			})

			It("deploys successfully", func() {
				PushAppAndConfirm(app)

				Expect(app.GetBody("/")).To(ContainSubstring("Hello, world!"))
			})
		})

		Context("without specifying a buildpack", func() {
			BeforeEach(func() {
				app.Buildpacks = []string{}
			})

			It("fails to stage", func() {
				Expect(app.Push()).ToNot(Succeed())

				Eventually(app.Stdout.String).Should(ContainSubstring("None of the buildpacks detected a compatible application"))
			})
		})
	})
})

<|next_version|>
package integration_test

import (
	"path/filepath"

	"github.com/cloudfoundry/libbuildpack/cutlass"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"os"
)

var _ = Describe("CF Binary Buildpack", func() {
	var app *cutlass.App

	AfterEach(func() {
		if app != nil {
			app.Destroy()
		}
		app = nil
	})

	Describe("deploying a Ruby script", func() {
		BeforeEach(func() {
			app = cutlass.New(filepath.Join(bpDir, "fixtures", "webrick_app"))
			app.Stack = os.Getenv("CF_STACK")
		})

		Context("when specifying a buildpack", func() {
			BeforeEach(func() {
				app.Buildpacks = []string{"binary_buildpack"}
			})

			It("deploys successfully", func() {
				PushAppAndConfirm(app)

				Expect(app.GetBody("/")).To(ContainSubstring("Hello, world!"))
			})
		})

		Context("without specifying a buildpack", func() {
			BeforeEach(func() {
				app.Buildpacks = []string{}
			})

			It("fails to stage", func() {
				Expect(app.Push()).ToNot(Succeed())

				Eventually(app.Stdout.String).Should(ContainSubstring("None of the buildpacks detected a compatible application"))
			})
		})
	})
})


Add comment explaining `/debug/vars` route

--- routes.go
+++ routes.go
@@ -8,6 +8,8 @@
 )

 func registerRoutes() {
+	// Expose `expvar` debug variables
 	mux.Add("GET", "/debug/vars", http.DefaultServeMux)
+
 	mux.Get("/", handler.Index)
 }

<|original_code|>
package main

import (
	_ "expvar"
	"net/http"

	"gitlab.com/mattbostock/timeoff/handler"
)

func registerRoutes() {
	mux.Add("GET", "/debug/vars", http.DefaultServeMux)
	mux.Get("/", handler.Index)
}

<|edits_diff|>
--- routes.go
+++ routes.go
@@ -8,6 +8,7 @@
 )

 func registerRoutes() {
+	// Expose `expvar` debug variables
 	mux.Add("GET", "/debug/vars", http.DefaultServeMux)
 	mux.Get("/", handler.Index)
 }
<|current_version|>
package main

import (
	_ "expvar"
	"net/http"

	"gitlab.com/mattbostock/timeoff/handler"
)

func registerRoutes() {
	// Expose `expvar` debug variables
	mux.Add("GET", "/debug/vars", http.DefaultServeMux)
	mux.Get("/", handler.Index)
}

<|next_version|>
package main

import (
	_ "expvar"
	"net/http"

	"gitlab.com/mattbostock/timeoff/handler"
)

func registerRoutes() {
	// Expose `expvar` debug variables
	mux.Add("GET", "/debug/vars", http.DefaultServeMux)

	mux.Get("/", handler.Index)
}