<commit_before>// +build unit

// Copyright 2016 Google, Inc.
//
// 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 credhelper

import (
	"errors"
	"testing"

	"github.com/GoogleCloudPlatform/docker-credential-gcr/mock/mock_store" // mocks must be generated before test execution
	"github.com/GoogleCloudPlatform/docker-credential-gcr/store"
	"github.com/docker/docker-credential-helpers/credentials"
	"github.com/golang/mock/gomock"
)

const (
	expectedGCRUsername = "oauth2accesstoken"
)

var gcrHosts = [...]string{
	"gcr.io",
	"us.gcr.io",
	"eu.gcr.io",
	"asia.gcr.io",
	"b.gcr.io",
	"bucket.gcr.io",
	"appengine.gcr.io",
	"gcr.kubernetes.io",
}
var otherHosts = [...]string{"docker.io", "otherrepo.com"}

func TestIsAGCRHostname(t *testing.T) {
	t.Parallel()
	// test for GCR hosts
	for _, host := range gcrHosts {
		if !isAGCRHostname(host) {
			t.Error("Expected to be detected as a GCR hostname: ", host)
		}
	}

	// test for GCR hosts + scheme
	for _, host := range gcrHosts {
		if !isAGCRHostname("https://" + host) {
			t.Error("Expected to be detected as a GCR hostname: ", "https://"+host)
		}
	}

	// test for non-GCR hosts
	for _, host := range otherHosts {
		if isAGCRHostname(host) {
			t.Error("Expected to not be a GCR host: ", host)
		}
	}
}

func TestAdd_GCRCredentials(t *testing.T) {
	t.Parallel()
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)
	tested := NewGCRCredentialHelper(mockStore)

	creds := credentials.Credentials{
		Username: "foobarre",
		Secret:   "secret",
	}

	for _, host := range gcrHosts {
		creds.ServerURL = "https://" + host
		err := tested.Add(&creds)
		if err == nil {
			t.Error("Adding GCR credentials should return an error.")
		}
	}
}

func TestAdd_OtherCredentials(t *testing.T) {
	t.Parallel()
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)

	tested := NewGCRCredentialHelper(mockStore)

	creds := credentials.Credentials{
		Username: "foobarre",
		Secret:   "secret",
	}

	for _, host := range otherHosts {
		creds.ServerURL = "https://" + host
		mockStore.EXPECT().SetOtherCreds(&creds).Return(nil)

		err := tested.Add(&creds)

		if err != nil {
			t.Errorf("Add returned an error: %v", err)
		}
	}
}

func TestGet_OtherCredentials(t *testing.T) {
	t.Parallel()
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)
	expectedUsername := "foobarre"
	expectedSecret := "secrets!"
	creds := credentials.Credentials{
		Username: expectedUsername,
		Secret:   expectedSecret,
	}

	tested := NewGCRCredentialHelper(mockStore)

	for _, host := range otherHosts {
		mockStore.EXPECT().GetOtherCreds(host).Return(&creds, nil)

		username, secret, err := tested.Get(host)

		if err != nil {
			t.Errorf("Get returned an error: %v", err)
		} else if username != expectedUsername {
			t.Errorf("Expected username: %s but got: %s", expectedUsername, username)
		} else if secret != expectedSecret {
			t.Errorf("Expected secret: %s but got: %s", expectedSecret, secret)
		}
	}
}

func TestGet_GCRCredentials(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)

	// mock the helper methods used by getGCRAccessToken
	expectedSecret := "secrets!"
	tested := &gcrCredHelper{
		store: mockStore,
		defaultCredsToken: func() (string, error) {
			return expectedSecret, nil
		},
		gcloudSDKToken: func() (string, error) {
			return "", errors.New("No token here!")
		},
		credStoreToken: func(_ store.GCRCredStore) (string, error) {
			return "", errors.New("No token here!")
		},
	}

	for _, host := range gcrHosts {
		username, secret, err := tested.Get("https://" + host)
		if err != nil {
			t.Errorf("Get returned an error: %v", err)
		} else if username != expectedGCRUsername {
			t.Errorf("Expected GCR username: %s but got: %s", expectedGCRUsername, username)
		} else if secret != expectedSecret {
			t.Errorf("Expected secret: %s but got: %s", expectedSecret, secret)
		}
	}
}

func TestDelete_GCRCredentials(t *testing.T) {
	t.Parallel()
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)
	tested := NewGCRCredentialHelper(mockStore)

	for _, host := range gcrHosts {
		err := tested.Delete("https://" + host)
		if err == nil {
			t.Error("Deleting GCR credentials should return an error.")
		}
	}
}

func TestDelete_OtherCredentials(t *testing.T) {
	t.Parallel()
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)

	tested := NewGCRCredentialHelper(mockStore)

	for _, host := range otherHosts {
		schemedHost := "https://" + host
		mockStore.EXPECT().DeleteOtherCreds(schemedHost).Return(nil)

		err := tested.Delete(schemedHost)

		if err != nil {
			t.Errorf("Delete returned an error: %v", err)
		}
	}
}

/*
	The following tests verify the behavior of getGCRAccessToken. The token
	source preference should be as follows:
	application default > gcloud sdk > private store
*/

func TestGetGCRAccessToken_ApplicationDefault(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()
	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)
	// mock the helper methods used by getGCRAccessToken
	const expected = "application default creds!"
	tested := &gcrCredHelper{
		store: mockStore,
		defaultCredsToken: func() (string, error) {
			return expected, nil
		},
		gcloudSDKToken: func() (string, error) {
			return "gcloud sdk creds!", nil
		},
		credStoreToken: func(_ store.GCRCredStore) (string, error) {
			return "private creds!", nil
		},
	}

	token, err := tested.getGCRAccessToken()

	if err != nil {
		t.Fatalf("getGCRAccessToken returned an error: %v", err)
	} else if token != expected {
		t.Fatalf("Expected: %s got: %s", expected, token)
	}
}

func TestGetGCRAccessToken_GcloudSDK(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()
	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)
	// mock the helper methods used by getGCRAccessToken
	const expected = "gcloud sdk creds!"
	tested := &gcrCredHelper{
		store: mockStore,
		defaultCredsToken: func() (string, error) {
			return "", errors.New("No token here!")
		},
		gcloudSDKToken: func() (string, error) {
			return expected, nil
		},
		credStoreToken: func(_ store.GCRCredStore) (string, error) {
			return "private creds!", nil
		},
	}

	token, err := tested.getGCRAccessToken()

	if err != nil {
		t.Fatalf("getGCRAccessToken returned an error: %v", err)
	} else if token != expected {
		t.Fatalf("Expected: %s got: %s", expected, token)
	}
}

func TestGetGCRAccessToken_PrivateStore(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)

	// mock the helper methods used by getGCRAccessToken
	const expected = "private creds!"
	tested := &gcrCredHelper{
		store: mockStore,
		defaultCredsToken: func() (string, error) {
			return "", errors.New("No token here!")
		},
		gcloudSDKToken: func() (string, error) {
			return "", errors.New("Still no token here!")
		},
		credStoreToken: func(_ store.GCRCredStore) (string, error) {
			return expected, nil
		},
	}

	token, err := tested.getGCRAccessToken()

	if err != nil {
		t.Fatalf("getGCRAccessToken returned an error: %v", err)
	} else if token != expected {
		t.Fatalf("Expected: %s got: %s", expected, token)
	}
}

func TestGetGCRAccessToken_NoneExist(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)

	// mock the helper methods used by getGCRAccessToken
	tested := &gcrCredHelper{
		store: mockStore,
		defaultCredsToken: func() (string, error) {
			return "", errors.New("No token here!")
		},
		gcloudSDKToken: func() (string, error) {
			return "", errors.New("Still no token here!")
		},
		credStoreToken: func(_ store.GCRCredStore) (string, error) {
			return "", errors.New("Sad panda!")
		},
	}

	token, err := tested.getGCRAccessToken()

	if err == nil {
		t.Fatalf("Expected an error, got token: %s", token)
	}
}
<commit_msg>add test to confirm CredentialsNotFound error is being passed<commit_after>// +build unit

// Copyright 2016 Google, Inc.
//
// 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 credhelper

import (
	"errors"
	"testing"

	"github.com/GoogleCloudPlatform/docker-credential-gcr/mock/mock_store" // mocks must be generated before test execution
	"github.com/GoogleCloudPlatform/docker-credential-gcr/store"
	"github.com/docker/docker-credential-helpers/credentials"
	"github.com/golang/mock/gomock"
)

const (
	expectedGCRUsername = "oauth2accesstoken"
)

var gcrHosts = [...]string{
	"gcr.io",
	"us.gcr.io",
	"eu.gcr.io",
	"asia.gcr.io",
	"b.gcr.io",
	"bucket.gcr.io",
	"appengine.gcr.io",
	"gcr.kubernetes.io",
}
var otherHosts = [...]string{"docker.io", "otherrepo.com"}

func TestIsAGCRHostname(t *testing.T) {
	t.Parallel()
	// test for GCR hosts
	for _, host := range gcrHosts {
		if !isAGCRHostname(host) {
			t.Error("Expected to be detected as a GCR hostname: ", host)
		}
	}

	// test for GCR hosts + scheme
	for _, host := range gcrHosts {
		if !isAGCRHostname("https://" + host) {
			t.Error("Expected to be detected as a GCR hostname: ", "https://"+host)
		}
	}

	// test for non-GCR hosts
	for _, host := range otherHosts {
		if isAGCRHostname(host) {
			t.Error("Expected to not be a GCR host: ", host)
		}
	}
}

func TestAdd_GCRCredentials(t *testing.T) {
	t.Parallel()
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)
	tested := NewGCRCredentialHelper(mockStore)

	creds := credentials.Credentials{
		Username: "foobarre",
		Secret:   "secret",
	}

	for _, host := range gcrHosts {
		creds.ServerURL = "https://" + host
		err := tested.Add(&creds)
		if err == nil {
			t.Error("Adding GCR credentials should return an error.")
		}
	}
}

func TestAdd_OtherCredentials(t *testing.T) {
	t.Parallel()
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)

	tested := NewGCRCredentialHelper(mockStore)

	creds := credentials.Credentials{
		Username: "foobarre",
		Secret:   "secret",
	}

	for _, host := range otherHosts {
		creds.ServerURL = "https://" + host
		mockStore.EXPECT().SetOtherCreds(&creds).Return(nil)

		err := tested.Add(&creds)

		if err != nil {
			t.Errorf("Add returned an error: %v", err)
		}
	}
}

func TestGet_OtherCredentials(t *testing.T) {
	t.Parallel()
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)
	expectedUsername := "foobarre"
	expectedSecret := "secrets!"
	creds := credentials.Credentials{
		Username: expectedUsername,
		Secret:   expectedSecret,
	}

	tested := NewGCRCredentialHelper(mockStore)

	// positive case
	for _, host := range otherHosts {
		mockStore.EXPECT().GetOtherCreds(host).Return(&creds, nil)

		username, secret, err := tested.Get(host)

		if err != nil {
			t.Errorf("Get returned an error: %v", err)
		} else if username != expectedUsername {
			t.Errorf("Expected username: %s but got: %s", expectedUsername, username)
		} else if secret != expectedSecret {
			t.Errorf("Expected secret: %s but got: %s", expectedSecret, secret)
		}
	}

	// negative case
	mockStore.EXPECT().GetOtherCreds("somewhere.else").Return(nil, credentials.NewErrCredentialsNotFound())

	_, _, err := tested.Get("somewhere.else")

	if err == nil {
		t.Error("Expected an error to be returned")
	} else if !credentials.IsErrCredentialsNotFound(err) {
		t.Errorf("Expected a CredentialsNotFound error: %v", err)
	}
}

func TestGet_GCRCredentials(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)

	// mock the helper methods used by getGCRAccessToken
	expectedSecret := "secrets!"
	tested := &gcrCredHelper{
		store: mockStore,
		defaultCredsToken: func() (string, error) {
			return expectedSecret, nil
		},
		gcloudSDKToken: func() (string, error) {
			return "", errors.New("No token here!")
		},
		credStoreToken: func(_ store.GCRCredStore) (string, error) {
			return "", errors.New("No token here!")
		},
	}

	for _, host := range gcrHosts {
		username, secret, err := tested.Get("https://" + host)
		if err != nil {
			t.Errorf("Get returned an error: %v", err)
		} else if username != expectedGCRUsername {
			t.Errorf("Expected GCR username: %s but got: %s", expectedGCRUsername, username)
		} else if secret != expectedSecret {
			t.Errorf("Expected secret: %s but got: %s", expectedSecret, secret)
		}
	}
}

func TestDelete_GCRCredentials(t *testing.T) {
	t.Parallel()
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)
	tested := NewGCRCredentialHelper(mockStore)

	for _, host := range gcrHosts {
		err := tested.Delete("https://" + host)
		if err == nil {
			t.Error("Deleting GCR credentials should return an error.")
		}
	}
}

func TestDelete_OtherCredentials(t *testing.T) {
	t.Parallel()
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)

	tested := NewGCRCredentialHelper(mockStore)

	for _, host := range otherHosts {
		schemedHost := "https://" + host
		mockStore.EXPECT().DeleteOtherCreds(schemedHost).Return(nil)

		err := tested.Delete(schemedHost)

		if err != nil {
			t.Errorf("Delete returned an error: %v", err)
		}
	}
}

