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

// Antimony (sb51) is a Syncbase general-purpose client and management utility.
// It currently supports experimenting with the Syncbase query language.
//
// The 'sh' command connects to a specified database on a Syncbase instance,
// creating it if it does not exist if -create-missing is specified.
// The user can then enter the following at the command line:
//     1. dump - to get a dump of the database
//     2. a syncbase select statement - which is executed and results printed to stdout
//     3. make-demo - to create demo tables in the database to experiment with, equivalent to -make-demo flag
//     4. exit (or quit) - to exit the program
//
// When the shell is running non-interactively (stdin not connected to a tty),
// errors cause the shell to exit with a non-zero status.
//
// To build client:
//     v23 go install v.io/syncbase/x/ref/syncbase/sb51
//
// To run client:
//     $V23_ROOT/roadmap/go/bin/sb51 sh <appname> <dbname>
//
// Sample run (assuming a syncbase service is mounted at '/:8101/syncbase',
// otherwise specify using -service flag):
//     > $V23_ROOT/roadmap/go/bin/sb51 sh -create-missing -make-demo -format=csv demoapp demodb
//     ? select v.Name, v.Address.State from DemoCustomers where t = "Customer";
//     v.Name,v.Address.State
//     John Smith,CA
//     Bat Masterson,IA
//     ? select v.CustId, v.InvoiceNum, v.ShipTo.Zip, v.Amount from DemoCustomers where t = "Invoice" and v.Amount > 100;
//     v.CustId,v.InvoiceNum,v.ShipTo.Zip,v.Amount
//     2,1001,50055,166
//     2,1002,50055,243
//     2,1004,50055,787
//     ? select k, v fro DemoCustomers;
//     Error:
//     select k, v fro DemoCustomers
//                 ^
//     13: Expected 'from', found fro.
//     ? select k, v from DemoCustomers;
//     k,v
//     001,"{Name: ""John Smith"", Id: 1, Active: true, Address: {Street: ""1 Main St."", City: ""Palo Alto"", State: ""CA"", Zip: ""94303""}, Credit: {Agency: Equifax, Report: EquifaxReport: {Rating: 65}}}"
//     001001,"{CustId: 1, InvoiceNum: 1000, Amount: 42, ShipTo: {Street: ""1 Main St."", City: ""Palo Alto"", State: ""CA"", Zip: ""94303""}}"
//     001002,"{CustId: 1, InvoiceNum: 1003, Amount: 7, ShipTo: {Street: ""2 Main St."", City: ""Palo Alto"", State: ""CA"", Zip: ""94303""}}"
//     001003,"{CustId: 1, InvoiceNum: 1005, Amount: 88, ShipTo: {Street: ""3 Main St."", City: ""Palo Alto"", State: ""CA"", Zip: ""94303""}}"
//     002,"{Name: ""Bat Masterson"", Id: 2, Active: true, Address: {Street: ""777 Any St."", City: ""Collins"", State: ""IA"", Zip: ""50055""}, Credit: {Agency: TransUnion, Report: TransUnionReport: {Rating: 80}}}"
//     002001,"{CustId: 2, InvoiceNum: 1001, Amount: 166, ShipTo: {Street: ""777 Any St."", City: ""Collins"", State: ""IA"", Zip: ""50055""}}"
//     002002,"{CustId: 2, InvoiceNum: 1002, Amount: 243, ShipTo: {Street: ""888 Any St."", City: ""Collins"", State: ""IA"", Zip: ""50055""}}"
//     002003,"{CustId: 2, InvoiceNum: 1004, Amount: 787, ShipTo: {Street: ""999 Any St."", City: ""Collins"", State: ""IA"", Zip: ""50055""}}"
//     002004,"{CustId: 2, InvoiceNum: 1006, Amount: 88, ShipTo: {Street: ""101010 Any St."", City: ""Collins"", State: ""IA"", Zip: ""50055""}}"
//     ? exit;
//     >
package main
<commit_msg>syncbase: syncQL: replace t with Type(), remove restrictions on k<commit_after>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Antimony (sb51) is a Syncbase general-purpose client and management utility.
// It currently supports experimenting with the Syncbase query language.
//
// The 'sh' command connects to a specified database on a Syncbase instance,
// creating it if it does not exist if -create-missing is specified.
// The user can then enter the following at the command line:
//     1. dump - to get a dump of the database
//     2. a syncbase select statement - which is executed and results printed to stdout
//     3. make-demo - to create demo tables in the database to experiment with, equivalent to -make-demo flag
//     4. exit (or quit) - to exit the program
//
// When the shell is running non-interactively (stdin not connected to a tty),
// errors cause the shell to exit with a non-zero status.
//
// To build client:
//     v23 go install v.io/syncbase/x/ref/syncbase/sb51
//
// To run client:
//     $V23_ROOT/roadmap/go/bin/sb51 sh <appname> <dbname>
//
// Sample run (assuming a syncbase service is mounted at '/:8101/syncbase',
// otherwise specify using -service flag):
//     > $V23_ROOT/roadmap/go/bin/sb51 sh -create-missing -make-demo -format=csv demoapp demodb
//     ? select v.Name, v.Address.State from DemoCustomers where Type(v) = "Customer";
//     v.Name,v.Address.State
//     John Smith,CA
//     Bat Masterson,IA
//     ? select v.CustId, v.InvoiceNum, v.ShipTo.Zip, v.Amount from DemoCustomers where Type(v) = "Invoice" and v.Amount > 100;
//     v.CustId,v.InvoiceNum,v.ShipTo.Zip,v.Amount
//     2,1001,50055,166
//     2,1002,50055,243
//     2,1004,50055,787
//     ? select k, v fro DemoCustomers;
//     Error:
//     select k, v fro DemoCustomers
//                 ^
//     13: Expected 'from', found fro.
//     ? select k, v from DemoCustomers;
//     k,v
//     001,"{Name: ""John Smith"", Id: 1, Active: true, Address: {Street: ""1 Main St."", City: ""Palo Alto"", State: ""CA"", Zip: ""94303""}, Credit: {Agency: Equifax, Report: EquifaxReport: {Rating: 65}}}"
//     001001,"{CustId: 1, InvoiceNum: 1000, Amount: 42, ShipTo: {Street: ""1 Main St."", City: ""Palo Alto"", State: ""CA"", Zip: ""94303""}}"
//     001002,"{CustId: 1, InvoiceNum: 1003, Amount: 7, ShipTo: {Street: ""2 Main St."", City: ""Palo Alto"", State: ""CA"", Zip: ""94303""}}"
//     001003,"{CustId: 1, InvoiceNum: 1005, Amount: 88, ShipTo: {Street: ""3 Main St."", City: ""Palo Alto"", State: ""CA"", Zip: ""94303""}}"
//     002,"{Name: ""Bat Masterson"", Id: 2, Active: true, Address: {Street: ""777 Any St."", City: ""Collins"", State: ""IA"", Zip: ""50055""}, Credit: {Agency: TransUnion, Report: TransUnionReport: {Rating: 80}}}"
//     002001,"{CustId: 2, InvoiceNum: 1001, Amount: 166, ShipTo: {Street: ""777 Any St."", City: ""Collins"", State: ""IA"", Zip: ""50055""}}"
//     002002,"{CustId: 2, InvoiceNum: 1002, Amount: 243, ShipTo: {Street: ""888 Any St."", City: ""Collins"", State: ""IA"", Zip: ""50055""}}"
//     002003,"{CustId: 2, InvoiceNum: 1004, Amount: 787, ShipTo: {Street: ""999 Any St."", City: ""Collins"", State: ""IA"", Zip: ""50055""}}"
//     002004,"{CustId: 2, InvoiceNum: 1006, Amount: 88, ShipTo: {Street: ""101010 Any St."", City: ""Collins"", State: ""IA"", Zip: ""50055""}}"
//     ? exit;
//     >
package main
<|endoftext|>


<commit_before>// Copyright 2015-2016, Cyrill @ Schumacher.fm and the CoreStore contributors
//
// 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 net

// Method* defines the available methods which this library supports
const (
	MethodHead    = `HEAD`
	MethodGet     = "GET"
	MethodPost    = "POST"
	MethodPut     = "PUT"
	MethodPatch   = "PATCH"
	MethodDelete  = "DELETE"
	MethodTrace   = "TRACE"
	MethodOptions = "OPTIONS"
)

// Courtesy: github.com/labstack/echo

// HTTP methods
const (
	CONNECT = "CONNECT"
	DELETE  = "DELETE"
	GET     = "GET"
	HEAD    = "HEAD"
	OPTIONS = "OPTIONS"
	PATCH   = "PATCH"
	POST    = "POST"
	PUT     = "PUT"
	TRACE   = "TRACE"
)

// Media types
const (
	ApplicationJSON                  = "application/json"
	ApplicationJSONCharsetUTF8       = ApplicationJSON + "; " + CharsetUTF8
	ApplicationJavaScript            = "application/javascript"
	ApplicationJavaScriptCharsetUTF8 = ApplicationJavaScript + "; " + CharsetUTF8
	ApplicationXML                   = "application/xml"
	ApplicationXMLCharsetUTF8        = ApplicationXML + "; " + CharsetUTF8
	ApplicationForm                  = "application/x-www-form-urlencoded"
	ApplicationProtobuf              = "application/protobuf"
	ApplicationMsgpack               = "application/msgpack"
	TextHTML                         = "text/html"
	TextHTMLCharsetUTF8              = TextHTML + "; " + CharsetUTF8
	TextPlain                        = "text/plain"
	TextPlainCharsetUTF8             = TextPlain + "; " + CharsetUTF8
	MultipartForm                    = "multipart/form-data"
	CompressGZIP                     = "gzip"
	CompressDeflate                  = "deflate"
)

// Charset
const (
	CharsetUTF8 = "charset=utf-8"
)

// Headers
const (
	AcceptEncoding     = "Accept-Encoding"
	Authorization      = "Authorization"
	ContentDisposition = "Content-Disposition"
	ContentEncoding    = "Content-Encoding"
	ContentLength      = "Content-Length"
	ContentType        = "Content-Type"
	Location           = "Location"
	Upgrade            = "Upgrade"
	Vary               = "Vary"
	WWWAuthenticate    = "WWW-Authenticate"
	XForwarded         = "X-Forwarded"
	XForwardedFor      = "X-Forwarded-For"
	XRealIP            = "X-Real-IP"
	ClientIP           = "Client-Ip"
	Forwarded          = "Forwarded"
	ForwardedFor       = "Forwarded-For"
	XClusterClientIP   = "X-Cluster-Client-Ip"
)

// Protocols
const (
	WebSocket = "websocket"
)
<commit_msg>net: Add ContentSignature constant<commit_after>// Copyright 2015-2016, Cyrill @ Schumacher.fm and the CoreStore contributors
//
// 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 net

// Method* defines the available methods which this library supports
const (
	MethodHead    = `HEAD`
	MethodGet     = "GET"
	MethodPost    = "POST"
	MethodPut     = "PUT"
	MethodPatch   = "PATCH"
	MethodDelete  = "DELETE"
	MethodTrace   = "TRACE"
	MethodOptions = "OPTIONS"
)

// Courtesy: github.com/labstack/echo

// HTTP methods
const (
	CONNECT = "CONNECT"
	DELETE  = "DELETE"
	GET     = "GET"
	HEAD    = "HEAD"
	OPTIONS = "OPTIONS"
	PATCH   = "PATCH"
	POST    = "POST"
	PUT     = "PUT"
	TRACE   = "TRACE"
)

