<commit_before>// Copyright 2019 Google LLC
//
// 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
//
// 		https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"
)

// Each case must be positive when the rule in test
// is enabled. It must also contain a "disable-me-here"
// comment at the place where you want the rule to be
// disabled.
var testCases = []struct {
	testName, rule, proto string
}{
	{
		testName: "GetRequestMessage",
		rule:     "core::0131::request-message-name",
		proto: `
		syntax = "proto3";

		service Library {
			// disable-me-here
			rpc GetBook(Book) returns (Book);
		}

		message Book {}
		`,
	},
	{
		testName: "PackageVersion",
		rule:     "core::0215::versioned-packages",
		proto: `
		syntax = "proto3";

		// disable-me-here
		package google.test;

		message Test {}
		`,
	},
	{
		testName: "FieldNames",
		rule:     "core::0140::lower-snake",
		proto: `
				syntax = "proto3";
				import "dummy.proto";
				message Test {
					// disable-me-here
					string badName = 1;
					dummy.Dummy dummy = 2;
				}
			`,
	},
}

func TestRules_EnabledByDefault(t *testing.T) {
	for _, test := range testCases {
		t.Run(test.testName, func(t *testing.T) {
			proto := test.proto
			result := runLinter(t, proto, "")
			if !strings.Contains(result, test.rule) {
				t.Errorf("Rule %q should be enabled by default", test.rule)
			}
		})
	}
}

func TestRules_DisabledByFileComments(t *testing.T) {
	for _, test := range testCases {
		t.Run(test.testName, func(t *testing.T) {
			disableInFile := fmt.Sprintf("// (-- api-linter: %s=disabled --)", test.rule)
			proto := disableInFile + "\n" + test.proto
			result := runLinter(t, proto, "")
			if strings.Contains(result, test.rule) {
				t.Errorf("Rule %q should be disabled by file comments", test.rule)
			}
		})
	}
}

func TestRules_DisabledByInlineComments(t *testing.T) {
	for _, test := range testCases {
		t.Run(test.testName, func(t *testing.T) {
			disableInline := fmt.Sprintf("(-- api-linter: %s=disabled --)", test.rule)
			proto := strings.Replace(test.proto, "disable-me-here", disableInline, -1)
			result := runLinter(t, proto, "")
			if strings.Contains(result, test.rule) {
				t.Errorf("Rule %q should be disabled by in-line comments", test.rule)
			}
		})
	}
}

func TestRules_DisabledByConfig(t *testing.T) {
	config := `
	[
		{
			"disabled_rules": ["replace-me-here"]
		}
	]
	`

	for _, test := range testCases {
		t.Run(test.testName, func(t *testing.T) {
			c := strings.Replace(config, "replace-me-here", test.rule, -1)
			result := runLinter(t, test.proto, c)
			if strings.Contains(result, test.rule) {
				t.Errorf("Rule %q should be disabled by the user config: %q", test.rule, c)
			}
		})
	}
}

func TestBuildErrors(t *testing.T) {
	expected := `internal/testdata/build_errors.proto:8:1: syntax error: unexpected '}', expecting ';' or '['
internal/testdata/build_errors.proto:13:1: syntax error: unexpected '}', expecting ';' or '['`
	err := runCLI([]string{"internal/testdata/build_errors.proto"})
	if err == nil {
		t.Fatal("expected build error for build_errors.proto")
	}
	actual := err.Error()
	if expected != actual {
		t.Fatalf("expected %q, got %q", expected, actual)
	}
}

func TestExitStatusForLintFailure(t *testing.T) {
	type testCase struct{ testName, rule, proto string }
	failCase := testCase{
		testName: "GetRequestMessage",
		rule:     "core::0131::request-message-name",
		proto: `
		syntax = "proto3";

		service Library {
			// disable-me-here
			rpc GetBook(Book) returns (Book);
		}

		message Book {}
		`,
	}
	// checks lint failure = true when lint problems found
	t.Run(failCase.testName+"ReturnsFailure", func(t *testing.T) {
		lintFailureStatus, result := runLinterWithFailureStatus(t, failCase.proto, "", []string{"--set-exit-status"})
		if lintFailureStatus == false {
			t.Log(result)
			t.Fatalf("Expected: %v Actual: %v", true, lintFailureStatus)
		}
	})

	// checks lint failure = false when no problems found
	t.Run(failCase.testName+"ReturnsNoFailure", func(t *testing.T) {
		disableAll := `[ { "disabled_rules": [ "core" ] } ]`
		lintFailureStatus, result := runLinterWithFailureStatus(t, failCase.proto, disableAll, []string{"--set-exit-status"})
		if lintFailureStatus {
			t.Log(result)
		}
		if lintFailureStatus == true {
			t.Fatalf("Expected: %v Actual: %v", false, lintFailureStatus)
		}
	})

	// checks lint failure = false when lint problems found but --set-exit-status not set
	for _, test := range testCases {
		t.Run(test.testName, func(t *testing.T) {
			proto := test.proto
			lintFailureStatus, result := runLinterWithFailureStatus(t, proto, "", []string{})
			expected := result == ""
			if lintFailureStatus != expected {
				t.Fatalf("Expected: %v Actual: %v", expected, lintFailureStatus)
			}
		})
	}
}

func runLinter(t *testing.T, protoContent, configContent string) string {
	_, result := runLinterWithFailureStatus(t, protoContent, configContent, []string{})
	return result
}

func runLinterWithFailureStatus(t *testing.T, protoContent, configContent string, appendArgs []string) (bool, string) {
	tempDir, err := ioutil.TempDir("", "test")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tempDir)

	// Prepare command line flags.
	args := []string{}
	// Add a flag for the linter config file if the provided
	// config content is not empty.
	if configContent != "" {
		configFileName := "test_config.json"
		configFilePath := filepath.Join(tempDir, configFileName)
		if err := writeFile(configFilePath, configContent); err != nil {
			t.Fatal(err)
		}
		args = append(args, fmt.Sprintf("--config=%s", configFilePath))
	}
	// Add a flag for the output path.
	outPath := filepath.Join(tempDir, "test.out")
	args = append(args, fmt.Sprintf("-o=%s", outPath))
	// Add the temp dir to the proto paths.
	args = append(args, fmt.Sprintf("-I=%s", tempDir))
	// Add a flag for the file descriptor set.
	args = append(args, "--descriptor-set-in=internal/testdata/dummy.protoset")
	// Write the proto file.
	protoFileName := "test.proto"
	protoFilePath := filepath.Join(tempDir, protoFileName)
	if err := writeFile(protoFilePath, protoContent); err != nil {
		t.Fatal(err)
	}
	args = append(args, protoFileName)
	args = append(args, appendArgs...)

	lintErr := runCLI(args)
	if lintErr != nil && !errors.Is(lintErr, ExitForLintFailure) {
		t.Fatal(lintErr)
	}

	out, err := ioutil.ReadFile(outPath)
	if err != nil {
		t.Fatal(err)
	}
	return errors.Is(lintErr, ExitForLintFailure), string(out)
}

func writeFile(path, content string) error {
	if path == "" {
		return nil
	}
	err := os.MkdirAll(filepath.Dir(path), os.ModePerm)
	if err != nil {
		return err
	}
	return ioutil.WriteFile(path, []byte(content), 0644)
}
<commit_msg>fix: disable all rules instead of only core in test (#899)<commit_after>// Copyright 2019 Google LLC
//
// 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
//
// 		https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"
)

// Each case must be positive when the rule in test
// is enabled. It must also contain a "disable-me-here"
// comment at the place where you want the rule to be
// disabled.
var testCases = []struct {
	testName, rule, proto string
}{
	{
		testName: "GetRequestMessage",
		rule:     "core::0131::request-message-name",
		proto: `
		syntax = "proto3";

		service Library {
			// disable-me-here
			rpc GetBook(Book) returns (Book);
		}

		message Book {}
		`,
	},
	{
		testName: "PackageVersion",
		rule:     "core::0215::versioned-packages",
		proto: `
		syntax = "proto3";

		// disable-me-here
		package google.test;

		message Test {}
		`,
	},
	{
		testName: "FieldNames",
		rule:     "core::0140::lower-snake",
		proto: `
				syntax = "proto3";
				import "dummy.proto";
				message Test {
					// disable-me-here
					string badName = 1;
					dummy.Dummy dummy = 2;
				}
			`,
	},
}

func TestRules_EnabledByDefault(t *testing.T) {
	for _, test := range testCases {
		t.Run(test.testName, func(t *testing.T) {
			proto := test.proto
			result := runLinter(t, proto, "")
			if !strings.Contains(result, test.rule) {
				t.Errorf("Rule %q should be enabled by default", test.rule)
			}
		})
	}
}

func TestRules_DisabledByFileComments(t *testing.T) {
	for _, test := range testCases {
		t.Run(test.testName, func(t *testing.T) {
			disableInFile := fmt.Sprintf("// (-- api-linter: %s=disabled --)", test.rule)
			proto := disableInFile + "\n" + test.proto
			result := runLinter(t, proto, "")
			if strings.Contains(result, test.rule) {
				t.Errorf("Rule %q should be disabled by file comments", test.rule)
			}
		})
	}
}

func TestRules_DisabledByInlineComments(t *testing.T) {
	for _, test := range testCases {
		t.Run(test.testName, func(t *testing.T) {
			disableInline := fmt.Sprintf("(-- api-linter: %s=disabled --)", test.rule)
			proto := strings.Replace(test.proto, "disable-me-here", disableInline, -1)
			result := runLinter(t, proto, "")
			if strings.Contains(result, test.rule) {
				t.Errorf("Rule %q should be disabled by in-line comments", test.rule)
			}
		})
	}
}

func TestRules_DisabledByConfig(t *testing.T) {
	config := `
	[
		{
			"disabled_rules": ["replace-me-here"]
		}
	]
	`

	for _, test := range testCases {
		t.Run(test.testName, func(t *testing.T) {
			c := strings.Replace(config, "replace-me-here", test.rule, -1)
			result := runLinter(t, test.proto, c)
			if strings.Contains(result, test.rule) {
				t.Errorf("Rule %q should be disabled by the user config: %q", test.rule, c)
			}
		})
	}
}

func TestBuildErrors(t *testing.T) {
	expected := `internal/testdata/build_errors.proto:8:1: syntax error: unexpected '}', expecting ';' or '['
internal/testdata/build_errors.proto:13:1: syntax error: unexpected '}', expecting ';' or '['`
	err := runCLI([]string{"internal/testdata/build_errors.proto"})
	if err == nil {
		t.Fatal("expected build error for build_errors.proto")
	}
	actual := err.Error()
	if expected != actual {
		t.Fatalf("expected %q, got %q", expected, actual)
	}
}

func TestExitStatusForLintFailure(t *testing.T) {
	type testCase struct{ testName, rule, proto string }
	failCase := testCase{
		testName: "GetRequestMessage",
		rule:     "core::0131::request-message-name",
		proto: `
		syntax = "proto3";

		service Library {
			// disable-me-here
			rpc GetBook(Book) returns (Book);
		}

		message Book {}
		`,
	}
	// checks lint failure = true when lint problems found
	t.Run(failCase.testName+"ReturnsFailure", func(t *testing.T) {
		lintFailureStatus, result := runLinterWithFailureStatus(t, failCase.proto, "", []string{"--set-exit-status"})
		if lintFailureStatus == false {
			t.Log(result)
			t.Fatalf("Expected: %v Actual: %v", true, lintFailureStatus)
		}
	})

	// checks lint failure = false when no problems found
	t.Run(failCase.testName+"ReturnsNoFailure", func(t *testing.T) {
		disableAll := `[ { "disabled_rules": [ "all" ] } ]`
		lintFailureStatus, result := runLinterWithFailureStatus(t, failCase.proto, disableAll, []string{"--set-exit-status"})
		if lintFailureStatus {
			t.Log(result)
		}
		if lintFailureStatus == true {
			t.Fatalf("Expected: %v Actual: %v", false, lintFailureStatus)
		}
	})

	// checks lint failure = false when lint problems found but --set-exit-status not set
	for _, test := range testCases {
		t.Run(test.testName, func(t *testing.T) {
			proto := test.proto
			lintFailureStatus, result := runLinterWithFailureStatus(t, proto, "", []string{})
			expected := result == ""
			if lintFailureStatus != expected {
				t.Fatalf("Expected: %v Actual: %v", expected, lintFailureStatus)
			}
		})
	}
}

func runLinter(t *testing.T, protoContent, configContent string) string {
	_, result := runLinterWithFailureStatus(t, protoContent, configContent, []string{})
	return result
}

