<commit_before>package org

import (
	"regexp"
	"strings"
	"unicode"
)

type Headline struct {
	Lvl        int
	Status     string
	Priority   string
	Properties *PropertyDrawer
	Title      []Node
	Tags       []string
	Children   []Node
}

var headlineRegexp = regexp.MustCompile(`^([*]+)\s+(.*)`)
var tagRegexp = regexp.MustCompile(`(.*?)\s+(:[A-Za-z0-9_@#%:]+:\s*$)`)

func lexHeadline(line string) (token, bool) {
	if m := headlineRegexp.FindStringSubmatch(line); m != nil {
		return token{"headline", 0, m[2], m}, true
	}
	return nilToken, false
}

func (d *Document) todoKeywords() []string {
	return strings.FieldsFunc(d.Get("TODO"), func(r rune) bool {
		return unicode.IsSpace(r) || r == '|'
	})
}

func (d *Document) parseHeadline(i int, parentStop stopFn) (int, Node) {
	t, headline := d.tokens[i], Headline{}
	headline.Lvl = len(t.matches[1])
	text := t.content

	for _, k := range d.todoKeywords() {
		if strings.HasPrefix(text, k) && len(text) > len(k) && unicode.IsSpace(rune(text[len(k)])) {
			headline.Status = k
			text = text[len(k)+1:]
			break
		}
	}

	if len(text) >= 3 && text[0:2] == "[#" && strings.Contains("ABC", text[2:3]) && text[3] == ']' {
		headline.Priority = text[2:3]
		text = strings.TrimSpace(text[4:])
	}

	if m := tagRegexp.FindStringSubmatch(text); m != nil {
		text = m[1]
		headline.Tags = strings.FieldsFunc(m[2], func(r rune) bool { return r == ':' })
	}

	headline.Title = d.parseInline(text)

	stop := func(d *Document, i int) bool {
		return parentStop(d, i) || d.tokens[i].kind == "headline" && d.tokens[i].lvl <= headline.Lvl
	}
	consumed, nodes := d.parseMany(i+1, stop)
	if len(nodes) > 0 {
		if d, ok := nodes[0].(PropertyDrawer); ok {
			headline.Properties = &d
			nodes = nodes[1:]
		}
	}
	headline.Children = nodes
	return consumed + 1, headline
}
<commit_msg>Refactor: Move todoKeywords into parseHeadline<commit_after>package org

import (
	"regexp"
	"strings"
	"unicode"
)

type Headline struct {
	Lvl        int
	Status     string
	Priority   string
	Properties *PropertyDrawer
	Title      []Node
	Tags       []string
	Children   []Node
}

var headlineRegexp = regexp.MustCompile(`^([*]+)\s+(.*)`)
var tagRegexp = regexp.MustCompile(`(.*?)\s+(:[A-Za-z0-9_@#%:]+:\s*$)`)

func lexHeadline(line string) (token, bool) {
	if m := headlineRegexp.FindStringSubmatch(line); m != nil {
		return token{"headline", 0, m[2], m}, true
	}
	return nilToken, false
}

func (d *Document) parseHeadline(i int, parentStop stopFn) (int, Node) {
	t, headline := d.tokens[i], Headline{}
	headline.Lvl = len(t.matches[1])
	text := t.content
	todoKeywords := strings.FieldsFunc(d.Get("TODO"), func(r rune) bool { return unicode.IsSpace(r) || r == '|' })
	for _, k := range todoKeywords {
		if strings.HasPrefix(text, k) && len(text) > len(k) && unicode.IsSpace(rune(text[len(k)])) {
			headline.Status = k
			text = text[len(k)+1:]
			break
		}
	}

	if len(text) >= 3 && text[0:2] == "[#" && strings.Contains("ABC", text[2:3]) && text[3] == ']' {
		headline.Priority = text[2:3]
		text = strings.TrimSpace(text[4:])
	}

	if m := tagRegexp.FindStringSubmatch(text); m != nil {
		text = m[1]
		headline.Tags = strings.FieldsFunc(m[2], func(r rune) bool { return r == ':' })
	}

	headline.Title = d.parseInline(text)

	stop := func(d *Document, i int) bool {
		return parentStop(d, i) || d.tokens[i].kind == "headline" && d.tokens[i].lvl <= headline.Lvl
	}
	consumed, nodes := d.parseMany(i+1, stop)
	if len(nodes) > 0 {
		if d, ok := nodes[0].(PropertyDrawer); ok {
			headline.Properties = &d
			nodes = nodes[1:]
		}
	}
	headline.Children = nodes
	return consumed + 1, headline
}
<|endoftext|>


<commit_before>package machinedeployment

import (
	"context"
	"fmt"

	"github.com/giantswarm/microerror"
	"github.com/giantswarm/operatorkit/controller/context/reconciliationcanceledcontext"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"github.com/giantswarm/aws-operator/pkg/label"
	"github.com/giantswarm/aws-operator/service/controller/clusterapi/v29/controllercontext"
	"github.com/giantswarm/aws-operator/service/controller/clusterapi/v29/key"
)

func (r *Resource) EnsureDeleted(ctx context.Context, obj interface{}) error {
	cr, err := key.ToCluster(obj)
	if err != nil {
		return microerror.Mask(err)
	}
	cc, err := controllercontext.FromContext(ctx)
	if err != nil {
		return microerror.Mask(err)
	}

	{
		r.logger.LogCtx(ctx, "level", "debug", "message", "finding machine deployment for cluster")

		in := metav1.ListOptions{
			LabelSelector: fmt.Sprintf("%s=%s", label.Cluster, key.ClusterID(&cr)),
		}

		out, err := r.cmaClient.ClusterV1alpha1().MachineDeployments(metav1.NamespaceAll).List(in)
		if err != nil {
			return microerror.Mask(err)
		}
		if len(out.Items) == 0 {
			r.logger.LogCtx(ctx, "level", "debug", "message", "did not find machine deployment for cluster")

			r.logger.LogCtx(ctx, "level", "debug", "message", "canceling reconciliation")
			reconciliationcanceledcontext.SetCanceled(ctx)

			return nil
		}
		if len(out.Items) != 1 {
			return microerror.Maskf(executionFailedError, "expected 1 machine deployment got %d", len(out.Items))
		}

		cc.Status.TenantCluster.TCCP.MachineDeployment = out.Items[0]

		r.logger.LogCtx(ctx, "level", "debug", "message", "found machine deployment for cluster")
	}

	return nil
}
<commit_msg>drop deletion logic from machindeployment resource (#1843)<commit_after>package machinedeployment

import (
	"context"
)

func (r *Resource) EnsureDeleted(ctx context.Context, obj interface{}) error {
	return nil
}
<|endoftext|>


<commit_before>package framework

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"strings"

	yaml "gopkg.in/yaml.v2"
)

type apiRequest struct {
	url  string
	data interface{}
}

type Client struct {
	host string
	user string
	key  string
}

func NewClient(host string) *Client {
	if !strings.HasPrefix(host, "http://") {
		host = "http://" + host
	}
	user := os.Getenv("SD_USER")
	key := os.Getenv("SD_KEY")
	return &Client{host: host, user: user, key: key}
}

func (c *Client) Ping() error {
	request := apiRequest{
		url:  "/health",
		data: make(map[string]interface{}),
	}
	_, err := c.request(request)
	if err != nil {
		return err
	}
	fmt.Println("Pong")
	return nil
}

func (c *Client) List() ([]string, error) {
	request := apiRequest{
		url:  "/list",
		data: make(map[string]interface{}),
	}
	content, err := c.request(request)
	if err != nil {
		return nil, err
	}

	stacks := make([]string, 0)
	err = yaml.Unmarshal(content, &stacks)
	if err != nil {
		return nil, err
	}

	return stacks, err
}

func (c *Client) GetStack(data *GetStackRequest) (*Stack, error) {
	request := apiRequest{
		url:  "/get",
		data: data,
	}
	content, err := c.request(request)
	if err != nil {
		return nil, err
	}

	stack := new(Stack)
	err = yaml.Unmarshal(content, &stack)
	if err != nil {
		return nil, err
	}

	return stack, err
}

func (c *Client) Run(data *RunRequest) error {
	request := apiRequest{
		url:  "/run",
		data: data,
	}
	_, err := c.request(request)
	return err
}

func (c *Client) CreateStack(data *CreateStackRequest) error {
	request := apiRequest{
		url:  "/createstack",
		data: data,
	}
	_, err := c.request(request)
	return err
}

func (c *Client) CreateLayer(data *CreateLayerRequest) error {
	request := apiRequest{
		url:  "/createlayer",
		data: data,
	}
	_, err := c.request(request)
	return err
}

func (c *Client) RemoveStack(data *RemoveStackRequest) error {
	request := apiRequest{
		url:  "/removestack",
		data: data,
	}
	_, err := c.request(request)
	return err
}

func (c *Client) CreateUser(data *CreateUserRequest) (string, error) {
	request := apiRequest{
		url:  "/createuser",
		data: data,
	}
	resp, err := c.request(request)
	if err != nil {
		return "", err
	}
	return string(resp), nil
}

func (c *Client) RefreshToken(data *RefreshTokenRequest) (string, error) {
	request := apiRequest{
		url:  "/refreshtoken",
		data: data,
	}
	resp, err := c.request(request)
	if err != nil {
		return "", err
	}
	return string(resp), nil
}

func (c *Client) Scheduled() ([]*ScheduledTask, error) {
	request := apiRequest{
		url:  "/scheduled",
		data: make(map[string]string),
	}
	resp, err := c.request(request)
	if err != nil {
		return nil, err
	}
	var response []*ScheduledTask
	err = json.Unmarshal(resp, &response)
	if err != nil {
		return nil, err
	}
	return response, nil
}

func (c *Client) RemoveScheduled(data *RemoveScheduledRequest) (string, error) {
	request := apiRequest{
		url:  "/scheduled/delete",
		data: data,
	}
	resp, err := c.request(request)
	if err != nil {
		return "", err
	}
	return string(resp), nil
}

func (c *Client) request(request apiRequest) ([]byte, error) {
	Logger.Debug("Sending request: %v", request)
	jsonData, err := json.Marshal(request.data)
	if err != nil {
		return nil, err
	}
	req, err := http.NewRequest("POST", c.host+request.url, bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, err
	}
	req.Header.Add("X-Api-User", c.user)
	req.Header.Add("X-Api-Key", c.key)
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		Logger.Debug("Error sending post request: %s", err)
		return nil, err
	}

	defer resp.Body.Close()
	Logger.Debug("Status code: %d", resp.StatusCode)
	content, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		Logger.Critical("Can't read response body: %s", err)
		return nil, err
	}

	if resp.StatusCode != http.StatusOK {
		Logger.Debug("Status code is not 200: %d", resp.StatusCode)
		return nil, errors.New(string(content))
	}

	return content, nil
}
<commit_msg>Fix issue where stack-deploy client was unable to reach server with api address ending with slash<commit_after>package framework

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"strings"

	yaml "gopkg.in/yaml.v2"
)

type apiRequest struct {
	url  string
	data interface{}
}

type Client struct {
	host string
	user string
	key  string
}

func NewClient(host string) *Client {
	if !strings.HasPrefix(host, "http://") {
		host = "http://" + host
	}

	if strings.HasSuffix(host, "/") {
		host = host[:len(host)-1]
	}

	user := os.Getenv("SD_USER")
	key := os.Getenv("SD_KEY")
	return &Client{host: host, user: user, key: key}
}

func (c *Client) Ping() error {
	request := apiRequest{
		url:  "/health",
		data: make(map[string]interface{}),
	}
	_, err := c.request(request)
	if err != nil {
		return err
	}
	fmt.Println("Pong")
	return nil
}

func (c *Client) List() ([]string, error) {
	request := apiRequest{
		url:  "/list",
		data: make(map[string]interface{}),
	}
	content, err := c.request(request)
	if err != nil {
		return nil, err
	}

	stacks := make([]string, 0)
	err = yaml.Unmarshal(content, &stacks)
	if err != nil {
		return nil, err
	}

	return stacks, err
}

func (c *Client) GetStack(data *GetStackRequest) (*Stack, error) {
	request := apiRequest{
		url:  "/get",
		data: data,
	}
	content, err := c.request(request)
	if err != nil {
		return nil, err
	}

	stack := new(Stack)
	err = yaml.Unmarshal(content, &stack)
	if err != nil {
		return nil, err
	}

	return stack, err
}

func (c *Client) Run(data *RunRequest) error {
	request := apiRequest{
		url:  "/run",
		data: data,
	}
	_, err := c.request(request)
	return err
}

func (c *Client) CreateStack(data *CreateStackRequest) error {
	request := apiRequest{
		url:  "/createstack",
		data: data,
	}
	_, err := c.request(request)
	return err
}

func (c *Client) CreateLayer(data *CreateLayerRequest) error {
	request := apiRequest{
		url:  "/createlayer",
		data: data,
	}
	_, err := c.request(request)
	return err
}

