<commit_before>package sqlgen

import (
	"context"
	"database/sql"
	"errors"
	"fmt"

	"github.com/samsarahq/thunder/batch"
	"github.com/samsarahq/thunder/opentracingkit"
)

// DB uses a *sql.DB connection that is established by its owner. DB assumes the
// database connection exists and is alive at all times during the lifecycle of
// the object.
type DB struct {
	Conn   *sql.DB
	Schema *Schema

	batchFetch *batch.Func
}

func NewDB(conn *sql.DB, schema *Schema) *DB {
	db := &DB{
		Conn:   conn,
		Schema: schema,
	}

	db.batchFetch = &batch.Func{
		Many: func(ctx context.Context, items []interface{}) ([]interface{}, error) {
			table := items[0].(*BaseSelectQuery).Table

			span, ctx := opentracingkit.MaybeStartSpanFromContext(ctx, fmt.Sprintf("thunder.sqlgen.BatchQuery(%s)", table.Name))
			defer span.Finish()

			// First, build the SQL query.
			filters := make([]Filter, 0, len(items))
			for _, item := range items {
				filters = append(filters, item.(*BaseSelectQuery).Filter)
			}
			clause, args := makeBatchQuery(filters)
			query, err := db.Schema.makeSelect(table.Type, nil, &SelectOptions{
				Where:  clause,
				Values: args,
			})
			if err != nil {
				return nil, err
			}
			selectQuery, err := query.MakeSelectQuery()
			if err != nil {
				return nil, err
			}
			clause, args = selectQuery.ToSQL()
			span.SetTag("query", clause)
			span.SetTag("queryVariables", args)

			// Then, run the SQL query.
			res, err := db.Conn.Query(clause, args...)
			if err != nil {
				return nil, err
			}
			defer res.Close()
			rows, err := db.Schema.ParseRows(selectQuery, res)
			if err != nil {
				return nil, err
			}

			// Finally, match the returned rows against the queries.
			matcher := newMatcher()
			for i, item := range items {
				query := item.(*BaseSelectQuery)
				// XXX: This needs more rigor, and a test. For now, call coerceMap on rows
				// and filters to flatten out all pointers to values, etc., to copy what
				// the row tester does when matching against the binlog. This way, a filter
				// specifying age=48 will match a value *age=48.
				matcher.add(i, coerceMap(query.Filter))
			}
			results := make([][]interface{}, len(items))
			for _, row := range rows {
				f := coerceMap(table.extractRow(row))
				for _, idx := range matcher.match(f) {
					i := idx.(int)
					results[i] = append(results[i], row)
				}
			}

			// Convert the [][]interface{} return type into a []interface{} to satisfy
			// the Batch interface.
			rawResults := make([]interface{}, 0, len(items))
			for _, result := range results {
				rawResults = append(rawResults, result)
			}
			return rawResults, nil
		},
		Shard: func(item interface{}) interface{} {
			return item.(*BaseSelectQuery).Table
		},
	}
	return db
}

func (db *DB) BaseQuery(ctx context.Context, query *BaseSelectQuery) ([]interface{}, error) {
	if query.Options == nil && !db.HasTx(ctx) && batch.HasBatching(ctx) {
		rows, err := db.batchFetch.Invoke(ctx, query)
		if err != nil {
			return nil, err
		}
		return rows.([]interface{}), nil
	}

	selectQuery, err := query.MakeSelectQuery()
	if err != nil {
		return nil, err
	}

	clause, fields := selectQuery.ToSQL()

	span, ctx := opentracingkit.MaybeStartSpanFromContext(ctx, fmt.Sprintf("thunder.sqlgen.BaseQuery(%s)", selectQuery.Table))
	defer span.Finish()
	span.SetTag("query", clause)
	span.SetTag("queryVariables", args)

	res, err := db.QueryExecer(ctx).Query(clause, fields...)
	if err != nil {
		return nil, err
	}
	defer res.Close()

	return db.Schema.ParseRows(selectQuery, res)
}

// Query fetches a collection of rows from the database
//
// result should be a pointer to a slice of pointers to structs, for example:
//
//   var users []*User
//   if err := db.Query(ctx, &users, nil, nil); err != nil {
//
func (db *DB) Query(ctx context.Context, result interface{}, filter Filter, options *SelectOptions) error {
	query, err := db.Schema.MakeSelect(result, filter, options)
	if err != nil {
		return err
	}

	rows, err := db.BaseQuery(ctx, query)
	if err != nil {
		return err
	}

	return CopySlice(result, rows)
}

// QueryRow fetches a single row from the database
//
// result should be a pointer to a pointer to a struct, for example:
//
//   var user *User
//   if err := db.Query(ctx, &user, Filter{"id": 10}, nil); err != nil {
//
func (db *DB) QueryRow(ctx context.Context, result interface{}, filter Filter, options *SelectOptions) error {
	query, err := db.Schema.MakeSelectRow(result, filter, options)
	if err != nil {
		return err
	}

	rows, err := db.BaseQuery(ctx, query)
	if err != nil {
		return err
	}

	return CopySingletonSlice(result, rows)
}

// InsertRow inserts a single row into the database
//
// row should be a pointer to a struct, for example:
//
//   user := &User{Name: "foo"}
//   if err := db.InsertRow(ctx, user); err != nil {
//
func (db *DB) InsertRow(ctx context.Context, row interface{}) (sql.Result, error) {
	query, err := db.Schema.MakeInsertRow(row)
	if err != nil {
		return nil, err
	}

	clause, args := query.ToSQL()

	span, ctx := opentracingkit.MaybeStartSpanFromContext(ctx, "thunder.sqlgen.InsertRow")
	defer span.Finish()
	span.SetTag("query", clause)
	span.SetTag("queryVariables", args)

	return db.QueryExecer(ctx).Exec(clause, args...)
}

// UpsertRow inserts a single row into the database
//
// row should be a pointer to a struct, for example:
//
//   user := &User{Name: "foo"}
//   if err := db.UpsertRow(ctx, user); err != nil {
//
func (db *DB) UpsertRow(ctx context.Context, row interface{}) (sql.Result, error) {
	query, err := db.Schema.MakeUpsertRow(row)
	if err != nil {
		return nil, err
	}

	clause, args := query.ToSQL()

	span, ctx := opentracingkit.MaybeStartSpanFromContext(ctx, "thunder.sqlgen.UpsertRow")
	defer span.Finish()
	span.SetTag("query", clause)
	span.SetTag("queryVariables", args)

	return db.QueryExecer(ctx).Exec(clause, args...)
}

// UpdateRow updates a single row in the database, identified by the row's primary key
//
// row should be a pointer to a struct, for example:
//
//   user := &User{Id; 10, Name: "bar"}
//   if err := db.UpdateRow(ctx, user); err != nil {
//
func (db *DB) UpdateRow(ctx context.Context, row interface{}) error {
	query, err := db.Schema.MakeUpdateRow(row)
	if err != nil {
		return err
	}

	clause, args := query.ToSQL()

	span, ctx := opentracingkit.MaybeStartSpanFromContext(ctx, "thunder.sqlgen.UpdateRow")
	defer span.Finish()
	span.SetTag("query", clause)
	span.SetTag("queryVariables", args)

	_, err = db.QueryExecer(ctx).Exec(clause, args...)
	return err
}

// DeleteRow deletes a single row from the database, identified by the row's primary key
//
// row should be a pointer to a struct, for example:
//
//   user := &User{Id; 10}
//   if err := db.DeleteRow(ctx, user); err != nil {
//
func (db *DB) DeleteRow(ctx context.Context, row interface{}) error {
	query, err := db.Schema.MakeDeleteRow(row)
	if err != nil {
		return err
	}

	clause, args := query.ToSQL()

	span, ctx := opentracingkit.MaybeStartSpanFromContext(ctx, "thunder.sqlgen.DeleteRow")
	defer span.Finish()
	span.SetTag("query", clause)
	span.SetTag("queryVariables", args)

	_, err = db.QueryExecer(ctx).Exec(clause, args...)
	return err
}

// txKey is used as a key for a context.Context to hold a transaction.
//
// With multiple open databases, each database can store its own transactions in a context.
type txKey struct {
	db *DB
}

func (db *DB) WithTx(ctx context.Context) (context.Context, *sql.Tx, error) {
	maybeTx := ctx.Value(txKey{db: db})
	if maybeTx != nil {
		return nil, nil, errors.New("already in a tx")
	}

	tx, err := db.Conn.Begin()
	if err != nil {
		return nil, nil, err
	}
	return context.WithValue(ctx, txKey{db: db}, tx), tx, nil
}

func (db *DB) WithExistingTx(ctx context.Context, tx *sql.Tx) (context.Context, error) {
	maybeTx := ctx.Value(txKey{db: db})
	if maybeTx != nil {
		return nil, errors.New("already in a tx")
	}

	return context.WithValue(ctx, txKey{db: db}, tx), nil
}

func (db *DB) HasTx(ctx context.Context) bool {
	return ctx.Value(txKey{db: db}) != nil
}

// A QueryExecer is either a *sql.Tx or a *sql.DB.
type QueryExecer interface {
	Query(query string, args ...interface{}) (*sql.Rows, error)
	QueryRow(query string, args ...interface{}) *sql.Row
	Exec(query string, args ...interface{}) (sql.Result, error)
}

func (db *DB) QueryExecer(ctx context.Context) QueryExecer {
	maybeTx := ctx.Value(txKey{db: db})
	if maybeTx != nil {
		return maybeTx.(*sql.Tx)
	}
	return db.Conn
}
<commit_msg>sqlgen: instrument errors with opentracing<commit_after>package sqlgen

import (
	"context"
	"database/sql"
	"errors"
	"fmt"

	"github.com/opentracing/opentracing-go/ext"
	"github.com/samsarahq/thunder/batch"
	"github.com/samsarahq/thunder/opentracingkit"
)

// DB uses a *sql.DB connection that is established by its owner. DB assumes the
// database connection exists and is alive at all times during the lifecycle of
// the object.
type DB struct {
	Conn   *sql.DB
	Schema *Schema

	batchFetch *batch.Func
}

func NewDB(conn *sql.DB, schema *Schema) *DB {
	db := &DB{
		Conn:   conn,
		Schema: schema,
	}

	db.batchFetch = &batch.Func{
		Many: func(ctx context.Context, items []interface{}) ([]interface{}, error) {
			table := items[0].(*BaseSelectQuery).Table

			span, ctx := opentracingkit.MaybeStartSpanFromContext(ctx, fmt.Sprintf("thunder.sqlgen.BatchQuery(%s)", table.Name))
			defer span.Finish()

			// First, build the SQL query.
			filters := make([]Filter, 0, len(items))
			for _, item := range items {
				filters = append(filters, item.(*BaseSelectQuery).Filter)
			}
			clause, args := makeBatchQuery(filters)
			query, err := db.Schema.makeSelect(table.Type, nil, &SelectOptions{
				Where:  clause,
				Values: args,
			})
			if err != nil {
				return nil, err
			}
			selectQuery, err := query.MakeSelectQuery()
			if err != nil {
				return nil, err
			}
			clause, args = selectQuery.ToSQL()
			span.SetTag("query", clause)
			span.SetTag("queryVariables", args)

			// Then, run the SQL query.
			res, err := db.Conn.Query(clause, args...)
			if err != nil {
				return nil, err
			}
			defer res.Close()
			rows, err := db.Schema.ParseRows(selectQuery, res)
			if err != nil {
				return nil, err
			}

			// Finally, match the returned rows against the queries.
			matcher := newMatcher()
			for i, item := range items {
				query := item.(*BaseSelectQuery)
				// XXX: This needs more rigor, and a test. For now, call coerceMap on rows
				// and filters to flatten out all pointers to values, etc., to copy what
				// the row tester does when matching against the binlog. This way, a filter
				// specifying age=48 will match a value *age=48.
				matcher.add(i, coerceMap(query.Filter))
			}
			results := make([][]interface{}, len(items))
			for _, row := range rows {
				f := coerceMap(table.extractRow(row))
				for _, idx := range matcher.match(f) {
					i := idx.(int)
					results[i] = append(results[i], row)
				}
			}

			// Convert the [][]interface{} return type into a []interface{} to satisfy
			// the Batch interface.
			rawResults := make([]interface{}, 0, len(items))
			for _, result := range results {
				rawResults = append(rawResults, result)
			}
			return rawResults, nil
		},
		Shard: func(item interface{}) interface{} {
			return item.(*BaseSelectQuery).Table
		},
	}
	return db
}