/*
	The following tests verify the behavior of getGCRAccessToken. The token
	source preference should be as follows:
	application default > gcloud sdk > private store
*/

func TestGetGCRAccessToken_ApplicationDefault(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()
	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)
	// mock the helper methods used by getGCRAccessToken
	const expected = "application default creds!"
	tested := &gcrCredHelper{
		store: mockStore,
		defaultCredsToken: func() (string, error) {
			return expected, nil
		},
		gcloudSDKToken: func() (string, error) {
			return "gcloud sdk creds!", nil
		},
		credStoreToken: func(_ store.GCRCredStore) (string, error) {
			return "private creds!", nil
		},
	}

	token, err := tested.getGCRAccessToken()

	if err != nil {
		t.Fatalf("getGCRAccessToken returned an error: %v", err)
	} else if token != expected {
		t.Fatalf("Expected: %s got: %s", expected, token)
	}
}

func TestGetGCRAccessToken_GcloudSDK(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()
	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)
	// mock the helper methods used by getGCRAccessToken
	const expected = "gcloud sdk creds!"
	tested := &gcrCredHelper{
		store: mockStore,
		defaultCredsToken: func() (string, error) {
			return "", errors.New("No token here!")
		},
		gcloudSDKToken: func() (string, error) {
			return expected, nil
		},
		credStoreToken: func(_ store.GCRCredStore) (string, error) {
			return "private creds!", nil
		},
	}

	token, err := tested.getGCRAccessToken()

	if err != nil {
		t.Fatalf("getGCRAccessToken returned an error: %v", err)
	} else if token != expected {
		t.Fatalf("Expected: %s got: %s", expected, token)
	}
}

func TestGetGCRAccessToken_PrivateStore(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)

	// mock the helper methods used by getGCRAccessToken
	const expected = "private creds!"
	tested := &gcrCredHelper{
		store: mockStore,
		defaultCredsToken: func() (string, error) {
			return "", errors.New("No token here!")
		},
		gcloudSDKToken: func() (string, error) {
			return "", errors.New("Still no token here!")
		},
		credStoreToken: func(_ store.GCRCredStore) (string, error) {
			return expected, nil
		},
	}

	token, err := tested.getGCRAccessToken()

	if err != nil {
		t.Fatalf("getGCRAccessToken returned an error: %v", err)
	} else if token != expected {
		t.Fatalf("Expected: %s got: %s", expected, token)
	}
}

func TestGetGCRAccessToken_NoneExist(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	// create a mock store to use
	mockStore := mock_store.NewMockGCRCredStore(mockCtrl)

	// mock the helper methods used by getGCRAccessToken
	tested := &gcrCredHelper{
		store: mockStore,
		defaultCredsToken: func() (string, error) {
			return "", errors.New("No token here!")
		},
		gcloudSDKToken: func() (string, error) {
			return "", errors.New("Still no token here!")
		},
		credStoreToken: func(_ store.GCRCredStore) (string, error) {
			return "", errors.New("Sad panda!")
		},
	}

	token, err := tested.getGCRAccessToken()

	if err == nil {
		t.Fatalf("Expected an error, got token: %s", token)
	}
}
<|endoftext|>


<commit_before>package lib

import (
	"bazil.org/fuse"
	"bazil.org/fuse/fs"
	drive "code.google.com/p/google-api-go-client/drive/v2"
	"io/ioutil"
	"log"
	"os"
	"time"
)

// DriveFile represents a file in google drive
type DriveFile struct {
	File     *drive.File
	TmpFile  *os.File
	Modified time.Time
	Created  time.Time
	Root     bool
}

// Attr returns the file attributes
func (d DriveFile) Attr() fuse.Attr {
	return fuse.Attr{
		Mode:  0777,
		Mtime: time.Now(),
		Size:  uint64(d.File.FileSize),
	}
}

// ReadAll reads an entire file from google drive and returns the resulting bytes
func (d DriveFile) ReadAll(intr fs.Intr) ([]byte, fuse.Error) {
	byteChan := make(chan *[]byte)
	errChan := make(chan error)
	defer func() {
		close(byteChan)
		close(errChan)
	}()
	// launch read goroutine
	go func() {
		// grab file from google drive api
		log.Println(d.File.Title)
		b, err := client.Get(d.File.DownloadUrl)
		if err != nil {
			log.Println(err)
			errChan <- err
			return
		}
		// read the data from body and close connection
		c, err := ioutil.ReadAll(b.Body)
		if err != nil {
			log.Println(err)
			errChan <- err
		}
		byteChan <- &c
	}()
	// wait for read to be done, or for file system interupt and return values
	select {
	case tmp := <-byteChan:
		return *tmp, nil
	case <-intr:
		return nil, nil
	}

}

// Setattr sets file attributs
func (d *DriveFile) Setattr(req *fuse.SetattrRequest, resp *fuse.SetattrResponse, intr fs.Intr) fuse.Error {
	valid := req.Valid
	if valid.Size() {
		return nil
	}
	return nil
}

// Write writes bytes to a tmp file, which are then synced by FSync
func (d *DriveFile) Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, intr fs.Intr) fuse.Error {
	// check if d already has a tmp file
	// If d does not have a tmp file, create one and write to it
	size, err := d.TmpFile.Write(req.Data)
	if err != nil {
		log.Println(err)
		return err
	}
	resp.Size = size
	return nil

}

// Open a file or directory
func (d *DriveFile) Open(req *fuse.OpenRequest, resp *fuse.OpenResponse, intr fs.Intr) (fs.Handle, fuse.Error) {
	d.TmpFile.Close()
	f, err := os.Create("/tmp/drivefs-" + d.File.Id)
	if err != nil {
		return nil, err
	}
	d.TmpFile = f

	resp.Flags &^= fuse.OpenDirectIO
	return d, nil
}

// Flush a file tmp to google drive
func (d *DriveFile) Flush(req *fuse.FlushRequest, intr fs.Intr) fuse.Error {
	log.Println("Flushing: ", d.TmpFile.Name())
	// sync file to disk
	err := d.TmpFile.Sync()
	if err != nil {
		log.Println(err)
		return err
	}
	d.TmpFile.Close()
	d.TmpFile, err = os.Open(d.TmpFile.Name())
	if err != nil {
		log.Println(err)
	}
	// upload file to google drive
	d.File, err = service.Files.Update(d.File.Id, d.File).Media(d.TmpFile).Do()
	if err != nil {
		log.Println(err)
		return err
	}
	return os.Remove(d.TmpFile.Name())

}

// exists checks if a file or directory exists on disk
func exists(fileName string) bool {
	if a, err := os.Stat(fileName); os.IsNotExist(err) {
		return false
	} else {
		log.Println(a)
		return true
	}
}
<commit_msg>flush now handles interupts<commit_after>package lib

import (
	"bazil.org/fuse"
	"bazil.org/fuse/fs"
	drive "code.google.com/p/google-api-go-client/drive/v2"
	"io/ioutil"
	"log"
	"os"
	"time"
)

// DriveFile represents a file in google drive
type DriveFile struct {
	File     *drive.File
	TmpFile  *os.File
	Modified time.Time
	Created  time.Time
	Root     bool
}

// Attr returns the file attributes
func (d DriveFile) Attr() fuse.Attr {
	return fuse.Attr{
		Mode:  0777,
		Mtime: time.Now(),
		Size:  uint64(d.File.FileSize),
	}
}

// ReadAll reads an entire file from google drive and returns the resulting bytes
func (d DriveFile) ReadAll(intr fs.Intr) ([]byte, fuse.Error) {
	byteChan := make(chan *[]byte)
	errChan := make(chan error)
	defer func() {
		close(byteChan)
		close(errChan)
	}()
	// launch read goroutine
	go func() {
		// grab file from google drive api
		log.Println(d.File.Title)
		b, err := client.Get(d.File.DownloadUrl)
		if err != nil {
			log.Println(err)
			errChan <- err
			return
		}
		// read the data from body and close connection
		c, err := ioutil.ReadAll(b.Body)
		if err != nil {
			log.Println(err)
			errChan <- err
		}
		byteChan <- &c
	}()
	// wait for read to be done, or for file system interupt and return values
	select {
	case tmp := <-byteChan:
		return *tmp, nil
	case <-intr:
		return nil, nil
	}

}

// Setattr sets file attributs
func (d *DriveFile) Setattr(req *fuse.SetattrRequest, resp *fuse.SetattrResponse, intr fs.Intr) fuse.Error {
	valid := req.Valid
	if valid.Size() {
		return nil
	}
	return nil
}

// Write writes bytes to a tmp file, which are then synced by FSync
func (d *DriveFile) Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, intr fs.Intr) fuse.Error {
	// check if d already has a tmp file
	// If d does not have a tmp file, create one and write to it
	size, err := d.TmpFile.Write(req.Data)
	if err != nil {
		log.Println(err)
		return err
	}
	resp.Size = size
	return nil

}

// Open a file or directory
func (d *DriveFile) Open(req *fuse.OpenRequest, resp *fuse.OpenResponse, intr fs.Intr) (fs.Handle, fuse.Error) {
	d.TmpFile.Close()
	f, err := os.Create("/tmp/drivefs-" + d.File.Id)
	if err != nil {
		return nil, err
	}
	d.TmpFile = f

	resp.Flags &^= fuse.OpenDirectIO
	return d, nil
}

// Flush a file tmp to google drive
func (d *DriveFile) Flush(req *fuse.FlushRequest, intr fs.Intr) fuse.Error {
	log.Println("Flushing: ", d.TmpFile.Name())
	// sync file to disk
	err := d.TmpFile.Sync()
	if err != nil {
		log.Println(err)
		return err
	}
	d.TmpFile.Close()
	d.TmpFile, err = os.Open(d.TmpFile.Name())
	if err != nil {
		log.Println(err)
	}
	// upload file to google drive
	// this is done in another go routine to catch interupts
	errChan := make(chan error)
	fileChan := make(chan *drive.File)
	go func() {
		f, err := service.Files.Update(d.File.Id, d.File).Media(d.TmpFile).Do()
		if err != nil {
			errChan <- err
			return
		}
		fileChan <- f
		return
	}()
	// wait for interupt while uploading file
	select {
	// if all goes well, set new file and return
	case f := <-fileChan:
		d.File = f
		return os.Remove(d.TmpFile.Name())
	case err := <-errChan:
		os.Remove(d.TmpFile.Name())
		return err
	// catch interupt
	case <-intr:
		return fuse.EINTR
	}

}

// exists checks if a file or directory exists on disk
func exists(fileName string) bool {
	if a, err := os.Stat(fileName); os.IsNotExist(err) {
		return false
	} else {
		log.Println(a)
		return true
	}
}
<|endoftext|>


<commit_before>package host

import (
	"errors"
	"os"
	"sync"

	"github.com/NebulousLabs/Sia/consensus"
	"github.com/NebulousLabs/Sia/modules"
)

const (
	// StorageProofReorgDepth states how many blocks to wait before submitting
	// a storage proof. This reduces the chance of needing to resubmit because
	// of a reorg.
	StorageProofReorgDepth = 20
	maxContractLen         = 1 << 16 // The maximum allowed size of a file contract coming in over the wire. This does not include the file.
)

// A contractObligation tracks a file contract that the host is obligated to
// fulfill.
type contractObligation struct {
	ID           consensus.FileContractID
	FileContract consensus.FileContract
	Path         string // Where on disk the file is stored.
}

// A Host contains all the fields necessary for storing files for clients and
// performing the storage proofs on the received files.
type Host struct {
	state       *consensus.State
	tpool       modules.TransactionPool
	wallet      modules.Wallet
	latestBlock consensus.BlockID

	saveDir        string
	spaceRemaining int64
	fileCounter    int

	obligationsByID     map[consensus.FileContractID]contractObligation
	obligationsByHeight map[consensus.BlockHeight][]contractObligation

	modules.HostSettings

	mu sync.RWMutex
}

// New returns an initialized Host.
func New(state *consensus.State, tpool modules.TransactionPool, wallet modules.Wallet, saveDir string) (h *Host, err error) {
	if state == nil {
		err = errors.New("host cannot use a nil state")
		return
	}
	if tpool == nil {
		err = errors.New("host cannot use a nil tpool")
		return
	}
	if wallet == nil {
		err = errors.New("host cannot use a nil wallet")
		return
	}

	addr, _, err := wallet.CoinAddress()
	if err != nil {
		return
	}
	h = &Host{
		state:  state,
		tpool:  tpool,
		wallet: wallet,

		// default host settings
		HostSettings: modules.HostSettings{
			TotalStorage: 2e9,                           // 2 GB
			MaxFilesize:  300e6,                         // 300 MB
			MaxDuration:  5e3,                           // Just over a month.
			WindowSize:   288,                           // 48 hours.
			Price:        consensus.NewCurrency64(1e12), // 10^12
			Collateral:   consensus.NewCurrency64(0),
			UnlockHash:   addr,
		},

		saveDir:        saveDir,
		spaceRemaining: 2e9,

		obligationsByID:     make(map[consensus.FileContractID]contractObligation),
		obligationsByHeight: make(map[consensus.BlockHeight][]contractObligation),
	}
	block, exists := state.BlockAtHeight(0)
	if !exists {
		err = errors.New("state doesn't have a genesis block")
		return
	}
	h.latestBlock = block.ID()

	err = os.MkdirAll(saveDir, 0700)
	if err != nil {
		return
	}
	h.load()

	consensusChan := state.SubscribeToConsensusChanges()
	go h.threadedConsensusListen(consensusChan)

	return
}