func runLinterWithFailureStatus(t *testing.T, protoContent, configContent string, appendArgs []string) (bool, string) {
	tempDir, err := ioutil.TempDir("", "test")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tempDir)

	// Prepare command line flags.
	args := []string{}
	// Add a flag for the linter config file if the provided
	// config content is not empty.
	if configContent != "" {
		configFileName := "test_config.json"
		configFilePath := filepath.Join(tempDir, configFileName)
		if err := writeFile(configFilePath, configContent); err != nil {
			t.Fatal(err)
		}
		args = append(args, fmt.Sprintf("--config=%s", configFilePath))
	}
	// Add a flag for the output path.
	outPath := filepath.Join(tempDir, "test.out")
	args = append(args, fmt.Sprintf("-o=%s", outPath))
	// Add the temp dir to the proto paths.
	args = append(args, fmt.Sprintf("-I=%s", tempDir))
	// Add a flag for the file descriptor set.
	args = append(args, "--descriptor-set-in=internal/testdata/dummy.protoset")
	// Write the proto file.
	protoFileName := "test.proto"
	protoFilePath := filepath.Join(tempDir, protoFileName)
	if err := writeFile(protoFilePath, protoContent); err != nil {
		t.Fatal(err)
	}
	args = append(args, protoFileName)
	args = append(args, appendArgs...)

	lintErr := runCLI(args)
	if lintErr != nil && !errors.Is(lintErr, ExitForLintFailure) {
		t.Fatal(lintErr)
	}

	out, err := ioutil.ReadFile(outPath)
	if err != nil {
		t.Fatal(err)
	}
	return errors.Is(lintErr, ExitForLintFailure), string(out)
}

func writeFile(path, content string) error {
	if path == "" {
		return nil
	}
	err := os.MkdirAll(filepath.Dir(path), os.ModePerm)
	if err != nil {
		return err
	}
	return ioutil.WriteFile(path, []byte(content), 0644)
}
<|endoftext|>


<commit_before>package v1alpha1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