// Media types
const (
	ApplicationJSON                  = "application/json"
	ApplicationJSONCharsetUTF8       = ApplicationJSON + "; " + CharsetUTF8
	ApplicationJavaScript            = "application/javascript"
	ApplicationJavaScriptCharsetUTF8 = ApplicationJavaScript + "; " + CharsetUTF8
	ApplicationXML                   = "application/xml"
	ApplicationXMLCharsetUTF8        = ApplicationXML + "; " + CharsetUTF8
	ApplicationForm                  = "application/x-www-form-urlencoded"
	ApplicationProtobuf              = "application/protobuf"
	ApplicationMsgpack               = "application/msgpack"
	TextHTML                         = "text/html"
	TextHTMLCharsetUTF8              = TextHTML + "; " + CharsetUTF8
	TextPlain                        = "text/plain"
	TextPlainCharsetUTF8             = TextPlain + "; " + CharsetUTF8
	MultipartForm                    = "multipart/form-data"
	CompressGZIP                     = "gzip"
	CompressDeflate                  = "deflate"
)

// Charset
const (
	CharsetUTF8 = "charset=utf-8"
)

// Headers
const (
	AcceptEncoding     = "Accept-Encoding"
	Authorization      = "Authorization"
	ContentDisposition = "Content-Disposition"
	ContentEncoding    = "Content-Encoding"
	ContentLength      = "Content-Length"
	ContentType        = "Content-Type"

	// Content-Signature: keyId="rsa-key-1",algorithm="rsa-sha256",signature="Base64(RSA-SHA256(signing string))"
	// Content-Signature: keyId="hmac-key-1",algorithm="hmac-sha1",signature="Base64(HMAC-SHA1(signing string))"
	ContentSignature = "Content-Signature"

	Location         = "Location"
	Upgrade          = "Upgrade"
	Vary             = "Vary"
	WWWAuthenticate  = "WWW-Authenticate"
	XForwarded       = "X-Forwarded"
	XForwardedFor    = "X-Forwarded-For"
	XRealIP          = "X-Real-Ip"
	ClientIP         = "Client-Ip"
	Forwarded        = "Forwarded"
	ForwardedFor     = "Forwarded-For"
	XClusterClientIP = "X-Cluster-Client-Ip"
)

// Protocols
const (
	WebSocket = "websocket"
)
<|endoftext|>


<commit_before>package network

import (
	"fmt"
	"os"
	"syscall"

	"github.com/dotcloud/docker/pkg/libcontainer"
	"github.com/dotcloud/docker/pkg/system"
)

//  crosbymichael: could make a network strategy that instead of returning veth pair names it returns a pid to an existing network namespace
type NetNS struct {
}

func (v *NetNS) Create(n *libcontainer.Network, nspid int, context libcontainer.Context) error {
	nsname, exists := n.Context["nsname"]

	if !exists {
		return fmt.Errorf("nspath does not exist in network context")
	}

	context["nspath"] = fmt.Sprintf("/var/run/netns/%s", nsname)
	return nil
}

func (v *NetNS) Initialize(config *libcontainer.Network, context libcontainer.Context) error {
	nspath, exists := context["nspath"]
	if !exists {
		return fmt.Errorf("nspath does not exist in network context")
	}

	f, err := os.OpenFile(nspath, os.O_RDONLY, 0)
	if err != nil {
		return fmt.Errorf("failed get network namespace fd: %v", err)
	}

	if err := system.Setns(f.Fd(), syscall.CLONE_NEWNET); err != nil {
		return fmt.Errorf("failed to setns current network namespace: %v", err)
	}
	return nil
}
<commit_msg>Allow containers to join the net namespace of other conatiners Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)<commit_after>package network

import (
	"fmt"
	"os"
	"syscall"

	"github.com/dotcloud/docker/pkg/libcontainer"
	"github.com/dotcloud/docker/pkg/system"
)

//  crosbymichael: could make a network strategy that instead of returning veth pair names it returns a pid to an existing network namespace
type NetNS struct {
}

func (v *NetNS) Create(n *libcontainer.Network, nspid int, context libcontainer.Context) error {
	context["nspath"] = n.Context["nspath"]
	return nil
}

func (v *NetNS) Initialize(config *libcontainer.Network, context libcontainer.Context) error {
	nspath, exists := context["nspath"]
	if !exists {
		return fmt.Errorf("nspath does not exist in network context")
	}
	f, err := os.OpenFile(nspath, os.O_RDONLY, 0)
	if err != nil {
		return fmt.Errorf("failed get network namespace fd: %v", err)
	}
	if err := system.Setns(f.Fd(), syscall.CLONE_NEWNET); err != nil {
		return fmt.Errorf("failed to setns current network namespace: %v", err)
	}
	return nil
}
<|endoftext|>


<commit_before>package cyder

import (
	"bytes"
	"fmt"
	"net/http"
	"testing"
)

type MockResponseWriter struct {
	StatusCode int
	Buffer     *bytes.Buffer
	header     http.Header
}

func NewMockResponseWriter() *MockResponseWriter {
	return &MockResponseWriter{Buffer: new(bytes.Buffer), header: make(http.Header)}
}

func (w *MockResponseWriter) Header() http.Header {
	return w.header
}

func (w *MockResponseWriter) WriteHeader(c int) {
	w.StatusCode = c
}

func (w *MockResponseWriter) Write(b []byte) (int, error) {
	if w.StatusCode == 0 {
		w.StatusCode = http.StatusOK
	}
	return w.Buffer.Write(b)
}

type Foo struct {
	Controller
}

func (f *Foo) Page() {
	fmt.Fprintf(f, "called page")
}

func (f *Foo) Add(a, b int) {
	fmt.Fprintf(f, "-%d-", a+b)
}

func (f *Foo) Bla(a string, b uint32, x float64) {
	fmt.Fprintf(f, "-%s|%d-%.1f-", a, b, x)
}

func (f *Foo) Deliver403() {
	f.WriteHeader(403)
	fmt.Fprintf(f, "delivered 403")
}

var httphandler_test = []struct {
	url string
	respcode int
	output string
}{
	{ "/page", http.StatusOK, "called page" },
	{ "/add/23/42", http.StatusOK, "-65-" },
	{ "/bla/foobar/129374/3.5", http.StatusOK, "-foobar|129374-3.5-" },
	{ "/deliver403", http.StatusForbidden, "delivered 403" },
}

func TestHTTPHandler(t *testing.T) {
	resp := NewMockResponseWriter()
	foo := &Foo{}
	foo.setResponseWriter(resp)
	handler, err := newHTTPHandler(func() interface{} { return foo }, "/", "")
	if err != nil {
		t.Fatal(err)
	}

	for _, test := range httphandler_test {
		resp.Buffer.Reset()
		req, _ := http.NewRequest("GET", "http://localhost:80" + test.url, nil)
		handler.ServeHTTP(resp, req)
		if resp.StatusCode != test.respcode {
			t.Errorf("%s didn't deliver correct %d code; %d instead", test.url, test.respcode, resp.StatusCode)
		}
		if resp.Buffer.String() != test.output {
			t.Errorf("%s didn't return correct content '%s'; '%s' instead", test.url, test.output, resp.Buffer.String())
		}
	}

}
<commit_msg>add benchmark to measure performance of HTTP handler.<commit_after>package cyder

import (
	"bytes"
	"fmt"
	"net/http"
	"testing"
)

type MockResponseWriter struct {
	StatusCode int
	Buffer     *bytes.Buffer
	header     http.Header
}

func NewMockResponseWriter() *MockResponseWriter {
	return &MockResponseWriter{Buffer: new(bytes.Buffer), header: make(http.Header)}
}

func (w *MockResponseWriter) Header() http.Header {
	return w.header
}

func (w *MockResponseWriter) WriteHeader(c int) {
	w.StatusCode = c
}

func (w *MockResponseWriter) Write(b []byte) (int, error) {
	if w.StatusCode == 0 {
		w.StatusCode = http.StatusOK
	}
	return w.Buffer.Write(b)
}

type Foo struct {
	Controller
}

func (f *Foo) Page() {
	fmt.Fprintf(f, "called page")
}

func (f *Foo) Add(a, b int) {
	fmt.Fprintf(f, "-%d-", a+b)
}

func (f *Foo) Bla(a string, b uint32, x float64) {
	fmt.Fprintf(f, "-%s|%d-%.1f-", a, b, x)
}

func (f *Foo) Deliver403() {
	f.WriteHeader(403)
	fmt.Fprintf(f, "delivered 403")
}

var httphandler_test = []struct {
	url      string
	respcode int
	output   string
}{
	{"/page", http.StatusOK, "called page"},
	{"/add/23/42", http.StatusOK, "-65-"},
	{"/bla/foobar/129374/3.5", http.StatusOK, "-foobar|129374-3.5-"},
	{"/deliver403", http.StatusForbidden, "delivered 403"},
}

func TestHTTPHandler(t *testing.T) {
	resp := NewMockResponseWriter()
	foo := &Foo{}
	foo.setResponseWriter(resp)
	handler, err := newHTTPHandler(func() interface{} { return foo }, "/", "")
	if err != nil {
		t.Fatal(err)
	}

	for _, test := range httphandler_test {
		resp.Buffer.Reset()
		req, _ := http.NewRequest("GET", "http://localhost:80"+test.url, nil)
		handler.ServeHTTP(resp, req)
		if resp.StatusCode != test.respcode {
			t.Errorf("%s didn't deliver correct %d code; %d instead", test.url, test.respcode, resp.StatusCode)
		}
		if resp.Buffer.String() != test.output {
			t.Errorf("%s didn't return correct content '%s'; '%s' instead", test.url, test.output, resp.Buffer.String())
		}
	}

}

func BenchmarkHTTPHandler(b *testing.B) {
	b.StopTimer()

	resp := NewMockResponseWriter()
	foo := &Foo{}
	foo.setResponseWriter(resp)
	handler, _ := newHTTPHandler(func() interface{} { return foo }, "/", "")

	b.StartTimer()

	for i := 0; i < b.N; i++ {
		b.StopTimer()
		resp.Buffer.Reset()
		req, _ := http.NewRequest("GET", "http://localhost:80/bla/foobar/1234/0.1", nil)
		b.StartTimer()
		handler.ServeHTTP(resp, req)
	}
}
<|endoftext|>


<commit_before>package data

import (
	"crypto/rand"
	"fmt"
	"math"
)

type Block struct {
	/*
	   magic - 6
	   block_len - 2
	   num_links - 2
	   offset - 4
	   content_len - 4
	   links - num_links * 768
	   content - content_len
	   padding
	*/
	magic       [6]byte
	block_len   int8
	num_links   int8
	offset      int32
	content_len int32
	links       []Link
	content     []byte
	padding     []byte
}

func NewBlock() *Block {
	return &Block{}
}

func (blk *Block) Create(block_size int, links []Link, content []byte) {

	blk.magic = [6]byte{0xF0, 0x07, 0xDA, 0x7A, '\r', '\n'}
	blk.block_len = int8(math.Log2(float64(block_size)))
	blk.num_links = int8(len(links))
	blk.offset = int32(blk.num_links)*96 + 16
	blk.content_len = int32(len(content))

	blk.links = links
	blk.content = content

	padding_len := block_size - 16 - int(blk.content_len) - (int(blk.num_links) * 96)

	padding := make([]byte, padding_len)
	_, err := rand.Read(padding)

	if err != nil {
		fmt.Println(err)
	}

}
<commit_msg>Adds accessors for testing.<commit_after>package data

import (
	"crypto/rand"
	"fmt"
	"math"
)

type Block struct {
	/*
	   magic - 6
	   block_len - 2
	   num_links - 2
	   offset - 4
	   content_len - 4
	   links - num_links * 768
	   content - content_len
	   padding
	*/
	magic       [6]byte
	block_len   int8
	num_links   int8
	offset      int32
	content_len int32
	links       []Link
	content     []byte
	padding     []byte
}

func NewBlock() *Block {
	return &Block{}
}