func (c *Client) RemoveStack(data *RemoveStackRequest) error {
	request := apiRequest{
		url:  "/removestack",
		data: data,
	}
	_, err := c.request(request)
	return err
}

func (c *Client) CreateUser(data *CreateUserRequest) (string, error) {
	request := apiRequest{
		url:  "/createuser",
		data: data,
	}
	resp, err := c.request(request)
	if err != nil {
		return "", err
	}
	return string(resp), nil
}

func (c *Client) RefreshToken(data *RefreshTokenRequest) (string, error) {
	request := apiRequest{
		url:  "/refreshtoken",
		data: data,
	}
	resp, err := c.request(request)
	if err != nil {
		return "", err
	}
	return string(resp), nil
}

func (c *Client) Scheduled() ([]*ScheduledTask, error) {
	request := apiRequest{
		url:  "/scheduled",
		data: make(map[string]string),
	}
	resp, err := c.request(request)
	if err != nil {
		return nil, err
	}
	var response []*ScheduledTask
	err = json.Unmarshal(resp, &response)
	if err != nil {
		return nil, err
	}
	return response, nil
}

func (c *Client) RemoveScheduled(data *RemoveScheduledRequest) (string, error) {
	request := apiRequest{
		url:  "/scheduled/delete",
		data: data,
	}
	resp, err := c.request(request)
	if err != nil {
		return "", err
	}
	return string(resp), nil
}

func (c *Client) request(request apiRequest) ([]byte, error) {
	Logger.Debug("Sending request: %v", request)
	jsonData, err := json.Marshal(request.data)
	if err != nil {
		return nil, err
	}
	req, err := http.NewRequest("POST", c.host+request.url, bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, err
	}
	req.Header.Add("X-Api-User", c.user)
	req.Header.Add("X-Api-Key", c.key)
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		Logger.Debug("Error sending post request: %s", err)
		return nil, err
	}

	defer resp.Body.Close()
	Logger.Debug("Status code: %d", resp.StatusCode)
	content, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		Logger.Critical("Can't read response body: %s", err)
		return nil, err
	}

	if resp.StatusCode != http.StatusOK {
		Logger.Debug("Status code is not 200: %d", resp.StatusCode)
		return nil, errors.New(string(content))
	}

	return content, nil
}
<|endoftext|>


<commit_before>package libcontainer

import (
	"fmt"
	"io/ioutil"
	"testing"
)

func TestErrorDetail(t *testing.T) {
	err := newGenericError(fmt.Errorf("test error"), SystemError)
	if derr := err.Detail(ioutil.Discard); derr != nil {
		t.Fatal(derr)
	}
}
<commit_msg>add testcase in generic_error_test.go<commit_after>package libcontainer

import (
	"fmt"
	"io/ioutil"
	"testing"
)

func TestErrorDetail(t *testing.T) {
	err := newGenericError(fmt.Errorf("test error"), SystemError)
	if derr := err.Detail(ioutil.Discard); derr != nil {
		t.Fatal(derr)
	}
}

func TestErrorWithCode(t *testing.T) {
	err := newGenericError(fmt.Errorf("test error"), SystemError)
	if code := err.Code(); code != SystemError {
		t.Fatalf("expected err code %q but %q", SystemError, code)
	}
}

func TestErrorWithError(t *testing.T) {
	cc := []struct {
		errmsg string
		cause  string
	}{
		{
			errmsg: "test error",
		},
		{
			errmsg: "test error",
			cause:  "test",
		},
	}

	for _, v := range cc {
		err := newSystemErrorWithCause(fmt.Errorf(v.errmsg), v.cause)

		msg := err.Error()
		if v.cause == "" && msg != v.errmsg {
			t.Fatalf("expected err(%q) equal errmsg(%q)", msg, v.errmsg)
		}
		if v.cause != "" && msg == v.errmsg {
			t.Fatalf("unexpected err(%q) equal errmsg(%q)", msg, v.errmsg)
		}

	}
}
<|endoftext|>


<commit_before>package unit

import (
	"flag"
	"github.com/timeredbull/tsuru/api/unit"
	"io/ioutil"
	. "launchpad.net/gocheck"
	"os"
	"testing"
)

func Test(t *testing.T) { TestingT(t) }

type S struct{}

var _ = Suite(&S{})

var jujuEnabled = flag.Bool("juju", false, "enable unit tests that require juju")

func (s *S) SetUpSuite(c *C) {
	if !*jujuEnabled {
		c.Skip("unit tests need juju installed (-juju to enable)")
	}
}

func (s *S) TestCreateAndDestroy(c *C) {
	u := unit.Unit{Type: "django", Name: "myUnit"}

	err := u.Create()
	c.Assert(err, IsNil)

	err = u.Destroy()
	c.Assert(err, IsNil)
}

func (s *S) TestCommand(c *C) {
	u := unit.Unit{Type: "django", Name: "myUnit"}

	err := u.Create()
	c.Assert(err, IsNil)

	output, err := u.Command("uname")
	c.Assert(err, IsNil)
	c.Assert(string(output), Equals, "Linux")

	err = u.Destroy()
	c.Assert(err, IsNil)
}

func (s *S) TestSendFile(c *C) {
	u := unit.Unit{Type: "django", Name: "myUnit"}

	err := u.Create()
	c.Assert(err, IsNil)

	file, err := ioutil.TempFile("", "upload")
	c.Assert(err, IsNil)

	defer os.Remove(file.Name())
	defer file.Close()

	err = u.SendFile(file.Name(), "/home/ubuntu")
	c.Assert(err, IsNil)

	err = u.Destroy()
	c.Assert(err, IsNil)

}

func (s *S) TestAddRelation(c *C) {
	appUnit := unit.Unit{Type: "django", Name: "myUnit"}
	serviceUnit := unit.Unit{Type: "mysql", Name: "MyService"}

	err := appUnit.AddRelation(&serviceUnit)
	c.Assert(err, IsNil)
}

func (s *S) TestRemoveRelation(c *C) {
	appUnit := unit.Unit{Type: "django", Name: "myUnit"}
	serviceUnit := unit.Unit{Type: "mysql", Name: "MyService"}

	err := appUnit.RemoveRelation(&serviceUnit)
	c.Assert(err, IsNil)
}

func (s *S) TestExecuteHook(c *C) {
	appUnit := unit.Unit{Type: "django", Name: "myUnit"}

	err := appUnit.ExecuteHook("requirements")
	c.Assert(err, IsNil)
}
<commit_msg>api/unit: fix imports and package utilisation<commit_after>package unit

import (
	"flag"
	"io/ioutil"
	. "launchpad.net/gocheck"
	"os"
	"testing"
)

func Test(t *testing.T) { TestingT(t) }

type S struct{}

var _ = Suite(&S{})

var jujuEnabled = flag.Bool("juju", false, "enable unit tests that require juju")

func (s *S) SetUpSuite(c *C) {
	if !*jujuEnabled {
		c.Skip("unit tests need juju installed (-juju to enable)")
	}
}

func (s *S) TestCreateAndDestroy(c *C) {
	u := Unit{Type: "django", Name: "myUnit"}

	err := u.Create()
	c.Assert(err, IsNil)

	err = u.Destroy()
	c.Assert(err, IsNil)
}

func (s *S) TestCommand(c *C) {
	u := Unit{Type: "django", Name: "myUnit"}

	err := u.Create()
	c.Assert(err, IsNil)

	output, err := u.Command("uname")
	c.Assert(err, IsNil)
	c.Assert(string(output), Equals, "Linux")

	err = u.Destroy()
	c.Assert(err, IsNil)
}

func (s *S) TestSendFile(c *C) {
	u := Unit{Type: "django", Name: "myUnit"}

	err := u.Create()
	c.Assert(err, IsNil)

	file, err := ioutil.TempFile("", "upload")
	c.Assert(err, IsNil)

	defer os.Remove(file.Name())
	defer file.Close()

	err = u.SendFile(file.Name(), "/home/ubuntu")
	c.Assert(err, IsNil)

	err = u.Destroy()
	c.Assert(err, IsNil)

}

func (s *S) TestAddRelation(c *C) {
	appUnit := Unit{Type: "django", Name: "myUnit"}
	serviceUnit := Unit{Type: "mysql", Name: "MyService"}

	err := appUnit.AddRelation(&serviceUnit)
	c.Assert(err, IsNil)
}

func (s *S) TestRemoveRelation(c *C) {
	appUnit := Unit{Type: "django", Name: "myUnit"}
	serviceUnit := Unit{Type: "mysql", Name: "MyService"}

	err := appUnit.RemoveRelation(&serviceUnit)
	c.Assert(err, IsNil)
}

func (s *S) TestExecuteHook(c *C) {
	appUnit := Unit{Type: "django", Name: "myUnit"}

	err := appUnit.ExecuteHook("requirements")
	c.Assert(err, IsNil)
}
<|endoftext|>


<commit_before>package ceph

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestImports(t *testing.T) {
	if assert.Equal(t, 1, 1) != true {
		t.Error("Something is wrong.")
	}
}
<commit_msg>ceph: remove use of boolean literal in expression<commit_after>package ceph

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestImports(t *testing.T) {
	if !assert.Equal(t, 1, 1) {
		t.Error("Something is wrong.")
	}
}
<|endoftext|>


<commit_before>package packer

import (
	"fmt"
	"log"
	"sync"
)

// This is the key in configurations that is set to "true" when Packer
// debugging is enabled.
const DebugConfigKey = "packer_debug"

// A Build represents a single job within Packer that is responsible for
// building some machine image artifact. Builds are meant to be parallelized.
type Build interface {
	// Name is the name of the build. This is unique across a single template,
	// but not absolutely unique. This is meant more to describe to the user
	// what is being built rather than being a unique identifier.
	Name() string

	// Prepare configures the various components of this build and reports
	// any errors in doing so (such as syntax errors, validation errors, etc.)
	Prepare() error

	// Run runs the actual builder, returning an artifact implementation
	// of what is built. If anything goes wrong, an error is returned.
	Run(Ui, Cache) ([]Artifact, error)

	// Cancel will cancel a running build. This will block until the build
	// is actually completely cancelled.
	Cancel()

	// SetDebug will enable/disable debug mode. Debug mode is always
	// enabled by adding the additional key "packer_debug" to boolean
	// true in the configuration of the various components. This must
	// be called prior to Prepare.
	//
	// When SetDebug is set to true, parallelism between builds is
	// strictly prohibited.
	SetDebug(bool)
}

// A build struct represents a single build job, the result of which should
// be a single machine image artifact. This artifact may be comprised of
// multiple files, of course, but it should be for only a single provider
// (such as VirtualBox, EC2, etc.).
type coreBuild struct {
	name           string
	builder        Builder
	builderConfig  interface{}
	builderType    string
	hooks          map[string][]Hook
	postProcessors [][]coreBuildPostProcessor
	provisioners   []coreBuildProvisioner

	debug         bool
	l             sync.Mutex
	prepareCalled bool
}

// Keeps track of the post-processor and the configuration of the
// post-processor used within a build.
type coreBuildPostProcessor struct {
	processor         PostProcessor
	processorType     string
	config            interface{}
	keepInputArtifact bool
}

// Keeps track of the provisioner and the configuration of the provisioner
// within the build.
type coreBuildProvisioner struct {
	provisioner Provisioner
	config      []interface{}
}

// Returns the name of the build.
func (b *coreBuild) Name() string {
	return b.name
}

// Prepare prepares the build by doing some initialization for the builder
// and any hooks. This _must_ be called prior to Run.
func (b *coreBuild) Prepare() (err error) {
	b.l.Lock()
	defer b.l.Unlock()

	if b.prepareCalled {
		panic("prepare already called")
	}

	b.prepareCalled = true

	debugConfig := map[string]interface{}{
		DebugConfigKey: b.debug,
	}

	// Prepare the builder
	err = b.builder.Prepare(b.builderConfig, debugConfig)
	if err != nil {
		log.Printf("Build '%s' prepare failure: %s\n", b.name, err)
		return
	}

	// Prepare the provisioners
	for _, coreProv := range b.provisioners {
		configs := make([]interface{}, len(coreProv.config), len(coreProv.config)+1)
		copy(configs, coreProv.config)
		configs = append(configs, debugConfig)

		if err = coreProv.provisioner.Prepare(configs...); err != nil {
			return
		}
	}

	// Prepare the post-processors
	for _, ppSeq := range b.postProcessors {
		for _, corePP := range ppSeq {
			if err = corePP.processor.Configure(corePP.config); err != nil {
				return
			}
		}
	}

	return
}