func (db *DB) BaseQuery(ctx context.Context, query *BaseSelectQuery) ([]interface{}, error) {
	if query.Options == nil && !db.HasTx(ctx) && batch.HasBatching(ctx) {
		rows, err := db.batchFetch.Invoke(ctx, query)
		if err != nil {
			return nil, err
		}
		return rows.([]interface{}), nil
	}

	selectQuery, err := query.MakeSelectQuery()
	if err != nil {
		return nil, err
	}

	clause, args := selectQuery.ToSQL()

	span, ctx := opentracingkit.MaybeStartSpanFromContext(ctx, fmt.Sprintf("thunder.sqlgen.BaseQuery(%s)", selectQuery.Table))
	defer span.Finish()
	span.SetTag("query", clause)
	span.SetTag("queryVariables", args)

	res, err := db.QueryExecer(ctx).Query(clause, args...)
	if err != nil {
		ext.Error.Set(span, true)
		span.SetTag("errorMessage", err.Error())
		return nil, err
	}
	defer res.Close()

	return db.Schema.ParseRows(selectQuery, res)
}

// Query fetches a collection of rows from the database
//
// result should be a pointer to a slice of pointers to structs, for example:
//
//   var users []*User
//   if err := db.Query(ctx, &users, nil, nil); err != nil {
//
func (db *DB) Query(ctx context.Context, result interface{}, filter Filter, options *SelectOptions) error {
	query, err := db.Schema.MakeSelect(result, filter, options)
	if err != nil {
		return err
	}

	rows, err := db.BaseQuery(ctx, query)
	if err != nil {
		return err
	}

	return CopySlice(result, rows)
}

// QueryRow fetches a single row from the database
//
// result should be a pointer to a pointer to a struct, for example:
//
//   var user *User
//   if err := db.Query(ctx, &user, Filter{"id": 10}, nil); err != nil {
//
func (db *DB) QueryRow(ctx context.Context, result interface{}, filter Filter, options *SelectOptions) error {
	query, err := db.Schema.MakeSelectRow(result, filter, options)
	if err != nil {
		return err
	}

	rows, err := db.BaseQuery(ctx, query)
	if err != nil {
		return err
	}

	return CopySingletonSlice(result, rows)
}

// InsertRow inserts a single row into the database
//
// row should be a pointer to a struct, for example:
//
//   user := &User{Name: "foo"}
//   if err := db.InsertRow(ctx, user); err != nil {
//
func (db *DB) InsertRow(ctx context.Context, row interface{}) (sql.Result, error) {
	query, err := db.Schema.MakeInsertRow(row)
	if err != nil {
		return nil, err
	}

	clause, args := query.ToSQL()

	span, ctx := opentracingkit.MaybeStartSpanFromContext(ctx, "thunder.sqlgen.InsertRow")
	defer span.Finish()
	span.SetTag("query", clause)
	span.SetTag("queryVariables", args)

	result, err := db.QueryExecer(ctx).Exec(clause, args...)
	if err != nil {
		ext.Error.Set(span, true)
		span.SetTag("errorMessage", err.Error())
	}
	return result, err
}

// UpsertRow inserts a single row into the database
//
// row should be a pointer to a struct, for example:
//
//   user := &User{Name: "foo"}
//   if err := db.UpsertRow(ctx, user); err != nil {
//
func (db *DB) UpsertRow(ctx context.Context, row interface{}) (sql.Result, error) {
	query, err := db.Schema.MakeUpsertRow(row)
	if err != nil {
		return nil, err
	}

	clause, args := query.ToSQL()

	span, ctx := opentracingkit.MaybeStartSpanFromContext(ctx, "thunder.sqlgen.UpsertRow")
	defer span.Finish()
	span.SetTag("query", clause)
	span.SetTag("queryVariables", args)

	result, err := db.QueryExecer(ctx).Exec(clause, args...)
	if err != nil {
		ext.Error.Set(span, true)
		span.SetTag("errorMessage", err.Error())
	}
	return result, err
}

// UpdateRow updates a single row in the database, identified by the row's primary key
//
// row should be a pointer to a struct, for example:
//
//   user := &User{Id; 10, Name: "bar"}
//   if err := db.UpdateRow(ctx, user); err != nil {
//
func (db *DB) UpdateRow(ctx context.Context, row interface{}) error {
	query, err := db.Schema.MakeUpdateRow(row)
	if err != nil {
		return err
	}

	clause, args := query.ToSQL()

	span, ctx := opentracingkit.MaybeStartSpanFromContext(ctx, "thunder.sqlgen.UpdateRow")
	defer span.Finish()
	span.SetTag("query", clause)
	span.SetTag("queryVariables", args)

	_, err = db.QueryExecer(ctx).Exec(clause, args...)
	if err != nil {
		ext.Error.Set(span, true)
		span.SetTag("errorMessage", err.Error())
	}
	return err
}

// DeleteRow deletes a single row from the database, identified by the row's primary key
//
// row should be a pointer to a struct, for example:
//
//   user := &User{Id; 10}
//   if err := db.DeleteRow(ctx, user); err != nil {
//
func (db *DB) DeleteRow(ctx context.Context, row interface{}) error {
	query, err := db.Schema.MakeDeleteRow(row)
	if err != nil {
		return err
	}

	clause, args := query.ToSQL()

	span, ctx := opentracingkit.MaybeStartSpanFromContext(ctx, "thunder.sqlgen.DeleteRow")
	defer span.Finish()
	span.SetTag("query", clause)
	span.SetTag("queryVariables", args)

	_, err = db.QueryExecer(ctx).Exec(clause, args...)
	if err != nil {
		ext.Error.Set(span, true)
		span.SetTag("errorMessage", err.Error())
	}
	return err
}

// txKey is used as a key for a context.Context to hold a transaction.
//
// With multiple open databases, each database can store its own transactions in a context.
type txKey struct {
	db *DB
}

func (db *DB) WithTx(ctx context.Context) (context.Context, *sql.Tx, error) {
	maybeTx := ctx.Value(txKey{db: db})
	if maybeTx != nil {
		return nil, nil, errors.New("already in a tx")
	}

	tx, err := db.Conn.Begin()
	if err != nil {
		return nil, nil, err
	}
	return context.WithValue(ctx, txKey{db: db}, tx), tx, nil
}

func (db *DB) WithExistingTx(ctx context.Context, tx *sql.Tx) (context.Context, error) {
	maybeTx := ctx.Value(txKey{db: db})
	if maybeTx != nil {
		return nil, errors.New("already in a tx")
	}

	return context.WithValue(ctx, txKey{db: db}, tx), nil
}

func (db *DB) HasTx(ctx context.Context) bool {
	return ctx.Value(txKey{db: db}) != nil
}

// A QueryExecer is either a *sql.Tx or a *sql.DB.
type QueryExecer interface {
	Query(query string, args ...interface{}) (*sql.Rows, error)
	QueryRow(query string, args ...interface{}) *sql.Row
	Exec(query string, args ...interface{}) (sql.Result, error)
}

func (db *DB) QueryExecer(ctx context.Context) QueryExecer {
	maybeTx := ctx.Value(txKey{db: db})
	if maybeTx != nil {
		return maybeTx.(*sql.Tx)
	}
	return db.Conn
}
<|endoftext|>


<commit_before>// Package magick is a hacked up port of the minimal functionality we need
// to satisfy the img.Decoder interface.  Code is based in part on
// github.com/quirkey/magick
package main

/*
#cgo pkg-config: MagickCore
#include <magick/MagickCore.h>
*/
import "C"
import (
	"fmt"
	"net/url"
	"os"
	"path/filepath"
	"rais/src/img"
	"rais/src/plugins"
	"strings"
	"unsafe"

	"github.com/uoregon-libraries/gopkg/logger"
)

var l *logger.Logger

// SetLogger is called by the RAIS server's plugin manager to let plugins use
// the central logger
func SetLogger(raisLogger *logger.Logger) {
	l = raisLogger
}

// Initialize sets up the MagickCore stuff and registers the TIFF, PNG, JPG,
// and GIF decoders
func Initialize() {
	path, _ := os.Getwd()
	cPath := C.CString(path)
	defer C.free(unsafe.Pointer(cPath))
	C.MagickCoreGenesis(cPath, C.MagickFalse)
	img.RegisterDecodeHandler(decodeCommonFile)
}

func makeError(exception *C.ExceptionInfo) error {
	return fmt.Errorf("%v: %v - %v", exception.severity, exception.reason, exception.description)
}

var validExtensions = []string{".tif", ".tiff", ".png", ".jpg", ".jpeg", ".gif"}

func validExt(u *url.URL) bool {
	var ext = strings.ToLower(filepath.Ext(u.Path))
	for _, validExt := range validExtensions {
		if ext == validExt {
			return true
		}
	}

	return false
}

func validScheme(u *url.URL) bool {
	return u.Scheme == "file"
}

func decodeCommonFile(s img.Streamer) (img.DecodeFunc, error) {
	var u = s.Location()
	if !validExt(u) {
		l.Debugf("plugins/imagick-decoder: skipping unsupported image extension %q (must be one of %s)",
			s.Location(), strings.Join(validExtensions, ", "))
		return nil, plugins.ErrSkipped
	}

	if !validScheme(u) {
		l.Debugf("plugins/imagick-decoder: skipping unsupported URL scheme %q (must be file)", u.Scheme)
		return nil, plugins.ErrSkipped
	}

	return func() (img.Decoder, error) { return NewImage(u.Path) }, nil
}
<commit_msg>imagick-decoder: fix error output<commit_after>// Package magick is a hacked up port of the minimal functionality we need
// to satisfy the img.Decoder interface.  Code is based in part on
// github.com/quirkey/magick
package main

/*
#cgo pkg-config: MagickCore
#include <magick/MagickCore.h>
*/
import "C"
import (
	"fmt"
	"net/url"
	"os"
	"path/filepath"
	"rais/src/img"
	"rais/src/plugins"
	"strings"
	"unsafe"

	"github.com/uoregon-libraries/gopkg/logger"
)

var l *logger.Logger

// SetLogger is called by the RAIS server's plugin manager to let plugins use
// the central logger
func SetLogger(raisLogger *logger.Logger) {
	l = raisLogger
}

// Initialize sets up the MagickCore stuff and registers the TIFF, PNG, JPG,
// and GIF decoders
func Initialize() {
	path, _ := os.Getwd()
	cPath := C.CString(path)
	defer C.free(unsafe.Pointer(cPath))
	C.MagickCoreGenesis(cPath, C.MagickFalse)
	img.RegisterDecodeHandler(decodeCommonFile)
}