func (blk *Block) Create(block_size int, links []Link, content []byte) {

	blk.magic = [6]byte{0xF0, 0x07, 0xDA, 0x7A, '\r', '\n'}
	blk.block_len = int8(math.Log2(float64(block_size)))
	blk.num_links = int8(len(links))
	blk.offset = int32(blk.num_links)*96 + 16
	blk.content_len = int32(len(content))

	blk.links = links
	blk.content = content

	padding_len := block_size - 16 - int(blk.content_len) - (int(blk.num_links) * 96)

	padding := make([]byte, padding_len)
	_, err := rand.Read(padding)

	if err != nil {
		fmt.Println(err)
	}
}

func (blk *Block) ContentSize() int32 {
	return blk.content_len
}

func (blk *Block) Offset() int32 {
	return blk.offset
}

func (blk *Block) NumLinks() int8 {
	return blk.num_links
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/fsouza/go-dockerclient"
)

func main() {
	var endpoint, appname, directory string
	flag.StringVar(&endpoint, "endpoint", "unix:///var/run/docker.sock", "docker daemon endpoint")
	flag.StringVar(&appname, "appname", "tbd_app_tmp", "container name for build")
	flag.StringVar(&directory, "directory", ".", "context directory for docker build")

	flag.Parse()

	client, err := docker.NewClient(endpoint)
	if err != nil {
		fmt.Println(err)
	}

	var builder docker.BuildImageOptions

	builder.Name = appname
	builder.RmTmpContainer = true
	builder.ContextDir = directory
	builder.OutputStream = os.Stderr

	err = client.BuildImage(builder)
	if err != nil {
		fmt.Println(err)
	}
}
<commit_msg>removed old tbd-build command<commit_after><|endoftext|>


<commit_before>package teamweek

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
)

const (
	libraryVersion = "0.1"
	userAgent      = "go-teamweek/" + libraryVersion
	defaultBaseURL = "https://new.teamweek.com/api/v3/"
)

type (
	Client struct {
		client    *http.Client
		BaseURL   *url.URL
		UserAgent string
	}

	Account struct {
		ID          int64   `json:"id,omitempty"`
		Name        string  `json:"name,omitempty"`
		IsDemo      bool    `json:"is_demo,omitempty"`
		SuspendedAt string  `json:"suspended_at,omitempty"`
		Groups      []Group `json:"groups,omitempty"`
	}

	Profile struct {
		ID          int64         `json:"id,omitempty"`
		Email       string        `json:"email,omitempty"`
		Name        string        `json:"name,omitempty"`
		Initials    string        `json:"initials,omitempty"`
		PictureUrl  string        `json:"picture_url,omitempty"`
		HasPicture  bool          `json:"has_picture,omitempty"`
		Color       string        `json:"color,omitempty"`
		Accounts    []Account     `json:"accounts,omitempty"`
		Invitations []interface{} `json:"invitations,omitempty"`
		CreatedAt   string        `json:"created_at,omitempty"`
		UpdatedAt   string        `json:"updated_at,omitempty"`
	}

	User struct {
		ID         int64  `json:"id,omitempty"`
		Email      string `json:"email,omitempty"`
		Name       string `json:"name,omitempty"`
		Initials   string `json:"initials,omitempty"`
		PictureUrl string `json:"picture_url,omitempty"`
		HasPicture bool   `json:"has_picture,omitempty"`
		Color      string `json:"color,omitempty"`
		Weight     int64  `json:"weight,omitempty"`
		Dummy      bool   `json:"dummy,omitempty"`
	}

	Project struct {
		ID    int64  `json:"id,omitempty"`
		Name  string `json:"name,omitempty"`
		Color string `json:"color,omitempty"`
	}

	Task struct {
		ID             int64    `json:"id,omitempty"`
		Name           string   `json:"name,omitempty"`
		StartDate      string   `json:"start_date,omitempty"`
		EndDate        string   `json:"end_date,omitempty"`
		StartTime      string   `json:"start_time,omitempty"`
		EndTime        string   `json:"end_time,omitempty"`
		Color          string   `json:"color,omitempty"`
		EstimatedHours float64  `json:"estimated_hours,omitempty"`
		Pinned         bool     `json:"pinned,omitempty"`
		Done           bool     `json:"done,omitempty"`
		UserID         int64    `json:"user_id,omitempty"`
		Project        *Project `json:"project,omitempty"`
	}

	Milestone struct {
		ID      int64  `json:"id,omitempty"`
		Name    string `json:"name,omitempty"`
		Date    string `json:"date,omitempty"`
		Done    bool   `json:"done,omitempty"`
		Holiday bool   `json:"holiday,omitempty"`
	}

	Group struct {
		ID         int64        `json:"id,omitempty"`
		Name       string       `json:"name,omitempty"`
		AccountID  int64        `json:"account_id,omitempty"`
		Membership []Membership `json:"memberships,omitempty"`
	}

	Membership struct {
		ID      int64 `json:"id,omitempty"`
		GroupID int64 `json:"group_id,omitempty"`
		UserID  int64 `json:"user_id,omitempty"`
		Weight  int64 `json:"weight,omitempty"`
	}
)

func (c *Client) Profile() (*Profile, error) {
	profile := new(Profile)
	err := c.Request("me.json", profile)
	return profile, err
}

func (c *Client) ListAccounts() ([]Account, error) {
	accounts := new([]Account)
	err := c.Request("me/accounts.json", accounts)
	return *accounts, err
}

func (c *Client) ListAccountUsers(accountID int64) ([]User, error) {
	users := new([]User)
	err := c.Request(fmt.Sprintf("%d/users.json", accountID), users)
	return *users, err
}

func (c *Client) ListAccountProjects(accountID int64) ([]Project, error) {
	projects := new([]Project)
	err := c.Request(fmt.Sprintf("%d/projects.json", accountID), projects)
	return *projects, err
}

func (c *Client) ListAccountMilestones(accountID int64) ([]Milestone, error) {
	milestones := new([]Milestone)
	err := c.Request(fmt.Sprintf("%d/milestones.json", accountID), milestones)
	return *milestones, err
}

func (c *Client) ListAccountGroups(accountID int64) ([]Group, error) {
	groups := new([]Group)
	err := c.Request(fmt.Sprintf("%d/groups.json", accountID), groups)
	return *groups, err
}

func (c *Client) ListAccountTasks(accountID int64) ([]Task, error) {
	tasks := new([]Task)
	err := c.Request(fmt.Sprintf("%d/tasks.json", accountID), tasks)
	return *tasks, err
}

func NewClient(httpClient *http.Client) *Client {
	if httpClient == nil {
		httpClient = http.DefaultClient
	}
	baseURL, _ := url.Parse(defaultBaseURL)
	client := &Client{client: httpClient, BaseURL: baseURL, UserAgent: userAgent}
	return client
}

func (c *Client) Request(urlStr string, v interface{}) error {
	rel, err := url.Parse(urlStr)
	if err != nil {
		return err
	}
	u := c.BaseURL.ResolveReference(rel)
	req, err := http.NewRequest("GET", u.String(), nil)
	if err != nil {
		return err
	}
	req.Header.Add("User-Agent", c.UserAgent)
	resp, err := c.client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	return json.NewDecoder(resp.Body).Decode(v)
}
<commit_msg>user fields and http status handlings improved<commit_after>package teamweek

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"
)

const (
	libraryVersion = "0.2"
	userAgent      = "go-teamweek/" + libraryVersion
	defaultBaseURL = "https://new.teamweek.com/api/v3/"
)

type (
	Client struct {
		client    *http.Client
		BaseURL   *url.URL
		UserAgent string
	}

	Account struct {
		ID          int64   `json:"id,omitempty"`
		Name        string  `json:"name,omitempty"`
		IsDemo      bool    `json:"is_demo,omitempty"`
		SuspendedAt string  `json:"suspended_at,omitempty"`
		Groups      []Group `json:"groups,omitempty"`
	}

	userFields struct {
		ID         int64  `json:"id,omitempty"`
		Email      string `json:"email,omitempty"`
		Name       string `json:"name,omitempty"`
		Initials   string `json:"initials,omitempty"`
		PictureUrl string `json:"picture_url,omitempty"`
		HasPicture bool   `json:"has_picture,omitempty"`
		Color      string `json:"color,omitempty"`
	}

	Profile struct {
		userFields
		Accounts    []Account     `json:"accounts,omitempty"`
		Invitations []interface{} `json:"invitations,omitempty"`
		CreatedAt   string        `json:"created_at,omitempty"`
		UpdatedAt   string        `json:"updated_at,omitempty"`
	}

	User struct {
		userFields
		Weight int64 `json:"weight,omitempty"`
		Dummy  bool  `json:"dummy,omitempty"`
	}

	Project struct {
		ID    int64  `json:"id,omitempty"`
		Name  string `json:"name,omitempty"`
		Color string `json:"color,omitempty"`
	}

	Task struct {
		ID             int64    `json:"id,omitempty"`
		Name           string   `json:"name,omitempty"`
		StartDate      string   `json:"start_date,omitempty"`
		EndDate        string   `json:"end_date,omitempty"`
		StartTime      string   `json:"start_time,omitempty"`
		EndTime        string   `json:"end_time,omitempty"`
		Color          string   `json:"color,omitempty"`
		EstimatedHours float64  `json:"estimated_hours,omitempty"`
		Pinned         bool     `json:"pinned,omitempty"`
		Done           bool     `json:"done,omitempty"`
		UserID         int64    `json:"user_id,omitempty"`
		Project        *Project `json:"project,omitempty"`
	}

	Milestone struct {
		ID      int64  `json:"id,omitempty"`
		Name    string `json:"name,omitempty"`
		Date    string `json:"date,omitempty"`
		Done    bool   `json:"done,omitempty"`
		Holiday bool   `json:"holiday,omitempty"`
	}

	Group struct {
		ID         int64        `json:"id,omitempty"`
		Name       string       `json:"name,omitempty"`
		AccountID  int64        `json:"account_id,omitempty"`
		Membership []Membership `json:"memberships,omitempty"`
	}

	Membership struct {
		ID      int64 `json:"id,omitempty"`
		GroupID int64 `json:"group_id,omitempty"`
		UserID  int64 `json:"user_id,omitempty"`
		Weight  int64 `json:"weight,omitempty"`
	}
)

func (c *Client) Profile() (*Profile, error) {
	profile := new(Profile)
	err := c.Request("me.json", profile)
	return profile, err
}

func (c *Client) ListAccounts() ([]Account, error) {
	accounts := new([]Account)
	err := c.Request("me/accounts.json", accounts)
	return *accounts, err
}

func (c *Client) ListAccountUsers(accountID int64) ([]User, error) {
	users := new([]User)
	err := c.Request(fmt.Sprintf("%d/users.json", accountID), users)
	return *users, err
}

func (c *Client) ListAccountProjects(accountID int64) ([]Project, error) {
	projects := new([]Project)
	err := c.Request(fmt.Sprintf("%d/projects.json", accountID), projects)
	return *projects, err
}

func (c *Client) ListAccountMilestones(accountID int64) ([]Milestone, error) {
	milestones := new([]Milestone)
	err := c.Request(fmt.Sprintf("%d/milestones.json", accountID), milestones)
	return *milestones, err
}

func (c *Client) ListAccountGroups(accountID int64) ([]Group, error) {
	groups := new([]Group)
	err := c.Request(fmt.Sprintf("%d/groups.json", accountID), groups)
	return *groups, err
}

func (c *Client) ListAccountTasks(accountID int64) ([]Task, error) {
	tasks := new([]Task)
	err := c.Request(fmt.Sprintf("%d/tasks.json", accountID), tasks)
	return *tasks, err
}

func NewClient(httpClient *http.Client) *Client {
	if httpClient == nil {
		httpClient = http.DefaultClient
	}
	baseURL, _ := url.Parse(defaultBaseURL)
	client := &Client{client: httpClient, BaseURL: baseURL, UserAgent: userAgent}
	return client
}