// Runs the actual build. Prepare must be called prior to running this.
func (b *coreBuild) Run(ui Ui, cache Cache) ([]Artifact, error) {
	if !b.prepareCalled {
		panic("Prepare must be called first")
	}

	// Copy the hooks
	hooks := make(map[string][]Hook)
	for hookName, hookList := range b.hooks {
		hooks[hookName] = make([]Hook, len(hookList))
		copy(hooks[hookName], hookList)
	}

	// Add a hook for the provisioners if we have provisioners
	if len(b.provisioners) > 0 {
		provisioners := make([]Provisioner, len(b.provisioners))
		for i, p := range b.provisioners {
			provisioners[i] = p.provisioner
		}

		if _, ok := hooks[HookProvision]; !ok {
			hooks[HookProvision] = make([]Hook, 0, 1)
		}

		hooks[HookProvision] = append(hooks[HookProvision], &ProvisionHook{provisioners})
	}

	hook := &DispatchHook{hooks}
	artifacts := make([]Artifact, 0, 1)

	log.Printf("Running builder: %s", b.builderType)
	builderArtifact, err := b.builder.Run(ui, hook, cache)
	if err != nil {
		return nil, err
	}

	errors := make([]error, 0)
	keepOriginalArtifact := len(b.postProcessors) == 0

	// Run the post-processors
PostProcessorRunSeqLoop:
	for _, ppSeq := range b.postProcessors {
		priorArtifact := builderArtifact
		for i, corePP := range ppSeq {
			ui.Say(fmt.Sprintf("Running post-processor: %s", corePP.processorType))
			artifact, err := corePP.processor.PostProcess(ui, priorArtifact)
			if err != nil {
				errors = append(errors, fmt.Errorf("Post-processor failed: %s", err))
				continue PostProcessorRunSeqLoop
			}

			if artifact == nil {
				log.Println("Nil artifact, halting post-processor chain.")
				continue PostProcessorRunSeqLoop
			}

			if i == 0 {
				// This is the first post-processor. We handle deleting
				// previous artifacts a bit different because multiple
				// post-processors may be using the original and need it.
				if !keepOriginalArtifact && corePP.keepInputArtifact {
					log.Printf(
						"Flagging to keep original artifact from post-processor '%s'",
						corePP.processorType)
					keepOriginalArtifact = true
				}
			} else {
				// We have a prior artifact. If we want to keep it, we append
				// it to the results list. Otherwise, we destroy it.
				if corePP.keepInputArtifact {
					artifacts = append(artifacts, priorArtifact)
				} else {
					log.Printf("Deleting prior artifact from post-processor '%s'", corePP.processorType)
					if err := priorArtifact.Destroy(); err != nil {
						errors = append(errors, fmt.Errorf("Failed cleaning up prior artifact: %s", err))
					}
				}
			}

			priorArtifact = artifact
		}

		// Add on the last artifact to the results
		if priorArtifact != nil {
			artifacts = append(artifacts, priorArtifact)
		}
	}

	if keepOriginalArtifact {
		artifacts = append(artifacts, nil)
		copy(artifacts[1:], artifacts)
		artifacts[0] = builderArtifact
	} else {
		log.Printf("Deleting original artifact for build '%s'", b.name)
		if err := builderArtifact.Destroy(); err != nil {
			errors = append(errors, fmt.Errorf("Error destroying builder artifact: %s", err))
		}
	}

	if len(errors) > 0 {
		err = &MultiError{errors}
	}

	return artifacts, err
}

func (b *coreBuild) SetDebug(val bool) {
	if b.prepareCalled {
		panic("prepare has already been called")
	}

	b.debug = val
}

// Cancels the build if it is running.
func (b *coreBuild) Cancel() {
	b.builder.Cancel()
}
<commit_msg>packer: Don't run post-processors if artifact is nil<commit_after>package packer

import (
	"fmt"
	"log"
	"sync"
)

// This is the key in configurations that is set to "true" when Packer
// debugging is enabled.
const DebugConfigKey = "packer_debug"

// A Build represents a single job within Packer that is responsible for
// building some machine image artifact. Builds are meant to be parallelized.
type Build interface {
	// Name is the name of the build. This is unique across a single template,
	// but not absolutely unique. This is meant more to describe to the user
	// what is being built rather than being a unique identifier.
	Name() string

	// Prepare configures the various components of this build and reports
	// any errors in doing so (such as syntax errors, validation errors, etc.)
	Prepare() error

	// Run runs the actual builder, returning an artifact implementation
	// of what is built. If anything goes wrong, an error is returned.
	Run(Ui, Cache) ([]Artifact, error)

	// Cancel will cancel a running build. This will block until the build
	// is actually completely cancelled.
	Cancel()

	// SetDebug will enable/disable debug mode. Debug mode is always
	// enabled by adding the additional key "packer_debug" to boolean
	// true in the configuration of the various components. This must
	// be called prior to Prepare.
	//
	// When SetDebug is set to true, parallelism between builds is
	// strictly prohibited.
	SetDebug(bool)
}

// A build struct represents a single build job, the result of which should
// be a single machine image artifact. This artifact may be comprised of
// multiple files, of course, but it should be for only a single provider
// (such as VirtualBox, EC2, etc.).
type coreBuild struct {
	name           string
	builder        Builder
	builderConfig  interface{}
	builderType    string
	hooks          map[string][]Hook
	postProcessors [][]coreBuildPostProcessor
	provisioners   []coreBuildProvisioner

	debug         bool
	l             sync.Mutex
	prepareCalled bool
}

// Keeps track of the post-processor and the configuration of the
// post-processor used within a build.
type coreBuildPostProcessor struct {
	processor         PostProcessor
	processorType     string
	config            interface{}
	keepInputArtifact bool
}

// Keeps track of the provisioner and the configuration of the provisioner
// within the build.
type coreBuildProvisioner struct {
	provisioner Provisioner
	config      []interface{}
}

// Returns the name of the build.
func (b *coreBuild) Name() string {
	return b.name
}

// Prepare prepares the build by doing some initialization for the builder
// and any hooks. This _must_ be called prior to Run.
func (b *coreBuild) Prepare() (err error) {
	b.l.Lock()
	defer b.l.Unlock()

	if b.prepareCalled {
		panic("prepare already called")
	}

	b.prepareCalled = true

	debugConfig := map[string]interface{}{
		DebugConfigKey: b.debug,
	}

	// Prepare the builder
	err = b.builder.Prepare(b.builderConfig, debugConfig)
	if err != nil {
		log.Printf("Build '%s' prepare failure: %s\n", b.name, err)
		return
	}

	// Prepare the provisioners
	for _, coreProv := range b.provisioners {
		configs := make([]interface{}, len(coreProv.config), len(coreProv.config)+1)
		copy(configs, coreProv.config)
		configs = append(configs, debugConfig)

		if err = coreProv.provisioner.Prepare(configs...); err != nil {
			return
		}
	}

	// Prepare the post-processors
	for _, ppSeq := range b.postProcessors {
		for _, corePP := range ppSeq {
			if err = corePP.processor.Configure(corePP.config); err != nil {
				return
			}
		}
	}

	return
}

// Runs the actual build. Prepare must be called prior to running this.
func (b *coreBuild) Run(ui Ui, cache Cache) ([]Artifact, error) {
	if !b.prepareCalled {
		panic("Prepare must be called first")
	}

	// Copy the hooks
	hooks := make(map[string][]Hook)
	for hookName, hookList := range b.hooks {
		hooks[hookName] = make([]Hook, len(hookList))
		copy(hooks[hookName], hookList)
	}

	// Add a hook for the provisioners if we have provisioners
	if len(b.provisioners) > 0 {
		provisioners := make([]Provisioner, len(b.provisioners))
		for i, p := range b.provisioners {
			provisioners[i] = p.provisioner
		}

		if _, ok := hooks[HookProvision]; !ok {
			hooks[HookProvision] = make([]Hook, 0, 1)
		}

		hooks[HookProvision] = append(hooks[HookProvision], &ProvisionHook{provisioners})
	}

	hook := &DispatchHook{hooks}
	artifacts := make([]Artifact, 0, 1)

	log.Printf("Running builder: %s", b.builderType)
	builderArtifact, err := b.builder.Run(ui, hook, cache)
	if err != nil {
		return nil, err
	}

	// If there was no result, don't worry about running post-processors
	// because there is nothing they can do, just return.
	if builderArtifact == nil {
		return nil, nil
	}

	errors := make([]error, 0)
	keepOriginalArtifact := len(b.postProcessors) == 0

	// Run the post-processors
PostProcessorRunSeqLoop:
	for _, ppSeq := range b.postProcessors {
		priorArtifact := builderArtifact
		for i, corePP := range ppSeq {
			ui.Say(fmt.Sprintf("Running post-processor: %s", corePP.processorType))
			artifact, err := corePP.processor.PostProcess(ui, priorArtifact)
			if err != nil {
				errors = append(errors, fmt.Errorf("Post-processor failed: %s", err))
				continue PostProcessorRunSeqLoop
			}

			if artifact == nil {
				log.Println("Nil artifact, halting post-processor chain.")
				continue PostProcessorRunSeqLoop
			}

			if i == 0 {
				// This is the first post-processor. We handle deleting
				// previous artifacts a bit different because multiple
				// post-processors may be using the original and need it.
				if !keepOriginalArtifact && corePP.keepInputArtifact {
					log.Printf(
						"Flagging to keep original artifact from post-processor '%s'",
						corePP.processorType)
					keepOriginalArtifact = true
				}
			} else {
				// We have a prior artifact. If we want to keep it, we append
				// it to the results list. Otherwise, we destroy it.
				if corePP.keepInputArtifact {
					artifacts = append(artifacts, priorArtifact)
				} else {
					log.Printf("Deleting prior artifact from post-processor '%s'", corePP.processorType)
					if err := priorArtifact.Destroy(); err != nil {
						errors = append(errors, fmt.Errorf("Failed cleaning up prior artifact: %s", err))
					}
				}
			}

			priorArtifact = artifact
		}

		// Add on the last artifact to the results
		if priorArtifact != nil {
			artifacts = append(artifacts, priorArtifact)
		}
	}

	if keepOriginalArtifact {
		artifacts = append(artifacts, nil)
		copy(artifacts[1:], artifacts)
		artifacts[0] = builderArtifact
	} else {
		log.Printf("Deleting original artifact for build '%s'", b.name)
		if err := builderArtifact.Destroy(); err != nil {
			errors = append(errors, fmt.Errorf("Error destroying builder artifact: %s", err))
		}
	}

	if len(errors) > 0 {
		err = &MultiError{errors}
	}

	return artifacts, err
}

func (b *coreBuild) SetDebug(val bool) {
	if b.prepareCalled {
		panic("prepare has already been called")
	}

	b.debug = val
}

// Cancels the build if it is running.
func (b *coreBuild) Cancel() {
	b.builder.Cancel()
}
<|endoftext|>


<commit_before>package main

import "sync"

// WatchChanges will watch the state of the given request. ch will send after
// each request state change and will be closed after the request is removed from
// the request state database.
//
// WatchChanges sends on ch from the same goroutine as the caller and will deadlock
// if there is no goroutine already listening on it.
//
// Returns ErrNotFound if the request is not reserved at call time.
// WatchChanges will do no operations on ch if any non-nil error is returned.
func WatchChanges(reqID string, ch chan<- int) error

// WatchAll watches for all events on the given request.
//
// The WaitGroup will be done after the request is reserved, and the channel
// will send on each state change, then be closed when the request is released.
//
// The channel will send from a new, internal goroutine, which you are not responsible
// for managing.
func WatchAll(reqID string) (*sync.WaitGroup, <-chan int)
<commit_msg>better docs<commit_after>package main

import "sync"

// WatchChanges will watch the state of the given request. ch will send after
// each request state change and will be closed after the request is removed from
// the request state database. Sends on ch from the same goroutine as the caller.
//
// Returns ErrNotFound if the request is not reserved at call time.
// WatchChanges will do no operations on ch if any non-nil error is returned.
func WatchChanges(reqID string, ch chan<- int) error

// WatchAll watches for all events on the given request.
//
// The WaitGroup will be done after the request is reserved, and the channel
// will send on each state change, then be closed when the request is released.
//
// The channel will send from a new, internal goroutine, which you are not responsible
// for managing.
func WatchAll(reqID string) (*sync.WaitGroup, <-chan int)
<|endoftext|>


<commit_before>// Package diode provides a thread-safe, lock-free, non-blocking io.Writer
// wrapper.
package diode

import (
	"context"
	"io"
	"sync"
	"time"

	"github.com/rs/zerolog/diode/internal/diodes"
)

var bufPool = &sync.Pool{
	New: func() interface{} {
		return make([]byte, 0, 500)
	},
}

type Alerter func(missed int)

type diodeFetcher interface {
	diodes.Diode
	Next() diodes.GenericDataType
}

// Writer is a io.Writer wrapper that uses a diode to make Write lock-free,
// non-blocking and thread safe.
type Writer struct {
	w    io.Writer
	d    diodeFetcher
	c    context.CancelFunc
	done chan struct{}
}