func makeError(exception *C.ExceptionInfo) error {
	var reason = C.GoString(exception.reason)
	var description = C.GoString(exception.description)
	return fmt.Errorf("ImageMagick API Error #%v: %q - %q", exception.severity, reason, description)
}

var validExtensions = []string{".tif", ".tiff", ".png", ".jpg", ".jpeg", ".gif"}

func validExt(u *url.URL) bool {
	var ext = strings.ToLower(filepath.Ext(u.Path))
	for _, validExt := range validExtensions {
		if ext == validExt {
			return true
		}
	}

	return false
}

func validScheme(u *url.URL) bool {
	return u.Scheme == "file"
}

func decodeCommonFile(s img.Streamer) (img.DecodeFunc, error) {
	var u = s.Location()
	if !validExt(u) {
		l.Debugf("plugins/imagick-decoder: skipping unsupported image extension %q (must be one of %s)",
			s.Location(), strings.Join(validExtensions, ", "))
		return nil, plugins.ErrSkipped
	}

	if !validScheme(u) {
		l.Debugf("plugins/imagick-decoder: skipping unsupported URL scheme %q (must be file)", u.Scheme)
		return nil, plugins.ErrSkipped
	}

	return func() (img.Decoder, error) { return NewImage(u.Path) }, nil
}
<|endoftext|>


<commit_before>package rbt

import (
	"fmt"
	"math/rand"
	"testing"

	"github.com/stretchr/testify/assert"
)

func less(x1, x2 interface{}) bool {
	i1, i2 := x1.(int), x2.(int)
	return i1 < i2
}

func TestNode(t *testing.T) {
	k := 3

	n := (*node)(nil)
	t.Log(n)
	n = n.insert(k, less)
	t.Log(n)

	kk, ok := n.search(k, less)
	assert.True(t, ok)
	assert.Equal(t, kk, k)
}

func TestNodeBalance(t *testing.T) {
	ks := []int{1, 2, 3, 4, 5, 6, 7, 8}
	n := (*node)(nil)

	for _, k := range ks {
		n.dump()
		n = n.insert(k, less)
	}

	n.dump()
}

func TestNodeTakeMax(t *testing.T) {
	ks := []int{1, 2, 3, 4, 5, 6, 7, 8}
	n := (*node)(nil)

	for _, k1 := range ks {
		n = n.insert(k1, less)
		n.dump()

		k2, m, _ := n.takeMax()
		assert.Equal(t, k1, k2.(int))
		m.dump()
	}
}

func TestNodeRemove(t *testing.T) {
	ks := []int{1, 2, 3, 4, 5, 6, 7, 8}
	n := (*node)(nil)

	for _, k := range ks {
		n = n.insert(k, less)
	}

	n.dump()

	for _, k := range ks {
		n = n.remove(k, less)
		n.dump()
	}
}

const (
	MaxIters = 2000
	MaxKey   = MaxIters / 2
)

func generateKey() int {
	return rand.Int() % MaxKey
}

func TestNodeInsertRandomly(t *testing.T) {
	n := (*node)(nil)

	for i := 0; i < MaxIters; i++ {
		k := generateKey()
		old := n

		n = n.insert(k, less)

		n.rank() // check ranks

		if !n.checkColors() {
			failWithDump(t, true, k, old, n)
		}
	}
}

func TestNodeRemoveRandomly(t *testing.T) {
	n := (*node)(nil)

	for i := 0; i < MaxIters; i++ {
		k := generateKey()
		old := n

		n, insert := n.insertOrRemove(t, k)

		n.rank() // check ranks

		if !n.checkColors() {
			failWithDump(t, insert, k, old, n)
		}
	}
}

func TestInsertRemovePersistency(t *testing.T) {
	n := (*node)(nil)

	for i := 0; i < MaxIters; i++ {
		k := generateKey()
		old := n
		oldCopy := n.deepCopy()

		n, insert := n.insertOrRemove(t, k)

		n.rank() // check ranks

		if !(old.equal(oldCopy) && n.checkColors()) {
			failWithDump(t, insert, k, old, n)
		}
	}
}

func (n *node) insertOrRemove(t *testing.T, x interface{}) (*node, bool) {
	insert := rand.Int()%2 == 0

	if insert {
		n = n.insert(x, less)
	} else {
		n = n.remove(x, less)
	}

	_, ok := n.search(x, less)
	assert.True(t, insert && ok || !insert && !ok)

	return n, insert
}

func failWithDump(t *testing.T, insert bool, k int, old, new *node) {
	if insert {
		fmt.Println("INSERT")
	} else {
		fmt.Println("REMOVE")
	}

	fmt.Println("KEY:", k)
	fmt.Println("OLD:")
	old.dump()
	fmt.Println("NEW:")
	new.dump()
	t.FailNow()
}

func TestNodeEqual(t *testing.T) {
	n0 := (*node)(nil)
	n1 := n0.insert(1, less)
	n2 := n0.insert(2, less)
	n3 := n1.insert(2, less)
	n4 := n3.insert(3, less)

	for _, test := range []struct {
		n1, n2 *node
		equal  bool
	}{
		{n0, n0, true},
		{n1, n1, true},
		{n2, n2, true},
		{n3, n3, true},
		{n4, n4, true},
		{n0, n1, false},
		{n0, n2, false},
		{n0, n3, false},
		{n0, n4, false},
		{n1, n2, false},
		{n1, n3, false},
		{n2, n3, false},
		{n2, n4, false},
		{n3, n4, false},
	} {
		assert.Equal(t, test.equal, test.n1.equal(test.n2))
	}
}
<commit_msg>Fix invalid assignment of node values on test<commit_after>package rbt

import (
	"fmt"
	"math/rand"
	"testing"

	"github.com/stretchr/testify/assert"
)

func less(x1, x2 interface{}) bool {
	i1, i2 := x1.(int), x2.(int)
	return i1 < i2
}

func TestNode(t *testing.T) {
	k := 3

	n := (*node)(nil)
	t.Log(n)
	n = n.insert(k, less)
	t.Log(n)

	kk, ok := n.search(k, less)
	assert.True(t, ok)
	assert.Equal(t, kk, k)
}

func TestNodeBalance(t *testing.T) {
	ks := []int{1, 2, 3, 4, 5, 6, 7, 8}
	n := (*node)(nil)

	for _, k := range ks {
		n.dump()
		n = n.insert(k, less)
	}

	n.dump()
}

func TestNodeTakeMax(t *testing.T) {
	ks := []int{1, 2, 3, 4, 5, 6, 7, 8}
	n := (*node)(nil)

	for _, k1 := range ks {
		n = n.insert(k1, less)
		n.dump()

		k2, m, _ := n.takeMax()
		assert.Equal(t, k1, k2.(int))
		m.dump()
	}
}

func TestNodeRemove(t *testing.T) {
	ks := []int{1, 2, 3, 4, 5, 6, 7, 8}
	n := (*node)(nil)

	for _, k := range ks {
		n = n.insert(k, less)
	}

	n.dump()

	for _, k := range ks {
		n = n.remove(k, less)
		n.dump()
	}
}

const (
	MaxIters = 2000
	MaxKey   = MaxIters / 2
)

func generateKey() int {
	return rand.Int() % MaxKey
}

func TestNodeInsertRandomly(t *testing.T) {
	n := (*node)(nil)

	for i := 0; i < MaxIters; i++ {
		k := generateKey()
		old := n

		n = n.insert(k, less)

		n.rank() // check ranks

		if !n.checkColors() {
			failWithDump(t, true, k, old, n)
		}
	}
}

func TestNodeRemoveRandomly(t *testing.T) {
	n := (*node)(nil)

	for i := 0; i < MaxIters; i++ {
		k := generateKey()
		old := n

		var insert bool
		n, insert = n.insertOrRemove(t, k)

		n.rank() // check ranks

		if !n.checkColors() {
			failWithDump(t, insert, k, old, n)
		}
	}
}

func TestInsertRemovePersistency(t *testing.T) {
	n := (*node)(nil)

	for i := 0; i < MaxIters; i++ {
		k := generateKey()
		old := n
		oldCopy := n.deepCopy()

		var insert bool
		n, insert = n.insertOrRemove(t, k)

		n.rank() // check ranks

		if !(old.equal(oldCopy) && n.checkColors()) {
			failWithDump(t, insert, k, old, n)
		}
	}
}

func (n *node) insertOrRemove(t *testing.T, x interface{}) (*node, bool) {
	insert := rand.Int()%2 == 0

	if insert {
		n = n.insert(x, less)
	} else {
		n = n.remove(x, less)
	}

	_, ok := n.search(x, less)
	assert.True(t, insert && ok || !insert && !ok)

	return n, insert
}

func failWithDump(t *testing.T, insert bool, k int, old, new *node) {
	if insert {
		fmt.Println("INSERT")
	} else {
		fmt.Println("REMOVE")
	}

	fmt.Println("KEY:", k)
	fmt.Println("OLD:")
	old.dump()
	fmt.Println("NEW:")
	new.dump()
	t.FailNow()
}

func TestNodeEqual(t *testing.T) {
	n0 := (*node)(nil)
	n1 := n0.insert(1, less)
	n2 := n0.insert(2, less)
	n3 := n1.insert(2, less)
	n4 := n3.insert(3, less)

	for _, test := range []struct {
		n1, n2 *node
		equal  bool
	}{
		{n0, n0, true},
		{n1, n1, true},
		{n2, n2, true},
		{n3, n3, true},
		{n4, n4, true},
		{n0, n1, false},
		{n0, n2, false},
		{n0, n3, false},
		{n0, n4, false},
		{n1, n2, false},
		{n1, n3, false},
		{n2, n3, false},
		{n2, n4, false},
		{n3, n4, false},
	} {
		assert.Equal(t, test.equal, test.n1.equal(test.n2))
	}
}
<|endoftext|>


<commit_before>package logmunch

import (
	"bytes"
	"fmt"
	"sort"
	"strconv"
	"strings"
	"time"

	"encoding/json"
	"github.com/kr/logfmt"
)

type LogLine struct {
	Time    time.Time
	RawLine []byte `json:"-"`
	Name    string
	Entries map[string]string
}

func NewLogLine(when time.Time, line string) LogLine {
	return LogLine{
		Time:    when,
		RawLine: []byte(line),
	}
}

func (l *LogLine) String() string {
	parts := make([]string, 2, len(l.Entries)+2)

	parts[0] = l.Time.Format(time.RFC3339Nano)
	parts[1] = l.Name

	// Key-value pairs
	for key, value := range l.Entries {
		if strings.Contains(value, " ") {
			value = fmt.Sprintf(`"%s"`, value)
		}
		parts = append(parts, fmt.Sprintf("%s=%s", key, value))
	}
	sort.Strings(parts[2:])

	return strings.Join(parts, " ")
}

func (l LogLine) MarshalJSON() ([]byte, error) {
	return json.Marshal(struct {
		Time    time.Time         `json:"time"`
		Unix    int64             `json:"unixtime"`
		Name    string            `json:"name"`
		Entries map[string]string `json:"entries"`
	}{
		Time:    l.Time,
		Unix:    l.Time.UnixNano() / 1e6,
		Name:    l.Name,
		Entries: l.Entries,
	})
}

func (l *LogLine) HandleLogfmt(key, val []byte) error {
	if l.Entries == nil {
		l.Entries = make(map[string]string)
	}
	l.Entries[string(key)] = string(val)
	return nil
}