// SetConfig updates the host's internal HostSettings object. To modify
// a specific field, use a combination of Info and SetConfig
func (h *Host) SetSettings(settings modules.HostSettings) {
	h.mu.Lock()
	defer h.mu.Unlock()
	h.HostSettings = settings
	h.save()
}

// Settings is an RPC used to request the settings of a host.
func (h *Host) Settings(conn modules.NetConn) error {
	h.mu.RLock()
	hs := h.HostSettings
	h.mu.RUnlock()
	return conn.WriteObject(hs)
}

func (h *Host) Info() modules.HostInfo {
	h.mu.RLock()
	defer h.mu.RUnlock()

	info := modules.HostInfo{
		HostSettings: h.HostSettings,

		StorageRemaining: h.spaceRemaining,
		NumContracts:     len(h.obligationsByID),
	}
	return info
}
<commit_msg>tweak default host price<commit_after>package host

import (
	"errors"
	"os"
	"sync"

	"github.com/NebulousLabs/Sia/consensus"
	"github.com/NebulousLabs/Sia/modules"
)

const (
	// StorageProofReorgDepth states how many blocks to wait before submitting
	// a storage proof. This reduces the chance of needing to resubmit because
	// of a reorg.
	StorageProofReorgDepth = 20
	maxContractLen         = 1 << 16 // The maximum allowed size of a file contract coming in over the wire. This does not include the file.
)

// A contractObligation tracks a file contract that the host is obligated to
// fulfill.
type contractObligation struct {
	ID           consensus.FileContractID
	FileContract consensus.FileContract
	Path         string // Where on disk the file is stored.
}

// A Host contains all the fields necessary for storing files for clients and
// performing the storage proofs on the received files.
type Host struct {
	state       *consensus.State
	tpool       modules.TransactionPool
	wallet      modules.Wallet
	latestBlock consensus.BlockID

	saveDir        string
	spaceRemaining int64
	fileCounter    int

	obligationsByID     map[consensus.FileContractID]contractObligation
	obligationsByHeight map[consensus.BlockHeight][]contractObligation

	modules.HostSettings

	mu sync.RWMutex
}

// New returns an initialized Host.
func New(state *consensus.State, tpool modules.TransactionPool, wallet modules.Wallet, saveDir string) (h *Host, err error) {
	if state == nil {
		err = errors.New("host cannot use a nil state")
		return
	}
	if tpool == nil {
		err = errors.New("host cannot use a nil tpool")
		return
	}
	if wallet == nil {
		err = errors.New("host cannot use a nil wallet")
		return
	}

	addr, _, err := wallet.CoinAddress()
	if err != nil {
		return
	}
	h = &Host{
		state:  state,
		tpool:  tpool,
		wallet: wallet,

		// default host settings
		HostSettings: modules.HostSettings{
			TotalStorage: 2e9,                          // 2 GB
			MaxFilesize:  300e6,                        // 300 MB
			MaxDuration:  5e3,                          // Just over a month.
			WindowSize:   288,                          // 48 hours.
			Price:        consensus.NewCurrency64(1e9), // 10^9
			Collateral:   consensus.NewCurrency64(0),
			UnlockHash:   addr,
		},

		saveDir:        saveDir,
		spaceRemaining: 2e9,

		obligationsByID:     make(map[consensus.FileContractID]contractObligation),
		obligationsByHeight: make(map[consensus.BlockHeight][]contractObligation),
	}
	block, exists := state.BlockAtHeight(0)
	if !exists {
		err = errors.New("state doesn't have a genesis block")
		return
	}
	h.latestBlock = block.ID()

	err = os.MkdirAll(saveDir, 0700)
	if err != nil {
		return
	}
	h.load()

	consensusChan := state.SubscribeToConsensusChanges()
	go h.threadedConsensusListen(consensusChan)

	return
}

// SetConfig updates the host's internal HostSettings object. To modify
// a specific field, use a combination of Info and SetConfig
func (h *Host) SetSettings(settings modules.HostSettings) {
	h.mu.Lock()
	defer h.mu.Unlock()
	h.HostSettings = settings
	h.save()
}

// Settings is an RPC used to request the settings of a host.
func (h *Host) Settings(conn modules.NetConn) error {
	h.mu.RLock()
	hs := h.HostSettings
	h.mu.RUnlock()
	return conn.WriteObject(hs)
}

func (h *Host) Info() modules.HostInfo {
	h.mu.RLock()
	defer h.mu.RUnlock()

	info := modules.HostInfo{
		HostSettings: h.HostSettings,

		StorageRemaining: h.spaceRemaining,
		NumContracts:     len(h.obligationsByID),
	}
	return info
}
<|endoftext|>


<commit_before>/*
ctxcopy is a Golang package which provides helper functions for performing context-aware copy task.

*/
package ctxcopy
<commit_msg>Add 'Package' before description to remove golint warnings.<commit_after>/*
Package ctxcopy is a Golang package which provides helper functions for performing context-aware copy task.

*/
package ctxcopy
<|endoftext|>


<commit_before>package gogitlab

import (
	"encoding/json"
	"net/url"
	"reflect"
	"strconv"
)

const (
	project_url_hooks = "/projects/:id/hooks"          // Get list of project hooks
	project_url_hook  = "/projects/:id/hooks/:hook_id" // Get single project hook
)

type Hook struct {
	ID                    int    `json:"id,omitempty"`
	URL                   string `json:"url,omitempty"`
	CreatedAt             string `json:"created_at,omitempty"`
	PushEvents            *bool  `json:"push_events,omitempty"`
	IssuesEvents          *bool  `json:"issues_events,omitempty"`
	MergeRequestsEvents   *bool  `json:"merge_requests_events,omitempty"`
	TagPushEvents         *bool  `json:"tag_push_events,omitempty"`
	NoteEvents            *bool  `json:"note_events,omitempty"`
	BuildEvents           *bool  `json:"build_events,omitempty"`
	PipelineEvents        *bool  `json:"pipeline_events,omitempty"`
	WikiPageEvents        *bool  `json:"wiki_page_events,omitempty"`
	EnableSSLVerification *bool  `json:"enable_ssl_verification,omitempty"`
}

/*
Get list of project hooks.

    GET /projects/:id/hooks

Parameters:

    id The ID of a project

*/
func (g *Gitlab) ProjectHooks(id string) ([]*Hook, error) {
	var hooks []*Hook

	url, opaque := g.ResourceUrlRaw(project_url_hooks, map[string]string{":id": id})

	contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
	if err != nil {
		return hooks, err
	}

	err = json.Unmarshal(contents, &hooks)

	return hooks, err
}

/*
Get single project hook.

    GET /projects/:id/hooks/:hook_id

Parameters:

    id      The ID of a project
    hook_id The ID of a hook

*/
func (g *Gitlab) ProjectHook(id string, hook_id int) (*Hook, error) {
	hook := new(Hook)
	url, opaque := g.ResourceUrlRaw(project_url_hook, map[string]string{
		":id":      id,
		":hook_id": strconv.Itoa(hook_id),
	})

	contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
	if err != nil {
		return hook, err
	}

	err = json.Unmarshal(contents, &hook)

	return hook, err
}

/*
Add new project hook.

    POST /projects/:id/hooks

Parameters:

    id                    The ID or NAMESPACE/PROJECT_NAME of a project
    hook_url              The hook URL
    push_events           Trigger hook on push events
    issues_events         Trigger hook on issues events
    merge_requests_events Trigger hook on merge_requests events

*/
func (g *Gitlab) AddProjectHook(id, hook *Hook) error {
	url, opaque := g.ResourceUrlRaw(project_url_hooks, map[string]string{":id": id})

	body := buildHookQuery(hook)
	_, err := g.buildAndExecRequestRaw("POST", url, opaque, []byte(body))

	return err
}

/*
Edit existing project hook.

    PUT /projects/:id/hooks/:hook_id

Parameters:

    id                    The ID or NAMESPACE/PROJECT_NAME of a project
    hook_id               The ID of a project hook
    hook_url              The hook URL
    push_events           Trigger hook on push events
    issues_events         Trigger hook on issues events
    merge_requests_events Trigger hook on merge_requests events

*/
func (g *Gitlab) EditProjectHook(id, hook *Hook) error {
	url, opaque := g.ResourceUrlRaw(project_url_hook, map[string]string{
		":id":      id,
		":hook_id": strconv.Itoa(hook.ID),
	})

	body := buildHookQuery(hook)
	_, err := g.buildAndExecRequestRaw("PUT", url, opaque, []byte(body))

	return err
}

/*
Remove hook from project.

    DELETE /projects/:id/hooks/:hook_id

Parameters:

    id      The ID or NAMESPACE/PROJECT_NAME of a project
    hook_id The ID of hook to delete

*/
func (g *Gitlab) RemoveProjectHook(id string, hook_id int) error {
	url, opaque := g.ResourceUrlRaw(project_url_hook, map[string]string{
		":id":      id,
		":hook_id": strconv.Itoa(hook_id),
	})

	_, err := g.buildAndExecRequestRaw("DELETE", url, opaque, nil)

	return err
}

/*
Build HTTP query to add or edit hook
*/
func buildHookQuery(hook *Hook) string {
	v := url.Values{}

	ht := reflect.TypeOf(hook)
	for i := 0; i < ht.NumField(); i++ {
		cf := ht.Field(i)
		if cf.Name == "ID" || cf.Name == "CreatedAt" {
			continue
		}

	}
	return v.Encode()
}
<commit_msg>Law of Reflection<commit_after>package gogitlab

import (
	"encoding/json"
	"fmt"
	"net/url"
	"reflect"
	"strconv"
	"strings"
)

const (
	project_url_hooks = "/projects/:id/hooks"          // Get list of project hooks
	project_url_hook  = "/projects/:id/hooks/:hook_id" // Get single project hook
)

type Hook struct {
	ID                    int    `json:"id,omitempty"`
	URL                   string `json:"url,omitempty"`
	CreatedAt             string `json:"created_at,omitempty"`
	PushEvents            *bool  `json:"push_events,omitempty"`
	IssuesEvents          *bool  `json:"issues_events,omitempty"`
	MergeRequestsEvents   *bool  `json:"merge_requests_events,omitempty"`
	TagPushEvents         *bool  `json:"tag_push_events,omitempty"`
	NoteEvents            *bool  `json:"note_events,omitempty"`
	BuildEvents           *bool  `json:"build_events,omitempty"`
	PipelineEvents        *bool  `json:"pipeline_events,omitempty"`
	WikiPageEvents        *bool  `json:"wiki_page_events,omitempty"`
	EnableSSLVerification *bool  `json:"enable_ssl_verification,omitempty"`
}

/*
Get list of project hooks.

    GET /projects/:id/hooks

Parameters:

    id The ID of a project

*/
func (g *Gitlab) ProjectHooks(id string) ([]*Hook, error) {
	var hooks []*Hook

	url, opaque := g.ResourceUrlRaw(project_url_hooks, map[string]string{":id": id})

	contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
	if err != nil {
		return hooks, err
	}

	err = json.Unmarshal(contents, &hooks)

	return hooks, err
}

/*
Get single project hook.

    GET /projects/:id/hooks/:hook_id

Parameters:

    id      The ID of a project
    hook_id The ID of a hook

*/
func (g *Gitlab) ProjectHook(id string, hook_id int) (*Hook, error) {
	hook := new(Hook)
	url, opaque := g.ResourceUrlRaw(project_url_hook, map[string]string{
		":id":      id,
		":hook_id": strconv.Itoa(hook_id),
	})

	contents, err := g.buildAndExecRequestRaw("GET", url, opaque, nil)
	if err != nil {
		return hook, err
	}

	err = json.Unmarshal(contents, &hook)

	return hook, err
}

/*
Add new project hook.

    POST /projects/:id/hooks

Parameters:

    id                    The ID or NAMESPACE/PROJECT_NAME of a project
    hook_url              The hook URL
    push_events           Trigger hook on push events
    issues_events         Trigger hook on issues events
    merge_requests_events Trigger hook on merge_requests events

*/
func (g *Gitlab) AddProjectHook(id, hook *Hook) error {
	url, opaque := g.ResourceUrlRaw(project_url_hooks, map[string]string{":id": id})

	body := buildHookQuery(hook)
	_, err := g.buildAndExecRequestRaw("POST", url, opaque, []byte(body))

	return err
}

/*
Edit existing project hook.

    PUT /projects/:id/hooks/:hook_id

Parameters:

    id                    The ID or NAMESPACE/PROJECT_NAME of a project
    hook_id               The ID of a project hook
    hook_url              The hook URL
    push_events           Trigger hook on push events
    issues_events         Trigger hook on issues events
    merge_requests_events Trigger hook on merge_requests events

*/
func (g *Gitlab) EditProjectHook(id, hook *Hook) error {
	url, opaque := g.ResourceUrlRaw(project_url_hook, map[string]string{
		":id":      id,
		":hook_id": strconv.Itoa(hook.ID),
	})

	body := buildHookQuery(hook)
	_, err := g.buildAndExecRequestRaw("PUT", url, opaque, []byte(body))

	return err
}