func handleResponseStatuses(resp *http.Response) error {
	if resp.StatusCode >= 500 {
		return errors.New("Teamweek API experienced an internal error. Please try again later.")
	}
	if resp.StatusCode == 400 {
		return errors.New("Malformed request sent.")
	}
	if resp.StatusCode == 401 || resp.StatusCode == 403 {
		return errors.New("Authorization error. Please check credentials and/or reauthenticate.")
	}
	if (resp.StatusCode > 200 && resp.StatusCode < 300) || resp.StatusCode > 403 {
		return fmt.Errorf("Teamweek API returned an unexpected status code: %d", resp.StatusCode)
	}

	return nil
}

func (c *Client) Request(urlStr string, v interface{}) error {
	rel, err := url.Parse(urlStr)
	if err != nil {
		return err
	}
	u := c.BaseURL.ResolveReference(rel)
	req, err := http.NewRequest("GET", u.String(), nil)
	if err != nil {
		return err
	}
	req.Header.Add("User-Agent", c.UserAgent)
	resp, err := c.client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if err := handleResponseStatuses(resp); err != nil {
		return err
	}

	return json.NewDecoder(resp.Body).Decode(v)
}
<|endoftext|>


<commit_before>package template

import (
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"log"
)

type Template struct {
	Context  string
	Skeleton []map[string]interface{}
}

func New(filepath string) *Template {
	t := Template{}
	data, err := ioutil.ReadFile(filepath)

	if err != nil {
		log.Fatal(err)
	}

	if err = yaml.Unmarshal(data, &t); err != nil {
		log.Fatal(err)
		return &Template{}
	}

	return &t
}
<commit_msg>Changed Template responsibility<commit_after>package template

import (
	"io"
	"io/ioutil"
	"os"
	"text/template"
)

type Template struct {
	name string
	path string
	vars map[string]interface{}
}

func New(name, template_path string) *Template {
	return &Template{
		name: name,
		path: template_path,
	}
}

func (t *Template) Create(w io.Writer, vars map[string]string) (*Template, error) {
	if _, err := os.Stat(t.path); err == nil {
		tmpl_content, err := ioutil.ReadFile(t.path)
		if err != nil {
			return t, err
		}

		tmpl, err := template.New(t.name).Option("missingkey=error").Parse(string(tmpl_content))
		if err != nil {
			return t, err
		}

		err = tmpl.Execute(w, vars)
		if err != nil {
			return t, err
		}
	}

	return t, nil
}
<|endoftext|>


<commit_before>// Utiltities for formatting Ripple data in a terminal
package terminal

import (
	"fmt"
	"github.com/donovanhide/ripple/data"
	"github.com/donovanhide/ripple/websockets"
	"github.com/fatih/color"
	"reflect"
)

type Flag uint32

const (
	Indent Flag = 1 << iota
	DoubleIndent
	TripleIndent

	ShowLedgerSequence
	ShowTransactionId
)

var Default Flag

var (
	ledgerStyle     = color.New(color.FgRed, color.Underline)
	leStyle         = color.New(color.FgWhite)
	txStyle         = color.New(color.FgGreen)
	proposalStyle   = color.New(color.FgYellow)
	validationStyle = color.New(color.FgYellow, color.Bold)
	tradeStyle      = color.New(color.FgBlue)
	balanceStyle    = color.New(color.FgMagenta)
	pathStyle       = color.New(color.FgYellow)
	infoStyle       = color.New(color.FgRed)
)

type bundle struct {
	color  *color.Color
	format string
	values []interface{}
	flag   Flag
}

func newLeBundle(v interface{}, flag Flag) (*bundle, error) {
	var (
		format = "%-11s "
		values = []interface{}{v.(data.LedgerEntry).GetLedgerEntryType()}
	)
	switch le := v.(type) {
	case *data.AccountRoot:
		format += "%-34s %08X %s"
		values = append(values, []interface{}{le.Account, *le.Flags, le.Balance}...)
	case *data.LedgerHashes:
		format += "%d hashes"
		values = append(values, []interface{}{len(le.Hashes)}...)
	case *data.RippleState:
		format += "%s %s %s"
		values = append(values, []interface{}{le.Balance, le.HighLimit, le.LowLimit}...)
	case *data.Offer:
		format += "%-34s %-60s %-60s %-18s"
		values = append(values, []interface{}{le.Account, le.TakerPays, le.TakerGets, le.Ratio()}...)
	case *data.FeeSettings:
		format += "%d %d %d %d"
		values = append(values, []interface{}{le.BaseFee, le.ReferenceFeeUnits, le.ReserveBase, le.ReserveIncrement}...)
	case *data.Amendments:
		format += "%s"
		values = append(values, []interface{}{le.Amendments}...)
	default:
		return nil, fmt.Errorf("Unknown Ledger Entry Type")
	}
	return &bundle{
		color:  leStyle,
		format: format,
		values: values,
		flag:   flag,
	}, nil
}

func newTxBundle(v data.Transaction, insert string, flag Flag) (*bundle, error) {
	var (
		base   = v.GetBase()
		format = "%s %-11s %-8s %s%s %-34s "
		values = []interface{}{data.CheckSymbol(v), base.GetType(), base.Fee, insert, base.MemoSymbol(), base.Account}
	)
	if flag&ShowTransactionId > 0 {
		format = "%s " + format
		values = append([]interface{}{data.TransactionId(v)}, values...)
	}
	switch tx := v.(type) {
	case *data.Payment:
		format += "=> %-34s %-60s %-60s"
		values = append(values, []interface{}{tx.Destination, tx.Amount, tx.SendMax}...)
	case *data.OfferCreate:
		format += "%-60s %-60s %-18s"
		values = append(values, []interface{}{tx.TakerPays, tx.TakerGets, tx.Ratio()}...)
	case *data.OfferCancel:
		format += "%-9d"
		values = append(values, tx.Sequence)
	case *data.AccountSet:
		format += "%-9d"
		values = append(values, tx.Sequence)
	case *data.TrustSet:
		format += "%-60s %d %d"
		values = append(values, tx.LimitAmount, tx.QualityIn, tx.QualityOut)
	}
	return &bundle{
		color:  txStyle,
		format: format,
		values: values,
		flag:   flag,
	}, nil
}

func newTxmBundle(txm *data.TransactionWithMetaData, flag Flag) (*bundle, error) {
	insert := fmt.Sprintf("%s ", txm.MetaData.TransactionResult.Symbol())
	if flag&ShowLedgerSequence > 0 {
		insert = fmt.Sprintf("%-9d %s", txm.LedgerSequence, insert)
	}
	b, err := newTxBundle(txm.Transaction, insert, flag)
	if err != nil {
		return nil, err
	}
	if !txm.MetaData.TransactionResult.Success() {
		b.color = infoStyle
	}
	return b, nil
}

func newBundle(value interface{}, flag Flag) (*bundle, error) {
	switch v := value.(type) {
	case *data.TransactionWithMetaData:
		return newTxmBundle(v, flag)
	case data.Transaction:
		return newTxBundle(v, "", flag)
	case data.LedgerEntry:
		return newLeBundle(v, flag)
	}
	switch v := reflect.Indirect(reflect.ValueOf(value)).Interface().(type) {
	case websockets.LedgerStreamMsg:
		return &bundle{
			color:  ledgerStyle,
			format: "Ledger %d closed at %s with %d transactions",
			values: []interface{}{v.LedgerSequence, v.LedgerTime.String(), v.TxnCount},
			flag:   flag,
		}, nil
	case websockets.ServerStreamMsg:
		return &bundle{
			color:  infoStyle,
			format: "Server Status: %s (%d/%d)",
			values: []interface{}{v.Status, v.LoadFactor, v.LoadBase},
			flag:   flag,
		}, nil
	case data.Ledger:
		return &bundle{
			color:  ledgerStyle,
			format: "Ledger %d closed at %s",
			values: []interface{}{v.LedgerSequence, v.CloseTime.String()},
			flag:   flag,
		}, nil
	case data.InnerNode:
		return &bundle{
			color:  leStyle,
			format: "%s: %d hashes",
			values: []interface{}{v.Type, v.Count()},
			flag:   flag,
		}, nil
	case data.Proposal:
		return &bundle{
			color:  proposalStyle,
			format: "%s Proposal:   %s %s %s %s",
			values: []interface{}{data.CheckSymbol(&v), v.PublicKey.NodePublicKey(), v.CloseTime.String(), v.PreviousLedger, v.LedgerHash},
			flag:   flag,
		}, nil
	case data.Validation:
		return &bundle{
			color:  validationStyle,
			format: "%s Validation: %s %s %s %-8d %08X %s",
			values: []interface{}{data.CheckSymbol(&v), v.SigningPubKey.NodePublicKey(), v.SigningTime.String(), v.LedgerHash, v.LedgerSequence, v.Flags, v.Amendments},
			flag:   flag,
		}, nil
	case data.Trade:
		return &bundle{
			color:  tradeStyle,
			format: "Trade: %-34s => %-34s %-18s %60s => %-60s",
			values: []interface{}{v.Seller, v.Buyer, v.Price(), v.Paid, v.Got},
			flag:   flag,
		}, nil
	case data.Balance:
		return &bundle{
			color:  balanceStyle,
			format: "Balance: %-34s  Currency: %s Balance: %20s Change: %20s",
			values: []interface{}{v.Account, v.Currency, v.Balance, v.Change},
			flag:   flag,
		}, nil
	case data.Paths:
		sig, err := v.Signature()
		if err != nil {
			return nil, err
		}
		return &bundle{
			color:  pathStyle,
			format: "Path: %08X %s",
			values: []interface{}{sig, v.String()},
			flag:   flag,
		}, nil
	default:
		return &bundle{
			color:  infoStyle,
			format: "%s",
			values: []interface{}{v},
			flag:   flag,
		}, nil
	}
}

func indent(flag Flag) string {
	switch {
	case flag&Indent > 0:
		return "  "
	case flag&DoubleIndent > 0:
		return "    "
	case flag&TripleIndent > 0:
		return "      "
	default:
		return ""
	}
}

func println(value interface{}, flag Flag) (int, error) {
	b, err := newBundle(value, flag)
	if err != nil {
		return 0, err
	}
	return b.color.Printf(indent(flag)+b.format+"\n", b.values...)
}

func Println(value interface{}, flag Flag) {
	if _, err := println(value, flag); err != nil {
		infoStyle.Println(err.Error())
	}
}

func Sprint(value interface{}, flag Flag) string {
	b, err := newBundle(value, flag)
	if err != nil {
		return fmt.Sprintf("Cannot format: %+v", value)
	}
	return b.color.SprintfFunc()(indent(flag)+b.format, b.values...)
}
<commit_msg>Make indentation 4 characters<commit_after>// Utiltities for formatting Ripple data in a terminal
package terminal

import (
	"fmt"
	"github.com/donovanhide/ripple/data"
	"github.com/donovanhide/ripple/websockets"
	"github.com/fatih/color"
	"reflect"
)

type Flag uint32

const (
	Indent Flag = 1 << iota
	DoubleIndent
	TripleIndent

	ShowLedgerSequence
	ShowTransactionId
)

var Default Flag

var (
	ledgerStyle     = color.New(color.FgRed, color.Underline)
	leStyle         = color.New(color.FgWhite)
	txStyle         = color.New(color.FgGreen)
	proposalStyle   = color.New(color.FgYellow)
	validationStyle = color.New(color.FgYellow, color.Bold)
	tradeStyle      = color.New(color.FgBlue)
	balanceStyle    = color.New(color.FgMagenta)
	pathStyle       = color.New(color.FgYellow)
	infoStyle       = color.New(color.FgRed)
)

type bundle struct {
	color  *color.Color
	format string
	values []interface{}
	flag   Flag
}