// TODO(msiebuhr): Arrays and nil's
func (l *LogLine) convertJsonToKeyValues(prefix []byte, in map[string]interface{}) {
	// l.HandleLogfmt(key, val) on each set of data

	for key, value := range in {
		var k []byte
		if len(prefix) > 0 {
			k = bytes.Join([][]byte{prefix, []byte(key)}, []byte{'.'})
		} else {
			k = []byte(key)
		}

		switch t := value.(type) {
		case bool:
			if t {
				l.HandleLogfmt(k, []byte("true"))
			} else {
				l.HandleLogfmt(k, []byte("false"))
			}
		case float64:
			l.HandleLogfmt(k, []byte(strconv.FormatFloat(t, 'f', -1, 64)))
		case string:
			l.HandleLogfmt(k, []byte(t))
		case map[string]interface{}:
			l.convertJsonToKeyValues(k, t)
		default:
			//fmt.Println("Doesn't know what to do with", t)
			l.HandleLogfmt(k, []byte(fmt.Sprintf("UNSUPPORTED: %+v", t)))
		}
	}
}

func (l *LogLine) parseLogEntries() error {
	// Don't parse if we already have values
	if l.Entries != nil {
		return nil
	}

	// Try parsing substring as JSON
	if bytes.IndexRune(l.RawLine, '{') != -1 {
		var x map[string]interface{}
		err := json.Unmarshal(l.RawLine[bytes.IndexRune(l.RawLine, '{'):], &x)
		// Bingo!
		if err == nil {
			l.Name = strings.Trim(string(l.RawLine[:bytes.IndexRune(l.RawLine, '{')]), " ")
			l.convertJsonToKeyValues([]byte{}, x)
			return nil
		}
	}

	// For name, pick the first thing that isn't a KV-pair
	names := bytes.Fields(l.RawLine)
	for _, name := range names {
		if bytes.Index(name, []byte{'='}) == -1 {
			l.Name = strings.Trim(string(name), " ")
			break
		}
	}

	// Parse values
	return logfmt.Unmarshal(l.RawLine, l)
}

func (l *LogLine) HasKey(key string) bool {
	l.parseLogEntries()
	_, exists := l.Entries[key]
	return exists
}

func (l *LogLine) KeyEqualsString(key, value string) bool {
	l.parseLogEntries()
	val, exists := l.Entries[key]
	if !exists {
		return false
	}
	return val == value
}

func (l *LogLine) GetNumber(key string) float64 {
	l.parseLogEntries()

	value, exists := l.Entries[key]
	if !exists {
		return 0
	}

	numbersInValue := strings.Map(func(r rune) rune {
		if (r >= '0' && '9' >= r) || r == '.' {
			return r
		}
		return -1
	}, value)

	n, err := strconv.ParseFloat(numbersInValue, 64)
	if err != nil {
		return 0
	}

	return n
}

func (l *LogLine) HasPrefix(prefix string) bool {
	l.parseLogEntries()
	return strings.HasPrefix(l.Name, prefix)
}
<commit_msg>LogLines: Quote keys with spaces in them.<commit_after>package logmunch

import (
	"bytes"
	"fmt"
	"sort"
	"strconv"
	"strings"
	"time"

	"encoding/json"
	"github.com/kr/logfmt"
)

type LogLine struct {
	Time    time.Time
	RawLine []byte `json:"-"`
	Name    string
	Entries map[string]string
}

func NewLogLine(when time.Time, line string) LogLine {
	return LogLine{
		Time:    when,
		RawLine: []byte(line),
	}
}

func (l *LogLine) String() string {
	parts := make([]string, 2, len(l.Entries)+2)

	parts[0] = l.Time.Format(time.RFC3339Nano)
	parts[1] = l.Name

	// Key-value pairs
	for key, value := range l.Entries {
		if strings.Contains(value, " ") {
			value = fmt.Sprintf(`"%s"`, value)
		}
		if strings.Contains(key, " ") {
			key = fmt.Sprintf(`"%s"`, key)
		}
		parts = append(parts, fmt.Sprintf("%s=%s", key, value))
	}
	sort.Strings(parts[2:])

	return strings.Join(parts, " ")
}

func (l LogLine) MarshalJSON() ([]byte, error) {
	return json.Marshal(struct {
		Time    time.Time         `json:"time"`
		Unix    int64             `json:"unixtime"`
		Name    string            `json:"name"`
		Entries map[string]string `json:"entries"`
	}{
		Time:    l.Time,
		Unix:    l.Time.UnixNano() / 1e6,
		Name:    l.Name,
		Entries: l.Entries,
	})
}

func (l *LogLine) HandleLogfmt(key, val []byte) error {
	if l.Entries == nil {
		l.Entries = make(map[string]string)
	}
	l.Entries[string(key)] = string(val)
	return nil
}

// TODO(msiebuhr): Arrays and nil's
func (l *LogLine) convertJsonToKeyValues(prefix []byte, in map[string]interface{}) {
	// l.HandleLogfmt(key, val) on each set of data

	for key, value := range in {
		var k []byte
		if len(prefix) > 0 {
			k = bytes.Join([][]byte{prefix, []byte(key)}, []byte{'.'})
		} else {
			k = []byte(key)
		}

		switch t := value.(type) {
		case bool:
			if t {
				l.HandleLogfmt(k, []byte("true"))
			} else {
				l.HandleLogfmt(k, []byte("false"))
			}
		case float64:
			l.HandleLogfmt(k, []byte(strconv.FormatFloat(t, 'f', -1, 64)))
		case string:
			l.HandleLogfmt(k, []byte(t))
		case map[string]interface{}:
			l.convertJsonToKeyValues(k, t)
		default:
			//fmt.Println("Doesn't know what to do with", t)
			l.HandleLogfmt(k, []byte(fmt.Sprintf("UNSUPPORTED: %+v", t)))
		}
	}
}

func (l *LogLine) parseLogEntries() error {
	// Don't parse if we already have values
	if l.Entries != nil {
		return nil
	}

	// Try parsing substring as JSON
	if bytes.IndexRune(l.RawLine, '{') != -1 {
		var x map[string]interface{}
		err := json.Unmarshal(l.RawLine[bytes.IndexRune(l.RawLine, '{'):], &x)
		// Bingo!
		if err == nil {
			l.Name = strings.Trim(string(l.RawLine[:bytes.IndexRune(l.RawLine, '{')]), " ")
			l.convertJsonToKeyValues([]byte{}, x)
			return nil
		}
	}

	// For name, pick the first thing that isn't a KV-pair
	names := bytes.Fields(l.RawLine)
	for _, name := range names {
		if bytes.Index(name, []byte{'='}) == -1 {
			l.Name = strings.Trim(string(name), " ")
			break
		}
	}

	// Parse values
	return logfmt.Unmarshal(l.RawLine, l)
}

func (l *LogLine) HasKey(key string) bool {
	l.parseLogEntries()
	_, exists := l.Entries[key]
	return exists
}

func (l *LogLine) KeyEqualsString(key, value string) bool {
	l.parseLogEntries()
	val, exists := l.Entries[key]
	if !exists {
		return false
	}
	return val == value
}

func (l *LogLine) GetNumber(key string) float64 {
	l.parseLogEntries()

	value, exists := l.Entries[key]
	if !exists {
		return 0
	}

	numbersInValue := strings.Map(func(r rune) rune {
		if (r >= '0' && '9' >= r) || r == '.' {
			return r
		}
		return -1
	}, value)

	n, err := strconv.ParseFloat(numbersInValue, 64)
	if err != nil {
		return 0
	}

	return n
}

func (l *LogLine) HasPrefix(prefix string) bool {
	l.parseLogEntries()
	return strings.HasPrefix(l.Name, prefix)
}
<|endoftext|>


<commit_before>package main

import (
	"net/http"
	"os"
	"fmt"
	"log"
	"github.com/nu7hatch/gouuid"
	"github.com/vaughan0/go-ini"
)

var TriggerNotFoundMsg = "Trigger could not be found."

// A handler for a specific trigger.
type TriggerTrigger struct {
	// the path for which this trigger is triggered.
	path string
	// the URL that is to be called when this trigger i triggered
	outputurl string
}

// create a new trigger trigger for a specific path
func LoadHandler(outputurl, path string) TriggerTrigger {
	return TriggerTrigger{
		path: path,
		outputurl: outputurl,
	}
}

// log and trigger the specific trigger
//
// Does proper checks to make sure that the right method is from
// downstream.
func (tt TriggerTrigger) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET"{
		// only supporting GET at the moment
		log.Println("[server]", r.Method, r.URL.Path, "404 (only GET allowed)")
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprintf(w, TriggerNotFoundMsg)
		return
	}
	if r.URL.Path != tt.path {
		// if this isn't here we'll trigger for all path
		// prefixes.
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprintf(w, TriggerNotFoundMsg)
		return
	}

	loguuid, err := uuid.NewV4()
	// used to correlate server and client log lines
	var id string
	if err != nil {
		id = "???"
	} else {
		id = loguuid.String()
	}

	log.Println("[server]", id, "GET", r.URL.Path, "200")
	fmt.Fprintf(w, "Triggered.")
	go func() {
		resp, err := http.Get(tt.outputurl)
		var result string
		if err != nil {
			result = "Err: " + err.Error()
		} else {
			result = resp.Status
		}
		log.Println("[client]", id, "GET", tt.outputurl, result)
	}()
}

// Load all handlers from the configuration file.
func LoadHandlers(file ini.File) {
	root_found := false

	for path, _ := range file {
		if path == "" {
			// ignoring default section
			continue
		}

		if path == "/" {
			root_found = true
		}

		outputurl, ok := file.Get(path, "url")
		if !ok {
			panic(fmt.Sprintf("'url' missing for: %s", path))
		}

		http.Handle(path, LoadHandler(outputurl, path))
	}

	if !root_found {
		// custom 404
		http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
			log.Println("[server]", r.Method, r.URL.Path, "404")
			w.WriteHeader(http.StatusNotFound)
			fmt.Fprintf(w, TriggerNotFoundMsg)
		})
	}
}

const CONFIG_FILE_ENVIRON = "TRIGGER_TRIGGER_CONFIG"

func main() {
	inifilename := os.Getenv(CONFIG_FILE_ENVIRON)
	if inifilename == "" {
		fmt.Println("Please point", CONFIG_FILE_ENVIRON, "to config file.")
		os.Exit(1)
	}

	file, err := ini.LoadFile(inifilename)
	if err != nil {
		panic(fmt.Sprintf("Could not read config file: %s", inifilename))
	}

	LoadHandlers(file)

	listen, ok := file.Get("", "listen")
	if !ok {
		log.Print("[server] 'listen' not defined. Using fallback ':8080'")
		listen = ":8080"
	}

	log.Fatal(http.ListenAndServe(listen, nil))
}
<commit_msg>Rename: `TriggerTrigger` => `Trigger`<commit_after>package main

import (
	"net/http"
	"os"
	"fmt"
	"log"
	"github.com/nu7hatch/gouuid"
	"github.com/vaughan0/go-ini"
)

var TriggerNotFoundMsg = "Trigger could not be found."

// A handler for a specific trigger.
type Trigger struct {
	// the path for which this trigger is triggered.
	path string
	// the URL that is to be called when this trigger i triggered
	outputurl string
}

// create a new trigger trigger for a specific path
func LoadHandler(outputurl, path string) Trigger {
	return Trigger{
		path: path,
		outputurl: outputurl,
	}
}

