<commit_before>package main

import (
	"errors"
	"fmt"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

type Chaincode struct { }

type ChaincodeFunctions struct {
	stub shim.ChaincodeStubInterface
}

func main() {
	err := shim.Start(new(Chaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

func (t Chaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	_ = stub.PutState("_companies", []byte("[]"))
	return nil, nil
}

func (t Chaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)
	fns := ChaincodeFunctions{stub}
	if function == "declareDoc" {
		docType := args[0]
		return fns.DeclareDoc(docType)
	}
	return nil, errors.New("Received unknown function invocation: " + function)
}

func (t Chaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)
	fns := ChaincodeFunctions{stub}
	if function == "ping" {
		return fns.Ping()
	} else if function == "getDocs" {
		company := args[0]
		return fns.GetDocsFor(company)
	} else if function == "getDocsForAllCompanies" {
		return fns.GetDocsForAllCompanies()
	}
	return nil, errors.New("Received unknown function query: " + function)
}

// Public Functions

func (c ChaincodeFunctions) Ping() ([]byte, error) {
    return []byte("pong"), nil
}

func (c ChaincodeFunctions) DeclareDoc(docType string) ([]byte, error)  {
	companyBytes, _ := c.stub.ReadCertAttribute("company")
	company := string(companyBytes)
	docs := c.getDocsFromBlockChain(company)
	docs = append(docs, docType)
	c.saveDocsToBlockChain(company, docs)
	c.stub.SetEvent("New Doc Registered", []byte("{\"docType\":\"" + docType + "\"}"))
	return nil, nil
}

func (c ChaincodeFunctions) GetDocsFor(company string) ([]byte, error) {
	myCompanyBytes, _ := c.stub.ReadCertAttribute("company")
	roleBytes, _ := c.stub.ReadCertAttribute("role")
	myCompany := string(myCompanyBytes)
	role := string(roleBytes)
	if myCompany != company && role != "regulator" && role != "bank" {
		return nil, errors.New("Not Permitted")
	}
	docs := c.getDocsFromBlockChain(company)
	docsJson, _ := json.Marshal(docs)
	return docsJson, nil
}

func (c ChaincodeFunctions) GetDocsForAllCompanies() ([]byte, error) {
	roleBytes, _ := c.stub.ReadCertAttribute("role")
	role := string(roleBytes)
	if role != "regulator" && role != "bank" {
		return nil, errors.New("Not Permitted")
	}
	allDocs := make(map[string][]string)
	companiesJson, _ := c.stub.GetState("_companies")
	var companies []string
	_ = json.Unmarshal(companiesJson, &companies)
	for _, company := range companies {
		docs := c.getDocsFromBlockChain(company)
		allDocs[company] = docs
	}
	allDocsJson, _ := json.Marshal(allDocs)
	return allDocsJson, nil
}

// Private Functions

func (c ChaincodeFunctions) getDocsFromBlockChain(company string) []string {
	docsJson, _ := c.stub.GetState(company)
	if docsJson == nil {
		return make([]string, 0)
	}
	var docs []string
	_ = json.Unmarshal(docsJson, &docs)
	return docs
}

func (c ChaincodeFunctions) saveDocsToBlockChain(company string, docs []string) {
	companiesJson, _ := c.stub.GetState("_companies")
	var companies []string
	_ = json.Unmarshal(companiesJson, &companies)
	companies = append(companies, company)
	companiesJson, _ = json.Marshal(companies)
	_ = c.stub.PutState("_companies", []byte(companiesJson))
	docsJson, _ := json.Marshal(docs)
	_ = c.stub.PutState(company, []byte(docsJson))
}<commit_msg>batch check-in<commit_after>package main

import (
	"errors"
	"fmt"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

type Chaincode struct { }

type ChaincodeFunctions struct {
	stub shim.ChaincodeStubInterface
}

func main() {
	err := shim.Start(new(Chaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

func (t Chaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	_ = stub.PutState("_companies", []byte("[]"))
	return nil, nil
}

func (t Chaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)
	fns := ChaincodeFunctions{stub}
	if function == "declareDoc" {
		docType := args[0]
		return fns.DeclareDoc(docType)
	}
	return nil, errors.New("Received unknown function invocation: " + function)
}

func (t Chaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)
	fns := ChaincodeFunctions{stub}
	if function == "ping" {
		return fns.Ping()
	} else if function == "getDocs" {
		company := args[0]
		return fns.GetDocsFor(company)
	} else if function == "getDocsForAllCompanies" {
		return fns.GetDocsForAllCompanies()
	}
	return nil, errors.New("Received unknown function query: " + function)
}

// Public Functions

func (c ChaincodeFunctions) Ping() ([]byte, error) {
    return []byte("pong"), nil
}

func (c ChaincodeFunctions) DeclareDoc(docType string) ([]byte, error)  {
	companyBytes, _ := c.stub.ReadCertAttribute("company")
	company := string(companyBytes)
	docs := c.getDocsFromBlockChain(company)
	docs = append(docs, docType)
	c.saveDocsToBlockChain(company, docs)
	c.stub.SetEvent("New Doc Registered", []byte("{\"docType\":\"" + docType + "\"}"))
	return nil, nil
}

func (c ChaincodeFunctions) GetDocsFor(company string) ([]byte, error) {
	myCompanyBytes, _ := c.stub.ReadCertAttribute("company")
	roleBytes, _ := c.stub.ReadCertAttribute("role")
	myCompany := string(myCompanyBytes)
	role := string(roleBytes)
	if myCompany != company && role != "regulator" && role != "bank" {
		return nil, errors.New("Not Permitted mycompany=" + myCompany + " company=" + company)
	}
	docs := c.getDocsFromBlockChain(company)
	docsJson, _ := json.Marshal(docs)
	return docsJson, nil
}

func (c ChaincodeFunctions) GetDocsForAllCompanies() ([]byte, error) {
	roleBytes, _ := c.stub.ReadCertAttribute("role")
	role := string(roleBytes)
	if role != "regulator" && role != "bank" {
		return nil, errors.New("Not Permitted")
	}
	allDocs := make(map[string][]string)
	companiesJson, _ := c.stub.GetState("_companies")
	var companies []string
	_ = json.Unmarshal(companiesJson, &companies)
	for _, company := range companies {
		docs := c.getDocsFromBlockChain(company)
		allDocs[company] = docs
	}
	allDocsJson, _ := json.Marshal(allDocs)
	return allDocsJson, nil
}

// Private Functions

func (c ChaincodeFunctions) getDocsFromBlockChain(company string) []string {
	docsJson, _ := c.stub.GetState(company)
	if docsJson == nil {
		return make([]string, 0)
	}
	var docs []string
	_ = json.Unmarshal(docsJson, &docs)
	return docs
}

func (c ChaincodeFunctions) saveDocsToBlockChain(company string, docs []string) {
	companiesJson, _ := c.stub.GetState("_companies")
	var companies []string
	_ = json.Unmarshal(companiesJson, &companies)
	companies = append(companies, company)
	companiesJson, _ = json.Marshal(companies)
	_ = c.stub.PutState("_companies", []byte(companiesJson))
	docsJson, _ := json.Marshal(docs)
	_ = c.stub.PutState(company, []byte(docsJson))
}<|endoftext|>


<commit_before>package controller

// TODO: Create package 'oauth'

import (
	"fmt"
	"net/http"
	"os"
	"time"

	"github.com/jinzhu/gorm"
	"github.com/oinume/lekcije/server/config"
	"github.com/oinume/lekcije/server/context_data"
	"github.com/oinume/lekcije/server/errors"
	"github.com/oinume/lekcije/server/model"
	"github.com/oinume/lekcije/server/util"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	google_auth2 "google.golang.org/api/oauth2/v2"
)

var _ = fmt.Print

var googleOAuthConfig = oauth2.Config{
	ClientID:     os.Getenv("GOOGLE_CLIENT_ID"),
	ClientSecret: os.Getenv("GOOGLE_CLIENT_SECRET"),
	Endpoint:     google.Endpoint,
	RedirectURL:  "",
	Scopes: []string{
		"openid email",
		"openid profile",
	},
}

type oauthError int

const (
	oauthErrorUnknown oauthError = 1 + iota
	oauthErrorAccessDenied
)

func (e oauthError) Error() string {
	switch e {
	case oauthErrorUnknown:
		return "oauthError: unknown"
	case oauthErrorAccessDenied:
		return "oauthError: access denied"
	}
	return fmt.Sprintf("oauthError: invalid: %v", e)
}

func OAuthGoogle(w http.ResponseWriter, r *http.Request) {
	state := util.RandomString(32)
	cookie := &http.Cookie{
		Name:     "oauthState",
		Value:    state,
		Path:     "/",
		Expires:  time.Now().Add(time.Minute * 30),
		HttpOnly: true,
	}
	http.SetCookie(w, cookie)
	c := getGoogleOAuthConfig(r)
	http.Redirect(w, r, c.AuthCodeURL(state), http.StatusFound)
}

func OAuthGoogleCallback(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	if err := checkState(r); err != nil {
		InternalServerError(w, err)
		return
	}
	token, idToken, err := exchange(r)
	if err != nil {
		if err == oauthErrorAccessDenied {
			http.Redirect(w, r, "/", http.StatusFound)
			return
		}
		InternalServerError(w, err)
		return
	}
	googleID, name, email, err := getGoogleUserInfo(token, idToken)
	if err != nil {
		InternalServerError(w, err)
		return
	}

	db := context_data.MustDB(ctx)
	userService := model.NewUserService(db)
	user, err := userService.FindByGoogleID(googleID)
	if err == nil {
		go sendMeasurementEvent2(r, eventCategoryUser, "login", fmt.Sprint(user.ID), 0, user.ID)
	} else {
		if _, notFound := err.(*errors.NotFound); !notFound {
			InternalServerError(w, err)
			return
		}
		// Couldn't find user for the googleID, so create a new user
		errTx := model.GORMTransaction(db, "OAuthGoogleCallback", func(tx *gorm.DB) error {
			var errCreate error
			user, _, errCreate = userService.CreateWithGoogle(name, email, googleID)
			return errCreate
		})
		if errTx != nil {
			InternalServerError(w, errTx)
			return
		}
		go sendMeasurementEvent2(r, eventCategoryUser, "create", fmt.Sprint(user.ID), 0, user.ID)
	}

	userAPITokenService := model.NewUserAPITokenService(context_data.MustDB(ctx))
	userAPIToken, err := userAPITokenService.Create(user.ID)
	if err != nil {
		InternalServerError(w, err)
		return
	}

	cookie := &http.Cookie{
		Name:     APITokenCookieName,
		Value:    userAPIToken.Token,
		Path:     "/",
		Expires:  time.Now().Add(model.UserAPITokenExpiration),
		HttpOnly: false,
	}
	http.SetCookie(w, cookie)
	http.Redirect(w, r, "/me", http.StatusFound)
}

func checkState(r *http.Request) error {
	state := r.FormValue("state")
	oauthState, err := r.Cookie("oauthState")
	if err != nil {
		return errors.InternalWrapf(err, "Failed to get cookie oauthState")
	}
	if state != oauthState.Value {
		return errors.InternalWrapf(err, "state mismatch")
	}
	return nil
}

func exchange(r *http.Request) (*oauth2.Token, string, error) {
	if e := r.FormValue("error"); e != "" {
		switch e {
		case "access_denied":
			return nil, "", oauthErrorAccessDenied
		default:
			return nil, "", oauthErrorUnknown
		}
	}
	code := r.FormValue("code")
	c := getGoogleOAuthConfig(r)
	token, err := c.Exchange(oauth2.NoContext, code)
	if err != nil {
		return nil, "", errors.InternalWrapf(err, "Failed to exchange")
	}
	idToken, ok := token.Extra("id_token").(string)
	if !ok {
		return nil, "", errors.Internalf("Failed to get id_token")
	}
	return token, idToken, nil
}

// Returns userId, name, email, error
func getGoogleUserInfo(token *oauth2.Token, idToken string) (string, string, string, error) {
	oauth2Client := oauth2.NewClient(oauth2.NoContext, oauth2.StaticTokenSource(token))
	service, err := google_auth2.New(oauth2Client)
	if err != nil {
		// TODO: quit using errors.Wrap
		return "", "", "", errors.InternalWrapf(err, "Failed to create oauth2.Client")
	}

	userinfo, err := service.Userinfo.V2.Me.Get().Do()
	if err != nil {
		return "", "", "", errors.InternalWrapf(err, "Failed to get userinfo")
	}

	tokeninfo, err := service.Tokeninfo().IdToken(idToken).Do()
	if err != nil {
		return "", "", "", errors.InternalWrapf(err, "Failed to get tokeninfo")
	}

	return tokeninfo.UserId, userinfo.Name, tokeninfo.Email, nil
}

func getGoogleOAuthConfig(r *http.Request) oauth2.Config {
	c := googleOAuthConfig
	c.RedirectURL = fmt.Sprintf("%s://%s/oauth/google/callback", config.WebURLScheme(r), r.Host)
	return c
}
<commit_msg>Investigating an error of rollbar #28<commit_after>package controller

// TODO: Create package 'oauth'

import (
	"fmt"
	"net/http"
	"os"
	"time"

	"github.com/jinzhu/gorm"
	"github.com/oinume/lekcije/server/config"
	"github.com/oinume/lekcije/server/context_data"
	"github.com/oinume/lekcije/server/errors"
	"github.com/oinume/lekcije/server/model"
	"github.com/oinume/lekcije/server/util"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	google_auth2 "google.golang.org/api/oauth2/v2"
)

var _ = fmt.Print

var googleOAuthConfig = oauth2.Config{
	ClientID:     os.Getenv("GOOGLE_CLIENT_ID"),
	ClientSecret: os.Getenv("GOOGLE_CLIENT_SECRET"),
	Endpoint:     google.Endpoint,
	RedirectURL:  "",
	Scopes: []string{
		"openid email",
		"openid profile",
	},
}

type oauthError int

const (
	oauthErrorUnknown oauthError = 1 + iota
	oauthErrorAccessDenied
)

func (e oauthError) Error() string {
	switch e {
	case oauthErrorUnknown:
		return "oauthError: unknown"
	case oauthErrorAccessDenied:
		return "oauthError: access denied"
	}
	return fmt.Sprintf("oauthError: invalid: %v", e)
}

func OAuthGoogle(w http.ResponseWriter, r *http.Request) {
	state := util.RandomString(32)
	cookie := &http.Cookie{
		Name:     "oauthState",
		Value:    state,
		Path:     "/",
		Expires:  time.Now().Add(time.Minute * 30),
		HttpOnly: true,
	}
	http.SetCookie(w, cookie)
	c := getGoogleOAuthConfig(r)
	http.Redirect(w, r, c.AuthCodeURL(state), http.StatusFound)
}

func OAuthGoogleCallback(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	if err := checkState(r); err != nil {
		InternalServerError(w, err)
		return
	}
	token, idToken, err := exchange(r)
	if err != nil {
		if err == oauthErrorAccessDenied {
			http.Redirect(w, r, "/", http.StatusFound)
			return
		}
		InternalServerError(w, err)
		return
	}
	googleID, name, email, err := getGoogleUserInfo(token, idToken)
	if err != nil {
		InternalServerError(w, err)
		return
	}

	db := context_data.MustDB(ctx)
	userService := model.NewUserService(db)
	user, err := userService.FindByGoogleID(googleID)
	if err == nil {
		go sendMeasurementEvent2(r, eventCategoryUser, "login", fmt.Sprint(user.ID), 0, user.ID)
	} else {
		if _, notFound := err.(*errors.NotFound); !notFound {
			InternalServerError(w, err)
			return
		}
		// Couldn't find user for the googleID, so create a new user
		errTx := model.GORMTransaction(db, "OAuthGoogleCallback", func(tx *gorm.DB) error {
			var errCreate error
			user, _, errCreate = userService.CreateWithGoogle(name, email, googleID)
			return errCreate
		})
		if errTx != nil {
			InternalServerError(w, errTx)
			return
		}
		go sendMeasurementEvent2(r, eventCategoryUser, "create", fmt.Sprint(user.ID), 0, user.ID)
	}

	userAPITokenService := model.NewUserAPITokenService(context_data.MustDB(ctx))
	userAPIToken, err := userAPITokenService.Create(user.ID)
	if err != nil {
		InternalServerError(w, err)
		return
	}

	cookie := &http.Cookie{
		Name:     APITokenCookieName,
		Value:    userAPIToken.Token,
		Path:     "/",
		Expires:  time.Now().Add(model.UserAPITokenExpiration),
		HttpOnly: false,
	}
	http.SetCookie(w, cookie)
	http.Redirect(w, r, "/me", http.StatusFound)
}

func checkState(r *http.Request) error {
	state := r.FormValue("state")
	oauthState, err := r.Cookie("oauthState")
	if err != nil {
		return errors.InternalWrapf(
			err, "Failed to get cookie oauthState: userAgent=%v, remoteAddr=%v",
			r.UserAgent(), GetRemoteAddress(r),
		)
	}
	if state != oauthState.Value {
		return errors.InternalWrapf(err, "state mismatch")
	}
	return nil
}

func exchange(r *http.Request) (*oauth2.Token, string, error) {
	if e := r.FormValue("error"); e != "" {
		switch e {
		case "access_denied":
			return nil, "", oauthErrorAccessDenied
		default:
			return nil, "", oauthErrorUnknown
		}
	}
	code := r.FormValue("code")
	c := getGoogleOAuthConfig(r)
	token, err := c.Exchange(oauth2.NoContext, code)
	if err != nil {
		return nil, "", errors.InternalWrapf(err, "Failed to exchange")
	}
	idToken, ok := token.Extra("id_token").(string)
	if !ok {
		return nil, "", errors.Internalf("Failed to get id_token")
	}
	return token, idToken, nil
}

// Returns userId, name, email, error
func getGoogleUserInfo(token *oauth2.Token, idToken string) (string, string, string, error) {
	oauth2Client := oauth2.NewClient(oauth2.NoContext, oauth2.StaticTokenSource(token))
	service, err := google_auth2.New(oauth2Client)
	if err != nil {
		// TODO: quit using errors.Wrap
		return "", "", "", errors.InternalWrapf(err, "Failed to create oauth2.Client")
	}

	userinfo, err := service.Userinfo.V2.Me.Get().Do()
	if err != nil {
		return "", "", "", errors.InternalWrapf(err, "Failed to get userinfo")
	}

	tokeninfo, err := service.Tokeninfo().IdToken(idToken).Do()
	if err != nil {
		return "", "", "", errors.InternalWrapf(err, "Failed to get tokeninfo")
	}

	return tokeninfo.UserId, userinfo.Name, tokeninfo.Email, nil
}

func getGoogleOAuthConfig(r *http.Request) oauth2.Config {
	c := googleOAuthConfig
	c.RedirectURL = fmt.Sprintf("%s://%s/oauth/google/callback", config.WebURLScheme(r), r.Host)
	return c
}
<|endoftext|>


<commit_before>package contour

import (
	"testing"
)

func TestOverride(t *testing.T) {
	tests := []struct {
		name        string
		key         string
		value       interface{}
		expectedErr string
	}{
		{"corebool", "corebool", true, "corebool is not a flag: only flags can be overridden"},
		{"coreint", "coreint", 42, "coreint is not a flag: only flags can be overridden"},
		{"corestring", "corestring", "beeblebrox", "corestring is not a flag: only flags can be overridden"},
		{"cfgbool", "cfgbool", true, "cfgbool is not a flag: only flags can be overridden"},
		{"cfgint", "cfgint", 43, "cfgint is not a flag: only flags can be overridden"},
		{"cfgstring", "cfgstring", "frood", "cfgstring is not a flag: only flags can be overridden"},
		{"flagbool", "flagbool", true, ""},
		{"flagint", "flagint", 41, ""},
		{"flagstring", "flagstring", "towel", ""},
		{"bool", "bool", true, "bool is not a flag: only flags can be overridden"},
		{"int", "int", 3, "int is not a flag: only flags can be overridden"},
		{"string", "string", "don't panic", "string is not a flag: only flags can be overridden"},
	}
	testCfg := newTestSettings()
	for i, test := range tests {
		err := testCfg.Override(test.key, test.value)
		if err != nil {
			if err.Error() != test.expectedErr {
				t.Errorf("%d: expected error to be %q, got %q", i, test.expectedErr, err)
			}
			continue
		}
		if test.expectedErr != "" {
			t.Errorf("%d: expected error to be %q: got none", i, test.expectedErr)
			continue
		}
		v := testCfg.Get(test.key)
		if v != test.value {
			t.Errorf("%d: expected %v got %v", i, test.value, v)
		}
	}
}
<commit_msg>clean up pverride tests<commit_after>package contour

import (
	"testing"
)

func TestOverride(t *testing.T) {
	tests := []struct {
		key         string
		value       interface{}
		expectedErr string
	}{
		{"corebool", true, "corebool is not a flag: only flags can be overridden"},
		{"coreint", 42, "coreint is not a flag: only flags can be overridden"},
		{"corestring", "beeblebrox", "corestring is not a flag: only flags can be overridden"},
		{"cfgbool", true, "cfgbool is not a flag: only flags can be overridden"},
		{"cfgint", 43, "cfgint is not a flag: only flags can be overridden"},
		{"cfgstring", "frood", "cfgstring is not a flag: only flags can be overridden"},
		{"flagbool", true, ""},
		{"flagint", 41, ""},
		{"flagstring", "towel", ""},
		{"bool", true, "bool is not a flag: only flags can be overridden"},
		{"int", 3, "int is not a flag: only flags can be overridden"},
		{"string", "don't panic", "string is not a flag: only flags can be overridden"},
	}
	testCfg := newTestSettings()
	for _, test := range tests {
		err := testCfg.Override(test.key, test.value)
		if err != nil {
			if err.Error() != test.expectedErr {
				t.Errorf("%s: expected error to be %q, got %q", test.key, test.expectedErr, err)
			}
			continue
		}
		if test.expectedErr != "" {
			t.Errorf("%s: expected error to be %q: got none", test.key, test.expectedErr)
			continue
		}
		v := testCfg.Get(test.key)
		if v != test.value {
			t.Errorf("%s: expected %v got %v", test.key, test.value, v)
		}
	}
}
<|endoftext|>


<commit_before>package main

import "flag"
import "fmt"
import "golang.org/x/net/context"
import "google.golang.org/grpc"
import "log"
import "math/rand"
import "strconv"
import "time"

import pb "github.com/brotherlogic/discogssyncer/server"
import pbd "github.com/brotherlogic/godiscogs"
import pbdi "github.com/brotherlogic/discovery/proto"
import pbc "github.com/brotherlogic/cardserver/card"

func getIP(servername string, ip string, port int) (string, int) {
	conn, _ := grpc.Dial(ip+":"+strconv.Itoa(port), grpc.WithInsecure())
	defer conn.Close()

	registry := pbdi.NewDiscoveryServiceClient(conn)
	entry := pbdi.RegistryEntry{Name: servername}
	r, _ := registry.Discover(context.Background(), &entry)
	return r.Ip, int(r.Port)
}

func getRelease(folderName string, host string, port string) *pbd.Release {

	log.Printf("Connecting to %v, %v", host, port)

	rand.Seed(time.Now().UTC().UnixNano())
	conn, err := grpc.Dial(host+":"+port, grpc.WithInsecure())
	defer conn.Close()
	client := pb.NewDiscogsServiceClient(conn)
	folder := &pbd.Folder{Name: folderName}

	r, err := client.GetReleasesInFolder(context.Background(), folder)
	if err != nil {
		log.Fatal("Problem getting releases %v", err)
	}

	log.Printf("RELEASES = %v from %v", rand.Intn(len(r.Releases)), len(r.Releases))
	return r.Releases[rand.Intn(len(r.Releases))]
}

func main() {
	var folder = flag.String("foldername", "", "Folder to retrieve from.")
	var host = flag.String("host", "10.0.1.17", "Hostname of server.")
	var port = flag.String("port", "50055", "Port number of server")
	flag.Parse()

	portVal, _ := strconv.Atoi(*port)
	dServer, dPort := getIP("discogssyncer", *host, portVal)

	rel := getRelease(*folder, dServer, strconv.Itoa(dPort))
	log.Printf("HERE %v", rel)
	fmt.Printf(pbd.GetReleaseArtist(*rel) + " - " + rel.Title)

	log.Printf("Writing Card: %v", rel)
	cServer, cPort := getIP("cardserver", *host, portVal)
	log.Printf("Writing to %v and %v", cServer, cPort)
	conn, err := grpc.Dial(cServer+":"+strconv.Itoa(cPort), grpc.WithInsecure())

	defer conn.Close()
	client := pbc.NewCardServiceClient(conn)
	cards := pbc.CardList{}

	imageURL := ""
	backupURL := ""
	for _, image := range rel.Images {
		if image.Type == "primary" {
			imageURL = image.Uri
		}
		backupURL = image.Uri
	}
	if imageURL == "" {
		imageURL = backupURL
	}

	card := pbc.Card{Text: pbd.GetReleaseArtist(*rel) + " - " + rel.Title, Hash: "discogs", Image: imageURL, Action: pbc.Card_DISMISS}
	log.Printf("Writing: %v", card)
	cards.Cards = append(cards.Cards, &card)
	_, err = client.AddCards(context.Background(), &cards)
	if err != nil {
		log.Printf("Problem adding cards %v", err)
	}
}
<commit_msg>Cleared extra output<commit_after>package main

import "flag"
import "golang.org/x/net/context"
import "google.golang.org/grpc"
import "log"
import "math/rand"
import "strconv"
import "time"

import pb "github.com/brotherlogic/discogssyncer/server"
import pbd "github.com/brotherlogic/godiscogs"
import pbdi "github.com/brotherlogic/discovery/proto"
import pbc "github.com/brotherlogic/cardserver/card"

func getIP(servername string, ip string, port int) (string, int) {
	conn, _ := grpc.Dial(ip+":"+strconv.Itoa(port), grpc.WithInsecure())
	defer conn.Close()

	registry := pbdi.NewDiscoveryServiceClient(conn)
	entry := pbdi.RegistryEntry{Name: servername}
	r, _ := registry.Discover(context.Background(), &entry)
	return r.Ip, int(r.Port)
}

func getRelease(folderName string, host string, port string) *pbd.Release {
	rand.Seed(time.Now().UTC().UnixNano())
	conn, err := grpc.Dial(host+":"+port, grpc.WithInsecure())
	defer conn.Close()
	client := pb.NewDiscogsServiceClient(conn)
	folder := &pbd.Folder{Name: folderName}

	r, err := client.GetReleasesInFolder(context.Background(), folder)
	if err != nil {
		log.Fatal("Problem getting releases %v", err)
	}

	return r.Releases[rand.Intn(len(r.Releases))]
}

func main() {
	var folder = flag.String("foldername", "", "Folder to retrieve from.")
	var host = flag.String("host", "10.0.1.17", "Hostname of server.")
	var port = flag.String("port", "50055", "Port number of server")
	flag.Parse()

	portVal, _ := strconv.Atoi(*port)
	dServer, dPort := getIP("discogssyncer", *host, portVal)

	rel := getRelease(*folder, dServer, strconv.Itoa(dPort))

	cServer, cPort := getIP("cardserver", *host, portVal)
	conn, err := grpc.Dial(cServer+":"+strconv.Itoa(cPort), grpc.WithInsecure())

	defer conn.Close()
	client := pbc.NewCardServiceClient(conn)
	cards := pbc.CardList{}

	imageURL := ""
	backupURL := ""
	for _, image := range rel.Images {
		if image.Type == "primary" {
			imageURL = image.Uri
		}
		backupURL = image.Uri
	}
	if imageURL == "" {
		imageURL = backupURL
	}

	card := pbc.Card{Text: pbd.GetReleaseArtist(*rel) + " - " + rel.Title, Hash: "discogs", Image: imageURL, Action: pbc.Card_DISMISS}
	cards.Cards = append(cards.Cards, &card)
	_, err = client.AddCards(context.Background(), &cards)
	if err != nil {
		log.Printf("Problem adding cards %v", err)
	}
}
<|endoftext|>


<commit_before>package main

// request arguments
type stopArgs struct {
	MachineId string `json:"machineId"`
}

// response type
type stopResult struct {
	State   string `json:"state"`
	EventId string `json:"eventId"`
}

func stopVm(machineId string) error {
	var result stopResult
	resp, err := KiteClient.Tell("stop", &stopArgs{MachineId: machineId})
	if err != nil {
		return err
	}

	if err := resp.Unmarshal(&result); err != nil {
		return err
	}

	return nil
}
<commit_msg>vmwatcher: no need to unmarshal response from kite<commit_after>package main

// request arguments
type stopArgs struct {
	MachineId string `json:"machineId"`
}

// response type
type stopResult struct {
	State   string `json:"state"`
	EventId string `json:"eventId"`
}

func stopVm(machineId string) error {
	_, err := KiteClient.Tell("stop", &stopArgs{MachineId: machineId})
	return err
}
<|endoftext|>


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

// Package kubernetes listens to Kubernetes for policy updates.
package kubernetes

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/romana/core/common"
	"github.com/romana/core/tenant"
	"io"
	"log"
	"net/http"
	"strings"
)

// readChunk reads the next chunk from the provided reader.
func readChunk(reader io.Reader) ([]byte, error) {
	var result []byte
	for {
		buf := make([]byte, bytes.MinRead)
		n, err := reader.Read(buf)
		if n < bytes.MinRead {
			result = append(result, buf[0:n]...)
			if err != nil {
				return result, err
			}
			break
		}
		result = append(result, buf...)
	}
	return result, nil
}

// listen connects to kubernetesURL and sends each
// chunk received to the ch channel. It exits on an
// error.
//func listen(ch chan []byte, kubernetesURL string) {
//	log.Printf("Listening to %s, currently %d goroutines are running", kubernetesURL, runtime.NumGoroutine())
//	resp, err := http.Get(kubernetesURL)
//	if err != nil {
//		log.Printf("Error connecting: %#v", err)
//		log.Println("Closing channel")
//		close(ch)
//		log.Println("Exiting goroutine")
//		return
//	}
//	//	chunkedReader := resp.Body
//	for {
//		chunk, err := readChunk(resp.Body)
//		if err != nil {
//			if err != io.EOF {
//				log.Printf("Error reading chunk: %#v", err)
//			}
//			if len(chunk) != 0 {
//				ch <- chunk
//			}
//			log.Println("Closing channel")
//			close(ch)
//			log.Println("Exiting goroutine")
//			return
//		}
//		if len(chunk) != 0 {
//			time.Sleep(1 * time.Millisecond)
//		} else {
//			ch <- chunk
//		}
//	}
//}

// processChunk processes a chunk received from Kubernetes. A chunk
// is a new update.
//func processChunk(chunk []byte) error {
//	m := make(map[string]interface{})
//	err := json.Unmarshal(chunk, &m)
//	if err != nil {
//		return err
//	}
//	method := m["method"]
//	if method == nil {
//		return errors.New("Expected 'method' field")
//	}
//	methodStr = strings.ToLower(method.(string))
//	networkPolicyIfc := m["policy_definition"]
//	if networkPolicyIfc == nil {
//		return errors.New("Expected 'policy_definition' field")
//	}
//	kubeNetworkPolicy := networkPolicyIfc.(map[string]interface{})
//	romanaNetworkPolicy, err := translateNetworkPolicy(kubeNetworkPolicy)
//	if err != nil {
//		return err
//	}
//
//	if methodStr == "added" {
//		applyNetworkPolicy(networkPolicyActionAdd, romanaNetworkPolicy)
//	} else if methodStr == "deleted" {
//		applyNetworkPolicy(networkPolicyActioDelete, romanaNetworkPolicy)
//	} else if methodStr == "modified" {
//		applyNetworkPolicy(networkPolicyActioModify, romanaNetworkPolicy)
//	} else {
//		return common.NewError("Unexpected method '%s'", methodStr)
//	}
//}

// Run implements the main loop, reconnecting as needed.
//func RunListener0(rootURL string, kubeURL string) {
//	l := kubeListener{kubeURL: kubeURL, restClient: common.NewRestClient(common.GetDefaultRestClientConfig(rootURL))}
//	l.Run()
//}
//
//func (l kubeListener) Run0() {
//	for {
//		ch := make(chan []byte)
//		go listen(ch, l.kubernetesURL)
//		for {
//			chunk, ok := <-ch
//			log.Println(ok)
//			if chunk != "" {
//				log.Printf("Read chunk %#v\n%s\n------------", ok, string(chunk))
//				err = processChunk(chunk)
//				if err != nil {
//					// TODO is there any other way to handle this?
//					log.Printf("Error processing chunk %s: %#v", string(chunk), err)
//				}
//			}
//			if !ok {
//				break
//			}
//		}
//	}
//}

/////////////////////////////////////////////////////////////

type networkPolicyAction int

const (
	networkPolicyActionDelete networkPolicyAction = iota
	networkPolicyActionAdd
	networkPolicyActionModify
)

// kubeListener is a Service that listens to updates
// from Kubernetes by connecting to the endpoints specified
// and consuming chunked JSON documents. The endpoints are
// constructed from kubeURL and the following paths:
// 1. namespaceNotificationPath for namespace additions/deletions
// 2. policyNotificationPathPrefix + <namespace name> + policyNotificationPathPostfix
//    for policy additions/deletions.
type kubeListener struct {
	config                        common.ServiceConfig
	restClient                    *common.RestClient
	kubeURL                       string
	namespaceNotificationPath     string
	policyNotificationPathPrefix  string
	policyNotificationPathPostfix string
	segmentLabelName              string
}

// Routes returns various routes used in the service.
func (l *kubeListener) Routes() common.Routes {
	routes := common.Routes{}
	return routes
}

// Name implements method of Service interface.
func (l *kubeListener) Name() string {
	return "kubernetesListener"
}

// SetConfig implements SetConfig function of the Service interface.
func (l *kubeListener) SetConfig(config common.ServiceConfig) error {
	m := config.ServiceSpecific
	if m["kubernetes_url"] == "" {
		return errors.New("kubernetes_url required")
	}
	l.kubeURL = m["kubernetes_url"].(string)

	if m["namespace_notification_path"] == "" {
		return errors.New("namespace_notification_path required")
	}
	l.namespaceNotificationPath = m["namespace_notification_path"].(string)

	if m["policy_notification_path_prefix"] == "" {
		return errors.New("policy_notification_path_prefix required")
	}
	l.policyNotificationPathPrefix = m["policy_notification_path_prefix"].(string)

	if m["policy_notification_path_postfix"] == "" {
		return errors.New("policy_notification_path_postfix required")
	}
	l.policyNotificationPathPostfix = m["policy_notification_path_postfix"].(string)

	if m["segment_label_name"] == "" {
		return errors.New("segment_label_name required")
	}
	l.segmentLabelName = m["segment_label_name"].(string)

	return nil
}

// Run configures and runs listener service.
func Run(rootServiceURL string, cred *common.Credential) (*common.RestServiceInfo, error) {
	clientConfig := common.GetDefaultRestClientConfig(rootServiceURL)
	clientConfig.Credential = cred
	client, err := common.NewRestClient(clientConfig)
	if err != nil {
		return nil, err
	}
	kubeListener := &kubeListener{}
	kubeListener.restClient = client
	config, err := client.GetServiceConfig(kubeListener.Name())
	if err != nil {
		return nil, err
	}
	return common.InitializeService(kubeListener, *config)
}

// getOrAddSegment finds a segment (based on segment selector).
// If not found, it adds one.
func (l *kubeListener) getOrAddSegment(tenantServiceURL string, namespace string, kubeSegmentID string) (*tenant.Segment, error) {
	segment := &tenant.Segment{}
	segmentsURL := fmt.Sprintf("%s/tenants/%s/segments", tenantServiceURL, namespace)
	err := l.restClient.Get(fmt.Sprintf("%s/%s", segmentsURL, kubeSegmentID), segment)
	if err == nil {
		return segment, nil
	}
	switch err := err.(type) {
	case common.HttpError:
		if err.StatusCode == http.StatusNotFound {
			// Not found, so let's create a segment.
			segreq := tenant.Segment{Name: kubeSegmentID, ExternalID: kubeSegmentID}
			err2 := l.restClient.Post(segmentsURL, segreq, segment)
			if err2 == nil {
				// Successful creation.
				return segment, nil
			}
			// Creation of non-existing segment gave an error.
			switch err2 := err2.(type) {
			case common.HttpError:
				// Maybe someone else just created a segment between the original
				// lookup and now?
				if err2.StatusCode == http.StatusConflict {
					switch details := err2.Details.(type) {
					case tenant.Segment:
						// We expect the existing segment to be returned in the details field.
						return &details, nil
					default:
						// This is unexpected...
						return nil, err
					}
				}
				// Any other HTTP error other than a Conflict here - return it.
				return nil, err2
			default:
				// Any other error - return it
				return nil, err2
			}
		}
		// Any other HTTP error other than a Not found here - return it
		return nil, err
	default:
		// Any other error - return it
		return nil, err
	}
}

// resolveTenantByName retrieves tenant information from romana.
func (l *kubeListener) resolveTenantByName(tenantName string) (*tenant.Tenant, string, error) {
	t := &tenant.Tenant{}
	tenantURL, err := l.restClient.GetServiceUrl("tenant")
	if err != nil {
		return t, "", err
	}

	err = l.restClient.Get(fmt.Sprintf("%s/tenants/%s", tenantURL, tenantName), t)
	if err != nil {
		return t, "", err
	}

	return t, tenantURL, nil
}

// translateNetworkPolicy translates a Kubernetes policy into
// Romana policy (see common.Policy) with the following rules:
// 1. Kubernetes Namespace corresponds to Romana Tenant
// 2. If Romana Tenant does not exist it is an error (a tenant should
//    automatically have been created when the namespace was added)
func (l *kubeListener) translateNetworkPolicy(kubePolicy *KubeObject) (common.Policy, error) {
	policyName := kubePolicy.Metadata.Name
	romanaPolicy := &common.Policy{Direction: common.PolicyDirectionIngress, Name: policyName, ExternalID: policyName}
	ns := kubePolicy.Metadata.Namespace
	// TODO actually look up tenant K8S ID.
	t, tenantURL, err := l.resolveTenantByName(ns)
	log.Printf("translateNetworkPolicy(): For namespace %s got %#v / %#v", ns, t, err)
	if err != nil {
		return *romanaPolicy, err
	}
	tenantID := t.ID
	tenantExternalID := t.ExternalID

	kubeSegmentID := kubePolicy.Spec.PodSelector[l.segmentLabelName]
	if kubeSegmentID == "" {
		return *romanaPolicy, common.NewError("Expected segment to be specified in podSelector part as '%s'", l.segmentLabelName)
	}

	segment, err := l.getOrAddSegment(tenantURL, ns, kubeSegmentID)
	if err != nil {
		return *romanaPolicy, err
	}
	segmentID := segment.ID
	appliedTo := common.Endpoint{TenantID: tenantID, SegmentID: segmentID}
	romanaPolicy.AppliedTo = make([]common.Endpoint, 1)
	romanaPolicy.AppliedTo[0] = appliedTo
	romanaPolicy.Peers = []common.Endpoint{}
	from := kubePolicy.Spec.AllowIncoming.From
	// This is subject to change once the network specification in Kubernetes is finalized.
	// Right now it is a work in progress.
	if from != nil {
		for _, entry := range from {
			pods := entry.Pods
			fromKubeSegmentID := pods[l.segmentLabelName]
			if fromKubeSegmentID == "" {
				return *romanaPolicy, common.NewError("Expected segment to be specified in podSelector part as '%s'", l.segmentLabelName)
			}
			fromSegment, err := l.getOrAddSegment(tenantURL, ns, fromKubeSegmentID)
			if err != nil {
				return *romanaPolicy, err
			}
			peer := common.Endpoint{TenantID: tenantID, TenantExternalID: tenantExternalID, SegmentID: fromSegment.ID, SegmentExternalID: fromSegment.ExternalID}
			romanaPolicy.Peers = append(romanaPolicy.Peers, peer)
		}
		toPorts := kubePolicy.Spec.AllowIncoming.ToPorts
		romanaPolicy.Rules = common.Rules{}
		for _, toPort := range toPorts {
			proto := strings.ToLower(toPort.Protocol)
			ports := []uint{toPort.Port}
			rule := common.Rule{Protocol: proto, Ports: ports}
			romanaPolicy.Rules = append(romanaPolicy.Rules, rule)
		}
	}
	err = romanaPolicy.Validate()
	if err != nil {
		return *romanaPolicy, err
	}
	return *romanaPolicy, nil
}

func (l *kubeListener) applyNetworkPolicy(action networkPolicyAction, romanaNetworkPolicy common.Policy) error {
	policyURL, err := l.restClient.GetServiceUrl("policy")
	if err != nil {
		return err
	}
	policyURL = fmt.Sprintf("%s/policies", policyURL)
	policyStr, _ := json.Marshal(romanaNetworkPolicy)
	switch action {
	case networkPolicyActionAdd:
		log.Printf("Applying policy %s", policyStr)
		err := l.restClient.Post(policyURL, romanaNetworkPolicy, &romanaNetworkPolicy)
		if err != nil {
			return err
		}
	case networkPolicyActionDelete:
		log.Printf("Deleting policy policy %s", policyStr)
		err := l.restClient.Delete(policyURL, romanaNetworkPolicy, &romanaNetworkPolicy)
		if err != nil {
			return err
		}
	default:
		return errors.New("Unsupported operation")
	}
	return nil
}

func (l *kubeListener) Initialize() error {
	log.Printf("%s: Starting server", l.Name())
	nsURL, err := common.CleanURL(fmt.Sprintf("%s%s", l.kubeURL, l.namespaceNotificationPath))
	if err != nil {
		return err
	}
	log.Printf("Starting to listen on %s", nsURL)
	done := make(chan Done)
	nsEvents, err := l.nsWatch(done, nsURL)
	if err != nil {
		log.Fatal("Namespace watcher failed to start", err)
	}

	events := l.conductor(nsEvents, done)
	l.process(events, done)
	log.Println("All routines started")
	return nil
}

// CreateSchema is placeholder for now.
func CreateSchema(rootServiceURL string, overwrite bool) error {
	return nil
}
<commit_msg>listener: remove commented code.<commit_after>// Copyright (c) 2016 Pani Networks
// All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

// Package kubernetes listens to Kubernetes for policy updates.
package kubernetes

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/romana/core/common"
	"github.com/romana/core/tenant"
	"io"
	"log"
	"net/http"
	"strings"
)

// readChunk reads the next chunk from the provided reader.
func readChunk(reader io.Reader) ([]byte, error) {
	var result []byte
	for {
		buf := make([]byte, bytes.MinRead)
		n, err := reader.Read(buf)
		if n < bytes.MinRead {
			result = append(result, buf[0:n]...)
			if err != nil {
				return result, err
			}
			break
		}
		result = append(result, buf...)
	}
	return result, nil
}

type networkPolicyAction int

const (
	networkPolicyActionDelete networkPolicyAction = iota
	networkPolicyActionAdd
	networkPolicyActionModify
)

// kubeListener is a Service that listens to updates
// from Kubernetes by connecting to the endpoints specified
// and consuming chunked JSON documents. The endpoints are
// constructed from kubeURL and the following paths:
// 1. namespaceNotificationPath for namespace additions/deletions
// 2. policyNotificationPathPrefix + <namespace name> + policyNotificationPathPostfix
//    for policy additions/deletions.
type kubeListener struct {
	config                        common.ServiceConfig
	restClient                    *common.RestClient
	kubeURL                       string
	namespaceNotificationPath     string
	policyNotificationPathPrefix  string
	policyNotificationPathPostfix string
	segmentLabelName              string
}

// Routes returns various routes used in the service.
func (l *kubeListener) Routes() common.Routes {
	routes := common.Routes{}
	return routes
}

// Name implements method of Service interface.
func (l *kubeListener) Name() string {
	return "kubernetesListener"
}

// SetConfig implements SetConfig function of the Service interface.
func (l *kubeListener) SetConfig(config common.ServiceConfig) error {
	m := config.ServiceSpecific
	if m["kubernetes_url"] == "" {
		return errors.New("kubernetes_url required")
	}
	l.kubeURL = m["kubernetes_url"].(string)

	if m["namespace_notification_path"] == "" {
		return errors.New("namespace_notification_path required")
	}
	l.namespaceNotificationPath = m["namespace_notification_path"].(string)

	if m["policy_notification_path_prefix"] == "" {
		return errors.New("policy_notification_path_prefix required")
	}
	l.policyNotificationPathPrefix = m["policy_notification_path_prefix"].(string)

	if m["policy_notification_path_postfix"] == "" {
		return errors.New("policy_notification_path_postfix required")
	}
	l.policyNotificationPathPostfix = m["policy_notification_path_postfix"].(string)

	if m["segment_label_name"] == "" {
		return errors.New("segment_label_name required")
	}
	l.segmentLabelName = m["segment_label_name"].(string)

	return nil
}

// Run configures and runs listener service.
func Run(rootServiceURL string, cred *common.Credential) (*common.RestServiceInfo, error) {
	clientConfig := common.GetDefaultRestClientConfig(rootServiceURL)
	clientConfig.Credential = cred
	client, err := common.NewRestClient(clientConfig)
	if err != nil {
		return nil, err
	}
	kubeListener := &kubeListener{}
	kubeListener.restClient = client
	config, err := client.GetServiceConfig(kubeListener.Name())
	if err != nil {
		return nil, err
	}
	return common.InitializeService(kubeListener, *config)
}

// getOrAddSegment finds a segment (based on segment selector).
// If not found, it adds one.
func (l *kubeListener) getOrAddSegment(tenantServiceURL string, namespace string, kubeSegmentID string) (*tenant.Segment, error) {
	segment := &tenant.Segment{}
	segmentsURL := fmt.Sprintf("%s/tenants/%s/segments", tenantServiceURL, namespace)
	err := l.restClient.Get(fmt.Sprintf("%s/%s", segmentsURL, kubeSegmentID), segment)
	if err == nil {
		return segment, nil
	}
	switch err := err.(type) {
	case common.HttpError:
		if err.StatusCode == http.StatusNotFound {
			// Not found, so let's create a segment.
			segreq := tenant.Segment{Name: kubeSegmentID, ExternalID: kubeSegmentID}
			err2 := l.restClient.Post(segmentsURL, segreq, segment)
			if err2 == nil {
				// Successful creation.
				return segment, nil
			}
			// Creation of non-existing segment gave an error.
			switch err2 := err2.(type) {
			case common.HttpError:
				// Maybe someone else just created a segment between the original
				// lookup and now?
				if err2.StatusCode == http.StatusConflict {
					switch details := err2.Details.(type) {
					case tenant.Segment:
						// We expect the existing segment to be returned in the details field.
						return &details, nil
					default:
						// This is unexpected...
						return nil, err
					}
				}
				// Any other HTTP error other than a Conflict here - return it.
				return nil, err2
			default:
				// Any other error - return it
				return nil, err2
			}
		}
		// Any other HTTP error other than a Not found here - return it
		return nil, err
	default:
		// Any other error - return it
		return nil, err
	}
}

// resolveTenantByName retrieves tenant information from romana.
func (l *kubeListener) resolveTenantByName(tenantName string) (*tenant.Tenant, string, error) {
	t := &tenant.Tenant{}
	tenantURL, err := l.restClient.GetServiceUrl("tenant")
	if err != nil {
		return t, "", err
	}

	err = l.restClient.Get(fmt.Sprintf("%s/tenants/%s", tenantURL, tenantName), t)
	if err != nil {
		return t, "", err
	}

	return t, tenantURL, nil
}

// translateNetworkPolicy translates a Kubernetes policy into
// Romana policy (see common.Policy) with the following rules:
// 1. Kubernetes Namespace corresponds to Romana Tenant
// 2. If Romana Tenant does not exist it is an error (a tenant should
//    automatically have been created when the namespace was added)
func (l *kubeListener) translateNetworkPolicy(kubePolicy *KubeObject) (common.Policy, error) {
	policyName := kubePolicy.Metadata.Name
	romanaPolicy := &common.Policy{Direction: common.PolicyDirectionIngress, Name: policyName, ExternalID: policyName}
	ns := kubePolicy.Metadata.Namespace
	// TODO actually look up tenant K8S ID.
	t, tenantURL, err := l.resolveTenantByName(ns)
	log.Printf("translateNetworkPolicy(): For namespace %s got %#v / %#v", ns, t, err)
	if err != nil {
		return *romanaPolicy, err
	}
	tenantID := t.ID
	tenantExternalID := t.ExternalID

	kubeSegmentID := kubePolicy.Spec.PodSelector[l.segmentLabelName]
	if kubeSegmentID == "" {
		return *romanaPolicy, common.NewError("Expected segment to be specified in podSelector part as '%s'", l.segmentLabelName)
	}

	segment, err := l.getOrAddSegment(tenantURL, ns, kubeSegmentID)
	if err != nil {
		return *romanaPolicy, err
	}
	segmentID := segment.ID
	appliedTo := common.Endpoint{TenantID: tenantID, SegmentID: segmentID}
	romanaPolicy.AppliedTo = make([]common.Endpoint, 1)
	romanaPolicy.AppliedTo[0] = appliedTo
	romanaPolicy.Peers = []common.Endpoint{}
	from := kubePolicy.Spec.AllowIncoming.From
	// This is subject to change once the network specification in Kubernetes is finalized.
	// Right now it is a work in progress.
	if from != nil {
		for _, entry := range from {
			pods := entry.Pods
			fromKubeSegmentID := pods[l.segmentLabelName]
			if fromKubeSegmentID == "" {
				return *romanaPolicy, common.NewError("Expected segment to be specified in podSelector part as '%s'", l.segmentLabelName)
			}
			fromSegment, err := l.getOrAddSegment(tenantURL, ns, fromKubeSegmentID)
			if err != nil {
				return *romanaPolicy, err
			}
			peer := common.Endpoint{TenantID: tenantID, TenantExternalID: tenantExternalID, SegmentID: fromSegment.ID, SegmentExternalID: fromSegment.ExternalID}
			romanaPolicy.Peers = append(romanaPolicy.Peers, peer)
		}
		toPorts := kubePolicy.Spec.AllowIncoming.ToPorts
		romanaPolicy.Rules = common.Rules{}
		for _, toPort := range toPorts {
			proto := strings.ToLower(toPort.Protocol)
			ports := []uint{toPort.Port}
			rule := common.Rule{Protocol: proto, Ports: ports}
			romanaPolicy.Rules = append(romanaPolicy.Rules, rule)
		}
	}
	err = romanaPolicy.Validate()
	if err != nil {
		return *romanaPolicy, err
	}
	return *romanaPolicy, nil
}

func (l *kubeListener) applyNetworkPolicy(action networkPolicyAction, romanaNetworkPolicy common.Policy) error {
	policyURL, err := l.restClient.GetServiceUrl("policy")
	if err != nil {
		return err
	}
	policyURL = fmt.Sprintf("%s/policies", policyURL)
	policyStr, _ := json.Marshal(romanaNetworkPolicy)
	switch action {
	case networkPolicyActionAdd:
		log.Printf("Applying policy %s", policyStr)
		err := l.restClient.Post(policyURL, romanaNetworkPolicy, &romanaNetworkPolicy)
		if err != nil {
			return err
		}
	case networkPolicyActionDelete:
		log.Printf("Deleting policy policy %s", policyStr)
		err := l.restClient.Delete(policyURL, romanaNetworkPolicy, &romanaNetworkPolicy)
		if err != nil {
			return err
		}
	default:
		return errors.New("Unsupported operation")
	}
	return nil
}

func (l *kubeListener) Initialize() error {
	log.Printf("%s: Starting server", l.Name())
	nsURL, err := common.CleanURL(fmt.Sprintf("%s%s", l.kubeURL, l.namespaceNotificationPath))
	if err != nil {
		return err
	}
	log.Printf("Starting to listen on %s", nsURL)
	done := make(chan Done)
	nsEvents, err := l.nsWatch(done, nsURL)
	if err != nil {
		log.Fatal("Namespace watcher failed to start", err)
	}

	events := l.conductor(nsEvents, done)
	l.process(events, done)
	log.Println("All routines started")
	return nil
}

// CreateSchema is placeholder for now.
func CreateSchema(rootServiceURL string, overwrite bool) error {
	return nil
}
<|endoftext|>


<commit_before>package apidApigeeSync

import (
	"database/sql"
	"github.com/30x/apid"
	"github.com/apigee-labs/transicator/common"
)

type handler struct {
}

func (h *handler) String() string {
	return "ApigeeSync"
}

// todo: The following was basically just copied from old APID - needs review.

func (h *handler) Handle(e apid.Event) {

	snapData, ok := e.(*common.Snapshot)
	if ok {
		processSnapshot(snapData)
	} else {
		changeSet, ok := e.(*common.ChangeList)
		if ok {
			processChange(changeSet)
		} else {
			log.Errorf("Received Invalid event. This shouldn't happen!")
		}
	}
	return
}

func processSnapshot(snapshot *common.Snapshot) {

	log.Debugf("Process Snapshot data")

	db, err := data.DB()
	if err != nil {
		panic("Unable to access Sqlite DB")
	}

	for _, payload := range snapshot.Tables {

		switch payload.Name {
		case "edgex.apid_config":
			for _, row := range payload.Rows {
				insertApidConfig(row, db, snapshot.SnapshotInfo)
			}
		case "edgex.apid_config_scope":
			insertApidConfigScopes(payload.Rows, db)
		}
	}
}

func processChange(changes *common.ChangeList) {

	log.Debugf("apigeeSyncEvent: %d changes", len(changes.Changes))
	var rows []common.Row
	db, err := data.DB()
	if err != nil {
		panic("Unable to access Sqlite DB")
	}

	for _, payload := range changes.Changes {
		rows = nil
		switch payload.Table {
		case "edgex.apid_config_scope":
			switch payload.Operation {
			case 1:
				rows = append(rows, payload.NewRow)
				insertApidConfigScopes(rows, db)
			}
		}
	}
}

/*
 * INSERT INTO APP_CREDENTIAL op
 */
func insertApidConfig(ele common.Row, db *sql.DB, snapInfo string) bool {

	var scope, id, name, orgAppName, createdBy, updatedBy, Description string
	var updated, created int64

	prep, err := db.Prepare("INSERT INTO APID_CONFIG (id, _apid_scope, name, umbrella_org_app_name, created, created_by, updated, updated_by, snapshotInfo)VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9);")
	if err != nil {
		log.Error("INSERT APID_CONFIG Failed: ", err)
		return false
	}

	txn, err := db.Begin()

	ele.Get("id", &id)
	ele.Get("_apid_scope", &scope)
	ele.Get("name", &name)
	ele.Get("umbrella_org_app_name", &orgAppName)
	ele.Get("created", &created)
	ele.Get("created_by", &createdBy)
	ele.Get("updated", &updated)
	ele.Get("updated_by", &updatedBy)
	ele.Get("description", &Description)

	_, err = txn.Stmt(prep).Exec(
		id,
		scope,
		name,
		orgAppName,
		created,
		createdBy,
		updated,
		updatedBy,
		snapInfo)

	if err != nil {
		log.Error("INSERT APID_CONFIG Failed: ", id, ", ", scope, ")", err)
		txn.Rollback()
		return false
	} else {
		log.Info("INSERT APID_CONFIG Success: (", id, ", ", scope, ")")
		txn.Commit()
		return true
	}

}

/*
 * INSERT INTO APP_CREDENTIAL op
 */
func insertApidConfigScopes(rows []common.Row, db *sql.DB) bool {

	var id, scopeId, apiConfigId, scope, createdBy, updatedBy string
	var created, updated int64

	prep, err := db.Prepare("INSERT INTO APID_CONFIG_SCOPE (id, _apid_scope, apid_config_id, scope, created, created_by, updated, updated_by)VALUES($1,$2,$3,$4,$5,$6,$7,$8);")
	if err != nil {
		log.Error("INSERT APID_CONFIG_SCOPE Failed: ", err)
		return false
	}

	txn, err := db.Begin()
	for _, ele := range rows {

		ele.Get("id", &id)
		ele.Get("_apid_scope", &scopeId)
		ele.Get("apid_config_id", &apiConfigId)
		ele.Get("scope", &scope)
		ele.Get("created", &created)
		ele.Get("created_by", &createdBy)
		ele.Get("updated", &updated)
		ele.Get("updated_by", &updatedBy)

		_, err = txn.Stmt(prep).Exec(
			id,
			scopeId,
			apiConfigId,
			scope,
			created,
			createdBy,
			updated,
			updatedBy)

		if err != nil {
			log.Error("INSERT APID_CONFIG_SCOPE Failed: ", id, ", ", scope, ")", err)
			txn.Rollback()
			return false
		} else {
			log.Info("INSERT APID_CONFIG_SCOPE Success: (", id, ", ", scope, ")")
		}
	}
	txn.Commit()
	return true
}
<commit_msg>Code refactor.<commit_after>package apidApigeeSync

import (
	"database/sql"
	"github.com/30x/apid"
	"github.com/apigee-labs/transicator/common"
)

type handler struct {
}

func (h *handler) String() string {
	return "ApigeeSync"
}

// todo: The following was basically just copied from old APID - needs review.

func (h *handler) Handle(e apid.Event) {

	res := true

	db, err := data.DB()
	if err != nil {
		panic("Unable to access Sqlite DB")
	}
	txn, err := db.Begin()
	if err != nil {
		log.Error("Unable to create Sqlite transaction")
		return
	}

	snapData, ok := e.(*common.Snapshot)
	if ok {
		res = processSnapshot(snapData, db, txn)
	} else {
		changeSet, ok := e.(*common.ChangeList)
		if ok {
			res = processChange(changeSet, db, txn)
		} else {
			log.Fatal("Received Invalid event. This shouldn't happen!")
		}
	}
	if res == true {
		txn.Commit()
	} else {
		txn.Rollback()
	}
	return
}

func processSnapshot(snapshot *common.Snapshot, db *sql.DB, txn *sql.Tx) bool {

	log.Debugf("Process Snapshot data")
	res := true

	for _, payload := range snapshot.Tables {

		switch payload.Name {
		case "edgex.apid_config":
			res = insertApidConfig(payload.Rows, db, txn, snapshot.SnapshotInfo)
		case "edgex.apid_config_scope":
			res = insertApidConfigScopes(payload.Rows, db, txn)
		}
		if res == false {
			log.Error("Error encountered in Downloading Snapshot for ApidApigeeSync")
			return res
		}
	}
	return res
}

func processChange(changes *common.ChangeList, db *sql.DB, txn *sql.Tx) bool {

	log.Debugf("apigeeSyncEvent: %d changes", len(changes.Changes))
	var rows []common.Row
	res := true

	for _, payload := range changes.Changes {
		rows = nil
		switch payload.Table {
		case "edgex.apid_config_scope":
			switch payload.Operation {
			case common.Insert:
				rows = append(rows, payload.NewRow)
				res = insertApidConfigScopes(rows, db, txn)
			}
		}
		if res == false {
			log.Error("Sql Operation error. Operation rollbacked")
			return res
		}
	}
	return res
}

/*
 * INSERT INTO APP_CREDENTIAL op
 */
func insertApidConfig(rows []common.Row, db *sql.DB, txn *sql.Tx, snapInfo string) bool {

	var scope, id, name, orgAppName, createdBy, updatedBy, Description string
	var updated, created int64

	prep, err := db.Prepare("INSERT INTO APID_CONFIG (id, _apid_scope, name, umbrella_org_app_name, created, created_by, updated, updated_by, snapshotInfo)VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9);")
	if err != nil {
		log.Error("INSERT APID_CONFIG Failed: ", err)
		return false
	}
	defer prep.Close()

	for _, ele := range rows {
		ele.Get("id", &id)
		ele.Get("_apid_scope", &scope)
		ele.Get("name", &name)
		ele.Get("umbrella_org_app_name", &orgAppName)
		ele.Get("created", &created)
		ele.Get("created_by", &createdBy)
		ele.Get("updated", &updated)
		ele.Get("updated_by", &updatedBy)
		ele.Get("description", &Description)

		_, err = txn.Stmt(prep).Exec(
			id,
			scope,
			name,
			orgAppName,
			created,
			createdBy,
			updated,
			updatedBy,
			snapInfo)

		if err != nil {
			log.Error("INSERT APID_CONFIG Failed: ", id, ", ", scope, ")", err)
			return false
		} else {
			log.Info("INSERT APID_CONFIG Success: (", id, ", ", scope, ")")
		}
	}
	return true
}

/*
 * INSERT INTO APP_CREDENTIAL op
 */
func insertApidConfigScopes(rows []common.Row, db *sql.DB, txn *sql.Tx) bool {

	var id, scopeId, apiConfigId, scope, createdBy, updatedBy string
	var created, updated int64

	prep, err := db.Prepare("INSERT INTO APID_CONFIG_SCOPE (id, _apid_scope, apid_config_id, scope, created, created_by, updated, updated_by)VALUES($1,$2,$3,$4,$5,$6,$7,$8);")
	if err != nil {
		log.Error("INSERT APID_CONFIG_SCOPE Failed: ", err)
		return false
	}
	defer prep.Close()

	for _, ele := range rows {

		ele.Get("id", &id)
		ele.Get("_apid_scope", &scopeId)
		ele.Get("apid_config_id", &apiConfigId)
		ele.Get("scope", &scope)
		ele.Get("created", &created)
		ele.Get("created_by", &createdBy)
		ele.Get("updated", &updated)
		ele.Get("updated_by", &updatedBy)

		_, err = txn.Stmt(prep).Exec(
			id,
			scopeId,
			apiConfigId,
			scope,
			created,
			createdBy,
			updated,
			updatedBy)

		if err != nil {
			log.Error("INSERT APID_CONFIG_SCOPE Failed: ", id, ", ", scope, ")", err)
			return false
		} else {
			log.Info("INSERT APID_CONFIG_SCOPE Success: (", id, ", ", scope, ")")
		}
	}
	return true
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"path"
	"runtime"
)

func allMaps() map[string]string {
	savesDir := ""
	switch runtime.GOOS {
	case "linux":
		savesDir = fmt.Sprintf("%s/.minecraft/saves", os.Getenv("HOME"))
	case "darwin":
		savesDir = fmt.Sprintf("%s/Library/Application Support/minecraft/saves", os.Getenv("HOME"))
	case "windows":
		savesDir = fmt.Sprintf(`%s\.minecraft`, os.Getenv("appdata"))
	default:
		return nil
	}

	f, err := os.Open(savesDir)
	if err != nil {
		return nil
	}
	defer f.Close()
	fi, err := f.Stat()
	if (err != nil) || (!fi.IsDir()) {
		return nil
	}

	infos, err := f.Readdir(-1)
	if err != nil {
		return nil
	}

	maps := make(map[string]string)
	for _, info := range infos {
		if !info.IsDir() {
			continue
		}
		p := path.Join(savesDir, info.Name())

		fi, err := os.Stat(path.Join(p, "level.dat"))
		if (err != nil) || (!fi.Mode().IsRegular()) {
			continue
		}

		maps[info.Name()] = path.Join(p, "region")
	}

	return maps
}
<commit_msg>Fixed savesDir for windows<commit_after>package main

import (
	"fmt"
	"os"
	"path"
	"runtime"
)

func allMaps() map[string]string {
	savesDir := ""
	switch runtime.GOOS {
	case "linux":
		savesDir = fmt.Sprintf("%s/.minecraft/saves", os.Getenv("HOME"))
	case "darwin":
		savesDir = fmt.Sprintf("%s/Library/Application Support/minecraft/saves", os.Getenv("HOME"))
	case "windows":
		savesDir = fmt.Sprintf(`%s\.minecraft\saves`, os.Getenv("appdata"))
	default:
		return nil
	}

	f, err := os.Open(savesDir)
	if err != nil {
		return nil
	}
	defer f.Close()
	fi, err := f.Stat()
	if (err != nil) || (!fi.IsDir()) {
		return nil
	}

	infos, err := f.Readdir(-1)
	if err != nil {
		return nil
	}

	maps := make(map[string]string)
	for _, info := range infos {
		if !info.IsDir() {
			continue
		}
		p := path.Join(savesDir, info.Name())

		fi, err := os.Stat(path.Join(p, "level.dat"))
		if (err != nil) || (!fi.Mode().IsRegular()) {
			continue
		}

		maps[info.Name()] = path.Join(p, "region")
	}

	return maps
}
<|endoftext|>


<commit_before>package raft

import (
	"bytes"
	"fmt"
	"reflect"
	"strconv"
	"testing"
)

// Log with 10 entries with terms as shown in Figure 7, leader line
func makeLogTerms_Figure7LeaderLine() []TermNo {
	return []TermNo{1, 1, 1, 4, 4, 5, 5, 6, 6, 6}
}

// Helper
func testCommandEquals(c Command, s string) bool {
	return bytes.Equal(c, Command(s))
}

// Blackbox test
// Send a Log with 10 entries with terms as shown in Figure 7, leader line
func PartialTest_Log_BlackboxTest(t *testing.T, log Log) {
	// Initial data tests
	if log.GetIndexOfLastEntry() != 10 {
		t.Fatal()
	}
	if log.GetTermAtIndex(10) != 6 {
		t.Fatal()
	}

	// get entry test
	le := log.GetLogEntryAtIndex(10)
	if le.TermNo != 6 {
		t.Fatal(le.TermNo)
	}
	if !testCommandEquals(le.Command, "c10") {
		t.Fatal(le.Command)
	}

	var logEntries []LogEntry

	// set test - invalid index
	logEntries = []LogEntry{{8, Command("c12")}}
	{
		stopThePanic := true
		defer func() {
			if stopThePanic {
				if recover() == nil {
					t.Fatal()
				}
			}
		}()
		log.SetEntriesAfterIndex(11, logEntries)
		stopThePanic = false
		t.Fatal()
	}

	// set test - no replacing
	logEntries = []LogEntry{{7, Command("c11")}, {8, Command("c12")}}
	log.SetEntriesAfterIndex(10, logEntries)
	if log.GetIndexOfLastEntry() != 12 {
		t.Fatal()
	}
	le = log.GetLogEntryAtIndex(12)
	if !reflect.DeepEqual(le, LogEntry{8, Command("c12")}) {
		t.Fatal(le)
	}

	// set test - partial replacing
	logEntries = []LogEntry{{7, Command("c11")}, {9, Command("c12")}, {9, Command("c13'")}}
	log.SetEntriesAfterIndex(10, logEntries)
	if log.GetIndexOfLastEntry() != 13 {
		t.Fatal()
	}
	le = log.GetLogEntryAtIndex(12)
	if !reflect.DeepEqual(le, LogEntry{9, Command("c12")}) {
		t.Fatal(le)
	}

	// set test - no new entries with empty slice
	logEntries = []LogEntry{}
	log.SetEntriesAfterIndex(3, logEntries)
	if log.GetIndexOfLastEntry() != 3 {
		t.Fatal()
	}
	le = log.GetLogEntryAtIndex(3)
	if !reflect.DeepEqual(le, LogEntry{1, Command("c3")}) {
		t.Fatal(le)
	}

	// set test - delete all entries; no new entries with nil
	log.SetEntriesAfterIndex(0, nil)
	if log.GetIndexOfLastEntry() != 0 {
		t.Fatal()
	}

}

// In-memory implementation of LogEntries - meant only for tests
type inMemoryLog struct {
	entries []LogEntry
}

func (imle *inMemoryLog) GetIndexOfLastEntry() LogIndex {
	return LogIndex(len(imle.entries))
}

func (imle *inMemoryLog) GetTermAtIndex(li LogIndex) TermNo {
	return imle.entries[li-1].TermNo
}

func (imle *inMemoryLog) GetLogEntryAtIndex(li LogIndex) LogEntry {
	return imle.entries[li-1]
}

func (imle *inMemoryLog) SetEntriesAfterIndex(li LogIndex, entries []LogEntry) {
	iole := imle.GetIndexOfLastEntry()
	if iole < li {
		panic(fmt.Sprintf("inMemoryLog: setEntriesAfterIndex(%d, ...) but iole=%d", li, iole))
	}
	// delete entries after index
	if iole > li {
		imle.entries = imle.entries[:li]
	}
	// append entries
	imle.entries = append(imle.entries, entries...)
}

func newIMLEWithDummyCommands(logTerms []TermNo) *inMemoryLog {
	imle := new(inMemoryLog)
	entries := []LogEntry{}
	for i, term := range logTerms {
		entries = append(entries, LogEntry{term, Command("c" + strconv.Itoa(i+1))})
	}
	imle.entries = entries
	return imle
}

// Run the blackbox test on inMemoryLog
func TestInMemoryLogEntries(t *testing.T) {
	// Log with 10 entries with terms as shown in Figure 7, leader line
	terms := makeLogTerms_Figure7LeaderLine()
	imle := newIMLEWithDummyCommands(terms)
	PartialTest_Log_BlackboxTest(t, imle)
}
<commit_msg>Add checks to inMemoryLog.GetTermAtIndex<commit_after>package raft

import (
	"bytes"
	"fmt"
	"reflect"
	"strconv"
	"testing"
)

// Log with 10 entries with terms as shown in Figure 7, leader line
func makeLogTerms_Figure7LeaderLine() []TermNo {
	return []TermNo{1, 1, 1, 4, 4, 5, 5, 6, 6, 6}
}

// Helper
func testCommandEquals(c Command, s string) bool {
	return bytes.Equal(c, Command(s))
}

// Blackbox test
// Send a Log with 10 entries with terms as shown in Figure 7, leader line
func PartialTest_Log_BlackboxTest(t *testing.T, log Log) {
	// Initial data tests
	if log.GetIndexOfLastEntry() != 10 {
		t.Fatal()
	}
	if log.GetTermAtIndex(10) != 6 {
		t.Fatal()
	}

	// get entry test
	le := log.GetLogEntryAtIndex(10)
	if le.TermNo != 6 {
		t.Fatal(le.TermNo)
	}
	if !testCommandEquals(le.Command, "c10") {
		t.Fatal(le.Command)
	}

	var logEntries []LogEntry

	// set test - invalid index
	logEntries = []LogEntry{{8, Command("c12")}}
	{
		stopThePanic := true
		defer func() {
			if stopThePanic {
				if recover() == nil {
					t.Fatal()
				}
			}
		}()
		log.SetEntriesAfterIndex(11, logEntries)
		stopThePanic = false
		t.Fatal()
	}

	// set test - no replacing
	logEntries = []LogEntry{{7, Command("c11")}, {8, Command("c12")}}
	log.SetEntriesAfterIndex(10, logEntries)
	if log.GetIndexOfLastEntry() != 12 {
		t.Fatal()
	}
	le = log.GetLogEntryAtIndex(12)
	if !reflect.DeepEqual(le, LogEntry{8, Command("c12")}) {
		t.Fatal(le)
	}

	// set test - partial replacing
	logEntries = []LogEntry{{7, Command("c11")}, {9, Command("c12")}, {9, Command("c13'")}}
	log.SetEntriesAfterIndex(10, logEntries)
	if log.GetIndexOfLastEntry() != 13 {
		t.Fatal()
	}
	le = log.GetLogEntryAtIndex(12)
	if !reflect.DeepEqual(le, LogEntry{9, Command("c12")}) {
		t.Fatal(le)
	}

	// set test - no new entries with empty slice
	logEntries = []LogEntry{}
	log.SetEntriesAfterIndex(3, logEntries)
	if log.GetIndexOfLastEntry() != 3 {
		t.Fatal()
	}
	le = log.GetLogEntryAtIndex(3)
	if !reflect.DeepEqual(le, LogEntry{1, Command("c3")}) {
		t.Fatal(le)
	}

	// set test - delete all entries; no new entries with nil
	log.SetEntriesAfterIndex(0, nil)
	if log.GetIndexOfLastEntry() != 0 {
		t.Fatal()
	}

}

// In-memory implementation of LogEntries - meant only for tests
type inMemoryLog struct {
	entries []LogEntry
}

func (imle *inMemoryLog) GetIndexOfLastEntry() LogIndex {
	return LogIndex(len(imle.entries))
}

func (imle *inMemoryLog) GetTermAtIndex(li LogIndex) TermNo {
	if li == 0 {
		panic("GetTermAtIndex(): li=0")
	}
	if li > LogIndex(len(imle.entries)) {
		panic(fmt.Sprintf("GetTermAtIndex(): li=%v > iole=%v", li, len(imle.entries)))
	}
	return imle.entries[li-1].TermNo
}

func (imle *inMemoryLog) GetLogEntryAtIndex(li LogIndex) LogEntry {
	return imle.entries[li-1]
}

func (imle *inMemoryLog) SetEntriesAfterIndex(li LogIndex, entries []LogEntry) {
	iole := imle.GetIndexOfLastEntry()
	if iole < li {
		panic(fmt.Sprintf("inMemoryLog: setEntriesAfterIndex(%d, ...) but iole=%d", li, iole))
	}
	// delete entries after index
	if iole > li {
		imle.entries = imle.entries[:li]
	}
	// append entries
	imle.entries = append(imle.entries, entries...)
}

func newIMLEWithDummyCommands(logTerms []TermNo) *inMemoryLog {
	imle := new(inMemoryLog)
	entries := []LogEntry{}
	for i, term := range logTerms {
		entries = append(entries, LogEntry{term, Command("c" + strconv.Itoa(i+1))})
	}
	imle.entries = entries
	return imle
}

// Run the blackbox test on inMemoryLog
func TestInMemoryLogEntries(t *testing.T) {
	// Log with 10 entries with terms as shown in Figure 7, leader line
	terms := makeLogTerms_Figure7LeaderLine()
	imle := newIMLEWithDummyCommands(terms)
	PartialTest_Log_BlackboxTest(t, imle)
}
<|endoftext|>


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

package main

import (
	"bytes"
	"encoding/hex"
	"fmt"
	"github.com/jacobsa/comeback/blob"
	"github.com/jacobsa/comeback/blob/disk"
	"github.com/jacobsa/comeback/fs"
	"github.com/jacobsa/comeback/repr"
	"github.com/jacobsa/comeback/sys"
	"io"
	"log"
	"os"
	"path"
	"syscall"
	"time"
)

const (
	gTarget = "/tmp/restore_target"
)

var blobStore blob.Store

func fromHexHash(h string) (blob.Score, error) {
	b, err := hex.DecodeString(h)
	if err != nil {
		return nil, fmt.Errorf("Invalid hex string: %s", h)
	}

	return blob.Score(b), nil
}

func chooseUserId(uid sys.UserId, username *string) (sys.UserId, error) {
	// If there is no symbolic username, just return the UID.
	if username == nil {
		return uid, nil
	}

	// Create a user registry.
	registry, err := sys.NewUserRegistry()
	if err != nil {
		return 0, fmt.Errorf("Creating user registry: %v", err)
	}

	// Attempt to look up the username. If it's not found, return the UID.
	betterUid, err := registry.FindByName(*username)

	if _, ok := err.(sys.NotFoundError); ok {
		return uid, nil
	} else if err != nil {
		return 0, fmt.Errorf("Looking up user: %v", err)
	}

	return betterUid, nil
}

func chooseGroupId(gid sys.GroupId, groupname *string) (sys.GroupId, error) {
	// If there is no symbolic groupname, just return the GID.
	if groupname == nil {
		return gid, nil
	}

	// Create a group registry.
	registry, err := sys.NewGroupRegistry()
	if err != nil {
		return 0, fmt.Errorf("Creating group registry: %v", err)
	}

	// Attempt to look up the groupname. If it's not found, return the GID.
	betterGid, err := registry.FindByName(*groupname)

	if _, ok := err.(sys.NotFoundError); ok {
		return gid, nil
	} else if err != nil {
		return 0, fmt.Errorf("Looking up group: %v", err)
	}

	return betterGid, nil
}

// Set the modification time for the supplied path without following symlinks
// (as syscall.Chtimes and therefore os.Chtimes do).
//
// c.f. http://stackoverflow.com/questions/10608724/set-modification-date-on-symbolic-link-in-cocoa
func setModTime(path string, mtime time.Time) error {
	// Open the file without following symlinks. Use O_NONBLOCK to allow opening
	// of named pipes without a writer.
	fd, err := syscall.Open(path, syscall.O_NONBLOCK|syscall.O_SYMLINK, 0)
	if err != nil {
		return err
	}

	defer syscall.Close(fd)

	// Call futimes.
	var utimes [2]syscall.Timeval
	atime := time.Now()
	atime_ns := atime.Unix()*1e9 + int64(atime.Nanosecond())
	mtime_ns := mtime.Unix()*1e9 + int64(mtime.Nanosecond())
	utimes[0] = syscall.NsecToTimeval(atime_ns)
	utimes[1] = syscall.NsecToTimeval(mtime_ns)

	err = syscall.Futimes(fd, utimes[0:])
	if err != nil {
		return err
	}

	return nil
}

// Restore the file whose contents are described by the referenced blobs to the
// supplied target, whose parent must already exist.
func restoreFile(target string, scores []blob.Score) error {
	// Open the file.
	//
	// TODO(jacobsa): Fix permissions race condition here, since we create the
	// file with 0666.
	f, err := os.Create(target)
	defer f.Close()

	if err != nil {
		return fmt.Errorf("Create: %v", err)
	}

	// Process each blob.
	for _, score := range scores {
		// Load the blob.
		blob, err := blobStore.Load(score)
		if err != nil {
			return fmt.Errorf("Loading blob: %v", err)
		}

		// Write out its contents.
		_, err = io.Copy(f, bytes.NewReader(blob))
		if err != nil {
			return fmt.Errorf("Copy: %v", err)
		}
	}

	return nil
}

// Like os.Chmod, but don't follow symlinks.
func setPermissions(path string, permissions os.FileMode) error {
	mode := syscallPermissions(permissions)

	// Open the file without following symlinks. Use O_NONBLOCK to allow opening
	// of named pipes without a writer.
	fd, err := syscall.Open(path, syscall.O_NONBLOCK|syscall.O_SYMLINK, 0)
	if err != nil {
		return err
	}

	defer syscall.Close(fd)

	// Call fchmod.
	err = syscall.Fchmod(fd, mode)
	if err != nil {
		return err
	}

	return nil
}

// Restore the directory whose contents are described by the referenced blob to
// the supplied target, which must already exist.
func restoreDir(basePath, relPath string, score blob.Score) error {
	// Load the appropriate blob.
	blob, err := blobStore.Load(score)
	if err != nil {
		return fmt.Errorf("Loading blob: %v", err)
	}

	// Parse its contents.
	entries, err := repr.Unmarshal(blob)
	if err != nil {
		return fmt.Errorf("Parsing blob: %v", err)
	}

	// Deal with each entry.
	for _, entry := range entries {
		entryRelPath := path.Join(relPath, entry.Name)
		entryFullPath := path.Join(basePath, entryRelPath)

		// Switch on type.
		switch entry.Type {
		case fs.TypeFile:
			// Is this a hard link to another file?
			if entry.HardLinkTarget != nil {
				// Create the hard link.
				targetFullPath := path.Join(basePath, *entry.HardLinkTarget)
				if err := os.Link(targetFullPath, entryFullPath); err != nil {
					return fmt.Errorf("os.Link: %v", err)
				}
			} else {
				// Create the file using its blobs.
				if err := restoreFile(entryFullPath, entry.Scores); err != nil {
					return fmt.Errorf("restoreFile: %v", err)
				}
			}

		case fs.TypeDirectory:
			if len(entry.Scores) != 1 {
				return fmt.Errorf("Wrong number of scores: %v", entry)
			}

			if err = os.Mkdir(entryFullPath, 0700); err != nil {
				return fmt.Errorf("Mkdir: %v", err)
			}

			if err = restoreDir(basePath, entryRelPath, entry.Scores[0]); err != nil {
				return fmt.Errorf("restoreDir: %v", err)
			}

		case fs.TypeSymlink:
			err = os.Symlink(entry.Target, entryFullPath)
			if err != nil {
				return fmt.Errorf("Symlink: %v", err)
			}

		case fs.TypeNamedPipe:
			err = makeNamedPipe(entryFullPath, entry.Permissions)
			if err != nil {
				return fmt.Errorf("makeNamedPipe: %v", err)
			}

		case fs.TypeBlockDevice:
			err = makeBlockDevice(entryFullPath, entry.Permissions, entry.DeviceNumber)
			if err != nil {
				return fmt.Errorf("makeBlockDevice: %v", err)
			}

		case fs.TypeCharDevice:
			err = makeCharDevice(entryFullPath, entry.Permissions, entry.DeviceNumber)
			if err != nil {
				return fmt.Errorf("makeCharDevice: %v", err)
			}

		default:
			return fmt.Errorf("Don't know how to deal with entry: %v", entry)
		}

		// Fix ownership.
		uid, err := chooseUserId(entry.Uid, entry.Username)
		if err != nil {
			return fmt.Errorf("chooseUserId: %v", err)
		}

		gid, err := chooseGroupId(entry.Gid, entry.Groupname)
		if err != nil {
			return fmt.Errorf("chooseGroupId: %v", err)
		}

		if err = os.Lchown(entryFullPath, int(uid), int(gid)); err != nil {
			return fmt.Errorf("Chown: %v", err)
		}

		// Fix permissions, but not on devices (otherwise we get resource busy
		// errors).
		if entry.Type != fs.TypeBlockDevice && entry.Type != fs.TypeCharDevice {
			if err := setPermissions(entryFullPath, entry.Permissions); err != nil {
				return fmt.Errorf("setPermissions(%s): %v", entryFullPath, err)
			}
		}

		// Fix modification time, but not on devices (otherwise we get resource
		// busy errors).
		if entry.Type != fs.TypeBlockDevice && entry.Type != fs.TypeCharDevice {
			if err = setModTime(entryFullPath, entry.MTime); err != nil {
				return fmt.Errorf("setModTime(%s): %v", entryFullPath, err)
			}
		}
	}

	return nil
}

func syscallPermissions(permissions os.FileMode) (o uint32) {
	// Include r/w/x permission bits.
	o = uint32(permissions & os.ModePerm)

	// Also include setuid/setgid/sticky bits.
	if permissions&os.ModeSetuid != 0 {
		o |= syscall.S_ISUID
	}

	if permissions&os.ModeSetgid != 0 {
		o |= syscall.S_ISGID
	}

	if permissions&os.ModeSticky != 0 {
		o |= syscall.S_ISVTX
	}

	return
}

// Create a named pipe at the supplied path.
func makeNamedPipe(path string, permissions os.FileMode) error {
	return syscall.Mkfifo(path, syscallPermissions(permissions))
}

// Create a block device at the supplied path.
func makeBlockDevice(path string, permissions os.FileMode, dev int32) error {
	mode := syscallPermissions(permissions) | syscall.S_IFBLK
	if err := syscall.Mknod(path, mode, int(dev)); err != nil {
		return fmt.Errorf("syscall.Mknod: %v", err)
	}

	return nil
}

// Create a character device at the supplied path.
func makeCharDevice(path string, permissions os.FileMode, dev int32) error {
	mode := syscallPermissions(permissions) | syscall.S_IFCHR
	if err := syscall.Mknod(path, mode, int(dev)); err != nil {
		return fmt.Errorf("syscall.Mknod: %v", err)
	}

	return nil
}

func main() {
	var err error

	// Create a user registry.
	userRegistry, err := sys.NewUserRegistry()
	if err != nil {
		log.Fatalf("Creating user registry: %v", err)
	}

	// Create a group registry.
	groupRegistry, err := sys.NewGroupRegistry()
	if err != nil {
		log.Fatalf("Creating group registry: %v", err)
	}

	// Create a file system.
	fileSystem, err := fs.NewFileSystem(userRegistry, groupRegistry)
	if err != nil {
		log.Fatalf("Creating file system: %v", err)
	}

	// Create the blob store.
	blobStore, err = disk.NewDiskBlobStore("/tmp/blobs", fileSystem)
	if err != nil {
		log.Fatalf("Creating store: %v", err)
	}

	// Parse the score.
	score, err := fromHexHash("2667b2f8338a20b576724377af5c57b38d6cc447")
	if err != nil {
		log.Fatalf("Parsing score: %v", err)
	}

	// Make sure the target doesn't exist.
	err = os.RemoveAll(gTarget)
	if err != nil {
		log.Fatalf("RemoveAll: %v", err)
	}

	// Create the target.
	err = os.Mkdir("/tmp/restore_target", 0755)
	if err != nil {
		log.Fatalf("Mkdir: %v", err)
	}

	// Attempt a restore.
	err = restoreDir(gTarget, "", score)
	if err != nil {
		log.Fatalf("Restoring: %v", err)
	}
}
<commit_msg>Updated restore tool.<commit_after>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"bytes"
	"encoding/hex"
	"flag"
	"fmt"
	"github.com/jacobsa/comeback/blob"
	"github.com/jacobsa/comeback/blob/disk"
	"github.com/jacobsa/comeback/fs"
	"github.com/jacobsa/comeback/repr"
	"github.com/jacobsa/comeback/sys"
	"io"
	"log"
	"os"
	"path"
	"syscall"
	"time"
)

var g_score = flag.String("score", "", "The score of the directory to restore.")
var g_target = flag.String("target", "", "The target directory.")

var g_blobStore blob.Store

func fromHexHash(h string) (blob.Score, error) {
	b, err := hex.DecodeString(h)
	if err != nil {
		return nil, fmt.Errorf("Invalid hex string: %s", h)
	}

	return blob.Score(b), nil
}

func chooseUserId(uid sys.UserId, username *string) (sys.UserId, error) {
	// If there is no symbolic username, just return the UID.
	if username == nil {
		return uid, nil
	}

	// Create a user registry.
	registry, err := sys.NewUserRegistry()
	if err != nil {
		return 0, fmt.Errorf("Creating user registry: %v", err)
	}

	// Attempt to look up the username. If it's not found, return the UID.
	betterUid, err := registry.FindByName(*username)

	if _, ok := err.(sys.NotFoundError); ok {
		return uid, nil
	} else if err != nil {
		return 0, fmt.Errorf("Looking up user: %v", err)
	}

	return betterUid, nil
}

func chooseGroupId(gid sys.GroupId, groupname *string) (sys.GroupId, error) {
	// If there is no symbolic groupname, just return the GID.
	if groupname == nil {
		return gid, nil
	}

	// Create a group registry.
	registry, err := sys.NewGroupRegistry()
	if err != nil {
		return 0, fmt.Errorf("Creating group registry: %v", err)
	}

	// Attempt to look up the groupname. If it's not found, return the GID.
	betterGid, err := registry.FindByName(*groupname)

	if _, ok := err.(sys.NotFoundError); ok {
		return gid, nil
	} else if err != nil {
		return 0, fmt.Errorf("Looking up group: %v", err)
	}

	return betterGid, nil
}

// Set the modification time for the supplied path without following symlinks
// (as syscall.Chtimes and therefore os.Chtimes do).
//
// c.f. http://stackoverflow.com/questions/10608724/set-modification-date-on-symbolic-link-in-cocoa
func setModTime(path string, mtime time.Time) error {
	// Open the file without following symlinks. Use O_NONBLOCK to allow opening
	// of named pipes without a writer.
	fd, err := syscall.Open(path, syscall.O_NONBLOCK|syscall.O_SYMLINK, 0)
	if err != nil {
		return err
	}

	defer syscall.Close(fd)

	// Call futimes.
	var utimes [2]syscall.Timeval
	atime := time.Now()
	atime_ns := atime.Unix()*1e9 + int64(atime.Nanosecond())
	mtime_ns := mtime.Unix()*1e9 + int64(mtime.Nanosecond())
	utimes[0] = syscall.NsecToTimeval(atime_ns)
	utimes[1] = syscall.NsecToTimeval(mtime_ns)

	err = syscall.Futimes(fd, utimes[0:])
	if err != nil {
		return err
	}

	return nil
}

// Restore the file whose contents are described by the referenced blobs to the
// supplied target, whose parent must already exist.
func restoreFile(target string, scores []blob.Score) error {
	// Open the file.
	//
	// TODO(jacobsa): Fix permissions race condition here, since we create the
	// file with 0666.
	f, err := os.Create(target)
	defer f.Close()

	if err != nil {
		return fmt.Errorf("Create: %v", err)
	}

	// Process each blob.
	for _, score := range scores {
		// Load the blob.
		blob, err := g_blobStore.Load(score)
		if err != nil {
			return fmt.Errorf("Loading blob: %v", err)
		}

		// Write out its contents.
		_, err = io.Copy(f, bytes.NewReader(blob))
		if err != nil {
			return fmt.Errorf("Copy: %v", err)
		}
	}

	return nil
}

// Like os.Chmod, but don't follow symlinks.
func setPermissions(path string, permissions os.FileMode) error {
	mode := syscallPermissions(permissions)

	// Open the file without following symlinks. Use O_NONBLOCK to allow opening
	// of named pipes without a writer.
	fd, err := syscall.Open(path, syscall.O_NONBLOCK|syscall.O_SYMLINK, 0)
	if err != nil {
		return err
	}

	defer syscall.Close(fd)

	// Call fchmod.
	err = syscall.Fchmod(fd, mode)
	if err != nil {
		return err
	}

	return nil
}

// Restore the directory whose contents are described by the referenced blob to
// the supplied target, which must already exist.
func restoreDir(basePath, relPath string, score blob.Score) error {
	// Load the appropriate blob.
	blob, err := g_blobStore.Load(score)
	if err != nil {
		return fmt.Errorf("Loading blob: %v", err)
	}

	// Parse its contents.
	entries, err := repr.Unmarshal(blob)
	if err != nil {
		return fmt.Errorf("Parsing blob: %v", err)
	}

	// Deal with each entry.
	for _, entry := range entries {
		entryRelPath := path.Join(relPath, entry.Name)
		entryFullPath := path.Join(basePath, entryRelPath)

		// Switch on type.
		switch entry.Type {
		case fs.TypeFile:
			// Is this a hard link to another file?
			if entry.HardLinkTarget != nil {
				// Create the hard link.
				targetFullPath := path.Join(basePath, *entry.HardLinkTarget)
				if err := os.Link(targetFullPath, entryFullPath); err != nil {
					return fmt.Errorf("os.Link: %v", err)
				}
			} else {
				// Create the file using its blobs.
				if err := restoreFile(entryFullPath, entry.Scores); err != nil {
					return fmt.Errorf("restoreFile: %v", err)
				}
			}

		case fs.TypeDirectory:
			if len(entry.Scores) != 1 {
				return fmt.Errorf("Wrong number of scores: %v", entry)
			}

			if err = os.Mkdir(entryFullPath, 0700); err != nil {
				return fmt.Errorf("Mkdir: %v", err)
			}

			if err = restoreDir(basePath, entryRelPath, entry.Scores[0]); err != nil {
				return fmt.Errorf("restoreDir: %v", err)
			}

		case fs.TypeSymlink:
			err = os.Symlink(entry.Target, entryFullPath)
			if err != nil {
				return fmt.Errorf("Symlink: %v", err)
			}

		case fs.TypeNamedPipe:
			err = makeNamedPipe(entryFullPath, entry.Permissions)
			if err != nil {
				return fmt.Errorf("makeNamedPipe: %v", err)
			}

		case fs.TypeBlockDevice:
			err = makeBlockDevice(entryFullPath, entry.Permissions, entry.DeviceNumber)
			if err != nil {
				return fmt.Errorf("makeBlockDevice: %v", err)
			}

		case fs.TypeCharDevice:
			err = makeCharDevice(entryFullPath, entry.Permissions, entry.DeviceNumber)
			if err != nil {
				return fmt.Errorf("makeCharDevice: %v", err)
			}

		default:
			return fmt.Errorf("Don't know how to deal with entry: %v", entry)
		}

		// Fix ownership.
		uid, err := chooseUserId(entry.Uid, entry.Username)
		if err != nil {
			return fmt.Errorf("chooseUserId: %v", err)
		}

		gid, err := chooseGroupId(entry.Gid, entry.Groupname)
		if err != nil {
			return fmt.Errorf("chooseGroupId: %v", err)
		}

		if err = os.Lchown(entryFullPath, int(uid), int(gid)); err != nil {
			return fmt.Errorf("Chown: %v", err)
		}

		// Fix permissions, but not on devices (otherwise we get resource busy
		// errors).
		if entry.Type != fs.TypeBlockDevice && entry.Type != fs.TypeCharDevice {
			if err := setPermissions(entryFullPath, entry.Permissions); err != nil {
				return fmt.Errorf("setPermissions(%s): %v", entryFullPath, err)
			}
		}

		// Fix modification time, but not on devices (otherwise we get resource
		// busy errors).
		if entry.Type != fs.TypeBlockDevice && entry.Type != fs.TypeCharDevice {
			if err = setModTime(entryFullPath, entry.MTime); err != nil {
				return fmt.Errorf("setModTime(%s): %v", entryFullPath, err)
			}
		}
	}

	return nil
}

func syscallPermissions(permissions os.FileMode) (o uint32) {
	// Include r/w/x permission bits.
	o = uint32(permissions & os.ModePerm)

	// Also include setuid/setgid/sticky bits.
	if permissions&os.ModeSetuid != 0 {
		o |= syscall.S_ISUID
	}

	if permissions&os.ModeSetgid != 0 {
		o |= syscall.S_ISGID
	}

	if permissions&os.ModeSticky != 0 {
		o |= syscall.S_ISVTX
	}

	return
}

// Create a named pipe at the supplied path.
func makeNamedPipe(path string, permissions os.FileMode) error {
	return syscall.Mkfifo(path, syscallPermissions(permissions))
}

// Create a block device at the supplied path.
func makeBlockDevice(path string, permissions os.FileMode, dev int32) error {
	mode := syscallPermissions(permissions) | syscall.S_IFBLK
	if err := syscall.Mknod(path, mode, int(dev)); err != nil {
		return fmt.Errorf("syscall.Mknod: %v", err)
	}

	return nil
}

// Create a character device at the supplied path.
func makeCharDevice(path string, permissions os.FileMode, dev int32) error {
	mode := syscallPermissions(permissions) | syscall.S_IFCHR
	if err := syscall.Mknod(path, mode, int(dev)); err != nil {
		return fmt.Errorf("syscall.Mknod: %v", err)
	}

	return nil
}

func main() {
	var err error
	flag.Parse()

	// Validate flags.
	if *g_score == "" {
		fmt.Println("You must set -score.")
		os.Exit(1)
	}

	if *g_target == "" {
		fmt.Println("You must set -target.")
		os.Exit(1)
	}

	// Create a user registry.
	userRegistry, err := sys.NewUserRegistry()
	if err != nil {
		log.Fatalf("Creating user registry: %v", err)
	}

	// Create a group registry.
	groupRegistry, err := sys.NewGroupRegistry()
	if err != nil {
		log.Fatalf("Creating group registry: %v", err)
	}

	// Create a file system.
	fileSystem, err := fs.NewFileSystem(userRegistry, groupRegistry)
	if err != nil {
		log.Fatalf("Creating file system: %v", err)
	}

	// Create the blob store.
	g_blobStore, err = disk.NewDiskBlobStore("/tmp/blobs", fileSystem)
	if err != nil {
		log.Fatalf("Creating store: %v", err)
	}

	// Parse the score.
	score, err := fromHexHash(*g_score)
	if err != nil {
		log.Fatalf("Parsing score: %v", err)
	}

	// Make sure the target doesn't exist.
	err = os.RemoveAll(*g_target)
	if err != nil {
		log.Fatalf("RemoveAll: %v", err)
	}

	// Create the target.
	err = os.Mkdir("/tmp/restore_target", 0755)
	if err != nil {
		log.Fatalf("Mkdir: %v", err)
	}

	// Attempt a restore.
	err = restoreDir(*g_target, "", score)
	if err != nil {
		log.Fatalf("Restoring: %v", err)
	}
}
<|endoftext|>