func newLeBundle(v interface{}, flag Flag) (*bundle, error) {
	var (
		format = "%-11s "
		values = []interface{}{v.(data.LedgerEntry).GetLedgerEntryType()}
	)
	switch le := v.(type) {
	case *data.AccountRoot:
		format += "%-34s %08X %s"
		values = append(values, []interface{}{le.Account, *le.Flags, le.Balance}...)
	case *data.LedgerHashes:
		format += "%d hashes"
		values = append(values, []interface{}{len(le.Hashes)}...)
	case *data.RippleState:
		format += "%s %s %s"
		values = append(values, []interface{}{le.Balance, le.HighLimit, le.LowLimit}...)
	case *data.Offer:
		format += "%-34s %-60s %-60s %-18s"
		values = append(values, []interface{}{le.Account, le.TakerPays, le.TakerGets, le.Ratio()}...)
	case *data.FeeSettings:
		format += "%d %d %d %d"
		values = append(values, []interface{}{le.BaseFee, le.ReferenceFeeUnits, le.ReserveBase, le.ReserveIncrement}...)
	case *data.Amendments:
		format += "%s"
		values = append(values, []interface{}{le.Amendments}...)
	default:
		return nil, fmt.Errorf("Unknown Ledger Entry Type")
	}
	return &bundle{
		color:  leStyle,
		format: format,
		values: values,
		flag:   flag,
	}, nil
}

func newTxBundle(v data.Transaction, insert string, flag Flag) (*bundle, error) {
	var (
		base   = v.GetBase()
		format = "%s %-11s %-8s %s%s %-34s "
		values = []interface{}{data.CheckSymbol(v), base.GetType(), base.Fee, insert, base.MemoSymbol(), base.Account}
	)
	if flag&ShowTransactionId > 0 {
		format = "%s " + format
		values = append([]interface{}{data.TransactionId(v)}, values...)
	}
	switch tx := v.(type) {
	case *data.Payment:
		format += "=> %-34s %-60s %-60s"
		values = append(values, []interface{}{tx.Destination, tx.Amount, tx.SendMax}...)
	case *data.OfferCreate:
		format += "%-60s %-60s %-18s"
		values = append(values, []interface{}{tx.TakerPays, tx.TakerGets, tx.Ratio()}...)
	case *data.OfferCancel:
		format += "%-9d"
		values = append(values, tx.Sequence)
	case *data.AccountSet:
		format += "%-9d"
		values = append(values, tx.Sequence)
	case *data.TrustSet:
		format += "%-60s %d %d"
		values = append(values, tx.LimitAmount, tx.QualityIn, tx.QualityOut)
	}
	return &bundle{
		color:  txStyle,
		format: format,
		values: values,
		flag:   flag,
	}, nil
}

func newTxmBundle(txm *data.TransactionWithMetaData, flag Flag) (*bundle, error) {
	insert := fmt.Sprintf("%s ", txm.MetaData.TransactionResult.Symbol())
	if flag&ShowLedgerSequence > 0 {
		insert = fmt.Sprintf("%-9d %s", txm.LedgerSequence, insert)
	}
	b, err := newTxBundle(txm.Transaction, insert, flag)
	if err != nil {
		return nil, err
	}
	if !txm.MetaData.TransactionResult.Success() {
		b.color = infoStyle
	}
	return b, nil
}

func newBundle(value interface{}, flag Flag) (*bundle, error) {
	switch v := value.(type) {
	case *data.TransactionWithMetaData:
		return newTxmBundle(v, flag)
	case data.Transaction:
		return newTxBundle(v, "", flag)
	case data.LedgerEntry:
		return newLeBundle(v, flag)
	}
	switch v := reflect.Indirect(reflect.ValueOf(value)).Interface().(type) {
	case websockets.LedgerStreamMsg:
		return &bundle{
			color:  ledgerStyle,
			format: "Ledger %d closed at %s with %d transactions",
			values: []interface{}{v.LedgerSequence, v.LedgerTime.String(), v.TxnCount},
			flag:   flag,
		}, nil
	case websockets.ServerStreamMsg:
		return &bundle{
			color:  infoStyle,
			format: "Server Status: %s (%d/%d)",
			values: []interface{}{v.Status, v.LoadFactor, v.LoadBase},
			flag:   flag,
		}, nil
	case data.Ledger:
		return &bundle{
			color:  ledgerStyle,
			format: "Ledger %d closed at %s",
			values: []interface{}{v.LedgerSequence, v.CloseTime.String()},
			flag:   flag,
		}, nil
	case data.InnerNode:
		return &bundle{
			color:  leStyle,
			format: "%s: %d hashes",
			values: []interface{}{v.Type, v.Count()},
			flag:   flag,
		}, nil
	case data.Proposal:
		return &bundle{
			color:  proposalStyle,
			format: "%s Proposal:   %s %s %s %s",
			values: []interface{}{data.CheckSymbol(&v), v.PublicKey.NodePublicKey(), v.CloseTime.String(), v.PreviousLedger, v.LedgerHash},
			flag:   flag,
		}, nil
	case data.Validation:
		return &bundle{
			color:  validationStyle,
			format: "%s Validation: %s %s %s %-8d %08X %s",
			values: []interface{}{data.CheckSymbol(&v), v.SigningPubKey.NodePublicKey(), v.SigningTime.String(), v.LedgerHash, v.LedgerSequence, v.Flags, v.Amendments},
			flag:   flag,
		}, nil
	case data.Trade:
		return &bundle{
			color:  tradeStyle,
			format: "Trade: %-34s => %-34s %-18s %60s => %-60s",
			values: []interface{}{v.Seller, v.Buyer, v.Price(), v.Paid, v.Got},
			flag:   flag,
		}, nil
	case data.Balance:
		return &bundle{
			color:  balanceStyle,
			format: "Balance: %-34s  Currency: %s Balance: %20s Change: %20s",
			values: []interface{}{v.Account, v.Currency, v.Balance, v.Change},
			flag:   flag,
		}, nil
	case data.Paths:
		sig, err := v.Signature()
		if err != nil {
			return nil, err
		}
		return &bundle{
			color:  pathStyle,
			format: "Path: %08X %s",
			values: []interface{}{sig, v.String()},
			flag:   flag,
		}, nil
	default:
		return &bundle{
			color:  infoStyle,
			format: "%s",
			values: []interface{}{v},
			flag:   flag,
		}, nil
	}
}

func indent(flag Flag) string {
	switch {
	case flag&Indent > 0:
		return "    "
	case flag&DoubleIndent > 0:
		return "        "
	case flag&TripleIndent > 0:
		return "           "
	default:
		return ""
	}
}

func println(value interface{}, flag Flag) (int, error) {
	b, err := newBundle(value, flag)
	if err != nil {
		return 0, err
	}
	return b.color.Printf(indent(flag)+b.format+"\n", b.values...)
}

func Println(value interface{}, flag Flag) {
	if _, err := println(value, flag); err != nil {
		infoStyle.Println(err.Error())
	}
}

func Sprint(value interface{}, flag Flag) string {
	b, err := newBundle(value, flag)
	if err != nil {
		return fmt.Sprintf("Cannot format: %+v", value)
	}
	return b.color.SprintfFunc()(indent(flag)+b.format, b.values...)
}
<|endoftext|>


<commit_before>package terraform

import (
	"fmt"

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

// The main version number that is being run at the moment.
const Version = "0.10.7"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
var VersionPrerelease = ""

// SemVersion is an instance of version.Version. This has the secondary
// benefit of verifying during tests and init time that our version is a
// proper semantic version, which should always be the case.
var SemVersion = version.Must(version.NewVersion(Version))

// VersionHeader is the header name used to send the current terraform version
// in http requests.
const VersionHeader = "Terraform-Version"

func VersionString() string {
	if VersionPrerelease != "" {
		return fmt.Sprintf("%s-%s", Version, VersionPrerelease)
	}
	return Version
}
<commit_msg>release: clean up after v0.10.7<commit_after>package terraform

import (
	"fmt"

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

// The main version number that is being run at the moment.
const Version = "0.10.8"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
var VersionPrerelease = "dev"

// SemVersion is an instance of version.Version. This has the secondary
// benefit of verifying during tests and init time that our version is a
// proper semantic version, which should always be the case.
var SemVersion = version.Must(version.NewVersion(Version))

// VersionHeader is the header name used to send the current terraform version
// in http requests.
const VersionHeader = "Terraform-Version"

func VersionString() string {
	if VersionPrerelease != "" {
		return fmt.Sprintf("%s-%s", Version, VersionPrerelease)
	}
	return Version
}
<|endoftext|>


<commit_before>// Copyright 2016 The kube-etcd-controller Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package e2e

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"testing"
	"time"

	"github.com/coreos/kube-etcd-controller/pkg/spec"
	"github.com/coreos/kube-etcd-controller/pkg/util/k8sutil"
	"github.com/coreos/kube-etcd-controller/test/e2e/framework"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/unversioned"
	k8sclient "k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/util/wait"
)

func TestCreateCluster(t *testing.T) {
	f := framework.Global
	testEtcd, err := createEtcdCluster(f, makeEtcdCluster("test-etcd-", 3))
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		if err := deleteEtcdCluster(f, testEtcd.Name); err != nil {
			t.Fatal(err)
		}
	}()

	if _, err := waitUntilSizeReached(f, testEtcd.Name, 3, 60); err != nil {
		t.Fatalf("failed to create 3 members etcd cluster: %v", err)
	}
}

func TestResizeCluster3to5(t *testing.T) {
	f := framework.Global
	testEtcd, err := createEtcdCluster(f, makeEtcdCluster("test-etcd-", 3))
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		if err := deleteEtcdCluster(f, testEtcd.Name); err != nil {
			t.Fatal(err)
		}
	}()

	if _, err := waitUntilSizeReached(f, testEtcd.Name, 3, 60); err != nil {
		t.Fatalf("failed to create 3 members etcd cluster: %v", err)
		return
	}
	fmt.Println("reached to 3 members cluster")

	testEtcd.Spec.Size = 5
	if err := updateEtcdCluster(f, testEtcd); err != nil {
		t.Fatal(err)
	}

	if _, err := waitUntilSizeReached(f, testEtcd.Name, 5, 60); err != nil {
		t.Fatalf("failed to resize to 5 members etcd cluster: %v", err)
	}
}

func TestResizeCluster5to3(t *testing.T) {
	f := framework.Global
	testEtcd, err := createEtcdCluster(f, makeEtcdCluster("test-etcd-", 5))
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		if err := deleteEtcdCluster(f, testEtcd.Name); err != nil {
			t.Fatal(err)
		}
	}()

	if _, err := waitUntilSizeReached(f, testEtcd.Name, 5, 90); err != nil {
		t.Fatalf("failed to create 5 members etcd cluster: %v", err)
		return
	}
	fmt.Println("reached to 5 members cluster")

	testEtcd.Spec.Size = 3
	if err := updateEtcdCluster(f, testEtcd); err != nil {
		t.Fatal(err)
	}

	if _, err := waitUntilSizeReached(f, testEtcd.Name, 3, 60); err != nil {
		t.Fatalf("failed to resize to 3 members etcd cluster: %v", err)
	}
}

func TestOneMemberRecovery(t *testing.T) {
	f := framework.Global
	testEtcd, err := createEtcdCluster(f, makeEtcdCluster("test-etcd-", 3))
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err := deleteEtcdCluster(f, testEtcd.Name); err != nil {
			t.Fatal(err)
		}
	}()

	names, err := waitUntilSizeReached(f, testEtcd.Name, 3, 60)
	if err != nil {
		t.Fatalf("failed to create 3 members etcd cluster: %v", err)
		return
	}
	fmt.Println("reached to 3 members cluster")

	if err := killMembers(f, names[0]); err != nil {
		t.Fatal(err)
	}
	if _, err := waitUntilSizeReached(f, testEtcd.Name, 3, 60); err != nil {
		t.Fatalf("failed to resize to 3 members etcd cluster: %v", err)
	}
}