/*
Remove hook from project.

    DELETE /projects/:id/hooks/:hook_id

Parameters:

    id      The ID or NAMESPACE/PROJECT_NAME of a project
    hook_id The ID of hook to delete

*/
func (g *Gitlab) RemoveProjectHook(id string, hook_id int) error {
	url, opaque := g.ResourceUrlRaw(project_url_hook, map[string]string{
		":id":      id,
		":hook_id": strconv.Itoa(hook_id),
	})

	_, err := g.buildAndExecRequestRaw("DELETE", url, opaque, nil)

	return err
}

/*
Build HTTP query to add or edit hook
*/
func buildHookQuery(hook *Hook) string {
	v := url.Values{}

	ht := reflect.TypeOf(hook)
	hv := reflect.ValueOf(hook)
	for i := 0; i < ht.NumField(); i++ {
		cf := ht.Field(i)
		if cf.Name == "ID" || cf.Name == "CreatedAt" {
			continue
		}
		v.Set(strings.Split(cf.Tag.Get("json"), ",")[0], fmt.Sprintf("%v", hv.FieldByName(cf.Name)))
	}
	return v.Encode()
}
<|endoftext|>


<commit_before>// Copyright 2017 Google Inc.
//
// 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 wlan provides an i3bar module for wireless information.
// NOTE: This module REQUIRES the external command "iwgetid",
// because getting the SSID is a privileged operation.
package wlan // import "barista.run/modules/wlan"

import (
	"net"
	"os/exec"
	"strconv"
	"strings"

	"barista.run/bar"
	"barista.run/base/value"
	"barista.run/base/watchers/netlink"
	l "barista.run/logging"
	"barista.run/outputs"
)

// Info represents the wireless card status.
type Info struct {
	Name           string
	State          netlink.OperState
	IPs            []net.IP
	SSID           string
	AccessPointMAC string
	Channel        int
	Frequency      float64
}

// Connecting returns true if a connection is in progress.
func (i Info) Connecting() bool {
	return i.State == netlink.Dormant
}

// Connected returns true if connected to a wireless network.
func (i Info) Connected() bool {
	return i.State == netlink.Up
}

// Enabled returns true if the wireless card is enabled.
func (i Info) Enabled() bool {
	return i.State > netlink.NotPresent
}

// Module represents a wlan bar module.
type Module struct {
	intf       string
	outputFunc value.Value // of func(Info) bar.Output
}

// Named constructs an instance of the wlan module for the specified interface.
func Named(iface string) *Module {
	m := &Module{intf: iface}
	l.Label(m, iface)
	l.Register(m, "outputFunc")
	// Default output is just the SSID when connected.
	m.Output(func(i Info) bar.Output {
		if i.Connected() {
			return outputs.Text(i.SSID)
		}
		return nil
	})
	return m
}

// Any constructs an instance of the wlan module that uses any available
// wireless interface, choosing the 'best' state from all available.
func Any() *Module {
	return Named("")
}

// Output configures a module to display the output of a user-defined function.
func (m *Module) Output(outputFunc func(Info) bar.Output) *Module {
	m.outputFunc.Set(outputFunc)
	return m
}

// Stream starts the module.
func (m *Module) Stream(s bar.Sink) {
	info := Info{}
	outputFunc := m.outputFunc.Get().(func(Info) bar.Output)
	nextOutputFunc := m.outputFunc.Next()
	var updateChan netlink.Subscription
	if m.intf == "" {
		updateChan = netlink.WithPrefix("wl")
	} else {
		updateChan = netlink.ByName(m.intf)
	}
	defer updateChan.Unsubscribe()
	for {
		select {
		case update := <-updateChan:
			info = Info{
				Name:  update.Name,
				State: update.State,
				IPs:   update.IPs,
			}
			fillWifiInfo(&info)
		case <-nextOutputFunc:
			nextOutputFunc = m.outputFunc.Next()
			outputFunc = m.outputFunc.Get().(func(Info) bar.Output)
		}
		s.Output(outputFunc(info))
	}
}

func fillWifiInfo(info *Info) {
	ssid, err := iwgetid(info.Name, "-r")
	if err != nil {
		return
	}
	info.SSID = ssid
	info.AccessPointMAC, _ = iwgetid(info.Name, "-a")
	ch, _ := iwgetid(info.Name, "-c")
	info.Channel, _ = strconv.Atoi(ch)
	freq, _ := iwgetid(info.Name, "-f")
	info.Frequency, _ = strconv.ParseFloat(freq, 64)
}

var iwgetid = func(intf, flag string) (string, error) {
	out, err := exec.Command("/sbin/iwgetid", intf, "-r", flag).Output()
	return strings.TrimSpace(string(out)), err
}
<commit_msg>Use unit.Frequency for wireless frequency<commit_after>// Copyright 2017 Google Inc.
//
// 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 wlan provides an i3bar module for wireless information.
// NOTE: This module REQUIRES the external command "iwgetid",
// because getting the SSID is a privileged operation.
package wlan // import "barista.run/modules/wlan"

import (
	"net"
	"os/exec"
	"strconv"
	"strings"

	"barista.run/bar"
	"barista.run/base/value"
	"barista.run/base/watchers/netlink"
	l "barista.run/logging"
	"barista.run/outputs"
	"github.com/martinlindhe/unit"
)

// Info represents the wireless card status.
type Info struct {
	Name           string
	State          netlink.OperState
	IPs            []net.IP
	SSID           string
	AccessPointMAC string
	Channel        int
	Frequency      unit.Frequency
}

// Connecting returns true if a connection is in progress.
func (i Info) Connecting() bool {
	return i.State == netlink.Dormant
}

// Connected returns true if connected to a wireless network.
func (i Info) Connected() bool {
	return i.State == netlink.Up
}

// Enabled returns true if the wireless card is enabled.
func (i Info) Enabled() bool {
	return i.State > netlink.NotPresent
}

// Module represents a wlan bar module.
type Module struct {
	intf       string
	outputFunc value.Value // of func(Info) bar.Output
}

// Named constructs an instance of the wlan module for the specified interface.
func Named(iface string) *Module {
	m := &Module{intf: iface}
	l.Label(m, iface)
	l.Register(m, "outputFunc")
	// Default output is just the SSID when connected.
	m.Output(func(i Info) bar.Output {
		if i.Connected() {
			return outputs.Text(i.SSID)
		}
		return nil
	})
	return m
}

// Any constructs an instance of the wlan module that uses any available
// wireless interface, choosing the 'best' state from all available.
func Any() *Module {
	return Named("")
}

// Output configures a module to display the output of a user-defined function.
func (m *Module) Output(outputFunc func(Info) bar.Output) *Module {
	m.outputFunc.Set(outputFunc)
	return m
}

// Stream starts the module.
func (m *Module) Stream(s bar.Sink) {
	info := Info{}
	outputFunc := m.outputFunc.Get().(func(Info) bar.Output)
	nextOutputFunc := m.outputFunc.Next()
	var updateChan netlink.Subscription
	if m.intf == "" {
		updateChan = netlink.WithPrefix("wl")
	} else {
		updateChan = netlink.ByName(m.intf)
	}
	defer updateChan.Unsubscribe()
	for {
		select {
		case update := <-updateChan:
			info = Info{
				Name:  update.Name,
				State: update.State,
				IPs:   update.IPs,
			}
			fillWifiInfo(&info)
		case <-nextOutputFunc:
			nextOutputFunc = m.outputFunc.Next()
			outputFunc = m.outputFunc.Get().(func(Info) bar.Output)
		}
		s.Output(outputFunc(info))
	}
}

func fillWifiInfo(info *Info) {
	ssid, err := iwgetid(info.Name, "-r")
	if err != nil {
		return
	}
	info.SSID = ssid
	info.AccessPointMAC, _ = iwgetid(info.Name, "-a")
	ch, _ := iwgetid(info.Name, "-c")
	info.Channel, _ = strconv.Atoi(ch)
	freq, _ := iwgetid(info.Name, "-f")
	freqFloat, _ := strconv.ParseFloat(freq, 64)
	info.Frequency = unit.Frequency(freqFloat) * unit.Hertz
}

var iwgetid = func(intf, flag string) (string, error) {
	out, err := exec.Command("/sbin/iwgetid", intf, "-r", flag).Output()
	return strings.TrimSpace(string(out)), err
}
<|endoftext|>


<commit_before>package jd

import (
	"strconv"
	"testing"
)

var corpus = []string{
	``,  // void
	` `, // void
	`null`,
	`0`,
	`1`,
	`""`,
	`"foo"`,
	`"bar"`,
	`"null"`,
	`[]`,
	`[null]`,
	`[null,null,null]`,
	`[1]`,
	`[1,2,3]`,
	`[{},[],3]`,
	`[1,{},[]]`,
	`{}`,
	`{"foo":"bar"}`,
	`{"foo":null}`,
	`{"foo":1}`,
	`{"foo":[]}`,
	`{"foo":[null]}`,
	`{"foo":[1]}`,
	`{"foo":[1,2,3]}`,
	`{"foo":[1,null,3]}`,
	`{"foo":{}}`,
	`{"foo":{"bar":null}}`,
	`{"foo":{"bar":1}}`,
	`{"foo":{"bar":[]}}`,
	`{"foo":{"bar":[1,2,3]}}`,
	`{"foo":{"bar":{}}}`,
}

func FuzzJd(f *testing.F) {
	for _, a := range corpus {
		_, err := ReadJsonString(a)
		if err != nil {
			f.Errorf("corpus entry not valid JSON: %q", a)
		}
		for _, b := range corpus {
			f.Add(a, b)
		}
	}
	f.Fuzz(fuzz)
}

func fuzz(t *testing.T, aStr, bStr string) {
	// Only valid JSON input.
	a, err := ReadJsonString(aStr)
	if err != nil {
		return
	}
	if a == nil {
		t.Errorf("nil parsed input: %q", aStr)
		return
	}
	b, err := ReadJsonString(bStr)
	if err != nil {
		return
	}
	if b == nil {
		t.Errorf("nil parsed input: %q", bStr)
		return
	}
	for _, format := range [][2]string{{
		"jd", "list",
	}, {
		"jd", "set",
	}, {
		"jd", "mset",
	}, {
		"patch", "list",
	}} {
		a, _ = ReadJsonString(aStr) // Fresh parsed copy.
		var metadata []Metadata
		switch format[0] {
		case "jd":
			switch format[1] {
			case "set":
				metadata = append(metadata, SET)
			case "mset":
				metadata = append(metadata, MULTISET)
			default: // list
			}
		default: // patch
		}

		// Diff A and B.
		d := a.Diff(b, metadata...)
		if d == nil {
			t.Errorf("nil diff of a and b")
			return
		}
		if format[0] == "patch" && hasUnsupportedObjectKey(d) {
			return
		}
		var diffABStr string
		var diffAB Diff
		switch format[0] {
		case "jd":
			diffABStr = d.Render()
			diffAB, err = ReadDiffString(diffABStr)
		case "patch":
			diffABStr, err = d.RenderPatch()
			if err != nil {
				t.Errorf("could not render diff %v as patch: %v", d, err)
				return
			}
			diffAB, err = ReadPatchString(diffABStr)
		}
		if err != nil {
			t.Errorf("error parsing diff string %q: %v", diffABStr, err)
			return
		}
		// Apply diff to A to get B.
		patchedA, err := a.Patch(diffAB)
		if err != nil {
			t.Errorf("applying patch %v to %v should give %v. Got err: %v", diffAB.Render(), aStr, bStr, err)
			return
		}
		if !patchedA.Equals(b, metadata...) {
			t.Errorf("applying patch %v to %v should give %v. Got: %v", diffAB.Render(), aStr, bStr, patchedA)
			return
		}
	}

}

func hasUnsupportedObjectKey(diff Diff) bool {
	for _, d := range diff {
		for _, p := range d.Path {
			if s, ok := p.(jsonString); ok {
				// Object key that looks like number is interpretted incorrectly as array index.
				if _, err := strconv.Atoi(string(s)); err == nil {
					return true
				}
				// Object key "-" is interpretted incorrectly as append-to-array.
				if string(s) == "-" {
					return true
				}
			}
		}
	}
	return false
}
<commit_msg>Add merge patch fuzzing.<commit_after>package jd

import (
	"strconv"
	"testing"
)

var corpus = []string{
	``,  // void
	` `, // void
	`null`,
	`0`,
	`1`,
	`""`,
	`"foo"`,
	`"bar"`,
	`"null"`,
	`[]`,
	`[null]`,
	`[null,null,null]`,
	`[1]`,
	`[1,2,3]`,
	`[{},[],3]`,
	`[1,{},[]]`,
	`{}`,
	`{"foo":"bar"}`,
	`{"foo":null}`,
	`{"foo":1}`,
	`{"foo":[]}`,
	`{"foo":[null]}`,
	`{"foo":[1]}`,
	`{"foo":[1,2,3]}`,
	`{"foo":[1,null,3]}`,
	`{"foo":{}}`,
	`{"foo":{"bar":null}}`,
	`{"foo":{"bar":1}}`,
	`{"foo":{"bar":[]}}`,
	`{"foo":{"bar":[1,2,3]}}`,
	`{"foo":{"bar":{}}}`,
}