// NewWriter creates a writer wrapping w with a many-to-one diode in order to
// never block log producers and drop events if the writer can't keep up with
// the flow of data.
//
// Use a diode.Writer when
//
//     wr := diode.NewWriter(w, 1000, 0, func(missed int) {
//         log.Printf("Dropped %d messages", missed)
//     })
//     log := zerolog.New(wr)
//
// If pollInterval is greater than 0, a poller is used otherwise a waiter is
// used.
//
// See code.cloudfoundry.org/go-diodes for more info on diode.
func NewWriter(w io.Writer, size int, poolInterval time.Duration, f Alerter) Writer {
	ctx, cancel := context.WithCancel(context.Background())
	dw := Writer{
		w:    w,
		c:    cancel,
		done: make(chan struct{}),
	}
	if f == nil {
		f = func(int) {}
	}
	d := diodes.NewManyToOne(size, diodes.AlertFunc(f))
	if poolInterval > 0 {
		dw.d = diodes.NewPoller(d,
			diodes.WithPollingInterval(poolInterval),
			diodes.WithPollingContext(ctx))
	} else {
		dw.d = diodes.NewWaiter(d,
			diodes.WithWaiterContext(ctx))
	}
	go dw.poll()
	return dw
}

func (dw Writer) Write(p []byte) (n int, err error) {
	// p is pooled in zerolog so we can't hold it passed this call, hence the
	// copy.
	p = append(bufPool.Get().([]byte), p...)
	dw.d.Set(diodes.GenericDataType(&p))
	return len(p), nil
}

// Close releases the diode poller and call Close on the wrapped writer if
// io.Closer is implemented.
func (dw Writer) Close() error {
	dw.c()
	<-dw.done
	if w, ok := dw.w.(io.Closer); ok {
		return w.Close()
	}
	return nil
}