// log and trigger the specific trigger
//
// Does proper checks to make sure that the right method is from
// downstream.
func (tt Trigger) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET"{
		// only supporting GET at the moment
		log.Println("[server]", r.Method, r.URL.Path, "404 (only GET allowed)")
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprintf(w, TriggerNotFoundMsg)
		return
	}
	if r.URL.Path != tt.path {
		// if this isn't here we'll trigger for all path
		// prefixes.
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprintf(w, TriggerNotFoundMsg)
		return
	}

	loguuid, err := uuid.NewV4()
	// used to correlate server and client log lines
	var id string
	if err != nil {
		id = "???"
	} else {
		id = loguuid.String()
	}

	log.Println("[server]", id, "GET", r.URL.Path, "200")
	fmt.Fprintf(w, "Triggered.")
	go func() {
		resp, err := http.Get(tt.outputurl)
		var result string
		if err != nil {
			result = "Err: " + err.Error()
		} else {
			result = resp.Status
		}
		log.Println("[client]", id, "GET", tt.outputurl, result)
	}()
}

// Load all handlers from the configuration file.
func LoadHandlers(file ini.File) {
	root_found := false

	for path, _ := range file {
		if path == "" {
			// ignoring default section
			continue
		}

		if path == "/" {
			root_found = true
		}

		outputurl, ok := file.Get(path, "url")
		if !ok {
			panic(fmt.Sprintf("'url' missing for: %s", path))
		}

		http.Handle(path, LoadHandler(outputurl, path))
	}

	if !root_found {
		// custom 404
		http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
			log.Println("[server]", r.Method, r.URL.Path, "404")
			w.WriteHeader(http.StatusNotFound)
			fmt.Fprintf(w, TriggerNotFoundMsg)
		})
	}
}

const CONFIG_FILE_ENVIRON = "TRIGGER_TRIGGER_CONFIG"

func main() {
	inifilename := os.Getenv(CONFIG_FILE_ENVIRON)
	if inifilename == "" {
		fmt.Println("Please point", CONFIG_FILE_ENVIRON, "to config file.")
		os.Exit(1)
	}

	file, err := ini.LoadFile(inifilename)
	if err != nil {
		panic(fmt.Sprintf("Could not read config file: %s", inifilename))
	}

	LoadHandlers(file)

	listen, ok := file.Get("", "listen")
	if !ok {
		log.Print("[server] 'listen' not defined. Using fallback ':8080'")
		listen = ":8080"
	}

	log.Fatal(http.ListenAndServe(listen, nil))
}
<|endoftext|>


<commit_before>// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build ignore
// +build ignore

package main

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
)

var gooses, goarches []string

func main() {
	data, err := os.ReadFile("../../../go/build/syslist.go")
	if err != nil {
		log.Fatal(err)
	}
	const (
		goosPrefix   = `const goosList = `
		goarchPrefix = `const goarchList = `
	)
	for _, line := range strings.Split(string(data), "\n") {
		if strings.HasPrefix(line, goosPrefix) {
			text, err := strconv.Unquote(strings.TrimPrefix(line, goosPrefix))
			if err != nil {
				log.Fatalf("parsing goosList: %v", err)
			}
			gooses = strings.Fields(text)
		}
		if strings.HasPrefix(line, goarchPrefix) {
			text, err := strconv.Unquote(strings.TrimPrefix(line, goarchPrefix))
			if err != nil {
				log.Fatalf("parsing goarchList: %v", err)
			}
			goarches = strings.Fields(text)
		}
	}

	for _, target := range gooses {
		if target == "nacl" {
			continue
		}
		var buf bytes.Buffer
		fmt.Fprintf(&buf, "// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.\n\n")
		if target == "linux" {
			fmt.Fprintf(&buf, "// +build !android\n") // must explicitly exclude android for linux
		}
		if target == "solaris" {
			fmt.Fprintf(&buf, "// +build !illumos\n") // must explicitly exclude illumos for solaris
		}
		if target == "darwin" {
			fmt.Fprintf(&buf, "// +build !ios\n") // must explicitly exclude ios for darwin
		}
		fmt.Fprintf(&buf, "// +build %s\n\n", target) // must explicitly include target for bootstrapping purposes
		fmt.Fprintf(&buf, "package sys\n\n")
		fmt.Fprintf(&buf, "const GOOS = `%s`\n\n", target)
		for _, goos := range gooses {
			value := 0
			if goos == target {
				value = 1
			}
			fmt.Fprintf(&buf, "const Goos%s = %d\n", strings.Title(goos), value)
		}
		err := os.WriteFile("zgoos_"+target+".go", buf.Bytes(), 0666)
		if err != nil {
			log.Fatal(err)
		}
	}

	for _, target := range goarches {
		if target == "amd64p32" {
			continue
		}
		var buf bytes.Buffer
		fmt.Fprintf(&buf, "// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.\n\n")
		fmt.Fprintf(&buf, "// +build %s\n\n", target) // must explicitly include target for bootstrapping purposes
		fmt.Fprintf(&buf, "package sys\n\n")
		fmt.Fprintf(&buf, "const GOARCH = `%s`\n\n", target)
		for _, goarch := range goarches {
			value := 0
			if goarch == target {
				value = 1
			}
			fmt.Fprintf(&buf, "const Goarch%s = %d\n", strings.Title(goarch), value)
		}
		err := os.WriteFile("zgoarch_"+target+".go", buf.Bytes(), 0666)
		if err != nil {
			log.Fatal(err)
		}
	}
}
<commit_msg>runtime/internal/sys: generate //go:build lines in gengoos.go<commit_after>// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build ignore
// +build ignore

package main

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
)

var gooses, goarches []string