type Image struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`
	Holder            string `json:"holder,omitempty"`
}
<commit_msg>Update image types<commit_after>package v1alpha1

import (
	"github.com/rancher/wrangler/pkg/condition"
	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var (
	ImageImported condition.Cond = "imported"
)

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

type Image struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   ImageSpec   `json:"spec"`
	Status ImageStatus `json:"status"`
}

type ImageSpec struct {
	DisplayName string `json:"displayName"`
	Description string `json:"description"`
	URL         string `json:"url"`
	SecretRef   string `json:"secretRef"`
}

type ImageStatus struct {
	AppliedURL  string      `json:"appliedUrl"`
	DownloadURL string      `json:"downloadUrl"`
	Progress    int         `json:"progress"`
	Conditions  []Condition `json:"conditions"`
}

type Condition struct {
	// Type of the condition.
	Type condition.Cond `json:"type"`
	// Status of the condition, one of True, False, Unknown.
	Status v1.ConditionStatus `json:"status"`
	// The last time this condition was updated.
	LastUpdateTime string `json:"lastUpdateTime,omitempty"`
	// Last time the condition transitioned from one status to another.
	LastTransitionTime string `json:"lastTransitionTime,omitempty"`
	// The reason for the condition's last transition.
	Reason string `json:"reason,omitempty"`
	// Human-readable message indicating details about last transition
	Message string `json:"message,omitempty"`
}
<|endoftext|>


<commit_before>package colors

import (
	"fmt"
)

const (
	// Attributes
	ATTR_RESET     = 0
	ATTR_BRIGHT    = 1
	ATTR_DIM       = 2
	ATTR_UNDERLINE = 3
	ATTR_BLINK     = 5
	ATTR_REVERSE   = 7

	// Foreground
	FG_BLACK   = 30
	FG_RED     = 31
	FG_GREEN   = 32
	FG_YELLOW  = 33
	FG_BLUE    = 34
	FG_MAGENTA = 35
	FG_CYAN    = 36
	FG_WHITE   = 37
	FG_DEFAULT = 39

	// Background
	BG_BLACK   = 40
	BG_RED     = 41
	BG_GREEN   = 42
	BG_YELLOW  = 43
	BG_BLUE    = 44
	BG_MAGENTA = 45
	BG_CYAN    = 46
	BG_WHITE   = 47
	BG_DEFAULT = 49
)

var (
	Default = Color{ATTR_RESET, FG_DEFAULT, BG_DEFAULT}
	Black   = Color{ATTR_RESET, FG_BLACK, BG_DEFAULT}
	Red     = Color{ATTR_RESET, FG_RED, BG_DEFAULT}
	Green   = Color{ATTR_RESET, FG_GREEN, BG_DEFAULT}
	Yellow  = Color{ATTR_RESET, FG_YELLOW, BG_DEFAULT}
	Blue    = Color{ATTR_RESET, FG_BLUE, BG_DEFAULT}
	Magenta = Color{ATTR_RESET, FG_MAGENTA, BG_DEFAULT}
	Cyan    = Color{ATTR_RESET, FG_CYAN, BG_DEFAULT}
	White   = Color{ATTR_RESET, FG_WHITE, BG_DEFAULT}
)

type Color struct {
	attr, fg, bg uint8
}

func (x Color) Format(f fmt.State, c rune) {
	if c == 'C' || c == 'v' {
		str := fmt.Sprint("\033[", x.attr, ";", x.fg, ";", x.bg, "m")
		bytes := []byte(str)
		f.Write(bytes)
	} else {
		f.Write([]byte(fmt.Sprint("#!C(colors.Color)")))
	}
}

func (x Color) Print(a ...interface{}) (n int, err error) {
	fmt.Print(x)
	n, err = fmt.Print(a...)
	fmt.Print(Default)
	return
}

func (x Color) Println(a ...interface{}) (n int, err error) {
	fmt.Print(x)
	n, err = fmt.Println(a...)
	fmt.Print(Default)
	return
}

func (x Color) Printf(format string, a ...interface{}) (n int, err error) {
	fmt.Print(x)
	n, err = fmt.Printf(format, a...)
	fmt.Print(Default)
	return
}

func Cprint(a ...interface{}) (n int, err error) {
	n, err = fmt.Print(a...)
	fmt.Print(Default)
	return
}

func Cprintf(format string, a ...interface{}) (n int, err error) {
	n, err = fmt.Printf(format, a...)
	fmt.Print(Default)
	return
}
<commit_msg>Use new color syntax<commit_after>package colors

import (
	"bytes"
	"fmt"
	"log"
)

const escapeCode = '@'

const resetCode = "@0"

var codeMap = map[int]int{
	'0': 0,
	'!': 1,
	'.': 2,
	'_': 3,
	'?': 5,
	'/': 7,
	'-': 8,

	'r': 31,
	'g': 32,
	'y': 33,
	'b': 34,
	'm': 35,
	'c': 36,
	'w': 37,
	'd': 39,

	'R': 41,
	'G': 42,
	'Y': 43,
	'B': 44,
	'M': 45,
	'C': 46,
	'W': 47,
	'D': 49,
}

func colorMap(x string) string {
	attr := 0
	fg := 39
	bg := 49

	for _, key := range x {
		c, ok := codeMap[key]
		switch {
		case !ok:
			log.Fatalf("Wrong color syntax: %c", key)
		case 0 <= c && c <= 8:
			attr = c
		case 30 <= c && c <= 37:
			fg = c
		case 40 <= c && c <= 47:
			bg = c
		}
	}
	return fmt.Sprintf("\033[%d;%d;%dm", attr, fg, bg)
}

func compileColorSyntax(input, output *bytes.Buffer) {
	i, _, err := input.ReadRune()
	if err != nil {
		// EOF got
		log.Fatal("Parse failed on color syntax")
	}

	switch i {
	default:
		output.WriteString(colorMap(string(i)))
	case '{':
		color := bytes.NewBufferString("")
		for {
			i, _, err := input.ReadRune()
			if err != nil {
				log.Fatal("Parse failed on color syntax")
			}
			if i == '}' {
				break
			}
			color.WriteRune(i)
		}
		output.WriteString(colorMap(color.String()))
	case escapeCode:
		output.WriteRune(escapeCode)
	}
}

func compile(x string) string {
	if x == "" {
		return ""
	}

	input := bytes.NewBufferString(x)
	output := bytes.NewBufferString("")

	for {
		i, _, err := input.ReadRune()
		if err != nil {
			break
		}
		switch i {
		default:
			output.WriteRune(i)
		case escapeCode:
			compileColorSyntax(input, output)
		}
	}
	return output.String()
}

func compileValues(a *[]interface{}) {
	for i, x := range *a {
                if str, ok := x.(string); ok {
			(*a)[i] = compile(str)
                }
	}
}

func Print(a ...interface{}) (int, error) {
	a = append(a, resetCode)
	compileValues(&a)
	return fmt.Print(a...)
}

func Println(a ...interface{}) (int, error) {
	a = append(a, resetCode)
	compileValues(&a)
	return fmt.Println(a...)
}

func Printf(format string, a ...interface{}) (int, error) {
	format += resetCode
	format = compile(format)
	return fmt.Printf(format, a...)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"

	log "github.com/Sirupsen/logrus"
)

var cmdCommit = &Command{
	Exec:        runCommit,
	UsageLine:   "commit [OPTIONS] SERVER [NAME]",
	Description: "Create a new snapshot from a server's volume",
	Help:        "Create a new snapshot from a server's volume.",
}

func runCommit(cmd *Command, args []string) {
	if len(args) == 0 {
		log.Fatalf("usage: scw %s", cmd.UsageLine)
	}

	serverId := cmd.GetServer(args[0])
	server, err := cmd.API.GetServer(serverId)
	if err != nil {
		log.Fatalf("Cannot fetch server: %v", err)
	}
	var volume ScalewayVolume = server.Volumes["0"]
	var name string
	if len(args) > 1 {
		name = args[1]
	} else {
		name = volume.Name + "-snapshot"
	}
	snapshot, err := cmd.API.PostSnapshot(volume.Identifier, name)
	if err != nil {
		log.Fatalf("Cannot create snapshot: %v", err)
	}
	fmt.Println(snapshot)
}
<commit_msg>Added 'commit --volume' option<commit_after>package main

import (
	"fmt"

	log "github.com/Sirupsen/logrus"
)

var cmdCommit = &Command{
	Exec:        runCommit,
	UsageLine:   "commit [OPTIONS] SERVER [NAME]",
	Description: "Create a new snapshot from a server's volume",
	Help:        "Create a new snapshot from a server's volume.",
}

func init() {
	// FIXME: -h
	cmdCommit.Flag.IntVar(&commitVolume, []string{"v", "-volume"}, 0, "Volume slot")
}

// Flags
var commitVolume int

func runCommit(cmd *Command, args []string) {
	if len(args) == 0 {
		log.Fatalf("usage: scw %s", cmd.UsageLine)
	}

	serverId := cmd.GetServer(args[0])
	server, err := cmd.API.GetServer(serverId)
	if err != nil {
		log.Fatalf("Cannot fetch server: %v", err)
	}
	var volume ScalewayVolume = server.Volumes[fmt.Sprintf("%d", commitVolume)]
	var name string
	if len(args) > 1 {
		name = args[1]
	} else {
		name = volume.Name + "-snapshot"
	}
	snapshot, err := cmd.API.PostSnapshot(volume.Identifier, name)
	if err != nil {
		log.Fatalf("Cannot create snapshot: %v", err)
	}
	fmt.Println(snapshot)
}
<|endoftext|>


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

/*
This module implements osbrick plugin for OpenSDS. It will pass these
operation requests about connector to OpenStack osbrick module.

*/

package connector

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"time"

	"openstack/golang-client/volume"

	"github.com/astaxie/beego/httplib"
)

const (
	URL_PREFIX = "http://localhost:7879"
)

type Connector struct {
	ConnInfo volume.ConnectionInfo `json:"connection_info"`
}

type InitializeRequest struct {
	Multipath bool `json:"multipath"`
}

func GetConnectorProperties(isMultipath bool) (*volume.ConnectorProperties, error) {
	url := URL_PREFIX + "Volume/Initialize"

	initReq := &InitializeRequest{
		Multipath: isMultipath,
	}

	log.Printf("Start POST request to initialize volume, url = %s, body = %+v\n",
		url, initReq)

	req := httplib.Post(url).SetTimeout(100*time.Second, 50*time.Second)
	req.JSONBody(initReq)

	resp, err := req.Response()
	if err != nil {
		return nil, err
	}

	err = CheckHTTPResponseStatusCode(resp)
	if err != nil {
		return nil, err
	}

	rbody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	var prop = &volume.ConnectorProperties{}
	err = json.Unmarshal(rbody, prop)
	if err != nil {
		log.Println("The format of response is not supported, resp:", string(rbody))
		return nil, err
	}

	prop.DoLocalAttach = true
	return prop, nil
}

func (conn *Connector) ConnectVolume() (string, error) {
	url := URL_PREFIX + "Volume/Connect"

	log.Printf("Start POST request to connect volume, url = %s, body = %+v\n",
		url, conn)

	req := httplib.Post(url).SetTimeout(100*time.Second, 50*time.Second)
	req.JSONBody(conn)

	resp, err := req.Response()
	if err != nil {
		return "", err
	}

	err = CheckHTTPResponseStatusCode(resp)
	if err != nil {
		return "", err
	}

	rbody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	return string(rbody), nil
}

func (conn *Connector) DisconnectVolume() (string, error) {
	url := URL_PREFIX + "Volume/Disconnect"

	log.Printf("Start POST request to disconnect volume, url = %s, body = %+v\n",
		url, conn)

	req := httplib.Post(url).SetTimeout(100*time.Second, 50*time.Second)
	req.JSONBody(conn)

	resp, err := req.Response()
	if err != nil {
		return "", err
	}

	err = CheckHTTPResponseStatusCode(resp)
	if err != nil {
		return "", err
	}

	rbody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

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

/*
This module implements osbrick plugin for OpenSDS. It will pass these
operation requests about connector to OpenStack osbrick module.

*/

package connector

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"time"

	"openstack/golang-client/volume"

	"github.com/astaxie/beego/httplib"
)

const (
	URL_PREFIX = "http://localhost:7879"
)

type Connector struct {
	ConnInfo volume.ConnectionInfo `json:"connection_info"`
}

type InitializeRequest struct {
	Multipath bool `json:"multipath"`
}

func GetConnectorProperties(isMultipath bool) (*volume.ConnectorProperties, error) {
	url := URL_PREFIX + "/Volume/Initialize"

	initReq := &InitializeRequest{
		Multipath: isMultipath,
	}

	log.Printf("Start POST request to initialize volume, url = %s, body = %+v\n",
		url, initReq)

	req := httplib.Post(url).SetTimeout(100*time.Second, 50*time.Second)
	req.JSONBody(initReq)

	resp, err := req.Response()
	if err != nil {
		return nil, err
	}

	err = CheckHTTPResponseStatusCode(resp)
	if err != nil {
		return nil, err
	}

	rbody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	var prop = &volume.ConnectorProperties{}
	err = json.Unmarshal(rbody, prop)
	if err != nil {
		log.Println("The format of response is not supported, resp:", string(rbody))
		return nil, err
	}

	prop.DoLocalAttach = true
	return prop, nil
}

func (conn *Connector) ConnectVolume() (string, error) {
	url := URL_PREFIX + "/Volume/Connect"

	log.Printf("Start POST request to connect volume, url = %s, body = %+v\n",
		url, conn)

	req := httplib.Post(url).SetTimeout(100*time.Second, 50*time.Second)
	req.JSONBody(conn)

	resp, err := req.Response()
	if err != nil {
		return "", err
	}

	err = CheckHTTPResponseStatusCode(resp)
	if err != nil {
		return "", err
	}

	rbody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	return string(rbody), nil
}

func (conn *Connector) DisconnectVolume() (string, error) {
	url := URL_PREFIX + "/Volume/Disconnect"

	log.Printf("Start POST request to disconnect volume, url = %s, body = %+v\n",
		url, conn)

	req := httplib.Post(url).SetTimeout(100*time.Second, 50*time.Second)
	req.JSONBody(conn)

	resp, err := req.Response()
	if err != nil {
		return "", err
	}

	err = CheckHTTPResponseStatusCode(resp)
	if err != nil {
		return "", err
	}

	rbody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	return string(rbody), nil
}
<|endoftext|>


<commit_before>/*
Package lint implements Vale's syntax-aware linting functionality.

The package is split into core linting logic (this file), source code
(code.go), and markup (markup.go). The general flow is as follows:

    Lint (files and directories)     LintString (stdin)
				\                   /
                 lintFiles         /
                         \        /
	                      +      +
	+-------------------+ lintFile ------+|lintMarkdown|lintADoc|lintRST
	|                    /    |   \       |            |       /
	|					/     |    \      |           /       /
    |				   /      |     \     |          +--------
    |				  /       |      \    |         /
    |                +        +       +	  +        +
	|	          lintCode  lintLines     lintHTML
	|			    |         |              |
    |               |         |              +
    |        		 \        |         lintProse
    |                 \       |        /
	|				   +      +       +
	| 					   lintText
    |   <= add Alerts{}       |
    +-------------------------+
*/
package lint

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"sync"

	"github.com/ValeLint/vale/check"
	"github.com/ValeLint/vale/core"
)

// A Linter lints a File.
type Linter struct{}

// A Block represents a section of text.
type Block struct {
	Context string        // parent content (if any) - e.g., sentence -> paragraph
	Text    string        // text content
	Scope   core.Selector // section selector
}

// NewBlock makes a new Block with prepared text and a Selector.
func NewBlock(ctx string, txt string, sel string) Block {
	if ctx == "" {
		ctx = txt
	}
	return Block{Context: ctx, Text: txt, Scope: core.Selector{Value: sel}}
}

// LintString src according to its format.
func (l Linter) LintString(src string) ([]*core.File, error) {
	return []*core.File{l.lintFile(src)}, nil
}

// Lint src according to its format.
func (l Linter) Lint(src string, pat string) ([]*core.File, error) {
	var linted []*core.File

	done := make(chan core.File)
	defer close(done)

	filesChan, errc := l.lintFiles(done, src, core.NewGlob(pat))
	for f := range filesChan {
		linted = append(linted, f)
	}
	if err := <-errc; err != nil {
		return nil, err
	}

	if core.CLConfig.Sorted {
		sort.Sort(core.ByName(linted))
	}
	return linted, nil
}

// lintFiles walks the `root` directory, creating a new goroutine to lint any
// file that matches the given glob pattern.
func (l Linter) lintFiles(done <-chan core.File, root string, glob core.Glob) (<-chan *core.File, <-chan error) {
	filesChan := make(chan *core.File)
	errc := make(chan error, 1)
	go func() {
		var wg sync.WaitGroup
		err := filepath.Walk(root, func(fp string, fi os.FileInfo, err error) error {
			if err != nil || fi.IsDir() {
				return nil
			} else if !glob.Match(fp) {
				return nil
			}
			wg.Add(1)
			go func() {
				select {
				case filesChan <- l.lintFile(fp):
				case <-done:
				}
				wg.Done()
			}()
			// Abort the walk if done is closed.
			select {
			case <-done:
				return errors.New("walk canceled")
			default:
				return nil
			}
		})
		// Walk has returned, so all calls to wg.Add are done.  Start a
		// goroutine to close c once all the sends are done.
		go func() {
			wg.Wait()
			close(filesChan)
		}()
		errc <- err
	}()
	return filesChan, errc
}

func (l Linter) lintFile(src string) *core.File {
	file := core.NewFile(src)
	if file.Format == "markup" && !core.CLConfig.Simple {
		switch file.NormedExt {
		case ".adoc":
			cmd := core.Which([]string{"asciidoctor"})
			if cmd != "" {
				l.lintADoc(file, cmd)
			} else {
				fmt.Println("asciidoctor not found!")
			}
		case ".md":
			l.lintMarkdown(file)
		case ".rst":
			cmd := core.Which([]string{"rst2html", "rst2html.py"})
			runtime := core.Which([]string{"python", "py", "python.exe"})
			if cmd != "" && runtime != "" {
				l.lintRST(file, runtime, cmd)
			} else {
				fmt.Println(fmt.Sprintf("can't run rst2html: (%s, %s)!", runtime, cmd))
			}
		case ".html":
			l.lintHTML(file)
		}
	} else if file.Format == "code" && !core.CLConfig.Simple {
		l.lintCode(file)
	} else {
		l.lintLines(file)
	}
	return file
}

func (l Linter) lintProse(f *core.File, ctx string, txt string, lnTotal int, lnLength int) {
	var b Block
	text := core.PrepText(txt)
	senScope := "sentence" + f.RealExt
	parScope := "paragraph" + f.RealExt
	txtScope := "text" + f.RealExt
	hasCtx := ctx != ""
	for _, p := range strings.SplitAfter(text, "\n\n") {
		for _, s := range core.SentenceTokenizer.Tokenize(p) {
			if hasCtx {
				b = NewBlock(ctx, s.Text, senScope)
			} else {
				b = NewBlock(p, s.Text, senScope)
			}
			l.lintText(f, b, lnTotal, lnLength)
		}
		l.lintText(f, NewBlock(ctx, p, parScope), lnTotal, lnLength)
	}
	l.lintText(f, NewBlock(ctx, text, txtScope), lnTotal, lnLength)
}

func (l Linter) lintLines(f *core.File) {
	var line string
	lines := 1
	for f.Scanner.Scan() {
		line = core.PrepText(f.Scanner.Text() + "\n")
		l.lintText(f, NewBlock("", line, "text"+f.RealExt), lines+1, 0)
		lines++
	}
}

func (l Linter) lintText(f *core.File, blk Block, lines int, pad int) {
	var style string
	var run bool

	ctx := blk.Context
	txt := core.PrepText(blk.Text)
	min := core.Config.MinAlertLevel
	f.ChkToCtx = make(map[string]string)
	for name, chk := range check.AllChecks {
		style = strings.Split(name, ".")[0]
		run = false

		// It has been disabled via an in-text comment.
		if f.QueryComments(name) {
			continue
		}

		if chk.Level < min || !blk.Scope.Contains(chk.Scope) {
			continue
		}

		// Has the check been disabled for this extension?
		if val, ok := f.Checks[name]; ok && !run {
			if !val {
				continue
			}
			run = true
		}

		// Has the check been disabled for all extensions?
		if val, ok := core.Config.GChecks[name]; ok && !run {
			if !val {
				continue
			}
			run = true
		}

		if !run && !core.StringInSlice(style, f.BaseStyles) {
			continue
		}

		for _, a := range chk.Rule(txt, f) {
			f.AddAlert(a, ctx, txt, lines, pad)
		}
	}
}
<commit_msg>refactor: tabs -> spaces<commit_after>/*
Package lint implements Vale's syntax-aware linting functionality.

The package is split into core linting logic (this file), source code
(code.go), and markup (markup.go). The general flow is as follows:

    Lint (files and directories)     LintString (stdin)
                \                   /
                 lintFiles         /
                         \        /
                          +      +
    +-------------------+ lintFile ------+|lintMarkdown|lintADoc|lintRST
    |                    /    |   \       |            |       /
    |                   /     |    \      |           /       /
    |                  /      |     \     |          +--------
    |                 /       |      \    |         /
    |                +        +       +	  +        +
    |               lintCode  lintLines     lintHTML
    |               |         |              |
    |               |         |              +
    |                \        |         lintProse
    |                 \       |        /
    |                  +      +       +
    |                      lintText
    |   <= add Alerts{}       |
    +-------------------------+
*/
package lint

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"sync"

	"github.com/ValeLint/vale/check"
	"github.com/ValeLint/vale/core"
)

// A Linter lints a File.
type Linter struct{}

// A Block represents a section of text.
type Block struct {
	Context string        // parent content (if any) - e.g., sentence -> paragraph
	Text    string        // text content
	Scope   core.Selector // section selector
}

// NewBlock makes a new Block with prepared text and a Selector.
func NewBlock(ctx string, txt string, sel string) Block {
	if ctx == "" {
		ctx = txt
	}
	return Block{Context: ctx, Text: txt, Scope: core.Selector{Value: sel}}
}

// LintString src according to its format.
func (l Linter) LintString(src string) ([]*core.File, error) {
	return []*core.File{l.lintFile(src)}, nil
}

// Lint src according to its format.
func (l Linter) Lint(src string, pat string) ([]*core.File, error) {
	var linted []*core.File

	done := make(chan core.File)
	defer close(done)

	filesChan, errc := l.lintFiles(done, src, core.NewGlob(pat))
	for f := range filesChan {
		linted = append(linted, f)
	}
	if err := <-errc; err != nil {
		return nil, err
	}

	if core.CLConfig.Sorted {
		sort.Sort(core.ByName(linted))
	}
	return linted, nil
}

// lintFiles walks the `root` directory, creating a new goroutine to lint any
// file that matches the given glob pattern.
func (l Linter) lintFiles(done <-chan core.File, root string, glob core.Glob) (<-chan *core.File, <-chan error) {
	filesChan := make(chan *core.File)
	errc := make(chan error, 1)
	go func() {
		var wg sync.WaitGroup
		err := filepath.Walk(root, func(fp string, fi os.FileInfo, err error) error {
			if err != nil || fi.IsDir() {
				return nil
			} else if !glob.Match(fp) {
				return nil
			}
			wg.Add(1)
			go func() {
				select {
				case filesChan <- l.lintFile(fp):
				case <-done:
				}
				wg.Done()
			}()
			// Abort the walk if done is closed.
			select {
			case <-done:
				return errors.New("walk canceled")
			default:
				return nil
			}
		})
		// Walk has returned, so all calls to wg.Add are done.  Start a
		// goroutine to close c once all the sends are done.
		go func() {
			wg.Wait()
			close(filesChan)
		}()
		errc <- err
	}()
	return filesChan, errc
}

func (l Linter) lintFile(src string) *core.File {
	file := core.NewFile(src)
	if file.Format == "markup" && !core.CLConfig.Simple {
		switch file.NormedExt {
		case ".adoc":
			cmd := core.Which([]string{"asciidoctor"})
			if cmd != "" {
				l.lintADoc(file, cmd)
			} else {
				fmt.Println("asciidoctor not found!")
			}
		case ".md":
			l.lintMarkdown(file)
		case ".rst":
			cmd := core.Which([]string{"rst2html", "rst2html.py"})
			runtime := core.Which([]string{"python", "py", "python.exe"})
			if cmd != "" && runtime != "" {
				l.lintRST(file, runtime, cmd)
			} else {
				fmt.Println(fmt.Sprintf("can't run rst2html: (%s, %s)!", runtime, cmd))
			}
		case ".html":
			l.lintHTML(file)
		}
	} else if file.Format == "code" && !core.CLConfig.Simple {
		l.lintCode(file)
	} else {
		l.lintLines(file)
	}
	return file
}

func (l Linter) lintProse(f *core.File, ctx string, txt string, lnTotal int, lnLength int) {
	var b Block
	text := core.PrepText(txt)
	senScope := "sentence" + f.RealExt
	parScope := "paragraph" + f.RealExt
	txtScope := "text" + f.RealExt
	hasCtx := ctx != ""
	for _, p := range strings.SplitAfter(text, "\n\n") {
		for _, s := range core.SentenceTokenizer.Tokenize(p) {
			if hasCtx {
				b = NewBlock(ctx, s.Text, senScope)
			} else {
				b = NewBlock(p, s.Text, senScope)
			}
			l.lintText(f, b, lnTotal, lnLength)
		}
		l.lintText(f, NewBlock(ctx, p, parScope), lnTotal, lnLength)
	}
	l.lintText(f, NewBlock(ctx, text, txtScope), lnTotal, lnLength)
}

func (l Linter) lintLines(f *core.File) {
	var line string
	lines := 1
	for f.Scanner.Scan() {
		line = core.PrepText(f.Scanner.Text() + "\n")
		l.lintText(f, NewBlock("", line, "text"+f.RealExt), lines+1, 0)
		lines++
	}
}

func (l Linter) lintText(f *core.File, blk Block, lines int, pad int) {
	var style string
	var run bool

	ctx := blk.Context
	txt := core.PrepText(blk.Text)
	min := core.Config.MinAlertLevel
	f.ChkToCtx = make(map[string]string)
	for name, chk := range check.AllChecks {
		style = strings.Split(name, ".")[0]
		run = false

		// It has been disabled via an in-text comment.
		if f.QueryComments(name) {
			continue
		}

		if chk.Level < min || !blk.Scope.Contains(chk.Scope) {
			continue
		}

		// Has the check been disabled for this extension?
		if val, ok := f.Checks[name]; ok && !run {
			if !val {
				continue
			}
			run = true
		}

		// Has the check been disabled for all extensions?
		if val, ok := core.Config.GChecks[name]; ok && !run {
			if !val {
				continue
			}
			run = true
		}

		if !run && !core.StringInSlice(style, f.BaseStyles) {
			continue
		}

		for _, a := range chk.Rule(txt, f) {
			f.AddAlert(a, ctx, txt, lines, pad)
		}
	}
}
<|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 openstackmodel

import (
	"fmt"
	"strings"

	"k8s.io/klog"
	"k8s.io/kops/pkg/apis/kops"
	"k8s.io/kops/pkg/dns"
	"k8s.io/kops/pkg/model"
	"k8s.io/kops/upup/pkg/fi"
	"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
	"k8s.io/kops/upup/pkg/fi/cloudup/openstacktasks"
	"k8s.io/kops/upup/pkg/fi/fitasks"
)

// ServerGroupModelBuilder configures server group objects
type ServerGroupModelBuilder struct {
	*OpenstackModelContext
	BootstrapScript *model.BootstrapScript
	Lifecycle       *fi.Lifecycle
}

var _ fi.ModelBuilder = &ServerGroupModelBuilder{}

func (b *ServerGroupModelBuilder) buildInstances(c *fi.ModelBuilderContext, sg *openstacktasks.ServerGroup, ig *kops.InstanceGroup) error {

	sshKeyNameFull, err := b.SSHKeyName()
	if err != nil {
		return err
	}

	sshKeyName := strings.Replace(sshKeyNameFull, ":", "_", -1)

	clusterTag := "KubernetesCluster:" + strings.Replace(b.ClusterName(), ".", "-", -1)

	var igUserData *string
	igMeta := make(map[string]string)

	if ig.Spec.Role != kops.InstanceGroupRoleBastion {
		// Bastion does not belong to the cluster and will not be running protokube.

		igMeta[openstack.TagClusterName] = b.ClusterName()
	}
	igMeta["k8s"] = b.ClusterName()
	igMeta["KopsInstanceGroup"] = ig.Name
	igMeta[openstack.INSTANCE_GROUP_GENERATION] = fmt.Sprintf("%d", ig.GetGeneration())
	igMeta[openstack.CLUSTER_GENERATION] = fmt.Sprintf("%d", b.Cluster.GetGeneration())

	startupScript, err := b.BootstrapScript.ResourceNodeUp(ig, b.Cluster)
	if err != nil {
		return fmt.Errorf("Could not create startup script for instance group %s: %v", ig.Name, err)
	}
	if startupScript != nil {
		// var userData bytes.Buffer
		startupStr, err := startupScript.AsString()
		if err != nil {
			return fmt.Errorf("Could not create startup script for instance group %s: %v", ig.Name, err)
		}
		igUserData = fi.String(startupStr)
	}

	var securityGroups []*openstacktasks.SecurityGroup
	securityGroupName := b.SecurityGroupName(ig.Spec.Role)
	securityGroups = append(securityGroups, b.LinkToSecurityGroup(securityGroupName))

	if b.Cluster.Spec.CloudConfig.Openstack.Loadbalancer == nil {
		securityGroups = append(securityGroups, b.LinkToSecurityGroup(b.Cluster.Spec.MasterPublicName))
	}

	// In the future, OpenStack will use Machine API to manage groups,
	// for now create d.InstanceGroups.Spec.MinSize amount of servers
	for i := int32(0); i < *ig.Spec.MinSize; i++ {
		if err != nil {
			return fmt.Errorf("Failed to create UUID for instance: %v", err)
		}
		// FIXME: Must ensure 63 or less characters
		// replace all dots with -, this is needed to get external cloudprovider working
		iName := strings.ToLower(fmt.Sprintf("%s-%d.%s", ig.Name, i+1, b.ClusterName()))
		instanceName := fi.String(strings.Replace(iName, ".", "-", -1))

		var az *string
		if len(ig.Spec.Subnets) > 0 {
			// bastion subnet name is not actual zone name, it contains "utility-" prefix
			if ig.Spec.Role == kops.InstanceGroupRoleBastion {
				az = fi.String(strings.Replace(ig.Spec.Subnets[int(i)%len(ig.Spec.Subnets)], "utility-", "", 1))
			} else {
				az = fi.String(ig.Spec.Subnets[int(i)%len(ig.Spec.Subnets)])
			}
		}
		// Create instance port task
		portTask := &openstacktasks.Port{
			Name:           fi.String(fmt.Sprintf("%s-%s", "port", *instanceName)),
			Network:        b.LinkToNetwork(),
			SecurityGroups: securityGroups,
			Lifecycle:      b.Lifecycle,
		}
		c.AddTask(portTask)

		instanceTask := &openstacktasks.Instance{
			Name:             instanceName,
			Region:           fi.String(b.Cluster.Spec.Subnets[0].Region),
			Flavor:           fi.String(ig.Spec.MachineType),
			Image:            fi.String(ig.Spec.Image),
			SSHKey:           fi.String(sshKeyName),
			ServerGroup:      sg,
			Tags:             []string{clusterTag},
			Role:             fi.String(string(ig.Spec.Role)),
			Port:             portTask,
			Metadata:         igMeta,
			AvailabilityZone: az,
		}
		if igUserData != nil {
			instanceTask.UserData = igUserData
		}
		c.AddTask(instanceTask)

		// Associate a floating IP to the master and bastion always, associate it to a node if bastion is not used
		switch ig.Spec.Role {
		case kops.InstanceGroupRoleBastion:
			t := &openstacktasks.FloatingIP{
				Name:      fi.String(fmt.Sprintf("%s-%s", "fip", *instanceTask.Name)),
				Server:    instanceTask,
				Lifecycle: b.Lifecycle,
			}
			c.AddTask(t)
		case kops.InstanceGroupRoleMaster:
			if b.Cluster.Spec.CloudConfig.Openstack.Loadbalancer == nil {
				t := &openstacktasks.FloatingIP{
					Name:      fi.String(fmt.Sprintf("%s-%s", "fip", *instanceTask.Name)),
					Server:    instanceTask,
					Lifecycle: b.Lifecycle,
				}
				c.AddTask(t)
				b.associateFIPToKeypair(c, t)
			}
		default:
			if !b.UsesSSHBastion() {
				t := &openstacktasks.FloatingIP{
					Name:      fi.String(fmt.Sprintf("%s-%s", "fip", *instanceTask.Name)),
					Server:    instanceTask,
					Lifecycle: b.Lifecycle,
				}
				c.AddTask(t)
			}
		}
	}

	return nil
}

func (b *ServerGroupModelBuilder) associateFIPToKeypair(c *fi.ModelBuilderContext, fipTask *openstacktasks.FloatingIP) error {
	// Ensure the floating IP is included in the TLS certificate,
	// if we're not going to use an alias for it
	// TODO: I don't love this technique for finding the task by name & modifying it
	masterKeypairTask, found := c.Tasks["Keypair/master"]
	if !found {
		return fmt.Errorf("keypair/master task not found")
	}
	masterKeypair := masterKeypairTask.(*fitasks.Keypair)
	masterKeypair.AlternateNameTasks = append(masterKeypair.AlternateNameTasks, fipTask)
	return nil
}

func (b *ServerGroupModelBuilder) Build(c *fi.ModelBuilderContext) error {
	clusterName := b.ClusterName()

	var masters []*openstacktasks.ServerGroup
	for _, ig := range b.InstanceGroups {
		klog.V(2).Infof("Found instance group with name %s and role %v.", ig.Name, ig.Spec.Role)
		sgTask := &openstacktasks.ServerGroup{
			Name:        s(fmt.Sprintf("%s-%s", clusterName, ig.Name)),
			ClusterName: s(clusterName),
			IGName:      s(ig.Name),
			Policies:    []string{"anti-affinity"},
			Lifecycle:   b.Lifecycle,
			MaxSize:     ig.Spec.MaxSize,
		}
		c.AddTask(sgTask)

		err := b.buildInstances(c, sgTask, ig)
		if err != nil {
			return err
		}

		if ig.Spec.Role == kops.InstanceGroupRoleMaster {
			masters = append(masters, sgTask)
		}
	}

	if b.Cluster.Spec.CloudConfig.Openstack.Loadbalancer != nil {
		lbSubnetName := b.MasterInstanceGroups()[0].Spec.Subnets[0]
		lbTask := &openstacktasks.LB{
			Name:          fi.String(b.Cluster.Spec.MasterPublicName),
			Subnet:        fi.String(lbSubnetName + "." + b.ClusterName()),
			Lifecycle:     b.Lifecycle,
			SecurityGroup: b.LinkToSecurityGroup(b.Cluster.Spec.MasterPublicName),
		}
		c.AddTask(lbTask)

		lbfipTask := &openstacktasks.FloatingIP{
			Name:      fi.String(fmt.Sprintf("%s-%s", "fip", *lbTask.Name)),
			LB:        lbTask,
			Lifecycle: b.Lifecycle,
		}
		c.AddTask(lbfipTask)

		if dns.IsGossipHostname(b.Cluster.Name) || b.UsePrivateDNS() {
			b.associateFIPToKeypair(c, lbfipTask)
		}

		poolTask := &openstacktasks.LBPool{
			Name:         fi.String(fmt.Sprintf("%s-https", fi.StringValue(lbTask.Name))),
			Loadbalancer: lbTask,
			Lifecycle:    b.Lifecycle,
		}
		c.AddTask(poolTask)

		listenerTask := &openstacktasks.LBListener{
			Name:      lbTask.Name,
			Lifecycle: b.Lifecycle,
			Pool:      poolTask,
		}
		c.AddTask(listenerTask)

		for _, mastersg := range masters {
			associateTask := &openstacktasks.PoolAssociation{
				Name:          mastersg.Name,
				Pool:          poolTask,
				ServerGroup:   mastersg,
				InterfaceName: fi.String(clusterName),
				ProtocolPort:  fi.Int(443),
				Lifecycle:     b.Lifecycle,
			}

			c.AddTask(associateTask)
		}

	}

	return nil
}
<commit_msg>add api sg group only to masters<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 openstackmodel

import (
	"fmt"
	"strings"

	"k8s.io/klog"
	"k8s.io/kops/pkg/apis/kops"
	"k8s.io/kops/pkg/dns"
	"k8s.io/kops/pkg/model"
	"k8s.io/kops/upup/pkg/fi"
	"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
	"k8s.io/kops/upup/pkg/fi/cloudup/openstacktasks"
	"k8s.io/kops/upup/pkg/fi/fitasks"
)

// ServerGroupModelBuilder configures server group objects
type ServerGroupModelBuilder struct {
	*OpenstackModelContext
	BootstrapScript *model.BootstrapScript
	Lifecycle       *fi.Lifecycle
}

var _ fi.ModelBuilder = &ServerGroupModelBuilder{}

func (b *ServerGroupModelBuilder) buildInstances(c *fi.ModelBuilderContext, sg *openstacktasks.ServerGroup, ig *kops.InstanceGroup) error {

	sshKeyNameFull, err := b.SSHKeyName()
	if err != nil {
		return err
	}

	sshKeyName := strings.Replace(sshKeyNameFull, ":", "_", -1)

	clusterTag := "KubernetesCluster:" + strings.Replace(b.ClusterName(), ".", "-", -1)

	var igUserData *string
	igMeta := make(map[string]string)

	if ig.Spec.Role != kops.InstanceGroupRoleBastion {
		// Bastion does not belong to the cluster and will not be running protokube.

		igMeta[openstack.TagClusterName] = b.ClusterName()
	}
	igMeta["k8s"] = b.ClusterName()
	igMeta["KopsInstanceGroup"] = ig.Name
	igMeta[openstack.INSTANCE_GROUP_GENERATION] = fmt.Sprintf("%d", ig.GetGeneration())
	igMeta[openstack.CLUSTER_GENERATION] = fmt.Sprintf("%d", b.Cluster.GetGeneration())

	startupScript, err := b.BootstrapScript.ResourceNodeUp(ig, b.Cluster)
	if err != nil {
		return fmt.Errorf("Could not create startup script for instance group %s: %v", ig.Name, err)
	}
	if startupScript != nil {
		// var userData bytes.Buffer
		startupStr, err := startupScript.AsString()
		if err != nil {
			return fmt.Errorf("Could not create startup script for instance group %s: %v", ig.Name, err)
		}
		igUserData = fi.String(startupStr)
	}

	var securityGroups []*openstacktasks.SecurityGroup
	securityGroupName := b.SecurityGroupName(ig.Spec.Role)
	securityGroups = append(securityGroups, b.LinkToSecurityGroup(securityGroupName))

	if b.Cluster.Spec.CloudConfig.Openstack.Loadbalancer == nil && ig.Spec.Role == kops.InstanceGroupRoleMaster {
		securityGroups = append(securityGroups, b.LinkToSecurityGroup(b.Cluster.Spec.MasterPublicName))
	}

	// In the future, OpenStack will use Machine API to manage groups,
	// for now create d.InstanceGroups.Spec.MinSize amount of servers
	for i := int32(0); i < *ig.Spec.MinSize; i++ {
		if err != nil {
			return fmt.Errorf("Failed to create UUID for instance: %v", err)
		}
		// FIXME: Must ensure 63 or less characters
		// replace all dots with -, this is needed to get external cloudprovider working
		iName := strings.ToLower(fmt.Sprintf("%s-%d.%s", ig.Name, i+1, b.ClusterName()))
		instanceName := fi.String(strings.Replace(iName, ".", "-", -1))

		var az *string
		if len(ig.Spec.Subnets) > 0 {
			// bastion subnet name is not actual zone name, it contains "utility-" prefix
			if ig.Spec.Role == kops.InstanceGroupRoleBastion {
				az = fi.String(strings.Replace(ig.Spec.Subnets[int(i)%len(ig.Spec.Subnets)], "utility-", "", 1))
			} else {
				az = fi.String(ig.Spec.Subnets[int(i)%len(ig.Spec.Subnets)])
			}
		}
		// Create instance port task
		portTask := &openstacktasks.Port{
			Name:           fi.String(fmt.Sprintf("%s-%s", "port", *instanceName)),
			Network:        b.LinkToNetwork(),
			SecurityGroups: securityGroups,
			Lifecycle:      b.Lifecycle,
		}
		c.AddTask(portTask)

		instanceTask := &openstacktasks.Instance{
			Name:             instanceName,
			Region:           fi.String(b.Cluster.Spec.Subnets[0].Region),
			Flavor:           fi.String(ig.Spec.MachineType),
			Image:            fi.String(ig.Spec.Image),
			SSHKey:           fi.String(sshKeyName),
			ServerGroup:      sg,
			Tags:             []string{clusterTag},
			Role:             fi.String(string(ig.Spec.Role)),
			Port:             portTask,
			Metadata:         igMeta,
			AvailabilityZone: az,
		}
		if igUserData != nil {
			instanceTask.UserData = igUserData
		}
		c.AddTask(instanceTask)

		// Associate a floating IP to the master and bastion always, associate it to a node if bastion is not used
		switch ig.Spec.Role {
		case kops.InstanceGroupRoleBastion:
			t := &openstacktasks.FloatingIP{
				Name:      fi.String(fmt.Sprintf("%s-%s", "fip", *instanceTask.Name)),
				Server:    instanceTask,
				Lifecycle: b.Lifecycle,
			}
			c.AddTask(t)
		case kops.InstanceGroupRoleMaster:
			if b.Cluster.Spec.CloudConfig.Openstack.Loadbalancer == nil {
				t := &openstacktasks.FloatingIP{
					Name:      fi.String(fmt.Sprintf("%s-%s", "fip", *instanceTask.Name)),
					Server:    instanceTask,
					Lifecycle: b.Lifecycle,
				}
				c.AddTask(t)
				b.associateFIPToKeypair(c, t)
			}
		default:
			if !b.UsesSSHBastion() {
				t := &openstacktasks.FloatingIP{
					Name:      fi.String(fmt.Sprintf("%s-%s", "fip", *instanceTask.Name)),
					Server:    instanceTask,
					Lifecycle: b.Lifecycle,
				}
				c.AddTask(t)
			}
		}
	}

	return nil
}

func (b *ServerGroupModelBuilder) associateFIPToKeypair(c *fi.ModelBuilderContext, fipTask *openstacktasks.FloatingIP) error {
	// Ensure the floating IP is included in the TLS certificate,
	// if we're not going to use an alias for it
	// TODO: I don't love this technique for finding the task by name & modifying it
	masterKeypairTask, found := c.Tasks["Keypair/master"]
	if !found {
		return fmt.Errorf("keypair/master task not found")
	}
	masterKeypair := masterKeypairTask.(*fitasks.Keypair)
	masterKeypair.AlternateNameTasks = append(masterKeypair.AlternateNameTasks, fipTask)
	return nil
}

func (b *ServerGroupModelBuilder) Build(c *fi.ModelBuilderContext) error {
	clusterName := b.ClusterName()

	var masters []*openstacktasks.ServerGroup
	for _, ig := range b.InstanceGroups {
		klog.V(2).Infof("Found instance group with name %s and role %v.", ig.Name, ig.Spec.Role)
		sgTask := &openstacktasks.ServerGroup{
			Name:        s(fmt.Sprintf("%s-%s", clusterName, ig.Name)),
			ClusterName: s(clusterName),
			IGName:      s(ig.Name),
			Policies:    []string{"anti-affinity"},
			Lifecycle:   b.Lifecycle,
			MaxSize:     ig.Spec.MaxSize,
		}
		c.AddTask(sgTask)

		err := b.buildInstances(c, sgTask, ig)
		if err != nil {
			return err
		}

		if ig.Spec.Role == kops.InstanceGroupRoleMaster {
			masters = append(masters, sgTask)
		}
	}

	if b.Cluster.Spec.CloudConfig.Openstack.Loadbalancer != nil {
		lbSubnetName := b.MasterInstanceGroups()[0].Spec.Subnets[0]
		lbTask := &openstacktasks.LB{
			Name:          fi.String(b.Cluster.Spec.MasterPublicName),
			Subnet:        fi.String(lbSubnetName + "." + b.ClusterName()),
			Lifecycle:     b.Lifecycle,
			SecurityGroup: b.LinkToSecurityGroup(b.Cluster.Spec.MasterPublicName),
		}
		c.AddTask(lbTask)

		lbfipTask := &openstacktasks.FloatingIP{
			Name:      fi.String(fmt.Sprintf("%s-%s", "fip", *lbTask.Name)),
			LB:        lbTask,
			Lifecycle: b.Lifecycle,
		}
		c.AddTask(lbfipTask)

		if dns.IsGossipHostname(b.Cluster.Name) || b.UsePrivateDNS() {
			b.associateFIPToKeypair(c, lbfipTask)
		}

		poolTask := &openstacktasks.LBPool{
			Name:         fi.String(fmt.Sprintf("%s-https", fi.StringValue(lbTask.Name))),
			Loadbalancer: lbTask,
			Lifecycle:    b.Lifecycle,
		}
		c.AddTask(poolTask)

		listenerTask := &openstacktasks.LBListener{
			Name:      lbTask.Name,
			Lifecycle: b.Lifecycle,
			Pool:      poolTask,
		}
		c.AddTask(listenerTask)

		for _, mastersg := range masters {
			associateTask := &openstacktasks.PoolAssociation{
				Name:          mastersg.Name,
				Pool:          poolTask,
				ServerGroup:   mastersg,
				InterfaceName: fi.String(clusterName),
				ProtocolPort:  fi.Int(443),
				Lifecycle:     b.Lifecycle,
			}

			c.AddTask(associateTask)
		}

	}

	return nil
}
<|endoftext|>


<commit_before>package libcontainer

import (
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"runtime/debug"
	"strconv"

	securejoin "github.com/cyphar/filepath-securejoin"
	"github.com/moby/sys/mountinfo"
	"golang.org/x/sys/unix"

	"github.com/opencontainers/runc/libcontainer/cgroups/manager"
	"github.com/opencontainers/runc/libcontainer/configs"
	"github.com/opencontainers/runc/libcontainer/configs/validate"
	"github.com/opencontainers/runc/libcontainer/intelrdt"
	"github.com/opencontainers/runc/libcontainer/utils"
	"github.com/sirupsen/logrus"
)

const (
	stateFilename    = "state.json"
	execFifoFilename = "exec.fifo"
)

var idRegex = regexp.MustCompile(`^[\w+-\.]+$`)

// InitArgs returns an options func to configure a LinuxFactory with the
// provided init binary path and arguments.
func InitArgs(args ...string) func(*LinuxFactory) error {
	return func(l *LinuxFactory) (err error) {
		if len(args) > 0 {
			// Resolve relative paths to ensure that its available
			// after directory changes.
			if args[0], err = filepath.Abs(args[0]); err != nil {
				// The only error returned from filepath.Abs is
				// the one from os.Getwd, i.e. a system error.
				return err
			}
		}

		l.InitArgs = args
		return nil
	}
}

// IntelRdtfs is an options func to configure a LinuxFactory to return
// containers that use the Intel RDT "resource control" filesystem to
// create and manage Intel RDT resources (e.g., L3 cache, memory bandwidth).
func IntelRdtFs(l *LinuxFactory) error {
	if !intelrdt.IsCATEnabled() && !intelrdt.IsMBAEnabled() {
		l.NewIntelRdtManager = nil
	} else {
		l.NewIntelRdtManager = func(config *configs.Config, id string, path string) intelrdt.Manager {
			return intelrdt.NewManager(config, id, path)
		}
	}
	return nil
}

// TmpfsRoot is an option func to mount LinuxFactory.Root to tmpfs.
func TmpfsRoot(l *LinuxFactory) error {
	mounted, err := mountinfo.Mounted(l.Root)
	if err != nil {
		return err
	}
	if !mounted {
		if err := mount("tmpfs", l.Root, "", "tmpfs", 0, ""); err != nil {
			return err
		}
	}
	return nil
}

// CriuPath returns an option func to configure a LinuxFactory with the
// provided criupath
func CriuPath(criupath string) func(*LinuxFactory) error {
	return func(l *LinuxFactory) error {
		l.CriuPath = criupath
		return nil
	}
}

// New returns a linux based container factory based in the root directory and
// configures the factory with the provided option funcs.
func New(root string, options ...func(*LinuxFactory) error) (Factory, error) {
	if root != "" {
		if err := os.MkdirAll(root, 0o700); err != nil {
			return nil, err
		}
	}
	l := &LinuxFactory{
		Root:      root,
		InitPath:  "/proc/self/exe",
		InitArgs:  []string{os.Args[0], "init"},
		Validator: validate.New(),
		CriuPath:  "criu",
	}

	for _, opt := range options {
		if opt == nil {
			continue
		}
		if err := opt(l); err != nil {
			return nil, err
		}
	}
	return l, nil
}

// LinuxFactory implements the default factory interface for linux based systems.
type LinuxFactory struct {
	// Root directory for the factory to store state.
	Root string

	// InitPath is the path for calling the init responsibilities for spawning
	// a container.
	InitPath string

	// InitArgs are arguments for calling the init responsibilities for spawning
	// a container.
	InitArgs []string

	// CriuPath is the path to the criu binary used for checkpoint and restore of
	// containers.
	CriuPath string

	// New{u,g}idmapPath is the path to the binaries used for mapping with
	// rootless containers.
	NewuidmapPath string
	NewgidmapPath string

	// Validator provides validation to container configurations.
	Validator validate.Validator

	// NewIntelRdtManager returns an initialized Intel RDT manager for a single container.
	NewIntelRdtManager func(config *configs.Config, id string, path string) intelrdt.Manager
}

func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, error) {
	if l.Root == "" {
		return nil, errors.New("root not set")
	}
	if err := l.validateID(id); err != nil {
		return nil, err
	}
	if err := l.Validator.Validate(config); err != nil {
		return nil, err
	}
	containerRoot, err := securejoin.SecureJoin(l.Root, id)
	if err != nil {
		return nil, err
	}
	if _, err := os.Stat(containerRoot); err == nil {
		return nil, ErrExist
	} else if !os.IsNotExist(err) {
		return nil, err
	}

	cm, err := manager.New(config.Cgroups)
	if err != nil {
		return nil, err
	}

	// Check that cgroup does not exist or empty (no processes).
	// Note for cgroup v1 this check is not thorough, as there are multiple
	// separate hierarchies, while both Exists() and GetAllPids() only use
	// one for "devices" controller (assuming others are the same, which is
	// probably true in almost all scenarios). Checking all the hierarchies
	// would be too expensive.
	if cm.Exists() {
		pids, err := cm.GetAllPids()
		// Reading PIDs can race with cgroups removal, so ignore ENOENT and ENODEV.
		if err != nil && !errors.Is(err, os.ErrNotExist) && !errors.Is(err, unix.ENODEV) {
			return nil, fmt.Errorf("unable to get cgroup PIDs: %w", err)
		}
		if len(pids) != 0 {
			// TODO: return an error.
			logrus.Warnf("container's cgroup is not empty: %d process(es) found", len(pids))
			logrus.Warn("DEPRECATED: running container in a non-empty cgroup won't be supported in runc 1.2; https://github.com/opencontainers/runc/issues/3132")
		}
	}

	// Check that cgroup is not frozen. Do not use Exists() here
	// since in cgroup v1 it only checks "devices" controller.
	st, err := cm.GetFreezerState()
	if err != nil {
		return nil, fmt.Errorf("unable to get cgroup freezer state: %w", err)
	}
	if st == configs.Frozen {
		return nil, errors.New("container's cgroup unexpectedly frozen")
	}

	if err := os.MkdirAll(containerRoot, 0o711); err != nil {
		return nil, err
	}
	if err := os.Chown(containerRoot, unix.Geteuid(), unix.Getegid()); err != nil {
		return nil, err
	}
	c := &linuxContainer{
		id:            id,
		root:          containerRoot,
		config:        config,
		initPath:      l.InitPath,
		initArgs:      l.InitArgs,
		criuPath:      l.CriuPath,
		newuidmapPath: l.NewuidmapPath,
		newgidmapPath: l.NewgidmapPath,
		cgroupManager: cm,
	}
	if l.NewIntelRdtManager != nil {
		c.intelRdtManager = l.NewIntelRdtManager(config, id, "")
	}
	c.state = &stoppedState{c: c}
	return c, nil
}

func (l *LinuxFactory) Load(id string) (Container, error) {
	if l.Root == "" {
		return nil, errors.New("root not set")
	}
	// when load, we need to check id is valid or not.
	if err := l.validateID(id); err != nil {
		return nil, err
	}
	containerRoot, err := securejoin.SecureJoin(l.Root, id)
	if err != nil {
		return nil, err
	}
	state, err := l.loadState(containerRoot)
	if err != nil {
		return nil, err
	}
	r := &nonChildProcess{
		processPid:       state.InitProcessPid,
		processStartTime: state.InitProcessStartTime,
		fds:              state.ExternalDescriptors,
	}
	cm, err := manager.NewWithPaths(state.Config.Cgroups, state.CgroupPaths)
	if err != nil {
		return nil, err
	}
	c := &linuxContainer{
		initProcess:          r,
		initProcessStartTime: state.InitProcessStartTime,
		id:                   id,
		config:               &state.Config,
		initPath:             l.InitPath,
		initArgs:             l.InitArgs,
		criuPath:             l.CriuPath,
		newuidmapPath:        l.NewuidmapPath,
		newgidmapPath:        l.NewgidmapPath,
		cgroupManager:        cm,
		root:                 containerRoot,
		created:              state.Created,
	}
	if l.NewIntelRdtManager != nil {
		c.intelRdtManager = l.NewIntelRdtManager(&state.Config, id, state.IntelRdtPath)
	}
	c.state = &loadedState{c: c}
	if err := c.refreshState(); err != nil {
		return nil, err
	}
	return c, nil
}

func (l *LinuxFactory) Type() string {
	return "libcontainer"
}

// StartInitialization loads a container by opening the pipe fd from the parent to read the configuration and state
// This is a low level implementation detail of the reexec and should not be consumed externally
func (l *LinuxFactory) StartInitialization() (err error) {
	// Get the INITPIPE.
	envInitPipe := os.Getenv("_LIBCONTAINER_INITPIPE")
	pipefd, err := strconv.Atoi(envInitPipe)
	if err != nil {
		err = fmt.Errorf("unable to convert _LIBCONTAINER_INITPIPE: %w", err)
		logrus.Error(err)
		return err
	}
	pipe := os.NewFile(uintptr(pipefd), "pipe")
	defer pipe.Close()

	defer func() {
		// We have an error during the initialization of the container's init,
		// send it back to the parent process in the form of an initError.
		if werr := writeSync(pipe, procError); werr != nil {
			fmt.Fprintln(os.Stderr, err)
			return
		}
		if werr := utils.WriteJSON(pipe, &initError{Message: err.Error()}); werr != nil {
			fmt.Fprintln(os.Stderr, err)
			return
		}
	}()

	// Only init processes have FIFOFD.
	fifofd := -1
	envInitType := os.Getenv("_LIBCONTAINER_INITTYPE")
	it := initType(envInitType)
	if it == initStandard {
		envFifoFd := os.Getenv("_LIBCONTAINER_FIFOFD")
		if fifofd, err = strconv.Atoi(envFifoFd); err != nil {
			return fmt.Errorf("unable to convert _LIBCONTAINER_FIFOFD: %w", err)
		}
	}

	var consoleSocket *os.File
	if envConsole := os.Getenv("_LIBCONTAINER_CONSOLE"); envConsole != "" {
		console, err := strconv.Atoi(envConsole)
		if err != nil {
			return fmt.Errorf("unable to convert _LIBCONTAINER_CONSOLE: %w", err)
		}
		consoleSocket = os.NewFile(uintptr(console), "console-socket")
		defer consoleSocket.Close()
	}

	logPipeFdStr := os.Getenv("_LIBCONTAINER_LOGPIPE")
	logPipeFd, err := strconv.Atoi(logPipeFdStr)
	if err != nil {
		return fmt.Errorf("unable to convert _LIBCONTAINER_LOGPIPE: %w", err)
	}

	// Get mount files (O_PATH).
	mountFds, err := parseMountFds()
	if err != nil {
		return err
	}

	// clear the current process's environment to clean any libcontainer
	// specific env vars.
	os.Clearenv()

	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("panic from initialization: %w, %v", e, string(debug.Stack()))
		}
	}()

	i, err := newContainerInit(it, pipe, consoleSocket, fifofd, logPipeFd, mountFds)
	if err != nil {
		return err
	}

	// If Init succeeds, syscall.Exec will not return, hence none of the defers will be called.
	return i.Init()
}

func (l *LinuxFactory) loadState(root string) (*State, error) {
	stateFilePath, err := securejoin.SecureJoin(root, stateFilename)
	if err != nil {
		return nil, err
	}
	f, err := os.Open(stateFilePath)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, ErrNotExist
		}
		return nil, err
	}
	defer f.Close()
	var state *State
	if err := json.NewDecoder(f).Decode(&state); err != nil {
		return nil, err
	}
	return state, nil
}

func (l *LinuxFactory) validateID(id string) error {
	if !idRegex.MatchString(id) || string(os.PathSeparator)+id != utils.CleanPath(string(os.PathSeparator)+id) {
		return ErrInvalidID
	}

	return nil
}

// NewuidmapPath returns an option func to configure a LinuxFactory with the
// provided ..
func NewuidmapPath(newuidmapPath string) func(*LinuxFactory) error {
	return func(l *LinuxFactory) error {
		l.NewuidmapPath = newuidmapPath
		return nil
	}
}

// NewgidmapPath returns an option func to configure a LinuxFactory with the
// provided ..
func NewgidmapPath(newgidmapPath string) func(*LinuxFactory) error {
	return func(l *LinuxFactory) error {
		l.NewgidmapPath = newgidmapPath
		return nil
	}
}

func parseMountFds() ([]int, error) {
	fdsJson := os.Getenv("_LIBCONTAINER_MOUNT_FDS")
	if fdsJson == "" {
		// Always return the nil slice if no fd is present.
		return nil, nil
	}

	var mountFds []int
	if err := json.Unmarshal([]byte(fdsJson), &mountFds); err != nil {
		return nil, fmt.Errorf("Error unmarshalling _LIBCONTAINER_MOUNT_FDS: %w", err)
	}

	return mountFds, nil
}
<commit_msg>libct: StartInitialization: fix %w related warning<commit_after>package libcontainer

import (
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"runtime/debug"
	"strconv"

	securejoin "github.com/cyphar/filepath-securejoin"
	"github.com/moby/sys/mountinfo"
	"golang.org/x/sys/unix"

	"github.com/opencontainers/runc/libcontainer/cgroups/manager"
	"github.com/opencontainers/runc/libcontainer/configs"
	"github.com/opencontainers/runc/libcontainer/configs/validate"
	"github.com/opencontainers/runc/libcontainer/intelrdt"
	"github.com/opencontainers/runc/libcontainer/utils"
	"github.com/sirupsen/logrus"
)

const (
	stateFilename    = "state.json"
	execFifoFilename = "exec.fifo"
)

var idRegex = regexp.MustCompile(`^[\w+-\.]+$`)

// InitArgs returns an options func to configure a LinuxFactory with the
// provided init binary path and arguments.
func InitArgs(args ...string) func(*LinuxFactory) error {
	return func(l *LinuxFactory) (err error) {
		if len(args) > 0 {
			// Resolve relative paths to ensure that its available
			// after directory changes.
			if args[0], err = filepath.Abs(args[0]); err != nil {
				// The only error returned from filepath.Abs is
				// the one from os.Getwd, i.e. a system error.
				return err
			}
		}

		l.InitArgs = args
		return nil
	}
}

// IntelRdtfs is an options func to configure a LinuxFactory to return
// containers that use the Intel RDT "resource control" filesystem to
// create and manage Intel RDT resources (e.g., L3 cache, memory bandwidth).
func IntelRdtFs(l *LinuxFactory) error {
	if !intelrdt.IsCATEnabled() && !intelrdt.IsMBAEnabled() {
		l.NewIntelRdtManager = nil
	} else {
		l.NewIntelRdtManager = func(config *configs.Config, id string, path string) intelrdt.Manager {
			return intelrdt.NewManager(config, id, path)
		}
	}
	return nil
}

// TmpfsRoot is an option func to mount LinuxFactory.Root to tmpfs.
func TmpfsRoot(l *LinuxFactory) error {
	mounted, err := mountinfo.Mounted(l.Root)
	if err != nil {
		return err
	}
	if !mounted {
		if err := mount("tmpfs", l.Root, "", "tmpfs", 0, ""); err != nil {
			return err
		}
	}
	return nil
}

// CriuPath returns an option func to configure a LinuxFactory with the
// provided criupath
func CriuPath(criupath string) func(*LinuxFactory) error {
	return func(l *LinuxFactory) error {
		l.CriuPath = criupath
		return nil
	}
}

// New returns a linux based container factory based in the root directory and
// configures the factory with the provided option funcs.
func New(root string, options ...func(*LinuxFactory) error) (Factory, error) {
	if root != "" {
		if err := os.MkdirAll(root, 0o700); err != nil {
			return nil, err
		}
	}
	l := &LinuxFactory{
		Root:      root,
		InitPath:  "/proc/self/exe",
		InitArgs:  []string{os.Args[0], "init"},
		Validator: validate.New(),
		CriuPath:  "criu",
	}

	for _, opt := range options {
		if opt == nil {
			continue
		}
		if err := opt(l); err != nil {
			return nil, err
		}
	}
	return l, nil
}

// LinuxFactory implements the default factory interface for linux based systems.
type LinuxFactory struct {
	// Root directory for the factory to store state.
	Root string

	// InitPath is the path for calling the init responsibilities for spawning
	// a container.
	InitPath string

	// InitArgs are arguments for calling the init responsibilities for spawning
	// a container.
	InitArgs []string

	// CriuPath is the path to the criu binary used for checkpoint and restore of
	// containers.
	CriuPath string

	// New{u,g}idmapPath is the path to the binaries used for mapping with
	// rootless containers.
	NewuidmapPath string
	NewgidmapPath string

	// Validator provides validation to container configurations.
	Validator validate.Validator

	// NewIntelRdtManager returns an initialized Intel RDT manager for a single container.
	NewIntelRdtManager func(config *configs.Config, id string, path string) intelrdt.Manager
}

func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, error) {
	if l.Root == "" {
		return nil, errors.New("root not set")
	}
	if err := l.validateID(id); err != nil {
		return nil, err
	}
	if err := l.Validator.Validate(config); err != nil {
		return nil, err
	}
	containerRoot, err := securejoin.SecureJoin(l.Root, id)
	if err != nil {
		return nil, err
	}
	if _, err := os.Stat(containerRoot); err == nil {
		return nil, ErrExist
	} else if !os.IsNotExist(err) {
		return nil, err
	}

	cm, err := manager.New(config.Cgroups)
	if err != nil {
		return nil, err
	}

	// Check that cgroup does not exist or empty (no processes).
	// Note for cgroup v1 this check is not thorough, as there are multiple
	// separate hierarchies, while both Exists() and GetAllPids() only use
	// one for "devices" controller (assuming others are the same, which is
	// probably true in almost all scenarios). Checking all the hierarchies
	// would be too expensive.
	if cm.Exists() {
		pids, err := cm.GetAllPids()
		// Reading PIDs can race with cgroups removal, so ignore ENOENT and ENODEV.
		if err != nil && !errors.Is(err, os.ErrNotExist) && !errors.Is(err, unix.ENODEV) {
			return nil, fmt.Errorf("unable to get cgroup PIDs: %w", err)
		}
		if len(pids) != 0 {
			// TODO: return an error.
			logrus.Warnf("container's cgroup is not empty: %d process(es) found", len(pids))
			logrus.Warn("DEPRECATED: running container in a non-empty cgroup won't be supported in runc 1.2; https://github.com/opencontainers/runc/issues/3132")
		}
	}

	// Check that cgroup is not frozen. Do not use Exists() here
	// since in cgroup v1 it only checks "devices" controller.
	st, err := cm.GetFreezerState()
	if err != nil {
		return nil, fmt.Errorf("unable to get cgroup freezer state: %w", err)
	}
	if st == configs.Frozen {
		return nil, errors.New("container's cgroup unexpectedly frozen")
	}

	if err := os.MkdirAll(containerRoot, 0o711); err != nil {
		return nil, err
	}
	if err := os.Chown(containerRoot, unix.Geteuid(), unix.Getegid()); err != nil {
		return nil, err
	}
	c := &linuxContainer{
		id:            id,
		root:          containerRoot,
		config:        config,
		initPath:      l.InitPath,
		initArgs:      l.InitArgs,
		criuPath:      l.CriuPath,
		newuidmapPath: l.NewuidmapPath,
		newgidmapPath: l.NewgidmapPath,
		cgroupManager: cm,
	}
	if l.NewIntelRdtManager != nil {
		c.intelRdtManager = l.NewIntelRdtManager(config, id, "")
	}
	c.state = &stoppedState{c: c}
	return c, nil
}

func (l *LinuxFactory) Load(id string) (Container, error) {
	if l.Root == "" {
		return nil, errors.New("root not set")
	}
	// when load, we need to check id is valid or not.
	if err := l.validateID(id); err != nil {
		return nil, err
	}
	containerRoot, err := securejoin.SecureJoin(l.Root, id)
	if err != nil {
		return nil, err
	}
	state, err := l.loadState(containerRoot)
	if err != nil {
		return nil, err
	}
	r := &nonChildProcess{
		processPid:       state.InitProcessPid,
		processStartTime: state.InitProcessStartTime,
		fds:              state.ExternalDescriptors,
	}
	cm, err := manager.NewWithPaths(state.Config.Cgroups, state.CgroupPaths)
	if err != nil {
		return nil, err
	}
	c := &linuxContainer{
		initProcess:          r,
		initProcessStartTime: state.InitProcessStartTime,
		id:                   id,
		config:               &state.Config,
		initPath:             l.InitPath,
		initArgs:             l.InitArgs,
		criuPath:             l.CriuPath,
		newuidmapPath:        l.NewuidmapPath,
		newgidmapPath:        l.NewgidmapPath,
		cgroupManager:        cm,
		root:                 containerRoot,
		created:              state.Created,
	}
	if l.NewIntelRdtManager != nil {
		c.intelRdtManager = l.NewIntelRdtManager(&state.Config, id, state.IntelRdtPath)
	}
	c.state = &loadedState{c: c}
	if err := c.refreshState(); err != nil {
		return nil, err
	}
	return c, nil
}

func (l *LinuxFactory) Type() string {
	return "libcontainer"
}

// StartInitialization loads a container by opening the pipe fd from the parent to read the configuration and state
// This is a low level implementation detail of the reexec and should not be consumed externally
func (l *LinuxFactory) StartInitialization() (err error) {
	// Get the INITPIPE.
	envInitPipe := os.Getenv("_LIBCONTAINER_INITPIPE")
	pipefd, err := strconv.Atoi(envInitPipe)
	if err != nil {
		err = fmt.Errorf("unable to convert _LIBCONTAINER_INITPIPE: %w", err)
		logrus.Error(err)
		return err
	}
	pipe := os.NewFile(uintptr(pipefd), "pipe")
	defer pipe.Close()

	defer func() {
		// We have an error during the initialization of the container's init,
		// send it back to the parent process in the form of an initError.
		if werr := writeSync(pipe, procError); werr != nil {
			fmt.Fprintln(os.Stderr, err)
			return
		}
		if werr := utils.WriteJSON(pipe, &initError{Message: err.Error()}); werr != nil {
			fmt.Fprintln(os.Stderr, err)
			return
		}
	}()

	// Only init processes have FIFOFD.
	fifofd := -1
	envInitType := os.Getenv("_LIBCONTAINER_INITTYPE")
	it := initType(envInitType)
	if it == initStandard {
		envFifoFd := os.Getenv("_LIBCONTAINER_FIFOFD")
		if fifofd, err = strconv.Atoi(envFifoFd); err != nil {
			return fmt.Errorf("unable to convert _LIBCONTAINER_FIFOFD: %w", err)
		}
	}

	var consoleSocket *os.File
	if envConsole := os.Getenv("_LIBCONTAINER_CONSOLE"); envConsole != "" {
		console, err := strconv.Atoi(envConsole)
		if err != nil {
			return fmt.Errorf("unable to convert _LIBCONTAINER_CONSOLE: %w", err)
		}
		consoleSocket = os.NewFile(uintptr(console), "console-socket")
		defer consoleSocket.Close()
	}

	logPipeFdStr := os.Getenv("_LIBCONTAINER_LOGPIPE")
	logPipeFd, err := strconv.Atoi(logPipeFdStr)
	if err != nil {
		return fmt.Errorf("unable to convert _LIBCONTAINER_LOGPIPE: %w", err)
	}

	// Get mount files (O_PATH).
	mountFds, err := parseMountFds()
	if err != nil {
		return err
	}

	// clear the current process's environment to clean any libcontainer
	// specific env vars.
	os.Clearenv()

	defer func() {
		if e := recover(); e != nil {
			if e, ok := e.(error); ok {
				err = fmt.Errorf("panic from initialization: %w, %s", e, debug.Stack())
			} else {
				//nolint:errorlint // here e is not of error type
				err = fmt.Errorf("panic from initialization: %v, %s", e, debug.Stack())
			}
		}
	}()

	i, err := newContainerInit(it, pipe, consoleSocket, fifofd, logPipeFd, mountFds)
	if err != nil {
		return err
	}

	// If Init succeeds, syscall.Exec will not return, hence none of the defers will be called.
	return i.Init()
}

func (l *LinuxFactory) loadState(root string) (*State, error) {
	stateFilePath, err := securejoin.SecureJoin(root, stateFilename)
	if err != nil {
		return nil, err
	}
	f, err := os.Open(stateFilePath)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, ErrNotExist
		}
		return nil, err
	}
	defer f.Close()
	var state *State
	if err := json.NewDecoder(f).Decode(&state); err != nil {
		return nil, err
	}
	return state, nil
}

func (l *LinuxFactory) validateID(id string) error {
	if !idRegex.MatchString(id) || string(os.PathSeparator)+id != utils.CleanPath(string(os.PathSeparator)+id) {
		return ErrInvalidID
	}

	return nil
}

// NewuidmapPath returns an option func to configure a LinuxFactory with the
// provided ..
func NewuidmapPath(newuidmapPath string) func(*LinuxFactory) error {
	return func(l *LinuxFactory) error {
		l.NewuidmapPath = newuidmapPath
		return nil
	}
}

// NewgidmapPath returns an option func to configure a LinuxFactory with the
// provided ..
func NewgidmapPath(newgidmapPath string) func(*LinuxFactory) error {
	return func(l *LinuxFactory) error {
		l.NewgidmapPath = newgidmapPath
		return nil
	}
}

func parseMountFds() ([]int, error) {
	fdsJson := os.Getenv("_LIBCONTAINER_MOUNT_FDS")
	if fdsJson == "" {
		// Always return the nil slice if no fd is present.
		return nil, nil
	}

	var mountFds []int
	if err := json.Unmarshal([]byte(fdsJson), &mountFds); err != nil {
		return nil, fmt.Errorf("Error unmarshalling _LIBCONTAINER_MOUNT_FDS: %w", err)
	}

	return mountFds, nil
}
<|endoftext|>


<commit_before>package deck

import (
	"encoding/gob"
	"fmt"
	"io"
)

const (
	QUIT = 0
)

// Message is a struct representing a request from one deck to another
type Message struct {
	Type uint64
}

// Protocol is an agent implementing the send and recieve sides of the
// cryptage protocol
type Protocol struct {
	r        *gob.Decoder
	w        *gob.Encoder
	recieved chan Message
	done     <-chan struct{}
}

// NewProtocol creates a Protocol instance assuming that the given
// io.ReadWriteCloser is a connection to another Protocol.
func NewProtocol(conn io.ReadWriteCloser, done <-chan struct{}) (*Protocol, error) {
	messages := make(chan Message)
	proto := &Protocol{
		r:        gob.NewDecoder(conn),
		w:        gob.NewEncoder(conn),
		recieved: messages,
		done:     done,
	}
	go func() {
		defer close(proto.recieved)
		for {
			var message Message
			select {
			case <-done:
				return
			default:
				if err := proto.r.Decode(&message); err == nil {
					proto.recieved <- message
				} else if err == io.EOF {
					fmt.Println("Disconnected: EOF")
					return
				} else {
					fmt.Println(err)
				}
			}
		}
	}()
	return proto, nil
}

// SendQuit asks the connected peer to quit
func (p *Protocol) SendQuit() error {
	return p.w.Encode(Message{Type: QUIT})
}

// Listen waits for events from the connected peer
func (p *Protocol) Listen() <-chan Message {
	return p.recieved
}
<commit_msg>Implement initial deck passing message<commit_after>package deck

import (
	"encoding/gob"
	"fmt"
	"io"
)

const (
	QUIT       = 0
	START_DECK = 1
)

// Message is a struct representing a request from one deck to another
type Message struct {
	Type uint64
	Deck []string
}

// Protocol is an agent implementing the send and recieve sides of the
// cryptage protocol
type Protocol struct {
	r        *gob.Decoder
	w        *gob.Encoder
	recieved chan Message
	done     <-chan struct{}
}

// NewProtocol creates a Protocol instance assuming that the given
// io.ReadWriteCloser is a connection to another Protocol.
func NewProtocol(conn io.ReadWriteCloser, done <-chan struct{}) (*Protocol, error) {
	messages := make(chan Message)
	proto := &Protocol{
		r:        gob.NewDecoder(conn),
		w:        gob.NewEncoder(conn),
		recieved: messages,
		done:     done,
	}
	go func() {
		defer close(proto.recieved)
		for {
			var message Message
			select {
			case <-done:
				return
			default:
				if err := proto.r.Decode(&message); err == nil {
					proto.recieved <- message
				} else if err == io.EOF {
					fmt.Println("Disconnected: EOF")
					return
				} else {
					fmt.Println(err)
				}
			}
		}
	}()
	return proto, nil
}

// SendQuit asks the connected peer to quit
func (p *Protocol) SendQuit() error {
	return p.w.Encode(Message{Type: QUIT})
}

// SendStartDeck ships the first encrypted deck state to the other player
func (p *Protocol) SendStartDeck(encryptedDeck []string) error {
	return p.w.Encode(Message{Type: START_DECK, Deck: encryptedDeck})
}

// Listen waits for events from the connected peer
func (p *Protocol) Listen() <-chan Message {
	return p.recieved
}
<|endoftext|>


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

package main

import (
	"io/ioutil"
	"path/filepath"
	"runtime"
	"strings"
	"testing"

	"golang.org/x/vuln/internal/report"
	"gopkg.in/yaml.v2"
)

func TestLintReports(t *testing.T) {
	if runtime.GOOS == "js" {
		t.Skipf("wasm builder does not have network access")
	}
	if runtime.GOOS == "android" {
		t.Skipf("android builder does not have access to reports/")
	}

	reports, err := ioutil.ReadDir("reports")
	if err != nil {
		t.Fatalf("unable to read reports/: %s", err)
	}

	for _, rf := range reports {
		if rf.IsDir() {
			continue
		}
		t.Run(rf.Name(), func(t *testing.T) {
			b, err := ioutil.ReadFile(filepath.Join("reports", rf.Name()))
			if err != nil {
				t.Fatalf("unable to read %q: %s", rf.Name(), err)
			}

			var r report.Report
			if err := yaml.UnmarshalStrict(b, &r); err != nil {
				t.Fatalf("unable to parse report %q: %s", rf.Name(), err)
			}

			if lints := r.Lint(); len(lints) > 0 {
				t.Errorf(strings.Join(lints, "\n"))
			}
		})
	}
}
<commit_msg>delete lint_test.go<commit_after><|endoftext|>


<commit_before>package message

import (
	"runtime"
	"time"
)

// CollectGoStats returns some very basic runtime statistics about the
// current go process, using runtimeMemStats and runtime.NumGoroutine.
//
// Internally, this uses message.Fields{}
//
// The basic idea is taken from https://github.com/YoSmudge/go-stats,
// but without the stateful collection.
func CollectGoStats() Composer {
	m := runtime.MemStats{}
	runtime.ReadMemStats(&m)

	lastGC := time.Unix(0, int64(m.LastGC))

	return MakeFields(Fields{
		"memory.objects.HeapObjects": m.HeapObjects,
		"memory.summary.Alloc":       m.Alloc,
		"memory.summary.System":      m.HeapSys,
		"memory.heap.Idle":           m.HeapIdle,
		"memory.heap.InUse":          m.HeapInuse,
		"gc.sinceLastNS":             time.Since(lastGC),
		"gc.sinceLast":               time.Since(lastGC).String(),
		"goroutines.total":           runtime.NumGoroutine(),
	})
}
<commit_msg>fix unclear field names<commit_after>package message

import (
	"runtime"
	"time"
)

// CollectGoStats returns some very basic runtime statistics about the
// current go process, using runtimeMemStats and runtime.NumGoroutine.
//
// Internally, this uses message.Fields{}
//
// The basic idea is taken from https://github.com/YoSmudge/go-stats,
// but without the stateful collection.
func CollectGoStats() Composer {
	m := runtime.MemStats{}
	runtime.ReadMemStats(&m)

	lastGC := time.Unix(0, int64(m.LastGC))

	return MakeFields(Fields{
		"memory.objects.HeapObjects": m.HeapObjects,
		"memory.summary.Alloc":       m.Alloc,
		"memory.summary.System":      m.HeapSys,
		"memory.heap.Idle":           m.HeapIdle,
		"memory.heap.InUse":          m.HeapInuse,
		"gc.sinceLast.span":          int64(time.Since(lastGC)),
		"gc.sinceLast.string":        time.Since(lastGC).String(),
		"goroutines.total":           runtime.NumGoroutine(),
	})
}
<|endoftext|>


<commit_before>package acr

import (
	"bufio"
	"bytes"
	"github.com/pkg/errors"
	"io"
	"net/http"
	"time"
)

const VERSION = "2018-03-28"

type AzureBlobStorage struct {
	UploadUrl string
	Bytes     bytes.Buffer
}

func NewBlobStorage(url string) AzureBlobStorage {
	return AzureBlobStorage{
		UploadUrl: url,
	}
}

func (s AzureBlobStorage) Writer() io.Writer {
	return bufio.NewWriter(&s.Bytes)
}

func (s AzureBlobStorage) UploadFileToBlob() error {
	req, err := http.NewRequest("PUT", s.UploadUrl, bytes.NewBuffer(s.Bytes.Bytes()))
	if err != nil {
		return err
	}
	req.Header.Add("x-ms-blob-type", "BlockBlob")
	req.Header.Add("x-ms-version", VERSION)
	req.Header.Add("x-ms-date", time.Now().String())
	req.Header.Add("Content-Length", string(s.Bytes.Len()))

	client := http.Client{}
	response, err := client.Do(req)
	if err != nil {
		return err
	}

	if response.StatusCode != http.StatusCreated {
		return errors.New("couldn't file to blob.")
	}
	return nil
}
<commit_msg>Use buffer pointer instead of buffer in azure blob storage<commit_after>package acr

import (
	"bufio"
	"bytes"
	"fmt"
	"github.com/pkg/errors"
	"io"
	"net/http"
	"time"
)

const VERSION = "2018-03-28"

type AzureBlobStorage struct {
	UploadUrl string
	Bytes     *bytes.Buffer
}

func NewBlobStorage(url string) AzureBlobStorage {
	return AzureBlobStorage{
		UploadUrl: url,
		Bytes:     new(bytes.Buffer),
	}
}

func (s *AzureBlobStorage) Writer() io.Writer {
	return bufio.NewWriter(s.Bytes)
}

func (s AzureBlobStorage) UploadFileToBlob() error {
	req, err := http.NewRequest("PUT", s.UploadUrl, s.Bytes)
	if err != nil {
		return err
	}
	req.Header.Add("x-ms-blob-type", "BlockBlob")
	req.Header.Add("x-ms-version", VERSION)
	req.Header.Add("x-ms-date", time.Now().String())
	req.Header.Add("Content-Length", fmt.Sprint(s.Bytes.Len()))

	client := http.Client{}
	response, err := client.Do(req)
	if err != nil {
		return err
	}

	if response.StatusCode != http.StatusCreated {
		return errors.New("couldn't file to blob.")
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright Istio 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 resource

import (
	"fmt"
	"path"
	"strings"

	"github.com/google/uuid"

	"istio.io/istio/pkg/test/framework/label"
)

const (
	// maxTestIDLength is the maximum length allowed for testID.
	maxTestIDLength = 30
)

// Settings is the set of arguments to the test driver.
type Settings struct {
	// Name of the test
	TestID string

	RunID uuid.UUID

	// Do not cleanup the resources after the test run.
	NoCleanup bool

	// Indicates that the tests are running in CI Mode
	CIMode bool

	// Should the tests fail if usage of deprecated stuff (e.g. Envoy flags) is detected
	FailOnDeprecation bool

	// Local working directory root for creating temporary directories / files in. If left empty,
	// os.TempDir() will be used.
	BaseDir string

	// The number of times to retry failed tests.
	// This should not be depended on as a primary means for reducing test flakes.
	Retries int

	// If enabled, namespaces will be reused rather than created with dynamic names each time.
	// This is useful when combined with NoCleanup, to allow quickly iterating on tests.
	StableNamespaces bool

	// The label selector that the user has specified.
	SelectorString string

	// The label selector, in parsed form.
	Selector label.Selector

	// EnvironmentFactory allows caller to override the environment creation. If nil, a default is used based
	// on the known environment names.
	EnvironmentFactory EnvironmentFactory
}

// RunDir is the name of the dir to output, for this particular run.
func (s *Settings) RunDir() string {
	u := strings.Replace(s.RunID.String(), "-", "", -1)
	t := strings.Replace(s.TestID, "_", "-", -1)
	// We want at least 6 characters of uuid padding
	padding := maxTestIDLength - len(t)
	if padding < 0 {
		padding = 0
	}
	n := fmt.Sprintf("%s-%s", t, u[0:padding])

	return path.Join(s.BaseDir, n)
}

// Clone settings
func (s *Settings) Clone() *Settings {
	cl := *s
	return &cl
}

// DefaultSettings returns a default settings instance.
func DefaultSettings() *Settings {
	return &Settings{
		RunID: uuid.New(),
	}
}

// String implements fmt.Stringer
func (s *Settings) String() string {
	result := ""

	result += fmt.Sprintf("TestID:            %s\n", s.TestID)
	result += fmt.Sprintf("RunID:             %s\n", s.RunID.String())
	result += fmt.Sprintf("NoCleanup:         %v\n", s.NoCleanup)
	result += fmt.Sprintf("BaseDir:           %s\n", s.BaseDir)
	result += fmt.Sprintf("Selector:          %v\n", s.Selector)
	result += fmt.Sprintf("FailOnDeprecation: %v\n", s.FailOnDeprecation)
	return result
}
<commit_msg>Add some missing test framework setting to output (#26811)<commit_after>// Copyright Istio 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 resource

import (
	"fmt"
	"path"
	"strings"

	"github.com/google/uuid"

	"istio.io/istio/pkg/test/framework/label"
)

const (
	// maxTestIDLength is the maximum length allowed for testID.
	maxTestIDLength = 30
)

// Settings is the set of arguments to the test driver.
type Settings struct {
	// Name of the test
	TestID string

	RunID uuid.UUID

	// Do not cleanup the resources after the test run.
	NoCleanup bool

	// Indicates that the tests are running in CI Mode
	CIMode bool

	// Should the tests fail if usage of deprecated stuff (e.g. Envoy flags) is detected
	FailOnDeprecation bool

	// Local working directory root for creating temporary directories / files in. If left empty,
	// os.TempDir() will be used.
	BaseDir string

	// The number of times to retry failed tests.
	// This should not be depended on as a primary means for reducing test flakes.
	Retries int

	// If enabled, namespaces will be reused rather than created with dynamic names each time.
	// This is useful when combined with NoCleanup, to allow quickly iterating on tests.
	StableNamespaces bool

	// The label selector that the user has specified.
	SelectorString string

	// The label selector, in parsed form.
	Selector label.Selector

	// EnvironmentFactory allows caller to override the environment creation. If nil, a default is used based
	// on the known environment names.
	EnvironmentFactory EnvironmentFactory
}

// RunDir is the name of the dir to output, for this particular run.
func (s *Settings) RunDir() string {
	u := strings.Replace(s.RunID.String(), "-", "", -1)
	t := strings.Replace(s.TestID, "_", "-", -1)
	// We want at least 6 characters of uuid padding
	padding := maxTestIDLength - len(t)
	if padding < 0 {
		padding = 0
	}
	n := fmt.Sprintf("%s-%s", t, u[0:padding])

	return path.Join(s.BaseDir, n)
}

// Clone settings
func (s *Settings) Clone() *Settings {
	cl := *s
	return &cl
}

// DefaultSettings returns a default settings instance.
func DefaultSettings() *Settings {
	return &Settings{
		RunID: uuid.New(),
	}
}

// String implements fmt.Stringer
func (s *Settings) String() string {
	result := ""

	result += fmt.Sprintf("TestID:            %s\n", s.TestID)
	result += fmt.Sprintf("RunID:             %s\n", s.RunID.String())
	result += fmt.Sprintf("NoCleanup:         %v\n", s.NoCleanup)
	result += fmt.Sprintf("BaseDir:           %s\n", s.BaseDir)
	result += fmt.Sprintf("Selector:          %v\n", s.Selector)
	result += fmt.Sprintf("FailOnDeprecation: %v\n", s.FailOnDeprecation)
	result += fmt.Sprintf("CIMode:            %v\n", s.CIMode)
	result += fmt.Sprintf("Retries:           %v\n", s.Retries)
	result += fmt.Sprintf("StableNamespaces:  %v\n", s.StableNamespaces)
	return result
}
<|endoftext|>