func (dw Writer) poll() {
	defer close(dw.done)
	for {
		d := dw.d.Next()
		if d == nil {
			return
		}
		p := *(*[]byte)(d)
		dw.w.Write(p)

		// Proper usage of a sync.Pool requires each entry to have approximately
		// the same memory cost. To obtain this property when the stored type
		// contains a variably-sized buffer, we add a hard limit on the maximum buffer
		// to place back in the pool.
		//
		// See https://golang.org/issue/23199
		const maxSize = 1 << 16 // 64KiB
		if cap(p) <= maxSize {
			bufPool.Put(p[:0])
		}
	}
}
<commit_msg>Fix typo in diode.NewWriter argument name (#254)<commit_after>// Package diode provides a thread-safe, lock-free, non-blocking io.Writer
// wrapper.
package diode

import (
	"context"
	"io"
	"sync"
	"time"

	"github.com/rs/zerolog/diode/internal/diodes"
)

var bufPool = &sync.Pool{
	New: func() interface{} {
		return make([]byte, 0, 500)
	},
}

type Alerter func(missed int)

type diodeFetcher interface {
	diodes.Diode
	Next() diodes.GenericDataType
}

// Writer is a io.Writer wrapper that uses a diode to make Write lock-free,
// non-blocking and thread safe.
type Writer struct {
	w    io.Writer
	d    diodeFetcher
	c    context.CancelFunc
	done chan struct{}
}

// NewWriter creates a writer wrapping w with a many-to-one diode in order to
// never block log producers and drop events if the writer can't keep up with
// the flow of data.
//
// Use a diode.Writer when
//
//     wr := diode.NewWriter(w, 1000, 0, func(missed int) {
//         log.Printf("Dropped %d messages", missed)
//     })
//     log := zerolog.New(wr)
//
// If pollInterval is greater than 0, a poller is used otherwise a waiter is
// used.
//
// See code.cloudfoundry.org/go-diodes for more info on diode.
func NewWriter(w io.Writer, size int, pollInterval time.Duration, f Alerter) Writer {
	ctx, cancel := context.WithCancel(context.Background())
	dw := Writer{
		w:    w,
		c:    cancel,
		done: make(chan struct{}),
	}
	if f == nil {
		f = func(int) {}
	}
	d := diodes.NewManyToOne(size, diodes.AlertFunc(f))
	if pollInterval > 0 {
		dw.d = diodes.NewPoller(d,
			diodes.WithPollingInterval(pollInterval),
			diodes.WithPollingContext(ctx))
	} else {
		dw.d = diodes.NewWaiter(d,
			diodes.WithWaiterContext(ctx))
	}
	go dw.poll()
	return dw
}

func (dw Writer) Write(p []byte) (n int, err error) {
	// p is pooled in zerolog so we can't hold it passed this call, hence the
	// copy.
	p = append(bufPool.Get().([]byte), p...)
	dw.d.Set(diodes.GenericDataType(&p))
	return len(p), nil
}

// Close releases the diode poller and call Close on the wrapped writer if
// io.Closer is implemented.
func (dw Writer) Close() error {
	dw.c()
	<-dw.done
	if w, ok := dw.w.(io.Closer); ok {
		return w.Close()
	}
	return nil
}

func (dw Writer) poll() {
	defer close(dw.done)
	for {
		d := dw.d.Next()
		if d == nil {
			return
		}
		p := *(*[]byte)(d)
		dw.w.Write(p)

		// Proper usage of a sync.Pool requires each entry to have approximately
		// the same memory cost. To obtain this property when the stored type
		// contains a variably-sized buffer, we add a hard limit on the maximum buffer
		// to place back in the pool.
		//
		// See https://golang.org/issue/23199
		const maxSize = 1 << 16 // 64KiB
		if cap(p) <= maxSize {
			bufPool.Put(p[:0])
		}
	}
}
<|endoftext|>


<commit_before>package command

import (
	"log"
	"net/url"
	"os"
	"path/filepath"

	"github.com/mitchellh/cli"
	homedir "github.com/mitchellh/go-homedir"
	"github.com/nerdalize/nerd/cmd"
	"github.com/nerdalize/nerd/nerd/client/auth/v1"
	v1payload "github.com/nerdalize/nerd/nerd/client/auth/v1/payload"

	"github.com/nerdalize/nerd/nerd/conf"
	"github.com/nerdalize/nerd/nerd/oauth"
	"github.com/nerdalize/nerd/pkg/populator"
	"github.com/pkg/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)

//ProjectSetOpts determine
type ProjectSetOpts struct {
	Config     string `long:"config-src" default:"oidc" default-mask:"" description:"type of configuration to use (from env, endpoint, or oidc)"`
	KubeConfig string `long:"kube-config" env:"KUBECONFIG" description:"file at which Nerd will look for Kubernetes credentials" default-mask:"~/.kube/config"`
}

//ProjectSet command
type ProjectSet struct {
	*command
	opts *ProjectSetOpts
}

//ProjectSetFactory returns a factory method for the join command
func ProjectSetFactory() (cli.Command, error) {
	opts := &ProjectSetOpts{}
	comm, err := newCommand("nerd project set", "Set current working project.", "", opts)
	if err != nil {
		return nil, errors.Wrap(err, "failed to create command")
	}
	cmd := &ProjectSet{
		command: comm,
		opts:    opts,
	}
	cmd.runFunc = cmd.DoRun

	return cmd, nil
}

//DoRun is called by run and allows an error to be returned
func (cmd *ProjectSet) DoRun(args []string) (err error) {
	if len(args) < 1 {
		return errShowHelp("Not enough arguments, see below for usage.")
	}
	projectSlug := args[0]

	authbase, err := url.Parse(cmd.config.Auth.APIEndpoint)
	if err != nil {
		return errors.Wrapf(err, "auth endpoint '%v' is not a valid URL", cmd.config.Auth.APIEndpoint)
	}
	authOpsClient := v1auth.NewOpsClient(v1auth.OpsClientConfig{
		Base:   authbase,
		Logger: cmd.outputter.Logger,
	})
	client := v1auth.NewClient(v1auth.ClientConfig{
		Base:               authbase,
		Logger:             cmd.outputter.Logger,
		OAuthTokenProvider: oauth.NewConfigProvider(authOpsClient, cmd.config.Auth.SecureClientID, cmd.config.Auth.SecureClientSecret, cmd.session),
	})

	project, err := client.GetProject(projectSlug)
	if err != nil {
		return HandleError(errors.Wrap(err, "Project not found, please check the project name. You can get a list of your projects by running `nerd project list`."))
	}

	err = setProject(cmd.opts.KubeConfig, cmd.opts.Config, project, cmd.outputter.Logger)
	if err != nil {
		return HandleError(err)
	}

	err = cmd.session.WriteProject(projectSlug, conf.DefaultAWSRegion)
	if err != nil {
		return HandleError(err)
	}

	cmd.outputter.Logger.Printf("Project %s set successfully", projectSlug)
	return nil
}

func setProject(kubeConfig, conf string, project *v1payload.GetProjectOutput, logger *log.Logger) error {
	var (
		hdir string
		err  error
	)
	hdir, err = homedir.Dir()
	if err != nil {
		return err
	}
	if kubeConfig == "" {
		kubeConfig = filepath.Join(hdir, ".kube", "config")
	}
	p, err := populator.New(conf, kubeConfig, hdir, project)
	if err != nil {
		return err
	}
	err = p.PopulateKubeConfig(project.Nk)
	if err != nil {
		return err
	}
	if err := checkNamespace(kubeConfig, project.Nk); err != nil {
		p.RemoveConfig(project.Nk)
		return err
	}
	return nil

}

func checkNamespace(kubeConfig, ns string) error {
	kcfg, err := clientcmd.BuildConfigFromFlags("", kubeConfig)
	if err != nil {
		if os.IsNotExist(err) {
			return cmd.ErrNotLoggedIn
		}
		return errors.Wrap(err, "failed to build Kubernetes config from provided kube config path")
	}
	kube, err := kubernetes.NewForConfig(kcfg)
	if err != nil {
		return errors.Wrap(err, "failed to create Kubernetes configuration")
	}

	_, err = kube.CoreV1().Namespaces().Get(ns, metav1.GetOptions{})
	if err != nil {
		return err
	}
	return nil
}
<commit_msg>remove kubernetes context if project/cluster set fails, fixes #325<commit_after>package command

import (
	"log"
	"net/url"
	"os"
	"path/filepath"

	"github.com/mitchellh/cli"
	homedir "github.com/mitchellh/go-homedir"
	"github.com/nerdalize/nerd/cmd"
	"github.com/nerdalize/nerd/nerd/client/auth/v1"
	v1payload "github.com/nerdalize/nerd/nerd/client/auth/v1/payload"

	"github.com/nerdalize/nerd/nerd/conf"
	"github.com/nerdalize/nerd/nerd/oauth"
	"github.com/nerdalize/nerd/pkg/populator"
	"github.com/pkg/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)

//ProjectSetOpts determine
type ProjectSetOpts struct {
	Config     string `long:"config-src" default:"oidc" default-mask:"" description:"type of configuration to use (from env, endpoint, or oidc)"`
	KubeConfig string `long:"kube-config" env:"KUBECONFIG" description:"file at which Nerd will look for Kubernetes credentials" default-mask:"~/.kube/config"`
}

//ProjectSet command
type ProjectSet struct {
	*command
	opts *ProjectSetOpts
}

//ProjectSetFactory returns a factory method for the join command
func ProjectSetFactory() (cli.Command, error) {
	opts := &ProjectSetOpts{}
	comm, err := newCommand("nerd project set", "Set current working project.", "", opts)
	if err != nil {
		return nil, errors.Wrap(err, "failed to create command")
	}
	cmd := &ProjectSet{
		command: comm,
		opts:    opts,
	}
	cmd.runFunc = cmd.DoRun

	return cmd, nil
}

//DoRun is called by run and allows an error to be returned
func (cmd *ProjectSet) DoRun(args []string) (err error) {
	if len(args) < 1 {
		return errShowHelp("Not enough arguments, see below for usage.")
	}
	projectSlug := args[0]

	authbase, err := url.Parse(cmd.config.Auth.APIEndpoint)
	if err != nil {
		return errors.Wrapf(err, "auth endpoint '%v' is not a valid URL", cmd.config.Auth.APIEndpoint)
	}
	authOpsClient := v1auth.NewOpsClient(v1auth.OpsClientConfig{
		Base:   authbase,
		Logger: cmd.outputter.Logger,
	})
	client := v1auth.NewClient(v1auth.ClientConfig{
		Base:               authbase,
		Logger:             cmd.outputter.Logger,
		OAuthTokenProvider: oauth.NewConfigProvider(authOpsClient, cmd.config.Auth.SecureClientID, cmd.config.Auth.SecureClientSecret, cmd.session),
	})

	project, err := client.GetProject(projectSlug)
	if err != nil {
		return HandleError(errors.Wrap(err, "Project not found, please check the project name. You can get a list of your projects by running `nerd project list`."))
	}

	err = setProject(cmd.opts.KubeConfig, cmd.opts.Config, project, cmd.outputter.Logger)
	if err != nil {
		return HandleError(err)
	}

	err = cmd.session.WriteProject(projectSlug, conf.DefaultAWSRegion)
	if err != nil {
		return HandleError(err)
	}

	cmd.outputter.Logger.Printf("Project %s set successfully", projectSlug)
	return nil
}

func setProject(kubeConfig, conf string, project *v1payload.GetProjectOutput, logger *log.Logger) error {
	var (
		hdir string
		err  error
	)
	hdir, err = homedir.Dir()
	if err != nil {
		return err
	}
	if kubeConfig == "" {
		kubeConfig = filepath.Join(hdir, ".kube", "config")
	}
	p, err := populator.New(conf, kubeConfig, hdir, project)
	if err != nil {
		return err
	}
	err = p.PopulateKubeConfig(project.Nk)
	if err != nil {
		p.RemoveConfig(project.Nk)
		return err
	}
	if err := checkNamespace(kubeConfig, project.Nk); err != nil {
		p.RemoveConfig(project.Nk)
		return err
	}
	return nil

}

func checkNamespace(kubeConfig, ns string) error {
	kcfg, err := clientcmd.BuildConfigFromFlags("", kubeConfig)
	if err != nil {
		if os.IsNotExist(err) {
			return cmd.ErrNotLoggedIn
		}
		return errors.Wrap(err, "failed to build Kubernetes config from provided kube config path")
	}
	kube, err := kubernetes.NewForConfig(kcfg)
	if err != nil {
		return errors.Wrap(err, "failed to create Kubernetes configuration")
	}

	_, err = kube.CoreV1().Namespaces().Get(ns, metav1.GetOptions{})
	if err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>/*
Copyright 2018 The Kubernetes Authors.

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

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

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

package azure

import (
	"fmt"
	"strings"

	"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2017-12-01/compute"
	"github.com/golang/glog"

	"k8s.io/apimachinery/pkg/types"
)

// AttachDisk attaches a vhd to vm
// the vhd must exist, can be identified by diskName, diskURI, and lun.
func (ss *scaleSet) AttachDisk(isManagedDisk bool, diskName, diskURI string, nodeName types.NodeName, lun int32, cachingMode compute.CachingTypes) error {
	ssName, instanceID, vm, err := ss.getVmssVM(string(nodeName))
	if err != nil {
		return err
	}

	disks := *vm.StorageProfile.DataDisks
	if isManagedDisk {
		disks = append(disks,
			compute.DataDisk{
				Name:         &diskName,
				Lun:          &lun,
				Caching:      compute.CachingTypes(cachingMode),
				CreateOption: "attach",
				ManagedDisk: &compute.ManagedDiskParameters{
					ID: &diskURI,
				},
			})
	} else {
		disks = append(disks,
			compute.DataDisk{
				Name: &diskName,
				Vhd: &compute.VirtualHardDisk{
					URI: &diskURI,
				},
				Lun:          &lun,
				Caching:      compute.CachingTypes(cachingMode),
				CreateOption: "attach",
			})
	}
	vm.StorageProfile.DataDisks = &disks

	ctx, cancel := getContextWithCancel()
	defer cancel()
	glog.V(2).Infof("azureDisk - update(%s): vm(%s) - attach disk", ss.resourceGroup, nodeName)
	resp, err := ss.VirtualMachineScaleSetVMsClient.Update(ctx, ss.resourceGroup, ssName, instanceID, vm)
	if ss.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) {
		glog.V(2).Infof("azureDisk - update(%s) backing off: vm(%s)", ss.resourceGroup, nodeName)
		retryErr := ss.UpdateVmssVMWithRetry(ctx, ss.resourceGroup, ssName, instanceID, vm)
		if retryErr != nil {
			err = retryErr
			glog.V(2).Infof("azureDisk - update(%s) abort backoff: vm(%s)", ss.resourceGroup, nodeName)
		}
	}
	if err != nil {
		detail := err.Error()
		if strings.Contains(detail, errLeaseFailed) || strings.Contains(detail, errDiskBlobNotFound) {
			// if lease cannot be acquired or disk not found, immediately detach the disk and return the original error
			glog.Infof("azureDisk - err %s, try detach", detail)
			ss.DetachDiskByName(diskName, diskURI, nodeName)
		}
	} else {
		glog.V(4).Info("azureDisk - azure attach succeeded")
		// Invalidate the cache right after updating
		ss.vmssVMCache.Delete(ss.makeVmssVMName(ssName, instanceID))
	}
	return err
}

// DetachDiskByName detaches a vhd from host
// the vhd can be identified by diskName or diskURI
func (ss *scaleSet) DetachDiskByName(diskName, diskURI string, nodeName types.NodeName) error {
	ssName, instanceID, vm, err := ss.getVmssVM(string(nodeName))
	if err != nil {
		return err
	}

	disks := *vm.StorageProfile.DataDisks
	bFoundDisk := false
	for i, disk := range disks {
		if disk.Lun != nil && (disk.Name != nil && diskName != "" && *disk.Name == diskName) ||
			(disk.Vhd != nil && disk.Vhd.URI != nil && diskURI != "" && *disk.Vhd.URI == diskURI) ||
			(disk.ManagedDisk != nil && diskURI != "" && *disk.ManagedDisk.ID == diskURI) {
			// found the disk
			glog.V(4).Infof("azureDisk - detach disk: name %q uri %q", diskName, diskURI)
			disks = append(disks[:i], disks[i+1:]...)
			bFoundDisk = true
			break
		}
	}

	if !bFoundDisk {
		return fmt.Errorf("detach azure disk failure, disk %s not found, diskURI: %s", diskName, diskURI)
	}

	vm.StorageProfile.DataDisks = &disks
	ctx, cancel := getContextWithCancel()
	defer cancel()
	glog.V(2).Infof("azureDisk - update(%s): vm(%s) - detach disk", ss.resourceGroup, nodeName)
	resp, err := ss.VirtualMachineScaleSetVMsClient.Update(ctx, ss.resourceGroup, ssName, instanceID, vm)
	if ss.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) {
		glog.V(2).Infof("azureDisk - update(%s) backing off: vm(%s)", ss.resourceGroup, nodeName)
		retryErr := ss.UpdateVmssVMWithRetry(ctx, ss.resourceGroup, ssName, instanceID, vm)
		if retryErr != nil {
			err = retryErr
			glog.V(2).Infof("azureDisk - update(%s) abort backoff: vm(%s)", ss.resourceGroup, nodeName)
		}
	}
	if err != nil {
		glog.Errorf("azureDisk - azure disk detach %q from %s failed, err: %v", diskName, nodeName, err)
	} else {
		glog.V(4).Info("azureDisk - azure detach succeeded")
		// Invalidate the cache right after updating
		ss.vmssVMCache.Delete(ss.makeVmssVMName(ssName, instanceID))
	}

	return err
}

// GetDataDisks gets a list of data disks attached to the node.
func (ss *scaleSet) GetDataDisks(nodeName types.NodeName) ([]compute.DataDisk, error) {
	_, _, vm, err := ss.getVmssVM(string(nodeName))
	if err != nil {
		return nil, err
	}

	if vm.StorageProfile.DataDisks == nil {
		return nil, nil
	}

	return *vm.StorageProfile.DataDisks, nil
}
<commit_msg>Fix panic for attaching AzureDisk to vmss nodes<commit_after>/*
Copyright 2018 The Kubernetes Authors.

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

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

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

package azure

import (
	"fmt"
	"strings"

	"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2017-12-01/compute"
	"github.com/golang/glog"

	"k8s.io/apimachinery/pkg/types"
)

// AttachDisk attaches a vhd to vm
// the vhd must exist, can be identified by diskName, diskURI, and lun.
func (ss *scaleSet) AttachDisk(isManagedDisk bool, diskName, diskURI string, nodeName types.NodeName, lun int32, cachingMode compute.CachingTypes) error {
	ssName, instanceID, vm, err := ss.getVmssVM(string(nodeName))
	if err != nil {
		return err
	}

	disks := []compute.DataDisk{}
	if vm.StorageProfile != nil && vm.StorageProfile.DataDisks != nil {
		disks = *vm.StorageProfile.DataDisks
	}
	if isManagedDisk {
		disks = append(disks,
			compute.DataDisk{
				Name:         &diskName,
				Lun:          &lun,
				Caching:      compute.CachingTypes(cachingMode),
				CreateOption: "attach",
				ManagedDisk: &compute.ManagedDiskParameters{
					ID: &diskURI,
				},
			})
	} else {
		disks = append(disks,
			compute.DataDisk{
				Name: &diskName,
				Vhd: &compute.VirtualHardDisk{
					URI: &diskURI,
				},
				Lun:          &lun,
				Caching:      compute.CachingTypes(cachingMode),
				CreateOption: "attach",
			})
	}
	vm.StorageProfile.DataDisks = &disks

	ctx, cancel := getContextWithCancel()
	defer cancel()
	glog.V(2).Infof("azureDisk - update(%s): vm(%s) - attach disk", ss.resourceGroup, nodeName)
	resp, err := ss.VirtualMachineScaleSetVMsClient.Update(ctx, ss.resourceGroup, ssName, instanceID, vm)
	if ss.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) {
		glog.V(2).Infof("azureDisk - update(%s) backing off: vm(%s)", ss.resourceGroup, nodeName)
		retryErr := ss.UpdateVmssVMWithRetry(ctx, ss.resourceGroup, ssName, instanceID, vm)
		if retryErr != nil {
			err = retryErr
			glog.V(2).Infof("azureDisk - update(%s) abort backoff: vm(%s)", ss.resourceGroup, nodeName)
		}
	}
	if err != nil {
		detail := err.Error()
		if strings.Contains(detail, errLeaseFailed) || strings.Contains(detail, errDiskBlobNotFound) {
			// if lease cannot be acquired or disk not found, immediately detach the disk and return the original error
			glog.Infof("azureDisk - err %s, try detach", detail)
			ss.DetachDiskByName(diskName, diskURI, nodeName)
		}
	} else {
		glog.V(4).Info("azureDisk - azure attach succeeded")
		// Invalidate the cache right after updating
		ss.vmssVMCache.Delete(ss.makeVmssVMName(ssName, instanceID))
	}
	return err
}

// DetachDiskByName detaches a vhd from host
// the vhd can be identified by diskName or diskURI
func (ss *scaleSet) DetachDiskByName(diskName, diskURI string, nodeName types.NodeName) error {
	ssName, instanceID, vm, err := ss.getVmssVM(string(nodeName))
	if err != nil {
		return err
	}

	disks := []compute.DataDisk{}
	if vm.StorageProfile != nil && vm.StorageProfile.DataDisks != nil {
		disks = *vm.StorageProfile.DataDisks
	}
	bFoundDisk := false
	for i, disk := range disks {
		if disk.Lun != nil && (disk.Name != nil && diskName != "" && *disk.Name == diskName) ||
			(disk.Vhd != nil && disk.Vhd.URI != nil && diskURI != "" && *disk.Vhd.URI == diskURI) ||
			(disk.ManagedDisk != nil && diskURI != "" && *disk.ManagedDisk.ID == diskURI) {
			// found the disk
			glog.V(4).Infof("azureDisk - detach disk: name %q uri %q", diskName, diskURI)
			disks = append(disks[:i], disks[i+1:]...)
			bFoundDisk = true
			break
		}
	}

	if !bFoundDisk {
		return fmt.Errorf("detach azure disk failure, disk %s not found, diskURI: %s", diskName, diskURI)
	}

	vm.StorageProfile.DataDisks = &disks
	ctx, cancel := getContextWithCancel()
	defer cancel()
	glog.V(2).Infof("azureDisk - update(%s): vm(%s) - detach disk", ss.resourceGroup, nodeName)
	resp, err := ss.VirtualMachineScaleSetVMsClient.Update(ctx, ss.resourceGroup, ssName, instanceID, vm)
	if ss.CloudProviderBackoff && shouldRetryHTTPRequest(resp, err) {
		glog.V(2).Infof("azureDisk - update(%s) backing off: vm(%s)", ss.resourceGroup, nodeName)
		retryErr := ss.UpdateVmssVMWithRetry(ctx, ss.resourceGroup, ssName, instanceID, vm)
		if retryErr != nil {
			err = retryErr
			glog.V(2).Infof("azureDisk - update(%s) abort backoff: vm(%s)", ss.resourceGroup, nodeName)
		}
	}
	if err != nil {
		glog.Errorf("azureDisk - azure disk detach %q from %s failed, err: %v", diskName, nodeName, err)
	} else {
		glog.V(4).Info("azureDisk - azure detach succeeded")
		// Invalidate the cache right after updating
		ss.vmssVMCache.Delete(ss.makeVmssVMName(ssName, instanceID))
	}

	return err
}

// GetDataDisks gets a list of data disks attached to the node.
func (ss *scaleSet) GetDataDisks(nodeName types.NodeName) ([]compute.DataDisk, error) {
	_, _, vm, err := ss.getVmssVM(string(nodeName))
	if err != nil {
		return nil, err
	}

	if vm.StorageProfile == nil || vm.StorageProfile.DataDisks == nil {
		return nil, nil
	}

	return *vm.StorageProfile.DataDisks, nil
}
<|endoftext|>


<commit_before>package resolve

import (
	"github.com/Aptomi/aptomi/pkg/lang"
	"github.com/Aptomi/aptomi/pkg/lang/expression"
	"github.com/Aptomi/aptomi/pkg/lang/template"
	"github.com/Aptomi/aptomi/pkg/util"
)

/*
	Data exposed to context expressions/criterias defined in policy
*/

// This method defines which contextual information will be exposed to the expression engine (for evaluating criterias)
// Be careful about what gets exposed through this method. User can refer to structs and their methods from the policy
func (node *resolutionNode) getContextualDataForContextExpression() *expression.Parameters {
	return expression.NewParams(
		node.labels.Labels,
		map[string]interface{}{},
	)
}

/*
	Data exposed to rules defined
*/

// This method defines which contextual information will be exposed to the expression engine (for evaluating rules)
// Be careful about what gets exposed through this method. User can refer to structs and their methods from the policy
func (node *resolutionNode) getContextualDataForRuleExpression() *expression.Parameters {
	return expression.NewParams(
		node.labels.Labels,
		map[string]interface{}{
			"service": node.proxyService(node.service),
		},
	)
}

/*
	Data exposed to templates defined in policy
*/

// This method defines which contextual information will be exposed to the template engine (for evaluating all templates - discovery, code params, etc)
// Be careful about what gets exposed through this method. User can refer to structs and their methods from the policy
func (node *resolutionNode) getContextualDataForContextAllocationTemplate() *template.Parameters {
	return template.NewParams(
		struct {
			User   interface{}
			Labels interface{}
		}{
			User:   node.proxyUser(node.user),
			Labels: node.labels.Labels,
		},
	)
}

// This method defines which contextual information will be exposed to the template engine (for evaluating all templates - discovery, code params, etc)
// Be careful about what gets exposed through this method. User can refer to structs and their methods from the policy
func (node *resolutionNode) getContextualDataForCodeDiscoveryTemplate() *template.Parameters {
	return template.NewParams(
		struct {
			User      interface{}
			Labels    interface{}
			Discovery interface{}
		}{
			User:      node.proxyUser(node.user),
			Labels:    node.labels.Labels,
			Discovery: node.proxyDiscovery(node.discoveryTreeNode, node.componentKey),
		},
	)
}

/*
	Proxy functions
*/

// How service is visible from the policy language
func (node *resolutionNode) proxyService(service *lang.Service) interface{} {
	return struct {
		lang.Metadata
		Labels interface{}
	}{
		Metadata: service.Metadata,
		Labels:   service.Labels,
	}
}

// How user is visible from the policy language
func (node *resolutionNode) proxyUser(user *lang.User) interface{} {
	result := struct {
		Name    interface{}
		Labels  interface{}
		Secrets interface{}
	}{
		Name:    user.Name,
		Labels:  user.Labels,
		Secrets: node.resolver.externalData.SecretLoader.LoadSecretsByUserName(user.Name),
	}
	return result
}

// How discovery tree is visible from the policy language
func (node *resolutionNode) proxyDiscovery(discoveryTree util.NestedParameterMap, cik *ComponentInstanceKey) interface{} {
	result := discoveryTree.MakeCopy()

	// special case to announce own component instance
	result["instance"] = util.EscapeName(cik.GetDeployName())

	// special case to announce own component ID
	result["instanceId"] = util.HashFnv(cik.GetKey())

	// expose parent service information as well
	if cik.IsComponent() {
		// Get service key
		serviceCik := cik.GetParentServiceKey()

		// create a bucket for service
		result["service"] = util.NestedParameterMap{}

		// special case to announce own component instance
		result.GetNestedMap("service")["instance"] = util.EscapeName(serviceCik.GetDeployName())

		// special case to announce own component ID
		result.GetNestedMap("service")["instanceId"] = util.HashFnv(serviceCik.GetKey())
	}

	return result
}
<commit_msg>comment fixes criterias -> criteria<commit_after>package resolve

import (
	"github.com/Aptomi/aptomi/pkg/lang"
	"github.com/Aptomi/aptomi/pkg/lang/expression"
	"github.com/Aptomi/aptomi/pkg/lang/template"
	"github.com/Aptomi/aptomi/pkg/util"
)

/*
	Data exposed to context expressions/criteria defined in policy
*/

// This method defines which contextual information will be exposed to the expression engine (for evaluating criteria)
// Be careful about what gets exposed through this method. User can refer to structs and their methods from the policy
func (node *resolutionNode) getContextualDataForContextExpression() *expression.Parameters {
	return expression.NewParams(
		node.labels.Labels,
		map[string]interface{}{},
	)
}

/*
	Data exposed to rules defined
*/

// This method defines which contextual information will be exposed to the expression engine (for evaluating rules)
// Be careful about what gets exposed through this method. User can refer to structs and their methods from the policy
func (node *resolutionNode) getContextualDataForRuleExpression() *expression.Parameters {
	return expression.NewParams(
		node.labels.Labels,
		map[string]interface{}{
			"service": node.proxyService(node.service),
		},
	)
}

/*
	Data exposed to templates defined in policy
*/

// This method defines which contextual information will be exposed to the template engine (for evaluating all templates - discovery, code params, etc)
// Be careful about what gets exposed through this method. User can refer to structs and their methods from the policy
func (node *resolutionNode) getContextualDataForContextAllocationTemplate() *template.Parameters {
	return template.NewParams(
		struct {
			User   interface{}
			Labels interface{}
		}{
			User:   node.proxyUser(node.user),
			Labels: node.labels.Labels,
		},
	)
}

// This method defines which contextual information will be exposed to the template engine (for evaluating all templates - discovery, code params, etc)
// Be careful about what gets exposed through this method. User can refer to structs and their methods from the policy
func (node *resolutionNode) getContextualDataForCodeDiscoveryTemplate() *template.Parameters {
	return template.NewParams(
		struct {
			User      interface{}
			Labels    interface{}
			Discovery interface{}
		}{
			User:      node.proxyUser(node.user),
			Labels:    node.labels.Labels,
			Discovery: node.proxyDiscovery(node.discoveryTreeNode, node.componentKey),
		},
	)
}

/*
	Proxy functions
*/

// How service is visible from the policy language
func (node *resolutionNode) proxyService(service *lang.Service) interface{} {
	return struct {
		lang.Metadata
		Labels interface{}
	}{
		Metadata: service.Metadata,
		Labels:   service.Labels,
	}
}

// How user is visible from the policy language
func (node *resolutionNode) proxyUser(user *lang.User) interface{} {
	result := struct {
		Name    interface{}
		Labels  interface{}
		Secrets interface{}
	}{
		Name:    user.Name,
		Labels:  user.Labels,
		Secrets: node.resolver.externalData.SecretLoader.LoadSecretsByUserName(user.Name),
	}
	return result
}

// How discovery tree is visible from the policy language
func (node *resolutionNode) proxyDiscovery(discoveryTree util.NestedParameterMap, cik *ComponentInstanceKey) interface{} {
	result := discoveryTree.MakeCopy()

	// special case to announce own component instance
	result["instance"] = util.EscapeName(cik.GetDeployName())

	// special case to announce own component ID
	result["instanceId"] = util.HashFnv(cik.GetKey())

	// expose parent service information as well
	if cik.IsComponent() {
		// Get service key
		serviceCik := cik.GetParentServiceKey()

		// create a bucket for service
		result["service"] = util.NestedParameterMap{}

		// special case to announce own component instance
		result.GetNestedMap("service")["instance"] = util.EscapeName(serviceCik.GetDeployName())

		// special case to announce own component ID
		result.GetNestedMap("service")["instanceId"] = util.HashFnv(serviceCik.GetKey())
	}

	return result
}
<|endoftext|>


<commit_before>// +build !containers_image_ostree_stub

package ostree

import (
	"bytes"
	"compress/gzip"
	"context"
	"encoding/base64"
	"fmt"
	"io"
	"io/ioutil"
	"strconv"
	"strings"
	"unsafe"

	"github.com/containers/image/manifest"
	"github.com/containers/image/types"
	"github.com/containers/storage/pkg/ioutils"
	"github.com/opencontainers/go-digest"
	glib "github.com/ostreedev/ostree-go/pkg/glibobject"
	"github.com/pkg/errors"
	"github.com/vbatts/tar-split/tar/asm"
	"github.com/vbatts/tar-split/tar/storage"
)

// #cgo pkg-config: glib-2.0 gobject-2.0 ostree-1
// #include <glib.h>
// #include <glib-object.h>
// #include <gio/gio.h>
// #include <stdlib.h>
// #include <ostree.h>
// #include <gio/ginputstream.h>
import "C"

type ostreeImageSource struct {
	ref    ostreeReference
	tmpDir string
	repo   *C.struct_OstreeRepo
}

// newImageSource returns an ImageSource for reading from an existing directory.
func newImageSource(ctx *types.SystemContext, tmpDir string, ref ostreeReference) (types.ImageSource, error) {
	return &ostreeImageSource{ref: ref, tmpDir: tmpDir}, nil
}

// Reference returns the reference used to set up this source.
func (s *ostreeImageSource) Reference() types.ImageReference {
	return s.ref
}

// Close removes resources associated with an initialized ImageSource, if any.
func (s *ostreeImageSource) Close() error {
	if s.repo != nil {
		C.g_object_unref(C.gpointer(s.repo))
	}
	return nil
}

func (s *ostreeImageSource) getLayerSize(blob string) (int64, error) {
	b := fmt.Sprintf("ociimage/%s", blob)
	found, data, err := readMetadata(s.repo, b, "docker.size")
	if err != nil || !found {
		return 0, err
	}
	return strconv.ParseInt(data, 10, 64)
}

func (s *ostreeImageSource) getLenSignatures() (int64, error) {
	b := fmt.Sprintf("ociimage/%s", s.ref.branchName)
	found, data, err := readMetadata(s.repo, b, "signatures")
	if err != nil {
		return -1, err
	}
	if !found {
		// if 'signatures' is not present, just return 0 signatures.
		return 0, nil
	}
	return strconv.ParseInt(data, 10, 64)
}

func (s *ostreeImageSource) getTarSplitData(blob string) ([]byte, error) {
	b := fmt.Sprintf("ociimage/%s", blob)
	found, out, err := readMetadata(s.repo, b, "tarsplit.output")
	if err != nil || !found {
		return nil, err
	}
	return base64.StdEncoding.DecodeString(out)
}

// GetManifest returns the image's manifest along with its MIME type (which may be empty when it can't be determined but the manifest is available).
// It may use a remote (= slow) service.
func (s *ostreeImageSource) GetManifest(instanceDigest *digest.Digest) ([]byte, string, error) {
	if instanceDigest != nil {
		return nil, "", errors.Errorf(`Manifest lists are not supported by "ostree:"`)
	}
	if s.repo == nil {
		repo, err := openRepo(s.ref.repo)
		if err != nil {
			return nil, "", err
		}
		s.repo = repo
	}

	b := fmt.Sprintf("ociimage/%s", s.ref.branchName)
	found, out, err := readMetadata(s.repo, b, "docker.manifest")
	if err != nil {
		return nil, "", err
	}
	if !found {
		return nil, "", errors.New("manifest not found")
	}
	m := []byte(out)
	return m, manifest.GuessMIMEType(m), nil
}

func (s *ostreeImageSource) GetTargetManifest(digest digest.Digest) ([]byte, string, error) {
	return nil, "", errors.New("manifest lists are not supported by this transport")
}

func openRepo(path string) (*C.struct_OstreeRepo, error) {
	var cerr *C.GError
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))
	pathc := C.g_file_new_for_path(cpath)
	defer C.g_object_unref(C.gpointer(pathc))
	repo := C.ostree_repo_new(pathc)
	r := glib.GoBool(glib.GBoolean(C.ostree_repo_open(repo, nil, &cerr)))
	if !r {
		C.g_object_unref(C.gpointer(repo))
		return nil, glib.ConvertGError(glib.ToGError(unsafe.Pointer(cerr)))
	}
	return repo, nil
}

type ostreePathFileGetter struct {
	repo       *C.struct_OstreeRepo
	parentRoot *C.GFile
}

type ostreeReader struct {
	stream *C.GFileInputStream
}

func (o ostreeReader) Close() error {
	C.g_object_unref(C.gpointer(o.stream))
	return nil
}
func (o ostreeReader) Read(p []byte) (int, error) {
	var cerr *C.GError
	instanceCast := C.g_type_check_instance_cast((*C.GTypeInstance)(unsafe.Pointer(o.stream)), C.g_input_stream_get_type())
	stream := (*C.GInputStream)(unsafe.Pointer(instanceCast))

	b := C.g_input_stream_read_bytes(stream, (C.gsize)(cap(p)), nil, &cerr)
	if b == nil {
		return 0, glib.ConvertGError(glib.ToGError(unsafe.Pointer(cerr)))
	}
	defer C.g_bytes_unref(b)

	count := int(C.g_bytes_get_size(b))
	if count == 0 {
		return 0, io.EOF
	}
	data := (*[1 << 30]byte)(unsafe.Pointer(C.g_bytes_get_data(b, nil)))[:count:count]
	copy(p, data)
	return count, nil
}

func readMetadata(repo *C.struct_OstreeRepo, commit, key string) (bool, string, error) {
	var cerr *C.GError
	var ref *C.char
	defer C.free(unsafe.Pointer(ref))

	cCommit := C.CString(commit)
	defer C.free(unsafe.Pointer(cCommit))

	if !glib.GoBool(glib.GBoolean(C.ostree_repo_resolve_rev(repo, cCommit, C.gboolean(1), &ref, &cerr))) {
		return false, "", glib.ConvertGError(glib.ToGError(unsafe.Pointer(cerr)))
	}

	if ref == nil {
		return false, "", nil
	}

	var variant *C.GVariant
	if !glib.GoBool(glib.GBoolean(C.ostree_repo_load_variant(repo, C.OSTREE_OBJECT_TYPE_COMMIT, ref, &variant, &cerr))) {
		return false, "", glib.ConvertGError(glib.ToGError(unsafe.Pointer(cerr)))
	}
	defer C.g_variant_unref(variant)
	if variant != nil {
		cKey := C.CString(key)
		defer C.free(unsafe.Pointer(cKey))

		metadata := C.g_variant_get_child_value(variant, 0)
		defer C.g_variant_unref(metadata)

		data := C.g_variant_lookup_value(metadata, (*C.gchar)(cKey), nil)
		if data != nil {
			defer C.g_variant_unref(data)
			ptr := (*C.char)(C.g_variant_get_string(data, nil))
			val := C.GoString(ptr)
			return true, val, nil
		}
	}
	return false, "", nil
}

func newOSTreePathFileGetter(repo *C.struct_OstreeRepo, commit string) (*ostreePathFileGetter, error) {
	var cerr *C.GError
	var parentRoot *C.GFile
	cCommit := C.CString(commit)
	defer C.free(unsafe.Pointer(cCommit))
	if !glib.GoBool(glib.GBoolean(C.ostree_repo_read_commit(repo, cCommit, &parentRoot, nil, nil, &cerr))) {
		return &ostreePathFileGetter{}, glib.ConvertGError(glib.ToGError(unsafe.Pointer(cerr)))
	}

	C.g_object_ref(C.gpointer(repo))

	return &ostreePathFileGetter{repo: repo, parentRoot: parentRoot}, nil
}

func (o ostreePathFileGetter) Get(filename string) (io.ReadCloser, error) {
	var file *C.GFile
	if strings.HasPrefix(filename, "./") {
		filename = filename[2:]
	}
	cfilename := C.CString(filename)
	defer C.free(unsafe.Pointer(cfilename))

	file = (*C.GFile)(C.g_file_resolve_relative_path(o.parentRoot, cfilename))

	var cerr *C.GError
	stream := C.g_file_read(file, nil, &cerr)
	if stream == nil {
		return nil, glib.ConvertGError(glib.ToGError(unsafe.Pointer(cerr)))
	}

	return &ostreeReader{stream: stream}, nil
}

func (o ostreePathFileGetter) Close() {
	C.g_object_unref(C.gpointer(o.repo))
	C.g_object_unref(C.gpointer(o.parentRoot))
}

func (s *ostreeImageSource) readSingleFile(commit, path string) (io.ReadCloser, error) {
	getter, err := newOSTreePathFileGetter(s.repo, commit)
	if err != nil {
		return nil, err
	}
	defer getter.Close()

	return getter.Get(path)
}

// GetBlob returns a stream for the specified blob, and the blob's size.
func (s *ostreeImageSource) GetBlob(info types.BlobInfo) (io.ReadCloser, int64, error) {
	blob := info.Digest.Hex()
	branch := fmt.Sprintf("ociimage/%s", blob)

	if s.repo == nil {
		repo, err := openRepo(s.ref.repo)
		if err != nil {
			return nil, 0, err
		}
		s.repo = repo
	}

	layerSize, err := s.getLayerSize(blob)
	if err != nil {
		return nil, 0, err
	}

	tarsplit, err := s.getTarSplitData(blob)
	if err != nil {
		return nil, 0, err
	}

	// if tarsplit is nil we are looking at the manifest.  Return directly the file in /content
	if tarsplit == nil {
		file, err := s.readSingleFile(branch, "/content")
		if err != nil {
			return nil, 0, err
		}
		return file, layerSize, nil
	}

	mf := bytes.NewReader(tarsplit)
	mfz, err := gzip.NewReader(mf)
	if err != nil {
		return nil, 0, err
	}
	defer mfz.Close()
	metaUnpacker := storage.NewJSONUnpacker(mfz)

	getter, err := newOSTreePathFileGetter(s.repo, branch)
	if err != nil {
		return nil, 0, err
	}

	ots := asm.NewOutputTarStream(getter, metaUnpacker)

	pipeReader, pipeWriter := io.Pipe()
	gzipWriter := gzip.NewWriter(pipeWriter)
	go func() {
		io.Copy(gzipWriter, ots)
		gzipWriter.Close()
		pipeWriter.Close()
	}()

	rc := ioutils.NewReadCloserWrapper(pipeReader, func() error {
		getter.Close()
		return ots.Close()
	})
	return rc, layerSize, nil
}

func (s *ostreeImageSource) GetSignatures(ctx context.Context, instanceDigest *digest.Digest) ([][]byte, error) {
	if instanceDigest != nil {
		return nil, errors.New("manifest lists are not supported by this transport")
	}
	lenSignatures, err := s.getLenSignatures()
	if err != nil {
		return nil, err
	}
	branch := fmt.Sprintf("ociimage/%s", s.ref.branchName)

	if s.repo == nil {
		repo, err := openRepo(s.ref.repo)
		if err != nil {
			return nil, err
		}
		s.repo = repo
	}

	signatures := [][]byte{}
	for i := int64(1); i <= lenSignatures; i++ {
		sigReader, err := s.readSingleFile(branch, fmt.Sprintf("/signature-%d", i))
		if err != nil {
			return nil, err
		}
		defer sigReader.Close()

		sig, err := ioutil.ReadAll(sigReader)
		if err != nil {
			return nil, err
		}
		signatures = append(signatures, sig)
	}
	return signatures, nil
}
<commit_msg>ostree: support only uncompressed images for now<commit_after>// +build !containers_image_ostree_stub

package ostree

import (
	"bytes"
	"compress/gzip"
	"context"
	"encoding/base64"
	"fmt"
	"io"
	"io/ioutil"
	"strconv"
	"strings"
	"unsafe"

	"github.com/containers/image/manifest"
	"github.com/containers/image/types"
	"github.com/containers/storage/pkg/ioutils"
	"github.com/opencontainers/go-digest"
	glib "github.com/ostreedev/ostree-go/pkg/glibobject"
	"github.com/pkg/errors"
	"github.com/vbatts/tar-split/tar/asm"
	"github.com/vbatts/tar-split/tar/storage"
)

// #cgo pkg-config: glib-2.0 gobject-2.0 ostree-1
// #include <glib.h>
// #include <glib-object.h>
// #include <gio/gio.h>
// #include <stdlib.h>
// #include <ostree.h>
// #include <gio/ginputstream.h>
import "C"

type ostreeImageSource struct {
	ref    ostreeReference
	tmpDir string
	repo   *C.struct_OstreeRepo
}

// newImageSource returns an ImageSource for reading from an existing directory.
func newImageSource(ctx *types.SystemContext, tmpDir string, ref ostreeReference) (types.ImageSource, error) {
	return &ostreeImageSource{ref: ref, tmpDir: tmpDir}, nil
}

// Reference returns the reference used to set up this source.
func (s *ostreeImageSource) Reference() types.ImageReference {
	return s.ref
}

// Close removes resources associated with an initialized ImageSource, if any.
func (s *ostreeImageSource) Close() error {
	if s.repo != nil {
		C.g_object_unref(C.gpointer(s.repo))
	}
	return nil
}

func (s *ostreeImageSource) getLayerSize(blob string) (int64, error) {
	b := fmt.Sprintf("ociimage/%s", blob)
	found, data, err := readMetadata(s.repo, b, "docker.size")
	if err != nil || !found {
		return 0, err
	}
	return strconv.ParseInt(data, 10, 64)
}

func (s *ostreeImageSource) getLenSignatures() (int64, error) {
	b := fmt.Sprintf("ociimage/%s", s.ref.branchName)
	found, data, err := readMetadata(s.repo, b, "signatures")
	if err != nil {
		return -1, err
	}
	if !found {
		// if 'signatures' is not present, just return 0 signatures.
		return 0, nil
	}
	return strconv.ParseInt(data, 10, 64)
}

func (s *ostreeImageSource) getTarSplitData(blob string) ([]byte, error) {
	b := fmt.Sprintf("ociimage/%s", blob)
	found, out, err := readMetadata(s.repo, b, "tarsplit.output")
	if err != nil || !found {
		return nil, err
	}
	return base64.StdEncoding.DecodeString(out)
}

// GetManifest returns the image's manifest along with its MIME type (which may be empty when it can't be determined but the manifest is available).
// It may use a remote (= slow) service.
func (s *ostreeImageSource) GetManifest(instanceDigest *digest.Digest) ([]byte, string, error) {
	if instanceDigest != nil {
		return nil, "", errors.Errorf(`Manifest lists are not supported by "ostree:"`)
	}
	if s.repo == nil {
		repo, err := openRepo(s.ref.repo)
		if err != nil {
			return nil, "", err
		}
		s.repo = repo
	}

	b := fmt.Sprintf("ociimage/%s", s.ref.branchName)
	found, out, err := readMetadata(s.repo, b, "docker.manifest")
	if err != nil {
		return nil, "", err
	}
	if !found {
		return nil, "", errors.New("manifest not found")
	}
	m := []byte(out)
	return m, manifest.GuessMIMEType(m), nil
}

func (s *ostreeImageSource) GetTargetManifest(digest digest.Digest) ([]byte, string, error) {
	return nil, "", errors.New("manifest lists are not supported by this transport")
}

func openRepo(path string) (*C.struct_OstreeRepo, error) {
	var cerr *C.GError
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))
	pathc := C.g_file_new_for_path(cpath)
	defer C.g_object_unref(C.gpointer(pathc))
	repo := C.ostree_repo_new(pathc)
	r := glib.GoBool(glib.GBoolean(C.ostree_repo_open(repo, nil, &cerr)))
	if !r {
		C.g_object_unref(C.gpointer(repo))
		return nil, glib.ConvertGError(glib.ToGError(unsafe.Pointer(cerr)))
	}
	return repo, nil
}