func FuzzJd(f *testing.F) {
	for _, a := range corpus {
		_, err := ReadJsonString(a)
		if err != nil {
			f.Errorf("corpus entry not valid JSON: %q", a)
		}
		for _, b := range corpus {
			f.Add(a, b)
		}
	}
	f.Fuzz(fuzz)
}

func fuzz(t *testing.T, aStr, bStr string) {
	// Only valid JSON input.
	a, err := ReadJsonString(aStr)
	if err != nil {
		return
	}
	if a == nil {
		t.Errorf("nil parsed input: %q", aStr)
		return
	}
	b, err := ReadJsonString(bStr)
	if err != nil {
		return
	}
	if b == nil {
		t.Errorf("nil parsed input: %q", bStr)
		return
	}
	for _, format := range [][2]string{{
		"jd", "list",
	}, {
		"jd", "set",
	}, {
		"jd", "mset",
	}, {
		"patch", "list",
	}, {
		"merge", "list",
	}} {
		a, _ = ReadJsonString(aStr) // Fresh parsed copy.
		if format[0] == "merge" {
			if hasUnsupportedNullValue(a) {
				continue
			}
			if hasUnsupportedNullValue(b) {
				continue
			}
		}
		var metadata []Metadata
		switch format[0] {
		case "jd":
			switch format[1] {
			case "set":
				metadata = append(metadata, SET)
			case "mset":
				metadata = append(metadata, MULTISET)
			default: // list
			}
		case "merge":
			metadata = append(metadata, MERGE)
		default: // patch
		}

		// Diff A and B.
		d := a.Diff(b, metadata...)
		if d == nil {
			t.Errorf("nil diff of a and b")
			return
		}
		if format[0] == "patch" && hasUnsupportedObjectKey(d) {
			return
		}
		var diffABStr string
		var diffAB Diff
		switch format[0] {
		case "jd":
			diffABStr = d.Render()
			diffAB, err = ReadDiffString(diffABStr)
		case "patch":
			diffABStr, err = d.RenderPatch()
			if err != nil {
				t.Errorf("could not render diff %v as patch: %v", d, err)
				return
			}
			diffAB, err = ReadPatchString(diffABStr)
		case "merge":
			diffABStr, err = d.RenderMerge()
			if err != nil {
				t.Errorf("could not render diff %v as merge: %v", d, err)
				return
			}
			diffAB, err = ReadMergeString(diffABStr)
		}
		if err != nil {
			t.Errorf("error parsing diff string %q: %v", diffABStr, err)
			return
		}
		// Apply diff to A to get B.
		patchedA, err := a.Patch(diffAB)
		if err != nil {
			t.Errorf("applying patch %v to %v should give %v. Got err: %v", diffAB.Render(), aStr, bStr, err)
			return
		}
		if !patchedA.Equals(b, metadata...) {
			t.Errorf("applying patch %v to %v should give %v. Got: %v", diffAB.Render(), aStr, bStr, patchedA)
			return
		}
	}

}

func hasUnsupportedObjectKey(diff Diff) bool {
	for _, d := range diff {
		for _, p := range d.Path {
			if s, ok := p.(jsonString); ok {
				// Object key that looks like number is interpretted incorrectly as array index.
				if _, err := strconv.Atoi(string(s)); err == nil {
					return true
				}
				// Object key "-" is interpretted incorrectly as append-to-array.
				if string(s) == "-" {
					return true
				}
			}
		}
	}
	return false
}

func hasUnsupportedNullValue(node JsonNode) bool {
	switch n := node.(type) {
	case jsonObject:
		for _, v := range n {
			if isNull(v) {
				return true
			}
			return hasUnsupportedNullValue(v)
		}
		return false
	case jsonArray, jsonList, jsonSet, jsonMultiset:
		for _, v := range n.(jsonArray) {
			if isNull(v) {
				return true
			}
			return hasUnsupportedNullValue(v)
		}
		return false
	case jsonNull:
		return true
	default:
		return false
	}
}
<|endoftext|>


<commit_before>package handlers

import (
	"socialapi/workers/common/handler"
	"socialapi/workers/common/mux"
)

func (h *Handler) AddHandlers(m *mux.Mux) {

	// channel authentication
	m.AddSessionlessHandler(
		handler.Request{
			Handler:        h.Authenticate,
			Name:           "channel-authenticate",
			Type:           handler.PostRequest,
			Endpoint:       "/channel/{name}/authenticate",
			CollectMetrics: true,
		})

	// channel push message
	m.AddSessionlessHandler(
		handler.Request{
			Handler:        h.Push,
			Name:           "channel-push",
			Type:           handler.PostRequest,
			Endpoint:       "/channel/{name}/push",
			CollectMetrics: true,
		})
}
<commit_msg>gatekeeper: use channel/{id}/fetch as endpoint<commit_after>package handlers

import (
	"socialapi/workers/common/handler"
	"socialapi/workers/common/mux"
)

func (h *Handler) AddHandlers(m *mux.Mux) {

	// channel authentication
	m.AddSessionlessHandler(
		handler.Request{
			Handler:        h.Authenticate,
			Name:           "channel-authenticate",
			Type:           handler.PostRequest,
			Endpoint:       "/channel/{name}/authenticate",
			CollectMetrics: true,
		})

	// channel push message
	m.AddSessionlessHandler(
		handler.Request{
			Handler:        h.Push,
			Name:           "channel-push",
			Type:           handler.PostRequest,
			Endpoint:       "/channel/{id}/push",
			CollectMetrics: true,
		})
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"runtime"
	"strings"

	"github.com/cloudfoundry/cli/cf/commandregistry"
	"github.com/cloudfoundry/cli/cf/configuration/confighelpers"
	"github.com/cloudfoundry/cli/cf/configuration/coreconfig"
	"github.com/cloudfoundry/cli/cf/configuration/pluginconfig"
	. "github.com/cloudfoundry/cli/cf/i18n"
	"github.com/cloudfoundry/cli/cf/net"
	"github.com/cloudfoundry/cli/cf/panicprinter"
	"github.com/cloudfoundry/cli/cf/requirements"
	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/cloudfoundry/cli/cf/trace"
	"github.com/cloudfoundry/cli/commandsloader"
	"github.com/cloudfoundry/cli/flags"
	"github.com/cloudfoundry/cli/plugin/rpc"
)

var cmdRegistry = commandregistry.Commands

func main() {
	traceEnv := os.Getenv("CF_TRACE")
	traceLogger := trace.NewLogger(false, traceEnv, "")

	//handle `cf -v` for cf version
	if len(os.Args) == 2 && (os.Args[1] == "-v" || os.Args[1] == "--version") {
		os.Args[1] = "version"
	}

	//handles `cf`
	if len(os.Args) == 1 {
		os.Args = []string{os.Args[0], "help"}
	}

	//handles `cf [COMMAND] -h ...`
	//rearrange args to `cf help COMMAND` and let `command help` to print out usage
	os.Args = append([]string{os.Args[0]}, handleHelp(os.Args[1:])...)

	newArgs, isVerbose := handleVerbose(os.Args)
	os.Args = newArgs
	traceLogger = trace.NewLogger(isVerbose, traceEnv, "")

	errFunc := func(err error) {
		if err != nil {
			ui := terminal.NewUI(os.Stdin, terminal.NewTeePrinter(), traceLogger)
			ui.Failed(fmt.Sprintf("Config error: %s", err))
		}
	}

	// Only used to get Trace, so our errorHandler doesn't matter, since it's not used
	configPath, err := confighelpers.DefaultFilePath()
	if err != nil {
		errFunc(err)
	}
	config := coreconfig.NewRepositoryFromFilepath(configPath, errFunc)
	defer config.Close()

	traceConfigVal := config.Trace()

	traceLogger = trace.NewLogger(isVerbose, traceEnv, traceConfigVal)

	deps := commandregistry.NewDependency(traceLogger)
	defer handlePanics(deps.TeePrinter, deps.Logger)
	defer deps.Config.Close()

	//handle `cf --build`
	if len(os.Args) == 2 && (os.Args[1] == "--build" || os.Args[1] == "-b") {
		deps.UI.Say(T("{{.CFName}} was built with Go version: {{.GoVersion}}",
			map[string]interface{}{
				"CFName":    os.Args[0],
				"GoVersion": runtime.Version(),
			}))
		os.Exit(0)
	}

	warningProducers := []net.WarningProducer{}
	for _, warningProducer := range deps.Gateways {
		warningProducers = append(warningProducers, warningProducer)
	}

	warningsCollector := net.NewWarningsCollector(deps.UI, warningProducers...)

	commandsloader.Load()

	//run core command
	cmdName := os.Args[1]
	cmd := cmdRegistry.FindCommand(cmdName)
	if cmd != nil {
		meta := cmd.MetaData()
		flagContext := flags.NewFlagContext(meta.Flags)
		flagContext.SkipFlagParsing(meta.SkipFlagParsing)

		cmdArgs := os.Args[2:]
		err := flagContext.Parse(cmdArgs...)
		if err != nil {
			usage := cmdRegistry.CommandUsage(cmdName)
			deps.UI.Failed(T("Incorrect Usage") + "\n\n" + err.Error() + "\n\n" + usage)
		}

		cmd = cmd.SetDependency(deps, false)
		cmdRegistry.SetCommand(cmd)

		requirementsFactory := requirements.NewFactory(deps.Config, deps.RepoLocator)
		reqs := cmd.Requirements(requirementsFactory, flagContext)

		for _, req := range reqs {
			err = req.Execute()
			if err != nil {
				deps.UI.Failed(err.Error())
			}
		}

		cmd.Execute(flagContext)

		warningsCollector.PrintWarnings()

		os.Exit(0)
	}

	//non core command, try plugin command
	rpcService, err := rpc.NewRpcService(deps.TeePrinter, deps.TeePrinter, deps.Config, deps.RepoLocator, rpc.NewCommandRunner(), deps.Logger)
	if err != nil {
		deps.UI.Say(T("Error initializing RPC service: ") + err.Error())
		os.Exit(1)
	}

	pluginConfig := pluginconfig.NewPluginConfig(func(err error) {
		deps.UI.Failed(fmt.Sprintf("Error read/writing plugin config: %s, ", err.Error()))
	})
	pluginList := pluginConfig.Plugins()

	ran := rpc.RunMethodIfExists(rpcService, os.Args[1:], pluginList)
	if !ran {
		deps.UI.Say("'" + os.Args[1] + T("' is not a registered command. See 'cf help'"))
		os.Exit(1)
	}

}

func handlePanics(printer terminal.Printer, logger trace.Printer) {
	panicprinter.UI = terminal.NewUI(os.Stdin, printer, logger)

	commandArgs := strings.Join(os.Args, " ")
	stackTrace := generateBacktrace()

	err := recover()
	panicprinter.DisplayCrashDialog(err, commandArgs, stackTrace)

	if err != nil {
		os.Exit(1)
	}
}

func generateBacktrace() string {
	stackByteCount := 0
	STACK_SIZE_LIMIT := 1024 * 1024
	var bytes []byte
	for stackSize := 1024; (stackByteCount == 0 || stackByteCount == stackSize) && stackSize < STACK_SIZE_LIMIT; stackSize = 2 * stackSize {
		bytes = make([]byte, stackSize)
		stackByteCount = runtime.Stack(bytes, true)
	}
	stackTrace := "\t" + strings.Replace(string(bytes), "\n", "\n\t", -1)
	return stackTrace
}

func handleHelp(args []string) []string {
	hIndex := -1

	for i, v := range args {
		if v == "-h" || v == "--help" || v == "--h" {
			hIndex = i
			break
		}
	}

	if hIndex == -1 {
		return args
	} else if len(args) > 1 {
		if hIndex == 0 {
			return []string{"help", args[1]}
		} else {
			return []string{"help", args[0]}
		}
	} else {
		return []string{"help"}
	}
}

func handleVerbose(args []string) ([]string, bool) {
	var verbose bool
	idx := -1

	for i, arg := range args {
		if arg == "-v" {
			idx = i
			break
		}
	}

	if idx != -1 && len(args) > 1 {
		verbose = true
		args = append(args[:idx], args[idx+1:]...)
	}

	return args, verbose
}
<commit_msg>Fix err variable shadowing govet error<commit_after>package main

import (
	"fmt"
	"os"
	"runtime"
	"strings"

	"github.com/cloudfoundry/cli/cf/commandregistry"
	"github.com/cloudfoundry/cli/cf/configuration/confighelpers"
	"github.com/cloudfoundry/cli/cf/configuration/coreconfig"
	"github.com/cloudfoundry/cli/cf/configuration/pluginconfig"
	. "github.com/cloudfoundry/cli/cf/i18n"
	"github.com/cloudfoundry/cli/cf/net"
	"github.com/cloudfoundry/cli/cf/panicprinter"
	"github.com/cloudfoundry/cli/cf/requirements"
	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/cloudfoundry/cli/cf/trace"
	"github.com/cloudfoundry/cli/commandsloader"
	"github.com/cloudfoundry/cli/flags"
	"github.com/cloudfoundry/cli/plugin/rpc"
)

var cmdRegistry = commandregistry.Commands