func TestDisasterRecovery(t *testing.T) {
	f := framework.Global
	backupPolicy := &spec.BackupPolicy{
		SnapshotIntervalInSecond: 120,
		MaxSnapshot:              5,
		VolumeSizeInMB:           512,
		StorageType:              spec.BackupStorageTypePersistentVolume,
		CleanupBackupIfDeleted:   true,
	}
	origEtcd := makeEtcdCluster("test-etcd-", 3)
	origEtcd = etcdClusterWithBackup(origEtcd, backupPolicy)
	testEtcd, err := createEtcdCluster(f, origEtcd)
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err := deleteEtcdCluster(f, testEtcd.Name); err != nil {
			t.Fatal(err)
		}
		// TODO: add checking of removal of backup pod
	}()

	names, err := waitUntilSizeReached(f, testEtcd.Name, 3, 60)
	if err != nil {
		t.Fatalf("failed to create 3 members etcd cluster: %v", err)
		return
	}
	fmt.Println("reached to 3 members cluster")
	// TODO: There might be race that controller will recover members between
	// 		these members are deleted individually.
	if err := killMembers(f, names[0], names[1]); err != nil {
		t.Fatal(err)
	}
	if _, err := waitUntilSizeReached(f, testEtcd.Name, 3, 120); err != nil {
		t.Fatalf("failed to resize to 3 members etcd cluster: %v", err)
	}
	// TODO: add checking of data in etcd
}

func waitUntilSizeReached(f *framework.Framework, clusterName string, size, timeout int) ([]string, error) {
	return waitSizeReachedWithFilter(f, clusterName, size, timeout, func(*api.Pod) bool { return true })
}

func waitSizeReachedWithFilter(f *framework.Framework, clusterName string, size, timeout int, filterPod func(*api.Pod) bool) ([]string, error) {
	var names []string
	err := wait.Poll(5*time.Second, time.Duration(timeout)*time.Second, func() (done bool, err error) {
		podList, err := f.KubeClient.Pods(f.Namespace.Name).List(k8sutil.EtcdPodListOpt(clusterName))
		if err != nil {
			return false, err
		}
		names = nil
		for i := range podList.Items {
			pod := &podList.Items[i]
			if pod.Status.Phase == api.PodRunning {
				names = append(names, pod.Name)
			}
		}
		fmt.Printf("waiting size (%d), etcd pods: %v\n", size, names)
		if len(names) != size {
			return false, nil
		}
		// TODO: check etcd member membership
		return true, nil
	})
	if err != nil {
		return nil, err
	}
	return names, nil
}

func killMembers(f *framework.Framework, names ...string) error {
	for _, name := range names {
		err := f.KubeClient.Pods(f.Namespace.Name).Delete(name, nil)
		if err != nil {
			return err
		}
	}
	return nil
}

func makeEtcdCluster(genName string, size int) *spec.EtcdCluster {
	return &spec.EtcdCluster{
		TypeMeta: unversioned.TypeMeta{
			Kind:       "EtcdCluster",
			APIVersion: "coreos.com/v1",
		},
		ObjectMeta: api.ObjectMeta{
			GenerateName: genName,
		},
		Spec: spec.ClusterSpec{
			Size: size,
		},
	}
}

func etcdClusterWithBackup(ec *spec.EtcdCluster, backupPolicy *spec.BackupPolicy) *spec.EtcdCluster {
	ec.Spec.Backup = backupPolicy
	return ec
}
func etcdClusterWithVersion(ec *spec.EtcdCluster, version string) *spec.EtcdCluster {
	ec.Spec.Version = version
	return ec
}

func createEtcdCluster(f *framework.Framework, e *spec.EtcdCluster) (*spec.EtcdCluster, error) {
	b, err := json.Marshal(e)
	if err != nil {
		return nil, err
	}
	resp, err := f.KubeClient.Client.Post(
		fmt.Sprintf("%s/apis/coreos.com/v1/namespaces/%s/etcdclusters", f.MasterHost, f.Namespace.Name),
		"application/json", bytes.NewReader(b))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusCreated {
		return nil, fmt.Errorf("unexpected status: %v", resp.Status)
	}
	decoder := json.NewDecoder(resp.Body)
	res := &spec.EtcdCluster{}
	if err := decoder.Decode(res); err != nil {
		return nil, err
	}
	fmt.Printf("created etcd cluster: %v\n", res.Name)
	return res, nil
}

func updateEtcdCluster(f *framework.Framework, e *spec.EtcdCluster) error {
	b, err := json.Marshal(e)
	if err != nil {
		return err
	}
	req, err := http.NewRequest("PUT",
		fmt.Sprintf("%s/apis/coreos.com/v1/namespaces/%s/etcdclusters/%s", f.MasterHost, f.Namespace.Name, e.Name),
		bytes.NewReader(b))
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")
	resp, err := f.KubeClient.Client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("unexpected status: %v", resp.Status)
	}
	return nil
}

func deleteEtcdCluster(f *framework.Framework, name string) error {
	fmt.Printf("deleting etcd cluster: %v\n", name)
	podList, err := f.KubeClient.Pods(f.Namespace.Name).List(k8sutil.EtcdPodListOpt(name))
	if err != nil {
		return err
	}
	fmt.Println("etcd pods ======")
	for i := range podList.Items {
		pod := &podList.Items[i]
		fmt.Printf("pod (%v): status (%v)\n", pod.Name, pod.Status.Phase)
		buf := bytes.NewBuffer(nil)

		if pod.Status.Phase == api.PodFailed {
			if err := getLogs(f.KubeClient, f.Namespace.Name, pod.Name, "etcd", buf); err != nil {
				return err
			}
			fmt.Println(pod.Name, "logs ===")
			fmt.Println(buf.String())
			fmt.Println(pod.Name, "logs END ===")
		}
	}

	buf := bytes.NewBuffer(nil)
	if err := getLogs(f.KubeClient, f.Namespace.Name, "kube-etcd-controller", "kube-etcd-controller", buf); err != nil {
		return err
	}
	fmt.Println("kube-etcd-controller logs ===")
	fmt.Println(buf.String())
	fmt.Println("kube-etcd-controller logs END ===")

	req, err := http.NewRequest("DELETE",
		fmt.Sprintf("%s/apis/coreos.com/v1/namespaces/%s/etcdclusters/%s", f.MasterHost, f.Namespace.Name, name), nil)
	if err != nil {
		return err
	}
	resp, err := f.KubeClient.Client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("unexpected status: %v", resp.Status)
	}
	return nil
}

func getLogs(kubecli *k8sclient.Client, ns, p, c string, out io.Writer) error {
	req := kubecli.RESTClient.Get().
		Namespace(ns).
		Resource("pods").
		Name(p).
		SubResource("log").
		Param("container", c).
		Param("tailLines", "20")

	readCloser, err := req.Stream()
	if err != nil {
		return err
	}
	defer readCloser.Close()

	_, err = io.Copy(out, readCloser)
	return err
}
<commit_msg>e2e: add waitBackupPodUp<commit_after>// Copyright 2016 The kube-etcd-controller Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package e2e

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"testing"
	"time"

	"github.com/coreos/kube-etcd-controller/pkg/spec"
	"github.com/coreos/kube-etcd-controller/pkg/util/k8sutil"
	"github.com/coreos/kube-etcd-controller/test/e2e/framework"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/unversioned"
	k8sclient "k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/util/wait"
	"k8s.io/kubernetes/pkg/watch"
)

func TestCreateCluster(t *testing.T) {
	f := framework.Global
	testEtcd, err := createEtcdCluster(f, makeEtcdCluster("test-etcd-", 3))
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		if err := deleteEtcdCluster(f, testEtcd.Name); err != nil {
			t.Fatal(err)
		}
	}()

	if _, err := waitUntilSizeReached(f, testEtcd.Name, 3, 60); err != nil {
		t.Fatalf("failed to create 3 members etcd cluster: %v", err)
	}
}

func TestResizeCluster3to5(t *testing.T) {
	f := framework.Global
	testEtcd, err := createEtcdCluster(f, makeEtcdCluster("test-etcd-", 3))
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		if err := deleteEtcdCluster(f, testEtcd.Name); err != nil {
			t.Fatal(err)
		}
	}()

	if _, err := waitUntilSizeReached(f, testEtcd.Name, 3, 60); err != nil {
		t.Fatalf("failed to create 3 members etcd cluster: %v", err)
		return
	}
	fmt.Println("reached to 3 members cluster")

	testEtcd.Spec.Size = 5
	if err := updateEtcdCluster(f, testEtcd); err != nil {
		t.Fatal(err)
	}

	if _, err := waitUntilSizeReached(f, testEtcd.Name, 5, 60); err != nil {
		t.Fatalf("failed to resize to 5 members etcd cluster: %v", err)
	}
}

func TestResizeCluster5to3(t *testing.T) {
	f := framework.Global
	testEtcd, err := createEtcdCluster(f, makeEtcdCluster("test-etcd-", 5))
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		if err := deleteEtcdCluster(f, testEtcd.Name); err != nil {
			t.Fatal(err)
		}
	}()

	if _, err := waitUntilSizeReached(f, testEtcd.Name, 5, 90); err != nil {
		t.Fatalf("failed to create 5 members etcd cluster: %v", err)
		return
	}
	fmt.Println("reached to 5 members cluster")

	testEtcd.Spec.Size = 3
	if err := updateEtcdCluster(f, testEtcd); err != nil {
		t.Fatal(err)
	}

	if _, err := waitUntilSizeReached(f, testEtcd.Name, 3, 60); err != nil {
		t.Fatalf("failed to resize to 3 members etcd cluster: %v", err)
	}
}

func TestOneMemberRecovery(t *testing.T) {
	f := framework.Global
	testEtcd, err := createEtcdCluster(f, makeEtcdCluster("test-etcd-", 3))
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err := deleteEtcdCluster(f, testEtcd.Name); err != nil {
			t.Fatal(err)
		}
	}()

	names, err := waitUntilSizeReached(f, testEtcd.Name, 3, 60)
	if err != nil {
		t.Fatalf("failed to create 3 members etcd cluster: %v", err)
		return
	}
	fmt.Println("reached to 3 members cluster")

	if err := killMembers(f, names[0]); err != nil {
		t.Fatal(err)
	}
	if _, err := waitUntilSizeReached(f, testEtcd.Name, 3, 60); err != nil {
		t.Fatalf("failed to resize to 3 members etcd cluster: %v", err)
	}
}

func TestDisasterRecovery(t *testing.T) {
	f := framework.Global
	backupPolicy := &spec.BackupPolicy{
		SnapshotIntervalInSecond: 120,
		MaxSnapshot:              5,
		VolumeSizeInMB:           512,
		StorageType:              spec.BackupStorageTypePersistentVolume,
		CleanupBackupIfDeleted:   true,
	}
	origEtcd := makeEtcdCluster("test-etcd-", 3)
	origEtcd = etcdClusterWithBackup(origEtcd, backupPolicy)
	testEtcd, err := createEtcdCluster(f, origEtcd)
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err := deleteEtcdCluster(f, testEtcd.Name); err != nil {
			t.Fatal(err)
		}
		// TODO: add checking of removal of backup pod
	}()

	names, err := waitUntilSizeReached(f, testEtcd.Name, 3, 60)
	if err != nil {
		t.Fatalf("failed to create 3 members etcd cluster: %v", err)
		return
	}
	fmt.Println("reached to 3 members cluster")
	if err := waitBackupPodUp(f, testEtcd.Name, 60*time.Second); err != nil {
		t.Fatalf("failed to create backup pod: %v", err)
	}
	// TODO: There might be race that controller will recover members between
	// 		these members are deleted individually.
	if err := killMembers(f, names[0], names[1]); err != nil {
		t.Fatal(err)
	}
	if _, err := waitUntilSizeReached(f, testEtcd.Name, 3, 120); err != nil {
		t.Fatalf("failed to resize to 3 members etcd cluster: %v", err)
	}
	// TODO: add checking of data in etcd
}