type ostreePathFileGetter struct {
	repo       *C.struct_OstreeRepo
	parentRoot *C.GFile
}

type ostreeReader struct {
	stream *C.GFileInputStream
}

func (o ostreeReader) Close() error {
	C.g_object_unref(C.gpointer(o.stream))
	return nil
}
func (o ostreeReader) Read(p []byte) (int, error) {
	var cerr *C.GError
	instanceCast := C.g_type_check_instance_cast((*C.GTypeInstance)(unsafe.Pointer(o.stream)), C.g_input_stream_get_type())
	stream := (*C.GInputStream)(unsafe.Pointer(instanceCast))

	b := C.g_input_stream_read_bytes(stream, (C.gsize)(cap(p)), nil, &cerr)
	if b == nil {
		return 0, glib.ConvertGError(glib.ToGError(unsafe.Pointer(cerr)))
	}
	defer C.g_bytes_unref(b)

	count := int(C.g_bytes_get_size(b))
	if count == 0 {
		return 0, io.EOF
	}
	data := (*[1 << 30]byte)(unsafe.Pointer(C.g_bytes_get_data(b, nil)))[:count:count]
	copy(p, data)
	return count, nil
}

func readMetadata(repo *C.struct_OstreeRepo, commit, key string) (bool, string, error) {
	var cerr *C.GError
	var ref *C.char
	defer C.free(unsafe.Pointer(ref))

	cCommit := C.CString(commit)
	defer C.free(unsafe.Pointer(cCommit))

	if !glib.GoBool(glib.GBoolean(C.ostree_repo_resolve_rev(repo, cCommit, C.gboolean(1), &ref, &cerr))) {
		return false, "", glib.ConvertGError(glib.ToGError(unsafe.Pointer(cerr)))
	}

	if ref == nil {
		return false, "", nil
	}

	var variant *C.GVariant
	if !glib.GoBool(glib.GBoolean(C.ostree_repo_load_variant(repo, C.OSTREE_OBJECT_TYPE_COMMIT, ref, &variant, &cerr))) {
		return false, "", glib.ConvertGError(glib.ToGError(unsafe.Pointer(cerr)))
	}
	defer C.g_variant_unref(variant)
	if variant != nil {
		cKey := C.CString(key)
		defer C.free(unsafe.Pointer(cKey))

		metadata := C.g_variant_get_child_value(variant, 0)
		defer C.g_variant_unref(metadata)

		data := C.g_variant_lookup_value(metadata, (*C.gchar)(cKey), nil)
		if data != nil {
			defer C.g_variant_unref(data)
			ptr := (*C.char)(C.g_variant_get_string(data, nil))
			val := C.GoString(ptr)
			return true, val, nil
		}
	}
	return false, "", nil
}