func main() {
	traceEnv := os.Getenv("CF_TRACE")
	traceLogger := trace.NewLogger(false, traceEnv, "")

	//handle `cf -v` for cf version
	if len(os.Args) == 2 && (os.Args[1] == "-v" || os.Args[1] == "--version") {
		os.Args[1] = "version"
	}

	//handles `cf`
	if len(os.Args) == 1 {
		os.Args = []string{os.Args[0], "help"}
	}

	//handles `cf [COMMAND] -h ...`
	//rearrange args to `cf help COMMAND` and let `command help` to print out usage
	os.Args = append([]string{os.Args[0]}, handleHelp(os.Args[1:])...)

	newArgs, isVerbose := handleVerbose(os.Args)
	os.Args = newArgs
	traceLogger = trace.NewLogger(isVerbose, traceEnv, "")

	errFunc := func(err error) {
		if err != nil {
			ui := terminal.NewUI(os.Stdin, terminal.NewTeePrinter(), traceLogger)
			ui.Failed(fmt.Sprintf("Config error: %s", err))
		}
	}

	// Only used to get Trace, so our errorHandler doesn't matter, since it's not used
	configPath, err := confighelpers.DefaultFilePath()
	if err != nil {
		errFunc(err)
	}
	config := coreconfig.NewRepositoryFromFilepath(configPath, errFunc)
	defer config.Close()

	traceConfigVal := config.Trace()

	traceLogger = trace.NewLogger(isVerbose, traceEnv, traceConfigVal)

	deps := commandregistry.NewDependency(traceLogger)
	defer handlePanics(deps.TeePrinter, deps.Logger)
	defer deps.Config.Close()

	//handle `cf --build`
	if len(os.Args) == 2 && (os.Args[1] == "--build" || os.Args[1] == "-b") {
		deps.UI.Say(T("{{.CFName}} was built with Go version: {{.GoVersion}}",
			map[string]interface{}{
				"CFName":    os.Args[0],
				"GoVersion": runtime.Version(),
			}))
		os.Exit(0)
	}

	warningProducers := []net.WarningProducer{}
	for _, warningProducer := range deps.Gateways {
		warningProducers = append(warningProducers, warningProducer)
	}

	warningsCollector := net.NewWarningsCollector(deps.UI, warningProducers...)

	commandsloader.Load()

	//run core command
	cmdName := os.Args[1]
	cmd := cmdRegistry.FindCommand(cmdName)
	if cmd != nil {
		meta := cmd.MetaData()
		flagContext := flags.NewFlagContext(meta.Flags)
		flagContext.SkipFlagParsing(meta.SkipFlagParsing)

		cmdArgs := os.Args[2:]
		err = flagContext.Parse(cmdArgs...)
		if err != nil {
			usage := cmdRegistry.CommandUsage(cmdName)
			deps.UI.Failed(T("Incorrect Usage") + "\n\n" + err.Error() + "\n\n" + usage)
		}

		cmd = cmd.SetDependency(deps, false)
		cmdRegistry.SetCommand(cmd)

		requirementsFactory := requirements.NewFactory(deps.Config, deps.RepoLocator)
		reqs := cmd.Requirements(requirementsFactory, flagContext)

		for _, req := range reqs {
			err = req.Execute()
			if err != nil {
				deps.UI.Failed(err.Error())
			}
		}

		cmd.Execute(flagContext)

		warningsCollector.PrintWarnings()

		os.Exit(0)
	}

	//non core command, try plugin command
	rpcService, err := rpc.NewRpcService(deps.TeePrinter, deps.TeePrinter, deps.Config, deps.RepoLocator, rpc.NewCommandRunner(), deps.Logger)
	if err != nil {
		deps.UI.Say(T("Error initializing RPC service: ") + err.Error())
		os.Exit(1)
	}

	pluginConfig := pluginconfig.NewPluginConfig(func(err error) {
		deps.UI.Failed(fmt.Sprintf("Error read/writing plugin config: %s, ", err.Error()))
	})
	pluginList := pluginConfig.Plugins()

	ran := rpc.RunMethodIfExists(rpcService, os.Args[1:], pluginList)
	if !ran {
		deps.UI.Say("'" + os.Args[1] + T("' is not a registered command. See 'cf help'"))
		os.Exit(1)
	}

}

func handlePanics(printer terminal.Printer, logger trace.Printer) {
	panicprinter.UI = terminal.NewUI(os.Stdin, printer, logger)

	commandArgs := strings.Join(os.Args, " ")
	stackTrace := generateBacktrace()

	err := recover()
	panicprinter.DisplayCrashDialog(err, commandArgs, stackTrace)

	if err != nil {
		os.Exit(1)
	}
}

func generateBacktrace() string {
	stackByteCount := 0
	STACK_SIZE_LIMIT := 1024 * 1024
	var bytes []byte
	for stackSize := 1024; (stackByteCount == 0 || stackByteCount == stackSize) && stackSize < STACK_SIZE_LIMIT; stackSize = 2 * stackSize {
		bytes = make([]byte, stackSize)
		stackByteCount = runtime.Stack(bytes, true)
	}
	stackTrace := "\t" + strings.Replace(string(bytes), "\n", "\n\t", -1)
	return stackTrace
}

func handleHelp(args []string) []string {
	hIndex := -1

	for i, v := range args {
		if v == "-h" || v == "--help" || v == "--h" {
			hIndex = i
			break
		}
	}

	if hIndex == -1 {
		return args
	} else if len(args) > 1 {
		if hIndex == 0 {
			return []string{"help", args[1]}
		} else {
			return []string{"help", args[0]}
		}
	} else {
		return []string{"help"}
	}
}

func handleVerbose(args []string) ([]string, bool) {
	var verbose bool
	idx := -1

	for i, arg := range args {
		if arg == "-v" {
			idx = i
			break
		}
	}

	if idx != -1 && len(args) > 1 {
		verbose = true
		args = append(args[:idx], args[idx+1:]...)
	}

	return args, verbose
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/couchbaselabs/logg"
	"github.com/tleyden/checkerlution"
	ng "github.com/tleyden/neurgo"
)

func init() {
	logg.LogKeys["MAIN"] = true
	logg.LogKeys["DEBUG"] = true
	logg.LogKeys["NEURGO"] = true
	logg.LogKeys["NODE_PRE_SEND"] = true
	logg.LogKeys["NODE_POST_SEND"] = true
	logg.LogKeys["NODE_POST_RECV"] = true
	logg.LogKeys["NODE_STATE"] = true
	ng.SeedRandom()
}

func main() {
	// checkerlution.RunTopologyMutatingTrainer()
	checkerlution.RunPopulationTrainer()
}
<commit_msg>debug sensor and actuator sync<commit_after>package main

import (
	"github.com/couchbaselabs/logg"
	"github.com/tleyden/checkerlution"
	ng "github.com/tleyden/neurgo"
)

func init() {
	logg.LogKeys["MAIN"] = true
	logg.LogKeys["DEBUG"] = true
	logg.LogKeys["NEURGO"] = true
	logg.LogKeys["SENSOR_SYNC"] = true
	logg.LogKeys["ACTUATOR_SYNC"] = true
	logg.LogKeys["NODE_PRE_SEND"] = true
	logg.LogKeys["NODE_POST_SEND"] = true
	logg.LogKeys["NODE_POST_RECV"] = true
	logg.LogKeys["NODE_STATE"] = true
	ng.SeedRandom()
}

func main() {
	// checkerlution.RunTopologyMutatingTrainer()
	checkerlution.RunPopulationTrainer()
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"flag"
	"fmt"
	"github.com/fatih/color"
	"io"
	"log"
	"os"
	"strings"
)

const (
	versionString = "kubectl-repl {{{VERSION}}}"
)

var (
	input     *bufio.Reader
	namespace string
	context   string
	verbose   bool
)

func prompt() (string, error) {
	color.New(color.Bold).Print("# ")

	if context != "" {
		color.New(color.FgBlack, color.Italic).Print(context)
		fmt.Print(" ")
	}

	if namespace != "" {
		color.New(color.Bold).Print(namespace)
	} else {
		color.New(color.Bold).Print("namespace")
	}
	fmt.Print(" ")

	line, err := input.ReadString('\n')
	if err != nil {
		return "", err
	}
	response := strings.Trim(line, "\n")
	return substituteForVars(response)
}

func printIndexedLine(index, line string) {
	coloredIndex := color.New(color.FgBlue).Sprintf("$%s", index)
	fmt.Printf("%s \t%s\n", coloredIndex, line)
}

func repl(commands Commands) error {
	command, err := prompt()
	if err != nil {
		return err
	}

	if strings.TrimSpace(command) == "" {
		return nil
	}

	for _, builtin := range commands {
		if builtin.filter(command) {
			return builtin.run(command)
		}
	}

	return sh(kubectl(command))
}

func main() {
	var version bool
	flag.BoolVar(&verbose, "verbose", false, "Verbose")
	flag.BoolVar(&version, "version", false, "Print current version")
	flag.StringVar(&context, "context", "", "Override current context")
	flag.Parse()

	if version {
		fmt.Println(versionString)
		return
	}

	commands := Commands{
		builtinExit{},
		builtinNamespace{},
		builtinShell{},
		builtinGet{},
	}
	err := commands.Init()
	if err != nil {
		log.Fatal(err)
	}

	variables = make(map[string][]string)
	input = bufio.NewReader(os.Stdin)

	err = pickNamespace()
	if err == io.EOF {
		return
	} else if err != nil {
		log.Fatal(err)
	}

	for {
		err = repl(commands)
		if err == io.EOF {
			break
		} else if err != nil {
			color.New(color.FgRed).Println(err)
		}
	}
}
<commit_msg>Ignore input lines starting with `#` (comments)<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"github.com/fatih/color"
	"io"
	"log"
	"os"
	"strings"
)

const (
	versionString = "kubectl-repl {{{VERSION}}}"
)

var (
	input     *bufio.Reader
	namespace string
	context   string
	verbose   bool
)

func prompt() (string, error) {
	color.New(color.Bold).Print("# ")

	if context != "" {
		color.New(color.FgBlack, color.Italic).Print(context)
		fmt.Print(" ")
	}

	if namespace != "" {
		color.New(color.Bold).Print(namespace)
	} else {
		color.New(color.Bold).Print("namespace")
	}
	fmt.Print(" ")

	line, err := input.ReadString('\n')
	if err != nil {
		return "", err
	}
	response := strings.Trim(line, "\n")
	return substituteForVars(response)
}

func printIndexedLine(index, line string) {
	coloredIndex := color.New(color.FgBlue).Sprintf("$%s", index)
	fmt.Printf("%s \t%s\n", coloredIndex, line)
}

func repl(commands Commands) error {
	command, err := prompt()
	if err != nil {
		return err
	}

	if trimmed := strings.TrimSpace(command); trimmed == "" || strings.HasPrefix(trimmed, "#") {
		return nil
	}

	for _, builtin := range commands {
		if builtin.filter(command) {
			return builtin.run(command)
		}
	}

	return sh(kubectl(command))
}