func waitBackupPodUp(f *framework.Framework, clusterName string, timeout time.Duration) error {
	w, err := f.KubeClient.Pods(f.Namespace.Name).Watch(api.ListOptions{
		LabelSelector: labels.SelectorFromSet(map[string]string{
			"app":          "etcd_backup_tool",
			"etcd_cluster": clusterName,
		}),
	})
	_, err = watch.Until(timeout, w, k8sclient.PodRunning)
	return err
}

func waitUntilSizeReached(f *framework.Framework, clusterName string, size, timeout int) ([]string, error) {
	return waitSizeReachedWithFilter(f, clusterName, size, timeout, func(*api.Pod) bool { return true })
}

func waitSizeReachedWithFilter(f *framework.Framework, clusterName string, size, timeout int, filterPod func(*api.Pod) bool) ([]string, error) {
	var names []string
	err := wait.Poll(5*time.Second, time.Duration(timeout)*time.Second, func() (done bool, err error) {
		podList, err := f.KubeClient.Pods(f.Namespace.Name).List(k8sutil.EtcdPodListOpt(clusterName))
		if err != nil {
			return false, err
		}
		names = nil
		for i := range podList.Items {
			pod := &podList.Items[i]
			if pod.Status.Phase == api.PodRunning {
				names = append(names, pod.Name)
			}
		}
		fmt.Printf("waiting size (%d), etcd pods: %v\n", size, names)
		if len(names) != size {
			return false, nil
		}
		// TODO: check etcd member membership
		return true, nil
	})
	if err != nil {
		return nil, err
	}
	return names, nil
}

func killMembers(f *framework.Framework, names ...string) error {
	for _, name := range names {
		err := f.KubeClient.Pods(f.Namespace.Name).Delete(name, nil)
		if err != nil {
			return err
		}
	}
	return nil
}

func makeEtcdCluster(genName string, size int) *spec.EtcdCluster {
	return &spec.EtcdCluster{
		TypeMeta: unversioned.TypeMeta{
			Kind:       "EtcdCluster",
			APIVersion: "coreos.com/v1",
		},
		ObjectMeta: api.ObjectMeta{
			GenerateName: genName,
		},
		Spec: spec.ClusterSpec{
			Size: size,
		},
	}
}

func etcdClusterWithBackup(ec *spec.EtcdCluster, backupPolicy *spec.BackupPolicy) *spec.EtcdCluster {
	ec.Spec.Backup = backupPolicy
	return ec
}
func etcdClusterWithVersion(ec *spec.EtcdCluster, version string) *spec.EtcdCluster {
	ec.Spec.Version = version
	return ec
}

func createEtcdCluster(f *framework.Framework, e *spec.EtcdCluster) (*spec.EtcdCluster, error) {
	b, err := json.Marshal(e)
	if err != nil {
		return nil, err
	}
	resp, err := f.KubeClient.Client.Post(
		fmt.Sprintf("%s/apis/coreos.com/v1/namespaces/%s/etcdclusters", f.MasterHost, f.Namespace.Name),
		"application/json", bytes.NewReader(b))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusCreated {
		return nil, fmt.Errorf("unexpected status: %v", resp.Status)
	}
	decoder := json.NewDecoder(resp.Body)
	res := &spec.EtcdCluster{}
	if err := decoder.Decode(res); err != nil {
		return nil, err
	}
	fmt.Printf("created etcd cluster: %v\n", res.Name)
	return res, nil
}

func updateEtcdCluster(f *framework.Framework, e *spec.EtcdCluster) error {
	b, err := json.Marshal(e)
	if err != nil {
		return err
	}
	req, err := http.NewRequest("PUT",
		fmt.Sprintf("%s/apis/coreos.com/v1/namespaces/%s/etcdclusters/%s", f.MasterHost, f.Namespace.Name, e.Name),
		bytes.NewReader(b))
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")
	resp, err := f.KubeClient.Client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("unexpected status: %v", resp.Status)
	}
	return nil
}

func deleteEtcdCluster(f *framework.Framework, name string) error {
	fmt.Printf("deleting etcd cluster: %v\n", name)
	podList, err := f.KubeClient.Pods(f.Namespace.Name).List(k8sutil.EtcdPodListOpt(name))
	if err != nil {
		return err
	}
	fmt.Println("etcd pods ======")
	for i := range podList.Items {
		pod := &podList.Items[i]
		fmt.Printf("pod (%v): status (%v)\n", pod.Name, pod.Status.Phase)
		buf := bytes.NewBuffer(nil)

		if pod.Status.Phase == api.PodFailed {
			if err := getLogs(f.KubeClient, f.Namespace.Name, pod.Name, "etcd", buf); err != nil {
				return err
			}
			fmt.Println(pod.Name, "logs ===")
			fmt.Println(buf.String())
			fmt.Println(pod.Name, "logs END ===")
		}
	}

	buf := bytes.NewBuffer(nil)
	if err := getLogs(f.KubeClient, f.Namespace.Name, "kube-etcd-controller", "kube-etcd-controller", buf); err != nil {
		return err
	}
	fmt.Println("kube-etcd-controller logs ===")
	fmt.Println(buf.String())
	fmt.Println("kube-etcd-controller logs END ===")

	req, err := http.NewRequest("DELETE",
		fmt.Sprintf("%s/apis/coreos.com/v1/namespaces/%s/etcdclusters/%s", f.MasterHost, f.Namespace.Name, name), nil)
	if err != nil {
		return err
	}
	resp, err := f.KubeClient.Client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("unexpected status: %v", resp.Status)
	}
	return nil
}

func getLogs(kubecli *k8sclient.Client, ns, p, c string, out io.Writer) error {
	req := kubecli.RESTClient.Get().
		Namespace(ns).
		Resource("pods").
		Name(p).
		SubResource("log").
		Param("container", c).
		Param("tailLines", "20")

	readCloser, err := req.Stream()
	if err != nil {
		return err
	}
	defer readCloser.Close()

	_, err = io.Copy(out, readCloser)
	return err
}
<|endoftext|>


<commit_before>package test

import (
	"context"
	"fmt"
	"strings"
	"testing"

	"k8s.io/client-go/kubernetes"

	"github.com/tektoncd/pipeline/pkg/apis/config"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"knative.dev/pkg/system"
)

// requireAnyGate returns a setup func that will skip the current
// test if none of the feature-flags in the given map match
// what's in the feature-flags ConfigMap. It will fatally fail
// the test if it cannot get the feature-flag configmap.
func requireAnyGate(gates map[string]string) func(context.Context, *testing.T, *clients, string) {
	return func(ctx context.Context, t *testing.T, c *clients, namespace string) {
		featureFlagsCM, err := c.KubeClient.CoreV1().ConfigMaps(system.Namespace()).Get(ctx, config.GetFeatureFlagsConfigName(), metav1.GetOptions{})
		if err != nil {
			t.Fatalf("Failed to get ConfigMap `%s`: %s", config.GetFeatureFlagsConfigName(), err)
		}
		pairs := []string{}
		for name, value := range gates {
			actual, ok := featureFlagsCM.Data[name]
			if ok && value == actual {
				return
			}
			pairs = append(pairs, fmt.Sprintf("%q: %q", name, value))
		}
		t.Skipf("No feature flag matching %s", strings.Join(pairs, " or "))
	}
}

// GetEmbeddedStatus gets the current value for the "embedded-status" feature flag.
// If the flag is not set, it returns the default value.
func GetEmbeddedStatus(ctx context.Context, t *testing.T, kubeClient kubernetes.Interface) string {
	featureFlagsCM, err := kubeClient.CoreV1().ConfigMaps(system.Namespace()).Get(ctx, config.GetFeatureFlagsConfigName(), metav1.GetOptions{})
	if err != nil {
		t.Fatalf("Failed to get ConfigMap `%s`: %s", config.GetFeatureFlagsConfigName(), err)
	}
	val := featureFlagsCM.Data["embedded-status"]
	if val == "" {
		return config.DefaultEmbeddedStatus
	}
	return val
}
<commit_msg>Adds more info the the error message when feature flags are missing<commit_after>package test

import (
	"context"
	"fmt"
	"strings"
	"testing"

	"k8s.io/client-go/kubernetes"

	"github.com/tektoncd/pipeline/pkg/apis/config"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"knative.dev/pkg/system"
)

// requireAnyGate returns a setup func that will skip the current
// test if none of the feature-flags in the given map match
// what's in the feature-flags ConfigMap. It will fatally fail
// the test if it cannot get the feature-flag configmap.
func requireAnyGate(gates map[string]string) func(context.Context, *testing.T, *clients, string) {
	return func(ctx context.Context, t *testing.T, c *clients, namespace string) {
		featureFlagsCM, err := c.KubeClient.CoreV1().ConfigMaps(system.Namespace()).Get(ctx, config.GetFeatureFlagsConfigName(), metav1.GetOptions{})
		if err != nil {
			t.Fatalf("Failed to get ConfigMap `%s`: %s", config.GetFeatureFlagsConfigName(), err)
		}
		pairs := []string{}
		for name, value := range gates {
			actual, ok := featureFlagsCM.Data[name]
			if ok && value == actual {
				return
			}
			pairs = append(pairs, fmt.Sprintf("%q: %q", name, value))
		}
		t.Skipf("No feature flag in namespace %q matching %s\nExisting feature flag: %#v", system.Namespace(), strings.Join(pairs, " or "), featureFlagsCM.Data)
	}
}