func newOSTreePathFileGetter(repo *C.struct_OstreeRepo, commit string) (*ostreePathFileGetter, error) {
	var cerr *C.GError
	var parentRoot *C.GFile
	cCommit := C.CString(commit)
	defer C.free(unsafe.Pointer(cCommit))
	if !glib.GoBool(glib.GBoolean(C.ostree_repo_read_commit(repo, cCommit, &parentRoot, nil, nil, &cerr))) {
		return &ostreePathFileGetter{}, glib.ConvertGError(glib.ToGError(unsafe.Pointer(cerr)))
	}

	C.g_object_ref(C.gpointer(repo))

	return &ostreePathFileGetter{repo: repo, parentRoot: parentRoot}, nil
}

func (o ostreePathFileGetter) Get(filename string) (io.ReadCloser, error) {
	var file *C.GFile
	if strings.HasPrefix(filename, "./") {
		filename = filename[2:]
	}
	cfilename := C.CString(filename)
	defer C.free(unsafe.Pointer(cfilename))

	file = (*C.GFile)(C.g_file_resolve_relative_path(o.parentRoot, cfilename))

	var cerr *C.GError
	stream := C.g_file_read(file, nil, &cerr)
	if stream == nil {
		return nil, glib.ConvertGError(glib.ToGError(unsafe.Pointer(cerr)))
	}

	return &ostreeReader{stream: stream}, nil
}