func main() {
	var version bool
	flag.BoolVar(&verbose, "verbose", false, "Verbose")
	flag.BoolVar(&version, "version", false, "Print current version")
	flag.StringVar(&context, "context", "", "Override current context")
	flag.Parse()

	if version {
		fmt.Println(versionString)
		return
	}

	commands := Commands{
		builtinExit{},
		builtinNamespace{},
		builtinShell{},
		builtinGet{},
	}
	err := commands.Init()
	if err != nil {
		log.Fatal(err)
	}

	variables = make(map[string][]string)
	input = bufio.NewReader(os.Stdin)

	err = pickNamespace()
	if err == io.EOF {
		return
	} else if err != nil {
		log.Fatal(err)
	}

	for {
		err = repl(commands)
		if err == io.EOF {
			break
		} else if err != nil {
			color.New(color.FgRed).Println(err)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	_ "expvar"
	"github.com/couchbaselabs/logg"
	"github.com/tleyden/checkerlution"
	ng "github.com/tleyden/neurgo"
	"net/http"
)

func init() {
	logg.LogKeys["MAIN"] = true
	logg.LogKeys["DEBUG"] = true
	logg.LogKeys["CHECKERLUTION_SCAPE"] = true
	logg.LogKeys["NEURGO"] = false
	logg.LogKeys["SENSOR_SYNC"] = false
	logg.LogKeys["ACTUATOR_SYNC"] = false
	logg.LogKeys["NODE_PRE_SEND"] = false
	logg.LogKeys["NODE_POST_SEND"] = false
	logg.LogKeys["NODE_POST_RECV"] = false
	logg.LogKeys["NODE_STATE"] = false
	ng.SeedRandom()
}

func main() {

	// run a webserver in order to view expvar output
	// at http://localhost:8080/debug/vars
	go http.ListenAndServe(":8080", nil)

	trainer := &checkerlution.CheckerlutionTrainer{}

	// checkerlution.RunTopologyMutatingTrainer()
	trainer.RunPopulationTrainer()

}
<commit_msg>run checkerlution bot in run mode (as opposed to training mode)<commit_after>package main

import (
	_ "expvar"
	"github.com/couchbaselabs/logg"
	"github.com/tleyden/checkerlution"
	cbot "github.com/tleyden/checkers-bot"
	ng "github.com/tleyden/neurgo"
	"net/http"
)

func init() {
	logg.LogKeys["MAIN"] = true
	logg.LogKeys["DEBUG"] = true
	logg.LogKeys["CHECKERLUTION"] = true
	logg.LogKeys["CHECKERLUTION_SCAPE"] = true
	logg.LogKeys["NEURGO"] = false
	logg.LogKeys["SENSOR_SYNC"] = false
	logg.LogKeys["ACTUATOR_SYNC"] = false
	logg.LogKeys["NODE_PRE_SEND"] = false
	logg.LogKeys["NODE_POST_SEND"] = false
	logg.LogKeys["NODE_POST_RECV"] = false
	logg.LogKeys["NODE_STATE"] = false
	ng.SeedRandom()
}

func train() {

	// run a webserver in order to view expvar output
	// at http://localhost:8080/debug/vars
	go http.ListenAndServe(":8080", nil)

	trainer := &checkerlution.CheckerlutionTrainer{}

	// checkerlution.RunTopologyMutatingTrainer()
	trainer.RunPopulationTrainer()

}

func run() {

	checkersBotFlags := cbot.ParseCmdLine()

	thinker := &checkerlution.Checkerlution{}
	thinker.SetMode(checkerlution.RUNNING_MODE)
	thinker.Start(checkersBotFlags.Team) // TODO: take filename and call StartWithCortex

	game := cbot.NewGame(checkersBotFlags.Team, thinker)
	game.SetServerUrl(checkersBotFlags.SyncGatewayUrl)
	game.SetFeedType(checkersBotFlags.FeedType)
	game.SetDelayBeforeMove(checkersBotFlags.RandomDelayBeforeMove)

	logg.LogTo("CHECKERLUTION", "Starting game loop")
	game.GameLoop()
	logg.LogTo("CHECKERLUTION", "Game loop finished")

}

func main() {
	MODE := 0
	if MODE == 0 {
		run()
	} else {
		train()
	}

}
<|endoftext|>


<commit_before>package daemon

import (
	"strings"
	"time"

	"github.com/go-kit/kit/log"
	"github.com/pkg/errors"

	"sync"

	"github.com/weaveworks/flux"
	"github.com/weaveworks/flux/git"
	"github.com/weaveworks/flux/history"
	"github.com/weaveworks/flux/resource"
	fluxsync "github.com/weaveworks/flux/sync"
	"github.com/weaveworks/flux/update"
)

type LoopVars struct {
	GitPollInterval      time.Duration
	RegistryPollInterval time.Duration
	syncSoon             chan struct{}
	pollImagesSoon       chan struct{}
	initOnce             sync.Once
}

func (loop *LoopVars) ensureInit() {
	loop.initOnce.Do(func() {
		loop.syncSoon = make(chan struct{}, 1)
		loop.pollImagesSoon = make(chan struct{}, 1)
	})
}

// Loop for potentially long-running stuff. This includes running
// jobs, and looking for new commits.

func (d *Daemon) ImagePollLoop(stop chan struct{}, wg *sync.WaitGroup, logger log.Logger) {
	defer wg.Done()

	imagePollTicker := time.NewTicker(d.RegistryPollInterval)
	d.askForImagePoll()
	for {
		select {
		case <-stop:
			logger.Log("stopping", "true")
			return
		case <-d.pollImagesSoon:
			d.pollForNewImages(logger)
		case <-imagePollTicker.C:
			// Time to poll for new images
			d.askForImagePoll()
		}
	}
}

func (d *Daemon) GitPollLoop(stop chan struct{}, wg *sync.WaitGroup, logger log.Logger) {
	defer wg.Done()
	// We want to pull the repo and sync at least every
	// `GitPollInterval`. Being told to sync, or completing a job, may
	// intervene (in which case, reschedule the next pull-and-sync)
	gitPollTimer := time.NewTimer(d.GitPollInterval)
	pullThen := func(k func(logger log.Logger)) {
		defer func() {
			gitPollTimer.Stop()
			gitPollTimer = time.NewTimer(d.GitPollInterval)
		}()
		if err := d.Checkout.Pull(); err != nil {
			logger.Log("operation", "pull", "err", err)
			return
		}
		k(logger)
	}

	// Ask for a sync, and to poll images, straight away
	d.askForSync()
	for {
		select {
		case <-stop:
			logger.Log("stopping", "true")
			return
		case <-d.syncSoon:
			pullThen(d.doSync)
		case <-gitPollTimer.C:
			// Time to poll for new commits (unless we're already
			// about to do that)
			d.askForSync()
		case job := <-d.Jobs.Ready():
			jobLogger := log.NewContext(logger).With("jobID", job.ID)
			jobLogger.Log("state", "in-progress")
			// It's assumed that (successful) jobs will push commits
			// to the upstream repo, and therefore we probably want to
			// pull from there and sync the cluster afterwards.
			if err := job.Do(jobLogger); err != nil {
				jobLogger.Log("state", "done", "success", "false", "err", err)
				continue
			}
			jobLogger.Log("state", "done", "success", "true")
			pullThen(d.doSync)
		}
	}
}

// Ask for a sync, or if there's one waiting, let that happen.
func (d *LoopVars) askForSync() {
	d.ensureInit()
	select {
	case d.syncSoon <- struct{}{}:
	default:
	}
}

// Ask for an image poll, or if there's one waiting, let that happen.
func (d *LoopVars) askForImagePoll() {
	d.ensureInit()
	select {
	case d.pollImagesSoon <- struct{}{}:
	default:
	}
}

// -- extra bits the loop needs

func (d *Daemon) doSync(logger log.Logger) {
	started := time.Now().UTC()

	// Pull for new commits
	if err := d.Checkout.Pull(); err != nil {
		logger.Log("err", err)
		return
	}

	// checkout a working clone so we can mess around with tags later
	working, err := d.Checkout.WorkingClone()
	if err != nil {
		logger.Log("err", err)
		return
	}
	defer working.Clean()

	// TODO logging, metrics?
	// Get a map of all resources defined in the repo
	allResources, err := d.Manifests.LoadManifests(working.ManifestDir())
	if err != nil {
		logger.Log("err", errors.Wrap(err, "loading resources from repo"))
		return
	}

	// TODO supply deletes argument from somewhere (command-line?)
	if err := fluxsync.Sync(d.Manifests, allResources, d.Cluster, false, logger); err != nil {
		logger.Log("err", err)
	}

	// Figure out which service IDs changed in this release
	changedResources := map[string]resource.Resource{}
	changedFiles, err := working.ChangedFiles(working.SyncTag)
	switch {
	case err == nil:
		// We had some changed files, we're syncing a diff
		changedResources, err = d.Manifests.LoadManifests(changedFiles...)
		if err != nil {
			logger.Log("err", errors.Wrap(err, "loading resources from repo"))
			return
		}
	case isUnknownRevision(err):
		// no synctag, We are syncing everything from scratch
		changedResources = allResources
	default:
		logger.Log("err", err)
	}
	serviceIDs := flux.ServiceIDSet{}
	for _, r := range changedResources {
		serviceIDs.Add(r.ServiceIDs(allResources))
	}

	// update notes and emit events for applied commits
	revisions, err := working.RevisionsBetween(working.SyncTag, "HEAD")
	if isUnknownRevision(err) {
		// No sync tag, grab all revisions
		revisions, err = working.RevisionsBefore("HEAD")
	}
	if err != nil {
		logger.Log("err", err)
	}

	// Emit an event
	if len(revisions) > 0 {
		if err := d.LogEvent(history.Event{
			ServiceIDs: serviceIDs.ToSlice(),
			Type:       history.EventSync,
			StartedAt:  started,
			EndedAt:    started,
			LogLevel:   history.LogLevelInfo,
			Metadata:   &history.SyncEventMetadata{Revisions: revisions},
		}); err != nil {
			logger.Log("err", err)
		}

		// Find notes in revisions.
		for i := len(revisions) - 1; i >= 0; i-- {
			n, err := working.GetNote(revisions[i])
			if err != nil {
				logger.Log("err", errors.Wrap(err, "loading notes from repo; possibly no notes"))
				// TODO: We're ignoring all errors here, not just the "no notes" error. Parse error to report proper errors.
				continue
			}
			if n == nil {
				continue
			}

			// If any of the commit notes has a release event, send
			// that to the service
			switch n.Spec.Type {
			case update.Images:
				// Map new note.Spec into ReleaseSpec
				spec := n.Spec.Spec.(update.ReleaseSpec)
				// And create a release event
				// Then wrap inside a ReleaseEventMetadata
				if err := d.LogEvent(history.Event{
					ServiceIDs: serviceIDs.ToSlice(),
					Type:       history.EventRelease,
					StartedAt:  started,
					EndedAt:    time.Now().UTC(),
					LogLevel:   history.LogLevelInfo,
					Metadata: &history.ReleaseEventMetadata{
						ReleaseEventCommon: history.ReleaseEventCommon{
							Revision: revisions[i],
							Result:   n.Result,
							Error:    n.Result.Error(),
						},
						Spec:  spec,
						Cause: n.Spec.Cause,
					},
				}); err != nil {
					logger.Log("err", err)
				}
			case update.Auto:
				spec := n.Spec.Spec.(update.Automated)
				if err := d.LogEvent(history.Event{
					ServiceIDs: serviceIDs.ToSlice(),
					Type:       history.EventAutoRelease,
					StartedAt:  started,
					EndedAt:    time.Now().UTC(),
					LogLevel:   history.LogLevelInfo,
					Metadata: &history.AutoReleaseEventMetadata{
						ReleaseEventCommon: history.ReleaseEventCommon{
							Revision: revisions[i],
							Result:   n.Result,
							Error:    n.Result.Error(),
						},
						Spec: spec,
					},
				}); err != nil {
					logger.Log("err", err)
				}
			}
		}
	}

	// Move the tag and push it so we know how far we've gotten.
	if err := working.MoveTagAndPush("HEAD", "Sync pointer"); err != nil {
		logger.Log("err", err)
	}

	// Pull the tag if it has changed
	if err := d.updateTagRev(working, logger); err != nil {
		logger.Log("err", errors.Wrap(err, "updating tag"))
	}
}

func (d *Daemon) updateTagRev(working *git.Checkout, logger log.Logger) error {
	oldTagRev, err := d.Checkout.TagRevision(d.Checkout.SyncTag)
	if err != nil && !strings.Contains(err.Error(), "unknown revision or path not in the working tree") {
		return err
	}
	newTagRev, err := working.TagRevision(working.SyncTag)
	if err != nil {
		return err
	}

	if oldTagRev != newTagRev {
		logger.Log("tag", d.Checkout.SyncTag, "old", oldTagRev, "new", newTagRev)

		if err := d.Checkout.Pull(); err != nil {
			return err
		}
	}

	return nil
}

func isUnknownRevision(err error) bool {
	return err != nil &&
		(strings.Contains(err.Error(), "unknown revision or path not in the working tree.") ||
			strings.Contains(err.Error(), "bad revision"))
}
<commit_msg>Remove extraneous git pull<commit_after>package daemon

import (
	"strings"
	"time"

	"github.com/go-kit/kit/log"
	"github.com/pkg/errors"

	"sync"

	"github.com/weaveworks/flux"
	"github.com/weaveworks/flux/git"
	"github.com/weaveworks/flux/history"
	"github.com/weaveworks/flux/resource"
	fluxsync "github.com/weaveworks/flux/sync"
	"github.com/weaveworks/flux/update"
)

type LoopVars struct {
	GitPollInterval      time.Duration
	RegistryPollInterval time.Duration
	syncSoon             chan struct{}
	pollImagesSoon       chan struct{}
	initOnce             sync.Once
}

func (loop *LoopVars) ensureInit() {
	loop.initOnce.Do(func() {
		loop.syncSoon = make(chan struct{}, 1)
		loop.pollImagesSoon = make(chan struct{}, 1)
	})
}

// Loop for potentially long-running stuff. This includes running
// jobs, and looking for new commits.

func (d *Daemon) ImagePollLoop(stop chan struct{}, wg *sync.WaitGroup, logger log.Logger) {
	defer wg.Done()

	imagePollTicker := time.NewTicker(d.RegistryPollInterval)
	d.askForImagePoll()
	for {
		select {
		case <-stop:
			logger.Log("stopping", "true")
			return
		case <-d.pollImagesSoon:
			d.pollForNewImages(logger)
		case <-imagePollTicker.C:
			// Time to poll for new images
			d.askForImagePoll()
		}
	}
}

func (d *Daemon) GitPollLoop(stop chan struct{}, wg *sync.WaitGroup, logger log.Logger) {
	defer wg.Done()
	// We want to pull the repo and sync at least every
	// `GitPollInterval`. Being told to sync, or completing a job, may
	// intervene (in which case, reschedule the next pull-and-sync)
	gitPollTimer := time.NewTimer(d.GitPollInterval)
	pullThen := func(k func(logger log.Logger)) {
		defer func() {
			gitPollTimer.Stop()
			gitPollTimer = time.NewTimer(d.GitPollInterval)
		}()
		if err := d.Checkout.Pull(); err != nil {
			logger.Log("operation", "pull", "err", err)
			return
		}
		k(logger)
	}

	// Ask for a sync, and to poll images, straight away
	d.askForSync()
	for {
		select {
		case <-stop:
			logger.Log("stopping", "true")
			return
		case <-d.syncSoon:
			pullThen(d.doSync)
		case <-gitPollTimer.C:
			// Time to poll for new commits (unless we're already
			// about to do that)
			d.askForSync()
		case job := <-d.Jobs.Ready():
			jobLogger := log.NewContext(logger).With("jobID", job.ID)
			jobLogger.Log("state", "in-progress")
			// It's assumed that (successful) jobs will push commits
			// to the upstream repo, and therefore we probably want to
			// pull from there and sync the cluster afterwards.
			if err := job.Do(jobLogger); err != nil {
				jobLogger.Log("state", "done", "success", "false", "err", err)
				continue
			}
			jobLogger.Log("state", "done", "success", "true")
			pullThen(d.doSync)
		}
	}
}

// Ask for a sync, or if there's one waiting, let that happen.
func (d *LoopVars) askForSync() {
	d.ensureInit()
	select {
	case d.syncSoon <- struct{}{}:
	default:
	}
}

// Ask for an image poll, or if there's one waiting, let that happen.
func (d *LoopVars) askForImagePoll() {
	d.ensureInit()
	select {
	case d.pollImagesSoon <- struct{}{}:
	default:
	}
}

// -- extra bits the loop needs

func (d *Daemon) doSync(logger log.Logger) {
	started := time.Now().UTC()

	// checkout a working clone so we can mess around with tags later
	working, err := d.Checkout.WorkingClone()
	if err != nil {
		logger.Log("err", err)
		return
	}
	defer working.Clean()

	// TODO logging, metrics?
	// Get a map of all resources defined in the repo
	allResources, err := d.Manifests.LoadManifests(working.ManifestDir())
	if err != nil {
		logger.Log("err", errors.Wrap(err, "loading resources from repo"))
		return
	}

	// TODO supply deletes argument from somewhere (command-line?)
	if err := fluxsync.Sync(d.Manifests, allResources, d.Cluster, false, logger); err != nil {
		logger.Log("err", err)
	}

	// Figure out which service IDs changed in this release
	changedResources := map[string]resource.Resource{}
	changedFiles, err := working.ChangedFiles(working.SyncTag)
	switch {
	case err == nil:
		// We had some changed files, we're syncing a diff
		changedResources, err = d.Manifests.LoadManifests(changedFiles...)
		if err != nil {
			logger.Log("err", errors.Wrap(err, "loading resources from repo"))
			return
		}
	case isUnknownRevision(err):
		// no synctag, We are syncing everything from scratch
		changedResources = allResources
	default:
		logger.Log("err", err)
	}
	serviceIDs := flux.ServiceIDSet{}
	for _, r := range changedResources {
		serviceIDs.Add(r.ServiceIDs(allResources))
	}

	// update notes and emit events for applied commits
	revisions, err := working.RevisionsBetween(working.SyncTag, "HEAD")
	if isUnknownRevision(err) {
		// No sync tag, grab all revisions
		revisions, err = working.RevisionsBefore("HEAD")
	}
	if err != nil {
		logger.Log("err", err)
	}

	// Emit an event
	if len(revisions) > 0 {
		if err := d.LogEvent(history.Event{
			ServiceIDs: serviceIDs.ToSlice(),
			Type:       history.EventSync,
			StartedAt:  started,
			EndedAt:    started,
			LogLevel:   history.LogLevelInfo,
			Metadata:   &history.SyncEventMetadata{Revisions: revisions},
		}); err != nil {
			logger.Log("err", err)
		}

		// Find notes in revisions.
		for i := len(revisions) - 1; i >= 0; i-- {
			n, err := working.GetNote(revisions[i])
			if err != nil {
				logger.Log("err", errors.Wrap(err, "loading notes from repo; possibly no notes"))
				// TODO: We're ignoring all errors here, not just the "no notes" error. Parse error to report proper errors.
				continue
			}
			if n == nil {
				continue
			}

			// If any of the commit notes has a release event, send
			// that to the service
			switch n.Spec.Type {
			case update.Images:
				// Map new note.Spec into ReleaseSpec
				spec := n.Spec.Spec.(update.ReleaseSpec)
				// And create a release event
				// Then wrap inside a ReleaseEventMetadata
				if err := d.LogEvent(history.Event{
					ServiceIDs: serviceIDs.ToSlice(),
					Type:       history.EventRelease,
					StartedAt:  started,
					EndedAt:    time.Now().UTC(),
					LogLevel:   history.LogLevelInfo,
					Metadata: &history.ReleaseEventMetadata{
						ReleaseEventCommon: history.ReleaseEventCommon{
							Revision: revisions[i],
							Result:   n.Result,
							Error:    n.Result.Error(),
						},
						Spec:  spec,
						Cause: n.Spec.Cause,
					},
				}); err != nil {
					logger.Log("err", err)
				}
			case update.Auto:
				spec := n.Spec.Spec.(update.Automated)
				if err := d.LogEvent(history.Event{
					ServiceIDs: serviceIDs.ToSlice(),
					Type:       history.EventAutoRelease,
					StartedAt:  started,
					EndedAt:    time.Now().UTC(),
					LogLevel:   history.LogLevelInfo,
					Metadata: &history.AutoReleaseEventMetadata{
						ReleaseEventCommon: history.ReleaseEventCommon{
							Revision: revisions[i],
							Result:   n.Result,
							Error:    n.Result.Error(),
						},
						Spec: spec,
					},
				}); err != nil {
					logger.Log("err", err)
				}
			}
		}
	}

	// Move the tag and push it so we know how far we've gotten.
	if err := working.MoveTagAndPush("HEAD", "Sync pointer"); err != nil {
		logger.Log("err", err)
	}

	// Pull the tag if it has changed
	if err := d.updateTagRev(working, logger); err != nil {
		logger.Log("err", errors.Wrap(err, "updating tag"))
	}
}

func (d *Daemon) updateTagRev(working *git.Checkout, logger log.Logger) error {
	oldTagRev, err := d.Checkout.TagRevision(d.Checkout.SyncTag)
	if err != nil && !strings.Contains(err.Error(), "unknown revision or path not in the working tree") {
		return err
	}
	newTagRev, err := working.TagRevision(working.SyncTag)
	if err != nil {
		return err
	}

	if oldTagRev != newTagRev {
		logger.Log("tag", d.Checkout.SyncTag, "old", oldTagRev, "new", newTagRev)

		if err := d.Checkout.Pull(); err != nil {
			return err
		}
	}

	return nil
}

func isUnknownRevision(err error) bool {
	return err != nil &&
		(strings.Contains(err.Error(), "unknown revision or path not in the working tree.") ||
			strings.Contains(err.Error(), "bad revision"))
}
<|endoftext|>


<commit_before>package containerd

import (
	"context"
	"io"
	"os/exec"
	"sync"
	"syscall"
	"time"

	"github.com/pkg/errors"
)

type daemon struct {
	sync.Mutex
	addr string
	cmd  *exec.Cmd
}

func (d *daemon) start(name, address string, args []string, stdout, stderr io.Writer) error {
	d.Lock()
	defer d.Unlock()
	if d.cmd != nil {
		return errors.New("daemon is already running")
	}
	args = append(args, []string{"--address", address}...)
	cmd := exec.Command(name, args...)
	cmd.Stdout = stdout
	cmd.Stderr = stderr
	if err := cmd.Start(); err != nil {
		cmd.Wait()
		return errors.Wrap(err, "failed to start daemon")
	}
	d.addr = address
	d.cmd = cmd
	return nil
}

func (d *daemon) waitForStart(ctx context.Context) (*Client, error) {
	var (
		client  *Client
		serving bool
		err     error
	)

	client, err = New(address)
	if err != nil {
		return nil, err
	}
	serving, err = client.IsServing(ctx)
	if !serving {
		client.Close()
		if err == nil {
			err = errors.New("connection was successful but service is not available")
		}
		return nil, err
	}
	return client, err
}

func (d *daemon) Stop() error {
	d.Lock()
	d.Unlock()
	if d.cmd == nil {
		return errors.New("daemon is not running")
	}
	return d.cmd.Process.Signal(syscall.SIGTERM)
}

func (d *daemon) Kill() error {
	d.Lock()
	d.Unlock()
	if d.cmd == nil {
		return errors.New("daemon is not running")
	}
	return d.cmd.Process.Kill()
}

func (d *daemon) Wait() error {
	d.Lock()
	d.Unlock()
	if d.cmd == nil {
		return errors.New("daemon is not running")
	}
	return d.cmd.Wait()
}

func (d *daemon) Restart() error {
	d.Lock()
	d.Unlock()
	if d.cmd == nil {
		return errors.New("daemon is not running")
	}

	var err error
	if err = d.cmd.Process.Signal(syscall.SIGTERM); err != nil {
		return errors.Wrap(err, "failed to signal daemon")
	}

	d.cmd.Wait()

	<-time.After(1 * time.Second)

	cmd := exec.Command(d.cmd.Path, d.cmd.Args[1:]...)
	cmd.Stdout = d.cmd.Stdout
	cmd.Stderr = d.cmd.Stderr
	if err := cmd.Start(); err != nil {
		cmd.Wait()
		return errors.Wrap(err, "failed to start new daemon instance")
	}
	d.cmd = cmd

	return nil
}
<commit_msg>Defer unlock for testing daemon<commit_after>package containerd

import (
	"context"
	"io"
	"os/exec"
	"sync"
	"syscall"
	"time"

	"github.com/pkg/errors"
)

type daemon struct {
	sync.Mutex
	addr string
	cmd  *exec.Cmd
}

func (d *daemon) start(name, address string, args []string, stdout, stderr io.Writer) error {
	d.Lock()
	defer d.Unlock()
	if d.cmd != nil {
		return errors.New("daemon is already running")
	}
	args = append(args, []string{"--address", address}...)
	cmd := exec.Command(name, args...)
	cmd.Stdout = stdout
	cmd.Stderr = stderr
	if err := cmd.Start(); err != nil {
		cmd.Wait()
		return errors.Wrap(err, "failed to start daemon")
	}
	d.addr = address
	d.cmd = cmd
	return nil
}

func (d *daemon) waitForStart(ctx context.Context) (*Client, error) {
	var (
		client  *Client
		serving bool
		err     error
	)

	client, err = New(address)
	if err != nil {
		return nil, err
	}
	serving, err = client.IsServing(ctx)
	if !serving {
		client.Close()
		if err == nil {
			err = errors.New("connection was successful but service is not available")
		}
		return nil, err
	}
	return client, err
}

func (d *daemon) Stop() error {
	d.Lock()
	defer d.Unlock()
	if d.cmd == nil {
		return errors.New("daemon is not running")
	}
	return d.cmd.Process.Signal(syscall.SIGTERM)
}

func (d *daemon) Kill() error {
	d.Lock()
	defer d.Unlock()
	if d.cmd == nil {
		return errors.New("daemon is not running")
	}
	return d.cmd.Process.Kill()
}

func (d *daemon) Wait() error {
	d.Lock()
	defer d.Unlock()
	if d.cmd == nil {
		return errors.New("daemon is not running")
	}
	return d.cmd.Wait()
}

func (d *daemon) Restart() error {
	d.Lock()
	defer d.Unlock()
	if d.cmd == nil {
		return errors.New("daemon is not running")
	}

	var err error
	if err = d.cmd.Process.Signal(syscall.SIGTERM); err != nil {
		return errors.Wrap(err, "failed to signal daemon")
	}

	d.cmd.Wait()

	<-time.After(1 * time.Second)

	cmd := exec.Command(d.cmd.Path, d.cmd.Args[1:]...)
	cmd.Stdout = d.cmd.Stdout
	cmd.Stderr = d.cmd.Stderr
	if err := cmd.Start(); err != nil {
		cmd.Wait()
		return errors.Wrap(err, "failed to start new daemon instance")
	}
	d.cmd = cmd

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"log"

	"github.com/mpl/scgiclient"
)

func ughxml(command string) string {
	return `<?xml version="1.0"?>
	<methodCall>
		<methodName>` + command + `</methodName>
	</methodCall>`
}

func main() {
	flag.Parse()
	args := flag.Args()
	if len(args) < 2 {
		log.Fatal("wat")
	}
	// TODO(mpl): hostport parsing. trust for now.
	addr := args[0]
	xmlrpc := ughxml(args[1])
	conn, err := scgiclient.Send(addr, bytes.NewReader([]byte(xmlrpc)))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	resp, err := scgiclient.Receive(conn)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%v", string(resp))
}
<commit_msg>accept more args. will need to do some better type parsing.<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"log"

	"github.com/mpl/scgiclient"
)

func ughxml(command, arg string) string {
	xml := `<?xml version="1.0"?>
	<methodCall>
		<methodName>` + command + `</methodName>`
	if arg != "" {
		xml += `<params><param><value><string>` + arg + `</string></value></param></params>`
	}
	xml += "</methodCall>"
	return xml
}

func main() {
	flag.Parse()
	args := flag.Args()
	if len(args) < 2 {
		log.Fatal("wat")
	}
	// TODO(mpl): hostport parsing. trust for now.
	addr := args[0]
	command := args[1]
	cmdArg := ""
	if args[2] != "" {
		cmdArg = args[2]
	}
	xmlrpc := ughxml(command, cmdArg)
	conn, err := scgiclient.Send(addr, bytes.NewReader([]byte(xmlrpc)))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	resp, err := scgiclient.Receive(conn)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%v", string(resp))
}
<|endoftext|>