func main() {
	data, err := os.ReadFile("../../../go/build/syslist.go")
	if err != nil {
		log.Fatal(err)
	}
	const (
		goosPrefix   = `const goosList = `
		goarchPrefix = `const goarchList = `
	)
	for _, line := range strings.Split(string(data), "\n") {
		if strings.HasPrefix(line, goosPrefix) {
			text, err := strconv.Unquote(strings.TrimPrefix(line, goosPrefix))
			if err != nil {
				log.Fatalf("parsing goosList: %v", err)
			}
			gooses = strings.Fields(text)
		}
		if strings.HasPrefix(line, goarchPrefix) {
			text, err := strconv.Unquote(strings.TrimPrefix(line, goarchPrefix))
			if err != nil {
				log.Fatalf("parsing goarchList: %v", err)
			}
			goarches = strings.Fields(text)
		}
	}

	for _, target := range gooses {
		if target == "nacl" {
			continue
		}
		var tags []string
		if target == "linux" {
			tags = append(tags, "!android") // must explicitly exclude android for linux
		}
		if target == "solaris" {
			tags = append(tags, "!illumos") // must explicitly exclude illumos for solaris
		}
		if target == "darwin" {
			tags = append(tags, "!ios") // must explicitly exclude ios for darwin
		}
		tags = append(tags, target) // must explicitly include target for bootstrapping purposes
		var buf bytes.Buffer
		fmt.Fprintf(&buf, "// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.\n\n")
		fmt.Fprintf(&buf, "//go:build %s\n", strings.Join(tags, " && "))
		fmt.Fprintf(&buf, "// +build %s\n\n", strings.Join(tags, ","))
		fmt.Fprintf(&buf, "package sys\n\n")
		fmt.Fprintf(&buf, "const GOOS = `%s`\n\n", target)
		for _, goos := range gooses {
			value := 0
			if goos == target {
				value = 1
			}
			fmt.Fprintf(&buf, "const Goos%s = %d\n", strings.Title(goos), value)
		}
		err := os.WriteFile("zgoos_"+target+".go", buf.Bytes(), 0666)
		if err != nil {
			log.Fatal(err)
		}
	}

	for _, target := range goarches {
		if target == "amd64p32" {
			continue
		}
		var buf bytes.Buffer
		fmt.Fprintf(&buf, "// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.\n\n")
		fmt.Fprintf(&buf, "//go:build %s\n", target)
		fmt.Fprintf(&buf, "// +build %s\n\n", target) // must explicitly include target for bootstrapping purposes
		fmt.Fprintf(&buf, "package sys\n\n")
		fmt.Fprintf(&buf, "const GOARCH = `%s`\n\n", target)
		for _, goarch := range goarches {
			value := 0
			if goarch == target {
				value = 1
			}
			fmt.Fprintf(&buf, "const Goarch%s = %d\n", strings.Title(goarch), value)
		}
		err := os.WriteFile("zgoarch_"+target+".go", buf.Bytes(), 0666)
		if err != nil {
			log.Fatal(err)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"strings"

	"github.com/containers/buildah"
	"github.com/containers/buildah/define"
	"github.com/containers/buildah/internal/util"
	buildahcli "github.com/containers/buildah/pkg/cli"
	"github.com/containers/buildah/pkg/parse"
	"github.com/containers/common/pkg/auth"
	"github.com/containers/common/pkg/config"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

type fromReply struct {
	authfile        string
	certDir         string
	cidfile         string
	creds           string
	format          string
	name            string
	pull            string
	pullAlways      bool
	pullNever       bool
	quiet           bool
	signaturePolicy string
	tlsVerify       bool
	*buildahcli.FromAndBudResults
	*buildahcli.UserNSResults
	*buildahcli.NameSpaceResults
}

var suffix string

func init() {
	var (
		fromDescription = "\n  Creates a new working container, either from scratch or using a specified\n  image as a starting point."
		opts            fromReply
	)
	fromAndBudResults := buildahcli.FromAndBudResults{}
	userNSResults := buildahcli.UserNSResults{}
	namespaceResults := buildahcli.NameSpaceResults{}
	fromCommand := &cobra.Command{
		Use:   "from",
		Short: "Create a working container based on an image",
		Long:  fromDescription,
		RunE: func(cmd *cobra.Command, args []string) error {
			// Add in the results from the common cli commands
			opts.FromAndBudResults = &fromAndBudResults
			opts.UserNSResults = &userNSResults
			opts.NameSpaceResults = &namespaceResults
			return fromCmd(cmd, args, opts)
		},
		Example: `buildah from --pull imagename
  buildah from docker-daemon:imagename:imagetag
  buildah from --name "myimagename" myregistry/myrepository/imagename:imagetag`,
	}
	fromCommand.SetUsageTemplate(UsageTemplate())

	flags := fromCommand.Flags()
	flags.SetInterspersed(false)
	flags.StringVar(&opts.authfile, "authfile", auth.GetDefaultAuthFile(), "path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override")
	flags.StringVar(&opts.certDir, "cert-dir", "", "use certificates at the specified path to access the registry")
	flags.StringVar(&opts.cidfile, "cidfile", "", "write the container ID to the file")
	flags.StringVar(&opts.creds, "creds", "", "use `[username[:password]]` for accessing the registry")
	flags.StringVarP(&opts.format, "format", "f", defaultFormat(), "`format` of the image manifest and metadata")
	flags.StringVar(&opts.name, "name", "", "`name` for the working container")
	flags.StringVar(&opts.pull, "pull", "true", "pull the image from the registry if newer or not present in store, if false, only pull the image if not present, if always, pull the image even if the named image is present in store, if never, only use the image present in store if available")
	flags.Lookup("pull").NoOptDefVal = "true" //allow `--pull ` to be set to `true` as expected.

	flags.BoolVar(&opts.pullAlways, "pull-always", false, "pull the image even if the named image is present in store")
	if err := flags.MarkHidden("pull-always"); err != nil {
		panic(fmt.Sprintf("error marking the pull-always flag as hidden: %v", err))
	}
	flags.BoolVar(&opts.pullNever, "pull-never", false, "do not pull the image, use the image present in store if available")
	if err := flags.MarkHidden("pull-never"); err != nil {
		panic(fmt.Sprintf("error marking the pull-never flag as hidden: %v", err))
	}
	flags.BoolVarP(&opts.quiet, "quiet", "q", false, "don't output progress information when pulling images")
	flags.StringVar(&opts.signaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
	flags.StringVar(&suffix, "suffix", "", "suffix to add to intermediate containers")
	if err := flags.MarkHidden("suffix"); err != nil {
		panic(fmt.Sprintf("error marking the suffix flag as hidden: %v", err))
	}

	if err := flags.MarkHidden("signature-policy"); err != nil {
		panic(fmt.Sprintf("error marking signature-policy as hidden: %v", err))
	}
	flags.BoolVar(&opts.tlsVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry. TLS verification cannot be used when talking to an insecure registry.")

	// Add in the common flags
	fromAndBudFlags, err := buildahcli.GetFromAndBudFlags(&fromAndBudResults, &userNSResults, &namespaceResults)
	if err != nil {
		logrus.Errorf("failed to setup From and Bud flags: %v", err)
		os.Exit(1)
	}
	flags.AddFlagSet(&fromAndBudFlags)
	flags.SetNormalizeFunc(buildahcli.AliasFlags)

	rootCmd.AddCommand(fromCommand)
}

func onBuild(builder *buildah.Builder, quiet bool) error {
	ctr := 0
	for _, onBuildSpec := range builder.OnBuild() {
		ctr = ctr + 1
		commands := strings.Split(onBuildSpec, " ")
		command := strings.ToUpper(commands[0])
		args := commands[1:]
		if !quiet {
			fmt.Fprintf(os.Stderr, "STEP %d: %s\n", ctr, onBuildSpec)
		}
		switch command {
		case "ADD":
		case "COPY":
			dest := ""
			size := len(args)
			if size > 1 {
				dest = args[size-1]
				args = args[:size-1]
			}
			if err := builder.Add(dest, command == "ADD", buildah.AddAndCopyOptions{}, args...); err != nil {
				return err
			}
		case "ANNOTATION":
			annotation := strings.SplitN(args[0], "=", 2)
			if len(annotation) > 1 {
				builder.SetAnnotation(annotation[0], annotation[1])
			} else {
				builder.UnsetAnnotation(annotation[0])
			}
		case "CMD":
			builder.SetCmd(args)
		case "ENV":
			env := strings.SplitN(args[0], "=", 2)
			if len(env) > 1 {
				builder.SetEnv(env[0], env[1])
			} else {
				builder.UnsetEnv(env[0])
			}
		case "ENTRYPOINT":
			builder.SetEntrypoint(args)
		case "EXPOSE":
			builder.SetPort(strings.Join(args, " "))
		case "HOSTNAME":
			builder.SetHostname(strings.Join(args, " "))
		case "LABEL":
			label := strings.SplitN(args[0], "=", 2)
			if len(label) > 1 {
				builder.SetLabel(label[0], label[1])
			} else {
				builder.UnsetLabel(label[0])
			}
		case "MAINTAINER":
			builder.SetMaintainer(strings.Join(args, " "))
		case "ONBUILD":
			builder.SetOnBuild(strings.Join(args, " "))
		case "RUN":
			var stdout io.Writer
			if quiet {
				stdout = ioutil.Discard
			}
			if err := builder.Run(args, buildah.RunOptions{Stdout: stdout}); err != nil {
				return err
			}
		case "SHELL":
			builder.SetShell(args)
		case "STOPSIGNAL":
			builder.SetStopSignal(strings.Join(args, " "))
		case "USER":
			builder.SetUser(strings.Join(args, " "))
		case "VOLUME":
			builder.AddVolume(strings.Join(args, " "))
		case "WORKINGDIR":
			builder.SetWorkDir(strings.Join(args, " "))
		default:
			logrus.Errorf("unknown OnBuild command %q; ignored", onBuildSpec)
		}
	}
	builder.ClearOnBuild()
	return nil
}

func fromCmd(c *cobra.Command, args []string, iopts fromReply) error {
	defaultContainerConfig, err := config.Default()
	if err != nil {
		return fmt.Errorf("failed to get container config: %w", err)
	}

	if len(args) == 0 {
		return errors.New("an image name (or \"scratch\") must be specified")
	}
	if err := buildahcli.VerifyFlagsArgsOrder(args); err != nil {
		return err
	}
	if len(args) > 1 {
		return errors.New("too many arguments specified")
	}

	if err := auth.CheckAuthFile(iopts.authfile); err != nil {
		return err
	}
	systemContext, err := parse.SystemContextFromOptions(c)
	if err != nil {
		return fmt.Errorf("error building system context: %w", err)
	}
	platforms, err := parse.PlatformsFromOptions(c)
	if err != nil {
		return err
	}
	if len(platforms) > 1 {
		logrus.Warnf("ignoring platforms other than %+v: %+v", platforms[0], platforms[1:])
	}

	pullFlagsCount := 0
	if c.Flag("pull").Changed {
		pullFlagsCount++
	}
	if c.Flag("pull-always").Changed {
		pullFlagsCount++
	}
	if c.Flag("pull-never").Changed {
		pullFlagsCount++
	}

	if pullFlagsCount > 1 {
		return errors.New("can only set one of 'pull' or 'pull-always' or 'pull-never'")
	}

	// Allow for --pull, --pull=true, --pull=false, --pull=never, --pull=always
	// --pull-always and --pull-never.  The --pull-never and --pull-always options
	// will not be documented.
	pullPolicy := define.PullIfMissing
	if strings.EqualFold(strings.TrimSpace(iopts.pull), "true") {
		pullPolicy = define.PullIfNewer
	}
	if iopts.pullAlways || strings.EqualFold(strings.TrimSpace(iopts.pull), "always") {
		pullPolicy = define.PullAlways
	}
	if iopts.pullNever || strings.EqualFold(strings.TrimSpace(iopts.pull), "never") {
		pullPolicy = define.PullNever
	}
	logrus.Debugf("Pull Policy for pull [%v]", pullPolicy)

	signaturePolicy := iopts.signaturePolicy

	store, err := getStore(c)
	if err != nil {
		return err
	}

	commonOpts, err := parse.CommonBuildOptions(c)
	if err != nil {
		return err
	}

	isolation, err := parse.IsolationOption(iopts.Isolation)
	if err != nil {
		return err
	}

	namespaceOptions, networkPolicy, err := parse.NamespaceOptions(c)
	if err != nil {
		return fmt.Errorf("error parsing namespace-related options: %w", err)
	}
	usernsOption, idmappingOptions, err := parse.IDMappingOptions(c, isolation)
	if err != nil {
		return fmt.Errorf("error parsing ID mapping options: %w", err)
	}
	namespaceOptions.AddOrReplace(usernsOption...)

	format, err := util.GetFormat(iopts.format)
	if err != nil {
		return err
	}
	devices := define.ContainerDevices{}
	for _, device := range append(defaultContainerConfig.Containers.Devices, iopts.Devices...) {
		dev, err := parse.DeviceFromPath(device)
		if err != nil {
			return err
		}
		devices = append(devices, dev...)
	}

	capabilities, err := defaultContainerConfig.Capabilities("", iopts.CapAdd, iopts.CapDrop)
	if err != nil {
		return err
	}

	commonOpts.Ulimit = append(defaultContainerConfig.Containers.DefaultUlimits, commonOpts.Ulimit...)

	decConfig, err := util.DecryptConfig(iopts.DecryptionKeys)
	if err != nil {
		return fmt.Errorf("unable to obtain decrypt config: %w", err)
	}

	options := buildah.BuilderOptions{
		FromImage:             args[0],
		Container:             iopts.name,
		ContainerSuffix:       suffix,
		PullPolicy:            pullPolicy,
		SignaturePolicyPath:   signaturePolicy,
		SystemContext:         systemContext,
		DefaultMountsFilePath: globalFlagResults.DefaultMountsFile,
		Isolation:             isolation,
		NamespaceOptions:      namespaceOptions,
		ConfigureNetwork:      networkPolicy,
		CNIPluginPath:         iopts.CNIPlugInPath,
		CNIConfigDir:          iopts.CNIConfigDir,
		IDMappingOptions:      idmappingOptions,
		Capabilities:          capabilities,
		CommonBuildOpts:       commonOpts,
		Format:                format,
		BlobDirectory:         iopts.BlobCache,
		Devices:               devices,
		MaxPullRetries:        buildahcli.MaxPullPushRetries,
		PullRetryDelay:        buildahcli.PullPushRetryDelay,
		OciDecryptConfig:      decConfig,
	}

	if !iopts.quiet {
		options.ReportWriter = os.Stderr
	}

	builder, err := buildah.NewBuilder(getContext(), store, options)
	if err != nil {
		return err
	}

	if err := onBuild(builder, iopts.quiet); err != nil {
		return err
	}

	if iopts.cidfile != "" {
		filePath := iopts.cidfile
		if err := ioutil.WriteFile(filePath, []byte(builder.ContainerID), 0644); err != nil {
			return fmt.Errorf("filed to write Container ID File %q: %w", filePath, err)
		}
	}
	fmt.Printf("%s\n", builder.Container)
	return builder.Save()
}
<commit_msg>Fix a typo in an error message<commit_after>package main

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"strings"

	"github.com/containers/buildah"
	"github.com/containers/buildah/define"
	"github.com/containers/buildah/internal/util"
	buildahcli "github.com/containers/buildah/pkg/cli"
	"github.com/containers/buildah/pkg/parse"
	"github.com/containers/common/pkg/auth"
	"github.com/containers/common/pkg/config"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

type fromReply struct {
	authfile        string
	certDir         string
	cidfile         string
	creds           string
	format          string
	name            string
	pull            string
	pullAlways      bool
	pullNever       bool
	quiet           bool
	signaturePolicy string
	tlsVerify       bool
	*buildahcli.FromAndBudResults
	*buildahcli.UserNSResults
	*buildahcli.NameSpaceResults
}

var suffix string

func init() {
	var (
		fromDescription = "\n  Creates a new working container, either from scratch or using a specified\n  image as a starting point."
		opts            fromReply
	)
	fromAndBudResults := buildahcli.FromAndBudResults{}
	userNSResults := buildahcli.UserNSResults{}
	namespaceResults := buildahcli.NameSpaceResults{}
	fromCommand := &cobra.Command{
		Use:   "from",
		Short: "Create a working container based on an image",
		Long:  fromDescription,
		RunE: func(cmd *cobra.Command, args []string) error {
			// Add in the results from the common cli commands
			opts.FromAndBudResults = &fromAndBudResults
			opts.UserNSResults = &userNSResults
			opts.NameSpaceResults = &namespaceResults
			return fromCmd(cmd, args, opts)
		},
		Example: `buildah from --pull imagename
  buildah from docker-daemon:imagename:imagetag
  buildah from --name "myimagename" myregistry/myrepository/imagename:imagetag`,
	}
	fromCommand.SetUsageTemplate(UsageTemplate())

	flags := fromCommand.Flags()
	flags.SetInterspersed(false)
	flags.StringVar(&opts.authfile, "authfile", auth.GetDefaultAuthFile(), "path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override")
	flags.StringVar(&opts.certDir, "cert-dir", "", "use certificates at the specified path to access the registry")
	flags.StringVar(&opts.cidfile, "cidfile", "", "write the container ID to the file")
	flags.StringVar(&opts.creds, "creds", "", "use `[username[:password]]` for accessing the registry")
	flags.StringVarP(&opts.format, "format", "f", defaultFormat(), "`format` of the image manifest and metadata")
	flags.StringVar(&opts.name, "name", "", "`name` for the working container")
	flags.StringVar(&opts.pull, "pull", "true", "pull the image from the registry if newer or not present in store, if false, only pull the image if not present, if always, pull the image even if the named image is present in store, if never, only use the image present in store if available")
	flags.Lookup("pull").NoOptDefVal = "true" //allow `--pull ` to be set to `true` as expected.

	flags.BoolVar(&opts.pullAlways, "pull-always", false, "pull the image even if the named image is present in store")
	if err := flags.MarkHidden("pull-always"); err != nil {
		panic(fmt.Sprintf("error marking the pull-always flag as hidden: %v", err))
	}
	flags.BoolVar(&opts.pullNever, "pull-never", false, "do not pull the image, use the image present in store if available")
	if err := flags.MarkHidden("pull-never"); err != nil {
		panic(fmt.Sprintf("error marking the pull-never flag as hidden: %v", err))
	}
	flags.BoolVarP(&opts.quiet, "quiet", "q", false, "don't output progress information when pulling images")
	flags.StringVar(&opts.signaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
	flags.StringVar(&suffix, "suffix", "", "suffix to add to intermediate containers")
	if err := flags.MarkHidden("suffix"); err != nil {
		panic(fmt.Sprintf("error marking the suffix flag as hidden: %v", err))
	}

	if err := flags.MarkHidden("signature-policy"); err != nil {
		panic(fmt.Sprintf("error marking signature-policy as hidden: %v", err))
	}
	flags.BoolVar(&opts.tlsVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry. TLS verification cannot be used when talking to an insecure registry.")

	// Add in the common flags
	fromAndBudFlags, err := buildahcli.GetFromAndBudFlags(&fromAndBudResults, &userNSResults, &namespaceResults)
	if err != nil {
		logrus.Errorf("failed to setup From and Bud flags: %v", err)
		os.Exit(1)
	}
	flags.AddFlagSet(&fromAndBudFlags)
	flags.SetNormalizeFunc(buildahcli.AliasFlags)

	rootCmd.AddCommand(fromCommand)
}

func onBuild(builder *buildah.Builder, quiet bool) error {
	ctr := 0
	for _, onBuildSpec := range builder.OnBuild() {
		ctr = ctr + 1
		commands := strings.Split(onBuildSpec, " ")
		command := strings.ToUpper(commands[0])
		args := commands[1:]
		if !quiet {
			fmt.Fprintf(os.Stderr, "STEP %d: %s\n", ctr, onBuildSpec)
		}
		switch command {
		case "ADD":
		case "COPY":
			dest := ""
			size := len(args)
			if size > 1 {
				dest = args[size-1]
				args = args[:size-1]
			}
			if err := builder.Add(dest, command == "ADD", buildah.AddAndCopyOptions{}, args...); err != nil {
				return err
			}
		case "ANNOTATION":
			annotation := strings.SplitN(args[0], "=", 2)
			if len(annotation) > 1 {
				builder.SetAnnotation(annotation[0], annotation[1])
			} else {
				builder.UnsetAnnotation(annotation[0])
			}
		case "CMD":
			builder.SetCmd(args)
		case "ENV":
			env := strings.SplitN(args[0], "=", 2)
			if len(env) > 1 {
				builder.SetEnv(env[0], env[1])
			} else {
				builder.UnsetEnv(env[0])
			}
		case "ENTRYPOINT":
			builder.SetEntrypoint(args)
		case "EXPOSE":
			builder.SetPort(strings.Join(args, " "))
		case "HOSTNAME":
			builder.SetHostname(strings.Join(args, " "))
		case "LABEL":
			label := strings.SplitN(args[0], "=", 2)
			if len(label) > 1 {
				builder.SetLabel(label[0], label[1])
			} else {
				builder.UnsetLabel(label[0])
			}
		case "MAINTAINER":
			builder.SetMaintainer(strings.Join(args, " "))
		case "ONBUILD":
			builder.SetOnBuild(strings.Join(args, " "))
		case "RUN":
			var stdout io.Writer
			if quiet {
				stdout = ioutil.Discard
			}
			if err := builder.Run(args, buildah.RunOptions{Stdout: stdout}); err != nil {
				return err
			}
		case "SHELL":
			builder.SetShell(args)
		case "STOPSIGNAL":
			builder.SetStopSignal(strings.Join(args, " "))
		case "USER":
			builder.SetUser(strings.Join(args, " "))
		case "VOLUME":
			builder.AddVolume(strings.Join(args, " "))
		case "WORKINGDIR":
			builder.SetWorkDir(strings.Join(args, " "))
		default:
			logrus.Errorf("unknown OnBuild command %q; ignored", onBuildSpec)
		}
	}
	builder.ClearOnBuild()
	return nil
}

func fromCmd(c *cobra.Command, args []string, iopts fromReply) error {
	defaultContainerConfig, err := config.Default()
	if err != nil {
		return fmt.Errorf("failed to get container config: %w", err)
	}

	if len(args) == 0 {
		return errors.New("an image name (or \"scratch\") must be specified")
	}
	if err := buildahcli.VerifyFlagsArgsOrder(args); err != nil {
		return err
	}
	if len(args) > 1 {
		return errors.New("too many arguments specified")
	}

	if err := auth.CheckAuthFile(iopts.authfile); err != nil {
		return err
	}
	systemContext, err := parse.SystemContextFromOptions(c)
	if err != nil {
		return fmt.Errorf("error building system context: %w", err)
	}
	platforms, err := parse.PlatformsFromOptions(c)
	if err != nil {
		return err
	}
	if len(platforms) > 1 {
		logrus.Warnf("ignoring platforms other than %+v: %+v", platforms[0], platforms[1:])
	}

	pullFlagsCount := 0
	if c.Flag("pull").Changed {
		pullFlagsCount++
	}
	if c.Flag("pull-always").Changed {
		pullFlagsCount++
	}
	if c.Flag("pull-never").Changed {
		pullFlagsCount++
	}

	if pullFlagsCount > 1 {
		return errors.New("can only set one of 'pull' or 'pull-always' or 'pull-never'")
	}

	// Allow for --pull, --pull=true, --pull=false, --pull=never, --pull=always
	// --pull-always and --pull-never.  The --pull-never and --pull-always options
	// will not be documented.
	pullPolicy := define.PullIfMissing
	if strings.EqualFold(strings.TrimSpace(iopts.pull), "true") {
		pullPolicy = define.PullIfNewer
	}
	if iopts.pullAlways || strings.EqualFold(strings.TrimSpace(iopts.pull), "always") {
		pullPolicy = define.PullAlways
	}
	if iopts.pullNever || strings.EqualFold(strings.TrimSpace(iopts.pull), "never") {
		pullPolicy = define.PullNever
	}
	logrus.Debugf("Pull Policy for pull [%v]", pullPolicy)

	signaturePolicy := iopts.signaturePolicy

	store, err := getStore(c)
	if err != nil {
		return err
	}

	commonOpts, err := parse.CommonBuildOptions(c)
	if err != nil {
		return err
	}

	isolation, err := parse.IsolationOption(iopts.Isolation)
	if err != nil {
		return err
	}

	namespaceOptions, networkPolicy, err := parse.NamespaceOptions(c)
	if err != nil {
		return fmt.Errorf("error parsing namespace-related options: %w", err)
	}
	usernsOption, idmappingOptions, err := parse.IDMappingOptions(c, isolation)
	if err != nil {
		return fmt.Errorf("error parsing ID mapping options: %w", err)
	}
	namespaceOptions.AddOrReplace(usernsOption...)

	format, err := util.GetFormat(iopts.format)
	if err != nil {
		return err
	}
	devices := define.ContainerDevices{}
	for _, device := range append(defaultContainerConfig.Containers.Devices, iopts.Devices...) {
		dev, err := parse.DeviceFromPath(device)
		if err != nil {
			return err
		}
		devices = append(devices, dev...)
	}

	capabilities, err := defaultContainerConfig.Capabilities("", iopts.CapAdd, iopts.CapDrop)
	if err != nil {
		return err
	}

	commonOpts.Ulimit = append(defaultContainerConfig.Containers.DefaultUlimits, commonOpts.Ulimit...)

	decConfig, err := util.DecryptConfig(iopts.DecryptionKeys)
	if err != nil {
		return fmt.Errorf("unable to obtain decrypt config: %w", err)
	}

	options := buildah.BuilderOptions{
		FromImage:             args[0],
		Container:             iopts.name,
		ContainerSuffix:       suffix,
		PullPolicy:            pullPolicy,
		SignaturePolicyPath:   signaturePolicy,
		SystemContext:         systemContext,
		DefaultMountsFilePath: globalFlagResults.DefaultMountsFile,
		Isolation:             isolation,
		NamespaceOptions:      namespaceOptions,
		ConfigureNetwork:      networkPolicy,
		CNIPluginPath:         iopts.CNIPlugInPath,
		CNIConfigDir:          iopts.CNIConfigDir,
		IDMappingOptions:      idmappingOptions,
		Capabilities:          capabilities,
		CommonBuildOpts:       commonOpts,
		Format:                format,
		BlobDirectory:         iopts.BlobCache,
		Devices:               devices,
		MaxPullRetries:        buildahcli.MaxPullPushRetries,
		PullRetryDelay:        buildahcli.PullPushRetryDelay,
		OciDecryptConfig:      decConfig,
	}

	if !iopts.quiet {
		options.ReportWriter = os.Stderr
	}

	builder, err := buildah.NewBuilder(getContext(), store, options)
	if err != nil {
		return err
	}

	if err := onBuild(builder, iopts.quiet); err != nil {
		return err
	}

	if iopts.cidfile != "" {
		filePath := iopts.cidfile
		if err := ioutil.WriteFile(filePath, []byte(builder.ContainerID), 0644); err != nil {
			return fmt.Errorf("failed to write container ID file %q: %w", filePath, err)
		}
	}
	fmt.Printf("%s\n", builder.Container)
	return builder.Save()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"strconv"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/infrakit/pkg/discovery"
	metadata_plugin "github.com/docker/infrakit/pkg/plugin/metadata"
	"github.com/docker/infrakit/pkg/rpc/client"
	metadata_rpc "github.com/docker/infrakit/pkg/rpc/metadata"
	"github.com/docker/infrakit/pkg/spi/metadata"
	"github.com/spf13/cobra"
)

func getPlugin(plugins func() discovery.Plugins, name string) (found metadata.Plugin, err error) {
	err = forPlugin(plugins, func(n string, p metadata.Plugin) error {
		if n == name {
			found = p
		}
		return nil
	})
	return
}

func forPlugin(plugins func() discovery.Plugins, do func(string, metadata.Plugin) error) error {
	all, err := plugins().List()
	if err != nil {
		return err
	}
	for name, endpoint := range all {
		rpcClient, err := client.New(endpoint.Address, metadata.InterfaceSpec)
		if err != nil {
			continue
		}
		if err := do(name, metadata_rpc.Adapt(rpcClient)); err != nil {
			return err
		}
	}
	return nil
}

func listAll(m metadata.Plugin, path metadata.Path) ([]metadata.Path, error) {
	if m == nil {
		return nil, fmt.Errorf("no plugin")
	}
	result := []metadata.Path{}
	nodes, err := m.List(path)
	if err != nil {
		return nil, err
	}
	for _, n := range nodes {
		c := path.Join(n)
		more, err := listAll(m, c)
		if err != nil {
			return nil, err
		}
		if len(more) == 0 {
			result = append(result, c)
		}
		for _, pp := range more {
			result = append(result, pp)
		}
	}
	return result, nil
}

func metadataCommand(plugins func() discovery.Plugins) *cobra.Command {

	cmd := &cobra.Command{
		Use:   "metadata",
		Short: "Access metadata exposed by infrakit plugins",
	}

	ls := &cobra.Command{
		Use:   "ls",
		Short: "List all metadata entries",
	}

	long := ls.Flags().BoolP("long", "l", false, "Print full path")
	all := ls.Flags().BoolP("all", "a", false, "Find all under the paths given")

	ls.RunE = func(c *cobra.Command, args []string) error {
		paths := []string{"."}

		// All implies long
		if *all {
			*long = true
		}

		if len(args) > 0 {
			paths = args
		}

		for _, p := range paths {

			if p == "/" {
				// TODO(chungers) -- this is a 'local' infrakit ensemble.
				// Absolute paths will come in a multi-cluster / federated model.
				return fmt.Errorf("No absolute path")
			}

			path := metadata_plugin.Path(p)
			first := path.Index(0)

			targets := []string{} // target plugins to query

			// Check all the plugins -- scanning via discovery
			if err := forPlugin(plugins,
				func(name string, mp metadata.Plugin) error {
					if p == "." || (first != nil && name == *first) {
						targets = append(targets, name)
					}
					return nil
				}); err != nil {
				return err
			}

			for _, target := range targets {

				nodes := []metadata.Path{} // the result set to print

				match, err := getPlugin(plugins, target)
				if err != nil {
					return err
				}

				if p == "." {
					if *all {
						allPaths, err := listAll(match, path.Shift(1))
						if err != nil {
							log.Warningln("Cannot metadata ls on plugin", target, "err=", err)
						}
						for _, c := range allPaths {
							nodes = append(nodes, metadata_plugin.Path(target).Sub(c))
						}
					} else {
						for _, t := range targets {
							nodes = append(nodes, metadata_plugin.Path(t))
						}
					}
				} else {
					if *all {
						allPaths, err := listAll(match, path.Shift(1))
						if err != nil {
							log.Warningln("Cannot metadata ls on plugin", target, "err=", err)
						}
						for _, c := range allPaths {
							nodes = append(nodes, metadata_plugin.Path(target).Sub(c))
						}
					} else {
						children, err := match.List(path.Shift(1))
						if err != nil {
							log.Warningln("Cannot metadata ls on plugin", target, "err=", err)
						}
						for _, c := range children {
							nodes = append(nodes, path.Join(c))
						}
					}
				}

				if len(targets) > 1 {
					fmt.Printf("%s:\n", target)
				}
				if *long {
					fmt.Printf("total %d:\n", len(nodes))
				}
				for _, l := range nodes {
					if *long {
						fmt.Println(metadata_plugin.String(l))
					} else {
						fmt.Println(metadata_plugin.String(l.Rel(path)))
					}
				}
				fmt.Println()
			}

		}
		return nil
	}

	cat := &cobra.Command{
		Use:   "cat",
		Short: "Get metadata entry by path",
		RunE: func(c *cobra.Command, args []string) error {

			for _, p := range args {

				path := metadata_plugin.Path(p)
				first := path.Index(0)
				if first != nil {
					match, err := getPlugin(plugins, *first)
					if err != nil {
						return err
					}

					value, err := match.Get(path.Shift(1))
					if err == nil {
						if value != nil {
							str := value.String()
							if s, err := strconv.Unquote(value.String()); err == nil {
								str = s
							}
							fmt.Println(str)
						}

					} else {
						log.Warningln("Cannot metadata cat on plugin", *first, "err=", err)
					}
				}
			}
			return nil
		},
	}

	cmd.AddCommand(ls, cat)

	return cmd
}
<commit_msg>command line presentation fixes (#407)<commit_after>package main

import (
	"fmt"
	"strconv"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/infrakit/pkg/discovery"
	metadata_plugin "github.com/docker/infrakit/pkg/plugin/metadata"
	"github.com/docker/infrakit/pkg/rpc/client"
	metadata_rpc "github.com/docker/infrakit/pkg/rpc/metadata"
	"github.com/docker/infrakit/pkg/spi/metadata"
	"github.com/spf13/cobra"
)

func getPlugin(plugins func() discovery.Plugins, name string) (found metadata.Plugin, err error) {
	err = forPlugin(plugins, func(n string, p metadata.Plugin) error {
		if n == name {
			found = p
		}
		return nil
	})
	return
}

func forPlugin(plugins func() discovery.Plugins, do func(string, metadata.Plugin) error) error {
	all, err := plugins().List()
	if err != nil {
		return err
	}
	for name, endpoint := range all {
		rpcClient, err := client.New(endpoint.Address, metadata.InterfaceSpec)
		if err != nil {
			continue
		}
		if err := do(name, metadata_rpc.Adapt(rpcClient)); err != nil {
			return err
		}
	}
	return nil
}

func listAll(m metadata.Plugin, path metadata.Path) ([]metadata.Path, error) {
	if m == nil {
		return nil, fmt.Errorf("no plugin")
	}
	result := []metadata.Path{}
	nodes, err := m.List(path)
	if err != nil {
		return nil, err
	}
	for _, n := range nodes {
		c := path.Join(n)
		more, err := listAll(m, c)
		if err != nil {
			return nil, err
		}
		if len(more) == 0 {
			result = append(result, c)
		}
		for _, pp := range more {
			result = append(result, pp)
		}
	}
	return result, nil
}

func metadataCommand(plugins func() discovery.Plugins) *cobra.Command {

	cmd := &cobra.Command{
		Use:   "metadata",
		Short: "Access metadata exposed by infrakit plugins",
	}

	ls := &cobra.Command{
		Use:   "ls",
		Short: "List all metadata entries",
	}

	long := ls.Flags().BoolP("long", "l", false, "Print full path")
	all := ls.Flags().BoolP("all", "a", false, "Find all under the paths given")
	quick := ls.Flags().BoolP("quick", "q", false, "True to turn off headers, etc.")

	ls.RunE = func(c *cobra.Command, args []string) error {
		paths := []string{"."}

		// All implies long
		if *all {
			*long = true
		}

		if len(args) > 0 {
			paths = args
		}

		for i, p := range paths {

			if p == "/" {
				// TODO(chungers) -- this is a 'local' infrakit ensemble.
				// Absolute paths will come in a multi-cluster / federated model.
				return fmt.Errorf("No absolute path")
			}

			path := metadata_plugin.Path(p)
			first := path.Index(0)

			targets := []string{} // target plugins to query

			// Check all the plugins -- scanning via discovery
			if err := forPlugin(plugins,
				func(name string, mp metadata.Plugin) error {
					if p == "." || (first != nil && name == *first) {
						targets = append(targets, name)
					}
					return nil
				}); err != nil {
				return err
			}

			for j, target := range targets {

				nodes := []metadata.Path{} // the result set to print

				match, err := getPlugin(plugins, target)
				if err != nil {
					return err
				}

				if p == "." {
					if *all {
						allPaths, err := listAll(match, path.Shift(1))
						if err != nil {
							log.Warningln("Cannot metadata ls on plugin", target, "err=", err)
						}
						for _, c := range allPaths {
							nodes = append(nodes, metadata_plugin.Path(target).Sub(c))
						}
					} else {
						for _, t := range targets {
							nodes = append(nodes, metadata_plugin.Path(t))
						}
					}

				} else {
					if *all {
						allPaths, err := listAll(match, path.Shift(1))
						if err != nil {
							log.Warningln("Cannot metadata ls on plugin", target, "err=", err)
						}
						for _, c := range allPaths {
							nodes = append(nodes, metadata_plugin.Path(target).Sub(c))
						}
					} else {
						children, err := match.List(path.Shift(1))
						if err != nil {
							log.Warningln("Cannot metadata ls on plugin", target, "err=", err)
						}
						for _, c := range children {
							nodes = append(nodes, path.Join(c))
						}
					}
				}

				if p == "." && !*all {
					// special case of showing the top level plugin namespaces
					if i > 0 && !*quick {
						fmt.Println()
					}
					for _, l := range nodes {
						if *long {
							fmt.Println(metadata_plugin.String(l))
						} else {
							fmt.Println(metadata_plugin.String(l.Rel(path)))
						}
					}
					break
				}

				if len(targets) > 1 {
					if j > 0 && !*quick {
						fmt.Println()
					}
					fmt.Printf("%s:\n", target)
				}
				if *long && !*quick {
					fmt.Printf("total %d:\n", len(nodes))
				}
				for _, l := range nodes {
					if *long {
						fmt.Println(metadata_plugin.String(l))
					} else {
						fmt.Println(metadata_plugin.String(l.Rel(path)))
					}
				}
			}

		}
		return nil
	}

	cat := &cobra.Command{
		Use:   "cat",
		Short: "Get metadata entry by path",
		RunE: func(c *cobra.Command, args []string) error {

			for _, p := range args {

				path := metadata_plugin.Path(p)
				first := path.Index(0)
				if first != nil {
					match, err := getPlugin(plugins, *first)
					if err != nil {
						return err
					}

					value, err := match.Get(path.Shift(1))
					if err == nil {
						if value != nil {
							str := value.String()
							if s, err := strconv.Unquote(value.String()); err == nil {
								str = s
							}
							fmt.Println(str)
						}

					} else {
						log.Warningln("Cannot metadata cat on plugin", *first, "err=", err)
					}
				}
			}
			return nil
		},
	}

	cmd.AddCommand(ls, cat)

	return cmd
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/codegangsta/cli"
)

var Flags = []cli.Flag{
	flagInterval,
	flagHourly,
	flagDaily,
	flagOutput,
}

var flagInterval = cli.DurationFlag{
	Name:  "interval",
	Value: 0,
	Usage: "analyze data in this previous interval",
}

var flagHourly = cli.BoolFlag{
	Name:  "hourly",
	Usage: "analyze data for the previous hour",
}

var flagDaily = cli.BoolFlag{
	Name:  "daily",
	Usage: "analyze data for the previous day",
}

var flagOutput = cli.StringFlag{
	Name:  "output",
	Value: "csv",
	Usage: "specify the output format: csv or text",
}
<commit_msg>Move global flags to interval command flags<commit_after>package main

import (
	"github.com/codegangsta/cli"
)

var Flags = []cli.Flag{
	flagOutput,
}

var flagOutput = cli.StringFlag{
	Name:  "output",
	Value: "csv",
	Usage: "specify the output format: csv or text",
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"log"
	"net/http"
	"time"
)

func main() {
	log.Println("Flooding with metrics... =D")

	client := &http.Client{}
	for range time.Tick(time.Millisecond) {
		m := map[string]interface{}{
			"username": "kodingbot",
			"count":    1,
			"metric":   "kite_call",
		}
		json, _ := json.Marshal(m)

		contentReader := bytes.NewReader(json)

		req, _ := http.NewRequest("POST", "http://127.0.0.1:8080/metric", contentReader)
		req.Header.Set("Content-Type", "application/json")
		_, err = client.Do(req)
		if err != nil {
			log.Fatalln(err)
		}

	}
}
<commit_msg>add url flag to flooder<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"net/http"
	"time"
)

var (
	url = flag.String("url", "http://127.0.0.1:8080", "metric endpoint url")
)

func main() {
	log.Println("Flooding with metrics... =D")

	client := &http.Client{}
	dest := fmt.Sprintf("%s/metric", *url)

	m := map[string]interface{}{
		"username": "kodingbot",
		"count":    1,
		"metric":   "kite_call",
	}

	for range time.Tick(500 * time.Millisecond) {

		json, _ := json.Marshal(m)

		contentReader := bytes.NewReader(json)

		req, _ := http.NewRequest("POST", dest, contentReader)
		req.Header.Set("Content-Type", "application/json")
		_, err := client.Do(req)
		if err != nil {
			log.Fatalln(err)
		}

	}
}
<|endoftext|>