func (o ostreePathFileGetter) Close() {
	C.g_object_unref(C.gpointer(o.repo))
	C.g_object_unref(C.gpointer(o.parentRoot))
}

func (s *ostreeImageSource) readSingleFile(commit, path string) (io.ReadCloser, error) {
	getter, err := newOSTreePathFileGetter(s.repo, commit)
	if err != nil {
		return nil, err
	}
	defer getter.Close()

	return getter.Get(path)
}

// GetBlob returns a stream for the specified blob, and the blob's size.
func (s *ostreeImageSource) GetBlob(info types.BlobInfo) (io.ReadCloser, int64, error) {
	blob := info.Digest.Hex()
	branch := fmt.Sprintf("ociimage/%s", blob)

	if s.repo == nil {
		repo, err := openRepo(s.ref.repo)
		if err != nil {
			return nil, 0, err
		}
		s.repo = repo
	}

	layerSize, err := s.getLayerSize(blob)
	if err != nil {
		return nil, 0, err
	}

	tarsplit, err := s.getTarSplitData(blob)
	if err != nil {
		return nil, 0, err
	}

	// if tarsplit is nil we are looking at the manifest.  Return directly the file in /content
	if tarsplit == nil {
		file, err := s.readSingleFile(branch, "/content")
		if err != nil {
			return nil, 0, err
		}
		return file, layerSize, nil
	}

	mf := bytes.NewReader(tarsplit)
	mfz, err := gzip.NewReader(mf)
	if err != nil {
		return nil, 0, err
	}
	defer mfz.Close()
	metaUnpacker := storage.NewJSONUnpacker(mfz)

	getter, err := newOSTreePathFileGetter(s.repo, branch)
	if err != nil {
		return nil, 0, err
	}

	ots := asm.NewOutputTarStream(getter, metaUnpacker)

	pipeReader, pipeWriter := io.Pipe()
	go func() {
		io.Copy(pipeWriter, ots)
		pipeWriter.Close()
	}()

	rc := ioutils.NewReadCloserWrapper(pipeReader, func() error {
		getter.Close()
		return ots.Close()
	})
	return rc, layerSize, nil
}

func (s *ostreeImageSource) GetSignatures(ctx context.Context, instanceDigest *digest.Digest) ([][]byte, error) {
	if instanceDigest != nil {
		return nil, errors.New("manifest lists are not supported by this transport")
	}
	lenSignatures, err := s.getLenSignatures()
	if err != nil {
		return nil, err
	}
	branch := fmt.Sprintf("ociimage/%s", s.ref.branchName)

	if s.repo == nil {
		repo, err := openRepo(s.ref.repo)
		if err != nil {
			return nil, err
		}
		s.repo = repo
	}

	signatures := [][]byte{}
	for i := int64(1); i <= lenSignatures; i++ {
		sigReader, err := s.readSingleFile(branch, fmt.Sprintf("/signature-%d", i))
		if err != nil {
			return nil, err
		}
		defer sigReader.Close()

		sig, err := ioutil.ReadAll(sigReader)
		if err != nil {
			return nil, err
		}
		signatures = append(signatures, sig)
	}
	return signatures, nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io"
	"os"
	"os/signal"
	"path/filepath"
	"syscall"

	"v2ray.com/core"
	"v2ray.com/core/common/log"

	// The following are necessary as they register handlers in their init functions.
	_ "v2ray.com/core/proxy/blackhole"
	_ "v2ray.com/core/proxy/dokodemo"
	_ "v2ray.com/core/proxy/freedom"
	_ "v2ray.com/core/proxy/http"
	_ "v2ray.com/core/proxy/shadowsocks"
	_ "v2ray.com/core/proxy/socks"
	_ "v2ray.com/core/proxy/vmess/inbound"
	_ "v2ray.com/core/proxy/vmess/outbound"

	_ "v2ray.com/core/transport/internet/kcp"
	_ "v2ray.com/core/transport/internet/tcp"
	_ "v2ray.com/core/transport/internet/udp"
	_ "v2ray.com/core/transport/internet/ws"

	_ "v2ray.com/core/transport/internet/authenticators/noop"
	_ "v2ray.com/core/transport/internet/authenticators/srtp"
	_ "v2ray.com/core/transport/internet/authenticators/utp"
)

var (
	configFile string
	version    = flag.Bool("version", false, "Show current version of V2Ray.")
	test       = flag.Bool("test", false, "Test config file only, without launching V2Ray server.")
	format     = flag.String("format", "json", "Format of input file.")
)

func init() {
	defaultConfigFile := ""
	workingDir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err == nil {
		defaultConfigFile = filepath.Join(workingDir, "config.json")
	}
	flag.StringVar(&configFile, "config", defaultConfigFile, "Config file for this Point server.")
}

func startV2Ray() *core.Point {
	if len(configFile) == 0 {
		log.Error("Config file is not set.")
		return nil
	}
	var configInput io.Reader
	if configFile == "stdin:" {
		configInput = os.Stdin
	} else {
		fixedFile := os.ExpandEnv(configFile)
		file, err := os.Open(fixedFile)
		if err != nil {
			log.Error("Config file not readable: ", err)
			return nil
		}
		defer file.Close()
		configInput = file
	}
	config, err := core.LoadConfig(configInput)
	if err != nil {
		log.Error("Failed to read config file (", configFile, "): ", configFile, err)
		return nil
	}

	vPoint, err := core.NewPoint(config)
	if err != nil {
		log.Error("Failed to create Point server: ", err)
		return nil
	}

	if *test {
		fmt.Println("Configuration OK.")
		return nil
	}

	err = vPoint.Start()
	if err != nil {
		log.Error("Error starting Point server: ", err)
		return nil
	}

	return vPoint
}

func main() {
	flag.Parse()

	core.PrintVersion()

	if *version {
		return
	}

	if point := startV2Ray(); point != nil {
		osSignals := make(chan os.Signal, 1)
		signal.Notify(osSignals, os.Interrupt, os.Kill, syscall.SIGTERM)

		<-osSignals
		point.Close()
	}
	log.Close()
}
<commit_msg>update main code<commit_after>package main

import (
	"flag"
	"fmt"
	"io"
	"os"
	"os/signal"
	"path/filepath"
	"syscall"

	"v2ray.com/core"
	"v2ray.com/core/common/log"
)

var (
	configFile string
	version    = flag.Bool("version", false, "Show current version of V2Ray.")
	test       = flag.Bool("test", false, "Test config file only, without launching V2Ray server.")
	format     = flag.String("format", "json", "Format of input file.")
)

func init() {
	defaultConfigFile := ""
	workingDir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err == nil {
		defaultConfigFile = filepath.Join(workingDir, "config.json")
	}
	flag.StringVar(&configFile, "config", defaultConfigFile, "Config file for this Point server.")
}

func startV2Ray() *core.Point {
	if len(configFile) == 0 {
		log.Error("Config file is not set.")
		return nil
	}
	var configInput io.Reader
	if configFile == "stdin:" {
		configInput = os.Stdin
	} else {
		fixedFile := os.ExpandEnv(configFile)
		file, err := os.Open(fixedFile)
		if err != nil {
			log.Error("Config file not readable: ", err)
			return nil
		}
		defer file.Close()
		configInput = file
	}
	config, err := core.LoadConfig(configInput)
	if err != nil {
		log.Error("Failed to read config file (", configFile, "): ", configFile, err)
		return nil
	}

	vPoint, err := core.NewPoint(config)
	if err != nil {
		log.Error("Failed to create Point server: ", err)
		return nil
	}

	if *test {
		fmt.Println("Configuration OK.")
		return nil
	}

	err = vPoint.Start()
	if err != nil {
		log.Error("Error starting Point server: ", err)
		return nil
	}

	return vPoint
}

func main() {
	flag.Parse()

	core.PrintVersion()

	if *version {
		return
	}

	if point := startV2Ray(); point != nil {
		osSignals := make(chan os.Signal, 1)
		signal.Notify(osSignals, os.Interrupt, os.Kill, syscall.SIGTERM)

		<-osSignals
		point.Close()
	}
	log.Close()
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"flag"
	"fmt"
	"github.com/lifeforms/urlcheck/urlcheck"
	"io/ioutil"
	"os"
)

func parseArgs() (manifestfile string, server string, timeout uint, verbose bool) {
	flagi := flag.String("i", "manifest.yaml", "Input file with YAML manifest")
	flags := flag.String("s", "", "Only check this server, default check all servers in manifest")
	flagt := flag.Uint("t", 5, "Timeout for each HTTP request in seconds, 0 for no timeout")
	flagv := flag.Bool("v", false, "Verbose, prints the result of each test")
	flag.Parse()

	manifestfile = *flagi
	server = *flags
	timeout = *flagt
	verbose = *flagv
	return
}

func readManifest(manifestfile string) (manifest urlcheck.Manifest, err error) {
	y, err := ioutil.ReadFile(manifestfile)
	if err == nil {
		manifest, err = urlcheck.FromYAML(y)
	}
	return
}

func filterManifest(in urlcheck.Manifest, server string) (out urlcheck.Manifest, err error) {
	if server == "" {
		return in, nil
	}

	for _, s := range in {
		if s.Name == server {
			out = append(out, s)
		}
	}
	if len(out) == 0 {
		return nil, errors.New("Server not in manifest: " + server)
	}
	return
}

func main() {
	manifestfile, server, timeout, verbose := parseArgs()

	urlcheck.RequestTimeout = timeout
	urlcheck.Verbose = verbose
	manifest, err := readManifest(manifestfile)

	if err == nil {
		manifest, err = filterManifest(manifest, server)
	}

	if err == nil {
		err = manifest.Test()
	}

	if err != nil {
		fmt.Println("Failures:")
		fmt.Println(err)
		os.Exit(1)
	} else {
		if verbose {
			fmt.Println("OK")
		}
	}
}
<commit_msg>main: parse ServerTimeout<commit_after>package main

import (
	"errors"
	"flag"
	"fmt"
	"github.com/lifeforms/urlcheck/urlcheck"
	"io/ioutil"
	"os"
)

func parseArgs() (manifestfile string, server string, rt uint, st uint, verbose bool) {
	flagi := flag.String("i", "manifest.yaml", "Input file with YAML manifest")
	flags := flag.String("s", "", "Only check this server, default check all servers in manifest")
	flagr := flag.Uint("r", 5, "Timeout for each HTTP request in seconds, 0 for no timeout")
	flagt := flag.Uint("t", 120, "Timeout for each server in seconds, 0 for no timeout")
	flagv := flag.Bool("v", false, "Verbose, prints the result of each test")
	flag.Parse()

	manifestfile = *flagi
	server = *flags
	rt = *flagr
	st = *flagt
	verbose = *flagv
	return
}

func readManifest(manifestfile string) (manifest urlcheck.Manifest, err error) {
	y, err := ioutil.ReadFile(manifestfile)
	if err == nil {
		manifest, err = urlcheck.FromYAML(y)
	}
	return
}

func filterManifest(in urlcheck.Manifest, server string) (out urlcheck.Manifest, err error) {
	if server == "" {
		return in, nil
	}

	for _, s := range in {
		if s.Name == server {
			out = append(out, s)
		}
	}
	if len(out) == 0 {
		return nil, errors.New("Server not in manifest: " + server)
	}
	return
}

func main() {
	manifestfile, server, rt, st, verbose := parseArgs()

	urlcheck.RequestTimeout = rt
	urlcheck.ServerTimeout = st
	urlcheck.Verbose = verbose
	manifest, err := readManifest(manifestfile)

	if err == nil {
		manifest, err = filterManifest(manifest, server)
	}

	if err == nil {
		err = manifest.Test()
	}

	if err != nil {
		fmt.Println("Failures:")
		fmt.Println(err)
		os.Exit(1)
	} else {
		if verbose {
			fmt.Println("OK")
		}
	}
}
<|endoftext|>