// GetEmbeddedStatus gets the current value for the "embedded-status" feature flag.
// If the flag is not set, it returns the default value.
func GetEmbeddedStatus(ctx context.Context, t *testing.T, kubeClient kubernetes.Interface) string {
	featureFlagsCM, err := kubeClient.CoreV1().ConfigMaps(system.Namespace()).Get(ctx, config.GetFeatureFlagsConfigName(), metav1.GetOptions{})
	if err != nil {
		t.Fatalf("Failed to get ConfigMap `%s`: %s", config.GetFeatureFlagsConfigName(), err)
	}
	val := featureFlagsCM.Data["embedded-status"]
	if val == "" {
		return config.DefaultEmbeddedStatus
	}
	return val
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package btcchain

import (
	"fmt"
)

// NotificationType represents the type of a notification message.
type NotificationType int

// Constants for the type of a notification message.
const (
	// NTOrphanBlock indicates an orphan block was processed and the
	// associated block hash should be passed to the GetOrphanRoot function
	// to find the root of all known orphans which should then be used to
	// request the missing blocks.
	NTOrphanBlock NotificationType = iota

	// NTBlockAccepted indicates the associated block was accepted into
	// the block chain.  Note that this does not necessarily mean it was
	// added to the main chain.  For that, use NTBlockConnected.
	NTBlockAccepted

	// NTBlockConnected indicates the associated block was connected to the
	// main chain.
	NTBlockConnected

	// NTBlockDisconnected indicates the associated block was disconnected
	// from the main chain.
	NTBlockDisconnected
)

// notificationTypeStrings is a map of notification types back to their constant
// names for pretty printing.
var notificationTypeStrings = map[NotificationType]string{
	NTOrphanBlock:       "NTOrphanBlock",
	NTBlockAccepted:     "NTBlockAccepted",
	NTBlockConnected:    "NTBlockConnected",
	NTBlockDisconnected: "NTBlockDisconnected",
}

// String returns the NotificationType in human-readable form.
func (n NotificationType) String() string {
	if s, ok := notificationTypeStrings[n]; ok {
		return s
	}
	return fmt.Sprintf("Unknown Notification Type (%d)", int(n))
}

// Notification defines an asynchronous notification that is sent to the caller
// over the notification channel provided during the call to New and consists
// of a notification type as well as associated data that depends on the type as
// follows:
// 	- NTOrphanBlock:       *btcwire.ShaHash
// 	- NTBlockAccepted:     *btcutil.Block
// 	- NTBlockConnected:    *btcutil.Block
// 	- NTBlockDisconnected: *btcutil.Block
type Notification struct {
	Type NotificationType
	Data interface{}
}

// sendNotification sends a notification with the passed type and data if the
// caller requested notifications by providing a channel in the call to New.
func (b *BlockChain) sendNotification(typ NotificationType, data interface{}) {
	// Ignore it if the caller didn't request notifications.
	if b.notifications == nil {
		return
	}

	// Generate and send the notification asynchronously.
	go func() {
		n := Notification{Type: typ, Data: data}
		b.notifications <- &n
	}()
}
<commit_msg>Revert "Send notification in their own goroutine."<commit_after>// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package btcchain

import (
	"fmt"
)

// NotificationType represents the type of a notification message.
type NotificationType int

// Constants for the type of a notification message.
const (
	// NTOrphanBlock indicates an orphan block was processed and the
	// associated block hash should be passed to the GetOrphanRoot function
	// to find the root of all known orphans which should then be used to
	// request the missing blocks.
	NTOrphanBlock NotificationType = iota

	// NTBlockAccepted indicates the associated block was accepted into
	// the block chain.  Note that this does not necessarily mean it was
	// added to the main chain.  For that, use NTBlockConnected.
	NTBlockAccepted

	// NTBlockConnected indicates the associated block was connected to the
	// main chain.
	NTBlockConnected

	// NTBlockDisconnected indicates the associated block was disconnected
	// from the main chain.
	NTBlockDisconnected
)

// notificationTypeStrings is a map of notification types back to their constant
// names for pretty printing.
var notificationTypeStrings = map[NotificationType]string{
	NTOrphanBlock:       "NTOrphanBlock",
	NTBlockAccepted:     "NTBlockAccepted",
	NTBlockConnected:    "NTBlockConnected",
	NTBlockDisconnected: "NTBlockDisconnected",
}

// String returns the NotificationType in human-readable form.
func (n NotificationType) String() string {
	if s, ok := notificationTypeStrings[n]; ok {
		return s
	}
	return fmt.Sprintf("Unknown Notification Type (%d)", int(n))
}

// Notification defines an asynchronous notification that is sent to the caller
// over the notification channel provided during the call to New and consists
// of a notification type as well as associated data that depends on the type as
// follows:
// 	- NTOrphanBlock:       *btcwire.ShaHash
// 	- NTBlockAccepted:     *btcutil.Block
// 	- NTBlockConnected:    *btcutil.Block
// 	- NTBlockDisconnected: *btcutil.Block
type Notification struct {
	Type NotificationType
	Data interface{}
}

// sendNotification sends a notification with the passed type and data if the
// caller requested notifications by providing a channel in the call to New.
func (b *BlockChain) sendNotification(typ NotificationType, data interface{}) {
	// Ignore it if the caller didn't request notifications.
	if b.notifications == nil {
		return
	}

	// Generate and send the notification.
	n := Notification{Type: typ, Data: data}
	b.notifications <- &n
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Knative Authors

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

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

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

package helpers

import (
	"log"
	"math/rand"
	"strings"
	"time"
	"unicode"

	"knative.dev/pkg/test"
)

const (
	letterBytes    = "abcdefghijklmnopqrstuvwxyz"
	randSuffixLen  = 8
	sep            = '-'
	testNamePrefix = "Test"
)

func init() {
	// Properly seed the random number generator so AppendRandomString() is actually random.
	// Otherwise, rerunning tests will generate the same names for the test resources, causing conflicts with
	// already existing resources.
	seed := time.Now().UTC().UnixNano()
	log.Printf("Using '%d' to seed the random number generator", seed)
	rand.Seed(seed)
}

// ObjectPrefixForTest returns the name prefix for this test's random names.
func ObjectPrefixForTest(t test.T) string {
	return MakeK8sNamePrefix(strings.TrimPrefix(t.Name(), testNamePrefix))
}

// ObjectNameForTest generates a random object name based on the test name.
func ObjectNameForTest(t test.T) string {
	return AppendRandomString(ObjectPrefixForTest(t))
}

// AppendRandomString will generate a random string that begins with prefix.
// This is useful if you want to make sure that your tests can run at the same
// time against the same environment without conflicting.
// This method will use "-" as the separator between the prefix and
// the random suffix.
func AppendRandomString(prefix string) string {
	suffix := make([]byte, randSuffixLen)

	for i := range suffix {
		suffix[i] = letterBytes[rand.Intn(len(letterBytes))]
	}

	return strings.Join([]string{prefix, string(suffix)}, string(sep))
}

// MakeK8sNamePrefix converts each chunk of non-alphanumeric character into a single dash
// and also convert camelcase tokens into dash-delimited lowercase tokens.
func MakeK8sNamePrefix(s string) string {
	var sb strings.Builder
	newToken := false
	for _, c := range s {
		if !(unicode.IsLetter(c) || unicode.IsNumber(c)) {
			newToken = true
			continue
		}
		if sb.Len() > 0 && (newToken || unicode.IsUpper(c)) {
			sb.WriteRune(sep)
		}
		sb.WriteRune(unicode.ToLower(c))
		newToken = false
	}
	return sb.String()
}

// GetBaseFuncName returns the baseFuncName parsed from the fullFuncName.
// eg. test/e2e.TestMain will return TestMain.
func GetBaseFuncName(fullFuncName string) string {
	name := fullFuncName
	// Possibly there is no parent package, so only remove it from the name if '/' exists
	if strings.ContainsRune(name, '/') {
		name = name[strings.LastIndex(name, "/")+1:]
	}
	name = name[strings.LastIndex(name, ".")+1:]
	return name
}
<commit_msg>Shorten object name to avoid DNS issue defined (RFC 1035) (#1224)<commit_after>/*
Copyright 2019 The Knative Authors

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

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

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

package helpers

import (
	"log"
	"math/rand"
	"strings"
	"time"
	"unicode"

	"knative.dev/pkg/kmeta"
	"knative.dev/pkg/test"
)

const (
	letterBytes    = "abcdefghijklmnopqrstuvwxyz"
	randSuffixLen  = 8
	sep            = '-'
	testNamePrefix = "Test"
)

func init() {
	// Properly seed the random number generator so RandomString() is actually random.
	// Otherwise, rerunning tests will generate the same names for the test resources, causing conflicts with
	// already existing resources.
	seed := time.Now().UTC().UnixNano()
	log.Printf("Using '%d' to seed the random number generator", seed)
	rand.Seed(seed)
}

// ObjectPrefixForTest returns the name prefix for this test's random names.
func ObjectPrefixForTest(t test.T) string {
	return MakeK8sNamePrefix(strings.TrimPrefix(t.Name(), testNamePrefix))
}

// ObjectNameForTest generates a random object name based on the test name.
func ObjectNameForTest(t test.T) string {
	return kmeta.ChildName(ObjectPrefixForTest(t), string(sep)+RandomString())
}

// AppendRandomString will generate a random string that begins with prefix.
// This is useful if you want to make sure that your tests can run at the same
// time against the same environment without conflicting.
// This method will use "-" as the separator between the prefix and
// the random suffix.
func AppendRandomString(prefix string) string {
	return strings.Join([]string{prefix, RandomString()}, string(sep))
}

// RandomString will generate a random string.
func RandomString() string {
	suffix := make([]byte, randSuffixLen)

	for i := range suffix {
		suffix[i] = letterBytes[rand.Intn(len(letterBytes))]
	}
	return string(suffix)
}

// MakeK8sNamePrefix converts each chunk of non-alphanumeric character into a single dash
// and also convert camelcase tokens into dash-delimited lowercase tokens.
func MakeK8sNamePrefix(s string) string {
	var sb strings.Builder
	newToken := false
	for _, c := range s {
		if !(unicode.IsLetter(c) || unicode.IsNumber(c)) {
			newToken = true
			continue
		}
		if sb.Len() > 0 && (newToken || unicode.IsUpper(c)) {
			sb.WriteRune(sep)
		}
		sb.WriteRune(unicode.ToLower(c))
		newToken = false
	}
	return sb.String()
}

// GetBaseFuncName returns the baseFuncName parsed from the fullFuncName.
// eg. test/e2e.TestMain will return TestMain.
func GetBaseFuncName(fullFuncName string) string {
	name := fullFuncName
	// Possibly there is no parent package, so only remove it from the name if '/' exists
	if strings.ContainsRune(name, '/') {
		name = name[strings.LastIndex(name, "/")+1:]
	}
	name = name[strings.LastIndex(name, ".")+1:]
	return name
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"strings"

	"github.com/jinzhu/gorm"
	_ "github.com/lib/pq"
)

var (
	user   = "socialapplication"
	dbName = "social"
)

func main() {
	if len(os.Args) < 3 {
		fmt.Println("Please pass pg host and url as seperate arguments.")
		os.Exit(1)
	}

	url, port := os.Args[1], os.Args[2]

	pgConfString := fmt.Sprintf(
		"host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
		url, port, user, user, dbName,
	)

	db, err := gorm.Open("postgres", pgConfString)
	if err != nil {
		fmt.Println("Error connecting to db", err)
		return
	}

	db.DB()

	// uncomment this line to see sql queries, useful in debugging
	// db = *db.Debug()

	checkIfLocalIsUptodate(db)
}

func checkIfLocalIsUptodate(db gorm.DB) {
	var count int
	err := db.Table("payment.customer").Count(&count).Error

	if err == nil {
		return
	}

	if ErrConnRefusedFn(err) {
		fmt.Println(
			"Your postgresql isn't running/accessible, be run `./run services`.",
		)

		os.Exit(1)
	}

	if ErrPaymentTablesFn(err) {
		fmt.Println(
			"Your db doesn't have the latest schema, please do `./run buildservices`.",
		)

		os.Exit(1)
	}

	fmt.Println(err)
	os.Exit(1)
}

var ErrConnRefusedFn = func(err error) bool {
	return strings.Contains(err.Error(), "connection refused") || strings.Contains(err.Error(), "no such host")
}

var ErrPaymentTablesFn = func(err error) bool {
	return strings.Contains(err.Error(),
		`pq: relation "payment.customerr" does not exist`,
	)
}
<commit_msg>payment: minor spelling fix<commit_after>package main

import (
	"fmt"
	"os"
	"strings"

	"github.com/jinzhu/gorm"
	_ "github.com/lib/pq"
)

var (
	user   = "socialapplication"
	dbName = "social"
)

func main() {
	if len(os.Args) < 3 {
		fmt.Println("Please pass pg host and url as seperate arguments.")
		os.Exit(1)
	}

	url, port := os.Args[1], os.Args[2]

	pgConfString := fmt.Sprintf(
		"host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
		url, port, user, user, dbName,
	)

	db, err := gorm.Open("postgres", pgConfString)
	if err != nil {
		fmt.Println("Error connecting to db", err)
		return
	}

	db.DB()

	// uncomment this line to see sql queries, useful in debugging
	// db = *db.Debug()

	checkIfLocalIsUptodate(db)
}

func checkIfLocalIsUptodate(db gorm.DB) {
	var count int
	err := db.Table("payment.customer").Count(&count).Error

	if err == nil {
		return
	}

	if ErrConnRefusedFn(err) {
		fmt.Println(
			"Your postgresql isn't running/accessible, be run `./run services`.",
		)

		os.Exit(1)
	}

	if ErrPaymentTablesFn(err) {
		fmt.Println(
			"Your db doesn't have the latest schema, please do `./run buildservices`.",
		)

		os.Exit(1)
	}

	fmt.Println(err)
	os.Exit(1)
}

var ErrConnRefusedFn = func(err error) bool {
	return strings.Contains(err.Error(), "connection refused") || strings.Contains(err.Error(), "no such host")
}

var ErrPaymentTablesFn = func(err error) bool {
	return strings.Contains(err.Error(),
		`pq: relation "payment.customer" does not exist`,
	)
}
<|endoftext|>